#InterSystems IRIS for Health

0 Seguidores · 307 Postagens

InterSystems IRIS for Health™ é a primeira e única plataforma de dados do mundo projetada especificamente para o rápido desenvolvimento de aplicações de saúde, para gerenciar os dados mais críticos do mundo. Inclui poderosos recursos prontos para uso: processamento e análise de transações, um modelo de dados de saúde extensível, desenvolvimento de solução baseada em FHIR, suporte para padrões de interoperabilidade em saúde e muito mais. Tudo isso permitindo que os desenvolvedores percebam valor e criem aplicações inovadoras, rapidamente. Saber mais.

Artigo Larissa Prussak · Fev. 14, 2024 1m read

Rubrica de perguntas frequentes da InterSystems

No Linux, siga as etapas a seguir para excluir uma instância do InterSystems IRIS (doravante denominada IRIS).

(1) Pare a instância IRIS que você deseja desinstalar usando iris stop 

# iris stop <instance name>

(2) Exclua as informações da instância usando o seguinte comando

# iris delete <instance name>

(3) Exclua o diretório de instalação do IRIS usando o comando rm -r 

# rm -r <install directory>

Além do diretório de instalação, o IRIS também usa (a) e (b) abaixo.

0
0 122
Artigo Larissa Prussak · Fev. 14, 2024 3m read

Após dois Webinars locais, focamos no VS Code ["Intro" e "Beyond Basics"; em hebraico], preparei para os participantes alguns links relacionados de recursos relevantes que enviamos como acompanhamento. Compartilhando-os aqui também para o benefício da Comunidade.
É claro que todos vocês são bem-vindos para adicionar mais recursos úteis.

0
0 88
Artigo Danusa Calixto · jan 26, 2024 3m read

De acordo com o Databricks, Apache Parquet é um formato de dados de código aberto orientado por colunas que é projetado para o armazenamento e recuperação de dados eficiente. Ele fornece esquemas eficientes de compactação e codificação de dados com um desempenho aprimorado para lidar com dados complexos em massa. O Apache Parquet foi criado para ser um formato de troca comum para ambas as cargas de trabalho em lote e interativas. É semelhante a outros formatos de arquivo de armazenamento colunar disponíveis no Hadoop, especificamente, RCFile e ORC. (fonte: https://www.databricks.com/glossary/what-is-parquet). Confira abaixo as características e os benefícios do Parquet de acordo com o Databricks:

Características do Parquet

  • Formato de arquivo gratuito e de código aberto.
  • Agnóstico a linguagens.
  • Formato baseado em colunas: os arquivos são organizados por coluna, e não por linha, o que economiza armazenamento e acelera as consultas de análise.
  • Usado para casos de uso de análise (OLAP), geralmente, em conjunto com bancos de dados OLTP tradicionais.
  • Compressão e descompressão de dados altamente eficiente.
  • É compatível com tipos de dados complexos e estruturas de dados aninhadas avançadas.

Benefícios do Parquet

  • É bom para armazenar big data de qualquer tipo (imagens, vídeos, documentos e tabelas de dados estruturados).
  • Economiza armazenamento na nuvem ao usar uma compressão de colunas altamente eficiente e esquemas de codificação flexíveis para colunas com diferentes tipos de dados.
  • Taxa de transferência de dados mais alta e melhor desempenho usando técnicas como data skipping, onde as consultas que buscam valores específicos de colunas não precisam ler toda a linha de dados.

Um padrão tão importante quanto esse não poderia ser deixado de fora do InterSystems IRIS, o melhor Data Fabric no mercado. Portanto, agora é possível usar o aplicativo iris parquet (https://openexchange.intersystems.com/package/iris-parquet) para ler e escrever dados parquet.

Procedimentos para instalação

Instalação com Docker

1. Faça o git pull/clone do repositório em qualquer diretório local:

$ git clone https://github.com/yurimarx/iris-parquet.git

2. Abra o terminal nesse diretório e chame o comando para compilar e executar o InterSystems IRIS no contêiner:

$ docker-compose build$ docker-compose up -d

Instalação com ZPM

1. Execute no terminal:

USER> zpm install iris-parquet

2. Instale os arquivos do hadoop e defina a variável ENV como HADOOP_HOME:

wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz && \
    tar -xzf hadoop-3.3.6.tar.gz && \
    echo "export HADOOP_HOME=//hadoop-3.3.6"

Escreva Parquet a partir do SQL

Há duas opções, a partir do ObjectScript ou da API REST:

1. Do ObjectScript (sample: mude pelos seus valores):

Set result = ##class(dc.irisparquet.IrisParquet).SQLToParquet(
        "personSchema",
        "persons",
        "jdbc:IRIS://localhost:1972/IRISAPP",
        "SELECT * FROM dc_irisparquet.SamplePerson",
        "/tmp/sample.parquet"
    )

2. Da API REST:

Ler Parquet para JSON

Há duas opções, a partir do ObjectScript ou da API REST:

1. Do ObjectScript (sample: mude pelos seus valores):

Set result = ##class(dc.irisparquet.IrisParquet).ParquetToJSON(
        "/tmp/"_source.FileName,
        "/tmp/content.json"
        )

2. Da API REST:

0
0 361
Artigo Danusa Calixto · jan 24, 2024 3m read
Cenário

O IRIS tem adaptadores de entrada SQL para uso com SQL gateways, como EnsLib.SQL.InboundAdapter, para consultar repetidamente as conexões do SQL Gateway. Surgiu uma situação em que queríamos consultar alguns dados em um banco de dados interno, mas não encontramos um serviço pronto para uso com essa finalidade. 

Abordagem desejada

Tenha um Serviço genérico que possa pesquisar o SQL interno para trabalhar com componentes downstream.

Como

O que não ficou claro era "Como envio um conjunto de resultados downstream". Não estava muito claro porque o próprio resultset não é uma classe persistente, e o objeto não pode ser "Convertido" em um erro assim 

 <METHOD DOES NOT EXIST>zNewRequestMessage+4^Ens.MessageHeader.1 *%GetSwizzleObject,%sqlcq.SRFT.cls535 -- logged as '-'
number - @''

A solução era usar o objeto 

EnsLib.SQL.Snapshot

Isso pode ser usado como uma operação de negócios para enviar um resultset downstream ao usar a função Import from resultset (Importar de resultset)

set result=##class(EnsLib.SQL.Snapshot).%New()
// Uma consulta SQL aqui resultando em resultset onde rset é objeto resultsetset tSC=result.ImportFromResultSet(rset)

Depois, você pode enviar isso para outra operação 

set tSC=..SendRequestAsync(..ForwardComponentName,result,0)  Quit:$$$ISERR(tSC)

 

Observe no código carregado no open exchange, disponível aqui pelo github. Você pode abrir e consultar o exemplo. Abaixo está o classmethod usado para colocá-lo em um html. É um pouco diferente do exemplo publicado, já que foi tirado de uma implementação ativa. 

ClassMethod GetDataTable(pRequest As EnsLib.SQL.Snapshot, html As%String) As%String
{
  //o primeiro obj html pode ser se o estilo precisa ser passadoif$ISOBJECT(html){set html=""}
  //loop para obter títulos das colunas set ColumnIteration=1set ColumnCount=pRequest.%ResultColumnCountGet()

set html=html_" <table class=""tg"">"set html= html_ " " _"<tr>"set meta=pRequest.%GetMetadata() //é como o texto bruto do resultado usando-o para tirar os títulos das colunasif ColumnCount>0{ while ColumnIteration<=ColumnCount{

  <span class="hljs-keyword">set</span> html= html_ <span class="hljs-string">" &lt;th&gt;"</span>_  meta.columns.GetAt(ColumnIteration).colName _<span class="hljs-string">" &lt;/th&gt;"</span>
  <span class="hljs-keyword">set</span> ColumnIteration=ColumnIteration+<span class="hljs-number">1</span>
}

} set html= html_ " ""</tr>"//não obtenha os dados de cada linha. Em html precisa de um <tr> e td. set coldataiteration=1While pRequest.%Next() { set html= html" <tr>"while coldataiteration <=ColumnCount{ set html= html_ " <td> "_pRequest.%GetData(coldataiteration) _" </td>"set coldataiteration=coldataiteration+1 }

<span class="hljs-keyword">set</span> html= html_ <span class="hljs-string">" &lt;/tr&gt;"</span>
<span class="hljs-keyword">set</span> coldataiteration=<span class="hljs-number">1</span>

} set html= html_ " " _"</table>"$$$TRACE(html) return html }

Sparkei/Internal-SQL-Service: serviço da Intersystems que pode ser usado para consultar uma tabela SQL interna para enviar um instantâneo downstream (github.com)
 

0
0 67
InterSystems Oficial Danusa Calixto · jan 19, 2024

InterSystems anuncia sua primeira prévia, como parte do programa de prévia para desenvolvedores da versão 2024.1. Esta versão incluirá InterSystems IRIS®,  InterSystems IRIS® for HealthTM, e HealthShare® Health Connect.

Destaques

0
0 59
Artigo Danusa Calixto · jan 11, 2024 6m read

Fui desafiado a criar um aplicativo de bot do Azure que possa recuperar e publicar dados no IRIS for Health.

 

Os dados de um paciente já foram registrados no repositório FHIR do IRIS for Health.

O MRN do paciente é 1001. O nome dele é Taro Yamad. (em japonês: 山田 太郎)

Esse bot pode publicar novas leituras de oxímetro como um recurso de observação associado ao paciente.

Visão geral de como o aplicativo de bot funciona abaixo:

 

(1) Em um aplicativo como o Teams, um usuário fala "Hello" (Olá).

O Teams envia a mensagem ao "Serviço de Canal Bot Framework" , hospedado pela Microsoft.

(2) O Serviço de Canal Bot Framework pergunta ao Bot.

O serviço pergunta ao Bot "Where is the endpoint?"(Onde está o endpoint?)

(3) O bot retorna as informações sobre o endpoint ao serviço.

O Bot conhece o endpoint.

(4) O serviço faz a solicitação do usuário ao endpoint.

O endpoint é um web application que é publicado no Azure web app.

(Minha amostra está escrita em Python.)  

​​(5) O endpoint cria a resposta e a envia ao serviço.

(6) O serviço recebe a resposta do endpoint e a passa ao usuário.

O IRIS não apareceu no fluxo acima.

Adicionei uma chamada do web application em python para a interoperabilidade do IRIS for Health. E preparei o repositório FHIR no IRIS assim:

 

