private static Resource FindMatchesOperation(string systemURL, NameValueCollection queryParam) { string versionVal = Utilities.GetQueryValue("version", queryParam); string focusConcept = Utilities.GetQueryValue("focus", queryParam); string exactVal = Utilities.GetQueryValue("exact", queryParam); List <Coding> attributeCodeVals = GetAttributePairs(queryParam); if (string.IsNullOrEmpty(systemURL)) { throw new Exception(MISSING_CODESYSTEM); } else if (string.IsNullOrEmpty(focusConcept)) { throw new Exception(MISSING_FOCUS_CONCEPT); } else if (attributeCodeVals.Count < 1) { throw new Exception(MISSING_ATTRIBUTE); } else if (string.IsNullOrEmpty(exactVal)) { throw new Exception(MISSING_EXACT); } else if (exactVal.ToLower() != "true") { throw new Exception(UNSUPPORTED_EXACT_SETTING); } Parameters param = new Parameters(); if (systemURL == (FhirSnomed.URI)) { // Get Proximal Primitive(s) of Focus Code List <Coding> proximalPrimitiveCodeVals = SnomedCtSearch.GetProximalPrimitives(focusConcept, false); if (proximalPrimitiveCodeVals.Count < 1) { throw new Exception(INVALID_CODE); } // load proximal primitves into string array (5 is max number of proximal primitives for any one concept) string[] pp = new string[5]; int ppCount = 0; foreach (Coding cc in proximalPrimitiveCodeVals) { //if (cc.Code != focusConcept) //{ pp[ppCount] = cc.Code; ppCount++; //} } // load attribute types and values into arrays (30 is max number of non-isa relationships for any one concept) string[] attType = new string[30]; string[] attValue = new string[30]; int attributeCount = 0; int relGroup; int relGroupSize = 1; foreach (Coding cc in attributeCodeVals) { attType[attributeCount] = cc.Code; attValue[attributeCount] = cc.Display; int.TryParse(cc.Version, out relGroup); relGroupSize = (relGroup > relGroupSize) ? relGroup : relGroupSize; attributeCount++; } // get attributes and definition status from focus concept (as may need to add attributes if concept fully-defined) List <Coding> focusAttributes = SnomedCtSearch.GetAttributes(focusConcept); foreach (Coding cc in focusAttributes) { if (cc.System.ToUpper() != "FULLY DEFINED") { break; } bool addFocusAttribute = true; foreach (Coding acv in attributeCodeVals) { if (acv.Code == cc.Code) { addFocusAttribute = false; break; } } if (addFocusAttribute) { for (int rg = 0; rg < relGroupSize; rg++) { attType[attributeCount] = cc.Code; attValue[attributeCount] = cc.Display; attributeCount++; } } } List <Coding> matchVals = SnomedCtSearch.GetCompositionMatch(attType, attValue, pp, attributeCount); if (matchVals.Count < 1) { throw new Exception(NO_EXACT_MATCH); } List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> >(); foreach (Coding cc in matchVals) { tuples.Add(new Tuple <string, Base>("code", new Coding { Code = cc.Code, Display = cc.Display, System = systemURL })); param.Add("match", tuples); } } else { throw new Exception(FIND_MATCHES_UNSUPPORTED); } return(param); }
private static Resource LookupOperation(string systemURL, NameValueCollection queryParam) { CodeSystem codeSys = GetCodeSystem(TerminologyOperation.lookup, systemURL, queryParam); if (codeSys.Concept.Count < 1) { throw new Exception(INVALID_CODE); } string codeVal = Utilities.GetQueryValue("code", queryParam); //string versionVal = Utilities.GetQueryValue("version", queryParam); string propertyVal = Utilities.GetQueryValue("property", queryParam); string languageVal = Utilities.GetQueryValue("displayLanguage", queryParam); if (!string.IsNullOrEmpty(languageVal) && languageVal != "en-NZ") { throw new Exception(UNSUPPORTED_DISPLAY_LANGUAGE); } bool displayCode = false; bool displaySystem = false; bool displayVersion = true; bool displayDisplay = true; bool displayDefinition = false; bool displayDesignation = false; bool displayParents = false; bool displayChildren = false; bool displaySubstance = false; bool displayInactive = false; bool displayModuleId = false; bool displaySufficientlyDefined = false; bool displayNf = false; bool displayNfTerse = false; bool displayAllAttributes = false; bool displaySingleAttribute = false; bool displayTermType = false; // standard properties...defined for all Code Systems /* * // The following properties are defined for all code systems: * // system, version, display, definition, designation, parent, child, and lang.X where X is a language code in a designation * // SCT properties * // inactive boolean Whether the code is active or not (defaults to false). This is derived from the active column in the Concept file of the RF2 Distribution (by inverting the value) * // sufficientlyDefined boolean True if the description logic definition of the concept includes sufficient conditions (i.e., if the concept is not primitive). * // moduleId code The SNOMED CT concept id of the module that the concept belongs to. * // normalForm string Generated Normal form expression for the provided code or expression, with terms * // normalFormTerse string Generated Normal form expression for the provided code or expression, conceptIds only * // In addition, any SNOMED CT relationships where the relationship type is subsumed by Attribute (246061005) automatically become properties. For example, laterality: * // Laterality code In this case, the URI (See the code system definition) is http://snomed.info/id/272741003, which can be used to unambiguously map to the underlying concept */ if (!string.IsNullOrEmpty(propertyVal)) { string pvl = propertyVal.ToLower(); displayCode = (pvl.Contains("code")); displaySystem = (pvl.Contains("system")); //displayVersion = (pvl.Contains("version")); // always return code system version //displayDisplay = true; // default true - don't see much point in looking up the code and not displaying its description! (otherwise use validate-code) displayDefinition = (pvl.Contains("definition")); displayDesignation = (pvl.Contains("designation")); displayParents = (pvl.Contains("parent")); displayChildren = (pvl.Contains("child")); displaySubstance = (pvl.Contains("substance")); displayTermType = (pvl.Contains("termtype")); displayInactive = (pvl.Contains("inactive")); displaySufficientlyDefined = (pvl.Contains("sufficientlydefined")); displayModuleId = (pvl.Contains("moduleid")); displayNfTerse = (pvl.Contains("normalformterse")); displayNf = (pvl.Contains("normalform") && !displayNfTerse); displayAllAttributes = (pvl.Contains(FhirSnomed.SCT_ATTRIBUTE_CONCEPT)); if (!displayAllAttributes) { displaySingleAttribute = (pvl.Count(x => Char.IsDigit(x)) > 7); } } List <Coding> loincPropertyVals = new List <Coding>(); List <Coding> substanceCodeVals = new List <Coding>(); List <Coding> designationCodeVals = new List <Coding>(); List <Coding> childCodeVals = new List <Coding>(); List <Coding> parentCodeVals = new List <Coding>(); List <Coding> propertyCodeVals = new List <Coding>(); List <Coding> attributeCodeVals = new List <Coding>(); List <Coding> termTypeVals = new List <Coding>(); List <Coding> proximalPrimitiveCodeVals = new List <Coding>(); // CodeSystem-specific actions if (systemURL == NzMt.URI) { string nzulmType = codeSys.Concept[0].Definition; string mp_id = codeSys.Concept[0].ElementId; if (displaySubstance) { substanceCodeVals = NzUlmSearch.GetConceptSubstanceDataByCode(mp_id, nzulmType); } } if (systemURL == FhirLoinc.URI) { if (!string.IsNullOrEmpty(propertyVal)) { loincPropertyVals = LoincSearch.GetPropertiesByCode(codeVal, propertyVal.ToUpper()); } } if (systemURL == FhirRxNorm.URI) { if (displayTermType) { termTypeVals = RxNormSearch.GetPropertiesByCode(codeVal); } } if (systemURL == FhirSnomed.URI) { displaySystem = true; displayDesignation = true; displayInactive = true; if (codeSys.Concept.Count > 0) { if (displayDesignation) { designationCodeVals = SnomedCtSearch.GetConceptDesignationsByCode(codeVal); } if (displayInactive || displayModuleId || displaySufficientlyDefined) { propertyCodeVals = SnomedCtSearch.GetConceptPropertiesByCode(codeVal); } if (displayChildren) { childCodeVals = SnomedCtSearch.GetChildCodes(codeVal); } if (displayParents) { parentCodeVals = SnomedCtSearch.GetParentCodes(codeVal); } if (displayAllAttributes || displaySingleAttribute) { List <Coding> acv = SnomedCtSearch.GetAttributes(codeVal); if (displayAllAttributes) { attributeCodeVals = acv; } else { foreach (Coding cv in acv) { if (propertyVal.Contains(cv.Code)) { attributeCodeVals.Add(cv); } } } } } } // build return parameters resource using default & requested properties Parameters param = new Parameters(); if (codeSys.Concept != null) { param.Add("name", codeSys.NameElement); foreach (CodeSystem.ConceptDefinitionComponent comp in codeSys.Concept) { if (displaySystem) { param.Add("system", codeSys.UrlElement); } if (displayVersion) { param.Add("version", codeSys.VersionElement); } if (displayCode) { param.Add("code", comp.CodeElement); } if (displayDisplay) { param.Add("display", comp.DisplayElement); } } foreach (Coding prop in loincPropertyVals) { // return all of them List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { new Tuple <string, Base>("code", new FhirString(prop.Code)), new Tuple <string, Base>("value", new FhirString(prop.Display)) }; param.Add("property", tuples); } foreach (Coding tty in termTypeVals) { List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { //new Tuple<string, Base>("code", new FhirString(tty.Version)), //new Tuple<string, Base>("value", new FhirString(FhirRxNorm.GetTermType(tty.Version))), //new Tuple<string, Base>("description", new FhirString(tty.Display)) new Tuple <string, Base>("use", new Coding { Display = FhirRxNorm.GetTermType(tty.Version), System = FhirRxNorm.URI, Code = tty.Version }), new Tuple <string, Base>("value", new FhirString(tty.Display)) }; param.Add("termType", tuples); } foreach (Coding desig in designationCodeVals) { List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { new Tuple <string, Base>("use", new Coding { Display = desig.System, System = FhirSnomed.URI, Code = FhirSnomed.GetDesignationTypeId(desig.System) }), new Tuple <string, Base>("value", new FhirString(desig.Display)) }; param.Add("designation", tuples); } foreach (Coding prop in propertyCodeVals) { if ((prop.Code == "inactive" && displayInactive) || (prop.Code == "sufficientlyDefined" && displaySufficientlyDefined) || (prop.Code == "moduleId" && displayModuleId)) { List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { new Tuple <string, Base>("code", new FhirString(prop.Code)), new Tuple <string, Base>("value", new FhirString(prop.Display)) }; param.Add("property", tuples); } } if (displayNf || displayNfTerse) { string nf = FhirSnomed.GetNormalFormDisplay(codeVal, displayNf); List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { new Tuple <string, Base>("code", new FhirString(displayNf ? "normalForm" : "normalFormTerse")), new Tuple <string, Base>("value", new FhirString(nf)) }; param.Add("property", tuples); } foreach (Coding subst in substanceCodeVals) { List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { new Tuple <string, Base>("use", new Coding { Display = subst.System }) }; if (!string.IsNullOrEmpty(subst.Code)) { tuples.Add(new Tuple <string, Base>("code", new FhirString(subst.Code))); } tuples.Add(new Tuple <string, Base>("value", new FhirString(subst.Display))); param.Add("substance", tuples); } foreach (Coding parent in parentCodeVals) { List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { new Tuple <string, Base>("code", new FhirString("Parent")), new Tuple <string, Base>("value", new FhirString(parent.Code)), new Tuple <string, Base>("description", new FhirString(parent.Display)) }; param.Add("property", tuples); } foreach (Coding child in childCodeVals) { List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { new Tuple <string, Base>("code", new FhirString("Child")), new Tuple <string, Base>("value", new FhirString(child.Code)), new Tuple <string, Base>("description", new FhirString(child.Display)) }; param.Add("property", tuples); } foreach (Coding attrib in attributeCodeVals) { List <Tuple <string, Base> > tuples = new List <Tuple <string, Base> > { new Tuple <string, Base>("code", new Code { Value = attrib.Code }), new Tuple <string, Base>("valueCode", new Code { Value = attrib.Display }) }; param.Add("property", tuples); } } return(param); }