WHO SMART Guideline: Surveillance and Outbreak Toolkit
0.2.1 - CI Build International flag

WHO SMART Guideline: Surveillance and Outbreak Toolkit, published by WHO. This is not an authorized publication; it is the continuous build for version 0.2.1. This version is based on the current content of https://github.com/WorldHealthOrganization/smart-ot and changes regularly. See the Directory of published versions

StructureMap:

Official URL: http://worldhealthorganization.github.io/smart-ot/StructureMap/AFROMRCIFLogicalModelToResources Version: 0.2.1
Draft as of 2023-11-07 Computable Name: AFROMRCIFLogicalModelToResources
map "http://worldhealthorganization.github.io/smart-ot/StructureMap/AFROMRCIFLogicalModelToResources" = "AFROMRCIFLogicalModelToResources"

uses "http://worldhealthorganization.github.io/smart-ot/StructureDefinition/AFROMRCIF" alias MeaslesLogicalModel as source
uses "http://hl7.org/fhir/StructureDefinition/Bundle" alias MeaslesCIFBundle as target
uses "http://worldhealthorganization.github.io/smart-ot/StructureDefinition/MeaslesCIFComposition" alias MeaslesCIFComposition as target

imports "http://worldhealthorganization.github.io/smart-ot/StructureMap/MetaDataTypesHelper"

group MRCIFLogicalModelToResources(source lm : AFROMRCIF, target bundle : Bundle) {
  lm -> bundle.type = 'document' "set bundle type";
  // lm.ReportingSource as reportingSource then {     reportingSource.DateReportedNational as date -> bundle.timestamp = date "set date";   } "set timestamp";
  lm ->  uuid() as bid,  bundle.id = bid "set id";
  lm ->  uuid() as cid,  uuid() as pid,  uuid() as prid,  uuid() as oid,  uuid() as eid then {
    lm ->  bundle.entry as entry,  entry.resource = create('Composition') as composition,  entry.fullUrl = append('urn:uuid:', cid) then {
      lm -> lm then LmToComposition(lm, composition, cid, pid, prid, oid, eid) "set";
      lm ->  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', pid),  create('Patient') as patient then {
        lm.Demographics as demographics -> demographics then DemographicsToPatient(demographics, patient, pid) "create patient";
        lm -> entry.resource = patient "set patient as entry";
      } "map patient resource";
      lm ->  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', prid),  create('Practitioner') as practitioner then {
        lm.Classification as classification -> classification then classificationToPractitioner(classification, practitioner, prid) "create practitioner";
        lm -> entry.resource = practitioner "set practitioner as entry";
      } "map practitioner resource";
      lm ->  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', oid),  create('Organization') as organization then {
        lm.ReportingSource as reportingSource -> reportingSource then ReportingSourceToOrganization(reportingSource, organization, oid) "create organization";
        lm -> entry.resource = organization "set organization as entry";
      } "map organization resource";
      lm ->  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', eid),  create('Encounter') as encounter then {
        lm.lmCaseInvestigation as var then {
          var.DateOfConsultation as date then {
            date ->  create('Coding') as type,  type.code = 'AMB',  type.system = 'http://terminology.hl7.org/CodeSystem/v3-ActCode',  type.display = 'ambulatory' then createCompositionEncounterResource(date, pid, type, eid, encounter) "create encounter";
          } "set encounter";
        } "set encounter";
        lm -> entry.resource = encounter "set encounter as entry";
      } "map encounter resource";
      lm -> lm then mapClinicalToObservations(lm, bundle, composition, pid) "set clinical data";
      lm -> lm then mapLabsToDiagnosticReport(lm, bundle, composition, pid) "set labs data";
      lm -> lm then mapVaccinationStatusToImmunization(lm, bundle, composition, pid) "set immunization data";
      lm -> lm then mapClassificationToConditions(lm, bundle, composition, pid, eid) "set classification";
    } "map composition resource";
  } "set entries";
}