A amostra de interoperabilidade do IRIS está aqui 👉 https://github.com/iijimam/iris-teams-interop

Você pode compilar e iniciar o contêiner com "docker-compose up -d". (Ele inclui os dados do paciente de amostra (MRN=1001) e as configurações necessárias.) 

Observação: o web application em python precisa chamar aplicativos via https. Mas removi os arquivos de certificado do meu repositório para evitar violar a política do git.

O web application em Python chama a classe dispatch REST do IRIS usando este URL "https://webserveraddress/production/request".

Confira as instruções abaixo para criar um aplicativo de Bot do Azure.

(1) Crie um grupo de recursos no Azure.

(2) Crie um Bot do Azure no grupo de recursos.

Você precisará confirmar seu "MicrosoftAppId" e "MicrosoftAppPassword". Vou explicar isso depois.

Se você quiser usar o bot do Teams, você precisa adicionar o canal do Teams ao bot. (O gif acima usa o canal do Teams.)

(3) Crie um web application no mesmo grupo de recursos que o bot no Azure.

Você obterá o endereço do servidor da web depois de criá-lo.

(4) Defina o endpoint na configuração do bot.

(5) Implante seu código para o web application.

Você pode escolher o repositório Git.

(6) Teste!

Vamos ver os detalhes!

(1) Crie um grupo de recursos no Azure.

Você pode criar um novo grupo de recursos a partir desta página (Grupos de recurso - Microsoft Azure)

Criei um novo recurso "202312ISJBotRG".

(2) Crie um Bot do Azure no grupo de recursos.

Depois de mover o grupo de recursos, você pode selecionar o menu "Create" (Criar).

   

Depois de criar o bot, você precisa definir "New client secret" (Novo segredo do cliente) na página [Configuration] da seguinte maneira:

Anote o caractere secreto e o valor do "Microsoft App ID".

Essas informações são necessárias para definir seu web application.

Se você quiser usar o bot do Teams, adicione o canal do Teams ao seu bot.

Você pode adicionar o canal do Teams usando o menu [Channels] no seu bot. (basta clicar no ícone do Teams.)

 

(3) Crie um web application no mesmo grupo de recursos que o bot no Azure.

Crie um web application para seu grupo de recursos. 

Volte para a página do grupo de recursos. E crie um web application assim:

 

Você pode selecionar sua "Runtime stack" (pilha de camada) favorita (o exemplo é Python 3.8), "Region" (região) e "Pricing plan" (plano de preços).

Depois de criar o aplicativo, você pode obter o endereço do servidor web na página do web application.

Precisamos definir o endereço para o código de aplicativo python. Então anote essa string. (O exemplo é "202312isjbotwebapp.azurewebsites.net")

Em seguida, precisamos definir o id do bot, o segredo e os detalhes de implantação.

Acesse a página [Configuration] na página do web application.

Você precisa adicionar "MicrosoftAppId" e "MicrosoftAppPassword" de "New application setting" (Configuração do novo aplicativo) a "Application settings" (Configurações do aplicativo).

(MicrosoftAppPassword é o segredo do bot que você copia na etapa (2).)

 

Em seguida, precisamos definir as "General settings" (Configurações gerais) para implantação.

 

Usei este código de exemplo 👉https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/44.prompt-for-user-input

O exemplo é simples, e é fácil de entender o que devo escrever sobre a comunicação do web application com o bot.

Atualizei alguns códigos nos diretórios bots e data_models.

Se você for executar o código no ambiente local, não precisa atualizá-lo.

Mas, se você quiser executá-lo no Azure web application, precisa atualizar o código de app.py assim:

definit_func(argv):
    APP = web.Application(middlewares=[aiohttp_error_middleware])
    APP.router.add_post("/api/messages", messages)
    return APP

ifname == "main": try: #web.run_app(APP, host="localhost", port=CONFIG.PORT) web.run_app(APP, host="0.0.0.0", port=CONFIG.PORT) except Exception as error: raise error

Adicionei esta chamada "python3.8 -m aiohttp.web -H 0.0.0.0 -P 8000 app:init_func" para iniciar um web application em Python no Azure.

Se você quiser saber os detalhes, consulte este URL👉https://stackoverflow.com/questions/60507967/running-an-python-app-as-an-azure-web-app

Meu código está aqui 👉 https://github.com/iijimam/teams-bot

Para executá-lo, você precisa atualizar partes do código.

  • Linha  15 e 16 de config.py: você precisa atualizar as informações do seu bot.
  • Linha 10 de GoIRIS.py : você precisa atualizar o endpoint que é o servidor REST do IRIS.

(4) Defina o endpoint na configuração do bot.

Acesse a página Configuration do bot.

Defina o endereço do servidor web + "/api/messages" como "Messaging endpoint".

 

(5) Implante seu código para o web application.

Eu uso o repositório git. É fácil implantar para o web application no Azure!!

Você pode definir as informações na página [Deployment Center] (Centro de implantação) do web application.

Após a implantação, você pode começar a testar!

(6) Teste!

Você pode testar seu aplicativo usando o "Test in Web Chat" (Testar no web chat) na página do bot.

 

Se você adicionar o canal do Teams, pode testar no Teams.

 

Depois de clicar em [Open in Teams] (Abrir no Teams), você pode abrir seu chat do teams e testar.😀

Bônus:

Você pode testar sem implantar seu aplicativo como um web application do Azure.

Quando o aplicativo em python e a interoperabilidade do IRIS estiverem prontos, você pode publicar esse aplicativo usando ngrok assim:

ngrok http 8000 --host-header=172.18.28.1:8000

ngrok pode oferecer um serviço de tunelamento.  Posso acessar minha porta local diretamente da área pública usando o serviço de tunelamento ngrok. 

E precisamos mudar o endpoint na configuração do bot assim:

Depois de configurado, posso testar usando o web chat.

0
0 120
Artigo Danusa Calixto · jan 10, 2024 2m read

No momento, vários artistas digitais usam a tecnologia de IA generativa como apoio para acelerar a entrega das suas obras. Hoje em dia, é possível gerar uma imagem correspondente a partir de uma frase. Há várias soluções no mercado para isso, incluindo algumas disponíveis para uso por APIs. Veja algumas neste link: https://www.analyticsvidhya.com/blog/2023/08/ai-image-generators/.

Criei um novo aplicativo para usar no IRIS aproveitando uma dessas APIs. Escolhi a API Imagine. Ela permite até 50 chamadas gratuitas por dia e tem um pacote pago interessante que possibilita a criação de milhares de imagens por mês. Para assinar a API e obter uma chave de API para usar o serviço, acesse: https://platform.imagine.art/dashboard/auth.

Depois disso, você pode usar meu aplicativo, alterando sua chave, gerar o JAR, copiar para a raiz do meu projeto IRIS e gerar suas imagens. Meu projeto está em https://github.com/yurimarx/imageaicreator.

O Criador de imagens de IA em ação

1. Copie, compile e execute o projeto docker:

git clone https://github.com/yurimarx/imageaicreator.git
$ docker-compose build
$ docker-compose up -d

2. Abra http://localhost:/swagger-ui/index.html. No swagger explore, coloque http://localhost:/image-ai-creator/_spec:

3. Execute o método /generate passando no corpo um texto com instruções para gerar a imagem (em inglês):

4. Baixe o arquivo png no link Download file (Baixar arquivo) e veja os resultados:

5. Veja a imagem para a frase "a ragdoll playing tennis", ou um ragdoll jogando tênis, (a IA sabe que ragdoll é uma raça de gatos, fantástico!):

0
0 85
Artigo Danusa Calixto · jan 4, 2024 8m read

Introdução

Este artigo busca explorar o funcionamento e desenvolvimento do sistema FHIR-PEX, aproveitando os recursos do InterSystems IRIS.

Otimizando a identificação e o processamento de exames médicos nos centros de diagnóstico clínico, nosso sistema visa aumentar a eficiência e precisão dos fluxos de trabalho de saúde. Ao integrar os padrões FHIR ao banco de dados Java-PEX do InterSystems IRIS, o sistema ajuda os profissionais de saúde com recursos de validação e roteamento, melhorando, em última análise, a tomada de decisões e o cuidado dos pacientes.

como funciona

  • Interoperabilidade IRIS: Recebe mensagens no padrão FHIR, garantindo a integração e a compatibilidade com os dados da saúde.

  • Processamento de informações com "PEX Java": Processa mensagens no formato FHIR e as direciona a tópicos do Kafka com base nas regras configuradas globalmente no banco de dados, possibilitando um processamento e roteamento de dados eficiente, especialmente para exames direcionados à quarentena.

  • Tratamento de retornos do Kafka via back-end Java externo: Interpreta apenas os exames direcionados à quarentena, permitindo que o sistema trate os retornos do Kafka por um back-end Java externo. Facilita a geração de insights prognósticos para profissionais da saúde através de IA Generativa, contando com consultas de resultados de exames anteriores dos respectivos pacientes.

Desenvolvimento

Através do PEX (Production EXtension) da InterSystems, ferramenta de extensibilidade que permite aprimoramento e personalização do comportamento do sistema, elaboramos uma Operação de Negócios. Este componente tem a tarefa de processar mensagens recebidas no formato FHIR dentro do sistema. Veja este exemplo:

import com.intersystems.enslib.pex.*;
import com.intersystems.jdbc.IRISObject;
import com.intersystems.jdbc.IRIS;
import com.intersystems.jdbc.IRISList;
import com.intersystems.gateway.GatewayContext;

import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.*;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class KafkaOperation extends BusinessOperation {
// Conexão ao InterSystems IRIS
private IRIS iris;

// Conexão ao Kafka
private Producer<Long, String> producer;

// Endereço do servidor do Kafka (se forem vários, separados por vírgula)
public String SERVERS;

// Nome do nosso Produtor
public String CLIENTID;

/// Caminho para o arquivo Config
public String CONFIG;

public void OnInit() throws Exception {
[...]
}

public void OnTearDown() throws Exception {
[...]
}

public Object OnMessage(Object request) throws Exception {
    IRISObject req = (IRISObject) request;
    LOGINFO("Received object: " + req.invokeString("%ClassName", 1));

    // Crie o registro
    String value = req.getString("Text");
    String topic = getTopicPush(req);
    final ProducerRecord<Long, String> record = new ProducerRecord<>(topic, value);

    // Envie o novo registro
    RecordMetadata metadata = producer.send(record).get();

    // Retorne as informações do regitro
    IRISObject response = (IRISObject)(iris.classMethodObject("Ens.StringContainer","%New",topic+"|"+metadata.offset()));
    return response;
}

private Producer<Long, String> createProducer() throws IOException {
[...]
}

private String getTopicPush(IRISObject req) {
[...]
}

[...]
}

