use of org.mitre.synthea.world.concepts.HealthRecord.Code in project synthea by synthetichealth.
the class CSVExporter method medication.
/**
* Write a single Medication to medications.csv.
*
* @param personID ID of the person prescribed the medication.
* @param encounterID ID of the encounter where the medication was prescribed
* @param payerID ID of the payer who covered the immunization.
* @param medication The medication itself
* @param stopTime End time
* @throws IOException if any IO error occurs
*/
private void medication(String personID, String encounterID, String payerID, Medication medication, long stopTime) throws IOException {
// START,STOP,PATIENT,PAYER,ENCOUNTER,CODE,DESCRIPTION,
// BASE_COST,PAYER_COVERAGE,DISPENSES,TOTALCOST,REASONCODE,REASONDESCRIPTION
StringBuilder s = new StringBuilder();
s.append(iso8601Timestamp(medication.start)).append(',');
if (medication.stop != 0L) {
s.append(iso8601Timestamp(medication.stop));
}
s.append(',');
s.append(personID).append(',');
s.append(payerID).append(',');
s.append(encounterID).append(',');
// CODE
Code coding = medication.codes.get(0);
s.append(coding.code).append(',');
// DESCRIPTION
s.append(clean(coding.display)).append(',');
// BASE_COST
BigDecimal cost = medication.getCost();
s.append(String.format(Locale.US, "%.2f", cost)).append(',');
// PAYER_COVERAGE
s.append(String.format(Locale.US, "%.2f", medication.claim.getCoveredCost())).append(',');
// dispenses = refills + original
long dispenses = 1;
// makes the math cleaner and more explicit. dispenses * unit cost = total cost
long stop = medication.stop;
if (stop == 0L) {
stop = stopTime;
}
long medDuration = stop - medication.start;
if (medication.prescriptionDetails != null && medication.prescriptionDetails.has("refills")) {
dispenses = medication.prescriptionDetails.get("refills").getAsInt();
} else if (medication.prescriptionDetails != null && medication.prescriptionDetails.has("duration")) {
JsonObject duration = medication.prescriptionDetails.getAsJsonObject("duration");
long quantity = duration.get("quantity").getAsLong();
String unit = duration.get("unit").getAsString();
long durationMs = Utilities.convertTime(unit, quantity);
dispenses = medDuration / durationMs;
} else {
// assume 1 refill / month
long durationMs = Utilities.convertTime("months", 1);
dispenses = medDuration / durationMs;
}
if (dispenses < 1) {
// integer division could leave us with 0,
// ex. if the active time (start->stop) is less than the provided duration
// or less than a month if no duration provided
dispenses = 1;
}
s.append(dispenses).append(',');
BigDecimal totalCost = cost.multiply(BigDecimal.valueOf(dispenses)).setScale(2, // Truncate 2 decimal places
RoundingMode.DOWN);
s.append(String.format(Locale.US, "%.2f", totalCost)).append(',');
if (medication.reasons.isEmpty()) {
// reason code & desc
s.append(',');
} else {
Code reason = medication.reasons.get(0);
s.append(reason.code).append(',');
s.append(clean(reason.display));
}
s.append(NEWLINE);
write(s.toString(), medications);
}
use of org.mitre.synthea.world.concepts.HealthRecord.Code in project synthea by synthetichealth.
the class CSVExporter method allergy.
/**
* Write a single Allergy to allergies.csv.
*
* @param personID ID of the person that has the allergy.
* @param encounterID ID of the encounter where the allergy was diagnosed
* @param allergy The allergy itself
* @throws IOException if any IO error occurs
*/
private void allergy(String personID, String encounterID, HealthRecord.Allergy allergy) throws IOException {
// START,STOP,PATIENT,ENCOUNTER,CODE,SYSTEM,DESCRIPTION,TYPE,CATEGORY
// REACTION1,DESCRIPTION1,SEVERITY1,
// REACTION2,DESCRIPTION2,SEVERITY2
StringBuilder s = new StringBuilder();
s.append(dateFromTimestamp(allergy.start)).append(',');
if (allergy.stop != 0L) {
s.append(dateFromTimestamp(allergy.stop));
}
s.append(',');
s.append(personID).append(',');
s.append(encounterID).append(',');
Code coding = allergy.codes.get(0);
s.append(coding.code).append(',');
s.append(getSystemFromURI(coding.system)).append(',');
s.append(clean(coding.display)).append(',');
if (allergy.allergyType != null) {
s.append(allergy.allergyType);
}
s.append(',');
if (allergy.category != null) {
s.append(allergy.category);
}
s.append(',');
int reactionsSize = 0;
if (allergy.reactions != null) {
reactionsSize = allergy.reactions.size();
}
Function<Map.Entry<HealthRecord.Code, HealthRecord.ReactionSeverity>, String> template = mapEntry -> {
StringBuilder reactionBuilder = new StringBuilder();
reactionBuilder.append(mapEntry.getKey().code).append(',');
reactionBuilder.append(clean(mapEntry.getKey().display)).append(',');
reactionBuilder.append(mapEntry.getValue());
return reactionBuilder.toString();
};
switch(reactionsSize) {
case 0:
s.append(",,,,,");
break;
case 1:
s.append(allergy.reactions.entrySet().stream().map(template).collect(Collectors.joining()));
s.append(",,,");
break;
default:
// case where there are more than two reactions so we need to support by severity
s.append(allergy.reactions.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue)).limit(2).map(template).collect(Collectors.joining(",")));
}
s.append(NEWLINE);
write(s.toString(), allergies);
}
use of org.mitre.synthea.world.concepts.HealthRecord.Code in project synthea by synthetichealth.
the class CSVExporter method supply.
/**
* Write a single Supply to supplies.csv.
*
* @param personID ID of the person the supply was used for.
* @param encounterID ID of the encounter where the supply was used
* @param supply The supply itself
* @throws IOException if any IO error occurs
*/
private void supply(String personID, String encounterID, Encounter encounter, Supply supply) throws IOException {
// DATE,PATIENT,ENCOUNTER,CODE,DESCRIPTION,QUANTITY
StringBuilder s = new StringBuilder();
s.append(dateFromTimestamp(supply.start)).append(',');
s.append(personID).append(',');
s.append(encounterID).append(',');
Code code = supply.codes.get(0);
s.append(code.code).append(',');
s.append(clean(code.display)).append(',');
s.append(supply.quantity);
s.append(NEWLINE);
write(s.toString(), supplies);
}
use of org.mitre.synthea.world.concepts.HealthRecord.Code in project synthea by synthetichealth.
the class CPCDSExporter method claim.
/**
* Method to write a single Claims file. Take an encounter in the parameters and
* processes Diagnoses, Procedures, and Pharmacy claims for each one, in order.
*
* @param rand Source of randomness to use when generating ids etc
* @param encounter The encounter object itself
* @param personID The Id of the involved patient
* @param encounterID The Id of the encounter
* @param medRecordNumber The patients Medical Record Number
* @param attributes Calculated attributes for the entire encounter
* @param payerId The Id of the payer
* @throws IOException Throws this exception
*/
private void claim(RandomNumberGenerator rand, Encounter encounter, String personID, String encounterID, UUID medRecordNumber, CPCDSAttributes attributes, String payerId, String coverageID) throws IOException {
StringBuilder s = new StringBuilder();
int i = 1;
while (i <= attributes.getLength()) {
// admin
String billType = attributes.getBillTypeCode();
String[] adminSection = { String.valueOf(dateFromTimestamp(encounter.start)), String.valueOf(dateFromTimestamp(encounter.stop)), String.valueOf(dateFromTimestamp(encounter.stop)), String.valueOf(dateFromTimestamp(encounter.start)), String.valueOf(dateFromTimestamp(encounter.start)), String.valueOf(dateFromTimestamp(encounter.stop)), personID.toString(), medRecordNumber.toString(), encounterID, "", "", "", attributes.getSourceAdminCode(), attributes.getAdmissionTypeCode(), Character.toString(billType.charAt(0)), Character.toString(billType.charAt(1)), Character.toString(billType.charAt(2)), attributes.getProcStatus(), attributes.getClaimType(), attributes.getDischarge(), attributes.getDenialCode(), coverageID, attributes.getPayeeType(), personID, attributes.getPaymentType(), coverageID };
StringBuilder admin = new StringBuilder();
for (String item : adminSection) {
admin.append(item).append(',');
}
String adminString = admin.toString();
// provider
practitioner(encounter.clinician.attributes.get("specialty").toString(), attributes.getNpiProvider(), attributes.getServiceSiteNPI(), encounter.clinician.getFullname());
String[] providerSection = { attributes.getNpiProvider(), attributes.getNetworkStatus(), attributes.getNpiProvider(), attributes.getNetworkStatus(), attributes.getServiceSiteNPI(), attributes.getNetworkStatus(), attributes.getNpiProvider(), attributes.getNetworkStatus(), attributes.getNpiProvider(), attributes.getNetworkStatus(), attributes.getNpiPrescribingProvider(), attributes.getNetworkStatus(), attributes.getNpiProvider() };
StringBuilder provider = new StringBuilder();
for (String item : providerSection) {
provider.append(item).append(',');
}
String providerString = provider.toString();
// totals
// encounter.claim.getTotalClaimCost();
double totalCost = attributes.getTotalClaimCost();
double coveredCost = encounter.claim.getCoveredCost();
double disallowed = totalCost - coveredCost;
double patientPaid;
double memberReimbursement;
double paymentAmount;
double toProvider;
double deductible = encounter.claim.person.coverage.getTotalCoverage();
double liability;
double copay = 0.00;
if (disallowed > 0) {
memberReimbursement = 0.00;
patientPaid = disallowed;
} else {
memberReimbursement = disallowed - 2 * disallowed;
disallowed = 0.00;
patientPaid = 0.00;
}
paymentAmount = coveredCost + patientPaid;
toProvider = paymentAmount;
liability = totalCost - paymentAmount;
String[] claimTotalsSection = { String.valueOf(paymentAmount), String.valueOf(totalCost), String.valueOf(patientPaid), String.valueOf(toProvider), String.valueOf(memberReimbursement), String.valueOf(paymentAmount), String.valueOf(disallowed), String.valueOf(deductible), String.valueOf(""), String.valueOf(copay), String.valueOf(liability), String.valueOf(coveredCost), String.valueOf(0.00) };
StringBuilder totals = new StringBuilder();
for (String item : claimTotalsSection) {
totals.append(item).append(',');
}
String totalsString = totals.toString();
String pharmacyEMPTY = ",,,,,,," + attributes.getResidence() + ",";
String procedureEMPTY = ",,,,,,,,";
// diagnosis
for (Entry condition : encounter.conditions) {
StringBuilder cond = new StringBuilder();
String presentOnAdmission;
String[] poaCodes = { "Y", "N", "U", "W" };
presentOnAdmission = poaCodes[(int) randomLongWithBounds(0, 3)];
cond.append(adminString);
cond.append(pharmacyEMPTY);
cond.append(providerString);
cond.append(totalsString);
cond.append(dateFromTimestamp(condition.start)).append(',');
cond.append(i).append(',');
cond.append(dateFromTimestamp(condition.stop)).append(',');
cond.append("").append(',');
cond.append(attributes.getPlaceOfService()).append(',');
cond.append(attributes.getRevenueCenterCode()).append(',');
cond.append("").append(',');
cond.append("").append(',');
cond.append("").append(',');
cond.append("").append(',');
cond.append("").append(',');
cond.append("").append(',');
cond.append(attributes.getBenefitPaymentStatus()).append(',');
cond.append(attributes.getDenialCode()).append(',');
BigDecimal cost = condition.getCost();
cond.append(0.00).append(',');
cond.append(0.00).append(',');
cond.append(0.00).append(',');
cond.append("").append(',');
cond.append(cost).append(',');
cond.append(cost).append(',');
cond.append(encounter.claim.person.coverage.getTotalCoverage()).append(',');
cond.append(cost).append(',');
cond.append(0.00).append(',');
cond.append(cost).append(',');
cond.append(cost).append(',');
cond.append(0.00).append(',');
cond.append(0.00).append(',');
cond.append(0.00).append(',');
Code coding = condition.codes.get(0);
String diagnosisCode = "SNOMED";
String diagnosisType = "principal";
cond.append(coding.code).append(',');
cond.append(clean(coding.display)).append(',');
cond.append(presentOnAdmission).append(',');
cond.append(diagnosisCode).append(',');
cond.append(diagnosisType).append(',');
cond.append("").append(',');
cond.append(procedureEMPTY).append(NEWLINE);
s.append(cond.toString());
i++;
}
// procedures
int k = 0;
for (Procedure procedure : encounter.procedures) {
String presentOnAdmission;
String diagnosisCode = "SNOMED";
String diagnosisType = "principal";
String procedureType;
if (k == 0) {
procedureType = "primary";
} else {
procedureType = "secondary";
}
String[] poaCodes = { "Y", "N", "U", "W" };
presentOnAdmission = poaCodes[(int) randomLongWithBounds(0, 3)];
StringBuilder proc = new StringBuilder();
proc.append(adminString);
proc.append(",").append(",").append(",").append(",").append(",").append(",");
proc.append("01,").append(attributes.getResidence()).append(',');
proc.append(providerString);
proc.append(totalsString);
String typeOfService = "01";
if (attributes.getNetworkStatus().equals("out")) {
typeOfService = "11";
}
proc.append(dateFromTimestamp(procedure.start)).append(',');
proc.append(i).append(',');
proc.append(dateFromTimestamp(procedure.stop)).append(',');
proc.append(typeOfService).append(',');
proc.append(attributes.getPlaceOfService()).append(',');
proc.append(attributes.getRevenueCenterCode()).append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append(attributes.getBenefitPaymentStatus()).append(',');
proc.append(attributes.getDenialCode()).append(',');
BigDecimal cost = procedure.getCost();
proc.append(0.00).append(',');
proc.append(0.00).append(',');
proc.append(0.00).append(',');
proc.append("").append(',');
proc.append(cost).append(',');
proc.append(cost).append(',');
proc.append(encounter.claim.person.coverage.getTotalCoverage()).append(',');
proc.append(cost).append(',');
proc.append(0.00).append(',');
proc.append(cost).append(',');
proc.append(cost).append(',');
proc.append(0.00).append(',');
proc.append(0.00).append(',');
proc.append(0.00).append(',');
if (procedure.reasons.size() != 0) {
Code reasons = procedure.reasons.get(0);
proc.append(reasons.code).append(',');
proc.append(clean(reasons.display)).append(',');
proc.append(presentOnAdmission).append(',');
proc.append(diagnosisCode).append(',');
proc.append(diagnosisType).append(',');
} else {
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(',');
}
proc.append("").append(',');
Code procedureCode = procedure.codes.get(0);
proc.append(procedureCode.code).append(',');
proc.append(clean(procedureCode.display)).append(',');
proc.append(dateFromTimestamp(procedure.start)).append(',');
proc.append(diagnosisCode).append(',');
proc.append(procedureType).append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(',');
proc.append("").append(NEWLINE);
s.append(proc.toString());
i++;
}
// pharmacy
for (Medication medication : encounter.medications) {
StringBuilder med = new StringBuilder();
String presentOnAdmission;
String diagnosisCode = "SNOMED";
String diagnosisType = "principal";
String[] poaCodes = { "Y", "N", "U", "W" };
presentOnAdmission = poaCodes[(int) randomLongWithBounds(0, 3)];
String[] brandGenericList = { "b", "g" };
String brandGenericCode = brandGenericList[(int) randomLongWithBounds(0, 1)];
String[] dawCodeList = { "1", "2", "3", "4", "7", "1", "3", "5", "8" };
String dawCode;
if (brandGenericCode.equals("b")) {
dawCode = dawCodeList[(int) randomLongWithBounds(0, 4)];
} else {
if (brandGenericCode.equals("g")) {
dawCode = dawCodeList[(int) randomLongWithBounds(5, 8)];
} else {
dawCode = "0";
}
}
/*
* {"dosage": {"amount":1,"frequency":2,"period":1,"unit":"days"},
* "duration":{"quantity":2,"unit":"weeks"}, "instructions":[ {
* "system":"SNOMED-CT", "code":"code", "display":"display string"} ] }
*/
JsonObject medicationDetails = medication.prescriptionDetails;
Dictionary<String, Integer> dayMultiplier = new Hashtable<String, Integer>();
dayMultiplier.put("hours", 1);
dayMultiplier.put("days", 1);
dayMultiplier.put("weeks", 2);
dayMultiplier.put("months", 30);
dayMultiplier.put("years", 365);
int dailyDosage;
int daysSupply;
JsonObject dosage;
JsonObject duration;
if (medicationDetails == null || medicationDetails.has("as_needed")) {
dailyDosage = 0;
daysSupply = 0;
} else {
if (medicationDetails != null && medicationDetails.has("dosage")) {
dosage = medicationDetails.get("dosage").getAsJsonObject();
if (dosage.has("amount") == false) {
dosage.addProperty("amount", 0);
}
if (dosage.has("frequency") == false) {
dosage.addProperty("frequency", 0);
}
if (dosage.has("period") == false) {
dosage.addProperty("period", 0);
}
if (dosage.has("unit") == false) {
dosage.addProperty("unit", "days");
}
} else {
dosage = new JsonObject();
dosage.addProperty("amount", 0);
dosage.addProperty("frequency", 0);
dosage.addProperty("period", 0);
dosage.addProperty("unit", "days");
}
if (medicationDetails != null && medicationDetails.has("duration")) {
duration = medicationDetails.get("duration").getAsJsonObject();
if (duration.has("quantity") == false) {
duration.addProperty("quantity", 0);
}
if (duration.has("unit") == false) {
duration.addProperty("unit", "days");
}
} else {
duration = new JsonObject();
duration.addProperty("quantity", 0);
duration.addProperty("unit", "days");
}
dailyDosage = dosage.get("amount").getAsInt() * dosage.get("frequency").getAsInt() * dosage.get("period").getAsInt() * (int) dayMultiplier.get(dosage.get("unit").getAsString());
daysSupply = duration.get("quantity").getAsInt() * dayMultiplier.get(duration.get("unit").getAsString());
}
UUID rxRef = rand.randUUID();
String[] serviceTypeList = { "01", "04", "06" };
String serviceType = serviceTypeList[(int) randomLongWithBounds(0, 2)];
med.append(adminString);
med.append(daysSupply).append(',');
med.append(rxRef).append(',');
med.append(dawCode).append(',');
med.append("0").append(',');
med.append("0").append(',');
med.append(brandGenericCode).append(',');
med.append(serviceType).append(',');
med.append(attributes.getResidence()).append(',');
med.append(providerString);
med.append(totalsString);
Code coding = medication.codes.get(0);
med.append(dateFromTimestamp(medication.start)).append(',');
med.append(i).append(',');
med.append(dateFromTimestamp(medication.stop)).append(',');
med.append("16").append(',');
med.append("01").append(',');
med.append(attributes.getRevenueCenterCode()).append(',');
med.append(dailyDosage * daysSupply).append(',');
med.append(dailyDosage * daysSupply).append(',');
med.append(coding.code).append(',');
med.append(randomLongWithBounds(0, 2)).append(',');
med.append(dailyDosage * daysSupply).append(',');
med.append("UN").append(',');
med.append(attributes.getBenefitPaymentStatus()).append(',');
med.append(attributes.getDenialCode()).append(',');
BigDecimal cost = medication.getCost();
med.append(0.00).append(',');
med.append(0.00).append(',');
med.append(0.00).append(',');
med.append((dailyDosage == 0 || daysSupply == 0 ? 0 : cost.longValue() / (dailyDosage * daysSupply))).append(',');
med.append(cost).append(',');
med.append(cost).append(',');
med.append(encounter.claim.person.coverage.getTotalCoverage()).append(',');
med.append(cost).append(',');
med.append(0.00).append(',');
med.append(cost).append(',');
med.append(cost).append(',');
med.append(0.00).append(',');
med.append(0.00).append(',');
med.append(0.00).append(',');
if (medication.reasons.size() != 0) {
Code reasons = medication.reasons.get(0);
med.append(reasons.code).append(',');
med.append(clean(reasons.display)).append(',');
med.append(presentOnAdmission).append(',');
med.append(diagnosisCode).append(',');
med.append(diagnosisType).append(',');
} else {
med.append("").append(',');
med.append("").append(',');
med.append("").append(',');
med.append("").append(',');
med.append("").append(',');
}
med.append("").append(',');
med.append(procedureEMPTY).append(NEWLINE);
s.append(med.toString());
i++;
}
// Devices
for (Device device : encounter.devices) {
StringBuilder dev = new StringBuilder();
dev.append(adminString);
dev.append(",").append(",").append(",").append(",").append(",").append(",");
dev.append("01,").append(attributes.getResidence()).append(',');
dev.append(providerString);
dev.append(totalsString);
String typeOfService = "01";
if (attributes.getNetworkStatus().equals("out")) {
typeOfService = "11";
}
dev.append(dateFromTimestamp(device.start)).append(',');
dev.append(i).append(',');
dev.append(dateFromTimestamp(device.stop)).append(',');
dev.append(typeOfService).append(',');
dev.append(attributes.getPlaceOfService()).append(',');
dev.append(attributes.getRevenueCenterCode()).append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append(attributes.getBenefitPaymentStatus()).append(',');
dev.append(attributes.getDenialCode()).append(',');
BigDecimal cost = device.getCost();
dev.append(0.00).append(',');
dev.append(0.00).append(',');
dev.append(0.00).append(',');
dev.append("").append(',');
dev.append(cost).append(',');
dev.append(cost).append(',');
dev.append(encounter.claim.person.coverage.getTotalCoverage()).append(',');
dev.append(cost).append(',');
dev.append(0.00).append(',');
dev.append(cost).append(',');
dev.append(cost).append(',');
dev.append(0.00).append(',');
dev.append(0.00).append(',');
dev.append(0.00).append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
String diagnosisCode = "SNOMED";
String deviceType = "";
Code deviceCode = device.codes.get(0);
dev.append(deviceCode.code).append(',');
dev.append(clean(deviceCode.display)).append(',');
dev.append(dateFromTimestamp(device.start)).append(',');
dev.append(diagnosisCode).append(',');
dev.append(deviceType).append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(',');
dev.append("").append(NEWLINE);
s.append(dev.toString());
i++;
}
}
write(s.toString(), claims);
}
use of org.mitre.synthea.world.concepts.HealthRecord.Code in project synthea by synthetichealth.
the class StateTest method condition_onset_diagnosed_by_target_encounter.
@Test
public void condition_onset_diagnosed_by_target_encounter() throws Exception {
Module module = TestHelper.getFixture("condition_onset.json");
State condition = module.getState("Diabetes");
// Should pass through this state immediately without calling the record
person.history.add(0, condition);
assertTrue(condition.process(person, time));
// The encounter comes next (and add it to history);
State encounter = module.getState("ED_Visit");
// states are added to history before being processed
person.history.add(0, encounter);
assertTrue(encounter.process(person, time));
assertEquals(1, person.record.encounters.size());
Encounter enc = person.record.encounters.get(0);
Code code = enc.codes.get(0);
assertEquals("50849002", code.code);
assertEquals("Emergency Room Admission", code.display);
assertEquals(1, enc.conditions.size());
code = enc.conditions.get(0).codes.get(0);
assertEquals("73211009", code.code);
assertEquals("Diabetes mellitus", code.display);
Long onsetTime = person.getOnsetConditionRecord().getConditionLastOnsetTimeFromModule(module.name, code.display);
assertTrue(onsetTime != null);
assertEquals(time, onsetTime.longValue());
}
Aggregations