group mapClassificationToConditions(source lm : MeaslesLogicalModel, target bundle : Bundle, target composition : MeaslesCIFComposition, source pid, source eid) {
  lm ->  composition.section as section,  section.title = 'Classification' then {
    lm.Classification as classification ->  uuid() as id,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', id),  section.entry as sectionEntry,  sectionEntry.reference = append('Condition/', id),  entry.resource = create('Condition') as condition then {
      classification -> condition.id = id "set id";
      classification ->  condition.verificationStatus as tgtStatus,  create('Coding') as status,  status.code = 'confirmed',  status.system = 'http://terminology.hl7.org/CodeSystem/condition-ver-status',  status.display = 'Confirmed' then mapCodingtoCodeableConcept(status, tgtStatus) "set";
      classification ->  condition.subject as subject,  subject.reference = append('Patient/', pid) "set subject";
      classification.FinalClassification as coding -> condition.code as code then mapCodingtoCodeableConcept(coding, code) "set code";
      classification ->  condition.encounter as encounter,  encounter.reference = append('Encounter/', eid) "set subject";
      classification ->  condition.category as tgt,  create('Coding') as status,  status.code = 'encounter-diagnosis',  status.system = 'http://terminology.hl7.org/CodeSystem/condition-category',  status.display = 'Encounter Diagnosis' then mapCodingtoCodeableConcept(status, tgt) "set";
      classification.ClassificationDate as date -> condition.recordedDate = date "set";
      classification.ClassifiedBy as person ->  uuid() as rpid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', rpid),  section.entry as sectionEntry,  sectionEntry.reference = append('RelatedPerson/', rpid),  entry.resource = create('RelatedPerson') as recorder then {
        person -> recorder.id = rpid "set id";
        person ->  recorder.name as targetName,  create('HumanName') as name,  name.text = person then humanNameToHumanName(name, targetName) "set";
        person ->  recorder.patient as patient,  patient.reference = append('Patient/', pid) "set patient";
      } "set person";
    } "Set classification";
  } "set section";
}

group mapContactTracing(source lm : MeaslesLogicalModel, target bundle : Bundle, target composition : MeaslesCIFComposition, source pid) {
  lm ->  composition.section as section,  section.title = 'Contact Tracing' "set";
}