`

Dentro da aplicação, o método getTopicPush assume a responsabilidade de identificar o tópico para o qual a mensagem será enviada.

A determinação do tópico a que a mensagem será enviada depende da existência de uma regra na global "quarantineRule", conforme lido no IRIS.

String code = FHIRcoding.path("code").asText();
String system = FHIRcoding.path("system").asText();

IRISList quarantineRule = iris.getIRISList("quarantineRule",code,system);

 String reference = quarantineRule.getString(1);
 String value = quarantineRule.getString(2);

 String observationValue = fhir.path("valueQuantity").path("value").asText()

Quando há a global ^quarantineRule, a validação do objeto FHIR pode ser validada.

private boolean quarantineValueQuantity(String reference, String value, String observationValue) {
    LOGINFO("quarantine rule reference/value: " + reference + "/" + value);
    double numericValue = Double.parseDouble(value);
    double numericObservationValue = Double.parseDouble(observationValue);

    if ("<".equals(reference)) {
        return numericObservationValue < numericValue;
    }
    else if (">".equals(reference)) {
        return numericObservationValue > numericValue;
    }
    else if ("<=".equals(reference)) {
        return numericObservationValue <= numericValue;
    }
    else if (">=".equals(reference)) {
        return numericObservationValue >= numericValue;
    }
    
    return false;
}

Exemplo prático:

Ao definir uma global, como:

Set ^quarantineRule("59462-2","http://loinc.org") = $LB(">","500") 

Isso estabelece uma regra para o código "59462-2" e o sistema ""http://loinc.org"" na global ^quarantineRule, especificando uma condição em que o valor é definido como quarentena quando ultrapassa 500. No aplicativo, o método getTopicPush pode então usar essa regra para determinar o tópico apropriado para enviar a mensagem com base no resultado da validação.

Dada a atribuição, o JSON abaixo seria enviado para quarentena, porque corresponde à condição especificada por ter:

 {
          "system": "http://loinc.org",
          "code": "59462-2",
          "display": "Testosterone"
}

"valueQuantity": { "value": 550, "unit": "ng/dL", "system": "http://unitsofmeasure.org", "code": "ng/dL" }

Observação FHIR:

{
    "resourceType": "Observation",
    "id": "3a8c7d54-1a2b-4c8f-b54a-3d2a7efc98c9",
    "status": "final",
    "category": [
      {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/observation-category",
            "code": "laboratory",
            "display": "laboratory"
          }
        ]
      }
    ],
    "code": {
      "coding": [
        {
          "system": "http://loinc.org",
          "code": "59462-2",
          "display": "Testosterone"
        }
      ],
      "text": "Testosterone"
    },
    "subject": {
      "reference": "urn:uuid:274f5452-2a39-44c4-a7cb-f36de467762e"
    },
    "encounter": {
      "reference": "urn:uuid:100b4a8f-5c14-4192-a78f-7276abdc4bc3"
    },
    "effectiveDateTime": "2022-05-15T08:45:00+00:00",
    "issued": "2022-05-15T08:45:00.123+00:00",
    "valueQuantity": {
      "value": 550,
      "unit": "ng/dL",
      "system": "http://unitsofmeasure.org",
      "code": "ng/dL"
    }
}

O aplicativo Quarkus Java

Após o envio para o tópico desejado, um aplicativo Quarkus Java foi criado para receber exames em quarentena.

@ApplicationScoped
 public class QuarentineObservationEventListener {

@Inject
PatientService patientService;

@Inject
EventBus eventBus;

@Transactional
@Incoming("observation_quarantine")
public CompletionStage<Void> onIncomingMessage(Message<QuarentineObservation> quarentineObservationMessage) {
	var quarentineObservation = quarentineObservationMessage.getPayload();
	var patientId = quarentineObservation.getSubject()
			.getReference();
	var patient = patientService.addObservation(patientId, quarentineObservation);
	publishSockJsEvent(patient.getId(), quarentineObservation.getCode()
			.getText());
	return quarentineObservationMessage.ack();
}

private void publishSockJsEvent(Long patientId, String text) {
	eventBus.publish("monitor", MonitorEventDto.builder()
			.id(patientId)
			.message(" is on quarentine list by observation ." + text)
			.build());
}
 }

Esse segmento do sistema tem a tarefa de persistir as informações recebidas de Kafka, armazená-las nas observações do paciente no banco de dados e notificar a ocorrência ao monitor.

O monitor

Por fim, o monitor do sistema é responsável por fornecer uma visualização simples do front-end. Isso permite que os profissionais de saúde revisem os dados do paciente/exame e realizem as ações necessárias.

Implementação de langchainPT

Através do monitor, o sistema permite que os profissionais de saúde solicitem recomendações da IA ​​Generativa.

@Unremovable
@Slf4j
@ApplicationScoped
public class PatientRepository {
	@Tool("Get anamnesis information for a given patient id")
	public Patient getAnamenisis(Long patientId) {
		log.info("getAnamenisis called with id " + patientId);
		Patient patient = Patient.findById(patientId);
		return patient;
	}

	@Tool("Get the last clinical results for a given patient id")
	public List<Observation> getObservations(Long patientId) {
		log.info("getObservations called with id " + patientId);
		Patient patient = Patient.findById(patientId);
		return patient.getObservationList();
	}

}

segue implementação de langchain4j

@RegisterAiService(chatMemoryProviderSupplier = RegisterAiService.BeanChatMemoryProviderSupplier.class, tools = {PatientRepository.class})
public interface PatientAI {

	@SystemMessage("""
			You are a health care assistant AI. You have to recommend exams for patients based on history information.
			""")
	@UserMessage("""
			 Your task is to recommend clinical exams for the patient id {patientId}.

			 To complete this task, perform the following actions:
			 1 - Retrieve anamnesis information for patient id {patientId}.
			 2 - Retrieve the last clinical results for patient id {patientId}, using the property 'name' as the name of exam and 'value' as the value.
			 3 - Analyse results against well known conditions of health care.

			 Answer with a **single** JSON document containing:
			 - the patient id in the 'patientId' key
			 - the patient weight in the 'weight' key
			 - the exam recommendation list in the 'recommendations' key, with properties exam, reason and condition.
			 - the 'explanation' key containing an explanation of your answer, especially about well known diseases.

			Your response must be just the raw JSON document, without ```json, ``` or anything else.
			 """)
	String recommendExams(Long patientId);
}

Dessa forma, o sistema pode auxiliar os profissionais de saúde a tomar decisões e realizar ações.

Vídeo de demonstração

VÍDEO

Autores

OBSERVAÇÃO:

O aplicativo https://openexchange.intersystems.com/package/fhir-pex está participando atualmente do InterSystems Java Contest 2023. Sinta-se à vontade para explorar a solução e não hesite em entrar em contato se tiver alguma dúvida ou precisar de informações adicionais. Recomendamos executar o aplicativo em seu ambiente local para uma experiência prática. Obrigado pela oportunidade 😀!

0
0 85
Artigo Danusa Calixto · jan 4, 2024 2m read

Você sabia que pode obter dados JSON diretamente das suas tabelas SQL?

Vou apresentar duas funções SQL úteis que são usadas para recuperar dados JSON de consultas SQL - JSON_ARRAY e JSON_OBJECT
Você pode usar essas funções na instrução SELECT com outros tipos de itens select, e elas podem ser especificadas em outros locais onde uma função SQL pode ser usada, como em uma cláusula WHERE 

A função JSON_ARRAY aceita uma lista separada por vírgula de expressões e retorna um array JSON com esses valores.

SELECT TOP 3Name,
JSON_ARRAY(%ID,%TABLENAME,UCASE(Name),Age,Home_State) "JSON data" 
FROM Sample.Person
Para  omitir propriedades de valores nulos, basta adicionar "ABSENT ON NULL" à função:
SELECT TOP 3Name,
JSON_ARRAY(%ID,%TABLENAME,UCASE(Name),Age,Home_State ABSENT ONNULL
) "JSON data" 
FROM Sample.Person

Para obter essas propriedades de valores nulos, use "NULL ON NULL" em vez disso (e, como isso é o padrão, você pode só não o adicionar como no primeiro exemplo).

Imagem obtendo todos os telefones de pacientes/clientes em um array JSON sem construi-lo​:

SELECT JSON_ARRAY(HomePhone,WorkPhone,Mobile) "JSON data"FROM Test.Phones
["055-8263371","052-4957286","054-4951066"]

A função JSON_OBJECT aceita uma lista separada por vírgulas de pares de chave:valor  e retorna um objeto JSON com esses valores.
Você pode especificar qualquer string entre aspas simples como um nome de chave, mas observe que isso não impõe nenhuma convenção de nomenclatura ou verificação de exclusividade para nomes de chaves.
Para o valor, você pode especificar um nome de coluna ou outra expressão. Além disso, observe que ele não aceita a sintaxe de asterisco (*) como uma forma de especificar todos os campos de uma tabela.

SELECT TOP 3 JSON_OBJECT('title':'Person from’,'country’:UCASE(Home_State),'table':%TABLENAME,'name':Name,'id':%ID,'age':Age) "JSON data" 
FROM Sample.Person

Para omitir as propriedades de valores nulos, basta adicionar "ABSENT ON NULL" à função:

SELECT TOP 3 JSON_OBJECT('title':'Person from’,'country’:UCASE(Home_State),'table':%TABLENAME,'name':Name,'id':%ID,'age':Age ABSENT ONNULL) "JSON data" 
FROM Sample.Person

Para obter essas propriedades de valores nulos, use "NULL ON NULL" em vez disso (e, como isso é o padrão, você pode só não o adicionar).

0
0 135
Artigo Larissa Prussak · jan 3, 2024 1m read

Rubrica de perguntas frequentes da InterSystems

Se vários produtos InterSystems estiverem instalados no mesmo sistema, a versão mais recente do driver ODBC da InterSystems entre os produtos instalados permanecerá registrada no gerenciador de drivers.

Você pode mudar para qualquer driver alterando a entrada de registro abaixo.

 Observe que a execução de RegFiles.bat não altera o driver ODBC.

A entrada do registro é a seguinte.

HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\InterSystems ODBC35 key Driver
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\InterSystems ODBC35 key Setup
0
1 113
Anúncio Danusa Calixto · Dez. 13, 2023
 

 

Últimas Noticias!

Você é um empreendedor de sucesso (não custa sonhar, certo?) e acaba de anunciar ao mundo que está pronto para fundar sua nova startup! Desta vez, você está armado com o poder da GenAI e da InterSystems.

Qual desafio sua nova startup enfrentará para alcançar o sucesso mais uma vez?  🌟🚀

Procuramos desafios importantes que precisam ser resolvidos, mas não há soluções. Quer se trate de transformar os cuidados de saúde, revolucionar a educação, inovar na agricultura ou em qualquer outro domínio – o céu é o limite!

0
0 74
Artigo Danusa Calixto · Dez. 12, 2023 1m read

Está se preparando para usar o VS Code pela primeira vez? Confira se você tem privilégios suficientes.

Você definiu seu servidor Iris nas configurações do VS Code e ainda recebe o erro a seguir?

O VS Code acessa o Iris/HealthConnect usando o web application /api/atelier.  Se você não tem a permissão (ou seja, estiver usando um usuário LDAP para a conexão, e o web application não estiver configurado para a compatibilidade com o LDAP), esse é o motivo pelo qual não é possível conectar.

você também perceberá uma entrada "Login Failure" (Falha no login) no banco de dados de auditoria, além do motivo dela. Peça para o gerente de sistema adicionar a permissão necessária ao web application para que você possa continuar.

Depois de conseguir conectar ao servidor, você talvez não consiga ver todas as classes/projetos no seu namespace. Você vê o erro a seguir?

Para permitir que o usuário 'keren' liste os projetos no namespace 'MAIN', execute esta instrução SQL nele usando uma conta com privilégio suficiente: GRANT SELECT ON %Studio.Project TO 'keren'

A lista de classes/projetos é recuperada ao consultar as tabelas do sistema SQL subjacentes.

Seu gerente de sistema deve executar a seguinte instrução SQL em cada um dos namespaces que você precisa acessar.

GRANT SELECT ON %Studio.Project TO 'keren'

Depois disso, você pode continuar sua jornada de desenvolvimento usando o VS Code.

Keren.

0
0 88
InterSystems Oficial Danusa Calixto · Dez. 5, 2023

Temos o prazer de anunciar uma nova parte da documentação da InterSystems que facilita a atualização da plataforma de dados InterSystems IRIS®, InterSystems IRIS® for Health™ ou HealthShare® Health Connect. A lista de verificação de impacto da atualização em https://docs.intersystems.com/upgrade mostra tudo o que você precisa considerar – e apenas o que você precisa considerar – em uma atualização entre duas versões quaisquer. Isso pega todo o conteúdo do nosso "Histórico de incompatibilidade" e adiciona filtros convenientes, categorias de nível superior e a capacidade de exportar a lista como

0
0 84
Artigo Danusa Calixto · Dez. 4, 2023 1m read

InterSystems FAQ

Ao executar comandos do sistema operacional, use $ZF(-100).

do$ZF(-100,"",program,args) // Execute the Windows command [synchronously].
do$ZF(-100,"/ASYNC",program,args) // Executes a Windows command [asynchronously].

Ao executar comandos do shell do sistema operacional, como mkdir e copy, especifique também /SHELL.

do$zf(-100,"/shell /async","mkdir","c:\temp\x")

Consulte os seguintes documentos para obter detalhes:

Sobre $ZF(-100) [IRIS]
Sobre $ZF(-100)

0
0 84
Artigo Danusa Calixto · Nov. 28, 2023 2m read

Neste artigo, demonstro como criar uma coluna de tabela (antes chamada de "propriedades") com suas classes datatype personalizadas ao usar a DDL definida pelo usuário. As propriedades são um membro fundamental da definição de classe persistente. Datatypes são essenciais para definir os tipos de valores armazenados em uma coluna da tabela. Em geral, os nomes de datatype do SQL diferem dos datatypes da InterSystems, como VARCHAR = %String. Você tem a capacidade de criar ou modificar uma tabela ao usar esses datatypes. De fato, você está criando tabelas pela DDL e já tem suas próprias classes de datatype definidas. Esses datatypes devem ser usados ao executar create/alter na sua definição de classe, em vez dos datatypes padrão da InterSystems. Eles são bastante fáceis de usar ao seguir os passos abaixo

Faça login no portal de gerenciamento. Acesse Sistema > Configuração > Mapeamentos de DDL definidos pelo usuário. Crie um novo mapeamento de DDL definido pelo usuário. Adicione o nome do datatype padrão do SQL que será usado nas consultas SQL. Incorpore sua própria classe datatype no Datatype. Pressione o botão Salvar. Tudo pronto para usar na DDL!

Crie/use sua classe datatype

Class Samples.DT.BoolYN [ ClassType = datatype ]
{
/// A implementação está pronta
}

Execute a consulta SQL. - O datatype de DDL definido pelo usuário está no campo IsActive

   CREATE TABLE Employees (
        FirstName VARCHAR(30),
        LastName VARCHAR(30),
        StartDate TIMESTAMP,
        IsActive BIT(%1)
    )

Depois que a consulta é executada. A definição da classe é criada com sua própria classe de datatype

/// Class Sample.Person Extends%Persistent [ ClassType = persistent, DdlAllowed, Final, Owner = {_SYSTEM}, ProcedureBlock, SqlRowIdPrivate, SqlTableName = Person ]
{

Property FirstName As%String(MAXLEN = 50) [ SqlColumnNumber = 2 ];Property LastName As%String(MAXLEN = 50) [ SqlColumnNumber = 3 ];Property StartDate As%Library.TimeStamp [ SqlColumnNumber = 4 ];Property IsActive As Samples.DT.BoolYN [ SqlColumnNumber = 5 ];Parameter USEEXTENTSET = 1;/// O Bitmap Extent Index é gerado automaticamente pela declaração CREATE TABLE da DDL. Não edite o SqlName desse índice. Index DDLBEIndex [ Extent, SqlName = "%%DDLBEIndex", Type = bitmap ]; }

 Você pode usar esses mesmos nomes da DDL definidos pelo usuário na execução da DDL de Datatype no InterSystems IRIS

CREATE TABLE Sample.Person (
            FirstName %String(MAXLEN=50),
            LastName %String(MAXLEN=50),
            StartDate %TimeStamp,
            IsActive BIT(%1)
        ) 
0
0 111
Artigo Danusa Calixto · Nov. 27, 2023 3m read

Introdução

A InterSystems quer otimizar o IRIS para aproveitar as extensões do conjunto de instruções de CPU modernas.  Isso é ótimo para o desempenho do produto, mas como saber se a sua CPU ainda será compatível com os novos builds do IRIS?  Veja também como descobrir a família de microarquiteturas e as extensões do conjunto de instruções da sua CPU.

Como descobrir a família de microarquiteturas da CPU

 

Etapa 1: saiba o modelo da sua CPU

O primeiro passo é descobrir o modelo de CPU específico para seu servidor IRIS.  Há várias maneiras de fazer isso, dependendo do seu sistema operacional, mas veja aqui como obter essa informação do próprio IRIS.

Em uma sessão do terminal IRIS, execute do $system.CPU.Dump(). Isso gerará resultados assim:

              Architecture: x86_64

                       Model: Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz

                     Vendor: Intel

             # of threads: 8

                # of cores: 4

                # of chips: 1

 # of threads per core: 2

   # of cores per chip: 4

          MT supported: 1

            MT enabled: 1

                       MHz: 2300

As informações necessárias sobre o modelo da CPU estão no campo "Model". 


Etapa 2: pergunte ao seu mecanismo de IA generativa sobre a família de microarquiteturas

O número do modelo que você encontrou parece bastante diferente em diversas plataformas e gerações de processadores, mas a IA generativa corrige as diferenças de forma razoavelmente boa.

Recentemente, tenho usado a interface GPT-4 do Bing para a IA generativa.  Com ela, eu pergunto

    Qual é a família de microarquiteturas da CPU "<Inserir modelo aqui>"?

Por exemplo:

    Qual é a família de microarquiteturas da CPU "Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz"?

Retorna o seguinte:

Intel® Core™ i7-1068NG7 CPU @ 2.30GHz faz parte da família 10ª Geração de processadores Intel® Core™ i7, baseada na microarquitetura Ice Lake.

Você pode verificar essas informações na Intel ou na AMD, conforme apropriado.  Às vezes, é preciso pesquisar um pouco, já que geralmente há vários nomes comerciais para a mesma família de arquiteturas – por exemplo, a linha de processadores EPYC da AMD inclui duas linhas secundárias, chamadas de "Milan" e "Rome".

Quais extensões do conjunto de instruções são compatíveis com minha CPU?

Em vez de procurar a família de microarquiteturas da sua CPU e comparar a uma lista de famílias de CPU compatíveis, você pode optar por verificar se a CPU tem as extensões específicas que serão necessárias. 

 

Linux

No Linux, abra um shell e execute o comando lscpu.  A seção "Flags" dos resultados contém a lista de extensões compatíveis com a CPU.

MacOS

Em um Mac, você pode ver as extensões compatíveis usando o comando sysctl.  Abra um shell e execute sysctl -a. Depois, procure as linhas machdep.cpu.features e machdep.cpu.leaf7_features para ver as extensões compatíveis com a CPU.

 

Windows

O utilitário coreinfo fornece uma lista fácil de ler das extensões do conjunto de instruções da CPU.

0
0 44
Artigo Davi Massaru Teixeira Muta · Nov. 26, 2023 9m read

Introdução

Este artigo tem como objetivo explorar como o sistema FHIR-PEX funciona e foi desenvolvido, aproveitando os recursos do InterSystems IRIS.

Agilizando a identificação e o processamento de exames médicos em centros de diagnóstico clínico, nosso sistema visa aumentar a eficiência e a precisão dos fluxos de trabalho de saúde. Ao integrar os padrões FHIR com o banco de dados Java-PEX da InterSystems IRIS, o sistema ajuda os profissionais de saúde com recursos de validação e roteamento, contribuindo, em última análise, para melhorar a tomada de decisões e o atendimento ao paciente.

como funciona

  • Interoperabilidade IRIS: Recebe mensagens no padrão FHIR, garantindo integração e compatibilidade com dados de saúde.

  • Processamento de informações com 'PEX Java': Processa mensagens no formato FHIR e as direciona para tópicos Kafka com base em regras configuradas globalmente no banco de dados, facilitando o processamento e roteamento eficiente de dados, principalmente para exames direcionados à quarentena.

  • Tratamento de devoluções Kafka via back-end Java externo: Interpreta apenas os exames direcionados à quarentena, permitindo que o sistema trate os retornos do Kafka por meio de um backend Java externo. Facilita a geração de insights prognósticos para profissionais de saúde através de IA Generativa, contando com consultas de resultados de exames anteriores dos respectivos pacientes.

 

Desenvolvimento

Através do PEX (Production EXtension) da InterSystems, ferramenta de extensibilidade que permite aprimoramento e customização do comportamento do sistema, elaboramos uma Operação de Negócio. Este componente tem a tarefa de processar mensagens recebidas no formato FHIR dentro do sistema.

Segue exemplo:

    import com.intersystems.enslib.pex.;     import com.intersystems.jdbc.IRISObject;     import com.intersystems.jdbc.IRIS;     import com.intersystems.jdbc.IRISList;     import com.intersystems.gateway.GatewayContext;          import org.apache.kafka.clients.producer.;     import org.apache.kafka.common.serialization.*;          import com.fasterxml.jackson.databind.JsonNode;     import com.fasterxml.jackson.databind.ObjectMapper;          import java.io.FileInputStream;     import java.io.IOException;     import java.util.Properties;

    public class KafkaOperation extends BusinessOperation {     // Connection to InterSystems IRIS     private IRIS iris;          // Connection to Kafka     private Producer<Long, String> producer;          // Kafka server address (comma separated if several)     public String SERVERS;          // Name of our Producer     public String CLIENTID;          /// Path to Config File     public String CONFIG;          public void OnInit() throws Exception {     [...]     }          public void OnTearDown() throws Exception {     [...]     }          public Object OnMessage(Object request) throws Exception {         IRISObject req = (IRISObject) request;         LOGINFO("Received object: " + req.invokeString("%ClassName", 1));              // Create record         String value = req.getString("Text");         String topic = getTopicPush(req);         final ProducerRecord<Long, String> record = new ProducerRecord<>(topic, value);              // Send new record         RecordMetadata metadata = producer.send(record).get();              // Return record info         IRISObject response = (IRISObject)(iris.classMethodObject("Ens.StringContainer","%New",topic+"|"+metadata.offset()));         return response;     }          private Producer<Long, String> createProducer() throws IOException {     [...]     }          private String getTopicPush(IRISObject req) {     [...]     }          [...]     } `

