0 关注者 · 104 帖子

快速医疗保健互操作性资源FHIR,发音为“fire”)是描述数据格式和元素(称为“资源”)的标准草案,也是用于交换电子健康记录的应用程序编程接口 (API)

官方网站

文章 Claire Zheng · 八月 17, 2021 5m read

国际互联互通的需求是在不断增长,这跟咱们国内的情况是非常类似的。这些年美国在互联互通领域的政策跟实践还是不少的,比如大家可能听到过包括“有意义的使用(Meaningful Use)”,“21世纪治愈法案(21st Century Cures Act)”,还有更多的政策上的驱动。这里先介绍一下“有意义的使用(Meaningful Use)”。

0
0 417
文章 Claire Zheng · 八月 17, 2021 3m read

回过头来,业务场景都是千人千面的, FHIR怎么能够用一个标准涵盖尽可能多的用例?HL7吸收了V3的教训,在V3里面不成功的、或者说采纳度比较低的一个原因就V3试图穷举所有用例,由HL7组织自己来规范这些用例。这个是蛮沉重的教训,这也是V3的方法论虽然好,但是这套实施的路线在国际上有很大障碍的原因。

0
0 504
文章 Claire Zheng · 八月 17, 2021 4m read

FHIR是快速医疗互操作资源(Fast Healthcare Interoperability Resources)的缩写,所以FHIR的核心是资源模型。它的颗粒度和结构都优于之前的V2 、V3、CDA标准,而且能够灵活扩展。另外一个优势就是它的API,它不仅提供了针对于资源模型本身的原子化的CRUD(创建、读取、更新、删除的这样一些原子化操作),而且提供了查询这种更复杂操作的能力,同样API是可以扩展的。

0
1 615
文章 Claire Zheng · 八月 17, 2021 2m read

什么是互联互通?我们所说的互联互通其实就是国际上的互操作性,HIMSS对于互操作性定义的是:不同的信息系统、设备、应用系统之间、程序之间,在机构区域和国家边界之内,以及跨机构、区域和国家边界,以协调的方式来访问交换集成和协作使用数据的能力。

0
0 427
公告 Claire Zheng · 五月 12, 2021

亲爱的社区开发者们,大家好!

InterSystems开发者竞赛:FHIR加速器 已于5月10日开启! 我们邀请所有FHIR开发者们在AWS上使用InterSystems IRIS FHIR加速器服务 (FHIRaaS)上开发或测试您的应用。

现在,我们为您提供绝佳机会,您可以在AWS上免费访问FHIRaaS! 那么,掌握FHIRaaS的第一步,是使用URL的特殊code在ISC Dev FHIR Portal 门户注册,链接如下:👉🏼 https://portal.trial.isccloud.io/account/signup

点击上面的链接,遵循相应步骤,即可掌控InterSystems FHIRaaS!

关于此次竞赛的任何疑问,请随时跟帖提问,或在 discord-contests channel 中提问。

再次欢迎大家加入此次竞赛,成为InterSystems FHIRaaS 大师! ✌🏼

Happy coding! :)

1
0 144
文章 Michael Lei · 五月 17, 2021 2m read

我创建了 iris-fhir-portal 来参加当前竞赛 **InterSystems IRIS for Health FHIR,**本篇快速概述旨在介绍我的应用程序提供的功能。

iris-fhir-portal 的目标是说明使用 IRIS for Health 中的 FHIR 功能创建患者图表并让用户拥有自己的数据有多么简单。

功能

患者列表

在左侧面板上,有一个患者列表,顶部是一个筛选栏。

患者详细信息

表格提供以下信息:

  • FHIR 患者 ID
  • SSN(社会保障号码)
  • 名字
  • 姓氏
  • 出生日期
  • 性别
  • 地址
  • 城市
  • 州/省
  • 国家/地区

在患者详细信息表格后面,是一个包含四个信息块的可折叠项。 提供这些信息的 FHIR 资源为:

  • AllergyIntolerance
  • Observation
    • 类别:vital-signs
    • 类别:laboratory
  • Immunization

右侧的徽章显示每个项目的结果总数。

附注:我在上一篇文章中写到了如何从 FHIR 资源获取所有这些信息。 
https://community.intersystems.com/post/my-experience-working-fhir

例如,以下是实验室数据结果的屏幕截图:

为了以透明的方式处理患者数据,在页面末尾有一个模版,其中包含 FHIR 资源提供的所有信息。

 

您可以在这里试用本应用程序!

http://iris-fhir-portal.eastus.cloudapp.azure.com:32783/csp/user/fhirUI/patientlist.html