group mapClinicalToObservations(source lm : AFROMRCIF, target bundle : Bundle, target composition : Composition, source pid) {
  lm ->  composition.section as section,  section.title = 'Clinical Data, Follow up and Treatment' then {
    lm.Clinical as clinical -> clinical then {
      clinical.Fever as fever ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        fever -> observation.id = obsid "set obsid";
        fever ->  create('Coding') as coding,  coding.code = 'DE31',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Fever' then {
          fever -> fever then createObservationResource(fever, coding, observation, pid) "set obs";
        } "set obs";
      } "set fever";
      clinical.Rash as rash ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        rash -> observation.id = obsid "set obsid";
        rash ->  create('Coding') as coding,  coding.code = 'DE35',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Rash' then {
          rash -> rash then createObservationResource(rash, coding, observation, pid) "set obs";
          lm.lmCaseInvestigation as var then {
            var.RashOnsetDate as onsetDate ->  create('Period') as period,  period.start = onsetDate,  observation.effective = period "set start date";
          } "set";
        } "set obs";
      } "set Rash";
      clinical.Cough as cough ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        cough -> observation.id = obsid "set obsid";
        cough ->  create('Coding') as coding,  coding.code = 'DE39',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Cough' then {
          cough -> cough then createObservationResource(cough, coding, observation, pid) "set obs";
        } "set obs";
      } "set cough";
      clinical.Conjunctivitis as conjunctivitis ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        conjunctivitis -> observation.id = obsid "set obsid";
        conjunctivitis ->  create('Coding') as coding,  coding.code = 'DE43',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Conjunctivitis' then {
          conjunctivitis -> conjunctivitis then createObservationResource(conjunctivitis, coding, observation, pid) "set obs";
        } "set obs";
      } "set conjunctivitis";
      clinical.Coryza as coryza ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        coryza -> observation.id = obsid "set obsid";
        coryza ->  create('Coding') as coding,  coding.code = 'DE47',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Coryza' then {
          coryza -> coryza then createObservationResource(coryza, coding, observation, pid) "set obs";
        } "set obs";
      } "set coryza";
      clinical.Lymphadenopathy as lymphadenopathy ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        lymphadenopathy -> observation.id = obsid "set obsid";
        lymphadenopathy ->  create('Coding') as coding,  coding.code = 'DE51',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Lymphadenopathy' then {
          lymphadenopathy -> lymphadenopathy then createObservationResource(lymphadenopathy, coding, observation, pid) "set obs";
        } "set obs";
      } "set lymphadenopathy";
      clinical.JointPain as jointPain ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        jointPain -> observation.id = obsid "set obsid";
        jointPain ->  create('Coding') as coding,  coding.code = 'DE55',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Joint Pain' then {
          jointPain -> jointPain then createObservationResource(jointPain, coding, observation, pid) "set obs";
        } "set obs";
      } "set jointPain";
      clinical.Outcome as outcome ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        outcome -> observation.id = obsid "set obsid";
        outcome ->  create('Coding') as coding,  coding.code = 'DE63',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Outcome' then {
          outcome -> outcome then createObservationResource(outcome, coding, observation, pid) "set obs";
        } "set obs";
      } "set outcome";
      clinical.travelledOutside as travel ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        travel -> observation.id = obsid "set obsid";
        travel ->  create('Coding') as coding,  coding.code = 'DE67',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Outcome' then {
          travel -> travel then createObservationResource(travel, coding, observation, pid) "set obs";
        } "set obs";
      } "set travel";
      // clinical.specifyInfectionSetting as infection -> uuid() as obsid, bundle.entry as entry, entry.fullUrl = append('urn:uuid:', obsid), section.entry as sectionEntry, sectionEntry.reference = append('Observation/', obsid), entry.resource = create('Observation') as observation then {        infection -> observation.id = obsid "set obsid";        infection -> create('Coding') as coding, coding.code = "DE71", coding.system = "http://worldhealthorganization.github.io/smart-ot/AFROMRCIF", coding.display = "Outcome" then {            infection -> infection then createObservationResource(infection, coding, observation, pid) "set obs";          } "set obs";       } "set infection";
      clinical.HistoryOfHospitalization as admitted ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  section.entry as sectionEntry,  sectionEntry.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        admitted -> observation.id = obsid "set obsid";
        admitted ->  create('Coding') as coding,  coding.code = 'DE59',  coding.system = 'http://worldhealthorganization.github.io/smart-ot/AFROMRCIF',  coding.display = 'Outcome' then {
          admitted -> admitted then createObservationResource(admitted, coding, observation, pid) "set obs";
        } "set obs";
      } "set infection";
    } "set clinical";
  } "set section";
}

group createObservationResource(source src, source coding : Coding, target observation : Observation, source pid) {
  src ->  create('CodeableConcept') as code,  code.coding = coding,  observation.code = code "set code";
  src ->  create('CodeableConcept') as value,  value.coding = src,  observation.value = value "set value";
  src -> observation.status = 'registered' "set status";
  src -> observation.subject as subject then {
    src -> subject.reference = append('Patient/', pid) "set subject";
  } "set subject";
}

