示例#1
0
def value_quantity(g: Graph, subject: Node,
                   obs_fact: ObservationFact) -> List[ObservationFact]:
    """ Process a FHIR:valueQuantity, recording salient information in obs_fact

    :param g: Graph containing the quantity
    :param subject: Subject of the fhir quantity node
    :param obs_fact: Fact to add the information to
    :return: Empty list - no additional facts are generated
    """
    units = fhirgraphutils.value(g, subject, FHIR.Quantity.unit)
    if not units:
        system = fhirgraphutils.value(g, subject, FHIR.Quantity.system)
        code = fhirgraphutils.value(g, subject, FHIR.Quantity.code)
        if code:
            ns = fhir_namespace_for(system)
            units = ((ns.upper() + ':') if ns else '') + code

    comparator = fhirgraphutils.value(g, subject, FHIR.Quantity.comparator)
    value_ = fhirgraphutils.value(g, subject, FHIR.Quantity.value)
    if value_ is not None:
        obs_fact._valtype_cd = valuetype_number
        obs_fact._nval_num = value_
        obs_fact._tval_char = 'E' if comparator is None else comparator_map.get(
            str(comparator), '?')
        obs_fact._units_cd = str(units) if units else None
    else:
        obs_fact._valtype_cd = valuetype_novalue
    return []
示例#2
0
    def test_value_quantity_units(self):
        self.g.parse(os.path.join(self.test_dir, 'observation-example-f204-creatinine-unit2.ttl'), format="turtle")
        s = URIRef("http://hl7.org/fhir/Observation/f204")

        # Units present
        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        qval = self.g.value(s, FHIR.Observation.valueQuantity1)
        value_quantity(self.g, qval, obsf)
        self.assertEqual('umol/L', obsf.units_cd)

        # System/code
        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        qval = self.g.value(s, FHIR.Observation.valueQuantity2)
        value_quantity(self.g, qval, obsf)
        self.assertEqual('SCT:258814008', obsf.units_cd)

        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        qval = self.g.value(s, FHIR.Observation.valueQuantity3)
        value_quantity(self.g, qval, obsf)
        self.assertEqual('GPF', obsf.units_cd)

        # No units at all
        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        qval = self.g.value(s, FHIR.Observation.valueQuantity4)
        value_quantity(self.g, qval, obsf)
        self.assertIsNone(obsf.units_cd)
示例#3
0
 def setUp(self):
     from i2fhirb2.i2b2model.data.i2b2observationfact import ObservationFact, ObservationFactKey
     ObservationFact._clear()
     ObservationFact.update_date = datetime(2017, 2, 19, 12, 33)
     # Patient / provider / encounter / start date
     self.ofk = ObservationFactKey(12345, 23456, 'provider', datetime(2017, 5, 23, 11, 17))
     
     self.g = Graph()
示例#4
0
def value_integer(g: Graph, subject: Node,
                  obs_fact: ObservationFact) -> List[ObservationFact]:
    """ Process a FHIR:valueInteger, recording salient information in obs_fact

    :param g: Graph containing the quantity
    :param subject: Subject of the fhir quantity node
    :param obs_fact: Fact to add the information to
    :return: Empty list - no additional facts are generated
    """
    obs_fact._valtype_cd = valuetype_number
    obs_fact._nval_num = g.value(subject, FHIR.value, any=False).value
    obs_fact._tval_char = 'E'
    return []
示例#5
0
    def test_value_string(self):
        self.g.parse(os.path.join(self.test_dir, 'observation-example-eye-color.ttl'), format="turtle")
        obsf = ObservationFact(self.ofk, FHIR.string)
        s = URIRef("http://hl7.org/fhir/Observation/eye-color")
        sval = self.g.value(s, FHIR.Observation.valueString)
        vs = value_string(self.g, sval, obsf)
        self.assertEqual(0, len(vs))
        self.assertEqual(valuetype_text.code, obsf.valtype_cd)
        self.assertEqual("blue", obsf.tval_char)

        obsf = ObservationFact(self.ofk, FHIR.string)
        vs2 = proc_value_node(self.g, obsf, FHIR.Observation.valueString, sval)
        self.assertEqual(0, len(vs2))
        self.assertEqual("blue", obsf.tval_char)
