Skip to content

Commit

Permalink
Merge pull request #1396 from hapifhir/2023-08-gg-tx-tests-externals
Browse files Browse the repository at this point in the history
2023 08 gg tx tests externals
  • Loading branch information
grahamegrieve authored Aug 19, 2023
2 parents 4766cb3 + 1248bae commit 12e38a3
Show file tree
Hide file tree
Showing 52 changed files with 1,429 additions and 606 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;

import org.hl7.fhir.exceptions.FHIRException;
Expand Down Expand Up @@ -56,19 +58,23 @@ private void doImport(String src, String version, String dst) throws FHIRExcepti
cs.setCopyright("CPT © Copyright 2019 American Medical Association. All rights reserved. AMA and CPT are registered trademarks of the American Medical Association.");
cs.addProperty().setCode("modifier").setDescription("Whether code is a modifier code").setType(PropertyType.BOOLEAN);
cs.addProperty().setCode("modified").setDescription("Whether code has been modified (all base codes are not modified)").setType(PropertyType.BOOLEAN);
cs.addProperty().setCode("orthopox").setDescription("Whether code is one of the Pathology and Laboratory and Immunization Code(s) for Orthopoxvirus").setType(PropertyType.BOOLEAN);
cs.addProperty().setCode("telemedicine").setDescription("Whether code is appropriate for use with telemedicine (and the telemedicine modifier)").setType(PropertyType.BOOLEAN);
cs.addProperty().setCode("kind").setDescription("Kind of Code (see metadata)").setType(PropertyType.CODE);

defineMetadata(cs);

System.out.println(readCodes(cs, Utilities.path(src, "LONGULT.txt"), false, null, null));
System.out.println(readCodes(cs, Utilities.path(src, "LONGUT.txt"), false, "upper", null));
System.out.println(readCodes(cs, Utilities.path(src, "MEDU.txt"), false, "med", null));
System.out.println(readCodes(cs, Utilities.path(src, "SHORTU.txt"), false, "short", null));
System.out.println(readCodes(cs, Utilities.path(src, "ConsumerDescriptor.txt"), true, "consumer", null));
System.out.println(readCodes(cs, Utilities.path(src, "ClinicianDescriptor.txt"), true, "clinician", null));
System.out.println(readCodes(cs, Utilities.path(src, "OrthopoxvirusCodes.txt"), false, null, "orthopod"));
System.out.println("LONGULT: "+readCodes(cs, Utilities.path(src, "LONGULT.txt"), false, null, null, null));
System.out.println("LONGUT: "+readCodes(cs, Utilities.path(src, "LONGUT.txt"), false, "upper", null, null));
System.out.println("MEDU: "+readCodes(cs, Utilities.path(src, "MEDU.txt"), false, "med", null, null));
System.out.println("SHORTU: "+readCodes(cs, Utilities.path(src, "SHORTU.txt"), false, "short", null, null));
System.out.println("ConsumerDescriptor: "+readCodes(cs, Utilities.path(src, "ConsumerDescriptor.txt"), true, "consumer", null, null));
System.out.println("ClinicianDescriptor: "+readCodes(cs, Utilities.path(src, "ClinicianDescriptor.txt"), true, "clinician", null, null));
System.out.println("OrthopoxvirusCodes: "+readCodes(cs, Utilities.path(src, "OrthopoxvirusCodes.txt"), false, null, null, "orthopox"));

System.out.println(processModifiers(cs, Utilities.path(src, "modifiers.csv")));
System.out.println("modifiers: "+processModifiers(cs, Utilities.path(src, "modifiers.csv")));
System.out.println("appendix P: "+processAppendixP(cs));


System.out.println("-------------------");
System.out.println(cs.getConcept().size());
Expand All @@ -87,11 +93,59 @@ private void doImport(String src, String version, String dst) throws FHIRExcepti
produceDB(Utilities.changeFileExt(dst, ".db"), cs);

cs.setContent(CodeSystemContentMode.FRAGMENT);
cs.getConcept().removeIf(cc -> !Utilities.existsInList(cc.getCode(), "metadata-kinds", "metadata-designations", "99202", "99203", "0001A", "25", "P1", "1P", "F1"));
cs.getConcept().removeIf(cc -> !Utilities.existsInList(cc.getCode(), "metadata-kinds", "metadata-designations", "99202", "99203", "0001A", "99252", "25", "P1", "1P", "F1", "95"));
new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.changeFileExt(dst, "-fragment.json")), cs);
produceDB(Utilities.changeFileExt(dst, "-fragment.db"), cs);
}

