Nueva publicación

查找

Artículo
· 7 mayo, 2025 Lectura de 4 min

Creación de una extensión primitiva en un recurso FHIR

Una extensión "extiende" o mejora un recurso FHIR o un elemento de datos de forma personalizada. La extensión puede añadirse a la raíz de un recurso, como “Patient.ethnicity” en el perfil US Core, y también pueden añadirse a elementos individuales como HumanName, Address o Identifier.

¿Sabíais que también podéis añadir una extensión a un tipo de dato primitivo?

Los elementos primitivos normalmente almacenan un solo elemento y son el componente más básico en FHIR. Por ejemplo: "Keren", false, 1234, 12/08/2024, etc.

Por ejemplo, los recursos del paciente podrían verse así:

Los elementos gender, birthDate o family son elementos primitivos, basados en tipos de datos primitivos.

¿Cómo añadiríais una extensión a la propiedad birthDate o a la propiedad deceased?

Necesitaréis crear un segundo atributo con el mismo nombre, pero con un guion bajo como prefijo, por lo que la extensión primitiva para la propiedad birthDate será _birthDate.

El guion bajo le indica a FHIR que estás accediendo al Elemento base subyacente del tipo de dato primitivo.

Todos los elementos en FHIR heredan o descienden del elemento base. Este contiene dos atributos: extension e id.

En el ejemplo de abajo, añadí una extensión de “Época del año” a la propiedad birthDate y una extensión de “Está vivo” a la propiedad deceasedBoolean.

Hay varias formas de crear un recurso FHIR, aquí tenéis un ejemplo de cómo añadir una extensión primitiva en cada una de ellas.

  1. Usando un objeto dinámico para construir el recurso FHIR

Si creáis el recurso FHIR utilizando un objeto dinámico, podéis acceder directamente a la nueva extensión primitiva:

    set resource = {}

    set resource.resourceType     = "Patient"
    do resource.%Set("active",1,"boolean")
    set resource.gender           = "female"
    set resource.birthDate        = "1984-12-24"
    set resource."_birthDate"     = {}
    set resource."_birthDate".id  = "123456"
    set resource."_birthDate".extension = []

    set extension               = {}
    set extension.url            = "http://example.org/fhir/StructureDefinition/Holiday"
    set extension.valueString   = "Christmas"
    do resource."_birthDate".extension.%Push(extension)
    write resource.toJson()

y este será el resultado:

  1. Usando las clases HS.FHIR.DTL.VR4.Model.*

Aunque no se recomienda, podéis usar las clases HS.FHIR.DTL.VR4.Model.*, ya que tendríais una lista de primitiveExtension en cada nivel. Deberéis añadir vuestras extensiones primitivas allí, y luego simplemente referenciar vuestra propiedad al índice de esa extensión.

Aquí tenéis un ejemplo usando el Data Transformation Builder:

y así es como se haría lo mismo en código:

 // Create a new patient resource
 set resource=##class(HS.FHIR.DTL.vR4.Model.Resource.Patient).%New()

 set resource.active=1
 set resource.gender="female"
 // cretate a new extension
 set extension=##class(HS.FHIR.DTL.vR4.Model.Base.Extension).%New()
 set extension.url="http://example.org/fhir/StructureDefinition/Holiday"
 set extension.valueString="Christmas"
 // Add the extension to the primitive extension list
 do resource.primitiveExtension.Insert(extension)

 // point the property to the extention index (#1 in this example)
 set resource.birthDate=$listbuild("1984-12-24",1)
 write resource.ToJSON().Read()

Básicamente, el valor de la propiedad es una función $listbuild que recibe varios parámetros:

set resource.property = $listbuild("valor original de la propiedad",<índice de la extensión primitiva>,...)

  • El primer parámetro es el valor para la propiedad original; si deseáis omitir completamente la propiedad original, simplemente enviad una cadena vacía en lugar de un valor.
  • El segundo parámetro es el número de índice de la extensión primitiva requerida desde la lista de extensiones primitivas.
  • Si deseáis añadir varias extensiones primitivas a la misma propiedad, simplemente agregadlas también (después de haberlas añadido a la lista de extensiones primitivas, por supuesto):
set resource.birthDate=$listbuild("1984-12-24",1,3,4,7)
  1. Usando las clases del FHIR Object Model (desde la versión 2024.2)

Si estáis trabajando en Iris for Health versión 2024.2 o superior, quizás queráis hacer lo mismo usando las nuevas clases del FHIR Object Model. En esas clases, las extensiones primitivas ya están definidas para cada propiedad que las tenga. Así que, en nuestro caso, existe una propiedad birthDate y también una propiedad _birthDate.

