internal static Type DetectHealthVaultTypeFromObservation(Observation observation) { if (observation.Code != null && observation.Code.Coding != null) { foreach (var code in observation.Code.Coding) { if (!String.IsNullOrWhiteSpace(code.System) && code.CodeElement != null) { if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(code.System)) { var uri = new Uri(code.System.ToLowerInvariant()); return(DetectFromHealthVaultCode(uri.Segments.Last(), code.CodeElement.Value)); } switch (code.System.ToLowerInvariant()) { case VocabularyUris.SnomedCd: return(DetectFromSnomedCd(code.CodeElement.Value)); case VocabularyUris.Loinc: return(DetectFromLoincCodes(code.CodeElement.Value)); } } } } throw new NotSupportedException(); }
internal static string GetVocabularyName(Uri uri) { if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(uri.ToString())) { return(uri.Segments.Last()); } return(null); }
private static string GetSystemUrl(CodedValue codedValue) { // If the coded value family contains a URL, it's not a healvault vocab and we should return it as is if (codedValue.Family.Contains("http")) { return(codedValue.Family); } return(HealthVaultVocabularies.GenerateSystemUrl(codedValue.VocabularyName, codedValue.Family)); }
internal static FhirMedication ToFhirInternal(HVMedication hvMedication, FhirMedication fhirMedication) { fhirMedication.Code = hvMedication.Name.ToFhir(); if (hvMedication.GenericName != null || hvMedication.Strength != null) { var medicationExtension = new Extension { Url = HealthVaultExtensions.Medication }; if (hvMedication.GenericName != null) { var genericName = hvMedication.GenericName?.ToFhir(); medicationExtension.AddExtension(HealthVaultExtensions.MedicationGenericName, genericName); } if (hvMedication.Strength != null) { var strengthExtension = new Extension { Url = HealthVaultExtensions.MedicationStrength }; strengthExtension.AddExtension(HealthVaultExtensions.MedicationStrengthDisplay, new FhirString(hvMedication.Strength.Display)); foreach (var structuredMeasurement in hvMedication.Strength.Structured) { var simpleQuantity = new SimpleQuantity() { Value = new decimal(structuredMeasurement.Value), Unit = structuredMeasurement.Units.Text }; if (structuredMeasurement.Units.Any()) { CodedValue measurementUnit = structuredMeasurement.Units.First(); simpleQuantity.Code = measurementUnit.Value; simpleQuantity.System = HealthVaultVocabularies.GenerateSystemUrl(measurementUnit.VocabularyName, measurementUnit.Family); } strengthExtension.AddExtension(HealthVaultExtensions.MedicationStrengthQuantity, simpleQuantity); } medicationExtension.Extension.Add(strengthExtension); } fhirMedication.Extension.Add(medicationExtension); } return(fhirMedication); }
private static string GetSystemUrl(CodedValue codedValue) { bool isNonHealthVaultVocabulary = codedValue.VocabularyName.Contains("http"); if (isNonHealthVaultVocabulary) { return(codedValue.VocabularyName); } return(HealthVaultVocabularies.GenerateSystemUrl(codedValue.VocabularyName, codedValue.Family)); }
public static CodedValue ToCodedValue(this Coding coding) { var familyVocab = HealthVaultVocabularies.ExtractFamilyAndVocabularyFromSystemUrl(coding.System); var returnValue = new CodedValue { Value = coding.Code, VocabularyName = familyVocab.vocabulary, Family = familyVocab.family, Version = coding.Version, }; return(returnValue); }
internal static Observation ToFhirInternal(BodyComposition bodyComposition, Observation observation) { observation.Category = new List <CodeableConcept> { FhirCategories.VitalSigns }; observation.Effective = bodyComposition.When.ToFhir(); observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.BodyComposition); if (bodyComposition.MeasurementName != null) { observation.Component.Add(new Observation.ComponentComponent { Code = bodyComposition.MeasurementName.ToFhir() }); } if (bodyComposition.Value.MassValue != null) { var massValue = new Observation.ComponentComponent { Code = bodyComposition.MeasurementName.ToFhir(), Value = new Quantity((decimal)bodyComposition.Value.MassValue.Kilograms, UnitAbbreviations.Kilogram) }; observation.Component.Add(massValue); } if (bodyComposition.Value.PercentValue.HasValue) { var percentageValue = new Observation.ComponentComponent { Code = bodyComposition.MeasurementName.ToFhir(), Value = new Quantity((decimal)bodyComposition.Value.PercentValue.Value, UnitAbbreviations.Percent) }; observation.Component.Add(percentageValue); } if (bodyComposition.Site != null) { observation.BodySite = bodyComposition.Site.ToFhir(); } if (bodyComposition.MeasurementMethod != null) { observation.Method = bodyComposition.MeasurementMethod.ToFhir(); } return(observation); }
internal static string GetFamily(Uri uri) { if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(uri.ToString())) { // Expected to cotain 6 if the family is specified in the URL if (uri.Segments.Length == 6) { return(uri.Segments[4].TrimEnd('/')); } // By default if nothing is specified, then wc is assumed return("wc"); } return(null); }
internal static BloodGlucose ToBloodGlucose(this Observation observation) { var bloodGlucose = observation.ToThingBase <BloodGlucose>(); bloodGlucose.Value = ObservationToHealthVault.GetThingValueFromQuantity <BloodGlucoseMeasurement>(observation.Value as Quantity); bloodGlucose.When = ObservationToHealthVault.GetWhenFromEffective(observation.Effective); var bloodGlucoseExtension = observation.GetExtension(HealthVaultExtensions.BloodGlucose); if (bloodGlucoseExtension != null) { bloodGlucose.MeasurementContext = bloodGlucoseExtension.GetExtensionValue <CodeableConcept>(HealthVaultExtensions.BloodGlucoseMeasurementContext).ToCodableValue(); bloodGlucose.OutsideOperatingTemperature = bloodGlucoseExtension.GetBoolExtension(HealthVaultExtensions.OutsideOperatingTemperatureExtensionName); bloodGlucose.IsControlTest = bloodGlucoseExtension.GetBoolExtension(HealthVaultExtensions.IsControlTestExtensionName); Normalcy normalcy; if (Enum.TryParse <Normalcy>(bloodGlucoseExtension.GetStringExtension(HealthVaultExtensions.ReadingNormalcyExtensionName), out normalcy)) { bloodGlucose.ReadingNormalcy = normalcy; } } if (observation.Code != null && observation.Code.Coding != null) { foreach (var code in observation.Code.Coding) { if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(code.System)) { bloodGlucose.GlucoseMeasurementType = observation.Method.ToCodableValue(); } else { bloodGlucose.SetGlucoseMeasurementType( code.Display, code.Code, HealthVaultVocabularies.Fhir, code.System, code.Version); } } } return(bloodGlucose); }
internal static Observation ToFhirInternal(BodyDimension bodyDimension, Observation observation) { observation.Category = new List <CodeableConcept> { FhirCategories.VitalSigns }; observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.BodyDimension); if (bodyDimension.MeasurementName != null) { observation.Method = bodyDimension.MeasurementName.ToFhir(); } observation.Value = new Quantity((decimal)bodyDimension.Value.Meters, UnitAbbreviations.Meter); observation.Effective = bodyDimension.When.ToFhir(); return(observation); }
private static Extension CreateDetailExtension(string key, ExerciseDetail exerciseDetail) { var extension = new Extension { Url = HealthVaultExtensions.ExerciseDetail }; extension.AddExtension(HealthVaultExtensions.ExerciseDetailName, new FhirString(key)); extension.AddExtension(HealthVaultExtensions.ExerciseDetailType, exerciseDetail.Name.ToFhir()); extension.AddExtension(HealthVaultExtensions.ExerciseDetailValue, new Quantity { Value = (decimal)exerciseDetail.Value.Value, Unit = exerciseDetail.Value.Units.Text, Code = exerciseDetail.Value.Units[0].Value, System = HealthVaultVocabularies.GenerateSystemUrl(exerciseDetail.Value.Units[0].VocabularyName, exerciseDetail.Value.Units[0].Family), }); return(extension); }
internal static Observation ToFhirInternal(BloodGlucose bg, Observation observation) { observation.Method = bg.GlucoseMeasurementType.ToFhir(); var bloodGlucoseExtension = new Extension { Url = HealthVaultExtensions.BloodGlucose }; if (bg.MeasurementContext != null) { bloodGlucoseExtension.AddExtension(HealthVaultExtensions.BloodGlucoseMeasurementContext, bg.MeasurementContext.ToFhir()); } if (bg.OutsideOperatingTemperature.HasValue) { bloodGlucoseExtension.AddExtension(HealthVaultExtensions.OutsideOperatingTemperatureExtensionName, new FhirBoolean(bg.OutsideOperatingTemperature.Value)); } if (bg.ReadingNormalcy.HasValue) { bloodGlucoseExtension.AddExtension(HealthVaultExtensions.ReadingNormalcyExtensionName, new FhirString(bg.ReadingNormalcy.Value.ToString())); } if (bg.IsControlTest.HasValue) { bloodGlucoseExtension.AddExtension(HealthVaultExtensions.IsControlTestExtensionName, new FhirBoolean(bg.IsControlTest.Value)); } observation.Extension.Add(bloodGlucoseExtension); observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.BloodGlucose); var quantity = new Quantity((decimal)bg.Value.Value, UnitAbbreviations.MillimolesPerLiter); observation.Value = quantity; observation.Effective = new FhirDateTime(bg.When.ToLocalDateTime().ToDateTimeUnspecified()); return(observation); }
internal static Observation ToFhirInternal(BloodPressure bp, Observation observation) { if (bp.IrregularHeartbeatDetected.HasValue) { observation.AddExtension(HealthVaultVocabularies.IrregularHeartBeatExtensionName, new FhirBoolean(bp.IrregularHeartbeatDetected.Value)); } var diastolicComponent = new Observation.ComponentComponent { Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultVitalStatisticsCodes.BloodPressureDiastolic), Value = new Quantity((decimal)bp.Diastolic, UnitAbbreviations.MillimeterOfMecury) }; var systolicComponent = new Observation.ComponentComponent { Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultVitalStatisticsCodes.BloodPressureSystolic), Value = new Quantity((decimal)bp.Systolic, UnitAbbreviations.MillimeterOfMecury) }; observation.Component = new List <Observation.ComponentComponent> { diastolicComponent, systolicComponent }; if (bp.Pulse != null) { observation.Component.Add(new Observation.ComponentComponent { Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultVitalStatisticsCodes.HeartRate), Value = new Quantity((decimal)bp.Pulse, UnitAbbreviations.PerMinute) }); } observation.Effective = new FhirDateTime(bp.When.ToLocalDateTime().ToDateTimeUnspecified()); observation.Code = HealthVaultVocabularies.BloodPressure; return(observation); }
public static SimpleQuantity GetSimpleQuantity(GeneralMeasurement measurement) { if (measurement?.Structured.Any() == true) { StructuredMeasurement structuredMeasurement = measurement.Structured.First(); var simpleQuantity = new SimpleQuantity() { Value = new decimal(structuredMeasurement.Value), Unit = structuredMeasurement.Units.Text }; if (structuredMeasurement.Units.Any()) { CodedValue measurementUnit = structuredMeasurement.Units.First(); simpleQuantity.Code = measurementUnit.Value; simpleQuantity.System = HealthVaultVocabularies.GenerateSystemUrl(measurementUnit.VocabularyName, measurementUnit.Family); } return(simpleQuantity); } return(null); }
internal static BloodPressure ToBloodPressure(this Observation observation) { var bloodPressure = observation.ToThingBase <BloodPressure>(); bloodPressure.When = ObservationToHealthVault.GetHealthVaultTimeFromEffectiveDate(observation.Effective); bloodPressure.IrregularHeartbeatDetected = observation.GetBoolExtension(HealthVaultVocabularies.IrregularHeartBeatExtensionName); if (observation.Component != null) { foreach (var component in observation.Component) { if (component.Code != null && component.Code.Coding != null) { foreach (var code in component.Code.Coding) { if (code.Code != null) { if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(code.System)) { if (code.Code == HealthVaultVitalStatisticsCodes.BloodPressureDiastolic.Code) { SetDiastolic(bloodPressure, component); } else if (code.Code == HealthVaultVitalStatisticsCodes.BloodPressureSystolic.Code) { SetSystolic(bloodPressure, component); } else if (code.Code == HealthVaultVitalStatisticsCodes.HeartRate.Code) { SetPulse(bloodPressure, component); } } else { switch (code.Code.ToLowerInvariant()) { // HeartRate component case "8867-4": SetPulse(bloodPressure, component); break; // Systolic LOINC, SNOMED, ACME codes case "8480-6": case "271649006": case "bp-s": SetSystolic(bloodPressure, component); break; // Diastolic LOINC code case "8462-4": SetDiastolic(bloodPressure, component); break; default: continue; } break; } } } } } } return(bloodPressure); }
public static Allergy ToHealthVault(this AllergyIntolerance allergyIntolerance) { if (allergyIntolerance.Code.IsNullOrEmpty()) { throw new System.ArgumentException($"Can not transform a {typeof(AllergyIntolerance)} with no code into {typeof(Allergy)}"); } var allergy = allergyIntolerance.ToThingBase <Allergy>(); string allergenType = string.Empty; var allergyExtension = allergyIntolerance.GetExtension(HealthVaultExtensions.Allergy); if (allergyExtension != null) { allergenType = allergyExtension.GetStringExtension(HealthVaultExtensions.AllergenType); allergy.AllergenCode = allergyExtension.GetExtensionValue <CodeableConcept>(HealthVaultExtensions.AllergenCode)?.ToCodableValue(); allergy.Treatment = allergyExtension.GetExtensionValue <CodeableConcept>(HealthVaultExtensions.AllergyTreatement)?.ToCodableValue(); } var coding = allergyIntolerance.Code.Coding.FirstOrDefault(); if (coding != null) { if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(coding.System)) { allergy.Name = allergyIntolerance.Code.ToCodableValue(); } else { allergy.SetAllergyName( coding.Display, coding.Code, HealthVaultVocabularies.Fhir, coding.System, coding.Version); } } if (allergyIntolerance.Reaction != null && allergyIntolerance.Reaction.Count > 0) { var code = allergyIntolerance.Reaction.First().Manifestation.First().Coding.FirstOrDefault(); if (code != null) { if (HealthVaultVocabularies.SystemContainsHealthVaultUrl(code.System)) { allergy.Reaction = allergyIntolerance.Reaction.First().Manifestation.First().ToCodableValue(); } else { allergy.SetAllergyReaction( code.Display, code.Code, HealthVaultVocabularies.Fhir, code.System, code.Version); } } } if (allergyIntolerance.Onset != null) { allergy.FirstObserved = allergyIntolerance.Onset.ToAproximateDateTime(); } if (!string.IsNullOrWhiteSpace(allergenType)) { allergy.AllergenType = new CodableValue(allergenType) { new CodedValue(allergenType, HealthVaultVocabularies.AllergenType, HealthVaultVocabularies.Wc, "1") }; } else if (allergyIntolerance.Category != null && allergyIntolerance.Category.Count() > 0) { allergy.AllergenType = new CodableValue(allergyIntolerance.Category.First().Value.ToString()) { new CodedValue(allergyIntolerance.Category.First().Value.ToString(), FhirCategories.HL7Allergy, HealthVaultVocabularies.Fhir, "") }; } if (allergyIntolerance.ClinicalStatus.HasValue) { if ((allergyIntolerance.ClinicalStatus.Value == (AllergyIntoleranceClinicalStatus.Resolved)) || (allergyIntolerance.ClinicalStatus.Value == (AllergyIntoleranceClinicalStatus.Inactive))) { allergy.IsNegated = true; } else { allergy.IsNegated = false; } } if (allergyIntolerance.Asserter != null) { allergy.TreatmentProvider = GetProvider(allergyIntolerance); } return(allergy); }
public void WhenMedicationStatementTransformedToHealthVault_ThenDosageIsCopiedToDoseFrequencyAndRoute() { var embeddedMedication = new FhirMedication() { Code = new CodeableConcept() { Text = "Amoxicillin 250mg/5ml Suspension" } }; string embeddedMedicationId = "med" + Guid.NewGuid(); embeddedMedication.Id = embeddedMedicationId; const int dosage = 1; const int period = 8; const string routeCode = "po"; var medicationStatement = new MedicationStatement() { Medication = new ResourceReference(embeddedMedicationId), Dosage = new System.Collections.Generic.List <Dosage> { new Dosage { Dose = new SimpleQuantity() { Value = dosage, Unit = "Tablets", System = HealthVaultVocabularies.GenerateSystemUrl (HealthVaultVocabularies.MedicationDoseUnits, HealthVaultVocabularies.Wc), Code = "tablet" }, Timing = new Timing { Repeat = new Timing.RepeatComponent { Period = period, PeriodUnit = Timing.UnitsOfTime.H } }, Route = new CodeableConcept { Text = "By mouth", Coding = new System.Collections.Generic.List <Coding> { new Coding { Code = routeCode, System = HealthVaultVocabularies.GenerateSystemUrl (HealthVaultVocabularies.MedicationRoutes, HealthVaultVocabularies.Wc), Version = "2" } } } } } }; medicationStatement.Contained.Add(embeddedMedication); medicationStatement.Medication = embeddedMedication.GetContainerReference(); var hvMedication = medicationStatement.ToHealthVault() as HVMedication; Assert.AreEqual(dosage, hvMedication?.Dose?.Structured?.First()?.Value); Assert.AreEqual(period, hvMedication?.Frequency?.Structured?.First()?.Value); Assert.AreEqual(routeCode, hvMedication?.Route?.First()?.Value); }
internal static Observation ToFhirInternal(Exercise exercise, Observation observation) { observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.Exercise); if (exercise.Distance != null) { var distanceValue = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.ExerciseDistance }, Value = new Quantity((decimal)exercise.Distance.Value, UnitAbbreviations.Meter) }; observation.Component.Add(distanceValue); } if (exercise.Duration != null) { var durationValue = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.ExerciseDuration }, Value = new Quantity((decimal)exercise.Duration.Value, UnitAbbreviations.Minute) }; observation.Component.Add(durationValue); } observation.Text = new Narrative { Div = exercise.Title }; observation.Effective = exercise.When.ToFhir(); var activityValue = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.ExerciseActivity }, Value = exercise.Activity.ToFhir() }; observation.Component.Add(activityValue); if (exercise.Details != null) { foreach (var detail in exercise.Details) { observation.Extension.Add(CreateDetailExtension(detail.Key, detail.Value)); } } if (!exercise.Segments.IsNullOrEmpty()) { foreach (var segment in exercise.Segments) { observation.Extension.Add(CreateSegmentExtension(segment)); } } return(observation); }
internal static Observation ToFhirInternal(SleepJournalAM sleepJournalAM, Observation observation) { observation.Code = HealthVaultVocabularies.GenerateCodeableConcept(HealthVaultThingTypeNameCodes.SleepJournalAM); observation.Effective = new FhirDateTime(sleepJournalAM.When.ToLocalDateTime().ToDateTimeUnspecified()); observation.Component = new List <Observation.ComponentComponent>(); var bedtimeComponent = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.SleepJournalAMBedtime }, Value = sleepJournalAM.Bedtime.ToFhir() }; observation.Component.Add(bedtimeComponent); var waketimeComponent = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.SleepJournalAMWaketime }, Value = sleepJournalAM.WakeTime.ToFhir() }; observation.Component.Add(waketimeComponent); var sleepMinutesComponent = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.SleepJournalAMSleepMinutes }, Value = new Quantity(sleepJournalAM.SleepMinutes, UnitAbbreviations.Minute) }; observation.Component.Add(sleepMinutesComponent); var settlingMinutesComponent = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.SleepJournalAMSettlingMinutes }, Value = new Quantity(sleepJournalAM.SettlingMinutes, UnitAbbreviations.Minute) }; observation.Component.Add(settlingMinutesComponent); if (sleepJournalAM.Awakenings != null) { foreach (var awakening in sleepJournalAM.Awakenings) { var dummyDateTimeStart = new DateTime(sleepJournalAM.When.Date.Year, sleepJournalAM.When.Date.Month, sleepJournalAM.When.Date.Day); dummyDateTimeStart = dummyDateTimeStart.AddHours(awakening.When.Hour); dummyDateTimeStart = dummyDateTimeStart.AddMinutes(awakening.When.Minute); if (awakening.When.Second.HasValue) { dummyDateTimeStart = dummyDateTimeStart.AddSeconds(awakening.When.Second.Value); } if (awakening.When.Millisecond.HasValue) { dummyDateTimeStart = dummyDateTimeStart.AddSeconds(awakening.When.Millisecond.Value); } var dummyDateTimeEnd = dummyDateTimeStart; dummyDateTimeEnd = dummyDateTimeEnd.AddMinutes(awakening.Minutes); var awakeningComponent = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.SleepJournalAMAwakening }, Value = new Period(new FhirDateTime(dummyDateTimeStart), new FhirDateTime(dummyDateTimeEnd)), }; observation.Component.Add(awakeningComponent); } } var wakeStateComponent = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.SleepJournalAMWakeState }, Value = new FhirString(sleepJournalAM.WakeState.ToString()), }; observation.Component.Add(wakeStateComponent); if (sleepJournalAM.Medications != null) { var medicationComponenet = new Observation.ComponentComponent { Code = new CodeableConcept { Text = HealthVaultVocabularies.SleepJournalAMMedication }, Value = sleepJournalAM.Medications.ToFhir(), }; observation.Component.Add(medicationComponenet); } return(observation); }
internal static CodableValue CreateCodableValueFromQuantityValues(string system, string code, string unit) { var familyVocab = HealthVaultVocabularies.ExtractFamilyAndVocabularyFromSystemUrl(system); return(new CodableValue(unit, code, familyVocab.vocabulary, familyVocab.family, null)); }