Limpiar filtro
Artículo
Ricardo Paiva · 4 mayo, 2023
En los últimos años, las tecnologías de inteligencia artificial para la generación de texto han avanzado significativamente. Por ejemplo, los modelos de generación de texto basados en redes neuronales pueden producir textos que son casi indistinguibles de los textos escritos por humanos. ChatGPT es uno de estos servicios. Es una enorme red neuronal entrenada con una gran cantidad de textos, que puede generar textos sobre varios temas y adaptarse a un contexto dado.
La nueva tarea para las personas es desarrollar formas de reconocer textos escritos no solo por personas sino también por inteligencia artificial (IA). Esto se debe a que, en los últimos años, los modelos de generación de texto basados en redes neuronales se han vuelto capaces de producir textos que son casi indistinguibles de los textos escritos por humanos.
Hay dos métodos principales para el reconocimiento de texto escrito por inteligencia artificial (IA):
Utilizar algoritmos de machine learning para analizar las características estadísticas del texto;
Utilizar métodos criptográficos que pueden ayudar a determinar la autoría del texto
En general, la tarea de reconocimiento de texto de IA es difícil pero importante.
Me complace presentar una aplicación para el reconocimiento de textos generados por inteligencia artificial (IA). Durante el desarrollo, aproveché los beneficios de InterSystems Cloud SQL e Integrated ML, que incluyen:
Solicitudes de datos rápidas y eficientes, con alto rendimiento y velocidad;
Interfaz amigable para usuarios no expertos en bases de datos y machine learning;
Escalabilidad y flexibilidad para ajustar rápidamente los modelos de ML según los requisitos;
En el desarrollo y entrenamiento posterior del modelo, utilicé un conjunto de datos abierto, concretamente 35 mil textos escritos. La mitad de los textos fueron escritos a mano por un gran número de autores, y la otra mitad fue generada por IA con ChatGPT.
Configuración usada para el modelo GPT:
model="text-curie-001"
temperature=0.7
max_tokens=300
top_p=1
frequency_penalty=0.4
presence_penalty=0.1
A continuación, se establecieron unos 20 parámetros básicos, según los cuales se llevó a cabo el entrenamiento posterior. Estas son algunas de las opciones que utilicé:
Cantidad de caracteres
Cantidad de palabras
Longitud media de las palabras
Cantidad de frases
Longitud media de las frases
Cantidad de palabras únicas
Cantidad de palabras vacías (stop words)
Ratio de palabras únicas
Cantidad de signos de puntuación
Ratio de signos de puntuación
Cantidad de preguntas
Cantidad de exclamaciones
Cantidad de dígitos
Cantidad de letras en mayúscula
Cantidad de palabras repetidas
Cantidad de bigramas únicos
Cantidad de trigramas únicos
Cantidad de cuatrigramas únicos
Como resultado, obtuve una sencilla aplicación que podéis usar para vuestras tareas o para pasarlo bien.
Así es como se ve:
Para probar la aplicación podéis usar la demo online o ejecutarla en local con vuestra cuenta Cloud SQL.
Todos los comentarios sobre la app son bienvenidos!
Anuncio
Esther Sanchez · 25 mar, 2021
¡Hola Comunidad!
En esta publicación, os explicamos las distintas Insignias de Global Masters y qué hay que hacer para conseguirlas.
Información general sobre Niveles e Insignias de Global Masters
Todos los miembros de Global Masters empiezan en el 1er nivel ("Insider"), cuando se registran en el Programa de Fidelización. Para subir de nivel, hay que ganar un número de insignias del siguiente nivel. Las insignias se ganan realizando diferentes "retos".¿Cómo puedes saber en qué nivel estás y las insignias que tienes? Sigue estos sencillos pasos:
1. En la página de inicio de Global Masters, haz clic en la foto de tu perfil, en la parte superior derecha > después, haz clic en tu nombre2. Ahí ya puedes ver en qué nivel estás, las insignias que has ganado y lo que te falta para pasar al siguiente nivel3. Si haces clic en "See available badges" verás todas las insignias y niveles del programa
También puedes ver tus insignias ganadas en tu página de perfil en la Comunidad de Desarrolladores.
Cómo conseguir las insignias en GM
Nombre de la insignia
Reglas
Insignias por número de vistas
Popular Writer - 750 vistas
Insignias conseguidas si cualquiera de tus publicaciones (preguntas o artículos) en la Comunidad de Desarrolladores consiguen más de 750 / 2 000 / 5 000 vistas únicas.
La publicación no debe ser eliminada; tiene que ser publicada.
Solo cuentan las publicaciones con una calificación positiva.
No cuentan las publicaciones con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
Cada insignia solo se concede una vez. Los puntos se dan por cada publicación que consigue el número de vistas indicadas.
Notable Writer - 2 000 vistas
Famous Writer - 5 000 vistas
Gold Writer - 15 000 vistas
Insignias por artículos publicados
Reporter - 5 artículos
Insignias conseguidas cuando llegas a 5 / 10 / 25 / 50 artículos (no preguntas) publicados en la Comunidad.
Las publicaciones no deben ser eliminadas; tienen que ser publicadas.
Solo cuentan las publicaciones con una calificación positiva.
No cuentan las publicaciones con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
Blogger - 10 artículos
Influencer - 25 artículos
Opinion Maker - 50 artículos
DC Best Practices Author Badge - 1 best practice
Insignias conseguidas cuando llegas a 1 / 10 / 25 / 50 artículos (no preguntas) considerados como Best Practice ("Mejores prácticas") en la Comunidad de Desarrolladores.
Las publicaciones no deben ser eliminadas; tienen que ser publicadas.
Solo cuentan las publicaciones con una calificación positiva.
No cuentan las publicaciones con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
RecognizableBest Practices Author Badge - 2 best practices
Bronze Best Practices Author Badge - 3 best practices
Silver Best Practices Author Badge- 4 best practices
Gold Best Practices Author Badge - 5 best practices
Master of Answers - 5 respuestas aceptadas
Insignias conseguidas cuando tus respuestas en la Comunidad de Desarrolladores son marcadas 5 / 10 / 25 / 50 veces como respuestas aceptadas.
Bronze Master of Answers - 10 respuestas aceptadas
Silver Master of Answers - 25 respuestas aceptadas
Gold Master of Answers - 50 respuestas aceptadas
Insignias por preguntas
Curious Member - 5 preguntas
Insignias conseguidas cuando llegas a 5 / 10 / 25 / 50 preguntas en la Comunidad de Desarrolladores.
Las preguntas no deben ser eliminadas; tienen que ser publicadas.
Solo cuentan las preguntas con una calificación positiva.
No cuentan las preguntas con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
Thorough Member - 10 preguntas
Inquisitive Member - 25 preguntas
Socratic Member - 50 preguntas
Insignias por favoritos
Favorite Post - 10 veces
Insignias conseguidas cuando tus publicaciones (preguntas o artículos) en la Comunidad de Desarrolladores, son marcadas 10 / 50 / 100 veces como favoritas.
Las publicaciones no deben ser eliminadas; tienen que ser publicadas.
Solo cuentan las publicaciones con una calificación positiva.
No cuentan las preguntas con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
Remarkable Post - 50 veces
Unforgettable Post - 100 veces
Insignias por votos
Insightful Author - 50 votos
Insignias conseguidas cuando tus publicaciones (preguntas o artículos) en la Comunidad de Desarrolladores, consiguen 50 / 100 / 500 / 1 000 votos.
Las publicaciones no deben ser eliminadas; tienen que ser publicadas.
No cuentan las publicaciones con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
Expert Author - 100 votos
Recognizable Author - 500 votos
Powerful Author - 1000 votos
Insightful Commenter - 50 votos
Insignias conseguidas cuando tus respuestas (comentarios a preguntas) en la Comunidad de Desarrolladores, consiguen 50 / 100 / 500 / 1 000 votos.
No cuentan las respuestas eliminadas
No cuentan las respuestas con la etiqueta Feedback sobre la Comunidad de Desarrolladores .
Expert Commenter - 100 votos
Recognizable Commenter - 500 votos
Powerful Commenter - 1 000 votos
DC Moderator
Concedida a los Moderadores de la Comunidad de Desarrolladores. Esta insignia no está relacionada con los niveles.
Insignias anuales - Top 10 Autores
Gold Best-Selling Author - 1er puesto
1º / 2º / 3º / 4º-10º puestos en la categoría "DC Best-Selling Author".
Autores cuyos artículos consiguieron el mayor número de visualizaciones en la Comunidad de Desarrolladores durante un año.
Silver Best-Selling Author - 2º puesto
Bronze Best-Selling Author - 3er puesto
DC Best-Selling Author - 4º-10º puestos
Gold Expert - 1er puesto
1º / 2º/ 3º / 4º-10º puestos en la categoría “DC Expert”.
Autores que consiguieron el mayor número de "Respuestas aceptadas" en la Comunidad de Desarrolladores durante un año.
Silver Expert - 2º puesto
Bronze Expert - 3er puesto
DC Expert - 4º-10º puestos
Gold Opinion Leader - 1er puesto
1º / 2º/ 3º / 4º-10º puestos en la categoría “DC Opinion Leader”.
Autores cuyas publicaciones y respuestas obtuvieron el mayor número de votos en la Comunidad de Desarrolladores durante un año.
Silver Opinion Leader - 2º puesto
Bronze Opinion Leader - 3er puesto
DC Opinion Leader - 4º-10º puestos
Insignias por recomendaciones
Gold Recruiter - 100 recomendaciones
Insignias conseguidas cuando se unen a la Comunidad de Desarrolladores 1 /10 / 50 / 100 personas a las que recomendaste la Comunidad.
Silver Recruiter - 50 recomendaciones
Bronze Recruiter - 10 recomendaciones
DC Recruiter - 1 recomendación
Insignias por Contribuciones Básicas
DC Author
Insignia conseguida cuando publicas tu primer artículo en la Comunidad de Desarrolladores.
La publicación no debe ser eliminada; tiene que ser publicada.
No cuentan los artículos con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
Debe ser una publicación del tipo "Artículo".
InterSystems Researcher
Insignia conseguida cuando publicas tu primera pregunta en la Comunidad de Desarrolladores.
La pregunta no debe ser eliminada; tiene que ser publicada.
No cuentan las preguntas con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
Debe ser una publicación del tipo "Pregunta".
DC Commenter
Insignia conseguida cuando publicas tu primer comentario en la Comunidad de Desarrolladores.
Comentario con algún "Me gusta" o sin ningún "Me gusta"
No cuentan los comentarios realizados con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
DC Problem Solver
Insignia conseguida cuando tu respuesta a la pregunta de alguien es marcada como "Respuesta aceptada" en la Comunidad de Desarrolladores.
La respuesta tiene que ser marcada como "Respuesta aceptada"
No cuentan las respuestas realizadas con la etiqueta Feedback sobre la Comunidad de Desarrolladores.
DC Translator
Insignia conseguida cuando publicas tu primera traducción en la Comunidad de Desarrolladores. Cómo añadir una traducción
Winner of Advent of Code
Insignia concedida a los ganadores del concurso "Advent of Code". Mas info aquí.
Global Master of the Month
Insignia concedida a los "Advocate of the Month" en Global Masters.
Gold Advocate of the Year
Insignias concedidas a los "Best Advocates of the Year" en Global Masters.
Silver Advocate of the Year
Bronze Advocate of the Year
Insignias de Open Exchange
InterSystems Open Exchange Developer
Insignias conseguidas cuando publicas 1 / 5 / 10 / 25 aplicaciones en InterSystems Open Exchange.
Bronze Open Exchange Developer
Silver Open Exchange Developer
Gold Open Exchange Developer
Además...
Consulta la información adicional sobre Global Masters:
Cómo unirse a Global Masters
Descripción de los Niveles de Global Masters
Si tienes alguna duda sobre las Insignias, puedes dejarnos un comentario en esta publicación y te responderemos al momento!
Artículo
Alberto Fuentes · 17 abr, 2019
El archivo events_examples.zip contiene dos ejemplos que muestran cómo procesar una carga de trabajo de forma asíncrona utilizando colas persistentes.Events_Simple.prj.xmlEvents_PubSub.prj.xml (actualizado! este ejemplo se ha publicado en https://github.com/intersystems-ib/cache-iat-pubsub)Events SimpleEste es un ejemplo muy sencillo que crea algunos procesos trabajadores y les encola mensajes utilizando $system.Event.
; crear un recurso compartido y crear los procesos trabajadores
USER>do ##class(IAT.S04.Event.Test).Setup()
; encolar algunos mensajes hacia los trabajadores y ver qué sucede
USER>do ##class(IAT.S04.Event.Test).Run()
Show log? no/[yes]:
^Samples.Log=10
^Samples.Log(1)="[2016-02-19 09:43:14] Enqueuing 1"
^Samples.Log(2)="[2016-02-19 09:43:14] Worker 8168 grabs: 1"
^Samples.Log(3)="[2016-02-19 09:43:14] Enqueuing 2"
^Samples.Log(4)="[2016-02-19 09:43:14] Worker 18184 grabs: 2"
^Samples.Log(5)="[2016-02-19 09:43:14] Enqueuing 3"
^Samples.Log(6)="[2016-02-19 09:43:14] Worker 8168 grabs: 3"
^Samples.Log(7)="[2016-02-19 09:43:14] Enqueuing 4"
^Samples.Log(8)="[2016-02-19 09:43:14] Worker 18184 grabs: 4"
^Samples.Log(9)="[2016-02-19 09:43:14] Enqueuing 5"
^Samples.Log(10)="[2016-02-19 09:43:14] Worker 8168 grabs: 5"
; trabajo terminado, podemos enviar más mensajes o matar a los procesos trabajadores
write $system.Process.Terminate(8168)
1
write $system.Process.Terminate(18184)
1
Clases:
Manager - métodos para crear recursos compartidos así como los procesos trabajadores y encolar mensajes.Queue - clase persistente simple utilizada para almacenar mensajes.Worker - representa a un trabajador que espera que le llegue un evento para procesar el mensaje recibido.
Events PubSub
Este ejemplo está construido sobre la misma base que Events_Simple.
El objetivo en este caso es construir un modelo sencillo de Publicador-Subscriptor.
Hay dos subscriptores para dos tipos de mensajes distintos:
SubPatient - gestiona los mensajes relacionados con pacientes.SubDummy - gestiona mensajes dummys.
; crear los eventos y los procesos subscriptores
do ##class(IAT.S05.PubSub.Example.Main).Setup()
; enviar algunos mensajes (de los dos tipos) al canal
do ##class(IAT.S05.PubSub.Example.Main).Run()
; mostrar el log con el resultado de lo que ha sucedido
zw ^PubSub.Log
Log
Clases
Hola Alberto!¡Qué buen artículo!Puedes a publicar el ejemplo en Open Exhcange tambien?
Artículo
Kurro Lopez · 20 abr, 2020
Aqui teneis una clase "test" con el código para envíar un correo electrónico en formato HTML con una imagen incrustada.
Edita el texto para cambiar la imagen incrustada, dirección de destino y remitente, asunto, contenido, etc...
Class objectscript.sendEmailWithImage Extends %RegisteredObject
{
classmethod test() {
S SmtpServer = ""
S SmtpUserName = ""
S SmtpPassword = ""
S imgPath="C:\test.jpg"
set s=##class(%Net.SMTP).%New()
set s.smtpserver=SmtpServer
set auth=##class(%Net.Authenticator).%New() ; use default authentication list
set auth.UserName=SmtpUserName
set auth.Password=SmtpPassword
set s.authenticator=auth
Set objMail=##class(%Net.MailMessage).%New()
Set objMail.From="sender@testhost.com"
Do objMail.To.Insert("reciever@testhost.com")
Set objMail.Subject="Test-Email"
Set objMail.Charset="iso-8859-1"
Set obj1 =objMail
Set obj1.IsHTML=1
Set obj1.IsBinary = 0
Set obj1.IsMultiPart = 1
Set obj1.MultiPartType ="related"
Do obj1.Headers.SetAt("inline","Content-Disposition")
//alternative container for the text-parts
#dim textbody as %Net.MailMessagePart
s textbody = obj1.AttachNewMessage()
s textbody.IsMultiPart=1
s textbody.IsHTML=0
s textbody.MultiPartType="alternative"
//html part
#dim text as %Net.MailMessagePart
//text part
#dim texttxt as %Net.MailMessagePart
s texttxt = textbody.AttachNewMessage()
//s texttxt.ContentType="text/plain"
d texttxt.TextData.Write("this is plain text")
s text = textbody.AttachNewMessage()
s text.IsHTML=1
s text.IsBinary=0
s text.IsMultiPart=0
Do text.TextData.Write("<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01 Transitional//EN"">")
do text.TextData.Write("<html><head><meta http-equiv=""content-type"" content=""text/html; charset=ISO-8859-1"">")
Do text.TextData.Write("</head><body text=""#000000"" bgcolor=""#ffffff"">")
Do text.TextData.Write("Das ist ein Test in html")
Do text.TextData.Write("<img src=""cid:test.jpg"" />")
Do text.TextData.Write("</body></html>")
// Image Message Part
#dim obj2 as %Net.MailMessagePart
Set obj2 = obj1.AttachNewMessage()
Set obj2.IsBinary = 1
Set obj2.IsMultiPart = 0
Set obj2.FileName="test.jpg"
Do obj2.BinaryData.LinkToFile(imgPath)
Do obj2.Headers.SetAt("inline","Content-Disposition")
Do obj2.Headers.SetAt("<test.jpg>","Content-ID")
set status=s.Send(objMail)
d $system.OBJ.DisplayError(status)
w status,!
}
}
Aquí tienes el enlace para ver el código en GitHub: https://github.com/intersystems-community/code-snippets/blob/master/src/cls/objectscript/sendEmailWithImage.cls
Artículo
Alberto Fuentes · 8 jun, 2021
Otro artículo sobre "Trucos y consejos de VSCode" -
.png)
¿Quieres ver esta opción en VSCode?
Esta vez nos centraremos en cómo obtener el Asistente SOAP (*SOAP Wizard*) tal y como estaba disponible en Studio — para definir un cliente de servicio web SOAP basado en WSDL (y *Business Operation*), o servicio —.
Si trabajas con Servicios web (*Web services*), lo más probable es que hayas utilizado el Asistente SOAP en Studio. Lo abrirías en *Tools > Add-Ins*:
.png)
Y este abría una "*Server Template*":
.png)
En VSCode, puede que te preguntes cómo puedes acceder a eso.
Bueno, el hecho básico que hay que comprender es que realmente este complemento o asistente es simplemente una página web, que se muestra en Studio como hemos visto anteriormente y, como tal, también se puede acceder a ella desde un simple navegador. VSCode facilita la apertura de dicho navegador con el contenido deseado (construyendo la URL correcta con el nombre del servidor, el puerto, la aplicación web, etc.).
El resultado sería el mismo que ver una opción para abrir el Portal de administración o la Referencia de clase (con las URLs correspondientes) al hacer clic en la Conexión del servidor sobre la barra de estado inferior de VSCode, por ejemplo:
.png)
También verás una entrada para el Asistente SOAP.
Puedes conseguir esto al añadir una entrada 'links' a tu objeto 'conn' que se encuentra en tu configuración de JSON de tu extensión ObjectScript, y especificando la URL deseada (utilizando las variables correspondientes).
Esto se mencionó en un debate sobre Problemas con VSCode que se encuentra en el GitHub VSCode ObjectScript, como [problema "Asistente SOAP"](https://github.com/intersystems-community/vscode-objectscript/issues/325), con comentarios de @John Murray y @Ondřej Hoferek, y también se menciona en esta respuesta de @Timothy Leavitt a una pregunta de la Comunidad.
El valor JSON sería:
"SOAP Wizard": "${serverUrl}/isc/studio/templates/%25ZEN.Template.AddInWizard.SOAPWizard.cls?Namespace=${namespace}${serverAuth}"
Y esta parte se vería así:
.png)
Una vez que tengas esto, verás una opción adicional cuando hagas clic en la Conexión -
.png)
Y al elegir esa opción accederás al esperado asistente (abierto en un navegador):
.png)
Os dejo un breve GIF mostrando este proceso (comienza por el menú normal al hacer clic en la Conexión, y termina con el menú que incluye el Asistente SOAP).

