Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
882e0853df
|
@ -62,6 +62,7 @@ public class TermConceptProperty implements Serializable {
|
|||
@Column(name = "PROP_KEY", nullable = false, length = MAX_LENGTH)
|
||||
@NotBlank
|
||||
private String myKey;
|
||||
// FIXME: DM 2019-09-13 - We presently truncate down to 500. The longest value for EXTERNAL_COPYRIGHT_NOTICE is 2,597 so we should use a LOB instead of a String.
|
||||
@Column(name = "PROP_VAL", nullable = true, length = MAX_LENGTH)
|
||||
private String myValue;
|
||||
@Column(name = "PROP_TYPE", nullable = false, length = MAX_PROPTYPE_ENUM_LENGTH)
|
||||
|
|
|
@ -691,11 +691,11 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
/**
|
||||
* @return Returns true if there are potentially more results to process.
|
||||
*/
|
||||
private Boolean expandValueSetHandleIncludeOrExclude(IValueSetConceptAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, boolean theAdd, AtomicInteger theCodeCounter, int theQueryIndex) {
|
||||
private Boolean expandValueSetHandleIncludeOrExclude(IValueSetConceptAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theIncludeOrExclude, boolean theAdd, AtomicInteger theCodeCounter, int theQueryIndex) {
|
||||
|
||||
String system = theInclude.getSystem();
|
||||
String system = theIncludeOrExclude.getSystem();
|
||||
boolean hasSystem = isNotBlank(system);
|
||||
boolean hasValueSet = theInclude.getValueSet().size() > 0;
|
||||
boolean hasValueSet = theIncludeOrExclude.getValueSet().size() > 0;
|
||||
|
||||
if (hasSystem) {
|
||||
ourLog.info("Starting {} expansion around CodeSystem: {}", (theAdd ? "inclusion" : "exclusion"), system);
|
||||
|
@ -711,7 +711,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
* since we're going to do it without the database.
|
||||
*/
|
||||
if (myFulltextSearchSvc == null) {
|
||||
expandWithoutHibernateSearch(theValueSetCodeAccumulator, theAddedCodes, theInclude, system, theAdd, theCodeCounter);
|
||||
expandWithoutHibernateSearch(theValueSetCodeAccumulator, theAddedCodes, theIncludeOrExclude, system, theAdd, theCodeCounter);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -726,85 +726,14 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
/*
|
||||
* Filters
|
||||
*/
|
||||
|
||||
if (theInclude.getFilter().size() > 0) {
|
||||
|
||||
for (ValueSet.ConceptSetFilterComponent nextFilter : theInclude.getFilter()) {
|
||||
if (isBlank(nextFilter.getValue()) && nextFilter.getOp() == null && isBlank(nextFilter.getProperty())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isBlank(nextFilter.getValue()) || nextFilter.getOp() == null || isBlank(nextFilter.getProperty())) {
|
||||
throw new InvalidRequestException("Invalid filter, must have fields populated: property op value");
|
||||
}
|
||||
|
||||
|
||||
if (nextFilter.getProperty().equals("display:exact") && nextFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
|
||||
addDisplayFilterExact(qb, bool, nextFilter);
|
||||
} else if ("display".equals(nextFilter.getProperty()) && nextFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
|
||||
if (nextFilter.getValue().trim().contains(" ")) {
|
||||
addDisplayFilterExact(qb, bool, nextFilter);
|
||||
} else {
|
||||
addDisplayFilterInexact(qb, bool, nextFilter);
|
||||
}
|
||||
} else if (nextFilter.getProperty().equals("concept") || nextFilter.getProperty().equals("code")) {
|
||||
|
||||
TermConcept code = findCode(system, nextFilter.getValue())
|
||||
.orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + system + "}" + nextFilter.getValue()));
|
||||
|
||||
if (nextFilter.getOp() == ValueSet.FilterOperator.ISA) {
|
||||
ourLog.info(" * Filtering on codes with a parent of {}/{}/{}", code.getId(), code.getCode(), code.getDisplay());
|
||||
bool.must(qb.keyword().onField("myParentPids").matching("" + code.getId()).createQuery());
|
||||
} else {
|
||||
throw new InvalidRequestException("Don't know how to handle op=" + nextFilter.getOp() + " on property " + nextFilter.getProperty());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (nextFilter.getOp() == ValueSet.FilterOperator.REGEX) {
|
||||
|
||||
/*
|
||||
* We treat the regex filter as a match on the regex
|
||||
* anywhere in the property string. The spec does not
|
||||
* say whether or not this is the right behaviour, but
|
||||
* there are examples that seem to suggest that it is.
|
||||
*/
|
||||
String value = nextFilter.getValue();
|
||||
if (value.endsWith("$")) {
|
||||
value = value.substring(0, value.length() - 1);
|
||||
} else if (!value.endsWith(".*")) {
|
||||
value = value + ".*";
|
||||
}
|
||||
if (!value.startsWith("^") && !value.startsWith(".*")) {
|
||||
value = ".*" + value;
|
||||
} else if (value.startsWith("^")) {
|
||||
value = value.substring(1);
|
||||
}
|
||||
|
||||
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + nextFilter.getProperty(), value);
|
||||
RegexpQuery query = new RegexpQuery(term);
|
||||
bool.must(query);
|
||||
|
||||
} else {
|
||||
|
||||
String value = nextFilter.getValue();
|
||||
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + nextFilter.getProperty(), value);
|
||||
bool.must(new TermsQuery(term));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
handleFilters(bool, system, qb, theIncludeOrExclude);
|
||||
|
||||
Query luceneQuery = bool.createQuery();
|
||||
|
||||
/*
|
||||
* Include Concepts
|
||||
* Include/Exclude Concepts
|
||||
*/
|
||||
|
||||
List<Term> codes = theInclude
|
||||
List<Term> codes = theIncludeOrExclude
|
||||
.getConcept()
|
||||
.stream()
|
||||
.filter(Objects::nonNull)
|
||||
|
@ -824,8 +753,8 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
/*
|
||||
* Execute the query
|
||||
*/
|
||||
|
||||
FullTextQuery jpaQuery = em.createFullTextQuery(luceneQuery, TermConcept.class);
|
||||
|
||||
/*
|
||||
* DM 2019-08-21 - Processing slows after any ValueSets with many codes explicitly identified. This might
|
||||
* be due to the dark arts that is memory management. Will monitor but not do anything about this right now.
|
||||
|
@ -864,15 +793,15 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
}
|
||||
|
||||
} else {
|
||||
// No codesystem matching the URL found in the database
|
||||
// No CodeSystem matching the URL found in the database.
|
||||
|
||||
CodeSystem codeSystemFromContext = getCodeSystemFromContext(system);
|
||||
if (codeSystemFromContext == null) {
|
||||
throw new InvalidRequestException("Unknown code system: " + system);
|
||||
}
|
||||
|
||||
if (!theInclude.getConcept().isEmpty()) {
|
||||
for (ValueSet.ConceptReferenceComponent next : theInclude.getConcept()) {
|
||||
if (!theIncludeOrExclude.getConcept().isEmpty()) {
|
||||
for (ValueSet.ConceptReferenceComponent next : theIncludeOrExclude.getConcept()) {
|
||||
String nextCode = next.getCode();
|
||||
if (isNoneBlank(system, nextCode) && !theAddedCodes.contains(system + "|" + nextCode)) {
|
||||
CodeSystem.ConceptDefinitionComponent code = findCode(codeSystemFromContext.getConcept(), nextCode);
|
||||
|
@ -895,7 +824,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
}
|
||||
} else if (hasValueSet) {
|
||||
|
||||
for (CanonicalType nextValueSet : theInclude.getValueSet()) {
|
||||
for (CanonicalType nextValueSet : theIncludeOrExclude.getValueSet()) {
|
||||
ourLog.info("Starting {} expansion around ValueSet: {}", (theAdd ? "inclusion" : "exclusion"), nextValueSet.getValueAsString());
|
||||
|
||||
List<VersionIndependentConcept> expanded = expandValueSet(nextValueSet.getValueAsString());
|
||||
|
@ -925,6 +854,191 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
|
||||
}
|
||||
|
||||
private void handleFilters(BooleanJunction<?> theBool, String theSystem, QueryBuilder theQb, ValueSet.ConceptSetComponent theIncludeOrExclude) {
|
||||
if (theIncludeOrExclude.getFilter().size() > 0) {
|
||||
for (ValueSet.ConceptSetFilterComponent nextFilter : theIncludeOrExclude.getFilter()) {
|
||||
handleFilter(theSystem, theQb, theBool, nextFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFilter(String theSystem, QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
|
||||
if (isBlank(theFilter.getValue()) && theFilter.getOp() == null && isBlank(theFilter.getProperty())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBlank(theFilter.getValue()) || theFilter.getOp() == null || isBlank(theFilter.getProperty())) {
|
||||
throw new InvalidRequestException("Invalid filter, must have fields populated: property op value");
|
||||
}
|
||||
|
||||
switch (theFilter.getProperty()) {
|
||||
case "display:exact":
|
||||
case "display":
|
||||
handleFilterDisplay(theQb, theBool, theFilter);
|
||||
break;
|
||||
case "concept":
|
||||
case "code":
|
||||
handleFilterConceptAndCode(theSystem, theQb, theBool, theFilter);
|
||||
break;
|
||||
case "parent":
|
||||
case "child":
|
||||
if (isCodeSystemLoinc(theSystem)) {
|
||||
handleFilterLoincParentChild(theQb, theBool, theFilter);
|
||||
} else {
|
||||
throw new InvalidRequestException("Invalid filter, property " + theFilter.getProperty() + " is LOINC-specific and cannot be used with system: " + theSystem);
|
||||
}
|
||||
break;
|
||||
case "copyright":
|
||||
if (isCodeSystemLoinc(theSystem)) {
|
||||
handleFilterLoincCopyright(theQb, theBool, theFilter);
|
||||
} else {
|
||||
throw new InvalidRequestException("Invalid filter, property " + theFilter.getProperty() + " is LOINC-specific and cannot be used with system: " + theSystem);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
handleFilterRegex(theBool, theFilter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCodeSystemLoinc(String theSystem) {
|
||||
return IHapiTerminologyLoaderSvc.LOINC_URI.equals(theSystem);
|
||||
}
|
||||
|
||||
private void handleFilterDisplay(QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
|
||||
if (theFilter.getProperty().equals("display:exact") && theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
|
||||
addDisplayFilterExact(theQb, theBool, theFilter);
|
||||
} else if (theFilter.getProperty().equals("display") && theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
|
||||
if (theFilter.getValue().trim().contains(" ")) {
|
||||
addDisplayFilterExact(theQb, theBool, theFilter);
|
||||
} else {
|
||||
addDisplayFilterInexact(theQb, theBool, theFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFilterConceptAndCode(String theSystem, QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
|
||||
TermConcept code = findCode(theSystem, theFilter.getValue())
|
||||
.orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + theSystem + "}" + theFilter.getValue()));
|
||||
|
||||
if (theFilter.getOp() == ValueSet.FilterOperator.ISA) {
|
||||
ourLog.info(" * Filtering on codes with a parent of {}/{}/{}", code.getId(), code.getCode(), code.getDisplay());
|
||||
theBool.must(theQb.keyword().onField("myParentPids").matching("" + code.getId()).createQuery());
|
||||
} else {
|
||||
throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFilterLoincParentChild(QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
|
||||
if (theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
|
||||
addLoincFilterParentChildEqual(theBool, theFilter.getProperty(), theFilter.getValue());
|
||||
} else if (theFilter.getOp() == ValueSet.FilterOperator.IN) {
|
||||
addLoincFilterParentChildIn(theBool, theFilter);
|
||||
} else {
|
||||
throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty());
|
||||
}
|
||||
}
|
||||
|
||||
private void addLoincFilterParentChildEqual(BooleanJunction<?> theBool, String theProperty, String theValue) {
|
||||
logFilteringValueOnProperty(theValue, theProperty);
|
||||
theBool.must(new TermsQuery(getPropertyTerm(theProperty, theValue)));
|
||||
}
|
||||
|
||||
private void addLoincFilterParentChildIn(BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
|
||||
String[] values = theFilter.getValue().split(",");
|
||||
List<Term> terms = new ArrayList<>();
|
||||
for (String value : values) {
|
||||
logFilteringValueOnProperty(value, theFilter.getProperty());
|
||||
terms.add(getPropertyTerm(theFilter.getProperty(), value));
|
||||
}
|
||||
theBool.must(new TermsQuery(terms));
|
||||
}
|
||||
|
||||
private Term getPropertyTerm(String theProperty, String theValue) {
|
||||
return new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + theProperty, theValue);
|
||||
}
|
||||
|
||||
private void handleFilterLoincCopyright(QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
|
||||
if (theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
|
||||
|
||||
String copyrightFilterValue = defaultString(theFilter.getValue()).toLowerCase();
|
||||
switch (copyrightFilterValue) {
|
||||
case "3rdparty":
|
||||
logFilteringValueOnProperty(theFilter.getValue(), theFilter.getProperty());
|
||||
addFilterLoincCopyright3rdParty(theBool);
|
||||
break;
|
||||
case "loinc":
|
||||
logFilteringValueOnProperty(theFilter.getValue(), theFilter.getProperty());
|
||||
addFilterLoincCopyrightLoinc(theBool);
|
||||
break;
|
||||
default:
|
||||
throwInvalidRequestForValueOnProperty(theFilter.getValue(), theFilter.getProperty());
|
||||
}
|
||||
|
||||
} else {
|
||||
throwInvalidRequestForOpOnProperty(theFilter.getOp(), theFilter.getProperty());
|
||||
}
|
||||
}
|
||||
|
||||
private void addFilterLoincCopyright3rdParty(BooleanJunction<?> theBool) {
|
||||
theBool.must(getRegexQueryForFilterLoincCopyright());
|
||||
}
|
||||
|
||||
private void addFilterLoincCopyrightLoinc(BooleanJunction<?> theBool) {
|
||||
theBool.must(getRegexQueryForFilterLoincCopyright()).not();
|
||||
}
|
||||
|
||||
private RegexpQuery getRegexQueryForFilterLoincCopyright() {
|
||||
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + "EXTERNAL_COPYRIGHT_NOTICE", ".*");
|
||||
return new RegexpQuery(term);
|
||||
}
|
||||
|
||||
private void logFilteringValueOnProperty(String theValue, String theProperty) {
|
||||
ourLog.info(" * Filtering with value={} on property {}", theValue, theProperty);
|
||||
}
|
||||
|
||||
private void throwInvalidRequestForOpOnProperty(ValueSet.FilterOperator theOp, String theProperty) {
|
||||
throw new InvalidRequestException("Don't know how to handle op=" + theOp + " on property " + theProperty);
|
||||
}
|
||||
|
||||
private void throwInvalidRequestForValueOnProperty(String theValue, String theProperty) {
|
||||
throw new InvalidRequestException("Don't know how to handle value=" + theValue + " on property " + theProperty);
|
||||
}
|
||||
|
||||
private void handleFilterRegex(BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
|
||||
if (theFilter.getOp() == ValueSet.FilterOperator.REGEX) {
|
||||
|
||||
/*
|
||||
* We treat the regex filter as a match on the regex
|
||||
* anywhere in the property string. The spec does not
|
||||
* say whether or not this is the right behaviour, but
|
||||
* there are examples that seem to suggest that it is.
|
||||
*/
|
||||
String value = theFilter.getValue();
|
||||
if (value.endsWith("$")) {
|
||||
value = value.substring(0, value.length() - 1);
|
||||
} else if (!value.endsWith(".*")) {
|
||||
value = value + ".*";
|
||||
}
|
||||
if (!value.startsWith("^") && !value.startsWith(".*")) {
|
||||
value = ".*" + value;
|
||||
} else if (value.startsWith("^")) {
|
||||
value = value.substring(1);
|
||||
}
|
||||
|
||||
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + theFilter.getProperty(), value);
|
||||
RegexpQuery query = new RegexpQuery(term);
|
||||
theBool.must(query);
|
||||
|
||||
} else {
|
||||
|
||||
String value = theFilter.getValue();
|
||||
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + theFilter.getProperty(), value);
|
||||
theBool.must(new TermsQuery(term));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void expandWithoutHibernateSearch(IValueSetConceptAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, String theSystem, boolean theAdd, AtomicInteger theCodeCounter) {
|
||||
ourLog.trace("Hibernate search is not enabled");
|
||||
if (theValueSetCodeAccumulator instanceof ValueSetExpansionComponentWithConceptAccumulator) {
|
||||
|
|
|
@ -480,6 +480,13 @@ public class TerminologyLoaderSvcImpl implements IHapiTerminologyLoaderSvc {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: DM 2019-09-13 - Manually add EXTERNAL_COPYRIGHT_NOTICE property until Regenstrief adds this to loinc.xml
|
||||
if (!propertyNamesToTypes.containsKey("EXTERNAL_COPYRIGHT_NOTICE")) {
|
||||
String externalCopyRightNoticeCode = "EXTERNAL_COPYRIGHT_NOTICE";
|
||||
CodeSystem.PropertyType externalCopyRightNoticeType = CodeSystem.PropertyType.STRING;
|
||||
propertyNamesToTypes.put(externalCopyRightNoticeCode, externalCopyRightNoticeType);
|
||||
}
|
||||
|
||||
IRecordHandler handler;
|
||||
|
||||
// Part
|
||||
|
|
|
@ -68,7 +68,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
|||
ValueSet vs;
|
||||
ConceptMap.ConceptMapGroupComponent group;
|
||||
|
||||
// Normal loinc code
|
||||
// Normal LOINC code
|
||||
code = concepts.get("10013-1");
|
||||
assertEquals("10013-1", code.getCode());
|
||||
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, code.getCodingProperties("PROPERTY").get(0).getSystem());
|
||||
|
@ -84,10 +84,17 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
|||
assertEquals("http://loinc.org", code.getCodingProperties("COMPONENT").get(0).getSystem());
|
||||
assertEquals("LP19258-0", code.getCodingProperties("COMPONENT").get(0).getCode());
|
||||
|
||||
// Loinc code with answer
|
||||
// LOINC code with answer
|
||||
code = concepts.get("61438-8");
|
||||
assertThat(code.getStringProperties("answer-list"), contains("LL1000-0"));
|
||||
|
||||
// LOINC code with 3rd party copyright
|
||||
code = concepts.get("47239-9");
|
||||
// FIXME: DM 2019-09-13 - We presently truncate down to 500. The longest value for EXTERNAL_COPYRIGHT_NOTICE is 2,597 so we should use a LOB instead of a String.
|
||||
// String expectedExternalCopyrightNotice = "Copyright © 2006 World Health Organization. Used with permission. Publications of the World Health Organization can be obtained from WHO Press, World Health Organization, 20 Avenue Appia, 1211 Geneva 27, Switzerland (tel: +41 22 791 2476; fax: +41 22 791 4857; email: bookorders@who.int). Requests for permission to reproduce or translate WHO publications – whether for sale or for noncommercial distribution – should be addressed to WHO Press, at the above address (fax: +41 22 791 4806; email: permissions@who.int). The designations employed and the presentation of the material in this publication do not imply the expression of any opinion whatsoever on the part of the World Health Organization concerning the legal status of any country, territory, city or area or of its authorities, or concerning the delimitation of its frontiers or boundaries. Dotted lines on maps represent approximate border lines for which there may not yet be full agreement. The mention of specific companies or of certain manufacturers’ products does not imply that they are endorsed or recommended by the World Health Organization in preference to others of a similar nature that are not mentioned. Errors and omissions excepted, the names of proprietary products are distinguished by initial capital letters. All reasonable precautions have been taken by WHO to verify the information contained in this publication. However, the published material is being distributed without warranty of any kind, either express or implied. The responsibility for the interpretation and use of the material lies with the reader. In no event shall the World Health Organization be liable for damages arising from its use.";
|
||||
String expectedExternalCopyrightNotice = "Copyright © 2006 World Health Organization. Used with permission. Publications of the World Health Organization can be obtained from WHO Press, World Health Organization, 20 Avenue Appia, 1211 Geneva 27, Switzerland (tel: +41 22 791 2476; fax: +41 22 791 4857; email: bookorders@who.int). Requests for permission to reproduce or translate WHO publications – whether for sale or for noncommercial distribution – should be addressed to WHO Press, at the above address (fax: +41 22 791 4806; email: perm";
|
||||
assertEquals(expectedExternalCopyrightNotice, code.getStringProperty("EXTERNAL_COPYRIGHT_NOTICE"));
|
||||
|
||||
// Answer list
|
||||
code = concepts.get("LL1001-8");
|
||||
assertEquals("LL1001-8", code.getCode());
|
||||
|
@ -330,7 +337,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
|||
Map<String, ValueSet> valueSets = extractValueSets();
|
||||
Map<String, ConceptMap> conceptMaps = extractConceptMaps();
|
||||
|
||||
// Normal loinc code
|
||||
// Normal LOINC code
|
||||
TermConcept code = concepts.get("10013-1");
|
||||
assertEquals("10013-1", code.getCode());
|
||||
|
||||
|
@ -394,7 +401,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
|||
ValueSet vs;
|
||||
ConceptMap.ConceptMapGroupComponent group;
|
||||
|
||||
// Normal loinc code
|
||||
// Normal LOINC code
|
||||
code = concepts.get("10013-1");
|
||||
assertEquals("10013-1", code.getCode());
|
||||
assertEquals(IHapiTerminologyLoaderSvc.LOINC_URI, code.getCodingProperties("PROPERTY").get(0).getSystem());
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc.LOINC_URI;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
@ -124,7 +125,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
public void createLoincSystemWithSomeCodes() {
|
||||
runInTransaction(() -> {
|
||||
CodeSystem codeSystem = new CodeSystem();
|
||||
codeSystem.setUrl(CS_URL);
|
||||
codeSystem.setUrl(LOINC_URI);
|
||||
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
|
||||
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
|
||||
|
||||
|
@ -133,22 +134,57 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
TermCodeSystemVersion cs = new TermCodeSystemVersion();
|
||||
cs.setResource(table);
|
||||
|
||||
TermConcept code;
|
||||
code = new TermConcept(cs, "50015-7");
|
||||
code.addPropertyString("SYSTEM", "Bld/Bone mar^Donor");
|
||||
cs.getConcepts().add(code);
|
||||
TermConcept code1 = new TermConcept(cs, "50015-7");
|
||||
TermConcept code2 = new TermConcept(cs, "43343-3");
|
||||
TermConcept code3 = new TermConcept(cs, "43343-4");
|
||||
TermConcept code4 = new TermConcept(cs, "47239-9");
|
||||
|
||||
code = new TermConcept(cs, "43343-3");
|
||||
code.addPropertyString("SYSTEM", "Ser");
|
||||
code.addPropertyString("HELLO", "12345-1");
|
||||
cs.getConcepts().add(code);
|
||||
code1.addPropertyString("SYSTEM", "Bld/Bone mar^Donor");
|
||||
code1.addPropertyCoding(
|
||||
"child",
|
||||
LOINC_URI,
|
||||
code2.getCode(),
|
||||
code2.getDisplay());
|
||||
cs.getConcepts().add(code1);
|
||||
|
||||
code = new TermConcept(cs, "43343-4");
|
||||
code.addPropertyString("SYSTEM", "Ser");
|
||||
code.addPropertyString("HELLO", "12345-2");
|
||||
cs.getConcepts().add(code);
|
||||
code2.addPropertyString("SYSTEM", "Ser");
|
||||
code2.addPropertyString("HELLO", "12345-1");
|
||||
code2.addPropertyCoding(
|
||||
"parent",
|
||||
LOINC_URI,
|
||||
code1.getCode(),
|
||||
code1.getDisplay());
|
||||
code2.addPropertyCoding(
|
||||
"child",
|
||||
LOINC_URI,
|
||||
code3.getCode(),
|
||||
code3.getDisplay());
|
||||
code2.addPropertyCoding(
|
||||
"child",
|
||||
LOINC_URI,
|
||||
code4.getCode(),
|
||||
code4.getDisplay());
|
||||
cs.getConcepts().add(code2);
|
||||
|
||||
myTermSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION" , cs);
|
||||
code3.addPropertyString("SYSTEM", "Ser");
|
||||
code3.addPropertyString("HELLO", "12345-2");
|
||||
code3.addPropertyCoding(
|
||||
"parent",
|
||||
LOINC_URI,
|
||||
code2.getCode(),
|
||||
code2.getDisplay());
|
||||
cs.getConcepts().add(code3);
|
||||
|
||||
code4.addPropertyString("SYSTEM", "^Patient");
|
||||
code4.addPropertyString("EXTERNAL_COPYRIGHT_NOTICE", "Copyright © 2006 World Health Organization...");
|
||||
code4.addPropertyCoding(
|
||||
"parent",
|
||||
LOINC_URI,
|
||||
code2.getCode(),
|
||||
code2.getDisplay());
|
||||
cs.getConcepts().add(code4);
|
||||
|
||||
myTermSvc.storeNewCodeSystemVersion(table.getId(), LOINC_URI, "SYSTEM NAME", "SYSTEM VERSION" , cs);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -273,6 +309,714 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincCopyrightWithExclude3rdParty() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent exclude;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("3rdParty");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("3rdparty");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincCopyrightWithExcludeLoinc() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent exclude;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("LOINC");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("47239-9"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("loinc");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("47239-9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincCopyrightWithInclude3rdParty() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("3rdParty");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("47239-9"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("3rdparty");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("47239-9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincCopyrightWithIncludeLoinc() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("LOINC");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("loinc");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincCopyrightWithUnsupportedOp() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
ValueSet vs;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.ISA)
|
||||
.setValue("LOINC");
|
||||
try {
|
||||
myTermSvc.expandValueSet(vs);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(400, e.getStatusCode());
|
||||
assertEquals("Don't know how to handle op=ISA on property copyright", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincCopyrightWithUnsupportedSystem() {
|
||||
createCodeSystem();
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
ValueSet vs;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("LOINC");
|
||||
try {
|
||||
myTermSvc.expandValueSet(vs);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(400, e.getStatusCode());
|
||||
assertEquals("Invalid filter, property copyright is LOINC-specific and cannot be used with system: http://example.com/my_code_system", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincCopyrightWithUnsupportedValue() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
ValueSet vs;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("copyright")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("bogus");
|
||||
try {
|
||||
myTermSvc.expandValueSet(vs);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(400, e.getStatusCode());
|
||||
assertEquals("Don't know how to handle value=bogus on property copyright", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincChildWithExcludeAndEqual() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent exclude;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("50015-7");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4", "47239-9"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("43343-3");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("43343-3", "43343-4", "47239-9"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("43343-4");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-4", "47239-9"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("47239-9");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-4", "47239-9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincChildWithExcludeAndIn() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent exclude;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.IN)
|
||||
.setValue("50015-7,43343-3,43343-4,47239-9");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("43343-4", "47239-9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincChildWithIncludeAndEqual() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("50015-7");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
assertEquals(0, outcome.getExpansion().getContains().size());
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("43343-3");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("43343-4");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("43343-3"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("47239-9");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("43343-3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincChildWithIncludeAndIn() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.IN)
|
||||
.setValue("50015-7,43343-3,43343-4,47239-9");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincChildWithUnsupportedOp() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
ValueSet vs;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.ISA)
|
||||
.setValue("50015-7");
|
||||
try {
|
||||
myTermSvc.expandValueSet(vs);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(400, e.getStatusCode());
|
||||
assertEquals("Don't know how to handle op=ISA on property child", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincChildWithUnsupportedSystem() {
|
||||
createCodeSystem();
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
ValueSet vs;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(CS_URL);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("child")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("50015-7");
|
||||
try {
|
||||
myTermSvc.expandValueSet(vs);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(400, e.getStatusCode());
|
||||
assertEquals("Invalid filter, property child is LOINC-specific and cannot be used with system: http://example.com/my_code_system", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincParentWithExcludeAndEqual() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent exclude;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("50015-7");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-4", "47239-9"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("43343-3");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("43343-4");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4", "47239-9"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("47239-9");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4", "47239-9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincParentWithExcludeAndIn() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent exclude;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(LOINC_URI);
|
||||
// Exclude
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.IN)
|
||||
.setValue("50015-7,43343-3,43343-4,47239-9");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincParentWithIncludeAndEqual() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("50015-7");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("43343-3"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("43343-3");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("43343-4", "47239-9"));
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("43343-4");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
assertEquals(0, outcome.getExpansion().getContains().size());
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("47239-9");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
assertEquals(0, outcome.getExpansion().getContains().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincParentWithIncludeAndIn() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
ValueSet vs;
|
||||
ValueSet outcome;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.IN)
|
||||
.setValue("50015-7,43343-3,43343-4,47239-9");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("43343-3", "43343-4", "47239-9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincParentWithUnsupportedOp() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
ValueSet vs;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.ISA)
|
||||
.setValue("50015-7");
|
||||
try {
|
||||
myTermSvc.expandValueSet(vs);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(400, e.getStatusCode());
|
||||
assertEquals("Don't know how to handle op=ISA on property parent", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertyFilterLoincParentWithUnsupportedSystem() {
|
||||
createCodeSystem();
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
ValueSet vs;
|
||||
ValueSet.ConceptSetComponent include;
|
||||
|
||||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(CS_URL);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("parent")
|
||||
.setOp(ValueSet.FilterOperator.EQUAL)
|
||||
.setValue("50015-7");
|
||||
try {
|
||||
myTermSvc.expandValueSet(vs);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(400, e.getStatusCode());
|
||||
assertEquals("Invalid filter, property parent is LOINC-specific and cannot be used with system: http://example.com/my_code_system", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertySearchWithRegexExclude() {
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
@ -286,10 +1030,10 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(CS_URL);
|
||||
.setSystem(LOINC_URI);
|
||||
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(CS_URL);
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("SYSTEM")
|
||||
|
@ -297,7 +1041,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
.setValue(".*\\^Donor$");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("43343-3", "43343-4"));
|
||||
assertThat(codes, containsInAnyOrder("43343-3", "43343-4", "47239-9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -313,10 +1057,10 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
vs = new ValueSet();
|
||||
vs.getCompose()
|
||||
.addInclude()
|
||||
.setSystem(CS_URL);
|
||||
.setSystem(LOINC_URI);
|
||||
|
||||
exclude = vs.getCompose().addExclude();
|
||||
exclude.setSystem(CS_URL);
|
||||
exclude.setSystem(LOINC_URI);
|
||||
exclude
|
||||
.addFilter()
|
||||
.setProperty("HELLO")
|
||||
|
@ -324,12 +1068,11 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
.setValue("12345-1|12345-2");
|
||||
outcome = myTermSvc.expandValueSet(vs);
|
||||
codes = toCodesContains(outcome.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("50015-7"));
|
||||
assertThat(codes, containsInAnyOrder("50015-7", "47239-9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandValueSetPropertySearchWithRegexInclude() {
|
||||
// create codes with "SYSTEM" property "Bld/Bone mar^Donor" and "Ser"
|
||||
createLoincSystemWithSomeCodes();
|
||||
|
||||
List<String> codes;
|
||||
|
@ -340,7 +1083,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(CS_URL);
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("SYSTEM")
|
||||
|
@ -353,7 +1096,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(CS_URL);
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("SYSTEM")
|
||||
|
@ -366,7 +1109,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(CS_URL);
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("SYSTEM")
|
||||
|
@ -379,7 +1122,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(CS_URL);
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("SYSTEM")
|
||||
|
@ -392,7 +1135,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(CS_URL);
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("SYSTEM")
|
||||
|
@ -405,7 +1148,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
|
|||
// Include
|
||||
vs = new ValueSet();
|
||||
include = vs.getCompose().addInclude();
|
||||
include.setSystem(CS_URL);
|
||||
include.setSystem(LOINC_URI);
|
||||
include
|
||||
.addFilter()
|
||||
.setProperty("SYSTEM")
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
"LOINC_NUM","COMPONENT" ,"PROPERTY","TIME_ASPCT","SYSTEM" ,"SCALE_TYP","METHOD_TYP" ,"CLASS" ,"VersionLastChanged","CHNG_TYPE","DefinitionDescription" ,"STATUS","CONSUMER_NAME","CLASSTYPE","FORMULA","SPECIES","EXMPL_ANSWERS","SURVEY_QUEST_TEXT" ,"SURVEY_QUEST_SRC" ,"UNITSREQUIRED","SUBMITTED_UNITS","RELATEDNAMES2" ,"SHORTNAME" ,"ORDER_OBS" ,"CDISC_COMMON_TESTS","HL7_FIELD_SUBFIELD_ID","EXTERNAL_COPYRIGHT_NOTICE","EXAMPLE_UNITS","LONG_COMMON_NAME" ,"UnitsAndRange","DOCUMENT_SECTION","EXAMPLE_UCUM_UNITS","EXAMPLE_SI_UCUM_UNITS","STATUS_REASON","STATUS_TEXT","CHANGE_REASON_PUBLIC" ,"COMMON_TEST_RANK","COMMON_ORDER_RANK","COMMON_SI_TEST_RANK","HL7_ATTACHMENT_STRUCTURE","EXTERNAL_COPYRIGHT_LINK","PanelType","AskAtOrderEntry","AssociatedObservations" ,"VersionFirstReleased","ValidHL7AttachmentRequest"
|
||||
"10013-1" ,"R' wave amplitude.lead I" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-I; R wave Amp L-I; Random; Right; Voltage" ,"R' wave Amp L-I" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead I" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10014-9" ,"R' wave amplitude.lead II" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"2; Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-II; R wave Amp L-II; Random; Right; Voltage" ,"R' wave Amp L-II" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead II" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10015-6" ,"R' wave amplitude.lead III" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"3; Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-III; R wave Amp L-III; Random; Right; Voltage" ,"R' wave Amp L-III" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead III" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10016-4" ,"R' wave amplitude.lead V1" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V1; R wave Amp L-V1; Random; Right; Voltage" ,"R' wave Amp L-V1" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V1" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"1001-7" ,"DBG Ab" ,"Pr" ,"Pt" ,"Ser/Plas^donor" ,"Ord" , ,"BLDBK" ,"2.44" ,"MIN" , ,"ACTIVE", ,1 , , , , , , , ,"ABS; Aby; Antby; Anti; Antibodies; Antibody; Autoantibodies; Autoantibody; BLOOD BANK; Donna Bennett-Goodspeed; Donr; Ordinal; Pl; Plasma; Plsm; Point in time; QL; Qual; Qualitative; Random; Screen; SerP; SerPl; SerPl^donor; SerPlas; Serum; Serum or plasma; SR" ,"DBG Ab SerPl Donr Ql" ,"Observation", , , , ,"DBG Ab [Presence] in Serum or Plasma from donor" , , , , , , ,"The Property has been changed from ACnc to Pr (Presence) to reflect the new model for ordinal terms where results are based on presence or absence." ,0 ,0 ,0 , , , , , , ,
|
||||
"10017-2" ,"R' wave amplitude.lead V2" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V2; R wave Amp L-V2; Random; Right; Voltage" ,"R' wave Amp L-V2" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V2" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10018-0" ,"R' wave amplitude.lead V3" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V3; R wave Amp L-V3; Random; Right; Voltage" ,"R' wave Amp L-V3" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V3" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10019-8" ,"R' wave amplitude.lead V4" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V4; R wave Amp L-V4; Random; Right; Voltage" ,"R' wave Amp L-V4" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V4" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10020-6" ,"R' wave amplitude.lead V5" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V5; R wave Amp L-V5; Random; Right; Voltage" ,"R' wave Amp L-V5" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V5" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"61438-8" ,"Each time you ate bread, toast or dinner rolls, how much did you usually eat in the past 30D","Find" ,"Pt" ,"^Patient" ,"Ord" ,"PhenX" ,"PHENX" ,"2.44" ,"MIN" , ,"TRIAL" , ,2 , , , ,"Each time you eat bread, toast or dinner rolls, how much do you usually eat?","PhenX.050201100100","N" , ,"Finding; Findings; How much bread in 30D; Last; Ordinal; Point in time; QL; Qual; Qualitative; Random; Screen" ,"How much bread in 30D PhenX", , , , , ,"Each time you ate bread, toast or dinner rolls, how much did you usually eat in the past 30 days [PhenX]", , , , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10000-8" ,"R wave duration.lead AVR" ,"Time" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; Durat; ECG; EKG.MEASUREMENTS; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave dur L-AVR; R wave dur L-AVR; Random; Right" ,"R wave dur L-AVR" ,"Observation", , , ,"s" ,"R wave duration in lead AVR" , , ,"s" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"17787-3" ,"Study report" ,"Find" ,"Pt" ,"Neck>Thyroid gland","Doc" ,"NM" ,"RAD" ,"2.61" ,"MIN" , ,"ACTIVE", ,2 , , , , , , , ,"Document; Finding; Findings; Imaging; Point in time; Radiology; Random; Study report; Thy" ,"NM Thyroid Study report" ,"Both" , , , , ,"NM Thyroid gland Study report" , , , , , , ,"Changed System from ""Thyroid"" for conformance with the LOINC/RadLex unified model.; Method of ""Radnuc"" was changed to ""NM"". The LOINC/RadLex Committee agreed to use a subset of the two-letter DICOM modality codes as the primary modality identifier." ,0 ,0 ,0 ,"IG exists" , , , ,"81220-6;72230-6" ,"1.0l" ,
|
||||
"17788-1" ,"Large unstained cells/100 leukocytes" ,"NFr" ,"Pt" ,"Bld" ,"Qn" ,"Automated count","HEM/BC" ,"2.50" ,"MIN" ,"Part of auto diff output of Bayer H*3S; peroxidase negative cells too large to be classified as lymph or basophil" ,"ACTIVE", ,1 , , , , , ,"Y" ,"%" ,"100WBC; Auto; Automated detection; Blood; Cell; Cellularity; Elec; Elect; Electr; HEMATOLOGY/CELL COUNTS; Leuc; Leuk; Leukocyte; Lkcs; LUC; Number Fraction; Percent; Point in time; QNT; Quan; Quant; Quantitative; Random; WB; WBC; WBCs; White blood cell; White blood cells; Whole blood" ,"LUC/leuk NFr Bld Auto" ,"Observation", , , ,"%" ,"Large unstained cells/100 leukocytes in Blood by Automated count" , , ,"%" , , , , ,1894 ,0 ,1894 , , , , , ,"1.0l" ,
|
||||
"11488-4" ,"Consultation note" ,"Find" ,"Pt" ,"{Setting}" ,"Doc" ,"{Role}" ,"DOC.ONTOLOGY","2.63" ,"MIN" , ,"ACTIVE", ,2 , , , , , , , ,"Consult note; DOC.ONT; Document; Encounter; Evaluation and management; Evaluation and management note; Finding; Findings; notes; Point in time; Random; Visit note" ,"Consult note" ,"Both" , , , , ,"Consult note" , , , , , , ,"Edit made because this term is conformant to the Document Ontology axis values and therefore are being placed in this class.; Based on Clinical LOINC Committee decision during the September 2014 meeting, {Provider} was changed to {Author Type} to emphasize a greater breadth of potential document authors. At the September 2015 Clinical LOINC Committee meeting, the Committee decided to change {Author Type} to {Role} to align with the 'Role' axis name in the LOINC Document Ontology.; Because it is too difficult to maintain and because the distinction between documents and sections is not clear-cut nor necessary in most cases, the DOCUMENT_SECTION field has been deemed to have little value. The field has been set to null in the December 2017 release in preparation for removal in the December 2018 release. These changes were approved by the Clinical LOINC Committee.",0 ,0 ,0 ,"IG exists" , , , ,"81222-2;72231-4;81243-8","1.0j-a" ,"Y"
|
||||
"LOINC_NUM","COMPONENT" ,"PROPERTY","TIME_ASPCT","SYSTEM" ,"SCALE_TYP","METHOD_TYP" ,"CLASS" ,"VersionLastChanged","CHNG_TYPE","DefinitionDescription" ,"STATUS","CONSUMER_NAME","CLASSTYPE","FORMULA","SPECIES","EXMPL_ANSWERS","SURVEY_QUEST_TEXT" ,"SURVEY_QUEST_SRC" ,"UNITSREQUIRED","SUBMITTED_UNITS","RELATEDNAMES2" ,"SHORTNAME" ,"ORDER_OBS" ,"CDISC_COMMON_TESTS","HL7_FIELD_SUBFIELD_ID","EXTERNAL_COPYRIGHT_NOTICE" ,"EXAMPLE_UNITS","LONG_COMMON_NAME" ,"UnitsAndRange","DOCUMENT_SECTION","EXAMPLE_UCUM_UNITS","EXAMPLE_SI_UCUM_UNITS","STATUS_REASON","STATUS_TEXT","CHANGE_REASON_PUBLIC" ,"COMMON_TEST_RANK","COMMON_ORDER_RANK","COMMON_SI_TEST_RANK","HL7_ATTACHMENT_STRUCTURE","EXTERNAL_COPYRIGHT_LINK","PanelType","AskAtOrderEntry","AssociatedObservations" ,"VersionFirstReleased","ValidHL7AttachmentRequest"
|
||||
"10013-1" ,"R' wave amplitude.lead I" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-I; R wave Amp L-I; Random; Right; Voltage" ,"R' wave Amp L-I" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead I" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10014-9" ,"R' wave amplitude.lead II" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"2; Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-II; R wave Amp L-II; Random; Right; Voltage" ,"R' wave Amp L-II" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead II" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10015-6" ,"R' wave amplitude.lead III" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"3; Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-III; R wave Amp L-III; Random; Right; Voltage" ,"R' wave Amp L-III" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead III" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10016-4" ,"R' wave amplitude.lead V1" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V1; R wave Amp L-V1; Random; Right; Voltage" ,"R' wave Amp L-V1" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V1" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"1001-7" ,"DBG Ab" ,"Pr" ,"Pt" ,"Ser/Plas^donor" ,"Ord" , ,"BLDBK" ,"2.44" ,"MIN" , ,"ACTIVE", ,1 , , , , , , , ,"ABS; Aby; Antby; Anti; Antibodies; Antibody; Autoantibodies; Autoantibody; BLOOD BANK; Donna Bennett-Goodspeed; Donr; Ordinal; Pl; Plasma; Plsm; Point in time; QL; Qual; Qualitative; Random; Screen; SerP; SerPl; SerPl^donor; SerPlas; Serum; Serum or plasma; SR" ,"DBG Ab SerPl Donr Ql" ,"Observation", , , , ,"DBG Ab [Presence] in Serum or Plasma from donor" , , , , , , ,"The Property has been changed from ACnc to Pr (Presence) to reflect the new model for ordinal terms where results are based on presence or absence." ,0 ,0 ,0 , , , , , , ,
|
||||
"10017-2" ,"R' wave amplitude.lead V2" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V2; R wave Amp L-V2; Random; Right; Voltage" ,"R' wave Amp L-V2" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V2" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10018-0" ,"R' wave amplitude.lead V3" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V3; R wave Amp L-V3; Random; Right; Voltage" ,"R' wave Amp L-V3" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V3" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10019-8" ,"R' wave amplitude.lead V4" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V4; R wave Amp L-V4; Random; Right; Voltage" ,"R' wave Amp L-V4" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V4" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10020-6" ,"R' wave amplitude.lead V5" ,"Elpot" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V5; R wave Amp L-V5; Random; Right; Voltage" ,"R' wave Amp L-V5" ,"Observation", , , ,"mV" ,"R' wave amplitude in lead V5" , , ,"mV" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"61438-8" ,"Each time you ate bread, toast or dinner rolls, how much did you usually eat in the past 30D","Find" ,"Pt" ,"^Patient" ,"Ord" ,"PhenX" ,"PHENX" ,"2.44" ,"MIN" , ,"TRIAL" , ,2 , , , ,"Each time you eat bread, toast or dinner rolls, how much do you usually eat?","PhenX.050201100100","N" , ,"Finding; Findings; How much bread in 30D; Last; Ordinal; Point in time; QL; Qual; Qualitative; Random; Screen" ,"How much bread in 30D PhenX", , , , , ,"Each time you ate bread, toast or dinner rolls, how much did you usually eat in the past 30 days [PhenX]", , , , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"10000-8" ,"R wave duration.lead AVR" ,"Time" ,"Pt" ,"Heart" ,"Qn" ,"EKG" ,"EKG.MEAS" ,"2.48" ,"MIN" , ,"ACTIVE", ,2 , , , , , ,"Y" , ,"Cardiac; Durat; ECG; EKG.MEASUREMENTS; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave dur L-AVR; R wave dur L-AVR; Random; Right" ,"R wave dur L-AVR" ,"Observation", , , ,"s" ,"R wave duration in lead AVR" , , ,"s" , , , , ,0 ,0 ,0 , , , , , , ,
|
||||
"17787-3" ,"Study report" ,"Find" ,"Pt" ,"Neck>Thyroid gland","Doc" ,"NM" ,"RAD" ,"2.61" ,"MIN" , ,"ACTIVE", ,2 , , , , , , , ,"Document; Finding; Findings; Imaging; Point in time; Radiology; Random; Study report; Thy" ,"NM Thyroid Study report" ,"Both" , , , , ,"NM Thyroid gland Study report" , , , , , , ,"Changed System from ""Thyroid"" for conformance with the LOINC/RadLex unified model.; Method of ""Radnuc"" was changed to ""NM"". The LOINC/RadLex Committee agreed to use a subset of the two-letter DICOM modality codes as the primary modality identifier." ,0 ,0 ,0 ,"IG exists" , , , ,"81220-6;72230-6" ,"1.0l" ,
|
||||
"17788-1" ,"Large unstained cells/100 leukocytes" ,"NFr" ,"Pt" ,"Bld" ,"Qn" ,"Automated count","HEM/BC" ,"2.50" ,"MIN" ,"Part of auto diff output of Bayer H*3S; peroxidase negative cells too large to be classified as lymph or basophil" ,"ACTIVE", ,1 , , , , , ,"Y" ,"%" ,"100WBC; Auto; Automated detection; Blood; Cell; Cellularity; Elec; Elect; Electr; HEMATOLOGY/CELL COUNTS; Leuc; Leuk; Leukocyte; Lkcs; LUC; Number Fraction; Percent; Point in time; QNT; Quan; Quant; Quantitative; Random; WB; WBC; WBCs; White blood cell; White blood cells; Whole blood" ,"LUC/leuk NFr Bld Auto" ,"Observation", , , ,"%" ,"Large unstained cells/100 leukocytes in Blood by Automated count" , , ,"%" , , , , ,1894 ,0 ,1894 , , , , , ,"1.0l" ,
|
||||
"11488-4" ,"Consultation note" ,"Find" ,"Pt" ,"{Setting}" ,"Doc" ,"{Role}" ,"DOC.ONTOLOGY","2.63" ,"MIN" , ,"ACTIVE", ,2 , , , , , , , ,"Consult note; DOC.ONT; Document; Encounter; Evaluation and management; Evaluation and management note; Finding; Findings; notes; Point in time; Random; Visit note" ,"Consult note" ,"Both" , , , , ,"Consult note" , , , , , , ,"Edit made because this term is conformant to the Document Ontology axis values and therefore are being placed in this class.; Based on Clinical LOINC Committee decision during the September 2014 meeting, {Provider} was changed to {Author Type} to emphasize a greater breadth of potential document authors. At the September 2015 Clinical LOINC Committee meeting, the Committee decided to change {Author Type} to {Role} to align with the 'Role' axis name in the LOINC Document Ontology.; Because it is too difficult to maintain and because the distinction between documents and sections is not clear-cut nor necessary in most cases, the DOCUMENT_SECTION field has been deemed to have little value. The field has been set to null in the December 2017 release in preparation for removal in the December 2018 release. These changes were approved by the Clinical LOINC Committee.",0 ,0 ,0 ,"IG exists" , , , ,"81222-2;72231-4;81243-8","1.0j-a" ,"Y"
|
||||
"47239-9" ,"Reason for stopping HIV Rx" ,"Type" ,"Pt" ,"^Patient" ,"Nom" ,"Reported" ,"ART" ,"2.50" ,"MIN" ,"Reason for stopping antiretroviral therapy" ,"ACTIVE", ,2 , , , , , ,"N" , ,"AIDS; Anti-retroviral therapy; ART; Human immunodeficiency virus; Nominal; Point in time; Random; Treatment; Typ" ,"Reason for stopping HIV Rx" ,"Observation", , ,"Copyright © 2006 World Health Organization. Used with permission. Publications of the World Health Organization can be obtained from WHO Press, World Health Organization, 20 Avenue Appia, 1211 Geneva 27, Switzerland (tel: +41 22 791 2476; fax: +41 22 791 4857; email: bookorders@who.int). Requests for permission to reproduce or translate WHO publications – whether for sale or for noncommercial distribution – should be addressed to WHO Press, at the above address (fax: +41 22 791 4806; email: permissions@who.int). The designations employed and the presentation of the material in this publication do not imply the expression of any opinion whatsoever on the part of the World Health Organization concerning the legal status of any country, territory, city or area or of its authorities, or concerning the delimitation of its frontiers or boundaries. Dotted lines on maps represent approximate border lines for which there may not yet be full agreement. The mention of specific companies or of certain manufacturers’ products does not imply that they are endorsed or recommended by the World Health Organization in preference to others of a similar nature that are not mentioned. Errors and omissions excepted, the names of proprietary products are distinguished by initial capital letters. All reasonable precautions have been taken by WHO to verify the information contained in this publication. However, the published material is being distributed without warranty of any kind, either express or implied. The responsibility for the interpretation and use of the material lies with the reader. In no event shall the World Health Organization be liable for damages arising from its use.", ,"Reason for stopping HIV treatment" , , , , , , , ,0 ,0 ,0 , ,"WHO_HIV" , , , ,"2.22" ,
|
||||
|
|
Can't render this file because it contains an unexpected character in line 1 and column 23.
|
Loading…
Reference in New Issue