Skip to content

Commit

Permalink
feat: correct dicom missing 00080005 when STOW
Browse files Browse the repository at this point in the history
# Problems
- When I uploaded DICOM file,
I got an `EXITCODE_CANNOT_CONVERT_TO_UNICODE ` error
- Upon checking DICOM file,
I found that the error was caused by missing 00080005

# Solution
- Use dcmconv to convert DICOM file to Unicode
that can replace 00080005 to `ISO_IR 192`
  • Loading branch information
Chinlinlee committed Mar 16, 2023
1 parent cf2bbeb commit 45ea880
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 7 deletions.
38 changes: 31 additions & 7 deletions api/dicom-web/stow/service/stow.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const jsonPath = require("jsonpath");
const {
updateImagingStudy
} = require("../../../FHIR/ImagingStudy/controller/putImagingStudy");
// eslint-disable-next-line @typescript-eslint/naming-convention
const { DcmConv } = require("../../../../models/dcmtk/dcmconv/dcmconv.class");

/**
*
Expand Down Expand Up @@ -518,13 +520,35 @@ async function stow(req, filename, originalFilename) {
try {
dicomJson = await dcm2jsonV8.exec(filename);
} catch (e) {
console.error(e);
return {
isFailure: true,
statusCode: 273,
message: "Could not convert DICOM to JSON",
httpStatusCode: 400
};

/**
* EXITCODE_CANNOT_CONVERT_TO_UNICODE is usually due to dicom file missing (0008,0005)
* To fix this error, we use dcmconv to convert DICOM file to UTF-8 (ISO_IR 192)
*/
if (e.message.includes("EXITCODE_CANNOT_CONVERT_TO_UNICODE")) {
let dcmConv = new DcmConv();
try {
await dcmConv.exec(filename);
dicomJson = await dcm2jsonV8.exec(filename);
} catch(e) {
console.error(e);
return {
isFailure: true,
statusCode: 273,
message: "Could not convert DICOM to JSON",
httpStatusCode: 400
};
}
} else {
console.error(e);
return {
isFailure: true,
statusCode: 273,
message: "Could not convert DICOM to JSON",
httpStatusCode: 400
};
}

}

let uidObj = getUidObj(dicomJson);
Expand Down
99 changes: 99 additions & 0 deletions models/dcmtk/dcmconv/dcmconv.class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const childProcess = require('child_process');
const path = require("path");
const iconv = require('iconv-lite');
const os = require("os");

const CONVERT_TO_UTF8_OPTION = "--convert-to-utf8";
const DISCARD_ILLEGAL_OPTION = "--discard-illegal";

class DcmConv {
constructor() {
let platform = os.platform();
/** @private */
this.executer = {};
if (platform === "win32") {
this.handler = new DcmConvWindowsHandler();
} else {
this.handler = new DcmConvBasicHandler();
}
}

async exec(inputFile, options=[]) {
return this.handler.exec(inputFile, options);
}
}

class DcmConvWindowsHandler {
constructor() {}

/**
* Convert file to UTF-8 that use dcmconv
* Use for dicom file missing (0008,0005)
* @param {string} inputFile
*/
exec(inputFile, options=[]) {
return new Promise((resolve, reject) => {
let dcmconvExecBinary = path.resolve(`models/dcmtk/dcmtk-3.6.5-win64-dynamic/bin/dcmconv.exe`);
let execOption = [inputFile, inputFile, CONVERT_TO_UTF8_OPTION, DISCARD_ILLEGAL_OPTION, ...options];

let dcmcovSpawn = childProcess.spawn(dcmconvExecBinary, execOption, {
cwd: process.cwd(),
shell: true
});

dcmcovSpawn.stdout.on("data" , function (data) {
if (data) console.log(data);
resolve(data);
});

dcmcovSpawn.on("close", function() {
resolve(true);
});

dcmcovSpawn.stderr.on("data", function (stderr) {
stderr = iconv.decode(stderr, 'cp950');
reject(new Error(stderr));
});

});
}
}

class DcmConvBasicHandler {
constructor() {}

/**
* Convert file to UTF-8 that use dcmconv
* Use for dicom file missing (0008,0005)
* @param {string} inputFile
*/
exec(inputFile, options=[]) {
return new Promise((resolve, reject) => {
let dcmconvExecBinary = `dcmconv`;
let execOption = [inputFile, inputFile, CONVERT_TO_UTF8_OPTION, DISCARD_ILLEGAL_OPTION, ...options];

let dcmcovSpawn = childProcess.spawn(dcmconvExecBinary, execOption, {
cwd: process.cwd(),
shell: true
});

dcmcovSpawn.stdout.on("data" , function (data) {
if (data) console.log(data);
resolve(data);
});

dcmcovSpawn.on("close", function() {
resolve(true);
});

dcmcovSpawn.stderr.on("data", function (stderr) {
stderr = iconv.decode(stderr, 'cp950');
reject(new Error(stderr));
});

});
}
}


module.exports.DcmConv = DcmConv;

0 comments on commit 45ea880

Please sign in to comment.