public async Task <IActionResult> PostData([FromBody] ConceptMap data) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } bool versionExists = await _conceptmapservice.VersionExists(data.Version, data.Domain); if (versionExists) { return(BadRequest(error: "Version already exists")); } var result = await _conceptmapservice.PostConceptMap(data); if (result.Equals(data)) { using (var connection = factoryformessagebus.CreateConnection()) using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "Concepts", durable: false, exclusive: false, autoDelete: false, arguments: null); string bodydata = JsonConvert.SerializeObject(data); channel.BasicPublish(exchange: "", routingKey: "Concepts", mandatory: true, basicProperties: null, body: Encoding.UTF8.GetBytes(bodydata)); } } return(CreatedAtAction("GetData", new { result.Domain, result.Version }, result)); }
private static XElement renderConceptMapList(ConceptMap conceptMap, XNamespace ns) { XElement xConceptMapList = null; if (conceptMap.Group.Count > 0) { xConceptMapList = new XElement(ns + "table", new XElement(ns + "tr", new XElement(ns + "th", "Source Code"), new XElement(ns + "th", "Source Display"), new XElement(ns + "th", "Source Code System"), new XElement(ns + "th", "Equivalence"), new XElement(ns + "th", "Target Code"), new XElement(ns + "th", "Target Display"), new XElement(ns + "th", "Target Code System"), new XElement(ns + "th", "Comments") ), from cmg in conceptMap.Group from exp in cmg.Element select new XElement(ns + "tr", new XElement(ns + "td", exp.Code), new XElement(ns + "td", exp.Display), new XElement(ns + "td", cmg.Source), new XElement(ns + "td", exp.Target[0].Equivalence.ToString()), new XElement(ns + "td", exp.Target[0].Code), new XElement(ns + "td", exp.Target[0].Display), new XElement(ns + "td", cmg.Target), new XElement(ns + "td", exp.Target[0].Comment) ) ); } return(xConceptMapList); }
private static Resource GetConceptMaps(string identifier, NameValueCollection queryParam) { Bundle cmBundle = new Bundle(); cmBundle.Id = Guid.NewGuid().ToString(); cmBundle.Type = Bundle.BundleType.Searchset; cmBundle.Link.Add(new Bundle.LinkComponent { Url = ServerCapability.TERMINZ_CANONICAL + "/ConceptMap", Relation = "self" }); if (string.IsNullOrEmpty(identifier) && queryParam.Count < 1) { cmBundle.AddResourceEntry(GetRequest("NZREAD_SCT", queryParam), ServerCapability.TERMINZ_CANONICAL + "/ConceptMap/NzRead_Sct"); cmBundle.AddResourceEntry(GetRequest("SCT_NZREAD", queryParam), ServerCapability.TERMINZ_CANONICAL + "ConceptMap/Sct_NzRead"); cmBundle.AddResourceEntry(GetRequest("NZMP_SCT", queryParam), ServerCapability.TERMINZ_CANONICAL + "/ConceptMap/NzMp_Sct"); cmBundle.AddResourceEntry(GetRequest("NZ_ETHNICITY", queryParam), ServerCapability.TERMINZ_CANONICAL + "/ConceptMap/NzEthnicity"); cmBundle.AddResourceEntry(GetRequest("DELPHIC_LOINC", queryParam), "http://sysmex.co.nz/LIS/Observation/Mapping"); cmBundle.AddResourceEntry(GetRequest("101", queryParam), "http://hl7.org/fhir/ConceptMap/101"); cmBundle.AddResourceEntry(GetRequest("102", queryParam), "http://hl7.org/fhir/ConceptMap/102"); } else { ConceptMap cm = (ConceptMap)GetRequest(identifier, queryParam); cmBundle.AddResourceEntry(cm, cm.Url); } cmBundle.Total = cmBundle.Entry.Count(); return(cmBundle); }
public async Task <ConceptMap> PostConceptMap(ConceptMap map) { await _context.Concepts.InsertOneAsync(map); ConceptMapDomain conceptMapDomain = new ConceptMapDomain(); conceptMapDomain.Domain = map.Domain; conceptMapDomain.Version = map.Version; var result = GetConceptMapbyVersionandDomain(map.Version, map.Domain).Result; conceptMapDomain.ConceptMapId = result.Select(x => x.ID).ToString(); await _context.ConceptMapDomain.InsertOneAsync(conceptMapDomain); return(map); }
private static Resource GetRequest(string identifier, NameValueCollection queryParam) { //if (string.IsNullOrEmpty(identifier)) //{ // throw new Exception(MISSING_CONCEPTMAP_IDENTIFIER); //} string url = Utilities.GetQueryValue("url", queryParam); ConceptMap conceptMap = new ConceptMap(); string sourceSystem = Utilities.GetQueryValue("source", queryParam); string targetSystem = Utilities.GetQueryValue("target", queryParam); string versionVal = Utilities.GetQueryValue("version", queryParam); conceptMap = GetConceptMap(identifier, string.Empty, sourceSystem, targetSystem, versionVal); AddNarrative(conceptMap); return(conceptMap); }
private object[] GenerateDefinition(ConceptMap conceptMap) { List <object> result = new List <object>(); List <object> table = new List <object>(); table.Add(Html.Tr(new object[] { Html.Td(Html.B("Source")), Html.Td(""), Html.Td(Html.B("Target")), Html.Td("") } )); ValueSet sourceValueSet = null; ValueSet targetValueSet = null; if (conceptMap.Item != null && conceptMap.Item.GetType() == typeof(Reference)) { // Cheating a little here at the mo. Not safe Reference source = (Reference)conceptMap.Item; Reference target = (Reference)conceptMap.Item1; Link sourceValuesetLink = _profileSet.GetValueSetLink(source.reference.GetValueAsString()); Link targetValuesetLink = _profileSet.GetValueSetLink(target.reference.GetValueAsString()); sourceValueSet = _profileSet.GetValueSet(source.reference.GetValueAsString()); targetValueSet = _profileSet.GetValueSet(target.reference.GetValueAsString()); table.Add(Html.Tr(new object[] { Html.Td(Html.P(GetLabelAndValue("Valueset", new object[] { Html.A(sourceValuesetLink.Url, sourceValuesetLink.Display) }))), Html.Td(""), Html.Td(Html.P(GetLabelAndValue("Valueset", new object[] { Html.A(targetValuesetLink.Url, targetValuesetLink.Display) }))), Html.Td("") } )); } if (conceptMap.element != null && sourceValueSet != null && targetValueSet != null) { foreach (ConceptMapElement element in conceptMap.element) { string sourceCode = element.code.GetValueAsString(); // GetExtensionValueAsString(FhirConstants.ValueSetSystemNameExtensionUrl); string sourceName = ""; foreach (ValueSetInclude include in sourceValueSet.compose.include) { foreach (ValueSetConcept1 concept in include.concept) { if (concept.code.value.Equals(sourceCode)) { sourceName = concept.display.GetValueAsString(); } } } if (element.code.WhenNotNull(t => t.ToString().Length) > 0) { if (element.target != null) { bool isFirstTarget = true; foreach (ConceptMapTarget target in element.target) { if (!isFirstTarget) { sourceCode = ""; } isFirstTarget = true; string targetCode = target.code.GetValueAsString(); string targetName = ""; foreach (ValueSetInclude include in targetValueSet.compose.include) { foreach (ValueSetConcept1 concept in include.concept) { if (concept.code.value.Equals(targetCode)) { targetName = concept.display.GetValueAsString(); } } } // Need to check codeSystem is SNOMED if (float.Parse(targetCode) > 0 && targetCode.Length > 7) { table.Add(Html.Tr(new object[] { Html.Td(sourceCode), Html.Td(sourceName), Html.Td(Html.A(SnomedHelper.GetBrowserUrl(targetCode), targetCode)), Html.Td(targetName) } )); } else { table.Add(Html.Tr(new object[] { Html.Td(sourceCode), Html.Td(sourceName), Html.Td(targetCode), Html.Td(targetName) } )); } } } else { table.Add(Html.Tr(new object[] { Html.Td(sourceCode), Html.Td(""), Html.Td(""), Html.Td("") } ) ); } } } } result.Add(Html.Table(new object[] { table, Html.Class(Styles.ValueSetReferenceTableClassName) })); return(result.ToArray()); }
private void FillValues(string version, string nzmpCode) { this.conceptMap = new ConceptMap(); this.conceptMap.Id = "NZMP_SCT"; this.conceptMap.Url = ServerCapability.TERMINZ_CANONICAL + "/ConceptMap/NzMp_Sct"; this.conceptMap.Name = this.conceptMap.Id; this.conceptMap.Title = "NZMT medicinal product to SNOMED CT map"; this.conceptMap.Description = new Markdown("A mapping between NZMT Medicinal Products and SNOMED CT, published by NZMT in May 2018."); this.conceptMap.Version = "20180501"; this.conceptMap.Status = PublicationStatus.Draft; this.conceptMap.Experimental = true; this.conceptMap.Publisher = "Ministry of Health"; this.conceptMap.Date = new FhirDateTime(2018, 05, 1).Value; this.conceptMap.Purpose = new Markdown("To begin alignment between NZMT and SNOMED CT"); this.conceptMap.Copyright = new Markdown("© 2018+ New Zealand Crown Copyright"); ContactPoint cp = new ContactPoint { System = ContactPoint.ContactPointSystem.Email, Value = "*****@*****.**" }; ContactDetail cd = new ContactDetail(); cd.Telecom.Add(cp); cd.Name = "Patients First Ltd"; this.conceptMap.Contact.Add(cd); string sourceCodeSystemUri = NzMt.URI; string sourceValueSetUri = @"http://itp.patientsfirst.org.nz/ValueSet/NzulmMp"; string targetCodeSystemUri = FhirSnomed.URI; string targetValueSetUri = @"http://snomed.info/sct?fhir_vs"; this.conceptMap.Source = new FhirUri(sourceValueSetUri); this.conceptMap.Target = new FhirUri(targetValueSetUri); if ((string.IsNullOrEmpty(version) || version == this.conceptMap.Version)) { List <Coding> map = SnomedCtSearch.GetConceptMap_NZ(REFSET_ID, nzmpCode); ConceptMap.GroupComponent gc = new ConceptMap.GroupComponent(); gc.Source = sourceCodeSystemUri; gc.Target = targetCodeSystemUri; foreach (Coding mv in map) { ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Equivalent; ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = mv.Version, Display = mv.System }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = mv.Code, Equivalence = cme, Display = mv.Display }; sec.Target.Add(tec); gc.Element.Add(sec); } this.conceptMap.Group.Add(gc); } }
private void FillValues(string version) { this.conceptMap = new ConceptMap(); this.conceptMap.Id = "101"; this.conceptMap.Url = "http://hl7.org/fhir/ConceptMap/101"; this.conceptMap.Identifier = new Identifier { System = "urn:ietf:rfc:3986", Value = "urn:uuid:53cd62ee-033e-414c-9f58-3ca97b5ffc3b" }; this.conceptMap.Name = this.conceptMap.Id; this.conceptMap.Title = "FHIR/v3 Address Use Mapping"; this.conceptMap.Description = new Markdown("A mapping between the FHIR and HL7 v3 AddressUse Code systems"); this.conceptMap.Version = "R4"; this.conceptMap.Status = PublicationStatus.Draft; this.conceptMap.Experimental = true; this.conceptMap.Publisher = "HL7, Inc"; this.conceptMap.Date = new FhirDateTime(2012, 6, 13).Value; this.conceptMap.Purpose = new Markdown("To help implementers map from HL7 v3/CDA to FHIR"); this.conceptMap.Copyright = new Markdown("Creative Commons 0"); ContactPoint cp = new ContactPoint { System = ContactPoint.ContactPointSystem.Other, Value = "http://hl7.org/fhir" }; ContactDetail cd = new ContactDetail(); cd.Telecom.Add(cp); cd.Name = "FHIR project team (example)"; this.conceptMap.Contact.Add(cd); string sourceUri = @"http://hl7.org/fhir/ValueSet/address-use"; string targetUri = @"http://terminology.hl7.org/ValueSet/v3-AddressUse"; this.conceptMap.Source = new FhirUri(sourceUri); // Value Set this.conceptMap.Target = new FhirUri(targetUri); // Value Set Dictionary <string, string> mapVals = new Dictionary <string, string>(); mapVals.Add("home", "H"); mapVals.Add("work", "WP"); mapVals.Add("temp", "TMP"); mapVals.Add("old", "BAD"); if (string.IsNullOrEmpty(version) || version == this.conceptMap.Version) { ConceptMap.GroupComponent gc = new ConceptMap.GroupComponent(); gc.Source = "http://hl7.org/fhir/address-use"; // Code System gc.Target = "http://terminology.hl7.org/CodeSystem/v3-AddressUse"; // Code System foreach (KeyValuePair <string, string> mapVal in mapVals) { ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Equivalent; string comments = ""; string display = mapVal.Value.Replace("H", "home address").Replace("WP", "work place").Replace("TMP", "temporary address"); if (mapVal.Key == "old") { cme = ConceptMap.ConceptMapEquivalence.Disjoint; comments = "In the HL7 v3 AD, old is handled by the usablePeriod element, but you have to provide a time, there's no simple equivalent of flagging an address as old"; display = "bad address"; } ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = mapVal.Key, Display = mapVal.Key }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = mapVal.Value, Display = display, Equivalence = cme, Comment = comments }; sec.Target.Add(tec); gc.Element.Add(sec); } this.conceptMap.Group.Add(gc); } else { throw new Exception(TerminologyConceptMap.UNSUPPORTED_VERSION); } }
internal static ConceptMap AddNarrative(ConceptMap conceptMap) { // create display text for ConceptMap Resource string textString = string.Empty; //string nameTitle = conceptMap.Name.ToString() + (!string.IsNullOrEmpty(conceptMap.Title) ? " | " + conceptMap.Title : ""); try { XNamespace ns = "http://www.w3.org/1999/xhtml"; var summary = new XElement(ns + "div", new XElement(ns + "h2", conceptMap.Title), new XElement(ns + "p", conceptMap.Description), new XElement(ns + "table", new XElement(ns + "tr", new XElement(ns + "td", "Id"), new XElement(ns + "td", conceptMap.Id) ), new XElement(ns + "tr", new XElement(ns + "td", "Url"), new XElement(ns + "td", conceptMap.Url) ), new XElement(ns + "tr", new XElement(ns + "td", "Version"), new XElement(ns + "td", conceptMap.Version) ), new XElement(ns + "tr", new XElement(ns + "td", "Publisher"), new XElement(ns + "td", conceptMap.Publisher) ), new XElement(ns + "tr", new XElement(ns + "td", "Status"), new XElement(ns + "td", conceptMap.Status.ToString()) ), new XElement(ns + "tr", new XElement(ns + "td", "Status Date"), new XElement(ns + "td", conceptMap.Date) ), new XElement(ns + "tr", new XElement(ns + "td", "Experimental"), new XElement(ns + "td", conceptMap.Experimental.ToString()) ) ), renderConceptMapList(conceptMap, ns) ); textString = summary.ToString(); } catch { throw new Exception(UNRECOGNISED_CONCEPTMAP); } conceptMap.Text = new Narrative(); conceptMap.Text.Status = Narrative.NarrativeStatus.Generated; conceptMap.Text.Div = textString; // format Name property correctly conceptMap.Name = conceptMap.Name.First().ToString().ToUpper() + conceptMap.Name.Substring(1).Replace('-', '_'); return(conceptMap); }
private static Resource ClosureOperation(NameValueCollection queryParam) { bool outcome = true; int spReturn = 0; bool resync = false; string nameVal = Utilities.GetQueryValue("name", queryParam); string versionVal = Utilities.GetQueryValue("version", queryParam); string codeVals = Utilities.GetQueryValue("code", queryParam); string systemVal = Utilities.GetQueryValue("system", queryParam); // need to determine task (initialise /add concept / version check / resync) from what is passed // nb client can pass a version or concept(s), but not both if (string.IsNullOrEmpty(nameVal)) { throw new Exception(MISSING_CLOSURE_NAME); } // nb if versionVal = 0 will re-synch entire table (BUT if >0 changes since certain version OR specific version?) resync = !string.IsNullOrEmpty(versionVal); if (resync && !string.IsNullOrEmpty(codeVals)) { throw new Exception(INVALID_CLOSURE_PARAMS); } if (!string.IsNullOrEmpty(codeVals) || resync) { if (systemVal != FhirSnomed.URI && !resync) { throw new Exception(UNSUPPORTED_CODE_SYSTEM); } string newConcepts = string.Empty; short dbVer = 0; string storedConcepts = Closure.GetClosureConcepts(nameVal, (short)spReturn, out dbVer); bool codesToAdd = false; foreach (string cd in codeVals.Split(';')) { if (!string.IsNullOrEmpty(cd)) { string newCode = cd.Trim() + "|"; if (storedConcepts.IndexOf(newCode) < 0) { storedConcepts += newCode; codesToAdd = true; } } } if (codesToAdd) { spReturn = Closure.UpdateClosureTable(nameVal, storedConcepts, CLOSURE_CODE_SYSTEM_ID, CLOSURE_CODE_SYSTEM_VERSION); } if (spReturn == -1) { throw new Exception(INVALID_CLOSURE_NAME); } else if (spReturn == 99) { throw new Exception(REINITIALISE_CLOSURE); } ConceptMap cMap = new ConceptMap(); cMap.Id = Guid.NewGuid().ToString(); cMap.Version = dbVer.ToString(); cMap.Name = "Updates for Closure Table " + nameVal; cMap.Status = PublicationStatus.Active; cMap.Experimental = true; cMap.Date = Hl7.Fhir.Model.Date.Today().Value; ConceptMap.GroupComponent gc = new ConceptMap.GroupComponent(); gc.Source = CLOSURE_CODE_SYSTEM_ID; gc.SourceVersion = CLOSURE_CODE_SYSTEM_VERSION; gc.Target = CLOSURE_CODE_SYSTEM_ID; gc.TargetVersion = CLOSURE_CODE_SYSTEM_VERSION; if (resync) { codeVals = storedConcepts.Replace("|", ";"); } string subSuper = string.Empty; // look for sub-type / super-type relationships between existing codes and new codes foreach (string newCode in codeVals.Split(';')) { foreach (string storedCode in storedConcepts.Split('|')) { if (!string.IsNullOrEmpty(newCode) && newCode != storedCode) { // does one of these codes subsume another? string relat = TerminologyCodeSystem.GetRelationship(storedCode, newCode); string supertype = string.Empty; string subType = string.Empty; if (relat == TerminologyCodeSystem.CODE_RELATIONSHIP_SUBSUMED_BY) { subType = storedCode; supertype = newCode; } else if (relat == TerminologyCodeSystem.CODE_RELATIONSHIP_SUBSUMES) { subType = newCode; supertype = storedCode; } // check if this combination used already (reSync) string combo = subType + "+" + supertype + "|"; bool newPair = false; if (!string.IsNullOrEmpty(supertype)) { if (subSuper.IndexOf(combo) < 0) { subSuper += combo; newPair = true; } } if (newPair) { ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = subType }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = supertype, Equivalence = ConceptMap.ConceptMapEquivalence.Subsumes }; sec.Target.Add(tec); gc.Element.Add(sec); } } } } cMap.Group.Add(gc); return(cMap); } else { // initialise Closure Table outcome = Closure.AddClosureTable(nameVal, CLOSURE_CODE_SYSTEM_ID, CLOSURE_CODE_SYSTEM_VERSION); if (outcome == false) { throw new Exception(INVALID_CLOSURE_NAME); } } Parameters param = new Parameters(); param.Add("outcome", new FhirBoolean(outcome)); return(param); }
private static ConceptMap GetConceptMap(string identifier, string sourceCode, string sourceSystem, string targetSystem, string mapVersion) { string resourceFilePath = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath) + @"\Test Files\"; // <TODO> need a factory method here ConceptMap conceptMap = new ConceptMap(); if (identifier == "101" || identifier == "http://hl7.org/fhir/ConceptMap/101" || (sourceSystem == "http://hl7.org/fhir/ValueSet/address-use" && targetSystem == "http://terminology.hl7.org/ValueSet/v3-AddressUse")) { AddressUseV3Fhir cm = new AddressUseV3Fhir(mapVersion); conceptMap = cm.conceptMap; } else if (identifier == "102" || identifier == "http://hl7.org/fhir/ConceptMap/102" || (sourceSystem == "http://hl7.org/fhir/v2/0487" && targetSystem.StartsWith(FhirSnomed.URI))) { FhirXmlParser fxp = new FhirXmlParser(); conceptMap = fxp.Parse <ConceptMap>(File.ReadAllText(resourceFilePath + "SpecimenType_v2_SCT_Map.xml")); } else if (identifier == "NZREAD_SCT" || identifier == "http://itp.patientsfirst.org.nz/ConceptMap/NzRead_Sct" || (sourceSystem.StartsWith("http://health.govt.nz/read-codes") && targetSystem.StartsWith(FhirSnomed.URI))) { NZReadToSCT cm = new NZReadToSCT(mapVersion, sourceCode); conceptMap = cm.conceptMap; } else if (identifier == "SCT_NZREAD" || identifier == "http://itp.patientsfirst.org.nz/ConceptMap/Sct_NzRead" || (sourceSystem.StartsWith(FhirSnomed.URI) && targetSystem.StartsWith("http://health.govt.nz/read-codes"))) { SctToNZRead cm = new SctToNZRead(mapVersion, sourceCode); conceptMap = cm.conceptMap; } else if (identifier == "NZMP_SCT" || identifier == "http://itp.patientsfirst.org.nz/ConceptMap/NzMp_Sct" || (sourceSystem.StartsWith(NzMt.URI) && targetSystem.StartsWith(FhirSnomed.URI))) { NzMpToSCT cm = new NzMpToSCT(mapVersion, sourceCode); conceptMap = cm.conceptMap; } else if (identifier == "NZ_ETHNICITY" || identifier == "http://itp.patientsfirst.org.nz/ConceptMap/NzEthnicity" || (sourceSystem.StartsWith("https://standards.digital.health.nz/codesystem/ethnic-group-level-") && targetSystem.StartsWith("https://standards.digital.health.nz/codesystem/ethnic-group-level-"))) { sourceSystem = string.IsNullOrEmpty(sourceSystem) ? "https://standards.digital.health.nz/codesystem/ethnic-group-level-" : sourceSystem; targetSystem = string.IsNullOrEmpty(targetSystem) ? "https://standards.digital.health.nz/codesystem/ethnic-group-level-" : targetSystem; // as this facilitates a generic map to/from levels 2-4, prevent use of an invalid ethnicity level string invalidLevels = "0156789"; string sourceLevel = sourceSystem.Substring(sourceSystem.Length - 1, 1); string targetLevel = targetSystem.Substring(targetSystem.Length - 1, 1); if (invalidLevels.Contains(sourceLevel) && invalidLevels.Contains(targetLevel)) { throw new Exception(UNSUPPORTED_CODE_SYSTEM); } NZEthnicityLevels cm = new NZEthnicityLevels(mapVersion, sourceCode, sourceSystem, targetSystem); conceptMap = cm.conceptMap; } else if (identifier == "DELPHIC_LOINC" || identifier == "http://sysmex.co.nz/LIS/Observation/Mapping" || identifier == "f9f7e8f3-4d81-4291-8534-538fecd6f554") { FhirXmlParser fxp = new FhirXmlParser(); conceptMap = fxp.Parse <ConceptMap>(File.ReadAllText(resourceFilePath + "DELPHIC_LOINC_Map.xml")); } //else if (identifier == "NZMP_SCT" || (sourceSystem == "http://nzmt.org.nz" && targetSystem == "http://snomed.info/sct")) //{ // NZMpToSCT cm = new NZMpToSCT(mapVersion, sourceCode); // conceptMap = cm.conceptMap; //} else { throw new Exception(UNRECOGNISED_CONCEPTMAP); } return(conceptMap); }
private static Resource TranslateOperation(string id, NameValueCollection queryParam) { string systemVal = Utilities.GetQueryValue("system", queryParam); string sourceSystemVal = Utilities.GetQueryValue("source", queryParam); string sourceCodeVal = Utilities.GetQueryValue("code", queryParam); //string codingVal = Utilities.GetQueryValue("coding", queryParam); string versionVal = Utilities.GetQueryValue("conceptMapVersion", queryParam); string targetVal = Utilities.GetQueryValue("target", queryParam); // ValueSet string targetSystemVal = Utilities.GetQueryValue("targetSystem", queryParam); // Code System if (string.IsNullOrEmpty(sourceSystemVal)) { sourceSystemVal = systemVal; } if (string.IsNullOrEmpty(targetSystemVal)) { targetSystemVal = targetVal; } // if id supplied - just require source code to be translated, otherwise both source and target code systems must also be supplied if (string.IsNullOrEmpty(sourceCodeVal)) { throw new Exception(MISSING_SOURCE_CODE_CODING); } else if (string.IsNullOrEmpty(id) && string.IsNullOrEmpty(sourceSystemVal)) { throw new Exception(MISSING_SOURCE_SYSTEM); } else if (string.IsNullOrEmpty(id) && string.IsNullOrEmpty(targetSystemVal)) { throw new Exception(MISSING_TARGET_SYSTEM); } // get Mapping(s) ConceptMap conceptMap = GetConceptMap(id, sourceCodeVal, sourceSystemVal, targetSystemVal, versionVal); // iterate through Mappings storing any results List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> >(); string matchMessage = string.Empty; Dictionary <string, string> targetCodes = new Dictionary <string, string>(); foreach (ConceptMap.GroupComponent cmGroup in conceptMap.Group) { foreach (ConceptMap.SourceElementComponent se in cmGroup.Element) { if (se.Code.Trim() == sourceCodeVal.Trim()) { foreach (ConceptMap.TargetElementComponent te in se.Target) { if (!string.IsNullOrEmpty(se.Display)) { matchMessage += string.IsNullOrEmpty(matchMessage) ? "Source Code Description(s): " : " | "; matchMessage += se.Display; } // prevent duplicate targets (e.g. Read to SCT maps with >1 description mapped per code) if (!targetCodes.ContainsKey(te.Code.Trim())) { tuples.Add(new Tuple <string, Base>("equivalence", new FhirString(te.Equivalence.ToString()))); tuples.Add(new Tuple <string, Base>("concept", new Coding { Code = te.Code.Trim(), Display = te.Display, System = cmGroup.Target })); targetCodes.Add(te.Code.Trim(), te.Display); } foreach (ConceptMap.OtherElementComponent prod in te.Product) { tuples.Add(new Tuple <string, Base>("product", new Coding { Code = prod.Value.Trim(), Display = prod.Display, System = prod.System, ElementId = prod.Property })); } } } } } Parameters param = new Parameters(); param.Add("result", new FhirBoolean(tuples.Count > 0)); if (tuples.Count < 1) { throw new Exception("No mappings could be found for " + sourceCodeVal + " / " + systemVal); //param.Add("message", new FhirString("No mappings could be found for " + sourceCodeVal + " / " + systemVal)); } else { if (!string.IsNullOrEmpty(matchMessage)) { param.Add("message", new FhirString(matchMessage)); } param.Add("match", tuples); } return(param); }
private object[] GenerateContent(ConceptMapFile conceptMapFile, string displayName) { List <object> content = new List <object>(); ConceptMap conceptMap = conceptMapFile.ConceptMap; string name = conceptMap.name.value; string url = ""; if (conceptMap.url != null) { url = conceptMap.url.value; } content.AddRange(new object[] { Html.H3(GetConceptMapNameLabel(name)), Html.P("The official URL for this value set is: "), Html.Pre(url), Html.P(GetMaturity(conceptMapFile.Maturity)), }); string description = conceptMap.description.WhenNotNull(t => t.value); string referenceUrl = conceptMap.GetExtensionValueAsString(FhirConstants.ValueSetSourceReferenceExtensionUrl); string oid = conceptMap.GetExtensionValueAsString(FhirConstants.ValueSetOidExtensionUrl); if ((!string.IsNullOrWhiteSpace(description)) || (!string.IsNullOrWhiteSpace(referenceUrl)) || (!string.IsNullOrWhiteSpace(oid))) { content.AddRange(new object[] { Html.H3("Description"), GetFormattedDescription(description, referenceUrl, oid) }); } content.AddRange(new object[] { Html.H3("Definition"), GenerateDefinition(conceptMap) }); string copyright = conceptMap.copyright.WhenNotNull(t => t.value); if (!string.IsNullOrEmpty(copyright)) { content.AddRange(new object[] { Html.H3("Copyright"), Html.P(copyright) }); } content.AddRange(new object[] { Html.H3("Schemas"), StructureDefinitionHtmlGenerator.GetSchemasList(new object[] { Html.A(_outputPaths.GetRelativePath(OutputFileType.ConceptMap, conceptMapFile.OutputXmlFilename), "ConceptMap XML"), Html.A(_outputPaths.GetRelativePath(OutputFileType.ConceptMap, conceptMapFile.OutputJsonFilename), "ConceptMap JSON") }) }); return(content.ToArray()); }
private void FillValues(string version, string sctid) { this.conceptMap = new ConceptMap(); this.conceptMap.Id = "SCT_NZREAD"; this.conceptMap.Url = ServerCapability.TERMINZ_CANONICAL + "/ConceptMap/Sct_NzRead"; //this.conceptMap.Identifier = new Identifier { System = "urn:ietf:rfc:3986", Value = "urn:uuid:53cd62ee-033e-414c-9f58-3ca97b5ffc3b" }; this.conceptMap.Name = this.conceptMap.Id; this.conceptMap.Title = "SNOMED CT to NZ Read Codes"; string caveat = string.Empty; if (string.IsNullOrEmpty(sctid)) { caveat = " Definition only - complete map too large to download (over 100k elements)."; } this.conceptMap.Description = new Markdown("A mapping between SNOMED CT and the NZ Read Codes, published by NHS Digital and augmented for use in NZ." + caveat); this.conceptMap.Version = "20190501"; this.conceptMap.Status = PublicationStatus.Draft; this.conceptMap.Experimental = true; this.conceptMap.Publisher = "Ministry of Health"; this.conceptMap.Date = new FhirDateTime(2019, 05, 01).Value; this.conceptMap.Purpose = new Markdown("Used by the NZ Ministry of Social Development to help process SNOMED - coded work capacity medical certificates."); this.conceptMap.Copyright = new Markdown("© 2010+ New Zealand Crown Copyright"); ContactPoint cp = new ContactPoint { System = ContactPoint.ContactPointSystem.Email, Value = "*****@*****.**" }; ContactDetail cd = new ContactDetail(); cd.Telecom.Add(cp); cd.Name = "Patients First Ltd"; this.conceptMap.Contact.Add(cd); string sourceCodeSystemUri = FhirSnomed.URI; string sourceValueSetUri = @"http://snomed.info/sct?fhir_vs"; string targetCodeSystemUri = @"http://health.govt.nz/read-codes"; string targetValueSetUri = @"http://health.govt.nz/read-codes/fhir_vs"; this.conceptMap.Source = new FhirUri(sourceValueSetUri); this.conceptMap.Target = new FhirUri(targetValueSetUri); if ((string.IsNullOrEmpty(version) || version == this.conceptMap.Version) && !string.IsNullOrEmpty(sctid)) { List <Coding> map = SnomedCtSearch.GetConceptMap_NZ(REFSET_ID, sctid); ConceptMap.GroupComponent gc = new ConceptMap.GroupComponent(); gc.Source = sourceCodeSystemUri; gc.Target = targetCodeSystemUri; foreach (Coding mv in map) { ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Equivalent; ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = mv.Version, Display = mv.System }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = mv.Code, Equivalence = cme, Display = mv.Display }; sec.Target.Add(tec); gc.Element.Add(sec); } this.conceptMap.Group.Add(gc); } }
private void FillValues(string version, string readcode) { this.conceptMap = new ConceptMap(); this.conceptMap.Id = "NZREAD_SCT"; this.conceptMap.Url = ServerCapability.TERMINZ_CANONICAL + "/ConceptMap/NzRead_Sct"; //this.conceptMap.Identifier = new Identifier { System = "urn:ietf:rfc:3986", Value = "urn:uuid:53cd62ee-033e-414c-9f58-3ca97b5ffc3b" }; this.conceptMap.Name = this.conceptMap.Id; this.conceptMap.Title = "NZ Read Codes to SNOMED CT"; string caveat = string.Empty; if (string.IsNullOrEmpty(readcode)) { caveat = " Definition only - complete map too large to download (over 100k elements)."; } this.conceptMap.Description = new Markdown("A mapping between the NZ Read Codes and SNOMED CT, published by NHS Digital and augmented for use in NZ." + caveat); this.conceptMap.Version = "20190501"; this.conceptMap.Status = PublicationStatus.Draft; this.conceptMap.Experimental = true; this.conceptMap.Publisher = "Ministry of Health"; this.conceptMap.Date = new FhirDateTime(2019, 05, 01).Value; this.conceptMap.Purpose = new Markdown("To help primary care facilities translate legacy Read Codes"); this.conceptMap.Copyright = new Markdown("© 2010+ New Zealand Crown Copyright"); ContactPoint cp = new ContactPoint { System = ContactPoint.ContactPointSystem.Email, Value = "*****@*****.**" }; ContactDetail cd = new ContactDetail(); cd.Telecom.Add(cp); cd.Name = "Patients First Ltd"; this.conceptMap.Contact.Add(cd); string sourceCodeSystemUri = @"http://health.govt.nz/read-codes"; string sourceValueSetUri = @"http://health.govt.nz/read-codes/fhir_vs"; string targetCodeSystemUri = FhirSnomed.URI; string targetValueSetUri = @"http://snomed.info/sct?fhir_vs"; this.conceptMap.Source = new FhirUri(sourceValueSetUri); this.conceptMap.Target = new FhirUri(targetValueSetUri); if ((string.IsNullOrEmpty(version) || version == this.conceptMap.Version) && !string.IsNullOrEmpty(readcode)) { // add any missing periods to end of code and default Term ID of '00' //readcode = readcode.PadRight(5, '.'); //readcode = readcode + (readcode.Length == 5 ? "00" : ""); List <Coding> map = SnomedCtSearch.GetConceptMap_NZ(REFSET_ID, readcode); ConceptMap.GroupComponent gc = new ConceptMap.GroupComponent(); gc.Source = sourceCodeSystemUri; gc.Target = targetCodeSystemUri; foreach (Coding mv in map) { ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Equivalent; ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = mv.Version, Display = mv.System }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = mv.Code, Equivalence = cme, Display = mv.Display }; sec.Target.Add(tec); gc.Element.Add(sec); } this.conceptMap.Group.Add(gc); } }
private void Validate(string filename, ConceptMap profile) { _logger.Log("Validating ConceptMap" + filename); _logger.LogError("ConceptMap validation not currently supported."); }
private void FillValues(string version, string ethcode, string sourceSystem, string targetSystem) { this.conceptMap = new ConceptMap(); this.conceptMap.Id = "NZ_ETHNICITY"; this.conceptMap.Url = ServerCapability.TERMINZ_CANONICAL + "/ConceptMap/NzEthnicityLevels"; this.conceptMap.Name = this.conceptMap.Id; this.conceptMap.Title = "NZ Ethnicity Level (2-4) Mappings"; this.conceptMap.Description = new Markdown("Mappings between NZ Ethnicity Levels 2, 3 and 4."); this.conceptMap.Version = "20161209"; this.conceptMap.Status = PublicationStatus.Draft; this.conceptMap.Experimental = true; this.conceptMap.Publisher = "Ministry of Health"; this.conceptMap.Date = new FhirDateTime(2016, 10, 26).Value; this.conceptMap.Purpose = new Markdown("To aid conversions of Ethnicity Codes held at different levels."); this.conceptMap.Copyright = new Markdown("© 2010+ New Zealand Crown Copyright"); ContactPoint cp = new ContactPoint { System = ContactPoint.ContactPointSystem.Email, Value = "*****@*****.**" }; ContactDetail cd = new ContactDetail(); cd.Telecom.Add(cp); cd.Name = "Patients First Ltd"; this.conceptMap.Contact.Add(cd); this.conceptMap.Source = new FhirUri(sourceSystem); this.conceptMap.Target = new FhirUri(targetSystem); // determine which maps have been requested or all bool allMaps = true; string mapping = string.Empty; string levels = "234"; string sourceLevel = sourceSystem.Substring(sourceSystem.Length - 1, 1); string targetLevel = targetSystem.Substring(targetSystem.Length - 1, 1); if (levels.Contains(sourceLevel) && levels.Contains(targetLevel)) { mapping = sourceLevel + targetLevel; allMaps = false; } // get ValueSets for Levels 2-4 NameValueCollection queryParams = new NameValueCollection(); ValueSet vsL2 = (ValueSet)TerminologyValueSet.PerformOperation("NzEthnicityL2", "$expand", queryParams); ValueSet vsL3 = (ValueSet)TerminologyValueSet.PerformOperation("NzEthnicityL3", "$expand", queryParams); ValueSet vsL4 = (ValueSet)TerminologyValueSet.PerformOperation("NzEthnicityL4", "$expand", queryParams); // Level 2-3 mappings Dictionary <string, string> mapVals23 = new Dictionary <string, string>(); mapVals23.Add("10", "100"); mapVals23.Add("11", "111"); mapVals23.Add("12", "129"); mapVals23.Add("21", "211"); mapVals23.Add("30", "300"); mapVals23.Add("31", "311"); mapVals23.Add("32", "321"); mapVals23.Add("33", "331"); mapVals23.Add("34", "341"); mapVals23.Add("35", "351"); mapVals23.Add("36", "361"); mapVals23.Add("37", "371"); mapVals23.Add("40", "400"); mapVals23.Add("41", "414"); mapVals23.Add("42", "421"); mapVals23.Add("43", "431"); mapVals23.Add("44", "444"); mapVals23.Add("51", "511"); mapVals23.Add("52", "521"); mapVals23.Add("53", "531"); mapVals23.Add("61", "611"); mapVals23.Add("94", "944"); mapVals23.Add("95", "955"); mapVals23.Add("96", "966"); mapVals23.Add("97", "977"); mapVals23.Add("98", "988"); mapVals23.Add("99", "999"); ConceptMap.GroupComponent gc23 = new ConceptMap.GroupComponent(); gc23.Source = NzEthnicityL2.URI; gc23.Target = NzEthnicityL3.URI; foreach (KeyValuePair <string, string> mapVal in mapVals23) { ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Narrower; ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = mapVal.Key, Display = GetCodeDisplay(vsL2, mapVal.Key) }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = mapVal.Value, Equivalence = cme, Display = GetCodeDisplay(vsL3, mapVal.Value) }; sec.Target.Add(tec); gc23.Element.Add(sec); } if (allMaps || mapping == "23") { this.conceptMap.Group.Add(gc23); } // Level 2-4 mappings Dictionary <string, string> mapVals24 = new Dictionary <string, string>(); mapVals24.Add("10", "10000"); mapVals24.Add("11", "11111"); mapVals24.Add("12", "12999"); mapVals24.Add("21", "21111"); mapVals24.Add("30", "30000"); mapVals24.Add("31", "31111"); mapVals24.Add("32", "32100"); mapVals24.Add("33", "33111"); mapVals24.Add("34", "34111"); mapVals24.Add("35", "35111"); mapVals24.Add("36", "36111"); mapVals24.Add("37", "37199"); mapVals24.Add("40", "40000"); mapVals24.Add("41", "41499"); mapVals24.Add("42", "42199"); mapVals24.Add("43", "43199"); mapVals24.Add("44", "44499"); mapVals24.Add("51", "51199"); mapVals24.Add("52", "52199"); mapVals24.Add("53", "53199"); mapVals24.Add("61", "61199"); mapVals24.Add("94", "94444"); mapVals24.Add("95", "95555"); mapVals24.Add("96", "96666"); mapVals24.Add("97", "97777"); mapVals24.Add("98", "98888"); mapVals24.Add("99", "99999"); ConceptMap.GroupComponent gc24 = new ConceptMap.GroupComponent(); gc24.Source = NzEthnicityL2.URI; gc24.Target = NzEthnicityL4.URI; foreach (KeyValuePair <string, string> mapVal in mapVals24) { ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Narrower; ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = mapVal.Key, Display = GetCodeDisplay(vsL2, mapVal.Key) }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = mapVal.Value, Equivalence = cme, Display = GetCodeDisplay(vsL4, mapVal.Value) }; sec.Target.Add(tec); gc24.Element.Add(sec); } if (allMaps || mapping == "24") { this.conceptMap.Group.Add(gc24); } // Level 3 to 4 ConceptMap.GroupComponent gc34 = new ConceptMap.GroupComponent(); gc34.Source = NzEthnicityL3.URI; gc34.Target = NzEthnicityL4.URI; foreach (ValueSet.ContainsComponent ec in vsL3.Expansion.Contains) { ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Narrower; string targetCode = ec.Code + ec.Code.Substring(2, 1) + ec.Code.Substring(2, 1); ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = ec.Code, Display = ec.Display }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = targetCode, Equivalence = cme, Display = GetCodeDisplay(vsL4, targetCode) }; sec.Target.Add(tec); gc34.Element.Add(sec); } if (allMaps || mapping == "34") { this.conceptMap.Group.Add(gc34); } // Level 3 to 2 ConceptMap.GroupComponent gc32 = new ConceptMap.GroupComponent(); gc32.Source = NzEthnicityL3.URI; gc32.Target = NzEthnicityL2.URI; foreach (ValueSet.ContainsComponent ec in vsL3.Expansion.Contains) { ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Wider; ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = ec.Code, Display = ec.Display }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = ec.Code.Substring(0, 2), Equivalence = cme, Display = GetCodeDisplay(vsL2, ec.Code.Substring(0, 2)) }; sec.Target.Add(tec); gc32.Element.Add(sec); } if (allMaps || mapping == "32") { this.conceptMap.Group.Add(gc32); } // Level 4 to 3 ConceptMap.GroupComponent gc43 = new ConceptMap.GroupComponent(); gc43.Source = NzEthnicityL4.URI; gc43.Target = NzEthnicityL3.URI; foreach (ValueSet.ContainsComponent ec in vsL4.Expansion.Contains) { string targetCode = (ec.Code == "61118") ? "111" : ec.Code.Substring(0, 3); ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Wider; ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = ec.Code, Display = ec.Display }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = targetCode, Equivalence = cme, Display = GetCodeDisplay(vsL3, targetCode) }; sec.Target.Add(tec); gc43.Element.Add(sec); } if (allMaps || mapping == "43") { this.conceptMap.Group.Add(gc43); } // Level 4 to 2 ConceptMap.GroupComponent gc42 = new ConceptMap.GroupComponent(); gc42.Source = NzEthnicityL4.URI; gc42.Target = NzEthnicityL2.URI; foreach (ValueSet.ContainsComponent ec in vsL4.Expansion.Contains) { string targetCode = (ec.Code == "61118") ? "11" : ec.Code.Substring(0, 2); ConceptMap.ConceptMapEquivalence cme = ConceptMap.ConceptMapEquivalence.Wider; ConceptMap.SourceElementComponent sec = new ConceptMap.SourceElementComponent { Code = ec.Code, Display = ec.Display }; ConceptMap.TargetElementComponent tec = new ConceptMap.TargetElementComponent { Code = targetCode, Equivalence = cme, Display = GetCodeDisplay(vsL2, targetCode) }; sec.Target.Add(tec); gc42.Element.Add(sec); } if (allMaps || mapping == "42") { this.conceptMap.Group.Add(gc42); } }