Dentro da aplicação, o método getTopicPush assume a responsabilidade de identificar o tópico para o qual a mensagem será enviada.

A determinação para qual tópico a mensagem será enviada depende da existência de uma regra na “quarantineRule” global, conforme lida dentro do IRIS.

    String code = FHIRcoding.path("code").asText();     String system = FHIRcoding.path("system").asText();

    IRISList quarantineRule = iris.getIRISList("quarantineRule",code,system);

     String reference = quarantineRule.getString(1);      String value = quarantineRule.getString(2);

     String observationValue = fhir.path("valueQuantity").path("value").asText()

Quando o ^quarantineRule global existe, a validação do objeto FHIR pode ser validada.

    private boolean quarantineValueQuantity(String reference, String value, String observationValue) {         LOGINFO("quarantine rule reference/value: " + reference + "/" + value);         double numericValue = Double.parseDouble(value);         double numericObservationValue = Double.parseDouble(observationValue);

        if ("<".equals(reference)) {             return numericObservationValue < numericValue;         }         else if (">".equals(reference)) {             return numericObservationValue > numericValue;         }         else if ("<=".equals(reference)) {             return numericObservationValue <= numericValue;         }         else if (">=".equals(reference)) {             return numericObservationValue >= numericValue;         }                  return false;     }