示例#6
0
 def test_value_integer(self):
     self.g.parse(os.path.join(self.test_dir, 'diagnosticreport-micro1.ttl'), format="turtle")
     s = URIRef("https://example.com/base/Observation/obx2-10")
     obsf = ObservationFact(self.ofk, FHIR.integer)
     qval = self.g.value(s, FHIR.Observation.valueInteger)
     vs = value_integer(self.g, qval, obsf)
     self.assertEqual(0, len(vs))
     self.assertEqual('E', obsf.tval_char)
     self.assertEqual(-17243, obsf.nval_num)
     self.assertIsNone(obsf.units_cd)
     # Dispatch test
     obsf = ObservationFact(self.ofk, FHIR.string)
     vs2 = proc_value_node(self.g, obsf, FHIR.Observation.valueInteger, qval)
     self.assertEqual(-17243, obsf.nval_num)
示例#7
0
def value_string(g: Graph, node: Node,
                 obs_fact: ObservationFact) -> List[ObservationFact]:
    """ Convert a FHIR.string type value into the i2b2 equivalent

    :param g: Graph containing the data
    :param node: Node containing the string value
    :param obs_fact: target fact to have string added to it
    :return: Empty list - no additional facts are generated
    """
    obs_fact._valtype_cd = valuetype_text
    obs_fact._tval_char = g.value(node,
                                  FHIR.value,
                                  default=Literal(""),
                                  any=False).value
    return []
示例#8
0
def value_codeable_concept(g: Graph, subject: Node,
                           obs_fact: ObservationFact) -> List[ObservationFact]:
    """ Process a FHIR:valueCodeableConcept node.  The first FHIR:CodeableConcept.coding entry is recorded as
    the value for the passed `obs_fact`.  Additional obs_fact entries are generated to carry the text, if it exists,
    and any additional codings.

    :param g: Graph containing the data
    :param subject: CodeableConcept node
    :param obs_fact: target fact(s)
    :return: Additional obs_facts beyond obs_fact itself
    """
    from i2fhirb2.fhir.fhirobservationfact import FHIRObservationFact

    rval = []
    if obs_fact.modifier_cd != '@':
        print(
            f"{obs_fact.concept_cd}, {obs_fact.modifier_cd}: Modifier on modifier!"
        )
    codings = sorted(list(g.objects(subject, FHIR.CodeableConcept.coding)))
    additional_entries = False
    if codings:
        for coding in codings:
            obs_fact_copy = copy.copy(obs_fact)
            if obs_fact.modifier_cd == '@':
                concept_uri = concept_uri_for(g, coding)
                concept_ns_name = FHIRObservationFact.ns_name_for(
                    concept_uri) if concept_uri else None
                if concept_ns_name:
                    obs_fact._modifier_cd = concept_ns_name
            display = fhirgraphutils.value(g, coding, FHIR.Coding.display)
            if not display:
                display = fhirgraphutils.value(g, subject,
                                               FHIR.CodeableConcept.text)
            if display:
                obs_fact._valtype_cd = valuetype_text
                obs_fact._tval_char = display
                if additional_entries:
                    rval.append(obs_fact)
                else:
                    additional_entries = True
                obs_fact = obs_fact_copy
    else:
        text = fhirgraphutils.value(g, subject, FHIR.CodeableConcept.text)
        if text:
            obs_fact._valtype_cd = valuetype_text
            obs_fact._tval_char = text

    return rval
