Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
Chinlinlee committed May 4, 2023
2 parents 580185b + b4ca0b9 commit ec24e3e
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ tempScript
/config/log4js.json

/local/local-upload-log.json
/local/local-upload-log-wado.json
/local/local-upload-wado-log.json
97 changes: 68 additions & 29 deletions api/dicom/controller/wado.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,28 @@ module.exports = async(req, res) =>
let disk = process.env.DICOM_STORE_ROOTPATH;
let oriPath = await getInstanceStorePath(param);
if (!oriPath) {
res.set('content-type' , 'application/json');
return dicomWebHandleError.sendNotFoundMessage(req , res);
}

let storePath = path.join(disk, oriPath);
if (!fs.existsSync(storePath)) {
let storeAbsPath = path.join(disk, oriPath);
if (!fs.existsSync(storeAbsPath)) {
res.set('content-type' , 'application/json');
return dicomWebHandleError.sendNotFoundMessage(req , res);
}

if (param.contentType == 'image/jpeg') {
if (param.frameNumber) {
return await handleFrameNumber(param , res , storePath);
if (!param.frameNumber) { //when user get DICOM without frame number, default return first frame image
param.frameNumber = 1;
}
//when user get DICOM without frame number, default return first frame image
param.frameNumber = 1;
return await handleFrameNumber(param , res , storePath);
return await handleFrameNumber(param , res , storeAbsPath);
} else {
res.writeHead(200 ,
{
'Content-Type' : param.contentType ,
'Content-Disposition' :'attachment; filename=' + path.basename(storePath)
'Content-Disposition' :'attachment; filename=' + path.basename(storeAbsPath)
});
return fs.createReadStream(storePath).pipe(res);
return fs.createReadStream(storeAbsPath).pipe(res);
}
} catch (e) {
console.error(e);
Expand Down Expand Up @@ -153,31 +153,48 @@ async function handleFrameNumber (param , res , dicomFile) {
if (param.contentType != "image/jpeg") {
return dicomWebHandleError.sendBadRequestMessage(res, "Parameter error : contentType only support image/jpeg with frameNumber");
}
let imageRelativePath = dicomFile.replace(process.env.DICOM_STORE_ROOTPATH,"");
let imageRelativePath = path.relative(process.env.DICOM_STORE_ROOTPATH, dicomFile);
let images = path.join(process.env.DICOM_STORE_ROOTPATH, imageRelativePath);
let jpegFile = images.replace(/\.dcm\b/gi , `.${param.frameNumber-1}.jpg`);
let finalJpegFile = "";
if(fs.existsSync(jpegFile)) {
finalJpegFile = jpegFile;
} else {
let dicomJson = await getDICOMJson(param);
let transferSyntax = _.get(dicomJson ,"00020010.Value.0");
if (!dcmtkSupportTransferSyntax.includes(transferSyntax)) {
let pythonDICOM2JPEGStatus = await getJpeg[process.env.ENV]['getJpegByPydicom'](images);
if (pythonDICOM2JPEGStatus) {
return fs.createReadStream(jpegFile).pipe(res);
}
res.set('content-type' , 'application/json');
return dicomWebHandleError.sendServerWrongMessage(res , `can't not convert dicom to jpeg with transfer syntax: ${transferSyntax}`);
}
let frame = await getFrameImage(imageRelativePath, param.frameNumber);
if (frame.status) {
finalJpegFile = frame.imagePath;
} else {
res.set('content-type' , 'application/json');
return dicomWebHandleError.sendServerWrongMessage(res , `dcmtk Convert frame error ${frame.imageStream}`);

let dicomJson = await getDICOMJson(param);

let isValidFrameNumber = checkIsValidFrameNumber(dicomJson, param.frameNumber);
if (!isValidFrameNumber.status) {
return dicomWebHandleError.sendBadRequestMessage(res, `invalid frame number: ${param.frameNumber}, but data's frame number is ${isValidFrameNumber.dataFrameNumber}`);
}

let transferSyntax = _.get(dicomJson ,"00020010.Value.0");
if (!dcmtkSupportTransferSyntax.includes(transferSyntax)) {
let pythonDICOM2JPEGStatus = await getJpeg[process.env.ENV]['getJpegByPydicom'](images);
if (pythonDICOM2JPEGStatus) {
return fs.createReadStream(jpegFile).pipe(res);
}
res.set('content-type' , 'application/json');
return dicomWebHandleError.sendServerWrongMessage(res , `can't not convert dicom to jpeg with transfer syntax: ${transferSyntax}`);
}

let windowCenter = _.get(dicomJson, "00281050.Value.0");
let windowWidth = _.get(dicomJson, "00281051.Value.0");
let frame;
if (windowCenter && windowWidth) {
frame = await getFrameImage(imageRelativePath, param.frameNumber, [
"+Ww",
windowCenter,
windowWidth
]);
} else {
frame = await getFrameImage(imageRelativePath, param.frameNumber);
}

if (frame.status) {
finalJpegFile = frame.imagePath;
} else {
res.set('content-type' , 'application/json');
return dicomWebHandleError.sendServerWrongMessage(res , `dcmtk Convert frame error ${frame.imageStream}`);
}

let imageSharp = sharp(finalJpegFile);
let magick = new Magick(finalJpegFile);
handleImageQuality(param, magick);
Expand All @@ -194,6 +211,28 @@ async function handleFrameNumber (param , res , dicomFile) {
}
}

/**
*
* @param {*} dicomJson
* @param {number} frameNumber
*/
function checkIsValidFrameNumber(dicomJson, frameNumber) {
let dataFrameNumber = _.get(dicomJson, "00280008.Value.0") | 1;
dataFrameNumber = parseInt(dataFrameNumber);

if (dataFrameNumber < frameNumber) {
return {
status: false,
dataFrameNumber
};
}

return {
status: true,
dataFrameNumber
};
}

async function getInstanceStorePath(iParam)
{
let aggregateQuery =
Expand Down
21 changes: 19 additions & 2 deletions local/DICOMUploader-wado.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ if (osPlatform.includes("linux")) {
}

program.requiredOption("-d, --dir <string>", "The directory path contains DICOM files that need to upload")
.requiredOption("-u, --url <string>", "STOW-RS URL");
.requiredOption("-u, --url <string>", "STOW-RS URL", "http://127.0.0.1:8081/dicom-web/studies")
.option("--resume <string>", "Resume from log file");
program.parse();

const options = program.opts();
Expand All @@ -37,7 +38,7 @@ async function storeInstance(filename, stowUrl) {
multipart: [
{
"Content-Type": "application/dicom",
"Content-Disposition": `attachment; filename="${filename}"`,
"Content-Disposition": `attachment; filename="${path.basename(filename)}"`,
body: stream
}
],
Expand All @@ -50,11 +51,27 @@ async function main() {
const STOW_URL = options.url;
console.log(`Input Directory: ${inputDir}`);

let resumeFile = options.resume;
let logUploadedFiles = [];
let successFiles = [];
let errorFiles = [];

if (resumeFile && !fs.existsSync(resumeFile)) {
console.error("resume file not exist");
process.exit(1);
} else if (fs.existsSync(resumeFile)){
let logInfo = JSON.parse(fs.readFileSync(resumeFile, "utf-8"));
logUploadedFiles = logInfo.successFiles;
successFiles = [...logUploadedFiles];
}

glob("**/*.dcm", { cwd: inputDir }, async function (err, matches) {
for (let file of matches) {
let fullFilename = path.join(inputDir, file);

if (logUploadedFiles.includes(fullFilename))
continue;

try {
let response = await storeInstance(fullFilename, STOW_URL);
let statusCode = response.res.statusCode;
Expand Down
23 changes: 20 additions & 3 deletions local/DICOMUploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,45 @@ if (osPlatform.includes("linux")) {
}

program.requiredOption("-d, --dir <string>", "The directory path contains DICOM files that need to upload")
.requiredOption("-u, --url <string>", "STOW-RS URL");
.option("--resume <string>", "Resume from log file");

program.parse();

const options = program.opts();

function main() {
let inputDir = options.dir;
console.log(`Input Directory: ${inputDir}`);


let resumeFile = options.resume;
let logUploadedFiles = [];
let successFiles = [];
let errorFiles = [];

if (resumeFile && !fs.existsSync(resumeFile)) {
console.error("resume file not exist");
process.exit(1);
} else if (fs.existsSync(resumeFile)){
let logInfo = JSON.parse(fs.readFileSync(resumeFile, "utf-8"));
logUploadedFiles = logInfo.successFiles;
successFiles = [...logUploadedFiles];
}

glob("**/*.dcm", { cwd: inputDir }, async function (err, matches) {
for (let file of matches) {
let fullFilename = path.join(inputDir, file);

if (logUploadedFiles.includes(fullFilename))
continue;

let storeInstanceResult = await stow(
{
headers: {
host: "localhost:8081"
}
},
fullFilename,
file
path.basename(file)
);
if (!storeInstanceResult.isFailure) {
successFiles.push(fullFilename);
Expand Down
2 changes: 1 addition & 1 deletion local/single-dicom-uploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ async function main() {
host: "localhost:8081"
}
},
filePath
path.basename(filePath)
);

if (storeInstanceResult.isFailure) {
Expand Down
2 changes: 1 addition & 1 deletion models/dcmtk/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ async function getFrameImage(imagesPath, frameNumber, otherOptions = []) {
let execCmd = "";
let images = path.join(process.env.DICOM_STORE_ROOTPATH, imagesPath);
let jpegFile = images.replace(/\.dcm\b/gi, `.${frameNumber - 1}.jpg`);
if (fs.existsSync(jpegFile)) {
if (fs.existsSync(jpegFile) && otherOptions.length == 0) {
let rs = fs.createReadStream(jpegFile);
return {
status: true,
Expand Down

0 comments on commit ec24e3e

Please sign in to comment.