如果您喜欢本应用程序,并认为我值得您投票,请为 iris-fhir-portal 投一票!  laugh
https://openexchange.intersystems.com/contest/current
 

0
0 149
文章 Michael Lei · 五月 16, 2021 8m read

FHIR 术语服务规范描述了一组对 CodeSystemValueSetConceptMap 资源的操作。 在这些操作中,以下四种操作似乎是最为广泛采用的:

开发该规范的部分实现一直是探索 IRIS for Health 2020.1 中引入的全新 FHIR 框架的有效途径。 本实现包括上述四种操作,并支持与 CodeSystemValueSet 资源的读取搜索交互。

需要注意的是,本实现使用普通 ObjectScript 持久化类作为源术语表。

安装和测试示例策略

下面列出了安装和基本测试步骤:

  1. 安装 IRIS for Health 2020.1 或更新版本。
  2. 使用门户的 System Administration > Configuration > System Configuration > Namespaces 菜单或在 HSLIB 命名空间中运行命令 do ##class(HS.HC.Util.Installer).InstallFoundation("<name for the new namespace>") 来建立一个新的命名空间。 然后从 intersystems-ru/fhir-terminology-service GitHub 仓库的 src/clssamples/cls 文件夹导入类。
  3. 基于 R4 数据集以及在 dummy-search-parameters.json 中定义的附加搜索参数,创建一个自定义 FHIR 元数据集。 这可以使用 ##class(HS.FHIRServer.ConsoleSetup).Setup() 交互实用工具或运行以下命令来完成:
do ##class(HS.FHIRServer.Installer).InstallMetadataSet("", "", "HL7v40", $lb("<directory with dummy-search-parameters.json>"), 1)
  • 为了使 $expand$validate-code 操作支持 HTTP GET 请求,此步骤是必需的。
  • 请注意,与 InterSystems IRIS 一起打包的 FHIR 元数据集文件位于 <installation directory>/dev/fhir/fhir-metadata 目录中。
  1. 基于新的元数据集和 Sample.iscru.fhir.fts.SimpleStrategy 类创建一个新的 FHIR 端点。 同样,这可以使用交互实用工具或运行以下命令来实现:
do ##class(HS.FHIRServer.Installer).InstallInstance("<web app URI, e.g. /csp/terminology>", "Sample.iscru.fhir.fts.SimpleStrategy", "")
  1. 允许对新端点进行未经身份验证的访问:使用交互实用工具或运行以下命令
set strategy = ##class(HS.FHIRServer.API.InteractionsStrategy).GetStrategyForEndpoint("<web app URI>")
set config = strategy.GetServiceConfigData()
set config.DebugMode = 4
do strategy.SaveServiceConfigData(config)
  1. 填充 Sample.iscru.fhir.fts.model.CodeTable
do ##class(Sample.iscru.fhir.fts.model.CodeTable).Populate(10)
  1. fhir-terminology-service.postman_collection.json 文件导入到 Postman 中,调整集合内定义的 url 变量,然后针对 Sample.iscru.fhir.fts.model.CodeTable(一个简单的持久化类)测试服务。

支持的 FHIR 交互

目前 CodeSystem 和 ValueSet 都支持的唯一搜索参数是 url

上述四种操作均支持 HTTP GET 和 HTTP POST 方法。

下表列出了一些针对 Sample.iscru.fhir.fts.model.CodeTable 类的可能 HTTP GET 请求。