Exemplo prático:

Ao definir um global, como:

    Set ^quarantineRule("59462-2","http://loinc.org") = $LB(">","500") 

Isso estabelece uma regra para o código "59462-2" e o sistema ""http://loinc.org"" na ^quarantineRule global, especificando uma condição onde o valor quando maior que 500 é definido como quarentena. No aplicativo, o método getTopicPush pode então usar essa regra para determinar o tópico apropriado para enviar a mensagem com base no resultado da validação.

Dada a atribuição, o JSON abaixo seria enviado para quarentena, pois corresponde à condição especificada por ter:

 {
          "system": "http://loinc.org",
          "code": "59462-2",
          "display": "Testosterone"
}

"valueQuantity": { "value": 550, "unit": "ng/dL", "system": "http://unitsofmeasure.org", "code": "ng/dL" }

FHIR Observation:

{
    "resourceType": "Observation",
    "id": "3a8c7d54-1a2b-4c8f-b54a-3d2a7efc98c9",
    "status": "final",
    "category": [
      {
        "coding": [
          {
            "system": "http://terminology.hl7.org/CodeSystem/observation-category",
            "code": "laboratory",
            "display": "laboratory"
          }
        ]
      }
    ],
    "code": {
      "coding": [
        {
          "system": "http://loinc.org",
          "code": "59462-2",
          "display": "Testosterone"
        }
      ],
      "text": "Testosterone"
    },
    "subject": {
      "reference": "urn:uuid:274f5452-2a39-44c4-a7cb-f36de467762e"
    },
    "encounter": {
      "reference": "urn:uuid:100b4a8f-5c14-4192-a78f-7276abdc4bc3"
    },
    "effectiveDateTime": "2022-05-15T08:45:00+00:00",
    "issued": "2022-05-15T08:45:00.123+00:00",
    "valueQuantity": {
      "value": 550,
      "unit": "ng/dL",
      "system": "http://unitsofmeasure.org",
      "code": "ng/dL"
    }
}

### Quarkus Java application

Após o envio para o tópico desejado, foi construída uma aplicação Quarkus Java para recebimento de exames em quarentena.

    @ApplicationScoped      public class QuarentineObservationEventListener {

    @Inject     PatientService patientService;

    @Inject     EventBus eventBus;

    @Transactional     @Incoming("observation_quarantine")     public CompletionStage<Void> onIncomingMessage(Message<QuarentineObservation> quarentineObservationMessage) {         var quarentineObservation = quarentineObservationMessage.getPayload();         var patientId = quarentineObservation.getSubject()                 .getReference();         var patient = patientService.addObservation(patientId, quarentineObservation);         publishSockJsEvent(patient.getId(), quarentineObservation.getCode()                 .getText());         return quarentineObservationMessage.ack();     }

    private void publishSockJsEvent(Long patientId, String text) {         eventBus.publish("monitor", MonitorEventDto.builder()                 .id(patientId)                 .message(" is on quarentine list by observation ." + text)                 .build());     }      }

Este segmento do sistema tem a tarefa de persistir as informações recebidas de Kafka, armazená-las nas observações do paciente no banco de dados e notificar a ocorrência ao monitor.

O monitor

Por fim, o monitor do sistema é responsável por fornecer uma visualização simples do front-end. Isso permite que os profissionais de saúde revisem os dados do paciente/exame e tomem as ações necessárias.

Implementação of langchain

Através do monitor, o sistema permite que os profissionais de saúde solicitem recomendações da IA ​​Generativa.

    @Unremovable     @Slf4j     @ApplicationScoped     public class PatientRepository {         @Tool("Get anamnesis information for a given patient id")         public Patient getAnamenisis(Long patientId) {             log.info("getAnamenisis called with id " + patientId);             Patient patient = Patient.findById(patientId);             return patient;         }              @Tool("Get the last clinical results for a given patient id")         public List<Observation> getObservations(Long patientId) {             log.info("getObservations called with id " + patientId);             Patient patient = Patient.findById(patientId);             return patient.getObservationList();         }          }

segue implementação de langchain4j

    @RegisterAiService(chatMemoryProviderSupplier = RegisterAiService.BeanChatMemoryProviderSupplier.class, tools = {PatientRepository.class})     public interface PatientAI {              @SystemMessage("""                 You are a health care assistant AI. You have to recommend exams for patients based on history information.                 """)         @UserMessage("""                  Your task is to recommend clinical exams for the patient id {patientId}.                       To complete this task, perform the following actions:                  1 - Retrieve anamnesis information for patient id {patientId}.                  2 - Retrieve the last clinical results for patient id {patientId}, using the property 'name' as the name of exam and 'value' as the value.                  3 - Analyse results against well known conditions of health care.                       Answer with a single JSON document containing:                  - the patient id in the 'patientId' key                  - the patient weight in the 'weight' key                  - the exam recommendation list in the 'recommendations' key, with properties exam, reason and condition.                  - the 'explanation' key containing an explanation of your answer, especially about well known diseases.                      Your response must be just the raw JSON document, without json, or anything else.                  """)         String recommendExams(Long patientId);     }

Dessa forma, o sistema pode auxiliar os profissionais de saúde na tomada de decisões e na execução de ações.

Video demonstração 

VIDEO

Autores

NOTA: 

O aplicativo https://openexchange.intersystems.com/package/fhir-pex está participando atualmente do InterSystems Java Contest 2023. Sinta-se à vontade para explorar a solução e não hesite em entrar em contato se tiver alguma dúvida ou precisar de informações adicionais. Recomendamos executar o aplicativo em seu ambiente local para uma experiência prática. Obrigado pela oportunidade 😀!

Artigo original: https://community.intersystems.com/post/sending-kafka-messages-java-pex-processing-quarantine-exam-prognoses

0
0 147
Artigo Danusa Calixto · Nov. 10, 2023 9m read

Experiência e feedback do curso on-line "Hands-On with InterSystems API Manager for Developers

Com o meu conhecimento básico sobre o contêiner Docker e a API REST, queria tentar usar o InterSystems API Manager pela primeira vez para controlar APIs e microsserviços. Concluí esse curso online usando minha instância IRIS local como host (SO Windows) e o IAM em execução em uma VM Linux (convidado). 

Primeiro, quero apresentar o InterSystems API Manager (IAM), explicar as etapas para configurar meu ambiente local e, por último, mostrar os capítulos do curso.

Introdução

Atualmente, o gerenciamento de API é muito importante ao aproveitar as vantagens da fácil implantação, com um portal de IU centralizado para gestão, monitoramento e proteção do tráfego da API.

O InterSystems API Manager (IAM) controla APIs e microsserviços consumidos e expostos pelo aplicativo IRIS. É um gateway de API entre sistemas downstream e upstream e também tem uma maneira de rastreamento visual para descobrir como as APIs são chamadas, com que frequência elas são chamadas e quem as chamam. 

