Search in sources :

Example 11 with ConceptSetFilterComponent

use of org.hl7.fhir.r4.model.ValueSet.ConceptSetFilterComponent in project org.hl7.fhir.core by hapifhir.

the class ValueSetCheckerSimple method codeInConceptIsAFilter.

private boolean codeInConceptIsAFilter(CodeSystem cs, ConceptSetFilterComponent f, String code, boolean rootOnly) {
    if (!rootOnly && code.equals(f.getProperty())) {
        return true;
    }
    ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), f.getValue());
    if (cc == null) {
        return false;
    }
    cc = findCodeInConcept(cc, code);
    return cc != null;
}
Also used : ConceptDefinitionComponent(org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent)

Example 12 with ConceptSetFilterComponent

use of org.hl7.fhir.r4.model.ValueSet.ConceptSetFilterComponent in project org.hl7.fhir.core by hapifhir.

the class ValueSetExpanderSimple method doInternalIncludeCodes.

public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException {
    if (cs == null) {
        if (context.isNoTerminologyServer())
            throw failTSE("Unable to find code system " + inc.getSystem().toString());
        else
            throw failTSE("Unable to find code system " + inc.getSystem().toString());
    }
    cs.checkNoModifiers("Code System", "expanding");
    if (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT)
        throw failTSE("Code system " + inc.getSystem().toString() + " is incomplete");
    if (cs.hasVersion())
        if (!existsInParams(exp.getParameter(), "version", new UriType(cs.getUrl() + "|" + cs.getVersion())))
            exp.getParameter().add(new ValueSetExpansionParameterComponent().setName("version").setValue(new UriType(cs.getUrl() + "|" + cs.getVersion())));
    if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) {
        // special case - add all the code system
        for (ConceptDefinitionComponent def : cs.getConcept()) {
            addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
        }
        if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
            addFragmentWarning(exp, cs);
        }
        if (cs.getContent() == CodeSystemContentMode.EXAMPLE) {
            addExampleWarning(exp, cs);
        }
    }
    if (!inc.getConcept().isEmpty()) {
        canBeHeirarchy = false;
        for (ConceptReferenceComponent c : inc.getConcept()) {
            c.checkNoModifiers("Code in Code System", "expanding");
            ConceptDefinitionComponent def = CodeSystemUtilities.findCode(cs.getConcept(), c.getCode());
            // default is true if we're a fragment and
            Boolean inactive = false;
            if (def == null) {
                if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
                    addFragmentWarning(exp, cs);
                } else if (cs.getContent() == CodeSystemContentMode.EXAMPLE) {
                    addExampleWarning(exp, cs);
                } else {
                    if (checkCodesWhenExpanding) {
                        throw failTSE("Unable to find code '" + c.getCode() + "' in code system " + cs.getUrl());
                    }
                }
            } else {
                inactive = CodeSystemUtilities.isInactive(cs, def);
            }
            addCode(inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), null, convertDesignations(c.getDesignation()), expParams, false, inactive, imports, noInactive);
        }
    }
    if (inc.getFilter().size() > 1) {
        // which will bt the case if we get around to supporting this
        canBeHeirarchy = false;
        // need to and them, and this isn't done yet. But this shouldn't arise in non loinc and snomed value sets
        throw failTSE("Multiple filters not handled yet");
    }
    if (inc.getFilter().size() == 1) {
        if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
            addFragmentWarning(exp, cs);
        }
        ConceptSetFilterComponent fc = inc.getFilter().get(0);
        if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISA) {
            // special: all codes in the target code system under the value
            ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
            if (def == null)
                throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
            addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
        } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISNOTA) {
            // special: all codes in the target code system that are not under the value
            ConceptDefinitionComponent defEx = getConceptForCode(cs.getConcept(), fc.getValue());
            if (defEx == null)
                throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
            for (ConceptDefinitionComponent def : cs.getConcept()) {
                addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter(), noInactive);
            }
        } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.DESCENDENTOF) {
            // special: all codes in the target code system under the value
            ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
            if (def == null)
                throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
            for (ConceptDefinitionComponent c : def.getConcept()) addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
            if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
                List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
                for (ConceptDefinitionComponent c : children) addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
            }
        } else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) {
            // gg; note: wtf is this: if the filter is display=v, look up the code 'v', and see if it's diplsay is 'v'?
            canBeHeirarchy = false;
            ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
            if (def != null) {
                if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
                    if (def.getDisplay().contains(fc.getValue())) {
                        addCode(inc.getSystem(), def.getCode(), def.getDisplay(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def), imports, noInactive);
                    }
                }
            }
        } else if (isDefinedProperty(cs, fc.getProperty())) {
            for (ConceptDefinitionComponent def : cs.getConcept()) {
                addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())), noInactive);
            }
        } else {
            throw fail("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
        }
    }
}
Also used : ConceptSetFilterComponent(org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent) ConceptDefinitionComponent(org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent) ValueSetExpansionParameterComponent(org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent) ArrayList(java.util.ArrayList) List(java.util.List) ConceptReferenceComponent(org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent) UriType(org.hl7.fhir.r5.model.UriType)