private String processAppendixP(CodeSystem cs) {
List<String> tcodes = new ArrayList<>();
tcodes.add("90785");
tcodes.add("90791");
tcodes.add("90792");
tcodes.add("90832");
tcodes.add("90833");
tcodes.add("90834");
tcodes.add("90836");
tcodes.add("90837");
tcodes.add("90838");
tcodes.add("90839");
tcodes.add("90840");
tcodes.add("90845");
tcodes.add("90846");
tcodes.add("90847");
tcodes.add("92507");
tcodes.add("92508");
tcodes.add("92521");
tcodes.add("92522");
tcodes.add("92523");
tcodes.add("92524");
tcodes.add("96040");
tcodes.add("96110");
tcodes.add("96116");
tcodes.add("96160");
tcodes.add("96161");
tcodes.add("97802");
tcodes.add("97803");
tcodes.add("97804");
tcodes.add("99406");
tcodes.add("99407");
tcodes.add("99408");
tcodes.add("99409");
tcodes.add("99497");
tcodes.add("99498");

for (String c : tcodes) {
ConceptDefinitionComponent cc = CodeSystemUtilities.findCode(cs.getConcept(), c);
if (cc == null) {
throw new Error("unable to find tcode "+c);
}
cc.addProperty().setCode("telemedicine").setValue(new BooleanType(true));
}
return String.valueOf(tcodes.size());
}


