PreNUDGE FHIR® IG for Data Provider / Data from Apps (R4)
0.1.0 - ci-build
PreNUDGE FHIR® IG for Data Provider / Data from Apps (R4) - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
| Official URL: https://fhir.hl7.at/prenudge/appdata/r4/StructureMap/PhysicalActivityMinutesQtoO | Version: 0.1.0 | |||
| Draft as of 2026-06-25 | Responsible: The PreNUDGE Consortium | Computable Name: Physical Activity Minutes Q to O | ||
Physical Activity EHIS-PAQ Q7 / ATHIS PE7 to O (aggregate-only variant)
map "https://fhir.hl7.at/prenudge/appdata/r4/StructureMap/PhysicalActivityMinutesQtoO" = "Physical Activity Minutes Q to O" // Physical Activity EHIS-PAQ Q7 / ATHIS PE7 to O (aggregate-only variant) uses "http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse" alias QR as source uses "http://hl7.org/fhir/StructureDefinition/Observation" alias Obs as target imports "http://hl7.org/fhir/StructureMap/*" imports "https://fhir.hl7.at/prenudge/appdata/r4/StructureMap/QuestionnaireResponseToObservationBase" // --------------------------------------------------------------------------- // Main entry group // --------------------------------------------------------------------------- group PhysicalActivityQuestionnaireResponseToObservation(source src : QR, target tgt : Obs) { // Shared base: identifier copy, derivedFrom, subject, issued. // SetObservationBase also sets method = SCT 87982008 (Manual) — correct for // all questionnaire-derived observations in this IG. src then SetObservationBase(src, tgt) "Base"; // Explicitly confirm method = Manual (base already does this; listed for clarity). src -> tgt.method = cc('http://snomed.info/sct', '87982008', 'Manual') "SetMethodManual"; // Target profile src -> tgt.meta = create('Meta') as meta, meta.profile = 'https://fhir.hl7.at/prenudge/appdata/r4/StructureDefinition/at-prenudge-physical-activity-minutes-observation' "SetProfile"; // Panel code src -> tgt.code = cc('http://loinc.org', '101691-4', 'Duration of physical activity') "SetCode"; // effectiveDateTime from authored (EHIS-PAQ Q7 has no embedded date item) src.authored as authored -> tgt.effectiveDateTime = authored "SetEffectiveDateTime"; // Map Q7 group to component[aggregateActivity] src.item as q7 where linkId = 'Q7' then MapQ7ToAggregate(q7, tgt) "ProcessQ7"; // component[moderateActivity] : NOT mapped // Q7 asks for total leisure activity time without separating intensity levels. // There is no questionnaire source for a moderate-only figure. // component[vigorousActivity] : NOT mapped // Total leisure time maps directly to aggregateActivity (see MapQ7ToAggregate). // component[classificationMethod] : NOT mapped // method = Manual → component must be absent or self-rp (pa-manual-comp-01). // The map does not set it; a consuming system may add self-rp post-transform // if explicit documentation of the classification basis is required. } // --------------------------------------------------------------------------- // Q7 → component[aggregateActivity] (LOINC 101691-4) // Formula: aggregateMinutes = (Q7-hours × 60) + Q7-minutes // This is a direct transcription of the patient-reported total time. // No intensity weighting is applied because Q7 does not capture intensity. // The ×2 vigorous weighting (WHO/IPAQ) is ONLY applied when a wearable // separately measures moderate and vigorous minutes (wearable variant). // Note on FML arithmetic / MaLaC-HD compatibility: // This map uses evaluate() with integer arithmetic (* 60, +) which is NOT // supported by MaLaC-HD 1.6.0. MaLaC-HD fails at parse time with // "Param type 14 not implemented" (integer literal in FHIRPath expression). // The questionnaire captures hours and minutes as separate integer items, // so no MaLaC-HD compatible rewrite exists without redesigning the questionnaire // or changing the output unit. Use matchbox or another evaluate()-capable engine. // --------------------------------------------------------------------------- group MapQ7ToAggregate(source src : QR, target tgt : Obs) { src -> tgt.component as aggComp then { // Component discriminator code: LOINC 101691-4 // Note: same code as panel Observation.code — collision documented in profile. // obs-7 is not violated because Observation.value[x] is absent. src -> aggComp.code = cc('http://loinc.org', '101691-4', 'Duration of physical activity') "SetAggregateCode"; src -> aggComp.value = create('Quantity') as qty then { // aggregateMinutes = (Q7-hours × 60) + Q7-minutes src -> qty.value = evaluate(src, (item.where(linkId = 'Q7-hours').answer.valueInteger * 60) + item.where(linkId = 'Q7-minutes').answer.valueInteger) "ComputeAggregateMinutes"; src -> qty.unit = 'min/wk' "SetUnit"; src -> qty.system = 'http://unitsofmeasure.org' "SetSystem"; src -> qty.code = 'min/wk' "SetUCUM"; } "SetAggregateQuantity"; } "MapAggregateComponent"; }