示例#9
0
    def test_value_codeable_concept_2(self):
        self.g.parse(os.path.join(self.test_dir, 'observation-example-2minute-apgar-score.ttl'), format="turtle")
        s = URIRef("http://hl7.org/fhir/Observation/2minute-apgar-score")
        found = False
        for v in self.g.objects(s, FHIR.Observation.component):
            if self.g.value(v, FHIR.index).value == 0:
                found = True
                cval = self.g.value(v, FHIR.Observation.component.valueCodeableConcept, any=False)
                obsf = ObservationFact(self.ofk, FHIR.CodeableConcept)
                output_buffer = StringIO()
                with redirect_stdout(output_buffer):
                    addl_facts = value_codeable_concept(self.g, cval, obsf)
                self.assertTrue('Unrecognized namespace: http:/acme.ped/apgarcolor/' in output_buffer.getvalue())

                self.assertEqual(valuetype_text.code, obsf.valtype_cd)
                self.assertEqual('1. Good color in body with bluish hands or feet', obsf.tval_char)
                self.assertEqual('@', obsf.modifier_cd)

                self.assertEqual(1, len(addl_facts))
                obsf2 = addl_facts[0]

                self.assertEqual(valuetype_text.code, obsf2.valtype_cd)
                self.assertEqual("Good color in body with bluish hands or feet", obsf2.tval_char)
                self.assertEqual("LOINC:LA6723-6", obsf2.modifier_cd)

        self.assertTrue(found)
示例#10
0
 def test_value_codeable_concept_1(self):
     self.g.parse(os.path.join(self.test_dir, 'diagnosticreport-micro1.ttl'), format="turtle")
     s = URIRef("https://example.com/base/Observation/obx1-4")
     obsf = ObservationFact(self.ofk, FHIR.CodeableConcept)
     cval = self.g.value(s, FHIR.Observation.valueCodeableConcept)
     vs = value_codeable_concept(self.g, cval, obsf)
     self.assertEqual(0, len(vs))
     self.assertEqual(valuetype_text.code, obsf.valtype_cd)
     self.assertEqual("Staphylococcus aureus", obsf.tval_char)
     self.assertEqual("@", obsf.modifier_cd)
示例#11
0
 def clear_i2b2_sourcesystems(tables: I2B2Tables, sourcesystemcd: str) -> None:
     print("Deleted {} patient_dimension records"
           .format(PatientDimension.delete_sourcesystem_cd(tables, sourcesystemcd)))
     print("Deleted {} patient_mapping records"
           .format(PatientMapping.delete_sourcesystem_cd(tables, sourcesystemcd)))
     print("Deleted {} observation_fact records"
           .format(ObservationFact.delete_sourcesystem_cd(tables, sourcesystemcd)))
     print("Deleted {} visit_dimension records"
           .format(VisitDimension.delete_sourcesystem_cd(tables, sourcesystemcd)))
     print("Deleted {} encounter_mapping records"
           .format(EncounterMapping.delete_sourcesystem_cd(tables, sourcesystemcd)))
示例#12
0
 def test_basics(self):
     from i2fhirb2.i2b2model.data.i2b2observationfact import ObservationFact, ObservationFactKey
     ObservationFact._clear()
     ObservationFact.update_date = datetime(2017, 2, 19, 12, 33)
     with self.sourcesystem_cd():
         ObservationFact.sourcesystem_cd = self._sourcesystem_cd
         ofk = ObservationFactKey(12345, 23456, 'provider',
                                  datetime(2017, 5, 23, 11, 17))
         x = ObservationFact(ofk,
                             'fhir:concept',
                             sourcesystem_cd=self._sourcesystem_cd)
         self.assertEqual(
             'encounter_num\tpatient_num\tconcept_cd\tprovider_id\tstart_date\tmodifier_cd\tinstance_num\t'
             'valtype_cd\ttval_char\tnval_num\tvalueflag_cd\tquantity_num\tunits_cd\tend_date\t'
             'location_cd\tobservation_blob\tconfidence_num\tupdate_date\tdownload_date\timport_date\t'
             'sourcesystem_cd\tupload_id', x._header())
         self.assertEqual(
             OrderedDict([('encounter_num', 23456), ('patient_num', 12345),
                          ('concept_cd', 'fhir:concept'),
                          ('provider_id', 'provider'),
                          ('start_date', datetime(2017, 5, 23, 11, 17)),
                          ('modifier_cd', '@'), ('instance_num', 0),
                          ('valtype_cd', '@'), ('tval_char', None),
                          ('nval_num', None), ('valueflag_cd', None),
                          ('quantity_num', None), ('units_cd', None),
                          ('end_date', None), ('location_cd', None),
                          ('observation_blob', None),
                          ('confidence_num', None),
                          ('update_date', datetime(2017, 2, 19, 12, 33)),
                          ('download_date', datetime(2017, 2, 19, 12, 33)),
                          ('import_date', datetime(2017, 2, 19, 12, 33)),
                          ('sourcesystem_cd', self._sourcesystem_cd),
                          ('upload_id', None)]), x._freeze())