Example 13 with ConceptSetFilterComponent

use of org.hl7.fhir.r4.model.ValueSet.ConceptSetFilterComponent in project org.hl7.fhir.core by hapifhir.

the class ValueSetExpanderSimple method includeCodes.

private void includeCodes(ConceptSetComponent inc, List<ValueSetExpansionParameterComponent> params, ExpansionProfile profile) throws ETooCostly, FileNotFoundException, IOException, FHIRException {
    List<ValueSet> imports = new ArrayList<ValueSet>();
    for (UriType imp : inc.getValueSet()) imports.add(importValueSet(imp.getValue(), params, profile));
    if (!inc.hasSystem()) {
        if (// though this is not supposed to be the case
        imports.isEmpty())
            return;
        ValueSet base = imports.get(0);
        imports.remove(0);
        copyImportContains(base.getExpansion().getContains(), null, profile, imports);
    } else {
        CodeSystem cs = context.fetchCodeSystem(inc.getSystem());
        if ((cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) && context.supportsSystem(inc.getSystem())) {
            addCodes(context.expandVS(inc, canBeHeirarchy), params, profile, imports);
            return;
        }
        if (cs == null) {
            if (context.isNoTerminologyServer())
                throw new NoTerminologyServiceException("unable to find code system " + inc.getSystem().toString());
            else
                throw new TerminologyServiceException("unable to find code system " + inc.getSystem().toString());
        }
        if (cs.getContent() != CodeSystemContentMode.COMPLETE)
            throw new TerminologyServiceException("Code system " + inc.getSystem().toString() + " is incomplete");
        if (cs.hasVersion())
            if (!existsInParams(params, "version", new UriType(cs.getUrl() + "|" + cs.getVersion())))
                params.add(new ValueSetExpansionParameterComponent().setName("version").setValue(new UriType(cs.getUrl() + "|" + cs.getVersion())));
        if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) {
            // special case - add all the code system
            for (ConceptDefinitionComponent def : cs.getConcept()) {
                addCodeAndDescendents(cs, inc.getSystem(), def, null, profile, imports);
            }
        }
        if (!inc.getConcept().isEmpty()) {
            canBeHeirarchy = false;
            for (ConceptReferenceComponent c : inc.getConcept()) {
                addCode(inc.getSystem(), c.getCode(), Utilities.noString(c.getDisplay()) ? getCodeDisplay(cs, c.getCode()) : c.getDisplay(), null, convertDesignations(c.getDesignation()), profile, false, CodeSystemUtilities.isInactive(cs, c.getCode()), imports);
            }
        }
        if (inc.getFilter().size() > 1) {
            // which will bt the case if we get around to supporting this
            canBeHeirarchy = false;
            // need to and them, and this isn't done yet. But this shouldn't arise in non loinc and snomed value sets
            throw new TerminologyServiceException("Multiple filters not handled yet");
        }
        if (inc.getFilter().size() == 1) {
            ConceptSetFilterComponent fc = inc.getFilter().get(0);
            if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISA) {
                // special: all codes in the target code system under the value
                ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
                if (def == null)
                    throw new TerminologyServiceException("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
                addCodeAndDescendents(cs, inc.getSystem(), def, null, profile, imports);
            } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.DESCENDENTOF) {
                // special: all codes in the target code system under the value
                ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
                if (def == null)
                    throw new TerminologyServiceException("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
                for (ConceptDefinitionComponent c : def.getConcept()) addCodeAndDescendents(cs, inc.getSystem(), c, null, profile, imports);
            } else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) {
                // gg; note: wtf is this: if the filter is display=v, look up the code 'v', and see if it's diplsay is 'v'?
                canBeHeirarchy = false;
                ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
                if (def != null) {
                    if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
                        if (def.getDisplay().contains(fc.getValue())) {
                            addCode(inc.getSystem(), def.getCode(), def.getDisplay(), null, def.getDesignation(), profile, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def), imports);
                        }
                    }
                }
            } else
                throw new NotImplementedException("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
        }
    }
}
Also used : NoTerminologyServiceException(org.hl7.fhir.exceptions.NoTerminologyServiceException) ConceptDefinitionComponent(org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent) NotImplementedException(org.apache.commons.lang3.NotImplementedException) NoTerminologyServiceException(org.hl7.fhir.exceptions.NoTerminologyServiceException) TerminologyServiceException(org.hl7.fhir.exceptions.TerminologyServiceException) ValueSet(org.hl7.fhir.dstu3.model.ValueSet)

