Пример #1
0
        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);
        }
Пример #6
0
        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());
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        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);
        }
Пример #13
0
        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());
        }
Пример #14
0
        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);
            }
        }
Пример #15
0
        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.");
 }
Пример #17
0
        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);
            }
        }