示例#13
0
    def test_value_quantity(self):
        self.g.parse(os.path.join(self.test_dir, 'observation-example-f204-creatinine.ttl'), format="turtle")
        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        s = URIRef("http://hl7.org/fhir/Observation/f204")
        qval = self.g.value(s, FHIR.Observation.valueQuantity)
        vs = value_quantity(self.g, qval, obsf)
        self.assertEqual(0, len(vs))
        self.assertEqual(valuetype_number.code, obsf.valtype_cd)
        self.assertEqual('E', obsf.tval_char)
        self.assertEqual(122, obsf.nval_num)
        self.assertEqual('umol/L', obsf.units_cd)

        # Test '>'
        self.g.parse(os.path.join(self.test_dir, 'diagnosticreport-micro1.ttl'), format="turtle")
        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        s = URIRef("https://example.com/base/Observation/obx2-2")
        qval = self.g.value(s, FHIR.Observation.valueQuantity)
        vs = value_quantity(self.g, qval, obsf)
        self.assertEqual(0, len(vs))
        self.assertEqual('G', obsf.tval_char)
        self.assertEqual(2, obsf.nval_num)
        self.assertIsNone(obsf.units_cd)

        # Test '>='
        s = URIRef("https://example.com/base/Observation/obx2-4")
        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        qval = self.g.value(s, FHIR.Observation.valueQuantity)
        vs = value_quantity(self.g, qval, obsf)
        self.assertEqual(0, len(vs))
        self.assertEqual('GE', obsf.tval_char)
        self.assertEqual(4, obsf.nval_num)
        self.assertIsNone(obsf.units_cd)

        # Test '<'
        s = URIRef("https://example.com/base/Observation/obx2-6")
        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        qval = self.g.value(s, FHIR.Observation.valueQuantity)
        vs = value_quantity(self.g, qval, obsf)
        self.assertEqual(0, len(vs))
        self.assertEqual('L', obsf.tval_char)
        self.assertEqual(0.5, obsf.nval_num)
        self.assertIsNone(obsf.units_cd)

        # Test '<;
        s = URIRef("https://example.com/base/Observation/obx2-8")
        obsf = ObservationFact(self.ofk, FHIR.SimpleQuantity)
        qval = self.g.value(s, FHIR.Observation.valueQuantity)
        vs = value_quantity(self.g, qval, obsf)
        self.assertEqual(0, len(vs))
        self.assertEqual('LE', obsf.tval_char)
        self.assertEqual(1, obsf.nval_num)
        self.assertIsNone(obsf.units_cd)

        # Dispatch test
        obsf = ObservationFact(self.ofk, FHIR.string)
        vs2 = proc_value_node(self.g, obsf, FHIR.Observation.valueQuantity, qval)
        self.assertEqual(0, len(vs2))
        self.assertEqual(1, obsf.nval_num)
    def test_sourcesystem_cd(self):
        ObservationFact._clear()
        ofk = ObservationFactKey(1, 1, "Provider")
        obsf = ObservationFact(ofk, "FHIR:Test")
        fobsf = FHIRObservationFact(Graph(), ofk, "FHIR:test", None, None)
        if obsf.sourcesystem_cd != "Unspecified":
            print("HERE")
        self.assertEqual("Unspecified", obsf.sourcesystem_cd)
        self.assertEqual("Unspecified", fobsf.sourcesystem_cd)

        cd1 = "SourceSystemCdTestCase_cd1"
        cd2 = "SourceSystemCdTestCase_cd2"
        ObservationFact.sourcesystem_cd = cd1
        FHIRObservationFact.sourcesystem_cd = cd2


        self.assertEqual(cd2, obsf.sourcesystem_cd)
        self.assertEqual(cd2, fobsf.sourcesystem_cd)
        ObservationFact._clear()
        self.assertEqual("Unspecified", obsf.sourcesystem_cd)
        self.assertEqual("Unspecified", fobsf.sourcesystem_cd)

        ObservationFact.sourcesystem_cd = cd1
        FHIRObservationFact.sourcesystem_cd = cd2
        self.assertEqual(cd2, obsf.sourcesystem_cd)
        self.assertEqual(cd2, fobsf.sourcesystem_cd)
        FHIRObservationFact._clear()
        self.assertEqual("Unspecified", obsf.sourcesystem_cd)
        self.assertEqual("Unspecified", fobsf.sourcesystem_cd)

        ObservationFact.sourcesystem_cd = cd1
        self.assertEqual(cd1, obsf.sourcesystem_cd)
        self.assertEqual(cd1, fobsf.sourcesystem_cd)
        FHIRObservationFact._clear()
        self.assertEqual("Unspecified", obsf.sourcesystem_cd)
        self.assertEqual("Unspecified", fobsf.sourcesystem_cd)