Benefícios de usar o IAM:

  • Monitorar APIs baseadas em HTTP
  • Controlar o tráfego 
  • Proteger a API usando o mecanismo de segurança 
  • Facilidade de uso para um novo desenvolvedor em processo de integração

Configuração do IAM

O que eu instalei antes de começar a configurar o IAM

  • Windows (instância do IRIS instalada)
  • VM Linux (Docker instalado)

Ative a instância InterSystems IRIS para o usar o IAM

  1. Abra o Portal de Gerenciamento da instância IRIS e ative o IAM.

    1. No Portal de Gerenciamento, selecione System Administration > Security > Users e selecione o usuário IAM
    2. Clique no botão de opção Password 
    3. Insira e confirme uma senha para o usuário IAM
    4. Selecione a caixa User enabled 
    5. Selecione Save
  2. Ative o aplicativo da Web IAM (confira se a sua licença do IRIS especifica "gerenciamento de API") 

    1. No Portal de Gerenciamento, selecione System Administration > Security > Applications > Web Applications e selecione o "/api/iam" 
    2. Selecione a caixa Enable Application 
    3. Selecione Save

Faça o download e extraia os arquivos de instalação do IAM

  1. Faça o download do kit de instalação do IAM da WRC dentro do ambiente Linux
  2. Extraia os arquivos tar (Não extraia iam-image.tar, porque essa é a imagem docker do IAM)

Configure e inicialize o IAM 

Nessa etapa, usei o usuário ROOT já que eu estava obtendo erros como "Não foi possível carregar o Portal de Gerenciamento corretamente" ou o script de configuração não estava transmitindo o valor das variáveis de ambiente para o arquivo docker-compose.yaml quando eu usei o sudo com meu usuário Linux. Uma solução para o último problema foi usar "**sudo -E" **para transmitir as variáveis de ambiente.

  1. Abra o terminal executando o comando "docker load -i iam_image.tar" no diretório onde você extraiu o arquivo do IAM.
  2. Execute "source ./scripts/iam-setup.sh" no diretório atual ou "source ./iam-setup.sh" na pasta "scripts".
    1. Insira o nome exato da imagem do IAM e o nome do repositório de https://containers.intersystems.com/contents Por exemplo: intersystems/iam:3.0.2.0-2 (Essa etapa é obrigatória. Caso contrário, você receberá um erro sobre a falha na autenticação do repositório após executar o "docker compose")
    2. Insira o endereço IP exato da máquina host (Você pode encontrar a especificação IPV4 na configuração do Windows, não insira localhost ou 127.0.0.1)  
    3. Insira o número da porta da instância IRIS no SO do Windows, por exemplo 52773 
    4. Insira e confirme a senha do usuário IAM
  3. Dentro do diretório "scripts", execute "iam-test.sh" para testar a conexão
  4. Dentro do diretório "scripts", execute "docker compose up -d" para inicializar o IAM
  5. Inicialize o portal do IAM no Linux ao acessar: http://localhost:8002/overview

Se você não conseguir dar um ping no endereço host usando a VM, confira Firewall do Windows - Configurações Avançadas - Regras de Entrada. Habilite  Ativar compartilhamento de arquivos e impressoras (Solicitação de Echo - ICMPv4-In) Perfil: Privado, Público

Teste o IAM

Dentro do kit de instalação, você encontrará um script chamado "iam-test.sh" no diretório de scripts. 

Digite e execute "./iam-test.sh" para começar a testar a conexão entre o IAM e a instância IRIS. 

Observação: se o resultado do teste disser "Error creating service. HTTP Status Code:000 ou Error creating service. HTTP Status Code:409" (Erro ao criar o serviço. Código de Status HTTP:000 ou 409), confira o status do docker. Se estiver íntegro, mas ainda não funcionar, encerre o contêiner e execute o docker compose novamente. Pela minha experiência, isso pode acontecer após você pausar a VM.

Para saber mais, encontre aqui a documentação de configuração do IAM: https://docs.intersystems.com/components/csp/docbook/DocBook.UI.Page.cls?KEY=CIAM3.0_install#CIAM3.0_install_setupIAM

Exercício prático: https://learning.intersystems.com/course/view.php?name=IAMExercise

 

Capítulos do curso

Depois de fazer esse exercício, concluí os três capítulos principais que eu gostaria de compartilhar:

  • Configuração de Serviços
  • Configuração de Rotas
  • Configurações de Consumidores e Plugins

Antes de começar a usar o IAM, esse exercício pediu que eu criasse uma solicitação REST usando o método GET, essa solicitação HTTP é do servidor cliente e aponta diretamente para o endpoint, que é um aplicativo da Web criado com base em uma instância IRIS. 

Para as próximas etapas, esse exercício mostrou como configurar os serviços a que a solicitação API é encaminhada e a rota que analisa a solicitação de entrada e depois aloca para a API mais adequada.

Configuração de Serviços e Roteadores

O que é um serviço? 

Um serviço é configurado para conectar a API Manager ao InterSystems IRIS. Geralmente, você tem um serviço por serviço REST ou aplicativo da Web no InterSystems IRIS. Por exemplo, se você tiver um aplicativo da Web com o caminho base /rest/coffeemakerapp, você configurará um serviço na API Manager para esse URL. Os serviços são geralmente definidos antes das rotas.

O que é uma rota?

Uma rota define o que será chamado pelos aplicativos clientes para o InterSystems API Manager. Geralmente, o serviço é definido antes de uma rota, porque a interface permite que você crie com facilidade as rotas correspondentes diretamente de um serviço definido. As rotas são normalmente versões simplificadas de caminhos no InterSystems IRIS. No exemplo a seguir, você criará rotas para /test, /coffeemakers, /coffeemaker e /newcoffeemaker. Quanto mais específicas forem suas rotas, maior controle você terá sobre suas APIs no API Manager, tanto para visualizar métricas quanto para adicionar plugins a rotas específicas.

Crie um serviço:

  1. Acesse o Portal de Administrador do IAM e selecione a guia Services
  2. Clique em New Service e nomeie o serviço
  3. Selecione Add using URL
  4. Forneça o URL base, que é o caminho de URL exato especificado no aplicativo da Web, e confira novamente se o endereço IP da instância está correto (não use localhost nem 127.0.0.1)

Crie uma rota:

  1. Role a tela para baixo no resumo do serviço e clique em Add a Route
  2. Especifique o nome, os protocolos e o(s) caminho(s)
  3. O campo Service deve ser gerado automaticamente com os detalhes do serviço
  4. De acordo com o exercício, era necessário desmarcar Strip Path em Advanced Fields. Caso contrário, o caminho seria removido ao enviar a solicitação para o InterSystems IRIS, o que é um elemento importante para a conexão ao endpoint do InterSystems IRIS.

Após criar o serviço e a rota, você pode usar um cliente REST como o Postman para enviar uma solicitação diretamente para o IAM e receber uma resposta "200 ok", por exemplo: GET http://10.0.0.1:8000/test (/test é a rota criada).

Observação: no meu caso, o URL da solicitação HTTP deve corresponder ao endereço IP da VM Linux. Você pode encontrar o endereço IP por Settings-Network ou executar o comando "ifconfig" no terminal. 

Abra o Portal de Administrador do IAM, você verá que a solicitação para mostrar todos os coffeemakers foi registrada com êxito, do cliente REST para o IAM.

Até mesmo com as solicitações CRUD básicas, em vez de enviar a solicitação HTTP diretamente para o aplicativo da Web do IRIS, o uso do IAM proporciona uma representação visual para controlar as APIs e manter a segurança do endpoint.

Usando plugins

Um dos benefícios de usar o IAM é que há vários plugins disponíveis, como o plugin de limitação de taxa, para ajudar com o throttling, de ACL e de OAuth2.0. No meu caso, vou compartilhar minha experiência ativando basic-auth e criando um consumidor.

Ative o plugin basic-auth

  1. Acesse o Portal de Administrador do IAM e selecione a guia Plugins
  2. Clique em New Plugin > Basic Authentication > Create

Crie um usuário IRIS para a autenticação básica 

  1. Abra o Portal de Gerenciamento do IRIS 
  2. Acesse System Administration > Security > Users > Create New User
  3. Defina um nome de usuário e senha
  4. Deixe os outros campos em branco e clique em Save. No meu caso, criei um usuário chamado "CoffeeManager"

Crie um consumidor e configure as credenciais

  1. Acesse o Portal de Administrador do IAM e selecione a guia Consumers
  2. Clique em New Consumer > Insira CoffeeManger (no meu caso) em Username > Create
  3. Acesse a página de informações do CoffeeManager > Credentials > New Basic Auth Credential
  4. Use as credenciais do usuário que criamos na instância IRIS > Salve

Agora concluímos todos os requisitos para o plugin basic-auth funcionar

Envie uma solicitação HTTP usando a autenticação básica com a credencial "CoffeeManager" que criamos na última etapa 

Acesse a página de informações do CoffeeManager > Activity, você verá que uma solicitação foi registrada

Conclusão

Em suma, comecei apresentando o que é o InterSystems API Manager (IAM) e seus benefícios. Expliquei como configurar o IAM em uma VM Linux e como usar o IAM ao implementar suas funções básicas, criar serviços e rotas e ativar plugins e consumidores.

Se você tiver dúvidas e comentários, não hesite em entrar em contato.

Divirta-se e aproveite o IAM!

0
0 167
Artigo Danusa Calixto · Nov. 10, 2023 10m read

​Palavras-chave: ChatGPT, COS, Tabelas de consulta, IRIS, IA 

Objetivo

Aqui está outra pequena observação antes de seguirmos para a jornada de automação assistida por GPT-4. Confira abaixo algumas "ajudinhas" que o ChatGPT já oferece,  em várias áreas, durante as tarefas diárias. 

Saiba também quais são as possíveis lacunas, riscos e armadilhas da automação assistida por LLMs, caso você explore esse caminho. Também adoraria ouvir os casos de uso e as experiências de outras pessoas nesse campo. 

Tabelas de consulta

Uma das tarefas mais simples podem ser as tabelas de consulta.  Com frequência, precisamos transformar tabelas de código Excel ou CSV em tabelas de consulta XML de forma manual. Principalmente, quando há espaços em branco e outros elementos distribuídos de maneira aleatória nos valores em milhares de registros, e você precisa organizá-los diversas vezes antes dos prazos de publicação. 