URI
(前面加上 http://<server>:<port><web app URI>
描述
/metadata获取端点的能力描述资源。
/CodeSystem/Sample.iscru.fhir.fts.model.CodeTable读取与 Sample.iscru.fhir.fts.model.CodeTable 类对应的 CodeSystem 资源。
/ValueSet/Sample.iscru.fhir.fts.model.CodeTable读取与 Sample.iscru.fhir.fts.model.CodeTable 类对应的 ValueSet 资源。
/CodeSystem?url=urn:CodeSystem:CodeTable通过 url 搜索 CodeSystem 资源。
/CodeSystem输出所有可用 CodeSystem 资源。
/ValueSet?url=urn:ValueSet:CodeTable通过 url 搜索 ValueSet 资源。
/ValueSet输出所有可用 ValueSet 资源。
/CodeSystem/$lookup?system=urn:CodeSystem:CodeTable&code=TEST在给定系统和代码的情况下,获取有关该概念的所有详细信息。
/ValueSet/$expand?url=urn:ValueSet:CodeTable展开 ValueSet。
/CodeSystem/Sample.iscru.fhir.fts.model.CodeTable/$validate-code?code=TEST验证某个代码是否在代码系统中。

创建自定义策略

为了将您自己的持久化类公开为 FHIR 代码系统/值集,您需要创建自定义策略类,方法是先将 iscru.fhir.fts.FTSStrategy 子类化,然后基于新的自定义策略创建 FHIR 端点(请参见上面的安装步骤 4)。

您的策略类必须覆盖一个类参数和至少三个方法:

  • StrategyKey 类参数应该被指定一个唯一值。 当前类的名称似乎是一个好选择。
  • getCodeTablePackage() 类方法应该返回通过规范 URL 标识的给定代码系统(或值集)的包名称。 通常,所有术语类都属于一个包,因此该方法通常会返回一个相同的包名称,不管参数值如何。
  • getCodePropertyName()getDisplayPropertyName() 类方法应该返回与 codedisplay 概念元素对应的类属性的名称。 不同的类可能有不同的属性映射到术语 code/display 元素。

iscru.fhir.fts.FTSStrategy 的其他可能适合覆盖的方法和参数如下:

  • listCodeTableClasses() 类方法需要覆盖,才能支持以返回所有可用代码系统(或值集)为结果的搜索请求。 此方法应该返回所有可用术语类的类名称列表。 Sample.iscru.fhir.fts.SimpleStrategy 包含此方法的以下基本实现:
/// Returns a list of all available code table classes.
ClassMethod listCodeTableClasses() As %List
{
    #dim sql As %String = "SELECT name FROM %Dictionary.ClassDefinition WHERE name LIKE '" _ ..#codeTablePACKAGE _ ".%' ORDER BY name"
    #dim resultSet As %SQL.StatementResult = ##class(%SQL.Statement).%ExecDirect(, sql)
    if (resultSet.%SQLCODE '= 0) && (resultSet.%SQLCODE '= 100) $$$ThrowStatus($$$ERROR($$$SQLError, resultSet.%SQLCODE, resultSet.%Message))

    #dim return As %List = ""
    while resultSet.%Next()
    {
        set return = return _ $lb(resultSet.name)
    }

    quit return
}
  • 如果您的持久化类的任何特定属性都不应出现在 CodeSystem 资源中,则需要覆盖 isExcludedProperty() 类方法。 默认情况下,此方法会过滤掉 CollectionIdentityInternalMultiDimensionalPrivate 属性。 需要注意的是,对象引用和流属性当前不受框架支持并被忽略。

  • codeSystemUrlPREFIXvalueSetUrlPREFIX 类参数以及 getCodeSystemForClassname()getValueSetForClassname()determineCodeTableClassname()determineCodeSystemForValueSet() 方法控制类名称与规范 URL 相互映射的方式。 默认情况下,对规范 URL 使用以下命名方案: | CodeSystem | ValueSet | | ----------------------------------------- | --------------------------------------- | | urn:CodeSystem:<short class name> | urn:ValueSet:<short class name> |

请注意,CodeSystem/ValueSet 资源的逻辑 id(也就是服务器 id)等于其对应类的全名。

待完成功能

目前缺少的是对代码系统版本管理、概念层次结构和 $subsumes 操作、ConceptMap 资源以及其他许多内容的支持。 欢迎发表意见和拉取请求!

0
0 220
公告 Claire Zheng · 五月 8, 2021

亲爱的社区开发者们,大家好!

欢迎积极参与新一轮InterSystems开发者竞赛!

🏆 InterSystems 编程大赛:FHIR 加速器 🏆

提交在AWS上使用InterSystems的IRIS FHIR-as-a-service的应用程序,或帮助使用InterSystems IRIS FHIR加速器开发的解决方案。点击这篇文章,了解如何在AWS上申请应用InterSystems IRIS FHIR 加速器服务 (FHIRaaS) 。

时间:2021年5月10日-6月6日

奖金总额: $8,750 

👉  点击登录活动页面 👈


0
0 167
文章 Qiao Peng · 四月 7, 2021 5m read

如果看了前一篇InterSystems IRIS医疗行业版创建FHIR服务器,应该您已经搭建好了FHIR服务器和FHIR资源仓库。除了使用FHIR REST API来操作这个FHIR服务器,您还可以更直观地看看它的价值 - 使用SMART on FHIR应用。这次,基于上次建好的FHIR服务器,我们用10分钟把一个SMART on FHIR运行起来。

SMART on FHIR背景

SMART是Substitutable Medical Applications and Reusable Technology的缩写,它的目标是创建可以被替换、可以复用的医疗应用,简单说就是希望医疗应用可以像我们的手机应用一样:不喜欢当前的天气应用,那么就换一个。SMART,这个起于2011年的哈佛和波士顿儿童医院的合作项目,在2013年注意到并快速采用了FHIR,成就了今天的SMART on FHIR。

2
0 544
文章 Qiao Peng · 一月 10, 2021 9m read

Swift-FHIR-Iris

iOS应用程序支持将HealthKit数据导入InterSystems IRIS医疗版(或任何FHIR资源仓库库)

main

目录

演示目的

目的是创建FHIR协议的端到端演示。

这里的端到端指的是从一个信息源到另一个信息源,例如iPhone。 苹果HealthKit将收集到的健康数据转换为FHIR,再发送到InterSystems IRIS 医疗版存储库。

必须通过web接口访问这些信息。

TL;DR: iPhone -> InterSystems FHIR -> web界面.

如何运行此演示

先决条件

  • 客户端 (iOS)
    • Xcode 12
  • 服务器和Web应用程序
    • Docker

安装 Xcode

这里没有太多要说的,打开AppStore,搜索Xcode,安装。

打开SwiftUi project

Swift是苹果在iOS、Mac、Apple TV和Apple Watch中使用的一种编程语言,是objective-C的替代品。

双击Swift-FHIR-Iris.xcodeproj

单击左上角的箭头打开模拟器。

xcode

配置模拟器

打开Health

点击“Steps”

添加数据

simulator

启动InterSystems FHIR服务器

在该git的根目录下,运行以下命令:

docker-compose up -d

构建过程结束时,你将连接到FHIR资源仓库:

http://localhost:32783/fhir/portal/patientlist.html

portal

该门户网站由@diashenrique创建.

为处理Apple活动足迹,进行了一些修改。

在iOS应用程序上操作

iOS应用程序首先会请求你同意分享部分信息。

点击授权

authorize

然后点击“Save and test server”对FHIR服务器进行测试

默认设置指向docker配置。

操作成功后,就可以输入患者信息。

名字、姓氏、生日、性别。

将患者信息保存到Fhir。弹出窗口将显示唯一的Fhir ID。

savepatient

可在门户网站查阅该患者信息:

访问: http://localhost:32783/fhir/portal/patientlist.html

在这里我们可以看到,增加了一个新的病人“Toto”,0个活动。

patient portal

发送她的活动信息:

回到iOS应用程序,点击“Step count”。

这里显示的是一周的步数。在我们的案例中有2条记录。

现在可以单击发送,将这些数据发送到InterSystems IRIS FHIR。

ios send

从门户网站上查询新的活动记录:

现在我们可以看到Toto有两条新的观察和活动消息。

portal activites

你还可以单击“chart”按钮以图表格式显示。

portal charts

工作原理

iOS

该demo大部分是基于SwiftUI构建的。

https://developer.apple.com/xcode/swiftui/

iOS和co的最新框架。

如何检查健康数据的授权

它在SwiftFhirIrisManager 类中。

该类采用单例模式,可使用@EnvironmentObject对应用程序中进行的所有操作进行注释。

更多信息请访问 : https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data-between-views

调用requestAuthorization的方法如下:

    // Request authorization to access HealthKit.
    func requestAuthorization() {
        // Requesting authorization.
        /// - Tag: RequestAuthorization
        
        let writeDataTypes: Set<HKSampleType> = dataTypesToWrite()
        let readDataTypes: Set<HKObjectType> = dataTypesToRead()
        
        // requset authorization
        healthStore.requestAuthorization(toShare: writeDataTypes, read: readDataTypes) { (success, error) in
            if !success {
                // Handle the error here.
            } else {
                
                DispatchQueue.main.async {
                    self.authorizedHK = true
                }
                
            }
        }
    }

其中healthStore是HKHealthStore()的对象。

HKHealthStore类似于iOS中的healthdata数据库。

dataTypesToWrite和dataTypesToRead是我们想要在数据库中查询的对象。

授权的目的可以通过在Info.plist xml文件中添加以下内容完成:

    <key>NSHealthClinicalHealthRecordsShareUsageDescription</key>
    <string>Read data for IrisExporter</string>
    <key>NSHealthShareUsageDescription</key>
    <string>Send data to IRIS</string>
    <key>NSHealthUpdateUsageDescription</key>
    <string>Write date for IrisExporter</string>

如何连接FHIR资源仓库

对于这一部分,我使用了从Smart-On-FHIR网站下载的FHIR包 : https://github.com/smart-on-fhir/Swift-FHIR

使用的类是FHIROpenServer。.

    private func test() {
        
        progress = true
        
        let url = URL(string: self.url)

        swiftIrisManager.fhirServer = FHIROpenServer(baseURL : url! , auth: nil)
        
        swiftIrisManager.fhirServer.getCapabilityStatement() { FHIRError in
            
            progress = false
            showingPopup = true
            
            if FHIRError == nil {
                showingSuccess = true
                textSuccess = "Connected to the fhir repository"
            } else {
                textError = FHIRError?.description ?? "Unknow error"
                showingSuccess = false
            }
            
            return
        }
 
    }

这一步将在单例swiftIrisManager中创建一个新的对象fhirServer。

接下来使用getCapabilityStatement()

如果能够检索到FHIR服务器的capabilityStatement,则意味着已成功连接到FHIR资源仓库。

这个资源仓库不在HTTPS下,默认情况下Apple会阻止这种通信。

想要获取HTTP支持,可以对Info.plist xml文件进行如下编辑:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>localhost</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>

如何将患者信息保存到FHIR资源仓库

基本操作:首先检查存储库中是否已经存在该患者的信息

Patient.search(["family": "\(self.lastName)"]).perform(fhirServer)

搜索具有相同姓氏的患者。

在这里,我们可以想象一下其他场景,比如使用Oauth2和JWT令牌加入patientId及其令牌。但在这个演示中,我们简单操作即可。

如果该患者信息已经存在,可以对其进行检索;否则,则创建新的患者信息 :

    func createPatient(callback: @escaping (Patient?, Error?) -> Void) {
        // Create the new patient resource
        let patient = Patient.createPatient(given: firstName, family: lastName, dateOfBirth: birthDay, gender: gender)
        
        patient?.create(fhirServer, callback: { (error) in
            callback(patient, error)
        })
    }

如何从HealthKit中提取数据

通过查询healthkit商店 store(HKHealthStore())即可完成。

这里我们查询一下步数。

使用predicate做好查询准备。

        //Last week
        let startDate = swiftFhirIrisManager.startDate
        //Now
        let endDate = swiftFhirIrisManager.endDate

        print("Collecting workouts between \(startDate) and \(endDate)")

        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: HKQueryOptions.strictEndDate)