Example 14 with ConceptSetFilterComponent

use of org.hl7.fhir.r4.model.ValueSet.ConceptSetFilterComponent in project org.hl7.fhir.core by hapifhir.

the class ValueSetComparer method compareDefinitions.

private void compareDefinitions(ConceptSetComponent left, ConceptSetComponent right, StructuralMatch<Element> combined, ConceptSetComponent union, ConceptSetComponent intersection) {
    // system must match, but the rest might not. we're going to do the full comparison whatever, so the outcome looks consistent to the user
    List<CanonicalType> matchVSR = new ArrayList<>();
    for (CanonicalType l : left.getValueSet()) {
        CanonicalType r = findInList(right.getValueSet(), l, left.getValueSet());
        if (r == null) {
            union.getValueSet().add(l);
            combined.getChildren().add(new StructuralMatch<Element>(l, vmI(IssueSeverity.INFORMATION, "Removed ValueSet", "ValueSet.compose.include.valueSet")));
        } else {
            matchVSR.add(r);
            if (l.getValue().equals(r.getValue())) {
                union.getValueSet().add(l);
                intersection.getValueSet().add(l);
                StructuralMatch<Element> sm = new StructuralMatch<Element>(l, r, null);
                combined.getChildren().add(sm);
            } else {
                union.getValueSet().add(l);
                union.getValueSet().add(r);
                StructuralMatch<Element> sm = new StructuralMatch<Element>(l, r, vmI(IssueSeverity.INFORMATION, "Values are different", "ValueSet.compose.include.valueSet"));
                combined.getChildren().add(sm);
            }
        }
    }
    for (CanonicalType r : right.getValueSet()) {
        if (!matchVSR.contains(r)) {
            union.getValueSet().add(r);
            combined.getChildren().add(new StructuralMatch<Element>(vmI(IssueSeverity.INFORMATION, "Add ValueSet", "ValueSet.compose.include.valueSet"), r));
        }
    }
    List<ConceptReferenceComponent> matchCR = new ArrayList<>();
    for (ConceptReferenceComponent l : left.getConcept()) {
        ConceptReferenceComponent r = findInList(right.getConcept(), l, left.getConcept());
        if (r == null) {
            union.getConcept().add(l);
            combined.getChildren().add(new StructuralMatch<Element>(l, vmI(IssueSeverity.INFORMATION, "Removed this Concept", "ValueSet.compose.include.concept")));
        } else {
            matchCR.add(r);
            if (l.getCode().equals(r.getCode())) {
                ConceptReferenceComponent cu = new ConceptReferenceComponent();
                ConceptReferenceComponent ci = new ConceptReferenceComponent();
                union.getConcept().add(cu);
                intersection.getConcept().add(ci);
                StructuralMatch<Element> sm = new StructuralMatch<Element>(l, r);
                combined.getChildren().add(sm);
                compareConcepts(l, r, sm, cu, ci);
            } else {
                union.getConcept().add(l);
                union.getConcept().add(r);
                StructuralMatch<Element> sm = new StructuralMatch<Element>(l, r, vmI(IssueSeverity.INFORMATION, "Concepts are different", "ValueSet.compose.include.concept"));
                combined.getChildren().add(sm);
                compareConcepts(l, r, sm, null, null);
            }
        }
    }
    for (ConceptReferenceComponent r : right.getConcept()) {
        if (!matchCR.contains(r)) {
            union.getConcept().add(r);
            combined.getChildren().add(new StructuralMatch<Element>(vmI(IssueSeverity.INFORMATION, "Added this Concept", "ValueSet.compose.include.concept"), r));
        }
    }
    List<ConceptSetFilterComponent> matchFR = new ArrayList<>();
    for (ConceptSetFilterComponent l : left.getFilter()) {
        ConceptSetFilterComponent r = findInList(right.getFilter(), l, left.getFilter());
        if (r == null) {
            union.getFilter().add(l);
            combined.getChildren().add(new StructuralMatch<Element>(l, vmI(IssueSeverity.INFORMATION, "Removed this item", "ValueSet.compose.include.filter")));
        } else {
            matchFR.add(r);
            if (l.getProperty().equals(r.getProperty()) && l.getOp().equals(r.getOp())) {
                ConceptSetFilterComponent cu = new ConceptSetFilterComponent();
                ConceptSetFilterComponent ci = new ConceptSetFilterComponent();
                union.getFilter().add(cu);
                intersection.getFilter().add(ci);
                StructuralMatch<Element> sm = new StructuralMatch<Element>(l, r);
                combined.getChildren().add(sm);
                compareFilters(l, r, sm, cu, ci);
            } else {
                union.getFilter().add(l);
                union.getFilter().add(r);
                StructuralMatch<Element> sm = new StructuralMatch<Element>(l, r, vmI(IssueSeverity.INFORMATION, "Codes are different", "ValueSet.compose.include.filter"));
                combined.getChildren().add(sm);
                compareFilters(l, r, sm, null, null);
            }
        }
    }
    for (ConceptSetFilterComponent r : right.getFilter()) {
        if (!matchFR.contains(r)) {
            union.getFilter().add(r);
            combined.getChildren().add(new StructuralMatch<Element>(vmI(IssueSeverity.INFORMATION, "Added this item", "ValueSet.compose.include.filter"), r));
        }
    }
}
Also used : ConceptSetFilterComponent(org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent) Element(org.hl7.fhir.r5.model.Element) ArrayList(java.util.ArrayList) CanonicalType(org.hl7.fhir.r5.model.CanonicalType) ConceptReferenceComponent(org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent)