示例#15
0
 def clear_i2b2_tables(tables: I2B2Tables, uploadid: int) -> None:
     """
     Remove all entries in the i2b2 tables for uploadid.
     :param tables:
     :param uploadid:
     :return:
     """
     # This is a static function to support the removefacts operation
     print("Deleted {} patient_dimension records"
           .format(PatientDimension.delete_upload_id(tables, uploadid)))
     print("Deleted {} patient_mapping records"
           .format(PatientMapping.delete_upload_id(tables, uploadid)))
     print("Deleted {} observation_fact records"
           .format(ObservationFact.delete_upload_id(tables, uploadid)))
     print("Deleted {} visit_dimension records"
           .format(VisitDimension.delete_upload_id(tables, uploadid)))
     print("Deleted {} encounter_mapping records"
           .format(EncounterMapping.delete_upload_id(tables, uploadid)))
示例#16
0
 def load_i2b2_tables(self, check_dups=False) -> None:
     # session = sessionmaker(bind=tables.crc_engine)()
     I2B2Core._check_dups = check_dups
     if self._opts.remove:
         # TODO: This should really be within a transaction boundary
         self.clear_i2b2_tables(self._opts.tables, self._opts.uploadid)
     change_column_length(self._opts.tables.observation_fact, self._opts.tables.observation_fact.c.concept_cd,
                          200, self._opts.tables.crc_connection)
     change_column_length(self._opts.tables.observation_fact, self._opts.tables.observation_fact.c.modifier_cd,
                          200, self._opts.tables.crc_connection)
     print("{} / {} patient_dimension records added / modified"
           .format(*PatientDimension.add_or_update_records(self._opts.tables, self.patient_dimensions)))
     print("{} / {} patient_mapping records added / modified"
           .format(*PatientMapping.add_or_update_records(self._opts.tables, self.patient_mappings)))
     print("{} / {} visit_dimension records added / modified"
           .format(*VisitDimension.add_or_update_records(self._opts.tables, self.visit_dimensions)))
     print("{} / {} encounter_mapping records added / modified"
           .format(*EncounterMapping.add_or_update_records(self._opts.tables, self.encounter_mappings)))
     print("{} / {} observation_fact records added / modified"
           .format(*ObservationFact.add_or_update_records(self._opts.tables, self.observation_facts)))
    def test_insert(self):
        from i2fhirb2.i2b2model.data.i2b2observationfact import ObservationFactKey

        print("{} records deleted".format(ObservationFact.delete_upload_id(self.opts.tables, self.opts.uploadid)))
        ofk = ObservationFactKey(12345, 23456, 'provider', datetime(2017, 5, 23, 11, 17))
        ObservationFact.update_date = datetime(2017, 2, 19, 12, 33)
        with self.sourcesystem_cd():
            ObservationFact.sourcesystem_cd = self._sourcesystem_cd
            ObservationFact.upload_id = self.opts.uploadid
            obsf = ObservationFact(ofk, 'fhir:concept', sourcesystem_cd="FHIR R4")
            n_ins, n_upd = ObservationFact.add_or_update_records(self.opts.tables, [obsf])
            self.assertEqual((0, 1), (n_upd, n_ins))
            obsf._instance_num = 2
            obsf2 = ObservationFact(ofk, 'fhir:concept', sourcesystem_cd="FHIR R4z")
            obsf2._instance_num = 2
            obsf2._modifier_cd = "fhir:modifier"
            n_ins, n_upd = ObservationFact.add_or_update_records(self.opts.tables, [obsf, obsf2])
            self.assertEqual((0, 2), (n_upd, n_ins))
            self.assertEqual(3, ObservationFact.delete_upload_id(self.opts.tables, self.opts.uploadid))
 def tearDown(self):
     ObservationFact._clear()