然后,会根据数据类型(HKQuantityType.quantityType(forIdentifier: .stepCount))和predicate内容进行查询。

func queryStepCount(){
        
        //Last week
        let startDate = swiftFhirIrisManager.startDate
        //Now
        let endDate = swiftFhirIrisManager.endDate

        print("Collecting workouts between \(startDate) and \(endDate)")

        let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: HKQueryOptions.strictEndDate)

        let query = HKSampleQuery(sampleType: HKQuantityType.quantityType(forIdentifier: .stepCount)!, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { (query, results, error) in
            
            guard let results = results as? [HKQuantitySample] else {
                   return
            }
       
            process(results, type: .stepCount)
        
        }

        healthStore.execute(query)

    }

如何将HealthKit数据转换为FHIR

在这部分,我们使用了微软软件包HealthKitToFHIR

https://github.com/microsoft/healthkit-to-fhir

这个包很有用,为开发商提供了将HKQuantitySample转换为FHIR Observation的功能。

     let observation = try! ObservationFactory().observation(from: item)
      let patientReference = try! Reference(json: ["reference" : "Patient/\(patientId)"])
      observation.category = try! [CodeableConcept(json: [
          "coding": [
            [
              "system": "http://terminology.hl7.org/CodeSystem/observation-category",
              "code": "activity",
              "display": "Activity"
            ]
          ]
      ])]
      observation.subject = patientReference
      observation.status = .final
      print(observation)
      observation.create(self.fhirServer,callback: { (error) in
          if error != nil {
              completion(error)
          }
      })

其中item是HKQuantitySample,在我们的例子中是stepCount类型。

这个factory完成了大部分工作,将“unit”和“type”转换为FHIR codeableConcept,并将“value”转换为FHIR valueQuantity。

对PatientId的引用是通过强制转换json fhir引用手动完成的。

let patientReference = try! Reference(json: ["reference" : "Patient/\(patientId)"])

对类别进行同样的操作 :

      observation.category = try! [CodeableConcept(json: [
          "coding": [
            [
              "system": "http://terminology.hl7.org/CodeSystem/observation-category",
              "code": "activity",
              "display": "Activity"
            ]
          ]
      ])]

最后,在fhir资源仓库中创建observation :

      observation.create(self.fhirServer,callback: { (error) in
          if error != nil {
              completion(error)
          }
      })

后端 (FHIR)

没什么好说的,它基于InterSystems社区的fhir模板 :

https://openexchange.intersystems.com/package/iris-fhir-template

前端

基于Henrique作品,Henrique是使用jquery制作的FHIR资源仓库的一个很好的前端。

https://openexchange.intersystems.com/package/iris-fhir-portal

0
0 431