O ChatGPT pode ajudar um pouco nisso? Aqui está um teste rápido.

Prompt:

Você é um programa que converte um arquivo CSV automaticamente em um arquivo de tabela de consulta XML.
A entrada é um arquivo CSV separado por vírgulas com 3 colunas de dados :
Blood Science ,XCOM,CANCELLED/REJECTED SAMPLE
Blood Science ,ADX ,ADD ON TEST COMMENT
Blood Transfusion,DARA,ALERT FOR DARA/CAMELLIA
Blood Transfusion, BT1 ,REJECT SAMPLE UNLABELLED
A saída deve ser um arquivo XML no seguinte formato:


<lookupTable>
     <entry table="HIE.ICE.FilterOBR4" key="XCOM">Blood Science</entry>
     <entry table="HIE.ICE.FilterOBR4" key="ADX ">Blood Science</entry>
     <entry table="HIE.ICE.FilterOB

R4" key="DARA">Blood Transfusion</entry>
     <entry table="HIE.ICE.FilterOBR4" key="BT1">Blood Transfusion</entry>
</lookupTable>
Observação: a sequência do atributo XML em cada raiz deve ser mantida

ChatGPT:

Aqui está um script em Python que lê o arquivo CSV, o processa e gera o arquivo XML:

import csv

defconvert_csv_to_xml(input_file, output_file):"""
    Convert a CSV file to an XML lookup table file.

    Parameters:
    input_file (str): Path to the input CSV file.
    output_file (str): Path to the output XML file.

    Returns:
    int: 0 if the conversion was successful, 1 if there was an error.
    """try:
        # Create a dictionary to hold the lookup table data
        lookup_table = {}

        # Read in the CSV file and process the datawith open(input_file, "r") as csvfile:
            csvreader = csv.reader(csvfile)
            for row in csvreader:
                category = row[0].strip()
                key = row[1].strip()
                value = row[2].strip()
                lookup_table[key] = category

        # Generate the XML filewith open(output_file, "w") as xmlfile:
            xmlfile.write('<?xml version="1.0"?>\n')
            xmlfile.write('<lookupTable>\n')
            for key in lookup_table:
                xmlfile.write(f'<entry table="HIE.ICE.FilterOBR4" key="{key}">{lookup_table[key]}</entry>\n')
            xmlfile.write('</lookupTable>\n')

        return0except Exception as e:
        print("Error:", e)
        return1

Esse script primeiro lê o arquivo CSV usando o módulo csv e cria um dicionário para manter os dados da tabela de consulta. Depois, ele processa cada linha do arquivo CSV e adiciona os dados relevantes ao dicionário.

Por fim, o script gera o arquivo XML ao iterar pelo dicionário e gravar as tags e os atributos XML apropriados no arquivo de saída. Veja que a sintaxe da string f é usada para inserir dinamicamente os dados da chave e da categoria nas tags XML.

Executei o script rapidamente em um Jupyter Notebook e deu certo. Ele também removeu todos os espaços em branco (seriam vários ajustes manuais). Ele ofereceu uma ferramenta para lidar com CSVs longos que têm valores confusos, sem limitação de tamanho do token. 

Nesse caso específico, eu diria que a produtividade aumentou cerca de 20 vezes em relação às abordagens manuais repetidas para lidar com várias tabelas de código confusas.

Depois de economizar um pouco de tempo, eu queria saber se ele poderia gerar uma amostra de COS para criar a classe Util para BAUs de serviços futuros etc. 

Prompt:  

Você pode converter a função em Python acima para o ClassMethod do COS da InterSystems usando a função correta específica do COS?

ChatGPT:

Com certeza! Aqui está o código convertido para o ClassMethod do ObjectScript da InterSystems:

ClassMethod ConvertCSVToXML(inputFile As%String, outputFile As%String) As%Integer
{
    try {
        // Create a dictionary to hold the lookup table dataset lookupTable = {}

        // Read in the CSV file and process the dataset csvReader = ##class(%File.CharacterStream).%New()
        do csvReader.LinkToFile(inputFile)
        while (csvReader.AtEnd = 0) {
            set row = csvReader.ReadLine()
            set category = $ZSTRIP($PIECE(row, ",", 1), "B")
            set key = $ZSTRIP($PIECE(row, ",", 2), "B")
            set value = $ZSTRIP($PIECE(row, ",", 3), "B")
            set lookupTable(key) = category
        }
        do csvReader.%Close()

        // Generate the XML fileset xmlWriter = ##class(%File.CharacterStream).%New()
        do xmlWriter.LinkToFile(outputFile)
        do xmlWriter.WriteLine("<?xml version=""1.0""?>")
        do xmlWriter.WriteLine("<lookupTable>")
        set keys = lookupTable.%GetKeys()
        while ('keys.%AtEnd) {
            set key = keys.%GetNext()
            set category = lookupTable(key)
            do xmlWriter.WriteLine("<entry table=""HIE.ICE.FilterOBR4"" key="""_key_""">"_category_"</entry>")
        }
        do xmlWriter.WriteLine("</lookupTable>")
        do xmlWriter.%Close()

        quit0
    }
    catch (ex) {
        Write"Error: "_ex.DisplayString(), !
        quit1
    }
}

No ObjectScript da InterSystems, podemos usar a classe %File.CharacterStream para ler e gravar arquivos. Usamos o método LinkToFile() para abrir os arquivos de entrada e saída, e depois usamos os métodos ReadLine() e WriteLine() para ler e gravar os dados nos arquivos.

Para remover os espaços à esquerda e à direita de cada campo, usamos a função $ZSTRIP() com a sinalização "B".

Também usamos o método %GetKeys() do objeto lookupTable para iterar as chaves no dicionário.

Por fim, o método retorna um código de status 0 se a conversão for bem-sucedida ou 1 se houver um erro.

Ele não fornece uma ferramenta correta que funciona de maneira tão imediata quanto o Python.  %File.CharacterStream deve ser  %Stream.FileCharacter, a remoção de espaços em branco deve usar "<>W", e a iteração pelos globais deve usar $ORDER etc. </p>

Os prompts podem ser melhorados, mas não sou muito bom em pedir favores, então fiz alguns ajustes rápidos durante o processo. 

ClassMethod ConvertCSVToXML2(inputFile As%String, outputFile As%String) As%Integer
{
  
  s tSC = $$$OKtry {
		set^lookupTable = ""// Read in the CSV file and process the dataset csvReader = ##class(%Stream.FileCharacter).%New()
        set tSC =  csvReader.LinkToFile(inputFile)
        while (csvReader.AtEnd = 0) {
            set row = csvReader.ReadLine()
            set category = $ZSTRIP($PIECE(row, ",", 1), "<>W")
            set key = $ZSTRIP($PIECE(row, ",", 2), "<>W")
            set value = $ZSTRIP($PIECE(row, ",", 3), "<>W")
            set^lookupTable(key) = category
        }
        //zw ^lookupTabledo csvReader.%Close()
        
        // Generate the XML fileset xmlWriter = ##class(%Stream.FileCharacter).%New()
        set tSC = xmlWriter.LinkToFile(outputFile)
        set tSC = xmlWriter.WriteLine("<?xml version=""1.0""?>")
        set tSC = xmlWriter.WriteLine("<lookupTable>")
        set key = $O(^lookupTable("")) //lookupTable.%GetKeys()while (key '= "") {
	        //w keyset category = $GET(^lookupTable(key))
            w !,key, " ", category
            set tSC =  xmlWriter.WriteLine("<entry table=""HIE.ICE.FilterOBR4"" key="""_key_""">"_category_"</entry>")
            set key = $O(^lookupTable(key))
        }
        set tSC = xmlWriter.WriteLine("</lookupTable>")
   		set tSC = xmlWriter.%Save("</lookupTable>")
        set tSC = xmlWriter.%Close()
  }
    catch (ex) {
        Write"Error: "_ex.DisplayString(), !
        s tSC = ex
    }
   return tSC
}

 

Então, quais são as lacunas detectadas aqui?  

Algumas possíveis implicações que vieram à minha mente:
1. Produtividade:  a recompensa de produtividade dependeria da proficiência do COS do desenvolvedor.  Essa ferramenta aumentaria ainda mais qualquer vantagem de proficiência em programação.  
2. Lacunas: minha pergunta seria — como podemos aumentar a precisão pela aprendizagem few-shot via prompts, com ou até mesmo sem ajustes?  Se você explora essa área em LLMs, eu adoraria ouvir suas ideias ou sonhos.  
 

Gerações automáticas de testes de unidades
 

Ao discutir o desenvolvimento, não podemos escapar dos testes.  
Parece que isso está mudando agora. Ferramentas polidas que parecem bastante "simples" e usam o poder dos GPTs, como RubberDuck, surgiram para ajudar.

Então, testei a extensão do RubberDuck no VSCode e configurei com minha chave da API OpenAI.
Depois, abri a função em Python mencionada acima no VSCode, conforme a seguir:

Em seguida, selecionei o menu "Generate Unit Test ...", que gera automaticamente uma cobertura de teste de unidade em alguns segundos, pelo menos 100 vezes mais rápido do que digitando. Ele fornece um marcador de posição rápido para ajustes.

Podemos fazer isso para o código COS também, mesmo que o RubberDuck e o ChatGPT ainda não entendam realmente o COS (e não é culpa do LLM):

Ele gerou esse marcador de posição de teste de unidade sem entender muito bem o COS — deixarei as lacunas abertas para conselhos agora e, especialmente, se ou como as lacunas precisarão ser resolvidas com um senso de propósito.

Precisaria de alguns ajustes, mas, usando o ChatGPT, parece que agora ele consegue gerar, analisar e comentar automaticamente o código, além de gerar marcadores de posição de testes de unidade para você. (Bem, mais ou menos, dependendo da linguagem de programação usada e do que queremos que ele faça em seguida).

Conclusão?


Novamente, não tenho conclusões rápidas, já que ainda não consigo explorar muito os limites e as armadilhas.  

Base matemática??


Talvez algum dia, assim como o conceito de "entropia" na teoria da informação foi criado em 1948, outro gênio da matemática possa simplesmente nos iluminar com outro conceito para quantificar as distâncias e lacunas "linguísticas" entre todos os tipos de linguagens, sejam humanas ou de máquina. Até lá, não saberemos realmente o potencial real, limites, riscos e armadilhas desses LLMs. Ainda assim, isso não parece impedir o avanço dos LLMs a cada mês ou semana. 

Outros casos de uso??


Painéis de análise baseados em consultas de linguagem natural humana: algumas semanas atrás, estava trabalhando na P&D de um projeto de inovação e, por acaso, percebi outro caso de uso:  transformar consultas clínicas em linguagem humana em uma consulta de máquina em SQL/MDX.  Na verdade, mais ou menos, sem qualquer ajuste ainda. Parece que ele está começando a aproximar linguagens humanas e tons de máquina, até certo ponto?   
Não seria difícil imaginar uma situação assim: um médico digita uma consulta clínica em um chat na sua linguagem natural e um painel clínico é gerado automaticamente, destacando os pacientes que possam ter perdido a detecção precoce da insuficiência cardíaca, além de agrupar e classificar esses pacientes em regiões, gênero e faixas etárias. As diferenças na qualidade do cuidado seriam destacadas em minutos, em vez de meses de esforços de engenharia. 

E, certamente, um assistente de IA personalizado de cuidados.  Parecia tão remoto e complexo no ano passado, mas, ao que tudo indica, se torna rapidamente uma realidade com o GPT4.  Teoricamente, nada impediria o GPT4 e os LLMs de analisarem meus registros de atendimento, apenas pedaços de dados estruturados e semiestruturados (como exames de laboratório e medicamentos), dados não estruturados (observações e relatórios clínicos etc.) e dados de imagem (raios X, tomografias e ressonâncias magnéticas), para começar a entender melhor e coordenar meus cuidados e consultas em breve.  


Ressalva 
 

Desculpe dizer o óbvio, mas o objetivo desta postagem não se trata de como podemos criar tabelas de consulta XML com rapidez, manualmente ou não. Na verdade, também sou muito bom com Excel e Notepad++. Em vez disso, o objetivo é entrar em contato com quem quer compartilhar casos de uso, reflexões, desafios, riscos e experiências na jornada das automações assistidas por LLMs etc
E o poder dos LLMs veio dos desenvolvedores, de todos os repositórios públicos e das postagens que todos fizeram em fóruns públicos. GPTs não surgem do nada. Nos últimos meses, isso ainda não foi totalmente valorizado e reconhecido.
A AGI apresenta riscos à humanidade nessa velocidade, mas, pessoalmente, me sinto um pouco sortudo, aliviado e dispensado, já que  estamos nos serviços de saúde. 
Outros riscos rotineiros incluem a conformidade de privacidade de dados de acordo com a HIPPA, o GDPR e os Acordos de Processamento de Dados.  

0
0 105
InterSystems Oficial Danusa Calixto · Nov. 6, 2023

A InterSystems tomou a decisão de interromper o desenvolvimento do InterSystems Cloud Manager e rotulá-lo como obsoleto a partir do lançamento do InterSystems IRIS 2023.3. A InterSystems continuará a oferecer suporte aos clientes existentes que utilizam a tecnologia, mas ela não é mais recomendada para novas implantações.

Os clientes na nuvem que estão interessados em implantar e gerenciar uma implantação IRIS com muitos sistemas são incentivados a considerar o Kubernetes e o InterSystems Kubernetes Operator, que possui funcionalidade muito semelhante ao ICM.

0
0 71
InterSystems Oficial Danusa Calixto · Nov. 6, 2023

A InterSystems encerrará o suporte ao uso do sistema de arquivos VxFS com o InterSystems IRIS e o rotulará como obsoleto a partir do lançamento do InterSystems IRIS 2023.3. A InterSystems continuará a oferecer suporte a quaisquer clientes existentes que utilizem a tecnologia, mas ela não é mais recomendada para novas implantações.

O VxFS só tinha suporte no SUSE Linux. Os clientes afetados são incentivados a migrar para o XFS ou outro sistema de arquivos compatível.

Os clientes com dúvidas devem entrar em contato com a equipe de conta ou entrar em contato com @Bob Kuszewski diretamente.

0
0 92
Artigo Danusa Calixto · Set. 1, 2023 4m read

Visão geral

Com o cross-skilling do objectScript do IRIS para o Python, ficam claras algumas diferenças fascinantes na sintaxe.

Uma dessas áreas é como o Python retorna Tuplas de um método com desempacotamento automático.

Efetivamente, isso se apresenta como um método que retorna vários valores. Que invenção incrível :)

out1, out2 = some_function(in1, in2)

O ObjectScript tem uma abordagem diferente com o ByRef e os parâmetros de saída.

Do ##class(some_class).SomeMethod(.inAndOut1, in2, .out2)

Onde:

  • inAndOut1 é o ByRef
  • out2 é a saída

O ponto à esquerda (".") na frente do nome da variável passa o ByRef e a saída.

A finalidade deste artigo é descrever como a comunidade do utilitário PyHelper foi otimizada para oferecer uma maneira pythônica de aproveitar o ByRef e os parâmetros de saída. Ele dá acesso a %objlasterror e tem uma abordagem para lidar com o tipo None do Python.
 

ByRef de exemplo

A invocação normal para o embedded python seria:

oHL7=iris.cls("EnsLib.HL7.Message")._OpenId('er12345')

Quando a abertura desse método falha, a variável "oHL7" é uma string vazia.
Na assinatura desse método, há um parâmetro de status disponível para o object script que fornece uma explicação do problema exato.
Por exemplo:

  • O registro pode não existir
  • Não foi possível abrir o registro no modo de simultaneidade exclusiva padrão ("1"), dentro do tempo limite
ClassMethod %OpenId(id As %String = "", concurrency As %Integer = -1, ByRef sc As %Status = {$$$OK}) As %ObjectHandle

O método TupleOut pode ajudar no retorno do valor do argumento sc, de volta a um contexto python.
 

> oHL7,tsc=iris.cls("alwo.PyHelper").TupleOut("EnsLib.HL7.Message","%OpenId",['sc'],1,'er145999', 0)
> oHL7
''
> iris.cls("%SYSTEM.Status").DisplayError(tsc)
ERROR #5809: Object to Load not found, class 'EnsLib.HL7.Message', ID 'er145999'1
```

A lista ['sc'] contém um único item nesse caso. Ela pode retornar vários valores Byref, e na ordem especificada. O que é útil para descompactar automaticamente as variáveis pretendidas do Python.

Exemplo de como lidar com um parâmetro de saída

Código em Python:

> oHL7=iris.cls("EnsLib.HL7.Message")._OpenId('145')
> oHL7.GetValueAt('&lt;%MSH:9.1')
''

A string retornada está vazia, mas isso se deve ao elemento realmente estar vazio OU algo que deu errado.
No object script, há também um parâmetro de status de saída (pStatus) que pode ser acessado para determinar essa condição.

Código em object script:

> write oHL7.GetValueAt("&lt;%MSH:9.1",,.pStatus)
''
> Do $System.Status.DisplayError(pStatus)
ERROR &lt;Ens>ErrGeneral: No segment found at path '&lt;%MSH'

Com TupleOut, a funcionalidade equivalente pode ser obtida ao retornar e descompactar ambos o valor de retorno do método E o parâmetro de saída do status.

Código em Python:

> hl7=iris.cls("EnsLib.HL7.Message")._OpenId(145,0)
> val, status = iris.cls("alwo.PyHelper").TupleOut(hl7,"GetValueAt",['pStatus'],1,"&lt;&$BadMSH:9.1")
> val==''
True
> iris.cls("%SYSTEM.Status").IsError(status)
1
> iris.cls("%SYSTEM.Status").DisplayError(status)
ERROR &lt;Ens>ErrGeneral: No segment found at path '&lt;&$BadMSH'1

###Variável especial %objlasterror

No objectscript, há acesso a variáveis de porcentagem no escopo do método.
Há cenários em que detectar ou acessar a variável especial %objlasterror é útil após chamar uma API de terceiros ou CORE
O método TupleOut permite o acesso a %objlasterror, como se tivesse sido definido como um parâmetro de saída, ao invocar métodos do Python

> del _objlasterror

> out,_objlasterror=iris.cls("alwo.PyHelper").TupleOut("EnsLib.HL7.Message","%OpenId",['%objlasterror'],1,'er145999', 0) 

> iris.cls("%SYSTEM.Status").DisplayError(_objlasterror)
ERROR #5809: Object to Load not found, class 'EnsLib.HL7.Message', ID 'er145999'1

Quando None não é uma String

O TupleOut lida com as referências a None do Python como objectscript indefinido. Isso permite que os parâmetros sejam padronizados e os métodos se comportem de forma consistente.
Isso é importante, por exemplo, com %Persistent::%OnNew, em que o método %OnNew não é acionado quando None é fornecido para initvalue, mas seria acionado se uma string vazia fosse fornecida.

No objectscript, a implementação pode dizer:

do oHL7.myMethod("val1",,,"val2")

Observe a ausência de variáveis entre vírgulas.

O TupleOut facilita o mesmo comportamento com:

Python:

iris.cls("alwo.PyHelper").TupleOut(oHL7,"myMethod",[],0,"val1",None,None,"val2")

Outra maneira de considerar isso é poder ter uma implementação de uma linha de código de invocação, com um comportamento flexível dependendo da pré-configuração das variáveis:

Object Script:

set arg1="val1"
kill arg2
kill arg3
set arg4="val2"
do oHL7.myMethod(.arg1, .arg2, .arg3, .arg4)

O TupleOut facilita o mesmo comportamento com:

Python:

arg1="val1"
arg2=None
arg3=None
arg4="val2"
iris.cls("alwo.PyHelper").TupleOut(oHL7,"myMethod",[],0,arg1,arg2,arg3,arg4)

Lista e dicionários

Ao lidar com parâmetros para entrada, ByRef e saída, o TupleOut utiliza o mapeamento automático do PyHelper entre:
Listas do IRIS e do Python
Arrays do IRIS e do Python
Onde é preciso sempre usar strings para representar as chaves do dicionário ao passar de Arrays do IRIS para tipos Dict do Python.

Conclusão

Espero que este artigo ajude a inspirar novas ideias, discussões e sugestões sobre o Embedded Python.

Também espero que incentive a explorar a flexibilidade do IRIS em se adaptar facilmente para enfrentar novos desafios.

0
0 52
Artigo Flávio Lúcio Naves Júnior · Ago. 23, 2023 1m read

Pergunta feita várias vezes para InterSystems 

Isso pode ser obtido usando a consulta AllFields query da classe %SYS.ProcessQuery.

Para obter mais detalhes, consulte o documento Process (Job)【IRIS】Process (Job).

Um exemplo de execução no terminal é o seguinte.

1
0 124