// Pregnancy episode start marker types: LMP: Last menstrual period date, GEST: Gestational age record, FERT: Assisted // conception procedure date, ULS: Nuchal ultrasound date, AFP: Alpha feto protein test date, AMEN: Amenorrhea record date, // URINE: Urine pregnancy test date private static IEnumerable <KeyValuePair <Event, Event> > FindPregnancEpisodes( Dictionary <string, List <Event> > validOutcomes, RawEvents raw, Dictionary <string, TermDurations> termDurations, Dictionary <string, GestEst> gestEst, string[] markers, bool hasDefault, bool desc) { var outcomes = new List <Event>(); foreach (var outcomeCategory in validOutcomes.Keys) { outcomes.AddRange(validOutcomes[outcomeCategory]); } foreach (var outcome in outcomes) { var duration = termDurations[outcome.Category]; var ge = gestEst[outcome.Category]; var priorOutcomeDate = DateTime.MinValue; var priorOutcomes = outcomes.Where(o => o.Date < outcome.Date).ToArray(); TermDurations durationPrior = null; if (priorOutcomes.Any()) { var po = priorOutcomes.OrderByDescending(o => o.Date).First(); priorOutcomeDate = po.Date; durationPrior = termDurations[po.Category]; } foreach (var startEpisodeOutcome in FindPregnancyStartEvent(raw, duration, durationPrior, outcome, priorOutcomeDate, ge, markers, hasDefault, desc)) { yield return(new KeyValuePair <Event, Event>(outcome, startEpisodeOutcome)); } } }
private static IEnumerable <Event> FindPregnancyStartEvent(RawEvents raw, TermDurations duration, TermDurations durationPrior, Event outcome, DateTime priorOutcomeDate, GestEst g, string[] markers, bool hasDefault, bool desc) { List <Event> starts = new List <Event>(); foreach (var startMarker in markers) { if (!raw.PregnancyEvents.ContainsKey(startMarker)) { continue; } foreach (var pe in raw.PregnancyEvents[startMarker] .OrderBy(e => e.Date)) { var e = FindStart(outcome, pe, duration, priorOutcomeDate); if (e == null) { continue; } e.OriginalDate = pe.Date; starts.Add(e); } } if (starts.Any()) { foreach (var group in starts.GroupBy(s => s.Category)) { if (desc) { var maxDate = group.Max(e => e.OriginalDate); yield return(group.Where(e => e.OriginalDate == maxDate).OrderBy(e => e.EventId).First()); } else { var minDate = group.Min(e => e.OriginalDate); yield return(group.Where(e => e.OriginalDate == minDate).OrderBy(e => e.EventId).First()); } } } if (hasDefault) { var wStart = outcome.Date.Date.AddDays(-1 * duration.MaxTerm); var wEnd = outcome.Date.AddDays(30); if (outcome.Date.Between(priorOutcomeDate > wStart ? priorOutcomeDate : wStart, wEnd)) { var episodeStartDate = outcome.Date; var category = "DEFAULT"; if (raw.PregnancyEvents.ContainsKey("PREM") && raw.PregnancyEvents["PREM"].Count(e => e.Date.Between(priorOutcomeDate > wStart ? priorOutcomeDate : wStart, wEnd)) > 0) { episodeStartDate = episodeStartDate.Date.AddDays(-1 * g.PreTerm); category = "PREM"; } else if (raw.PregnancyEvents.ContainsKey("FT") && raw.PregnancyEvents["FT"].Count(e => e.Date.Between(priorOutcomeDate > wStart ? priorOutcomeDate : wStart, wEnd)) > 0) { episodeStartDate = episodeStartDate.Date.AddDays(-1 * g.FullTerm); } else { episodeStartDate = episodeStartDate.Date.AddDays(-1 * g.NoData); } if (durationPrior != null && priorOutcomeDate.AddDays(durationPrior.Retry) > episodeStartDate) { episodeStartDate = priorOutcomeDate.AddDays(durationPrior.Retry); } yield return(new Event { EventId = outcome.EventId, Category = category, Date = episodeStartDate }); } } }
public IEnumerable <ConditionEra> GetPregnancyEpisodes(IVocabulary vocab, Person person, ObservationPeriod[] observationPeriods, ConditionOccurrence[] conditionOccurrences, ProcedureOccurrence[] procedureOccurrences, Observation[] observations, Measurement[] measurements, DrugExposure[] drugExposures) { if (person.GenderConceptId != 8532) { yield break; } var raw = new RawEvents(); raw.Fill(vocab, conditionOccurrences, procedureOccurrences, observations, measurements, drugExposures); if (raw.PregnancyEvents.Count == 0) { yield break; } var outcomeLimits = new Dictionary <string, Dictionary <string, OutcomeLimit> >(); foreach (var ol in _outcomeLimits) { if (!outcomeLimits.ContainsKey(ol.FirstPregCategory)) { outcomeLimits.Add(ol.FirstPregCategory, new Dictionary <string, OutcomeLimit>()); } outcomeLimits[ol.FirstPregCategory].Add(ol.OutcomePregCategory, ol); } var termDurations = _termDurations.ToDictionary(termDuration => termDuration.Category); var gestEsts = _gestEsts.ToDictionary(ge => ge.Category); var validOutcomes = new Dictionary <string, List <Event> >(); foreach (var outcomeType in _outcomeTypes) { if (!raw.PregnancyEvents.ContainsKey(outcomeType)) { continue; } foreach (var g in raw.PregnancyEvents[outcomeType].OrderBy(pe => pe.Date).GroupBy(pe => pe.Date)) { var e = g.First(); if (outcomeType == "AB" || outcomeType == "SA") { // Reassign abortion outcome date to last abortion date within 2 weeks after var revisedDates = new List <DateTime>(2) { GetRevisedDate("SA", 14, e, raw.PregnancyEvents), GetRevisedDate("AB", 14, e, raw.PregnancyEvents) }; var revisedDate = revisedDates.Max(); if (revisedDate != DateTime.MinValue) { e.Date = revisedDate; } } else if (outcomeType == "ECT") { // Reassign ectopic pregnancy outcome date to last treatment date within 2 weeks after var revisedDates = new List <DateTime>(2) { GetRevisedDate("ECT_SURG1", 14, e, raw.PregnancyEvents), GetRevisedDate("MTX", 14, e, raw.PregnancyEvents) }; var revisedDate = revisedDates.Max(); if (revisedDate != DateTime.MinValue) { e.Date = revisedDate; } } if (!HasInvalidWindow(e, outcomeLimits, validOutcomes) && IsValid(e, raw.PregnancyEvents)) { if (!validOutcomes.ContainsKey(e.Category)) { validOutcomes.Add(e.Category, new List <Event>()); } validOutcomes[e.Category].Add(e); } } } if (validOutcomes.Count > 0) { var allEpisodes = FindPregnancEpisodes(validOutcomes, raw, termDurations, gestEsts, new[] { "OVUL", "OVUL2", "NULS", "AFP", "AMEN", "UP" }, true, false).ToList(); allEpisodes.AddRange(FindPregnancEpisodes(validOutcomes, raw, termDurations, gestEsts, new[] { "LMP", "GEST" }, false, true)); var pconf = FindPregnancEpisodes(validOutcomes, raw, termDurations, gestEsts, new[] { "PCONF", "AGP", "PCOMP", "TA" }, false, false).ToArray(); var pconfEpisodes = new List <KeyValuePair <Event, Event> >(); if (pconf.Any()) { pconfEpisodes.AddRange(pconf.GroupBy(p => p.Key.Guid) .Select(g => g.OrderBy(e => e.Value.Date).First())); } var contraEpisodes = FindPregnancEpisodes(validOutcomes, raw, termDurations, gestEsts, new[] { "CONTRA" }, false, true).ToArray(); var all = GetEpisodesAllStarts(person, allEpisodes, pconfEpisodes, contraEpisodes).ToArray(); foreach (var episodes in all.GroupBy(e => e.EndDate)) { var pe = episodes.OrderBy(e => e.TypeConceptId).ThenBy(e => e.StartDate).First(); var startDate = pe.StartDate; var endDate = pe.EndDate.Value; if (startDate.Year - person.YearOfBirth >= 12 && startDate.Year - person.YearOfBirth <= 55 && observationPeriods.Any(op => startDate >= op.StartDate && endDate.Between(op.StartDate, op.EndDate.Value))) { int cnt = 0; foreach (var c in raw.PregnancyEvents.Keys) { foreach (var e in raw.PregnancyEvents[c]) { if (e.Date.Between( endDate.AddDays(-1 * termDurations[pe.SourceValue].MaxTerm + 1), endDate)) { cnt++; } } } if (cnt >= 2) { pe.ConceptId = GetConceptId(pe); yield return(pe); } } } } }