group mapLabsToDiagnosticReport(source lm : MeaslesLogicalModel, target bundle : Bundle, target composition : MeaslesCIFComposition, source pid) {
  lm ->  composition.section as section,  section.title = 'Specimens & Laboratory Testing' then {
    lm.LaboratoryResults as labs ->  uuid() as id,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', id),  section.entry as sectionEntry,  sectionEntry.reference = append('DiagnosticReport/', id),  entry.resource = create('DiagnosticReport') as diagnosticReport then {
      labs -> diagnosticReport.id = id "set id";
      labs -> diagnosticReport.status = 'registered' "set status";
      labs ->  diagnosticReport.subject as subject,  subject.reference = append('Patient/', pid) "set subject";
      labs.Antigen as antigen -> diagnosticReport.code as code then mapCodingtoCodeableConcept(antigen, code) "set code";
      labs ->  uuid() as id,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', id),  diagnosticReport.specimen as refSpecimen,  refSpecimen.reference = append('Specimen/', id),  entry.resource = create('Specimen') as specimen then {
        labs -> specimen.id = id "Set idn";
        labs.SpecimenCollectionDate as collectDate ->  specimen.collection as collection,  collection.collected = collectDate "set date";
        // labs.SpecimenSentDate as sentDate ->
        labs.SpecimenRecdDate as recdDate -> specimen.receivedTime = recdDate "set date";
        // labs.SampleId as sampleId -> specimen.identifier as identifier, identifier.value = sampleId "set identifier";
        labs.SampleType as sampleType -> specimen.type = sampleType "set type";
        labs.SpecimenNumber as number then {
          number.display as text ->  specimen.note as note,  note.text = text "set note";
        } "set note";
      } "set specimen";
      labs ->  uuid() as id,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', id),  diagnosticReport.performer as performer,  performer.reference = append('Organization/', id),  entry.resource = create('Organization') as perfOrg then {
        labs.LabName as labName -> perfOrg.name = labName "set name";
        labs -> perfOrg.id = id "set id";
      } "set performer";
      labs ->  uuid() as obsid,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', obsid),  diagnosticReport.result as result,  result.reference = append('Observation/', obsid),  entry.resource = create('Observation') as observation then {
        labs -> observation.id = obsid "set obsid";
        labs.TypeOfTest as testType -> testType then {
          labs.Results as result -> result then createObservationResource(result, testType, observation, pid) "set obs";
          labs.LabResultsDate as resultDate -> observation.effective = resultDate "set start date";
        } "set testType";
      } "set results";
      labs.TypeOfTest as testType -> diagnosticReport.code = testType "set code";
      labs.LabResultsDate as resultDate -> diagnosticReport.effective = resultDate "set date";
    } "set diagnosticReport";
  } "set section";
}

group createImmunizationResource(source vax : AFROMRCIFVaccinationStatus, target bundle : Bundle, target section : Element, source pid) {
  vax ->  uuid() as id,  bundle.entry as entry,  entry.fullUrl = append('urn:uuid:', id),  section.entry as sectionEntry,  sectionEntry.reference = append('Immunization/', id),  entry.resource = create('Immunization') as immunization then {
    vax -> immunization.id = id "set id";
    vax -> immunization.status = 'completed' "set status";
    vax -> immunization.vaccineCode as code then {
      vax.VaccineType as vaccineType -> vaccineType then mapCodingtoCodeableConcept(vaccineType, code) "set code";
    } "set";
    vax.Source as source -> immunization.reportOrigin as origin then {
      source -> source then mapCodingtoCodeableConcept(source, origin) "set report origin";
    } "set";
    vax.LastDoseDate as date -> immunization.occurrence = date "set date";
    vax.NumberOfDoses as doses then {
      doses.display as seriesDose ->  immunization.protocolApplied as protocol,  protocol.series = seriesDose "set";
    } "set dosenumber";
    vax ->  immunization.patient as subject,  subject.reference = append('Patient/', pid) "set subject";
  } "ad";
}

group mapVaccinationStatusToImmunization(source lm : MeaslesLogicalModel, target bundle : Bundle, target composition : MeaslesCIFComposition, source pid) {
  lm ->  composition.section as section,  section.title = 'Vaccination History' then {
    lm.VaccinationStatus as vax then {
      vax.NumberOfDoses as doses where code = '99' -> doses then createImmunizationResource(vax, bundle, section, pid) "do";
      vax.NumberOfDoses as doses where code = '1' -> doses then {
        vax.LastDoseDate as date -> date then createImmunizationResource(vax, bundle, section, pid) "do1";
      } "set";
      vax.NumberOfDoses as doses where code = '2' then {
        doses -> doses then createImmunizationResource(vax, bundle, section, pid) "do2";
        vax.LastDoseDate as date -> date then createImmunizationResource(vax, bundle, section, pid) "do";
      } "set doses";
      vax.NumberOfDoses as doses where code = '3' then {
        vax -> doses then createImmunizationResource(vax, bundle, section, pid) "do";
        vax -> doses then createImmunizationResource(vax, bundle, section, pid) "do";
        vax.LastDoseDate as date -> date then createImmunizationResource(vax, bundle, section, pid) "do";
      } "set doses";
      vax.NumberOfDoses as doses where code = '4' then {
        vax -> doses then createImmunizationResource(vax, bundle, section, pid) "do";
        vax -> doses then createImmunizationResource(vax, bundle, section, pid) "do";
        vax -> doses then createImmunizationResource(vax, bundle, section, pid) "do";
        vax.LastDoseDate as date -> date then createImmunizationResource(vax, bundle, section, pid) "do";
      } "set doses";
    } "set status";
  } "set section";
}

