Skip to content

Commit

Permalink
feat: add instance query task
Browse files Browse the repository at this point in the history
  • Loading branch information
Chinlinlee committed Aug 21, 2023
1 parent 22f5f86 commit 1c11f1d
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 6 deletions.
3 changes: 3 additions & 0 deletions dimse/c-find.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const { createCFindSCPInjectProxy } = require("@java-wrapper/org/github/chinlinl
const { JsPatientQueryTask } = require("./patientQueryTask");
const { JsStudyQueryTask } = require("./studyQueryTask");
const { JsSeriesQueryTask } = require("./seriesQueryTask");
const { JsInstanceQueryTask } = require("./instanceQueryTask");

const PATIENT_ROOT_LEVELS = EnumSet.ofSync(
QueryRetrieveLevel2.PATIENT,
Expand Down Expand Up @@ -107,6 +108,8 @@ class JsCFindScp {
return await (new JsStudyQueryTask(as, pc, rq, keys)).get();
} else if (await level.compareTo(QueryRetrieveLevel2.SERIES) === 0) {
return await (new JsSeriesQueryTask(as, pc, rq, keys)).get();
} else if (await level.compareTo(QueryRetrieveLevel2.IMAGE) === 0) {
return await (new JsInstanceQueryTask(as, pc, rq, keys)).get();
}
} catch (e) {
console.error(e);
Expand Down
125 changes: 125 additions & 0 deletions dimse/instanceQueryTask.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
const _ = require("lodash");

const { createQueryTaskInjectProxy } = require("@java-wrapper/org/github/chinlinlee/dcm777/net/QueryTaskInject");
const { DimseQueryBuilder } = require("./queryBuilder");
const { JsSeriesQueryTask } = require("./seriesQueryTask");
const dicomModel = require("@models/mongodb/models/dicom");
const { InstanceQueryTask } = require("@java-wrapper/org/github/chinlinlee/dcm777/net/InstanceQueryTask");
const { Attributes } = require("@dcm4che/data/Attributes");
const { createInstanceQueryTaskInjectProxy } = require("@java-wrapper/org/github/chinlinlee/dcm777/net/InstanceQueryTaskInject");


class JsInstanceQueryTask extends JsSeriesQueryTask {
constructor(as, pc, rq, keys) {
super(as, pc, rq, keys);

this.instanceCursor = null;
this.instance = null;
/** @type { Attributes | null } */
this.instanceAttr = null;
}

async get() {
let instanceQueryTask = await InstanceQueryTask.newInstanceAsync(
this.as,
this.pc,
this.rq,
this.keys,
this.getQueryTaskInjectProxy(),
this.getPatientQueryTaskInjectProxy(),
this.getStudyQueryTaskInjectProxy(),
this.getSeriesQueryTaskInjectProxy(),
this.getInstanceQueryTaskInjectProxy()
);

await super.get();
await this.instanceQueryTaskInjectMethods.wrappedFindNextInstance();

return instanceQueryTask;
}

getQueryTaskInjectProxy() {
this.instanceBasicQueryTaskInjectMethods = {
hasMoreMatches: () => {
return !_.isNull(this.instanceAttr);
},
nextMatch: async () => {
let returnAttr = await Attributes.newInstanceAsync(
await this.patientAttr.size() + await this.studyAttr.size() + await this.seriesAttr.size() + await this.instanceAttr.size()
);
await Attributes.unifyCharacterSets([this.patientAttr, this.studyAttr, this.seriesAttr, this.instanceAttr]);
await returnAttr.addAll(this.patientAttr);
await returnAttr.addAll(this.studyAttr, true);
await returnAttr.addAll(this.seriesAttr, true);
await returnAttr.addAll(this.instanceAttr, true);

await this.instanceQueryTaskInjectMethods.wrappedFindNextInstance();

return returnAttr;
},
adjust: async (match) => {
return await this.patientAdjust(match);
}
};

if (!this.queryTaskInjectProxy) {
this.queryTaskInjectProxy = createQueryTaskInjectProxy(this.instanceBasicQueryTaskInjectMethods);
}

return this.queryTaskInjectProxy;
}

getInstanceQueryTaskInjectProxy() {
/** @type { import("@java-wrapper/org/github/chinlinlee/dcm777/net/InstanceQueryTaskInject").InstanceQueryTaskInjectInterface } */
this.instanceQueryTaskInjectMethods = {
wrappedFindNextInstance: async () => {
await this.instanceQueryTaskInjectMethods.findNextInstance();
},
getInstance: async () => {
this.instance = await this.instanceCursor.next();
console.time("getAttributes");
this.instanceAttr = this.instance ? await this.instance.getAttributes() : null;
console.timeEnd("getAttributes");
},
findNextInstance: async () => {
if (!this.seriesAttr)
return false;

if (!this.instanceAttr) {
await this.getNextInstanceCursor();
await this.instanceQueryTaskInjectMethods.getInstance();
} else {
await this.instanceQueryTaskInjectMethods.getInstance();
}

while (!this.instanceAttr && await this.seriesQueryTaskInjectMethods.findNextSeries()) {
await this.getNextInstanceCursor();
await this.instanceQueryTaskInjectMethods.getInstance();
}

return _.isNull(this.instanceAttr);
}
};

if (!this.instanceQueryTaskInjectProxy) {
this.instanceQueryTaskInjectProxy = createInstanceQueryTaskInjectProxy(this.instanceQueryTaskInjectMethods);
}

return this.instanceQueryTaskInjectProxy;
}

async getNextInstanceCursor() {
let queryBuilder = new DimseQueryBuilder(this.keys, "instance");
let normalQuery = await queryBuilder.toNormalQuery();
let mongoQuery = await queryBuilder.getMongoQuery(normalQuery);

let returnKeys = this.getReturnKeys(normalQuery);

this.instanceCursor = await dicomModel.getDimseResultCursor({
...mongoQuery.$match
}, returnKeys);
}

}

module.exports.JsInstanceQueryTask = JsInstanceQueryTask;
6 changes: 6 additions & 0 deletions dimse/patientQueryTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ const { default: Tag } = require("@dcm4che/data/Tag");
const { default: VR } = require("@dcm4che/data/VR");
const { DimseQueryBuilder } = require("./queryBuilder");
const patientModel = require("@models/mongodb/models/patient");
const { Association } = require("@dcm4che/net/Association");
const { PresentationContext } = require("@dcm4che/net/pdu/PresentationContext");


class JsPatientQueryTask {
constructor(as, pc, rq, keys) {
/** @type { Association } */
this.as = as;
/** @type { PresentationContext } */
this.pc = pc;
/** @type { Attributes } */
this.rq = rq;
/** @type { Attributes } */
this.keys = keys;

this.patientAttr = null;
Expand Down
11 changes: 5 additions & 6 deletions dimse/seriesQueryTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ class JsSeriesQueryTask extends JsStudyQueryTask {
await this.patientAttr.size() + await this.studyAttr.size() + await this.seriesAttr.size()
);
await Attributes.unifyCharacterSets([this.patientAttr, this.studyAttr, this.seriesAttr]);
returnAttr.addAll(this.patientAttr);
returnAttr.addAll(this.studyAttr, true);
returnAttr.addAll(this.seriesAttr, true);
await returnAttr.addAll(this.patientAttr);
await returnAttr.addAll(this.studyAttr, true);
await returnAttr.addAll(this.seriesAttr, true);

await this.seriesQueryTaskInjectMethods.wrappedFindNextSeries();

Expand Down Expand Up @@ -88,15 +88,15 @@ class JsSeriesQueryTask extends JsStudyQueryTask {
await this.seriesQueryTaskInjectMethods.getSeries();
}

while(!this.seriesAttr && await this.studyQueryTaskInjectMethods.findNextStudy()) {
while (!this.seriesAttr && await this.studyQueryTaskInjectMethods.findNextStudy()) {
await this.getNextSeriesCursor();
await this.seriesQueryTaskInjectMethods.getSeries();
}

return !_.isNull(this.seriesAttr);
}
};

if (!this.seriesQueryTaskInjectProxy) {
this.seriesQueryTaskInjectProxy = createSeriesQueryTaskInjectProxy(this.seriesQueryTaskInjectMethods);
}
Expand All @@ -111,7 +111,6 @@ class JsSeriesQueryTask extends JsStudyQueryTask {

let returnKeys = this.getReturnKeys(normalQuery);

console.log(JSON.stringify(mongoQuery, null, 2));
this.seriesCursor = await dicomSeriesModel.getDimseResultCursor({
...mongoQuery.$match
}, returnKeys);
Expand Down
22 changes: 22 additions & 0 deletions models/mongodb/models/dicom.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ const { logger } = require("../../../utils/logs/log");
const { raccoonConfig } = require("@root/config-class");
const { dictionary } = require("@models/DICOM/dicom-tags-dic");

let Common;
if (raccoonConfig.dicomDimseConfig.enableDimse) {
require("@models/DICOM/dcm4che/java-instance");
Common = require("@java-wrapper/org/github/chinlinlee/dcm777/net/common/Common").Common;
}

let verifyingObserverSchema = new mongoose.Schema(
{
"0040A027": getVRSchema("LO"),
Expand Down Expand Up @@ -145,6 +151,22 @@ let dicomModelSchema = new mongoose.Schema(
} catch (e) {
console.error(e);
}
},
getAttributes: async function() {
let study = this.toObject();
delete study._id;
delete study.id;

let jsonStr = JSON.stringify(study);
return await Common.getAttributesFromJsonString(jsonStr);
}
},
statics: {
getDimseResultCursor: async (query, keys) => {
return mongoose.model("dicom").find(query, keys).setOptions({
strictQuery: false
})
.cursor();
}
},
timestamps: true
Expand Down

0 comments on commit 1c11f1d

Please sign in to comment.