/// <summary> /// Projects Enumeration of drug exposure from the raw set of drug exposure entities. /// During build: /// override the drug's start/end date using the end date of the corresponding observation period. /// </summary> /// <param name="drugExposures">raw set of drug exposures entities</param> /// <param name="visitOccurrences">the visit occurrences entities for current person</param> /// <param name="observationPeriods">the observation periods entities for current person</param> /// <returns>Enumeration of drug exposure entities</returns> public override IEnumerable<DrugExposure> BuildDrugExposures(DrugExposure[] drugExposures, Dictionary<long, VisitOccurrence> visitOccurrences, ObservationPeriod[] observationPeriods) { if (observationPeriods.Length != 0) { foreach (var drugExposure in drugExposures) { drugExposure.StartDate = drugExposure.DaysSupply.HasValue ? observationPeriods[0].EndDate.AddDays(drugExposure.DaysSupply.Value*-1) : observationPeriods[0].EndDate; drugExposure.EndDate = observationPeriods[0].EndDate; yield return drugExposure; } } }
/// <summary> /// Projects Enumeration of ConditionOccurrence from the raw set of ConditionOccurrence entities. /// During build: /// override the condition's start date using the end date of the corresponding observation period. /// </summary> /// <param name="conditionOccurrences">raw set of condition occurrence entities</param> /// <param name="visitOccurrences">the visit occurrence entities for current person</param> /// <param name="observationPeriods">the observation period entities for current person</param> /// <returns>Enumeration of condition occurrence entities</returns> public override IEnumerable<ConditionOccurrence> BuildConditionOccurrences( ConditionOccurrence[] conditionOccurrences, Dictionary<long, VisitOccurrence> visitOccurrences, ObservationPeriod[] observationPeriods) { if (observationPeriods.Length != 0) { foreach (var conditionOccurrence in conditionOccurrences) { var sourceValue = conditionOccurrence.SourceValue; if (sourceValue.Length < 2) continue; if (sourceValue.Substring(sourceValue.Length - 2) != "_1") continue; if (conditionOccurrence.ConceptId > 0) { conditionOccurrence.StartDate = observationPeriods[0].StartDate; conditionOccurrence.EndDate = null; yield return conditionOccurrence; } } } }
/// <summary> /// Projects Enumeration of ConditionOccurrence from the raw set of ConditionOccurrence entities. /// During build: /// override the condition's start date using the start date of the corresponding visit. /// overide TypeConceptId per CDM Mapping spec. /// </summary> /// <param name="conditionOccurrences">raw set of condition occurrence entities</param> /// <param name="vo">the visit occurrence entities for current person</param> /// <param name="op">the observation period entities for current person</param> /// <returns>Enumeration of condition occurrence entities</returns> public override IEnumerable<ConditionOccurrence> BuildConditionOccurrences(ConditionOccurrence[] conditionOccurrences, Dictionary<long, VisitOccurrence> vo, ObservationPeriod[] op) { var result = new HashSet<ConditionOccurrence>(); var dateClaimTypeDictionary = new Dictionary<DateTime, Dictionary<string, List<IEntity>>>(); foreach (var conditionOccurrence in conditionOccurrences) { var visitOccurrence = GetVisitOccurrence(conditionOccurrence); if (visitOccurrence == null) continue; conditionOccurrence.VisitOccurrenceId = visitOccurrence.Id; conditionOccurrence.StartDate = visitOccurrence.StartDate; conditionOccurrence.EndDate = null; conditionOccurrence.TypeConceptId = GetConditionTypeConceptId(conditionOccurrence.TypeConceptId.Value, visitOccurrence.ConceptId); AddToDateClaimTypeDictionary(dateClaimTypeDictionary, conditionOccurrence, visitOccurrence); } foreach (var sameStartDate in conditionOccurrences.Where(c => c.VisitOccurrenceId.HasValue && !string.IsNullOrEmpty(c.SourceValue)).GroupBy(c => c.StartDate)) { foreach (var sameVisit in sameStartDate.GroupBy(c => c.VisitOccurrenceId)) { foreach (var sameSource in sameVisit.GroupBy(c => c.SourceValue)) { foreach (var sameConcept in sameSource.GroupBy(c => c.ConceptId)) { var conditionOccurrence = sameConcept.OrderBy(c => c.TypeConceptId).ToList()[0]; if (!CodeValidator.IsValidIcd9(conditionOccurrence.SourceValue)) continue; conditionOccurrence.ProviderKey = GetProviderKey(vo[conditionOccurrence.VisitOccurrenceId.Value], conditionOccurrence, dateClaimTypeDictionary); result.Add(conditionOccurrence); } } } } return base.BuildConditionOccurrences(result.ToArray(), vo, op); }
private static IEnumerable<VisitOccurrence> CleanVisitOccurrences(IEnumerable<VisitOccurrence> visitOccurrences, ObservationPeriod[] observationPeriods) { foreach (var visitOccurrence in visitOccurrences) { if (!visitOccurrence.EndDate.HasValue || visitOccurrence.EndDate < visitOccurrence.StartDate) visitOccurrence.EndDate = visitOccurrence.StartDate; var observationPeriod = observationPeriods.FirstOrDefault(op => visitOccurrence.StartDate.Between(op.StartDate, op.EndDate) || visitOccurrence.EndDate.Value.Between(op.StartDate, op.EndDate)); if (observationPeriod == null) continue; if (visitOccurrence.StartDate < observationPeriod.StartDate) visitOccurrence.StartDate = observationPeriod.StartDate; if (visitOccurrence.EndDate > observationPeriod.EndDate) visitOccurrence.EndDate = observationPeriod.EndDate; yield return visitOccurrence; } }
/// <summary> /// Projects Enumeration of Visit Occurrence from the raw set of Visit Occurrence entities. /// </summary> /// <param name="rawVisitOccurrences">raw set of Visit Occurrence entities</param> /// <param name="observationPeriods">the observation periods entities for current person</param> /// <returns>Enumeration of Visit Occurrence</returns> public override IEnumerable<VisitOccurrence> BuildVisitOccurrences(VisitOccurrence[] rawVisitOccurrences, ObservationPeriod[] observationPeriods) { var visitOccurrences = CleanVisitOccurrences(rawVisitOccurrences, observationPeriods).ToList(); var ipVisits = GetIPClaims(visitOccurrences).ToList(); var erVisits = new List<VisitOccurrence>(); var opVisits = new List<VisitOccurrence>(); foreach (var visitOccurrence in visitOccurrences.Where(visitOccurrence => visitOccurrence.ConceptId != 9201)) { var ip = ipVisits.FirstOrDefault(v => visitOccurrence.StartDate.Between(v.StartDate, v.EndDate.Value)); if (visitOccurrence.ConceptId == 9203) { if (ip == null || (visitOccurrence.StartDate == ip.StartDate && visitOccurrence.EndDate == ip.StartDate)) //ER - 9203 { erVisits.Add(visitOccurrence); } else { if (!rawVisits.ContainsKey(visitOccurrence.SourceRecordGuid)) rawVisits.Add(visitOccurrence.SourceRecordGuid, ip); } } else if (ip == null) { opVisits.Add(visitOccurrence); } else { if (!rawVisits.ContainsKey(visitOccurrence.SourceRecordGuid)) rawVisits.Add(visitOccurrence.SourceRecordGuid, ip); } } foreach (var ipVisit in ipVisits) { yield return ipVisit; } // collapse claims with the same FST_DT in ER table as one unique ER visit foreach (var patplanidGroup in erVisits.GroupBy(vo => vo.AdditionalFields["pat_planid"])) { foreach (var erGroup in patplanidGroup.GroupBy(v => v.StartDate)) { var visit = erGroup.First(); visit.EndDate = erGroup.Max(v => v.EndDate); foreach ( var visitOccurrence in erGroup.Where(visitOccurrence => !rawVisits.ContainsKey(visitOccurrence.SourceRecordGuid))) { rawVisits.Add(visitOccurrence.SourceRecordGuid, visit); } yield return visit; } } foreach (var patplanidGroup in opVisits.GroupBy(vo => vo.AdditionalFields["pat_planid"])) { foreach (var opGroup in patplanidGroup.GroupBy(v => v.StartDate)) { foreach (var opGroup1 in opGroup.GroupBy(v => v.AdditionalFields["prov"])) { var visit = opGroup1.First(); visit.EndDate = opGroup1.Max(v => v.EndDate); foreach ( var visitOccurrence in opGroup1.Where(visitOccurrence => !rawVisits.ContainsKey(visitOccurrence.SourceRecordGuid)) ) { rawVisits.Add(visitOccurrence.SourceRecordGuid, visit); } yield return visit; } } } }
/// <summary> /// Projects Enumeration of ProcedureOccurrence from the raw set of ProcedureOccurence entities. /// During build: /// override the procedure's start date using the end date of the corresponding visit. /// overide TypeConceptId per CDM Mapping spec. /// truncate procedure's dates to the corresponding observation period dates /// </summary> /// <param name="procedureOccurrences">raw set of procedure occurrence entities</param> /// <param name="visitOccurrences">the visit occurrence entities for current person</param> /// <param name="observationPeriods">the observation period entities for current person</param> /// <returns>Enumeration of procedure occurrence entities</returns> public override IEnumerable<ProcedureOccurrence> BuildProcedureOccurrences(ProcedureOccurrence[] procedureOccurrences, Dictionary<long, VisitOccurrence> visitOccurrences, ObservationPeriod[] observationPeriods) { var result = new HashSet<ProcedureOccurrence>(); var cost = new Dictionary<ProcedureOccurrence, List<ProcedureCost>>(); var dateClaimTypeDictionary = new Dictionary<DateTime, Dictionary<string, List<IEntity>>>(); var cdProcedures = new List<ProcedureOccurrence>(); var otherProcedures = new List<ProcedureOccurrence>(); foreach (var procedureOccurrence in procedureOccurrences) { var visitOccurrence = GetVisitOccurrence(procedureOccurrence); if (visitOccurrence == null) continue; procedureOccurrence.VisitOccurrenceId = visitOccurrence.Id; var observationPeriod = observationPeriods.FirstOrDefault(op => op.StartDate.Between(procedureOccurrence.StartDate, procedureOccurrence.EndDate.Value) || op.EndDate.Between(procedureOccurrence.StartDate, procedureOccurrence.EndDate.Value)); if (observationPeriod != null) { if (procedureOccurrence.StartDate < observationPeriod.StartDate) procedureOccurrence.StartDate = observationPeriod.StartDate; if (procedureOccurrence.StartDate > observationPeriod.EndDate) procedureOccurrence.StartDate = observationPeriod.EndDate; } procedureOccurrence.EndDate = null; procedureOccurrence.TypeConceptId = GetProcedureTypeConceptId(procedureOccurrence.TypeConceptId.Value, visitOccurrence.ConceptId); if (procedureOccurrence.TypeConceptId == 38000272 || procedureOccurrence.TypeConceptId == 38000254) { if (procedureOccurrence.ProcedureCosts != null) { if (!cost.ContainsKey(procedureOccurrence)) cost.Add(procedureOccurrence, new List<ProcedureCost>()); cost[procedureOccurrence].AddRange(procedureOccurrence.ProcedureCosts); } cdProcedures.Add(procedureOccurrence); } else { procedureOccurrence.StartDate = visitOccurrence.EndDate.Value; if (CodeValidator.IsValidIcd9Procedure(procedureOccurrence.SourceValue)) otherProcedures.Add(procedureOccurrence); } AddToDateClaimTypeDictionary(dateClaimTypeDictionary, procedureOccurrence, visitOccurrence); } foreach (var procedureOccurrence in BuildProceduresCd(cdProcedures, cost)) { result.Add(procedureOccurrence); } foreach (var procedureOccurrence in BuildProceduresOther(otherProcedures, visitOccurrences, dateClaimTypeDictionary)) { result.Add(procedureOccurrence); } return base.BuildProcedureOccurrences(result.ToArray(), visitOccurrences, observationPeriods); }
/// <summary> /// Projects Enumeration of drug exposure from the raw set of drug exposure & procedure occurrence entities. /// During build: /// overide TypeConceptId per CDM Mapping spec. /// </summary> /// <param name="de">raw set of drug exposures entities</param> /// <param name="visitOccurrences">the visit occurrences entities for current person</param> /// <param name="observationPeriods">the observation periods entities for current person</param> /// <returns>Enumeration of drug exposure entities</returns> public override IEnumerable<DrugExposure> BuildDrugExposures(DrugExposure[] de, Dictionary<long, VisitOccurrence> visitOccurrences, ObservationPeriod[] observationPeriods) { var drugExposures = PrepareDrugExposures(de, visitOccurrences).ToArray(); return base.BuildDrugExposures(drugExposures, visitOccurrences, observationPeriods); }
/// <summary> /// Projects death entity from the raw set of death entities. /// </summary> /// <param name="deathRaw">raw set of death entities</param> /// <param name="visitOccurrences">the visit occurrence entities for current person</param> /// <param name="observationPeriods">the observation period entities for current person</param> /// <returns>death entity</returns> public override Death BuildDeath(Death[] deathRaw, Dictionary<long, VisitOccurrence> visitOccurrences, ObservationPeriod[] observationPeriods) { var death = FilterDeathRecords(deathRaw).ToList(); if (death.Any()) { var maxStartDate = death.Max(d => d.StartDate); var result = death.Where(d => d.StartDate == maxStartDate).OrderByDescending(d => d.Primary).First(); result.CauseConceptId = 0; var maxVisitStartDate = visitOccurrences.Values.Max(vo => vo.StartDate); if (maxVisitStartDate < result.StartDate.AddDays(32)) { return result; } } return null; }
/// <summary> /// Projects Enumeration of Observations from the raw set of Observation entities. /// During build: /// override the observations start date using the start date of the corresponding observation period. /// </summary> /// <param name="observations">raw set of observations entities</param> /// <param name="visitOccurrences">the visit occurrences entities for current person</param> /// <param name="observationPeriods">the observation periods entities for current person</param> /// <returns>Enumeration of Observation from the raw set of Observation entities</returns> public override IEnumerable<Observation> BuildObservations(Observation[] observations, Dictionary<long, VisitOccurrence> visitOccurrences, ObservationPeriod[] observationPeriods) { if (observationPeriods.Length != 0) { var unique = new HashSet<Observation>(); foreach (var observation in observations) { if (observation.ConceptId == -999) continue; observation.StartDate = observationPeriods[0].StartDate; observation.ValueAsConceptId = Convert.ToInt32(observation.UnitsConceptId); observation.UnitsConceptId = null; observation.UnitsSourceValue = null; unique.Add(observation); } foreach (var observation in unique) { yield return observation; } } }