Example 15 with ConceptSetFilterComponent

use of org.hl7.fhir.r4.model.ValueSet.ConceptSetFilterComponent in project org.hl7.fhir.core by hapifhir.

the class TerminologyCache method getIncSummary.

private String getIncSummary(ConceptSetComponent cc) {
    CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
    for (UriType vs : cc.getValueSet()) b.append(vs.asStringValue());
    String vsd = b.length() > 0 ? " where the codes are in the value sets (" + b.toString() + ")" : "";
    String system = cc.getSystem();
    if (cc.hasConcept())
        return Integer.toString(cc.getConcept().size()) + " codes from " + system + vsd;
    if (cc.hasFilter()) {
        String s = "";
        for (ConceptSetFilterComponent f : cc.getFilter()) {
            if (!Utilities.noString(s))
                s = s + " & ";
            s = s + f.getProperty() + " " + f.getOp().toCode() + " " + f.getValue();
        }
        return "from " + system + " where " + s + vsd;
    }
    return "All codes from " + system + vsd;
}
Also used : ConceptSetFilterComponent(org.hl7.fhir.r4.model.ValueSet.ConceptSetFilterComponent) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) UriType(org.hl7.fhir.r4.model.UriType)

Aggregations

ConceptSetFilterComponent (org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent)6 XhtmlNode (org.hl7.fhir.utilities.xhtml.XhtmlNode)6 ArrayList (java.util.ArrayList)5 NotImplementedException (org.apache.commons.lang3.NotImplementedException)5 ConceptSetFilterComponent (org.hl7.fhir.r4b.model.ValueSet.ConceptSetFilterComponent)5 ConceptDefinitionComponent (org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent)5 ConceptReferenceComponent (org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent)5 CommaSeparatedStringBuilder (org.hl7.fhir.utilities.CommaSeparatedStringBuilder)5 TerminologyServiceException (org.hl7.fhir.exceptions.TerminologyServiceException)4 NoTerminologyServiceException (org.hl7.fhir.exceptions.NoTerminologyServiceException)3 ConceptDefinitionComponent (org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent)3 ConceptDefinitionComponent (org.hl7.fhir.r4b.model.CodeSystem.ConceptDefinitionComponent)3 UriType (org.hl7.fhir.r4b.model.UriType)3 ConceptReferenceComponent (org.hl7.fhir.r4b.model.ValueSet.ConceptReferenceComponent)3 UriType (org.hl7.fhir.r5.model.UriType)3 FileNotFoundException (java.io.FileNotFoundException)2 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 List (java.util.List)2 ValueSet (org.hl7.fhir.dstu2.model.ValueSet)2