orthanc proxy

This commit is contained in:
Weiwei authored and Erik Ziegler committed 2016-02-14 15:22:23 +01:00
1 parent e354c6c577
commit 94076f6263
8 files changed
+403 -1

No files matched your search

+6 -1
View File
@@ -1,4 +1,9 @@
Services = {};
Services.QIDO = {};
Services.WADO = {};
Services.DIMSE = {};
Services.DIMSE = {};
Services.REMOTE = {};
remoteGetValue = function(obj) {
return obj ? obj.Value : null;
}
+82
View File
@@ -0,0 +1,82 @@
/**
* Parses data returned from a QIDO search and transforms it into
* an array of series that are present in the study
*
* @param server The DICOM server
* @param studyInstanceUid
* @param resultData
* @returns {Array} Series List
*/
function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
var seriesMap = {};
var seriesList = [];
resultData.forEach(function(instance) {
// Use seriesMap to cache series data
// If the series instance UID has already been used to
// process series data, continue using that series
var seriesInstanceUid = remoteGetValue(instance['0020,000e']);
var series = seriesMap[seriesInstanceUid];
// If no series data exists in the seriesMap cache variable,
// process any available series data
if(!series) {
series = {
seriesInstanceUid : seriesInstanceUid,
seriesNumber : parseFloat(remoteGetValue(instance['0020,0011'])),
instances: []
};
// Save this data in the seriesMap cache variable
seriesMap[seriesInstanceUid] = series;
seriesList.push(series);
}
// The uri for the dicomweb
// NOTE: DCM4CHEE seems to return the data zipped
// NOTE: Orthanc returns the data with multi-part mime which cornerstoneWADOImageLoader doesn't
// know how to parse yet
//var uri = DICOMWeb.getString(instance['00081190']);
//uri = uri.replace('wado-rs', 'dicom-web');
// manually create a WADO-URI from the UIDs
// NOTE: Haven't been able to get Orthanc's WADO-URI to work yet - maybe its not configured?
var sopInstanceUid = remoteGetValue(instance['0008,0018']);
var uri = server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + "&contentType=application%2Fdicom";
// Add this instance to the current series
series.instances.push({
sopClassUid: remoteGetValue(instance['0008,0016']),
sopInstanceUid: sopInstanceUid,
uri: uri,
instanceNumber: parseFloat(remoteGetValue(instance['0020,0013']))
});
});
return seriesList;
}
/**
* Retrieve a set of instances using a QIDO call
* @param server
* @param studyInstanceUid
* @returns {{wadoUriRoot: String, studyInstanceUid: String, seriesList: Array}}
*/
Services.REMOTE.Instances = function(server, studyInstanceUid) {
var parameters = {
PatientName: "",
PatientID: "",
AccessionNumber: "",
SeriesInstanceUID: "",
SeriesNumber : "",
SOPClassUID : "",
InstanceNumber : ""
};
var remote = new OrthancRemote(server.root, server.sourceAE);
return {
wadoUriRoot: server.wadoUriRoot,
studyInstanceUid: studyInstanceUid,
seriesList: resultDataToStudyMetadata(server, studyInstanceUid, remote.findInstances(server.modality, studyInstanceUid, null, parameters))
};
};
@@ -0,0 +1,133 @@
/**
* Parses the SourceImageSequence, if it exists, in order
* to return a ReferenceSOPInstanceUID. The ReferenceSOPInstanceUID
* is used to refer to this image in any accompanying DICOM-SR documents.
*
* @param instance
* @returns {String} The ReferenceSOPInstanceUID
*/
function getSourceImageInstanceUid(instance) {
// TODO= Parse the whole Source Image Sequence
// This is a really poor workaround for now.
// Later we should probably parse the whole sequence.
var SourceImageSequence = remoteGetValue(instance['0008,2112']);
if (SourceImageSequence && SourceImageSequence.Value && SourceImageSequence.Value.length) {
return SourceImageSequence.Value[0]['0008,1155'].Value[0];
}
}
/**
* Parses result data from a WADO search into Study MetaData
* Returns an object populated with study metadata, including the
* series list.
*
* @param server
* @param studyInstanceUid
* @param resultData
* @returns {{seriesList: Array, patientName: *, patientId: *, accessionNumber: *, studyDate: *, modalities: *, studyDescription: *, imageCount: *, studyInstanceUid: *}}
*/
function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
var seriesMap = {};
var seriesList = [];
if (!resultData.length) {
return;
}
var anInstance = resultData[0];
if (!anInstance) {
return;
}
var studyData = {
seriesList: seriesList,
patientName: remoteGetValue(anInstance['0010,0010']),
patientId: remoteGetValue(anInstance['0010,0020']),
accessionNumber: remoteGetValue(anInstance['0008,0050']),
studyDate: remoteGetValue(anInstance['0008,0020']),
modalities: remoteGetValue(anInstance['0008,0061']),
studyDescription: remoteGetValue(anInstance['0008,1030']),
imageCount: remoteGetValue(anInstance['0020,1208']),
studyInstanceUid: remoteGetValue(anInstance['0020,000d'])
};
resultData.forEach(function(instance) {
var seriesInstanceUid = remoteGetValue(instance['0020,000e']);
var series = seriesMap[seriesInstanceUid];
if (!series) {
series = {
seriesDescription: remoteGetValue(instance['0008,103e']),
modality: remoteGetValue(instance['0008,0060']),
seriesInstanceUid: seriesInstanceUid,
seriesNumber: parseFloat(remoteGetValue(instance['0020,0011'])),
instances: []
};
seriesMap[seriesInstanceUid] = series;
seriesList.push(series);
}
var sopInstanceUid = remoteGetValue(instance['0008,0018']);
var instanceSummary = {
imageType: remoteGetValue(instance['0008,0008']),
sopClassUid: remoteGetValue(instance['0008,0016']),
sopInstanceUid: sopInstanceUid,
instanceNumber: parseFloat(remoteGetValue(instance['0020,0013'])),
imagePositionPatient: remoteGetValue(instance['0020,0032']),
imageOrientationPatient: remoteGetValue(instance['0020,0037']),
frameOfReferenceUID: remoteGetValue(instance['0020,0052']),
sliceLocation: parseFloat(remoteGetValue(instance['0020,1041'])),
samplesPerPixel: parseFloat(remoteGetValue(instance['0028,0002'])),
photometricInterpretation: remoteGetValue(instance['0028,0004']),
rows: parseFloat(remoteGetValue(instance['0028,0010'])),
columns: parseFloat(remoteGetValue(instance['0028,0011'])),
pixelSpacing: remoteGetValue(instance['0028,0030']),
bitsAllocated: parseFloat(remoteGetValue(instance['0028,0100'])),
bitsStored: parseFloat(remoteGetValue(instance['0028,0101'])),
highBit: parseFloat(remoteGetValue(instance['0028,0102'])),
pixelRepresentation: parseFloat(remoteGetValue(instance['0028,0103'])),
windowCenter: remoteGetValue(instance['0028,1050']),
windowWidth: remoteGetValue(instance['0028,1051']),
rescaleIntercept: parseFloat(remoteGetValue(instance['0028,1052'])),
rescaleSlope: parseFloat(remoteGetValue(instance['0028,1053'])),
sourceImageInstanceUid: getSourceImageInstanceUid(instance),
laterality: remoteGetValue(instance['0020,0062']),
viewPosition: remoteGetValue(instance['0018,5101']),
numFrames: parseFloat(remoteGetValue(instance['0028,0008'])),
frameRate: parseFloat(remoteGetValue(instance['0018,1063']))
};
var iid = instance['xxxx,0001'].Value;
if (server.imageRendering === 'wadouri') {
instanceSummary.wadouri = server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + "&contentType=application%2Fdicom";
} else if (server.imageRendering == 'orthanc') {
instanceSummary.wadouri = server.root + '/instances/' + iid + '/file';
} else {
instanceSummary.wadorsuri = server.wadoRoot + '/studies/' + studyInstanceUid + '/series/' + seriesInstanceUid + '/instances/' + sopInstanceUid + '/frames/1';
}
series.instances.push(instanceSummary);
});
console.log(studyData.seriesList[0].instances);
return studyData;
}
/**
* Retrieved Study MetaData from a DICOM server using a WADO call
* @param server
* @param studyInstanceUid
* @returns {{seriesList: Array, patientName: *, patientId: *, accessionNumber: *, studyDate: *, modalities: *, studyDescription: *, imageCount: *, studyInstanceUid: *}}
*/
Services.REMOTE.RetrieveMetadata = function(server, studyInstanceUid) {
var remote = new OrthancRemote(server.root, server.sourceAE);
var study = resultDataToStudyMetadata(server, studyInstanceUid, remote.retrieveMetadata(server.modality, studyInstanceUid));
if (!study) {
study = {};
}
study.wadoUriRoot = server.wadoUriRoot;
study.studyInstanceUid = studyInstanceUid;
return study;
};
+47
View File
@@ -0,0 +1,47 @@
function resultDataToStudies(resultData) {
var studies = [];
resultData.forEach(function(study) {
studies.push({
studyInstanceUid: remoteGetValue(study['0020,000d']),
// 00080005 = SpecificCharacterSet
studyDate: remoteGetValue(study['0008,0020']),
studyTime: remoteGetValue(study['0008,0030']),
accessionNumber: remoteGetValue(study['0008,0050']),
referringPhysicianName: remoteGetValue(study['0008,0090']),
// 00081190 = URL
patientName: remoteGetValue(study['0010,0010']),
patientId: remoteGetValue(study['0010,0020']),
patientBirthdate: remoteGetValue(study['0010,0030']),
patientSex: remoteGetValue(study['0010,0040']),
studyId: remoteGetValue(study['0020,0010']),
numberOfStudyRelatedSeries: parseFloat(remoteGetValue(study['0020,1206'])),
numberOfStudyRelatedInstances: parseFloat(remoteGetValue(study['0020,1208'])),
studyDescription: remoteGetValue(study['0008,1030']),
modalities: remoteGetValue(study['0008,0061'])
});
});
return studies;
}
Services.REMOTE.Studies = function(server, filter) {
var parameters = {
PatientName: filter.patientName ? filter.patientName : "",
PatientID: filter.patientId,
AccessionNumber: filter.accessionNumber ? filter.accessionNumber : "",
StudyDescription: "",
StudyDate : "",
StudyTime : "",
ReferringPhysicianName : "",
PatientBirthDate : "",
PatientSex : "",
StudyID : "",
NumberOfStudyRelatedSeries : "",
NumberOfStudyRelatedInstances : "",
ModalitiesInStudy : ""
};
var remote = new OrthancRemote(server.root, server.sourceAE);
var data = remote.findStudies(server.modality, parameters);
return resultDataToStudies(data.results);
};