Podéis usar las estructuras predefinidas para añadir una extensión primitiva:

    #dim patient as HS.FHIRModel.R4.Patient
    #dim extension as HS.FHIRModel.R4.Extension

    set patient=##class(HS.FHIRModel.R4.Patient).%New()
    set patient.gender="female"
    set patient.active=1
    set patient.birthDate="1984-12-24"
    // create a new element
    set element=##class(HS.FHIRModel.R4.Element).%New()
    do element.IncludeExtension()

    // create a new extension
    set extension=element.extension.MakeEntry()
    set extension.url="http://example.org/fhir/StructureDefinition/Holiday"
    set extension.valueString="Christmas"
    // add the extension to the element
    do element.extension.add(extension)
    
    // add the element to the resource
    set patient."_birthDate"=element
    
    write patient.toString()

De cualquier forma en la que queráis trabajar, ¡ahora podéis crear una extensión primitiva como unos profesionales!

Mirad los ejemplos en el Open Exchange para las 3 formas:

https://openexchange.intersystems.com/package/FHIR-Primitive-Extension

Comentarios (0)1
Inicie sesión o regístrese para continuar
Anuncio
· 7 mayo, 2025

Winners of the Code Your Way to InterSystems READY 2025

Hi Community,

A huge thank you to everyone who participated in the Code Your Way to InterSystems READY 2025 challenge! We enjoyed watching your videos and checking out your projects. And now it's time to announce the winners! 

🥇 1st place, a pass and a hotel accommodation go to @Shawntelle Madison-Coker for her wp-iris-project app

🥈 2nd place and a pass go to @Kurro Lopez for his Iris-nator app

🥉 3rd place and a pass go to @Oliver Wilms for his jupyter-for-money app

Our sincerest congratulations to our winners and we look forward to seeing you at the InterSystems Ready 2025!

3 comentarios
Comentarios (3)2
Inicie sesión o regístrese para continuar
Pregunta
· 7 mayo, 2025

How to prevent reentrancy inside same process ?

I use the following code to protect some code for being called by multiple processes at same time :

lock +^TEMP("FOO"):0 //don't wait
quit:'$test
//critical section
//...
lock -^TEMP("FOO")

This works between processes but it does not prevent the same process entering critical section twice.

How to do that, is there any lock option ? I would like it to behave as the lock in C# or Java.

It's OK for me to use something else than LOCK instruction (eg : signals)

8 comentarios
Comentarios (8)2
Inicie sesión o regístrese para continuar
Comentarios (0)2
Inicie sesión o regístrese para continuar
Artículo
· 6 mayo, 2025 Lectura de 13 min

IRIS iRacing

 Hello IRIS Fans and Welcome to IRIS iRacing!

Here were going to take 3 laps of your time and demonstrate how I wired up my Racing SIM to IRIS for "As Real Time as It Gets" Metrics reporting.  I missed the window for the contest, which happens quite often, but I still ended up 3rd I think in the demo race in the video below.


Technical Salad

Below are the technical ingredients for this demonstration for a salad you can post on Instragram.

 
User.iRacing.cls


Dont forget to do a:

set tSC = ##class(SYS.Monitor.SAM.Config).AddApplicationClass("User.iRacing", "USER")

Then you should see your new metrics on the /api/monitor/metrics endpoint.


Notable here is my python setup on Windows:

cpf

[config]
LibPath=
MaxServerConn=1
MaxServers=2
Path=
PythonPath=c:\Python\Python313\python.exe
PythonRuntimeLibrary=C:\Python\Python313\python313.dll
PythonRuntimeLibraryVersion=3.13
UUIDv1RandomMac=0
bbsiz=-1
console=,


iris_site.py
 

def set_site_path(platform_name):
    sys.path = sys.path + __sitegetsitepackages(['C:\\Python\Python313'])    
    sys.path = sys.path + ["C:\\Python\Python313\\Lib"]

Racing SIM

Below is the SIM specifications, complete with Driver.

Gluing it all together, we have a rolling SIM emitting, scraping and serving up iRacing metrics suitable for real time display.

As Real Time as It Gets

The excuse I made for myself to derive some real value of sorts out of this was I have always wanted to be as agressive as possible with data reporting from the source to the exporter, clear through the Prometheus Scrape and the eventual dashboard.  The python sdk is wicked fast, as it reads from a memory mapped file while in session, and the other components can be configured to be agressive, but just are not by default and took some edits and daemon reloads.

In order to make this work, I found the following tweaks for necessary:

grafani.ini

min_refresh_interval = 1s

prometheus.yml
1s scrape
 

  - job_name: 'iracing'     # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 1s
    scrape_timeout: 1s     # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.
    static_configs:
      - targets: ['192.168.1.193:52773']
    metrics_path: '/api/monitor/metrics'

Dashboard

Newly added refresh rate can be added, and "Refresh Live Dashboards"  should be enabled.


At rest it doesnt look like much, as its designed to be real time, but a screenshot is in order to see the 5 panels.

 
Grafana Dash



Demo

The video shows us putting the Dashboard and scraping to work in a quick 3 lap shootout at Darlington Motor Speedway.

🏆 This is considered an InterSystems Best Practice

Comentarios (0)1
Inicie sesión o regístrese para continuar