HL7-4-PHI

From PhiWIKI

Jump to: navigation, search

This section uses terminology as defined in this whitepaper.

PHI mapped on the RIMBAA model:

Image:RIMBAA consistency of models.jpg

PHI is using JavaSIG (modified for EE Application) can be mapped on the RIMBAA MATRIX as follows:

Image:RimbaaPhi.JPG

or using a second version of RIMBAA MATRIX:

Image:RIMBAA matrix HL7 RIM architecture.jpg

Instead using the THIRD DIMENSION of the RIMBAA MATRIX PHI can be mapped as follows:

Image:RIMBAA-MATRIX-90.PNG

The PHI Technology solutions occupies the RP-RO-MS squares using the Java SIG materials.

The communication with other applications will be implemented using the Java SIG HL7 message v3 capability starting from RIM Object (RO) and it will be sent to the ESB that communicates with other system. A transformation feature from v3 to v2.x will be created when it's required.

phi-Technology is active in the comunity following this proposal that was presented during the HL7 WGM Tooling Demonostration in ATLANTA

Contents

User Interface

The User Interface is an R-MIM driven generation process (by PHI Designer). R-MIMs, process-tasks and GUI widgets are bound/configured using the toolset (the Process Explorer).

The RO object is bound to a UI widget using a binding string that has a XPATH-like format, e.g.:

 Patient_PRPA_MT201301UV02.player[classCode=PSN,determinerCode=INSTANCE].name.FAM