示例#19
0
 def _clear(cls, complete=True):
     cls._unknown_namespaces = []
     ObservationFact._clear(complete)
示例#20
0
    def as_observation_facts(self, encounter_num: int, provider_id: str,
                             start_date: datetime) -> List[ObservationFact]:
        rval = []
        pde = self.patient_dimension_entry
        ofk = ObservationFactKey(self.patient_dimension_entry.patient_num,
                                 encounter_num, provider_id, start_date)

        # Age entry
        rval.append(
            ObservationFact(ofk,
                            I2B2DemographicsCodes.age(pde.age_in_years_num)))

        # Sex
        rval.append(
            ObservationFact(
                ofk, I2B2DemographicsCodes.sex_female if pde.sex_cd == 'F' else
                I2B2DemographicsCodes.sex_male if pde.sex_cd == 'M' else
                I2B2DemographicsCodes.sex_undifferentiated
                if pde.sex_cd == 'U' else I2B2DemographicsCodes.sex_unknown))

        # Birthdate
        if pde.birth_date:
            bd_of = ObservationFact(ofk, I2B2DemographicsCodes.birthdate)
            bd_of._date_val(pde.birth_date)
            rval.append(bd_of)

        # Deathdate
        if pde.death_date:
            dd_of = ObservationFact(ofk, I2B2DemographicsCodes.birthdate)
            dd_of._date_val(pde.death_date)
            rval.append(dd_of)

        # Language
        rval.append(
            ObservationFact(ofk,
                            I2B2DemographicsCodes.language(self._language)))

        # Marital status
        rval.append(
            ObservationFact(
                ofk,
                I2B2DemographicsCodes.marital_status(self._marital_status)))

        # race
        rval.append(
            ObservationFact(ofk, I2B2DemographicsCodes.race(self._race)))

        # religion
        # Religion codes currently like the FHIR
        rval.append(
            ObservationFact(ofk,
                            I2B2DemographicsCodes.religion(self._religion)))

        # vital -- no idea what vital_deferred means
        rval.append(
            ObservationFact(
                ofk, I2B2DemographicsCodes.vital_living if
                pde._vital_status_code.dd_deceased == VitalStatusCd.dd_living
                else I2B2DemographicsCodes.vital_unknown
                if pde._vital_status_code.dd_unknown else
                I2B2DemographicsCodes.vital_dead))

        # zip
        rval.append(ObservationFact(ofk,
                                    I2B2DemographicsCodes.zip(pde.zip_cd)))

        return rval