Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNOMED Hydrating, Filtering, Special MR Generation #1648

Draft
wants to merge 19 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(snomed): adding special snomed bundle to html
Refs: #1442
  • Loading branch information
jonahkaye committed Apr 3, 2024
commit 9363f91240f2615038a4690d7f8f6528687723de
2,276 changes: 2,276 additions & 0 deletions packages/core/src/external/aws/lambda-logic/bundle-to-html-snomed.ts

Large diffs are not rendered by default.

240 changes: 93 additions & 147 deletions packages/core/src/external/aws/lambda-logic/bundle-to-html.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
{{>DataType/Identifier.hbs id=this}},
{{/each}}
],
"verificationStatus": {{ProvisionalStatus}},
"clinicalStatus": {
"coding":
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
{{#if medAdm.substanceAdministration.precondition}}
{{#each (toArray medAdm.substanceAdministration.precondition) as |precondition|}}
{{#if precondition.criterion.value.code}}
{{>Resources/Condition.hbs conditionEntry=precondition.criterion ProvisionalStatus="true" ID=(generateUUID (toJsonString precondition.criterion))}},
{{>Resources/Condition.hbs conditionEntry=precondition.criterion ID=(generateUUID (toJsonString precondition.criterion))}},
{{>References/MedicationAdministration/reasonReference.hbs ID=(generateUUID (toJsonString medAdm.substanceAdministration)) REF=(concat 'Condition/' (generateUUID (toJsonString precondition.criterion)))}},
{{/if}}
{{/each}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
{{#if medEntry.substanceAdministration.precondition}}
Copy link
Member Author

@jonahkaye jonahkaye Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grabbing conditions linked to medications.
This gets us a few more conditions but which empirically seem to not be the most valuable. Optional to keep this, though my preference is to default on the side of getting as much data from the convert and filtering out downstream.

{{#each (toArray medEntry.substanceAdministration.precondition) as |precondition|}}
{{#if precondition.criterion.value.code}}
{{>Resources/Condition.hbs conditionEntry=precondition.criterion ProvisionalStatus="true" ID=(generateUUID (toJsonString criterion.value))}},
{{>Resources/Condition.hbs conditionEntry=precondition.criterion ID=(generateUUID (toJsonString criterion.value))}},
{{>References/MedicationStatement/reasonReference.hbs ID=(generateUUID (toJsonString medEntry.substanceAdministration)) REF=(concat 'Condition/' (generateUUID (toJsonString criterion.value)))}},
{{/if}}
{{/each}}
Expand Down
9 changes: 3 additions & 6 deletions packages/utils/src/customer-requests/convert-html-to-csv.ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add documentation explaining what it does and how to use it, please.

Original file line number Diff line number Diff line change
Expand Up @@ -113,24 +113,22 @@ export function convertHtmlTablesToCsv(html: string) {
}

function main() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utility to call in the command line

const filePath = process.argv[2]; // Get the file path from command line arguments
const filePath = process.argv[2];

if (!filePath) {
console.error("Please provide an HTML file path.");
process.exit(1);
}

try {
const htmlContent = readFileSync(filePath, "utf8"); // Read the HTML file content
const csvContent = convertHtmlTablesToCsv(htmlContent); // Convert HTML to CSV
const htmlContent = readFileSync(filePath, "utf8");
const csvContent = convertHtmlTablesToCsv(htmlContent);

// Construct the CSV file path by changing the extension
const csvFilePath = path.join(
path.dirname(filePath),
path.basename(filePath, path.extname(filePath)) + ".csv"
);

// Write the CSV content to the new file
writeFileSync(csvFilePath, csvContent);
console.log(`CSV file has been created at: ${csvFilePath}`);
// eslint-disable-next-line
Expand All @@ -139,7 +137,6 @@ function main() {
}
}

// Call main if this script is run directly
if (require.main === module) {
main();
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the main customer facing output of this PR. A script that for a given customer, gets all their patients consolidated data and performs the filtering and MR summary generation

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full script for running this whole process

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// The script makes consolidated queries, inserts a patient FHIR resource, and then calls the filtering
// and MR generation logic.

import { bundleToHtml } from "@metriport/core/external/aws/lambda-logic/bundle-to-html";
import { bundleToHtml } from "@metriport/core/external/aws/lambda-logic/bundle-to-html-snomed";
import fs from "fs/promises";
import { convertHtmlTablesToCsv } from "./convert-html-to-csv";
import * as path from "path";
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add documentation explaining what it does and how to use it, please.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { bundleToHtml } from "@metriport/core/external/aws/lambda-logic/bundle-to-html";
import fs from "fs";

// Check if a file path is provided
if (process.argv.length < 3) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utility to call in command line

console.log("Usage: node medical-records-local.js <path-to-json-file>");
process.exit(1);
Expand All @@ -11,10 +10,8 @@ const filePath = process.argv[2];
const bundle = fs.readFileSync(filePath, "utf8");
const bundleParsed = JSON.parse(bundle);

// FHIR Bundle
const html = bundleToHtml(bundleParsed);

// Determine the output file name by replacing .json with .html
const outputFilePath = filePath.replace(".json", ".html");

fs.writeFileSync(outputFilePath, html);
Expand Down
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add documentation explaining what it does and how to use it, please.

Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export async function fullProcessing(directoryPath: string) {
const cptSet = new Set<string>();
const conditionsSet = new Set<string>();
const allRemainingEnries = new Set<string>();
const medicationConditionDict: Record<string, string> = {}; // a mapping of all medications to conditions
const medicationConditionDict: Record<string, string> = {};
await processDirectoryOrFile(directoryPath, async filePath => {
await removeConditionsProceduresMedAdmins(
filePath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ async function populateChildrenRecursively(
await Promise.all(childPromises);
}
} else {
// this is either a code
if (hashTable[childCode].found) {
console.log(`Downgrading ${childCode} to non-root (child)`);
hashTable[childCode] = { ...hashTable[childCode], root: false };
Expand Down
44 changes: 21 additions & 23 deletions packages/utils/src/terminology-server/term-server-api.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
import axios from "axios";

interface ParameterPart {
type ParameterPart = {
name: string;
valueCode?: string;
valueString?: string;
}
};

interface Parameter {
type Parameter = {
name: string;
valueString?: string;
part?: ParameterPart[];
}
};

interface CodeSystemUrl {
type CodeSystemUrl = {
name: string;
url: string;
}
};

export type CodeDetailsResponse = {
parameter: {
name: string;
part: [
{
name: string;
value?: string;
valueCode?: string;
}
];
}[];
};

export const codeSystemUrls: Record<string, CodeSystemUrl> = {
SNOMEDCT_US: {
Expand Down Expand Up @@ -48,19 +61,6 @@ export const codeSystemUrls: Record<string, CodeSystemUrl> = {
},
};

export type CodeDetailsResponse = {
parameter: {
name: string;
part: [
{
name: string;
value?: string;
valueCode?: string;
}
];
}[];
};

export async function getCodeDetailsFull(
code: string,
codeSystemType: string
Expand All @@ -80,7 +80,6 @@ export async function getCodeDetailsFull(
console.error("Connection refused. The server is not reachable at the moment.");
return undefined;
} else {
// console.error(`Error fetching code details. Code Not Found ${code}`);
return undefined;
}
}
Expand All @@ -102,12 +101,11 @@ export async function getCodeDisplay(

const displayParameter = response.data.parameter.find((p: Parameter) => p.name === "display");
if (displayParameter && displayParameter.valueString) {
// Extract the display text and category using a regular expression
const match = displayParameter.valueString.match(/^(.+?)\s*\(([^)]+)\)$/);
if (match) {
return {
display: match[1].trim(), // "Domestic abuse of adult"
category: match[2].trim(), // "event"
display: match[1].trim(),
category: match[2].trim(),
};
} else {
console.log("Display field format not recognized.");
Expand Down
Loading