All the user interface are linked to a JBoss Seam Bean that using the XPATH-like binding, derived by RMIM, can read/write attribute in the RIM Object (i.e. it's pur RIM-based objects that are being accessed; the access paths are however based on -the class clone names- defined in an R-MIM). Example:

       <h:outputText id="Label_1211819478500_id" rendered="true" styleClass="Label_1211819478500"
           value="#{RimBean.getValue('Doctor_PRPM_MT999999UV01.player[classCode=PSN,determinerCode=INSTANCE].name.FAM')}">      
       </h:outputText>   
       <h:selectOneMenu id="vocab_EncounterSpecialCourtesy_combobox_ComboBox_1217003891062"
                   rendered="true"  required="false"  styleClass="ComboBox_1217003891062"
                   valueChangeListener="#{SelectItemBean.processValueChange}">
                   <phi:selectItems  value="vocab_EncounterSpecialCourtesy" />
                   <f:param value="Encounter_PRPA_MT402001UV02.specialCourtesiesCode" name="binding"/>
      </h:selectOneMenu>
      <h:inputText id="TextBox_1210948378437_id"
          styleClass="TextBox_1210948378437"
          required="false"
          rendered="true" value="#{inputTextBean.value}">
          <f:param value="Patient_PRPA_MT201301UV02.player[classCode=PSN,determinerCode=INSTANCE].name.FAM" name="binding"/>   
          <f:converter  converterId="RimPropertyResolverAsConverter" />   
      </h:inputText>

When PHI RE receives this XPATH-like binding it checks:

  1. Re-use the object if it already exist in the current Process context, and access its contents:
    • If the Patient_PRPA_MT201301UV02 is in the context get/set value using XPATH-like binding player[classCode=PSN,determinerCode=INSTANCE].name.FAM for reading/setting the RIM Object attribute. A converter was implemented to manage RIM Type value and Java Type.
  2. Create a new object (if it didn't already exist)- an empty R-MIM root class instance initialized with some values that came from MIF.
    • If the Patient_PRPA_MT201301UV02 is NOT in the context then the instance associated to the root of the PRPA_MT201301UV02.mif is loaded using the Java Sig materials. All attributes with fixed/default value, as set in the mif file, are initialized and then the RIM Object instance is stored in the context and cached.

OID

July 23th, 2009: PHI TECHONOLOGY has its own OID [1] registered to create vocabulary with the Dictionary Manager.

The OID REGISTRATION was done under this AGREEMENT: "Entering an OID here will NOT give you rights to this OID because this OID repository is not an official Registration Authority. You should only enter it here if you know what it is or if it has been assigned to you by an official Registration Authority."

HL7 Vocabulary integration in Phi Dictionary and its management policies

Phi Designer is now able to take codes used in processes and mif file from multiple code systems which are imported in a db managed by Dictionary Manager. The HL7 vocabulary.xml now are picked-up from db implying that we need to identify uniquely a code associate to an attribute.

HL7 vocabulary and mif files give some troubles when using db codes: many times identification of the code to associate is not possible. Refer to following figure. Image:code-duplicate.png

This is a snapshot of the RMIM "Home Health Encounter Event Activate" (PRPA_MT404001UV02.mif). In the two ActRelationships "InFullfillmentOf" and "sequelTo" (highlighted with a green rectangle) there are two assignments of a code (OP) to attribute "contextControlCode": when the research of the code "OP" on HL7 vocabulary starts, more than one result is returned (see figure below).

Image:op-code.png

Domain "ContextControl" from which the code "OP" is dragged has more than one instance of it (all the instances are highlighted with a red rectangle in the figure) so during run-time process execution it's not possible to decide which value to assign to a code request. This is mainly due to the fact that not only HL7 vocabulary has duplicate codes but also mif file do not contains a more restrictive definition of the code to associate. If the xml part of the file defining the code "OP" is taken from "PRPA_MT404001UV02.mif" the following assignment is written:

       <attribute sortKey="2" minimumMultiplicity="0" maximumMultiplicity="1" isMandatory="false" conformance="R" name="contextControlCode" isImmutable="true">
         <enumerationValues>OP</enumerationValues>
         <derivedFrom staticModelDerivationId="1" className="ActRelationship" attributeName="contextControlCode"/>
         <derivedFrom staticModelDerivationId="2" className="InFulfillmentOf" attributeName="contextControlCode"/>
         <derivedFrom staticModelDerivationId="3" className="InFulfillmentOf" attributeName="contextControlCode"/>
         <type name="CS"/>
         <supplierVocabulary codingStrength="CNE">
           <vocabularyDomain name="ContextControl"/>
           <code code="OP"/>
         </supplierVocabulary>
       </attribute>

"OP" is associated to "ContextControl" vocabulary domain, a too much generic domain. A more logic domain could be "ContextControlOverriding" or "ContextControlPropagating" where code "OP" can be identified uniquely.

To overcome this type of problem we used to reassign vocabulary domain, also using OID. So the xml now reappears like the following:

       <attribute sortKey="2" minimumMultiplicity="0" maximumMultiplicity="1" isMandatory="false" conformance="R" name="contextControlCode" isImmutable="true">
         <enumerationValues>OP</enumerationValues>
         <derivedFrom staticModelDerivationId="1" className="ActRelationship" attributeName="contextControlCode"/>
         <derivedFrom staticModelDerivationId="2" className="InFulfillmentOf" attributeName="contextControlCode"/>
         <derivedFrom staticModelDerivationId="3" className="InFulfillmentOf" attributeName="contextControlCode"/>
         <type name="CS"/>
         <supplierVocabulary codingStrength="CNE">
           <vocabularyDomain name="2.16.840.1.113883.11.16478.18935"/>
           <code code="OP"/>
         </supplierVocabulary>
       </attribute>

Previous case appears when a bad assignment of value has been done (from domain to mif) and "mif refactoring strategy" has been adopted. But in some cases there is the need to adopt a "vocabulary refactoring strategy" and that happens especially when old domains are encountered. E.g: given the RMIM "Person Activate" ("PRPA_RM101301UV.mif") the classCode has value "PSN" associated to vocabulary domain "EntityClass". Searching for this value in the domain "EntityClass" three records are returned (see figure below, in the right panel).

Image:psn.png

In this case we prefer not to modify mif definitions but "to modify" db: this is done creating our code system where only the concept/domain of interest will be copied. In the previous image, in the left panel, highlighted in the red rectangle you can see the code "PSN" in a customization of "EntityClass" domain. When a process execution is running and it needs the code "PSN", first of all the research will be done in our customized domain, finding only one reference for this code we will have a successfull code retrieving.

Null Flavour

Rather than adding one additional field for every field in the DB SCHEMA (phi RIM based DB SCHEMA doesn’t store XML and the filed are not VARCHAR/TEXT for all the RIM attribute!) we simplifying the null-flavors to one, which makes it simpler to handle it in the business logic.

Concerning ADT (but the issue can be applied to any other domain) the problem regards mainly VALIDATION RULES (for reimbursement) and the outgoing RECORD FILES (to the payer org). We have managed these cases by a couple of techniques: - decoupling rules from java code by use of drools as rule engine, which makes it easier to give a logical meaning to a null value in a specific condition - enabling multiple transcodification on any coded value - constraining the input fields when needed (GUI) - enabling transformation by expression on several GUI widgets

As you can see we do not have found a single killer solution, but a set of techniques. If you find one, I'd love to be acquainted !

List of Q&A in the RIM

phi-Technology addresses the solutions of this problem in the way described in How to CREATE a CHECK-LIST

RIM VISUAL QUERY BUILDER

In the phi-Designer was implemented a component that is useful to prepare INSERT and SELECT query upon on RIM DB BASED, as it's visible here: How to USE the R-MIM link for preparing a READ or CREATE call/operation

VERSIONING

We need to deal with the customer request about how to trace all the change in the Object instance that our phi-Solution takes into to account. What we implemented is a mechanism that makes available to the final user an history of the R-MIM, the main idea is explained here

RIM DB

This section discusses some of the best practices for those applications that map RIM objects to an E-R database structure.
Note to readers: the reader is assumed to be aware of the characteristics of the object data model, the entity-relationship (ER) data model and the entity-attribute-value (EAV) data model.


  • See ORM for references.

Specific References

Introduction

The purpose of this white paper is to describe a process for transforming the Health Level Seven (HL7) Reference Information Model (RIM) into a Logical Data Model (LDM) and a Physical Data Model (PDM). The HL7 RIM is a conceptual data model built and maintained by HL7 to be used as a source of the data content portion of HL7 standards. Because it is a conceptual data model, the RIM is not well suited to be used as the design of a relational database schema. The RIM contains abstract classes, complex datatypes, and generic business rules that need to be resolved and reconciled to form a LDM. LDM can be mapped to its PDM via Hibernate o-r mapping tool for the target databases MySQL and Oracle.

A series of refinement steps is required to transform the RIM into a LDM that would be useful as input to design of a database schema. The steps are designed to render a less abstract model with normalized data structures and realm specific business rules. The resulting LDM is well suited for use in database design activities. The LDM is technology independent and to some extent application independent. As application design begins the LDM will be used as input and further transformed into a PDM. The PDM will consider the technological implications of the database schema including items such as the capabilities of the target database management system (DBMS), tuned for a typical OLTP application with 300 concurrent end users logged in.

Scope

The classes and datatypes in the HL7 RIM are grouped into logical packages. There are six core packages in the RIM, other packages are used for administrative and model management purposes only. The Entities, Roles, and Acts packages contain the respective entity, role, and act generalization hierarchies and dependent classes. The Datatypes package contains all of the defined version 3.0 datatypes. The Structured Documents and Message Control packages contain classes that represent artifacts peculiar to HL7 messaging and clinical document architecture standards. For the purpose of our example model only a subset of classes of Acts, Datatype, Entities, and Roles packages will be considered within scope of the paper. Image:Acimg1.GIF

To keep this paper simple, let's select only the relevant attributes:

Image:Acimg2.GIF

Resolving Generic Datatypes

These Data Types are included into the JavaSIG package: org.hl7.types.impl The relative java wrappers (WrappingBagAccessor, WrappingSetAccessor, WrappingListAccessor) are included into the package: org.hl7.hibernate

“IVL”, “EIVL” or “PIVL” Datatype

  • Entity.existence_time : IVL <TS>
    • Entity.existence_start_time : TS
    • Entity/existence_end_time : TS
  • Manufactured_material.stability_time : IVL <TS>
    • Manufactured_material.stability_time_start : TS
    • Manufactured_material.stability_time_stop : TS
  • Act.repeat_number : IVL<TS>
    • Act.repeat_number_start : TS
    • Act.repeat_number_stop : TS
  • Supply.expected_use_time : IVL<TS>
    • Supply.expected_use_time_start : TS
    • Supply.expected_use_time_stop : TS
  • SubstanceAdmnistration.rate_qty: IVL<PQ>
    • SubstanceAdmnistration.rate_qty_start : PQ
    • SubstanceAdmnistration.rate_qty_stop : PQ
  • SubstanceAdmnistration.dose_qty: IVL<PQ>
    • SubstanceAdmnistration.dose_qty_start : PQ
    • SubstanceAdmnistration.dose_qty_stop : PQ
  • Account.allowed_balance_qty: IVL<MO>
    • Account.allowed_balance_qty_start: MO
    • Account.allowed_balance_qty_stop: MO
  • RoleLink.effective_time: IVL<TS>
    • RoleLink.effective_time_start: TS
    • RoleLink.effective_time_stop: TS
  • Role.effective_time: IVL<TS>
    • Role.effective_time_start: TS
    • Role.effective_time_stop: TS
  • Participation.time:IVL<TS>
    • Participation.time_start: TS
    • Participation.time_stop: TS

“SET”, “DSET”, “QSET” or “List” Datatypes

  • Entity.id : SET<II> ==> Enity_Identifier.
  • Entity.status_cd : SET<CS> ==> Entity.status_cd : CS
  • Person.ethnic_group_cd : SET<CE> ==> Person.ethnic_group_cd : CE
  • Person.race_cd : SET<CE> ==> Person_Race.
  • Entity.qty : SET<PQ> ==> Entity.qty PQ
  • Person.religious_affiliation : SET<CE> ==> Person.religious_affiliation : CE
  • Act.id: SET<II> ==> Act_Identifier
  • Act.priority: SET<CE> ==> Act_Priority
  • Act.confidentiality_cd: SET<CE> ==> Act_Confidentiality
  • Act.reason_cd: SET<CE> ==> Act_Reason
  • PatientEncounter.special_courtesies_cd: SET<CE> ==> PatientEncounter_Courtesies
  • PatientEncounter.special_arrangement_cd: SET<CE> ==> PatientEncounter_Arrangement
  • Procedure.method_cd: SET<CE> ==> Procedure_method
  • Procedure.approach_site_cd: SET<CE> ==> Procedure_approach_site
  • Procedure.target_site_cd: SET<CE> ==> Procedure_target_site
  • Observation.interpretation_cd: SET<CE> ==> Observation_interpretation
  • Observation.method_cd: SET<CE> ==> Observation_method
  • Observation.target_site_cd: SET<CD> ==> Observation_target
  • SubstanceAdministration.approach_site_cd: SET<CD> ==> SubstanceAdministration_approach_site
  • SubstanceAdministration.dose_check_qty: SET<RTO> ==> SubstanceAdministration_dose_check
  • SubstanceAdministration.max_dose_qty: SET<RTO> ==> SubstanceAdministration_max_dose
  • SubstanceAdministration.method_cd: SET<CD> ==> SubstanceAdministration_method
  • InvoiceElement.modifier_cd: SET<CE> ==> InvoiceElement_modifier
  • DeviceTask.parameter_value: LIST<ANY> ==> DeviceTask_parameters
  • Role.id: SET<II> ==> Role_identifier
  • Role.confidentiality_cd: SET<CE> ==> Role_confidentiality
  • Role.position_number: LIST<INT> ==> Role_position
  • ManagedParticipation.id: SET<II> ==> ManagedParticipation_identifier
  • Document.bibliographic_designation_txt: SET<ED> ==> Document_Designation


Note: SET<CS> type for Entity.status_cd has been simplified to a single CS value (except Person.race_cd).

“BAG” Datatypes

  • Entity.nm : BAG<EN> ==> Enity_Name.
  • Entity.telecom : BAG<TEL> ==> Entity_Telecom_Address.
  • Organization.addr : BAG<AD> ==> Organization_Address.
  • Person.addr : BAG<AD> ==> Person_Address.
  • Role.name BAG<EN> ==> Role_name
  • Role.addr: BAG<AD> ==> Role_address

Image:Acimg3.GIF

Add Association Attributes

  • Entity_identifier./identified_entity : ENTITY
  • Entity_name./named_entity : ENTITY
  • Entity_telcom_address./addressed_entity : ENTITY
  • Organization_address./addressed_organization : ORGANIZATION
  • Person_address./addressed_person : PERSON
  • Person_race./attributed_person : PERSON
  • Act_reason.act: Act
  • Act_Confidentiality: Act
  • Act_Priority: Act
  • Act_identifier: Act
  • PatientEncounter_Courtesies.pencounter: PatientEncounter
  • PatientEncounter_Arragement.pencounter: PatientEncounter
  • Procedure_method.procedure: Procedure
  • Procedure_approach_site.procedure: Procedure
  • Procedure_target_site.procedure: Procedure
  • Observation_interpretation.observation: Observation
  • Observation_target.observation: Observation
  • Observation_method.observation: Observation
  • SubstanceAdministration_approach_site.sub_admin: SubstanceAdministration
  • SubstanceAdministration_dose_check.sub_admin: SubstanceAdministration
  • SubstanceAdministration_method.sub_admin: SubstanceAdministration
  • SubstanceAdministration_max_dose.sub_admin: SubstanceAdministration
  • Role_identifier. identified_role : Role
  • Role_confidentiality.confidentiality_role : Role
  • Role_position. positioned_role : Role
  • Role_name.named_role: Role
  • Role_address.addressed_role: Role
  • Role_telcom.addressed_role: Role
  • ManagedParticipation.identified_mparticipation: ManagedParticipation
  • Document_Designation.document: Document

Image:Acimg4.GIF

Delete Generalization Relationships

  • Entity § Living_subject
  • Entity § Organization
  • Entity § Place
  • Entity § Material
  • Entity § Group
  • Living_subject § Person
  • Living_subject § Non_Person_Living_subject
  • Material § Manufactured_material
  • Manufactured_material § Container
  • Manufactured_material § Device
  • Device § Imaging_modality
  • Act § PatientEncounter
  • Act § ControlAct
  • Act § Supply
  • Act § WorkingList
  • Act § Procedure
  • Act § Observation
  • Act § DeviceTask
  • Act § SubstanceAdministration
  • Act § FinancialContract
  • Act § Account
  • Act § FinancialTransaction
  • Act § InvoiceElement
  • Diet § Supply
  • Observation § PublicHealthCase
  • Observation § DiagnosticImage
  • Role § Employee
  • Role § Access
  • Role § QualifiedEntity
  • Role § LicensedEntity
  • Role § Patient
  • Participation § ManagedParticipation
  • ContextStructure § Document

Image:Acimg5.GIF

Propagate Inherited Attributes

Image:Acimg6.GIF

Propagate Inherited Associations

Image:Acimg7.GIF

Simplify datatypes

  • Person.nm: EN ==> PN
  • Organization.nm: EN ==> ON
  • All attributes of type CE ==> CV

Image:Acimg8.GIF

Datatype expansion

Image:Acimg9.GIF

All classes with composed attributes are expanded in the composing parts. The types interested in this process are PN, ON, EN, AD, TEL, II, PQ.


EN


Every attribute of type EN is expanded as the following schema.

This schema models the compositional nature of the attribute EN expanding in a container relationship.

Tables that have a EN attribute, create a table of name tablename_Name_Part table then this table refers the Entity_Name table.


Image:Acimg10.GIF


ON and EN


ON (Organization Name) and PN (Person Name) are specializations of EN that doesn’t add any attribute, so they are expanded in the same way as EN.


AD


AD represents the concept of address and defines it in terms of parts and subparts. It is expanded like in the in schema:


Image:Acimg11.GIF


The Person entity then refer the Person_Person_Address.


TEL


The TEL datatypes represents a set of telephone reference, so it is modeled as a multipart relation that expands in a schema like the following, in this case is showed the relation applied to an Organization entity:


Image:Acimg12.GIF


II

All attributes of type II are expanded in the three compositing sub attributes:

  • root: UID
  • extension: ST
  • authority: ST


PQ


This type of attribute specify a physical quantity, and has many sub attributes as shows in the following schema:


Image:Acimg13.GIF


Every table with a PQ attribute has reference to the table PhysicalQuantity.


Datatype Promotion

In this phase the CV (Coded Value) and CS (Coded Simple Value) data types are expanded in the corresponding UML class schema, so the all attributes of this types implicitly refers to this inserted element.

Image:Acimg14.GIF


LDM-2-PDM

Given a clean LDM, this guide assumes that Hibernate is used to generate the PDM. Hibernate offers 3 different O-R strategies.

We have chosen:

  • table per hierarchy for the 6 foundation classes (and relative sub-classes) and code values: Act, Entity, Role,Participation,ActRelationship & CodeValue.
  • table per concrete class for all other related classes
  • There is a group of 5 tables dedicated to Vocabolaries and DataTypes


 if you are going to use JavaSIG to persist RIM data into the PDM mind that you will have to adapt the wrappers.


PDM 4 MySQL


DATATYPE Mapping


  • REAL = DECIMANL(9,3)
  • ST = VARCHAR(5000)
  • UID = INT(11)
  • ED = VARCHAR(5000)
  • GTS = DATETIME
  • TS = TIMESTAMP
  • BL = BIT(1)
  • INT = INT(11)


PDM 4 ORACLE 11gR1


DATATYPE Mapping


  • REAL = NUMBER
  • ST = VARCHAR(5000)
  • UID = NUMBER
  • ED = VARCHAR(5000)
  • GTS = DATE
  • TS = DATE
  • BL = BOOLEAN
  • INT = NUMBER


WARNINGS


  • Object names cannot be longer than 30 characters, thus some table and index names have to be shorten.
  • "auto increment" capabilities are implemented via the creation of SEQUENCES, incremented by PRE-INSERT db triggers.
CHARACTER SET AL32UTF8;
NATIONAL CHARACTER SET AL16UTF16;

ORACLE ENVIRONMENT

Oracle environment sul server Linux:
EDITOR=vi
export EDITOR
ORACLE_SID=phidb
export ORACLE_SID
ORACLE_BASE=/oracle/app
export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/11.1.0/db_1
export ORACLE_HOME
ORA_CRS_HOME=$ORACLE_BASE/product/11.1.0/crs_1
export ORA_CRS_HOME
LD_LIBRARY_PATH=$ORACLE_HOME/lib
export LD_LIBRARY_PATH
PATH=$ORACLE_BASE/admin/rman/bin:$ORACLE_HOME/bin:
$ORA_CRS_HOME/bin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin:.
export PATH
umask 022
Place all DATAFILES in $ORACLE_BASE/oradata/phidb
Place ".bash_profile" and ".oracle_profile" into /home/oracle
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then . ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
if [ -f ~/.oracle_profile ]; then . ~/.oracle_profile
fi
.oracle_profile
PS1="`/bin/hostname `-> "
export PS1
EDITOR=vi
export EDITOR
ORACLE_SID=phidb
export ORACLE_SID
ORACLE_BASE=/oracle/app
export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/11.1.0/db_1
export ORACLE_HOME
ORA_CRS_HOME=$ORACLE_BASE/product/11.1.0/crs_1
export ORA_CRS_HOME
LD_LIBRARY_PATH=$ORACLE_HOME/lib
export LD_LIBRARY_PATH PATH=$ORACLE_BASE/admin/rman/bin:$ORACLE_HOME/bin:$ORA_CRS_HOME/bin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin:.
export PATH
umask 022
$ORACLE_BASE/admin has the following structure:
phidb
|-- adump
|-- ddl
| |-- arrdb.sql
| |-- dropall.sql
| |-- jbpm.sql
| |-- mkall.log
| |-- mkall.sql
| |-- mktablespaces.sql
| |-- mkusers.sql
| |-- qrtz.sql
| `-- rimpdm2.sql
|-- dpdump
| `-- dp.log
|-- pfile
| |-- crspfile.sql
| `-- init.ora
`-- scripts
|-- CreateDB.sql
|-- CreateDBCatalog.sql
|-- CreateDBFiles.sql
|-- JServer.sql
|-- apex.sql
|-- context.sql
|-- cwmlite.sql
|-- emRepository.sql
| -- init.ora
|-- interMedia.sql
|-- lockAccount.sql
|-- ordinst.sql
|-- owb.sql
|-- phidb.sh
|-- phidb.sql
|-- postDBCreation.sql
|-- spatial.sql
|-- ultraSearch.sql
|-- ultraSearchCfg.sql
`-- xdb_protocol.sql
Personal tools