group LmToComposition(source lm : AFROMRCIF, target composition : Composition, source cid, source pid, source prid, source oid, source eid) {
  cid -> composition.id = cid "set id";
  lm -> composition.status = 'final' "set status";
  lm.ReportingSource as src then {
    src.UniqueId as EPIDno ->  composition.identifier as identifier,  identifier.value = EPIDno "set identifier";
  } "set";
  lm -> composition.title = 'PAHO Measles Case Investigation Form' "set title";
  lm ->  create('Coding') as coding,  coding.code = '55751-2',  coding.system = 'http://loinc.org',  coding.display = 'Public health Case report',  create('CodeableConcept') as code,  code.coding = coding,  composition.type = code "set type";
  lm.CaseInvestigation as var -> var then {
    var.DateReportedLocal as date -> composition.date = date "set date";
  } "set date reported local";
  lm -> composition.subject as subject then {
    lm -> subject.reference = append('Patient/', pid) "set subject";
  } "set subject";
  lm -> composition.author as practitioner then {
    lm -> practitioner.reference = append('Practitioner/', prid) "set author practitioner";
  } "set author practitioner";
  lm -> composition.author as institution then {
    lm -> institution.reference = append('Organization/', oid) "set author institution";
  } "set author org";
  lm -> composition.encounter as encounter then {
    lm -> encounter.reference = append('Encounter/', eid) "set encounter";
  } "set encounter";
}

group DemographicsToPatient(source demographics : DemographicsLogicalModel, target patient : MeaslesPatient, source pid) {
  pid -> patient.id = pid "set patient id";
  demographics.Name as sourceName -> patient.name as targetName then {
    sourceName -> sourceName then humanNameToHumanName(sourceName, targetName) "Copy name";
  } "Set name";
  demographics.DateOfBirth as dob -> patient.birthDate = dob "set date of birth";
  demographics.Sex as sex -> patient.gender = sex "set sex";
  demographics.PlaceOfResidence as sourceAddress -> patient.address as targetAddress then {
    sourceAddress -> sourceAddress then addressToAddress(sourceAddress, targetAddress) "Copy Address";
  } "set address";
}

group classificationToPractitioner(source var : AFROMRCIFClassification, target practitioner : Practitioner, source prid) {
  prid -> practitioner.id = prid "set id";
  var.ReportedBy as name ->  practitioner.name as humanName,  humanName.text = name "set name";
}

group ReportingSourceToOrganization(source reportingSource : ReportingSourceLogicalModel, target organization : Organization, source oid) {
  oid -> organization.id = oid "set id";
  reportingSource.HealthServiceName as name -> organization.name = name "set name";
  reportingSource.HealthServiceTelephone as phoneSource ->  organization.contact as contactDetails,  contactDetails.telecom as phoneTarget then {
    phoneSource -> phoneSource then contactPointToContactPoint(phoneSource, phoneTarget) "set org contact";
  } "set phone";
  reportingSource.PlaceOfReporting as locationSource ->  organization.contact as contactDetails,  contactDetails.address as locationTarget then {
    locationSource -> locationSource then contactPointToContactPoint(locationSource, locationTarget) "set org address";
  } "set address";
}

group createCompositionEncounterResource(source date, source pid, source type : Coding, source eid, target encounter : Encounter) {
  date -> encounter.id = eid "set id";
  date -> encounter.status = 'finished' "set status";
  pid ->  encounter.subject as subject,  subject.reference = append('Patient/', pid) "set subject";
  date ->  encounter.period as period,  period.start = date "set date";
  type -> encounter.class = type "set type";
}