Fíjate que hay otros asistentes (o plantillas) que puedes añadir de esta manera (como el Asistente XSD, por ejemplo).
Excelente consejo, tanto para abrir este wizard como el resto de asistentes, poco a poco el VSCode va cogiendo forma. ¡Muchas gracias Alberto! Hay que potenciar el VSCode.
Artículo
Eduardo Anglada · 25 mayo, 2021
¡Hola Comunidad!
ObjectScript, el lenguaje de InterSystems IRIS, tiene la capacidad de extender clases utilizando una funcionalidad muy interesante llamada XData.
Es una sección en tu clase que puede ser usada para crear definiciones personalizadas, para utilizarlas dentro de la clase misma o externamente.
Crear una o más definiciones XData para tu clase es muy sencillo, mira el ejemplo:
Class dc.Sample.Person Extends (%Persistent, %JSON.Adaptor, %Populate)
{
Property Name As %VarString;
Property Title As %String;
Property Company As %String;
Property Phone As %VarString;
Property DOB As %Date(MAXVAL = "$piece($horolog, "","", 1)");
/// Index for property DOB
Index DOBIndex On DOB;
ClassMethod AddTestData(amount As %Integer = 10)
{
d ..Populate(amount)
}
/// Documentation for Person
XData PersonDocHtml [ MimeType = text/html ]
{
<h1>This is the Person class</h1>
}
XData PersonDocMarkdown [ MimeType = text/markdown ]
{
<h1>This is the Person class</h1>
}
Ten en cuenta que tras definir los métodos, solo tienes que añadir una o más secciones XData con tres subsecciones: XData NomeSecaoXData [MimeType = TypeOfMimeType]. El contenido se pone entre corchetes.
Todos los elementos XData se almacenan en la clase persistente % Dictionary.XDataDefinition. Esto significa que es posible recuperar las definiciones usando lenguaje SQL, internamente o externamente. Mira el ejemplo:
Class dc.mkdocs.Generator
{
ClassMethod Generate()
{
Set qry = "SELECT parent, Name, Description FROM %Dictionary.XDataDefinition WHERE MimeType IN ('text/markdown','text/html')"
Set stm = ##class(%SQL.Statement).%New()
Set qStatus = stm.%Prepare(qry)
If qStatus'=1 {Write "%Prepare failed:" Do $System.Status.DisplayError(qStatus) Quit}
Set rset = stm.%Execute()
While rset.%Next() {
Write "Row count ",rset.%ROWCOUNT,!
Write rset.parent
Write ": ",rset.Description,!
Write ..GetXDataContent(rset.parent,rset.Name),!!
}
Write !,"Total row count=",rset.%ROWCOUNT
}
ClassMethod GetXDataContent(className, xdataName) As %String
{
set content = ""
for i=1:1:$$$comMemberKeyGet(className,$$$cCLASSxdata,xdataName,$$$cXDATAdata) {
set content = content_$$$comMemberArrayGet(className,$$$cCLASSxdata,xdataName,$$$cXDATAdata,i)
}
quit content
}
}
En este ejemplo, todos los elementos XData con Mime Type markdown y html son recuperados y se imprime tanto el nombre de la clase en la que se localiza el elemento XData como su descripción. Si quieres recuperar el contenido del elemento XData consulta GetXDataContent (gracias @Eduard.Lebedyuk).
Es una funcionalidad muy interesante, ya que podemos catalogar la documentación de todas las clases de una aplicación y tener un fácil acceso a ellas. ¡Genial!
Anuncio
Ricardo Paiva · 18 mar, 2022
# Iris Healthtoolkit Service
[](https://youtu.be/lr2B7zSFkds "Video")
Fácil de usar HL7v2 a FHIR, CDA a FHIR, FHIR a HL7v2 como un Servicio.
El objetivo de este proyecto es ofrecer una API REST que pueda convertir fácilmente varios formatos de salud.
Publica el formato deseado en el cuerpo REST, obtén la respuesta en el nuevo formato.
*  SaaS Offer : https://aws.amazon.com/marketplace/pp/prodview-q7ryewpz75cq2 
*  Video : https://youtu.be/lr2B7zSFkds 
## Instalación
Clona este repositorio
```
git clone https://github.com/grongierisc/iris-healthtoolkit-service.git
```
Docker
```
docker-compose up --build -d
```
## Uso
* Ve a: http://localhost:32783/swagger-ui/index.html
## Detalles de la API
* HL7 a FHIR
```
POST http://localhost:32783/api/hl7/fhir
```
* FHIR a HL7 ADT
```
POST http://localhost:32783/api/fhir/hl7/adt
```
* FHIR a HL7 ORU
```
POST http://localhost:32783/api/fhir/hl7/oru
```
* FHIR a HL7 vxu
```
POST http://localhost:32783/api/fhir/hl7/vxu
```
* CDA a FHIR
```
POST http://localhost:32783/api/cda/fhir
```
* FHIR repo
```
GET http://localhost:32783/api/fhir/metadata
```
## Formatos de entrada de HL7 compatibles:
* ADT_A01, ADT_A02, ADT_A03, ADT_A04, ADT_A05, ADT_A06, ADT_A07, ADT_A08, ADT_A09, ADT_A10, ADT_A11, ADT_A12, ADT_A13, ADT_A17, ADT_A18, ADT_A23, ADT_A25, ADT_A27, ADT_A28, ADT_A29, ADT_A30, ADT_A31, ADT_A34, ADT_A36, ADT_A39, ADT_A40, ADT_A41, ADT_A45, ADT_A47, ADT_A49, ADT_A50, ADT_A51, ADT_A60
* BAR_P12
* MDM_T02, MDM_T04, MDM_T08, MDM_T11
* OMP_O09
* ORM_O01
* ORU_R01
* PPR_PC1, PPR_PC2, PPR_PC3
* RDE_O11
* SIU_S12, SIU_S13, SIU_S14, SIU_S15, SIU_S16, SIU_S17, SIU_S26
* VXU_V04
## Cómo funciona
El proyecto funciona con el diagrama dinámico: SDA.
El SDA (Summary Document Architecture) es el Formato de Datos Clínicos de InterSystems.
Las correspondencias SDA FHIR se pueden consultar [aquí](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=HXFHIR_transforms), y las de CDA -> SDA [aquí](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=HXCDA).

Artículo
Ricardo Paiva · 29 ene, 2021
¡Hola Desarroladores!
IRIS External Table es un proyecto de código abierto de la comunidad de InterSystems, que permite utilizar archivos almacenados en el sistema de archivos local y almacenar objetos en la nube como AWS S3 y tablas SQL. 
Se puede encontrar en GitHub Open Exchange y está incluido en el administrador de paquetes InterSystems Package Manager (ZPM).
Para instalar External Table desde GitHub, utilice:
git clone https://github.com/antonum/IRIS-ExternalTable.git
iris session iris
USER>set sc = ##class(%SYSTEM.OBJ).LoadDir("/IRIS-ExternalTable/src", "ck",,1)
Para instalarlo con el ZPM Package Manager, utilice:
USER>zpm "install external-table"
## Cómo trabajar con archivos locales
Crearemos un archivo simple que tiene este aspecto:
a1,b1
a2,b2
Abra su editor favorito y cree el archivo o utilice solo una línea de comandos en Linux/Mac:
echo $'a1,b1\na2,b2' > /tmp/test.txt
Cree una tabla SQL en IRIS para representar este archivo:
create table test (col1 char(10),col2 char(10))
Convierta la tabla para utilizar el almacenamiento externo:
CALL EXT.ConvertToExternal(
'test',
'{
"adapter":"EXT.LocalFile",
"location":"/tmp/test.txt",
"delimiter": ","
}')
Y finalmente, consulte la tabla:
select * from test
Si todo funciona según lo previsto, debería ver el resultado de la siguiente forma:
col1 col2
a1 b1
a2 b2
Ahora regrese al editor, modifique el contenido del archivo y ejecute nuevamente la consulta SQL. ¡¡¡Tarán!!! Está leyendo nuevos valores de su archivo local en SQL.
col1 col2
a1 b1
a2 b99
## Cómo leer los datos desde S3
En puede acceder a los datos de la COVID que se actualizan constantemente, estos se almacenan por AWS en el lago de datos públicos.
Intentaremos acceder a una de las fuentes de datos en este lago de datos: `s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states`
Si tiene instalada la herramienta de línea de comandos para AWS, puede repetir los siguientes pasos. Si no es así, vaya directamente a la parte de SQL. No es necesario que tenga ningún componente específico de AWS instalado en su equipo para continuar con la parte de SQL.
$ aws s3 ls s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/
2020-12-04 17:19:10 510572 us-states.csv
$ aws s3 cp s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv .
download: s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv to ./us-states.csv
$ head us-states.csv
date,state,fips,cases,deaths
2020-01-21,Washington,53,1,0
2020-01-22,Washington,53,1,0
2020-01-23,Washington,53,1,0
2020-01-24,Illinois,17,1,0
2020-01-24,Washington,53,1,0
2020-01-25,California,06,1,0
2020-01-25,Illinois,17,1,0
2020-01-25,Washington,53,1,0
2020-01-26,Arizona,04,1,0
Por lo tanto, tenemos un archivo con una estructura bastante simple y cinco campos delimitados.
Para mostrar esta carpeta S3 como en External Table, primero necesitamos crear una tabla “regular” con la estructura deseada:
-- create external table
create table covid_by_state (
"date" DATE,
"state" VARCHAR(20),
fips INT,
cases INT,
deaths INT
)
Tenga en cuenta que algunos campos de datos como “Date” son palabras reservadas en el SQL de IRIS y deben escribirse entre comillas dobles. Entonces, necesitamos convertir esta tabla “regular” en la tabla “externa”, basada en el bucket AWS S3 y con el tipo CSV.
-- convert table to external storage
call EXT.ConvertToExternal(
'covid_by_state',
'{
"adapter":"EXT.AWSS3",
"location":"s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/",
"type": "csv",
"delimiter": ",",
"skipHeaders": 1
}'
)
Si observa detenidamente, en EXT.ExternalTable los argumentos de los procedimientos son el nombre de la tabla y luego la cadena JSON, además contiene varios parámetros como la ubicación para buscar archivos, el adaptador para utilizarlos, un delimitador, etc. Además, External Table de AWS S3 es compatible con el almacenamiento de Azure BLOB, Google Cloud Buckets y el sistema de archivos local. El repositorio de GitHub contiene referencias para la sintaxis y opciones que son compatibles con todos los formatos.
Y finalmente, consulte la tabla:
-- query the table
select top 10 * from covid_by_state order by "date" desc
[SQL]USER>>select top 10 * from covid_by_state order by "date" desc
2. select top 10 * from covid_by_state order by "date" desc
date state fips cases deaths
2020-12-06 Alabama 01 269877 3889
2020-12-06 Alaska 02 36847 136
2020-12-06 Arizona 04 364276 6950
2020-12-06 Arkansas 05 170924 2660
2020-12-06 California 06 1371940 19937
2020-12-06 Colorado 08 262460 3437
2020-12-06 Connecticut 09 127715 5146
2020-12-06 Delaware 10 39912 793
2020-12-06 District of Columbia 11 23136 697
2020-12-06 Florida 12 1058066 19176
Es comprensible que se necesite más tiempo para consultar los datos de la tabla remota, que para consultar la tabla “nativa de IRIS” o la tabla basada en el global, pero esta se almacena y actualiza completamente en la nube, y en segundo plano se extrae a IRIS.
Exploremos un par de funciones adicionales de External Table.
## %PATH y las tablas basadas en varios archivos
La carpeta de nuestro ejemplo, que se encuentra en el bucket, contiene solo un archivo. Lo más común es que tenga varios archivos de la misma estructura, donde el nombre del archivo identifique tanto al registro de la hora como al identificador de algún otro atributo que queramos utilizar en nuestras consultas.
El campo %PATH se agrega automáticamente a cada tabla externa y contiene la ruta completa hacia el archivo de donde se recuperó la fila.
select top 5 %PATH,* from covid_by_state
%PATH date state fips cases deaths
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-21 Washington 53 1 0
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-22 Washington 53 1 0
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-23 Washington 53 1 0
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-24 Illinois 17 1 0
s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-24 Washington 53 1 0
Puede utilizar el campo %PATH en sus consultas SQL como cualquier otro campo.
## De datos ETL a “tablas regulares”
Si su tarea es cargar datos de S3 en una tabla IRIS, puede utilizar External Table como una herramienta ETL. Simplemente haga lo siguiente:
INSERT INTO internal_table SELECT * FROM external_table
En nuestro caso, si queremos copiar los datos COVID de S3 a la tabla local:
--create local table
create table covid_by_state_local (
"date" DATE,
"state" VARCHAR(100),
fips INT,
cases INT,
deaths INT
)
--ETL from External to Local table
INSERT INTO covid_by_state_local SELECT TO_DATE("date",'YYYY-MM-DD'),state,fips,cases,deaths FROM covid_by_state
## UNIÓN entre IRIS, tablas nativas y externas. Consultas federadas
External Table es una tabla SQL. Se puede unir con otras tablas, utilizarse en subconsultas y sistemas de archivos tipo UNION. Incluso puede combinar la tabla “Regular” de IRIS y dos o más tablas externas que provengan de diferentes fuentes en la misma consulta SQL.
Intente crear una tabla regular, por ejemplo, haga coincidir los nombres de los estados con sus códigos como en el caso de Washington y WA. Y únalos con nuestra tabla basada en S3.
create table state_codes (name varchar(100), code char(2))
insert into state_codes values ('Washington','WA')
insert into state_codes values ('Illinois','IL')
select top 10 "date", state, code, cases from covid_by_state join state_codes on state=name
Cambie “join” por “left join” para incluir aquellas filas donde el código del estado no esté definido. Como puede ver, el resultado es una combinación de datos provenientes de S3 y su tabla nativa de IRIS.
## Acceso seguro a la información
El lago de datos Covid en AWS es público. Cualquier persona puede leer los datos que provengan de esta fuente sin la necesidad de tener alguna autenticación o autorización. En la vida real seguramente quiere acceder a sus datos de una forma segura, donde se evite que extraños echen un vistazo a sus archivos. Los detalles completos sobre AWS Identity y Access Management (IAM) están fuera del alcance de este artículo. Pero lo mínimo que debe saber es que necesita por lo menos la clave de acceso a la cuenta y la información confidencial de AWS para acceder a los datos privados de su cuenta.
AWS utiliza la autenticación de claves/información confidencial de la cuenta para firmar las solicitudes. https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys
Si está ejecutando IRIS External Table en una instancia de EC2, la forma recomendada de lidiar con la autenticación es utilizando las funciones que se encuentran en la instancia de EC2 https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html. De este modo, IRIS External Table podría utilizar los permisos de esa función. No se requiere ninguna configuración adicional.
En una instancia local o que no sea de EC2 es necesario especificar AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY, ya sea con la ayuda de variables de entorno o mediante la instalación y configuración del cliente CLI de AWS.
export AWS_ACCESS_KEY_ID=AKIAEXAMPLEKEY
export AWS_SECRET_ACCESS_KEY=111222333abcdefghigklmnopqrst
Asegúrese de que la variable de entorno sea visible dentro del proceso de IRIS. Puede verificarlo al ejecutar:
USER>write $system.Util.GetEnviron("AWS_ACCESS_KEY_ID")
Esto debería emitir el valor de la clave.
O instale el CLI de AWS, mediante instrucciones que se encuentran aquí: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html y ejecutar:
aws configure
Entonces External Table podrá leer las credenciales desde los archivos de configuración para el CLI de AWS. Posiblemente su shell interactivo y el proceso de IRIS estén ejecutándose en cuentas diferentes, asegúrese de ejecutar `aws configure` con la misma cuenta que su proceso de IRIS.
Este artículo ha sido etiquetado como "Mejores prácticas" ("Best practices").
Los artículos con la etiqueta "Mejores prácticas" incluyen recomendaciones sobre cómo desarrollar, probar, implementar y administrar mejor las soluciones de InterSystems.
Artículo
Heloisa Paiva · 1 jun, 2023
Introducción
Entre las diversas soluciones que desarrollamos en Innovatium, un desafío habitual es la necesidad de acceder al tamaño de las bases de datos. Entonces me di cuenta de que eso no es algo tan trivial en IRIS. Ese tipo de información es importante para mantener un control del flujo de datos y del coste en gigabytes de un sistema para implementar. Sin embargo, lo que realmente me llamó la atención fue la necesidad de eso para algo muy importante: la migración a la nube. Al final, ¿quién no quiere migrar sus sistemas a la nube hoy en día?
Los servicios cloud ofrecen, de manera sencilla, todo lo que un sistema necesita: mirroring, escalabilidad, protección de datos, facilidad de flujo y lo que hace que todas las empresas se enamoren: solo se paga por lo que se usa. Y además, con los gigantes Google (Cloud), Microsoft (Azure), Amazon (AWS), etc. ofreciendo sus servicios casi impecables a precios accesibles, es algo que con una pequeña inversión puede ser una realidad para cualquiera que quiera aumentar sus ganancias y ahorrar a largo plazo. Además, para aquellos que ya están aquí, InterSystems también tiene sus propios servicios en la nube.
Por eso os voy a presentar la aplicación que estoy desarrollando, en la cual no solo es posible, sino también es fácil, observar el tamaño de los globals, para que los análisis necesarios para obtener un servicio cloud sean tan complicado como tu proveedor favorito lo complique.
Inspiración
Inspirándome en las aplicaciones isc-global-size-tracing y globals-tool, estoy creando una versión que pueda unir lo mejor de cada una y añadir las adaptaciones necesarias para nuestro negocio. Pero antes de mostrar mi desarrollo, voy a presentar brevemente las aplicaciones comentadas.
isc-global-size-tracing ofrece servicios de análisis a partir de clases dentro de IRIS, con métodos más amigables para el usuario y opciones de tareas programadas que actualizan una tabla con varios datos sobre los globals. Hay también opciones predefinidas para exportar las información a archivos externos. Así, si ya hay conocimiento de ObjectScript no es tan difícil dedicar unos minutos a entender cómo funciona y adaptarlo a tu negocio.
Globals-tool muestra un portal en forma de página web, donde es posible verificar los tamaños asignados y los tamaños disponibles para cada global, dentro de sus namespaces. Es un poco más simple, pero más amigable para el usuario, y también se puede utilizar para compartir los datos con personas de otras áreas sin conocimientos de programación. Los cambios y adaptaciones pueden requerir conocimientos previos no solo de ObjectScript, sino también de React y similares.
Lo que me gustaría entonces es combinar las diversas opciones de la primera con la facilidad de uso de la segunda, además de añadir otras funciones de análisis y exportación.
La aplicación - lo que ya está disponible
En esta sección, voy a explicar un poco lo que ya está hecho y cómo puedes aprovecharlo tú y tu empresa.
Todo el código está disponible para consultar, clonar o descargar en mi Github.
Empezar a utilizarla es muy sencillo, solamente hay que clonar o descargar el repositorio en la carpeta que prefieras y configurar para tu instancia de IRIS.
Abre el terminal en la carpeta donde quieres clonar el repositorio y usa el comando
git clone https://github.com/heloisatambara/iris-size-django
Entra en la carpeta iris-size-django e instala los requisitos necesarios:
.../iris-size-django > pip install -r requirements.txt
Edita el archivo .../iris-size-django/globalsize/settings.py para personalizar la configuración de la base de datos. No cambies el parámetro ENGINE, debe apuntar a la aplicación de CaretDev, django-iris. Sin embargo, hay que cambiar NAME para el namespace, USER y PASSWORD para un usuario con los privilegios adecuados (se requiere acceso al namespace %SYS y poder crear una tabla en el namespace deseado) y los parámetros HOST y PORT deben apuntar a tu instancia.
De vuelta al terminal, vamos a ejecutar los comandos makemigrations para preparar la aplicación, migrate para crear la tabla donde vamos a almacenar la información de los globals y runserver para poner todo en práctica.
> python manage.py makemigrations
> python manage.py migrate
> python manage.py runserver
Ahora, simplemente abre el enlace http://127.0.0.1:8000/globals/ en un navegador y haz clic en Update. En pocos segundos deberías ver una tabla con todos los namespaces y sus respectivos globals, mostrando la cantidad (en megabytes) de memoria asignada y utilizada, como se ve en la imagen al inicio de esta sección.
Ahora vamos a analizar mejor la parte superior de la foto:
Aquí se pueden ver las opciones de filtros, exportación y ordenación.
Puedes escribir parte del nombre de la base de datos o de los globals para ver resultados específicos, o escribir un número positivo en Size o Allocated para ver resultados por encima de ese valor. Si escribes un número negativo, tendrás los resultados debajo del módulo del valor. Haz clic en Filter para aplicar el filtro.
Selecciona el modelo de exportación (CSV, XML, JSON) y haz clic en Export para exportar a la carpeta iris-size-django. Ten en cuenta que los filtros aplicados se reflejarán en la exportación. Además, puedes cambiar la dirección de exportación en el código, en .../iris-size-django/globals/views.py.>
Finalmente, puedes seleccionar el orden ascendente en orden alfabético, por el nombre de la base de datos y del global o por el espacio ocupado o por la cantidad asignada. Haz clic en Filter para efectuar la ordenación y los filtros aplicados. Nota: la ordenación no se reflejará en la exportación.
Al final de la página se puede ver el recuento de globals dentro de los filtros seleccionados, además de la cantidad total asignada y utilizada:
Si quieres hacer análisis más detallados o incluso ver la tabla original, una buena opción es entrar en el portal de administración de la instancia referida en settings.py, en la sesión de SQL y seleccionar el namespace referido en el mismo lugar. La tabla habrá sido creada automáticamente por Django con el nombre de SQL_User.globals_iglobal, y ahí puedes usar las herramientas de InterSystems para ejecutar todo tipo de consultas.
Nota: en settings.py, el parámetro DEBUG está marcado como TRUE, porque aún está en desarrollo.
Ideas futuras
Mis próximas ideas son añadir más funciones al portal. Actualmente es posible modificar configuraciones de exportación y de la base de datos directamente en el código, además de realizar consultas más complejas a través del portal de IRIS. Sin embargo, creo que unificar todo eso en el portal puede ser más eficiente. Además, también estoy estudiando añadir un siguimiento del flujo de datos por período.
Por fin, me gustaría saber vuestra opinión: ¿Creéis que ese tipo de aplicación puede ayudar a vuestros negocio? ¿Qué otras funciones os gustaría ver aquí? ¿Os gustaría ver alguna función ya existente de IRIS de manera más amigable? ¿O preferiríais que algo presentado aquí fuera más simple?
Artículo
Ariel Arias · 22 nov, 2022
Disclosure Statement: Sugerencias para relalizar pruebas en ambientes usados para demostraciones o desarrollos, no en ambientes productivos.
Caso de uso: teniendo IAM, lo ejecutamos desde un archivo YML, y necesitamos que se conecte a una Instancia IRIS en seguida, pero IRIS tiene deshabilitado el usuario IAM y la aplicación IAM.
Alternativa: Modificamos el archivo YAML para agregar la imagen IRIS / IRIS for Health que queremos utilizar, nos aseguramos que usen la misma red; ya sea que la hemos definido previamente y queremos acoplar estas nuevas imágenes a esta red, o creamos una nueva para aislar estas nuevas imágenes en un ambiente propio; y lo principal: ejecutamos un script para habilitar el usuario y la aplicación IAM de modo que al iniciar quede todo el ambiente operativo.
Requisito: Acceso a WRC para descarga de imagen de IAM (IRIS API Manager) Distribution page
PASO A PASO
Lo primero es comentar que la primera vez que quise usar el script que viene con el mismo instalador, me encontré con dos inconvenientes (para mi, es probable que quien tiene mayor conocimiento de Docker y Kubernetes no lo vea como inconveniente) y es que, por un lado, quería conectar este IAM con una instancia de IRIS que ya estaba en ejecución y con algunas API desarrolladas, entonces esperaba que fuera "ejecutar y conectar", y me percaté que:
- El usuario IAM y la aplicación IAM de mi instancia están deshabilitados.
- Al momento de ejecutar con "docker compose up -d", se crea una nueva red con el nombre "scripts_default", entonces si quiero que se comunique con mi instancia (otra imagen docker de IRIS en otra red llamada "irisenv-net" debo ejecutar unos pasos adicionales.
Una alternativa que encontré y me llevó a escribir este artículo, es, primero crear una red en docker que será utilizada en adelante por mis imagenes
docker network create -d bridge irisenv-net
Y luego modificar el docker-compose.yml para utilizar una red ya creada por docker y que usan otras imagenes en ejecución, para ello, agregué al archivo lo siguiente:
networks:
irisenv-net:
external: true
Con esto, las imagenes que usen la red "irisenv-net" se comunicarán entre ellas sin pasos adicionales. Entonces para cada imagen del archivo, agregué también:
networks:
- irisenv-net
Me quedaba pendiente lo del usuario y aplicación IAM, que al ser una instancia ya en ejecución debía ejecutar manualmente tanto la habilitación como el establecer la contraseña que usaría mi usuario IAM, pues hay que pasarle ese parámetro al script.
Pero, ¿Si no está en ejecución?, ¿Puedo desde un mismo script levantar una imagen de IRIS, al mismo tiempo que levanto el IAM y que queden automáticamente conectadas y además el IAM tome la licencia existente en IRIS?: Mi respuesta fue SI. De la siguiente forma:
- Agregar en un mismo archivo (docker-iris.yml por ejemplo) la llamada a la imagen de IRIS que voy a utilizar, luego las que requiere IAM y las de IAM debo hacerlas depender de IRIS, entonces es un paso de copiar y pegar y modificar para dejar todo establecido.
Hasta acá tenemos un archivo que al ser ejecutado iniciará 4 imagenes: IRIS, IAM-MIGRATION, IAM y DB
Entonces, ¿Cómo resolvemos que al iniciar la instancia de IRIS, además de cargar la licencia, habilite el usuario IAM con una contraseña que conozco y puedo pasarle como parámetro al IAM, y además se habilite la aplicación IAM?. Respuesta: con un script que se ejecute al momento de iniciar la imagen de IRIS, es decir, tenemos un archivo docker llamado "irisdpfile" que contiene el detalle de la imagen que usaremos y agregamos la llamada al script.
El script que vamos a utilizar:
zn "%SYS"
Do ##class(Security.Users).UnExpireUserPasswords("*")
set st=$SYSTEM.Security.ChangePassword("IAM","iampassword")
set iamuser = ##class(Security.Users).%OpenId("iam")
set iamuser.Enabled = 1
set iamuser.AccountNeverExpires = 1
Set st = iamuser.%Save()
Set iamapp = ##class(Security.Applications).%OpenId("/api/iam")
Set iamapp.Enabled = 1
Set st = iamapp.%Save()
zn "USER"
Si vemos el detalle, en este archivo, habilitamos los usuarios que puedan estar expirados (por ejemplo el "superuser"); luego establecemos una nueva password para el usuario IAM y finalmente habilitamos la aplicación "/api/iam".
Este archivo, lo guardé en el mismo directorio desde donde estoy ejecutando el "docker-iris.yml" y lo nombré: "enableirisuser.script"
De esta forma, desde el dockerfile de IRIS (irisdpfile) agregué las líneas:
USER irisowner
COPY ./enableirisuser.script /tmp/enableirisuser.script
RUN iris start IRIS \
&& iris session IRIS < /tmp/enableirisuser.script \
&& iris stop IRIS quietly
USER irisowner
Nota: Deben quedar en una misma línea de ejecución el iniciar la instancia y llamada al script, me pasó que quise hacer todo por separado y no me dio resultado.
Así, logré desde un mismo archivo, levantar una instanacia de IRIS y de IAM, donde IAM lograba comunicarse con IRIS sin problema y dejar en seguida habilitada la licencia para poder crear workspaces, ambiente de desarrolladores, y todo lo que sea necesario desde IAM.
docker-compose -f docker-iris.yml up -d
Les comparto cómo quedó mi archivo yml finalmente:
version: "3.7"
services:
irishost:
depends_on:
- irishealth
build:
context: .
dockerfile: irisdpfile
container_name: irishost
volumes:
- type: bind
source: ./Licencias/
target: /licencias
- type: bind
source: ../sharingweb/T2017/
target: /common_shared
- type: bind
source: ./wwwshared/
target: /wwwfiles
command: --key /licencias/iris.key --check-caps false
environment:
IRIS_MASTER_HOST: APPTNOTSrv # DNS based on the name of the service!
IRIS_MASTER_PORT: 51773
IRIS_MASTER_USERNAME: SuperUser
IRIS_MASTER_PASSWORD: SYS
IRIS_MASTER_NAMESPACE: APPINT
IRIS_USERNAME: SuperUser
IRIS_PASSWORD: sys
WEBGW_HOST: webgateway2022
IRIS4H_HOST: irishealth
ports:
- "3071:1972" # 51773 is the superserver default port
- "3072:52773" # 52773 is the webserver/management portal port
- "3171:53773" # 53773 is the JDBC Gateway port
tty: true
links:
- irishealth:irishealth
networks:
- irisenv-net
iam-migrations:
depends_on:
- db
image: intersystems/iam:2.8.1.0-3
container_name: iam-migrations
hostname: iam-migrations
command: kong migrations bootstrap
environment:
KONG_DATABASE: postgres
KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
KONG_PG_HOST: db
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
KONG_PG_USER: ${KONG_PG_USER:-iam}
KONG_CASSANDRA_CONTACT_POINTS: db
ISC_IRIS_URL: 'IAM:iampassword@irishost:52773/api/iam/license'
ISC_CA_CERT: ${ISC_CA_CERT}
restart: on-failure
links:
- db:db
restart: on-failure
networks:
- irisenv-net
iam:
depends_on:
- irishost
- db
image: intersystems/iam:2.8.1.0-3
container_name: iam
hostname: iam
environment:
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: '0.0.0.0:8001'
KONG_ANONYMOUS_REPORTS: 'off'
KONG_CASSANDRA_CONTACT_POINTS: db
KONG_DATABASE: postgres
KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
KONG_PG_HOST: db
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
KONG_PG_USER: ${KONG_PG_USER:-iam}
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_PORTAL: on
KONG_VITALS: on
KONG_PORTAL_GUI_PROTOCOL: http
KONG_PORTAL_GUI_HOST: 'localhost:8003'
KONG_ADMIN_GUI_URL: 'http://localhost:8002'
ISC_IRIS_URL: 'IAM:iampassword@irishost:52773/api/iam/license'
ISC_CA_CERT: ${ISC_CA_CERT}
irishost: '172.26.0.2'
ports:
- target: 8000
published: 8000
protocol: tcp
- target: 8001
published: 8001
protocol: tcp
- target: 8002
published: 8002
protocol: tcp
- target: 8003
published: 8003
protocol: tcp
- target: 8004
published: 8004
protocol: tcp
- target: 8443
published: 8443
protocol: tcp
- target: 8444
published: 8444
protocol: tcp
- target: 8445
published: 8445
protocol: tcp
restart: on-failure
networks:
- irisenv-net
links:
- db:db
db:
image: postgres:9.6
container_name: db
hostname: db
environment:
POSTGRES_DB: ${KONG_PG_DATABASE:-iam}
POSTGRES_PASSWORD: ${KONG_PG_PASSWORD:-iam}
POSTGRES_USER: ${KONG_PG_USER:-iam}
volumes:
- 'pgdata:/var/lib/postgresql/data'
healthcheck:
test: ["CMD", "pg_isready", "-U", "${KONG_PG_USER:-iam}"]
interval: 30s
timeout: 30s
retries: 3
restart: on-failure
networks:
- irisenv-net
depends_on:
- irishost
stdin_open: true
volumes:
pgdata:
external: true
networks:
irisenv-net:
external: true
Y el "irisdpfile":
FROM intersystems/iris:2022.1.0.209.0
LABEL maintainer="Ariel Arias <ariel.arias@intersystems.com>"
USER root
RUN apt-get -y update
# Install some aditional software may be needed later
RUN apt-get install -y vim nano net-tools unzip wget sudo iputils-ping links
RUN echo "FROM IRISDPFILE"
USER irisowner
COPY ./Licencias/iris4h2023.key /usr/irissys/mgr/iris.key
COPY ./enableirisuser.script /tmp/enableirisuser.script
RUN iris start IRIS \
&& iris session IRIS < /tmp/enableirisuser.script \
&& iris stop IRIS quietly
USER irisowner
# add default health check
HEALTHCHECK --interval=1m --timeout=10s --start-period=1m --retries=3 \
CMD /irisHealth.sh || exit 1
USER irisowner
EXPOSE 1972
EXPOSE 52773
EXPOSE 53773
Artículo
Nancy Martínez · 25 sep, 2020
Método: para descargar el archivo FTP desde Caché de InterSystems: Si tienes cualquier consulta, deja un mensaje por favor:
ClassMethod FTPDownload(myFTP = "", myUserName = "", myPassword = "", sFileLocation = "", dLocation = "", noOfdownloadFile = 1, sourceFileDel = 0){ /*--------------------------------------------------------------------------------------------------------------------------- descargar el archivo según los requirimientos: FTP
Método: Resuable
creado por: Sanjib Raj Pandey el 30/03/2018
downLoadFile = Número de archivos o todos los archivos ...... que quieras descargar; EL VALOR PREDETERMINADO ES 1 = indica un valor, por ej. 1,3,7,100 archivos = escribe "*" para descargar todos los archivos. SourceFileDel = Si quieres eliminar los arhivos del directorio de origen después de la descarga..... entonces configura el valor 1 -- ; el valor predeterminado es: 0 1= True (elimina el archivo de la carpeta de origen después de la descarga), 0 = False (solo copiar) sFileLocation = Ubicación de origen del archivo (carpeta) dLocation = Carpeta de destinoEjemplo: La siguiente línea ..... mueve todos los archivos desde el origen a la ubicación de destino w ##class(CW.COMMON).FTPDownload("Dirección IP","Usuario","Password","Ruta origen","Ruta destino,"*",1) La siguiente línea...... copia 200 archivos desde la carpeta de origen a la de destinow ##class(CW.COMMON).FTPDownload("Dirección IP ","Usuario","Password","Ruta origen","Ruta destino",200,0)
------------------------------------------------------------------------------------------------------------------------- */ // puedes configurar el control de errores a, por ejemplo, Try and Catch Set (count,fileNo,key,messge,fileStream,myFileName,myFile,fSave,eMessage,eSubject)="" Set fIp= myFTP Set fUserName= myUserName set fPassword=myPassword set sFileLocaion=sFileLocation set dLocation=dLocation Set downloadFile=noOfdownloadFile Set sourceFileDel=sourceFileDel If $Length(fIp)=0||($L(fUserName)=0)||($L(fPassword)=0) || ($L(downloadFile)=0) Q "Credenciales inválidas o el archivo de descarga es 0.!, verifica la IP, Usuario, password o Ubicación o destino del FTP!" Set myFtp=##class(%Net.FtpSession).%New() Set eMessage="La conexión FTP falló, por favor comprueba "_fIp_" o el usuario, password.!" Set eSubject ="Mensaje de advertencia de FTP." Set myFtp.Timeout = 60 If 'myFtp.Connect(fIp,fUserName,fPassword) Quit w $$EVEMAIL^CW.COMMON(eSubject,eMessage) Do myFtp.SetDirectory(sFileLocaion) If 'myFtp.NameList(" ",.x) Quit "Fichero(s) no encontrados " Set fileStream = ##class(%Stream.FileBinary).%New() Set message ="copiado" Set myFileName="" Set fileNo=0 Set Key="" If (downloadFile = "*") { While (x.GetNext(.Key))'="" { Do StartCopy }Do myFtp.Logout()Quit fileNo_" Fichero(S) se han "_message_"con éxito !" } If (downloadFile >0) { Set count=1 While ((count <= downloadFile) && (count<=x.Count())) { do StartCopy Set count=count +1 } Do myFtp.Logout() Quit fileNo_" Fichero(S) se han "_message_"con éxito !" } StartCopy Set myFileName= x.GetNext(.fileNo) Do myFtp.Binary() Do myFtp.Retrieve(myFileName,.fileStream) Set myFile= ##class(%Library.FileBinaryStream).%New() Set myFile.Filename=dLocation_myFileName Do myFile.CopyFrom(fileStream) Set fSave=myFile.%Save() IF ((sourceFileDel=1) && (fSave = 1)) { Do myFtp.Delete(myFileName) Set message="Movidos"}
Artículo
Ricardo Paiva · 28 oct, 2021
¡Hola comunidad!
En el pasado, la documentación técnica del código fuente y de los productos de software se generaba en archivos chm, pdf y generadores de documentación de los propios lenguajes de programación. Este enfoque antiguo tenía las siguientes limitaciones:
Documentación obsoleta,
Documentación no interactiva y difícil de consultar,
Diseño poco amigable y que no se adhiere a HTML,
Imposibilidad de personalizar el diseño de los documentos,
Imposibilidad de tener documentación en HTML 5 online y offline.
Falta de soporte a Markdown.
Hoy en día, existen varias soluciones de generación de documentación que producen Portales de Documentación Web muy atractivos, interactivos y con opciones estáticas y dinámicas, con soporte total para HTML 5 y más recientemente Markdown.
Consulta la tabla con las opciones de código abierto más populares:
Documentation Product
Stars
MkDocsGithub Repo: https://github.com/mkdocs/mkdocs
Static and dynamic documentation generation
Simple and lightweight and built in Python
Smart full-text search box
Multiple themes and plug-ins
Support to Markdown and HTML
Integration with Git pages
Extensible using Python
SPA architecture
11.4k
DocsifyGithub Repo: https://github.com/docsifyjs/docsify
No statically built html files
Simple and lightweight (~21kB gzipped)
Smart full-text search plugin
Multiple themes
Useful plugin API
Compatible with IE11
Support SSR
Support embedded files
16.5k
DocusaurusGithub: https://github.com/facebook/docusaurus/
Powered by Markdown
Built Using React
Ready for Translations
Document Versioning
Document Search
Quick Setup
21.4k
SlateGithub: https://github.com/slatedocs/slate
Clean, intuitive design
Single page documentation
Markdown support
Out-of-the-box syntax highlighting
Write code samples in multiple languages
Automatic, smoothly scrolling table of contents
Documentation is editable by users via Github
RTL Support
31.9k
GitBookhttps://www.gitbook.com/
Clean, intuitive design
Collaborative work/text edition
Support to drafts and versioning
Single page documentation
Markdown support
Out-of-the-box syntax highlighting
Write code samples in multiple languages
Automatic, smoothly scrolling table of contents
The better integration with Github
Multiple output formats (PDF, HTML5, epub,etc.)
Cloud hosting, with free plans to personal projects and paid plans to business use cases
500,000 users
La aplicación IRIS Publisher, en Open Exchange, permite extraer bloques de documentación XData en HTML o Markdown y generar un sitio web con la documentación de tu app, utilizando MkDocs. Consulta las instrucciones en el siguiente artículo de esta serie:
Cómo crear el Portal de Documentación para InterSystems IRIS
Referencia:
5 free static documentation generators you must check out
Artículo
Ricardo Paiva · 16 sep, 2021
Como ayuda para aquellos que quieren utilizar las funciones de la [Base de datos documental](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GDOCDB_intro) (DocDB) dentro de InterSystems IRIS, y específicamente la [API REST](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GDOCDB_rest) que proporciona, reuní una [Colección](https://www.postman.com/product/api-client/) [Postman](https://www.postman.com/collection/) que ofrece muestras para varias llamadas básicas.
Por ejemplo:
.png)
En el ejemplo se utilizan documentos de "Color", por ejemplo, Rojo, Azul, etc., utilizando una estructura JSON de muestra desde [aquí](https://www.sitepoint.com/colors-json-example/).
La Colección incluye llamadas de diferentes "categorías":
* Crear metadatos: crear la base de datos y las propiedades relacionadas
* Obtener metadatos: entender qué bases de datos y propiedades están definidas
* CUD: crear/actualizar/eliminar documentos
* Buscar y obtener documentos: recuperar documentos según el ID o ciertos valores o criterios
* Eliminar metadatos: eliminar propiedades o bases de datos
El orden de las solicitudes en la Colección tiene cierta lógica interna (por ejemplo, primero crear la base de datos y las propiedades, luego insertar algunos datos y después recuperarlos), pero por supuesto puedes utilizarlos en el orden o los cambios que desees.
El orden también funciona bien si se ejecuta [Collection Runner](https://learning.postman.com/docs/running-collections/intro-to-collection-runs/) de Postman. Añadí algunos [scripts de prueba](https://learning.postman.com/docs/writing-scripts/test-scripts/) básicos, que permiten que Postman muestre el estado Aprobado o Fallido para cada llamada.
Por ejemplo:
.png)
Ten en cuenta que la última llamada **elimina todas las bases de datos de documentos dentro de un Namespace**, así que no ejecutes esto a menos que realmente quieras hacerlo... no lo hagas manualmente y tampoco como parte de la ejecución de toda la Colección.
Para conseguir que las llamadas funcionen en varios entornos, utilicé la función [variables](https://learning.postman.com/docs/sending-requests/variables/) de Postman.
Esto permite cambiar el nombre/la IP del servidor, el puerto y el namespace -
.png)
Así que cada llamada se parece a esto:
.png)
Seguramente también necesitarás adaptar la parte de autenticación.
Actualmente tengo "Basic Authentication" simplemente con "SuperUser" y "sys":
.png)
Solo para añadir un _**cambio "multimodelo"**_ a esto, aquí también hay un ejemplo de acceso a estos datos a través de SQL:
Esta es la estructura de la tabla (como se ve en la extensión SQL Tools en VSCode):
.png)
Este es un resultado SELECT sencillo:
.png)
Y aquí hay un SELECT con una cláusula WHERE sobre una de las propiedades que definimos:
.png)
Pregunta
Yone Moreno · 28 mar, 2022
Buenos días,
Agradeceríamos el apoyo de ustedes:
Desarrollando una integración para realizar un circuito "Query / Retrieve" con estudios de imágenes médicas DICOM, necesitaríamos lo siguiente:
Opciones de invocación del servicio DICOM TCP que se ha publicado para esta integración, alternativas a la opción por linea de comando
En concreto hemos leído: Recibir documento DICOM con un PDF embebido y metadatos
Adaptando el ejemplo, empleamos la línea:
./storescu -b VNAPRE -c ESBPRE@10.136.4.XYZ:19ABC ./embeddedpdf.dcm
Mediante la cual simulamos el envío de un documento DICOM con un PDF
Sin embargo, esto no nos es fructífero, provechoso o de solución, ya que lo que se necesita actualmente, es simular consultas del tipo "FIND".
En concreto necesitaríamos consultas del tipo "Obtener Resultados a nivel de Estudios" StudyRootQuery - FIND u "Obtener Estudios a nivel de Pacientes" PatientRootQuery - FIND
// StudyRootQuery - FIND
set tAffectedSOPClassUID="1.2.840.10008.5.1.4.1.2.2.1"
// PatientRootQuery - FIND
;set tAffectedSOPClassUID="1.2.840.10008.5.1.4.1.2.1.1"
Hemos indagado cómo simular las llamadas FIND: Query / Retrieve scenario
En particular probamos desde la "Salida" del Studio enviando el expediente del paciente en el campo "PatientID" del "DataSet" del documento DICOM:
do ##class(DICOM.BS.QueryService).TestFind("13168299")
Y de esta forma simularíamos una llamada al Servicio "dummy" cuya clase es: DICOM.BS.QueryService
Sin embargo, ¿ qué opciones de invocación del servicio DICOM TCP que se ha publicado para esta integración existen ?
¿ Existe un SoapUI / POSTMAN / herramienta línea comando y/o visual, que nos permita simular comandos FIND de DICOM por TCP ?
Gracias por leernos y por sus respuestas
Además hemos leído:
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_intro#EDICOM_intro_samples
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_storage_production
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_associations
https://es.community.intersystems.com/post/dicom-no-hay-asociaci%C3%B3n-activa-para-calling-aet-yyy-y-called-aet-aaa-%E2%B8%98-%E2%80%BD
https://community.intersystems.com/post/dicom-tcp-services-and-dicom-implementation-details-ensemble
A nivel visual, ahora estamos probando el circuito mediante un Servicio "dummy", cuya clase es: DICOM.BS.QueryService
Sin embargo, necesitamos encontrar la vía de simular ser el sistema origen, es decir, probar el servicio TCP, siendo de la clase: EnsLib.DICOM.Service.TCP
¿ Qué opciones de invocación del servicio DICOM TCP que se ha publicado para esta integración, alternativas a la opción por linea de comando, existirían ?
¿ De qué forma lo harían ustedes ?
¿Disponen de ejemplos, documentación, código, referencias o indicaciones que pudieran servir de apoyo?
Muchas gracias de antemano
Un saludo Hola Yone,
Imagino que te refieres al ejemplo https://github.com/intersystems-ib/iris-dicom-sample
Los comandos C-FIND son mensajes DICOM que deben tener el formato correcto y transmitirse usando el protocolo DICOM. Por eso, o usas un simulador, o generas ese mensaje desde Ensemble / Health Connect.
En el ejemplo, el comando do ##class(DICOM.BS.QueryService).TestFind() provoca la generación de un mensaje C-FIND dentro de la producción para un paciente concreto.
El simulador dcm4che tiene la utilidad findscu que permite simular la generación de mensajes C-FIND.
Artículo
Muhammad Waseem · 8 ago, 2022
La aplicación Carbon Footprint Counter utiliza el GHG Protocol para medir las emisiones de carbono en las empresas. El Protocolo de Gases de Efecto Invernadero (GHG Protocol) establece marcos estandarizados globales integrales para medir y gestionar las emisiones de gases de efecto invernadero (GHG) de las operaciones del sector público y privado, las cadenas de valor y las acciones de mitigación.
Sobre la base de una asociación de 20 años entre el Instituto de Recursos Mundiales (WRI) y el Consejo Empresarial Mundial para el Desarrollo Sostenible (WBCSD), el GHG Protocol trabaja con gobiernos, asociaciones industriales, ONGs, empresas y otras organizaciones. (fuente: https://ghgprotocol.org/about-us).
La aplicación Carbon Footprint Counter utiliza InterSystems IRIS para implementar APIs REST y la base de datos SQL para administrar el inventario de emisiones de carbono en las empresas. La interfaz es Angular 12 con el framework PrimeNG (líder de código abierto para Angular).
Factores de emisión
Para medir las emisiones de carbono de la empresa, la aplicación almacena 300 factores de emisión distribuidos en 4 segmentos (inmóvil, móvil, transporte y electricidad comprada). Cada factor, como el gas natural, la gasolina, el transporte en autobús, el transporte aéreo, los viajes en automóvil, etc., tiene valores de referencia para calcular las emisiones de co2, ch4 y n2o. Así:
Emisiones inmóviles (stationary)
El GHG Protocol define inmóvil como el consumo de combustible en una instalación para producir electricidad, vapor, calor o energía. La combustión de combustibles fósiles por parte de calderas de gas natural, generadores diésel y otros equipos emite dióxido de carbono, metano y óxido nitroso a la atmósfera. Puedes registrar tus emisiones inmóviles en el menú y la ventana de Combustión inmóvil (Stationary Combustion):
Emisiones de combustión móvil
El GHG Protocol define la combustión móvil como el consumo de combustible de los vehículos que son propiedad de la empresa o alquilados. La combustión de combustibles fósiles en vehículos (incluyendo automóviles, camiones, aviones y barcos) emite dióxido de carbono, metano y óxido nitroso a la atmósfera. Puedes registrar tus emisiones móviles en el menú y la ventana de Combustión móvil:
Emisiones del transporte
El GHG Protocol define el transporte como el consumo de combustible de los vehículos utilizados para realizar viajes de empresa. Los ejemplos incluyen viajes aéreos comerciales y el uso de vehículos alquilados durante viajes de negocios. Puedes registrar tus emisiones de transporte en el menú y la ventana de Transporte:
Emisiones de electricidad
El GHG Protoco define las emisiones de electricidad como energía comprada a las empresas de servicios locales (no se quema en el sitio). Los ejemplos incluyen electricidad, vapor y agua fría o caliente. Para generar esta energía, las empresas de servicios queman carbón, gas natural y otros combustibles fósiles, emitiendo dióxido de carbono, metano y óxido nitroso en el proceso. Puedea registrar tus emisiones de electricidad en el menú y la ventana de Emisiones de electricidad:
Cálculo de las emisiones totales de carbono
La aplicación computa todas las emisiones registradas:
Pasar a la acción
Ahora, tu empresa puede saber sus emisiones de carbono anuales y tomar medidas para compensar las emisiones. Se pueden comprar créditos de carbono, hacer donaciones a WWF, Greenpeace u otras instituciones...
Calcúlalo ahora usando https://openexchange.intersystems.com/package/Carbon-Footprint-Counter.