private void produceDB(String path, CodeSystem cs) throws ClassNotFoundException, SQLException {
Connection con = connect(path);

Expand Down Expand Up @@ -197,7 +251,6 @@ private void defineMetadata(CodeSystem cs) {
mm(pc.addConcept()).setCode("physical-status").setDisplay("Anesthesia Physical Status Modifiers");
mm(pc.addConcept()).setCode("general").setDisplay("A general modifier");
mm(pc.addConcept()).setCode("hcpcs").setDisplay("Level II (HCPCS/National) Modifiers");
mm(pc.addConcept()).setCode("orthopox").setDisplay("");
mm(pc.addConcept()).setCode("metadata").setDisplay("A kind of code or designation");

ConceptDefinitionComponent dc = mm(cs.addConcept().setCode("metadata-designations"));
Expand Down Expand Up @@ -251,7 +304,7 @@ private int processModifiers(CodeSystem cs, String path) throws FHIRException, F
return res;
}

private int readCodes(CodeSystem cs, String path, boolean hasConceptId, String use, String type) throws IOException {
private int readCodes(CodeSystem cs, String path, boolean hasConceptId, String use, String type, String boolProp) throws IOException {
int res = 0;
FileInputStream inputStream = null;
Scanner sc = null;
Expand Down Expand Up @@ -286,6 +339,9 @@ private int readCodes(CodeSystem cs, String path, boolean hasConceptId, String u
} else if (type != null) {
cc.addProperty().setCode("kind").setValue(new CodeType(type));
}
if (boolProp != null) {
cc.addProperty().setCode(boolProp).setValue(new BooleanType(true));
}
if (use == null) {
if (cc.hasDisplay()) {
System.err.println("?");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@
import java.util.Set;

import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.comparison.CanonicalResourceComparer.ChangeAnalysisState;
import org.hl7.fhir.r5.comparison.ResourceComparer.MessageCounts;
import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.DataType;
import org.hl7.fhir.r5.model.PrimitiveType;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.Utilities;
Expand Down Expand Up @@ -257,53 +255,53 @@ public CanonicalResourceComparer(ComparisonSession session) {
super(session);
}

protected boolean compareMetadata(CanonicalResource left, CanonicalResource right, Map<String, StructuralMatch<String>> comp, CanonicalResourceComparison<? extends CanonicalResource> res, List<String> changes, Base parent, String version) {
protected boolean compareMetadata(CanonicalResource left, CanonicalResource right, Map<String, StructuralMatch<String>> comp, CanonicalResourceComparison<? extends CanonicalResource> res, List<String> changes, Base parent) {
var changed = false;
if (comparePrimitivesWithTracking("url", left.getUrlElement(), right.getUrlElement(), comp, IssueSeverity.ERROR, res, parent, version)) {
if (comparePrimitivesWithTracking("url", left.getUrlElement(), right.getUrlElement(), comp, IssueSeverity.ERROR, res, parent)) {
changed = true;
changes.add("url");
}
if (session.getForVersion() == null) {
if (comparePrimitivesWithTracking("version", left.getVersionElement(), right.getVersionElement(), comp, IssueSeverity.ERROR, res, parent, version)) {
if (!session.isAnnotate()) {
if (comparePrimitivesWithTracking("version", left.getVersionElement(), right.getVersionElement(), comp, IssueSeverity.ERROR, res, parent)) {
changed = true;
changes.add("version");
}
}
if (comparePrimitivesWithTracking("name", left.getNameElement(), right.getNameElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
if (comparePrimitivesWithTracking("name", left.getNameElement(), right.getNameElement(), comp, IssueSeverity.INFORMATION, res, parent)) {
changed = true;
changes.add("name");
}
if (comparePrimitivesWithTracking("title", left.getTitleElement(), right.getTitleElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
if (comparePrimitivesWithTracking("title", left.getTitleElement(), right.getTitleElement(), comp, IssueSeverity.INFORMATION, res, parent)) {
changed = true;
changes.add("title");
}
if (comparePrimitivesWithTracking("status", left.getStatusElement(), right.getStatusElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
if (comparePrimitivesWithTracking("status", left.getStatusElement(), right.getStatusElement(), comp, IssueSeverity.INFORMATION, res, parent)) {
changed = true;
changes.add("status");
}
if (comparePrimitivesWithTracking("experimental", left.getExperimentalElement(), right.getExperimentalElement(), comp, IssueSeverity.WARNING, res, parent, version)) {
if (comparePrimitivesWithTracking("experimental", left.getExperimentalElement(), right.getExperimentalElement(), comp, IssueSeverity.WARNING, res, parent)) {
changed = true;
changes.add("experimental");
}
if (session.getForVersion() == null) {
if (comparePrimitivesWithTracking("date", left.getDateElement(), right.getDateElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
if (!session.isAnnotate()) {
if (comparePrimitivesWithTracking("date", left.getDateElement(), right.getDateElement(), comp, IssueSeverity.INFORMATION, res, parent)) {
changed = true;
changes.add("date");
}
}
if (comparePrimitivesWithTracking("publisher", left.getPublisherElement(), right.getPublisherElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
if (comparePrimitivesWithTracking("publisher", left.getPublisherElement(), right.getPublisherElement(), comp, IssueSeverity.INFORMATION, res, parent)) {
changed = true;
changes.add("publisher");
}
if (comparePrimitivesWithTracking("description", left.getDescriptionElement(), right.getDescriptionElement(), comp, IssueSeverity.NULL, res, parent, version)) {
if (comparePrimitivesWithTracking("description", left.getDescriptionElement(), right.getDescriptionElement(), comp, IssueSeverity.NULL, res, parent)) {
changed = true;
changes.add("description");
}
if (comparePrimitivesWithTracking("purpose", left.getPurposeElement(), right.getPurposeElement(), comp, IssueSeverity.NULL, res, parent, version)) {
if (comparePrimitivesWithTracking("purpose", left.getPurposeElement(), right.getPurposeElement(), comp, IssueSeverity.NULL, res, parent)) {
changed = true;
changes.add("purpose");
}
if (comparePrimitivesWithTracking("copyright", left.getCopyrightElement(), right.getCopyrightElement(), comp, IssueSeverity.INFORMATION, res, parent, version)) {
if (comparePrimitivesWithTracking("copyright", left.getCopyrightElement(), right.getCopyrightElement(), comp, IssueSeverity.INFORMATION, res, parent)) {
changed = true;
changes.add("copyright");
}
Expand Down Expand Up @@ -464,29 +462,59 @@ protected boolean comparePrimitives(String name, PrimitiveType l, PrimitiveType
}


protected boolean comparePrimitivesWithTracking(String name, List< ? extends PrimitiveType> ll, List<? extends PrimitiveType> rl, Map<String, StructuralMatch<String>> comp, IssueSeverity level, CanonicalResourceComparison<? extends CanonicalResource> res, Base parent) {
boolean def = false;

List<PrimitiveType> matchR = new ArrayList<>();
for (PrimitiveType l : ll) {
PrimitiveType r = findInList(rl, l);
if (r == null) {
session.markDeleted(parent, "element", l);
} else {
matchR.add(r);
def = comparePrimitivesWithTracking(name, l, r, comp, level, res, parent) || def;
}
}
for (PrimitiveType r : rl) {
if (!matchR.contains(r)) {
session.markAdded(r);
}
}
return def;
}

private PrimitiveType findInList(List<? extends PrimitiveType> rl, PrimitiveType l) {
for (PrimitiveType r : rl) {
if (r.equalsDeep(l)) {
return r;
}
}
return null;
}

@SuppressWarnings("rawtypes")
protected boolean comparePrimitivesWithTracking(String name, PrimitiveType l, PrimitiveType r, Map<String, StructuralMatch<String>> comp, IssueSeverity level, CanonicalResourceComparison<? extends CanonicalResource> res, Base parent, String version) {
protected boolean comparePrimitivesWithTracking(String name, PrimitiveType l, PrimitiveType r, Map<String, StructuralMatch<String>> comp, IssueSeverity level, CanonicalResourceComparison<? extends CanonicalResource> res, Base parent) {
StructuralMatch<String> match = null;
if (l.isEmpty() && r.isEmpty()) {
match = new StructuralMatch<>(null, null, null);
} else if (l.isEmpty()) {
match = new StructuralMatch<>(null, r.primitiveValue(), vmI(IssueSeverity.INFORMATION, "Added the item '"+r.primitiveValue()+"'", fhirType()+"."+name));
VersionComparisonAnnotation.markAdded(r, version);
session.markAdded(r);
} else if (r.isEmpty()) {
match = new StructuralMatch<>(l.primitiveValue(), null, vmI(IssueSeverity.INFORMATION, "Removed the item '"+l.primitiveValue()+"'", fhirType()+"."+name));
VersionComparisonAnnotation.markDeleted(parent, version, name, l);
session.markDeleted(parent, name, l);
} else if (!l.hasValue() && !r.hasValue()) {
match = new StructuralMatch<>(null, null, vmI(IssueSeverity.INFORMATION, "No Value", fhirType()+"."+name));
} else if (!l.hasValue()) {
match = new StructuralMatch<>(null, r.primitiveValue(), vmI(IssueSeverity.INFORMATION, "No Value on Left", fhirType()+"."+name));
VersionComparisonAnnotation.markAdded(r, version);
session.markAdded(r);
} else if (!r.hasValue()) {
match = new StructuralMatch<>(l.primitiveValue(), null, vmI(IssueSeverity.INFORMATION, "No Value on Right", fhirType()+"."+name));
VersionComparisonAnnotation.markDeleted(parent, version, name, l);
session.markDeleted(parent, name, l);
} else if (l.getValue().equals(r.getValue())) {
match = new StructuralMatch<>(l.primitiveValue(), r.primitiveValue(), null);
} else {
VersionComparisonAnnotation.markChanged(r, version);
session.markChanged(r, l);
match = new StructuralMatch<>(l.primitiveValue(), r.primitiveValue(), vmI(level, "Values Differ", fhirType()+"."+name));
if (level != IssueSeverity.NULL && res != null) {
res.getMessages().add(new ValidationMessage(Source.ProfileComparer, IssueType.INFORMATIONAL, fhirType()+"."+name, "Values for "+name+" differ: '"+l.primitiveValue()+"' vs '"+r.primitiveValue()+"'", level));
Expand All @@ -497,6 +525,65 @@ protected boolean comparePrimitivesWithTracking(String name, PrimitiveType l, Pr
}
return match.isDifferent();
}


protected boolean compareDataTypesWithTracking(String name, List< ? extends DataType> ll, List<? extends DataType> rl, Map<String, StructuralMatch<String>> comp, IssueSeverity level, CanonicalResourceComparison<? extends CanonicalResource> res, Base parent) {
boolean def = false;

List<DataType> matchR = new ArrayList<>();
for (DataType l : ll) {
DataType r = findInList(rl, l);
if (r == null) {
session.markDeleted(parent, "element", l);
} else {
matchR.add(r);
def = compareDataTypesWithTracking(name, l, r, comp, level, res, parent) || def;
}
}
for (DataType r : rl) {
if (!matchR.contains(r)) {
session.markAdded(r);
}
}
return def;
}

private DataType findInList(List<? extends DataType> rl, DataType l) {
for (DataType r : rl) {
if (r.equalsDeep(l)) {
return r;
}
}
return null;
}

@SuppressWarnings("rawtypes")
protected boolean compareDataTypesWithTracking(String name, DataType l, DataType r, Map<String, StructuralMatch<String>> comp, IssueSeverity level, CanonicalResourceComparison<? extends CanonicalResource> res, Base parent) {
StructuralMatch<String> match = null;
boolean le = l == null || l.isEmpty();
boolean re = r == null || r.isEmpty();
if (le && re) {
match = new StructuralMatch<>(null, null, null);
} else if (le) {
match = new StructuralMatch<>(null, r.primitiveValue(), vmI(IssueSeverity.INFORMATION, "Added the item '"+r.fhirType()+"'", fhirType()+"."+name));
session.markAdded(r);
} else if (re) {
match = new StructuralMatch<>(l.primitiveValue(), null, vmI(IssueSeverity.INFORMATION, "Removed the item '"+l.fhirType()+"'", fhirType()+"."+name));
session.markDeleted(parent, name, l);
} else if (l.equalsDeep(r)) {
match = new StructuralMatch<>(l.primitiveValue(), r.primitiveValue(), null);
} else {
session.markChanged(r, l);
match = new StructuralMatch<>(l.fhirType(), r.fhirType(), vmI(level, "Values Differ", fhirType()+"."+name));
if (level != IssueSeverity.NULL && res != null) {
res.getMessages().add(new ValidationMessage(Source.ProfileComparer, IssueType.INFORMATIONAL, fhirType()+"."+name, "Values for "+name+" differ: '"+l.fhirType()+"' vs '"+r.fhirType()+"'", level));
}
}
if (comp != null) {
comp.put(name, match);
}
return match.isDifferent();
}

protected abstract String fhirType();

Expand Down
Loading

0 comments on commit 12e38a3

Please sign in to comment.