Instance metadata/metadata providers overhaul (#1481)

* Instance metadata plus metadata provider overhaul.

Fix consumption of wado-uri urls

fallbacks + datatype agnosticism.

WIP DICOMify things.

fix various issues with naturalized variable naming migration.

Remove metadata provider.

Fix consumption of multiframe images and addition of CWIL metadata.

Fix strange build issues.

Fix CWIL style windowWidth to array from naturalized DICOM.

Fix PT, CT, CR and DX issues for cornerstone + DX issues for vtkjs.

Move color palette fetching down to the natuaralized JSON level.

Remove unused StudyMetadataSummary

Remove redundant dicom metadata dictionary.

Working local + json routes.

Fix SR read.

Finished first round of testing + cleaned up debugging etc.

* data => metadata for instance naturalizedJSON

* Update dcmjs version

* Correct github isssues.

* Fix erroneously replaced files.

* Danny's recommended changes.

* Instance metadata plus metadata provider overhaul.

Fix consumption of wado-uri urls

fallbacks + datatype agnosticism.

WIP DICOMify things.

fix various issues with naturalized variable naming migration.

Remove metadata provider.

Fix consumption of multiframe images and addition of CWIL metadata.

Fix strange build issues.

Fix CWIL style windowWidth to array from naturalized DICOM.

Fix PT, CT, CR and DX issues for cornerstone + DX issues for vtkjs.

Move color palette fetching down to the natuaralized JSON level.

Remove unused StudyMetadataSummary

Remove redundant dicom metadata dictionary.

Working local + json routes.

Fix SR read.

Finished first round of testing + cleaned up debugging etc.

* data => metadata for instance naturalizedJSON

* Update dcmjs version

* Correct github isssues.

* Fix erroneously replaced files.

* Danny's recommended changes.

* Update JSON CI

* Update casing of import.

* Fix jump for SR.

* Fix unit tests for measurements service

* Fix json CI test.

* fix: update yarn lock

* Fix local non-encapsulated pdf view

* CI updated to new sucess message.

Co-authored-by: Danny <danny.ri.brown@gmail.com>
This commit is contained in:
James PettsandDanny authored and GitHub committed 2020-03-09 19:03:23 +00:00
1 parent 8833731ad3
commit 1d85f7a74e
142 files changed
+5322 -8570

No files matched your search

@@ -34,7 +34,7 @@ const commandsModule = ({ commandsManager }) => {
const activeViewport =
viewportSpecificData[viewports.activeViewportIndex];
const studyMetadata = utils.studyMetadataManager.get(
activeViewport.studyInstanceUid
activeViewport.StudyInstanceUID
);
if (!studyMetadata) {
@@ -44,8 +44,8 @@ const commandsModule = ({ commandsManager }) => {
const allDisplaySets = studyMetadata.getDisplaySets();
const currentDisplaySetIndex = allDisplaySets.findIndex(
displaySet =>
displaySet.displaySetInstanceUid ===
activeViewport.displaySetInstanceUid
displaySet.displaySetInstanceUID ===
activeViewport.displaySetInstanceUID
);
if (currentDisplaySetIndex < 0) {
return;
@@ -1,4 +1,4 @@
import { measurements, utils } from "@ohif/core";
import { measurements, utils } from '@ohif/core';
const { MeasurementApi } = measurements;
const { studyMetadataManager } = utils;
@@ -68,10 +68,15 @@ export default function jumpToRowItem(
// Needs to update viewports.viewportData state to set image set data
const displaySetContainsSopInstance = (displaySet, sopInstanceUid) =>
displaySet.images.find(
image => image.getSOPInstanceUID() === sopInstanceUid
const displaySetContainsSopInstance = (displaySet, SOPInstanceUID) => {
if (!displaySet.images || !displaySet.images.length) {
return;
}
return displaySet.images.find(
image => image.getSOPInstanceUID() === SOPInstanceUID
);
};
const viewportSpecificData = [];
measurementsToJumpTo.forEach((data, viewportIndex) => {
@@ -80,32 +85,32 @@ export default function jumpToRowItem(
return;
}
const study = studyMetadataManager.get(data.studyInstanceUid);
const study = studyMetadataManager.get(data.StudyInstanceUID);
if (!study) {
throw new Error("Study not found.");
throw new Error('Study not found.');
}
const displaySet = study.findDisplaySet(displaySet => {
return displaySetContainsSopInstance(displaySet, data.sopInstanceUid);
return displaySetContainsSopInstance(displaySet, data.SOPInstanceUID);
});
if (!displaySet) {
throw new Error("Display set not found.");
throw new Error('Display set not found.');
}
displaySet.sopInstanceUid = data.sopInstanceUid;
displaySet.SOPInstanceUID = data.SOPInstanceUID;
if (data.frameIndex) {
displaySet.frameIndex = data.frameIndex;
}
viewportSpecificData.push({
viewportIndex,
displaySet
displaySet,
});
});
return {
viewportSpecificData,
layout: [] // TODO: if we need to change layout, we should return this here
layout: [], // TODO: if we need to change layout, we should return this here
};
}
@@ -69,13 +69,13 @@ const ViewportGrid = function(props) {
<ViewportPane
onDrop={({
viewportIndex,
studyInstanceUid,
displaySetInstanceUid,
StudyInstanceUID,
displaySetInstanceUID,
}) => {
setViewportData({
viewportIndex,
studyInstanceUid,
displaySetInstanceUid,
StudyInstanceUID,
displaySetInstanceUID,
});
}}
viewportIndex={viewportIndex} // Needed by `setViewportData`
@@ -13,9 +13,9 @@ const ViewportPane = function(props) {
const isOver = monitor.isOver();
if (canDrop && isOver && onDrop) {
const { studyInstanceUid, displaySetInstanceUid } = droppedItem;
const { StudyInstanceUID, displaySetInstanceUID } = droppedItem;
onDrop({ viewportIndex, studyInstanceUid, displaySetInstanceUid });
onDrop({ viewportIndex, StudyInstanceUID, displaySetInstanceUID });
}
},
// Monitor, and collect props.
@@ -17,8 +17,8 @@ const mapStateToProps = (state, ownProps) => {
studiesWithLoadingData.forEach(study => {
study.thumbnails.forEach(data => {
const { displaySetInstanceUid } = data;
const stackId = `StackProgress:${displaySetInstanceUid}`;
const { displaySetInstanceUID } = data;
const stackId = `StackProgress:${displaySetInstanceUID}`;
const stackProgressData = stackLoadingProgressMap[stackId];
let stackPercentComplete = 0;
@@ -37,9 +37,9 @@ const mapStateToProps = (state, ownProps) => {
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onThumbnailClick: displaySetInstanceUid => {
onThumbnailClick: displaySetInstanceUID => {
const displaySet = ownProps.studyMetadata[0].displaySets.find(
ds => ds.displaySetInstanceUid === displaySetInstanceUid
ds => ds.displaySetInstanceUID === displaySetInstanceUID
);
dispatch(setActiveViewportSpecificData(displaySet));
@@ -23,16 +23,16 @@ class Viewer extends Component {
static propTypes = {
studies: PropTypes.arrayOf(
PropTypes.shape({
studyInstanceUid: PropTypes.string.isRequired,
studyDate: PropTypes.string,
StudyInstanceUID: PropTypes.string.isRequired,
StudyDate: PropTypes.string,
displaySets: PropTypes.arrayOf(
PropTypes.shape({
displaySetInstanceUid: PropTypes.string.isRequired,
seriesDescription: PropTypes.string,
seriesNumber: PropTypes.number,
instanceNumber: PropTypes.number,
displaySetInstanceUID: PropTypes.string.isRequired,
SeriesDescription: PropTypes.string,
SeriesNumber: PropTypes.number,
InstanceNumber: PropTypes.number,
numImageFrames: PropTypes.number,
modality: PropTypes.string.isRequired,
Modality: PropTypes.string.isRequired,
images: PropTypes.arrayOf(
PropTypes.shape({
getImageId: PropTypes.func.isRequired,
@@ -42,7 +42,7 @@ class Viewer extends Component {
),
})
),
studyInstanceUids: PropTypes.array,
studyInstanceUIDs: PropTypes.array,
activeServer: PropTypes.shape({
type: PropTypes.string,
wadoRoot: PropTypes.string,
@@ -105,12 +105,12 @@ class Viewer extends Component {
if (this.props.studies) {
latestDate = new Date('1000-01-01').toISOString();
this.props.studies.forEach(study => {
const studyDate = moment(study.studyDate, 'YYYYMMDD').toISOString();
if (studyDate < earliestDate) {
earliestDate = studyDate;
const StudyDate = moment(study.StudyDate, 'YYYYMMDD').toISOString();
if (StudyDate < earliestDate) {
earliestDate = StudyDate;
}
if (studyDate > latestDate) {
latestDate = studyDate;
if (StudyDate > latestDate) {
latestDate = StudyDate;
}
});
}
@@ -120,8 +120,8 @@ class Viewer extends Component {
{
timepointType: 'baseline',
timepointId: 'TimepointId',
studyInstanceUids: this.props.studyInstanceUids,
patientId: filter.patientId,
studyInstanceUIDs: this.props.studyInstanceUIDs,
PatientID: filter.PatientID,
earliestDate,
latestDate,
isLocked: false,
@@ -144,7 +144,7 @@ class Viewer extends Component {
return Promise.resolve();
};
disassociateStudy = (timepointIds, studyInstanceUid) => {
disassociateStudy = (timepointIds, StudyInstanceUID) => {
OHIF.log.info('disassociateStudy');
return Promise.resolve();
};
@@ -179,11 +179,11 @@ class Viewer extends Component {
this.measurementApi = measurementApi;
if (studies) {
const patientId = studies[0] && studies[0].patientId;
const PatientID = studies[0] && studies[0].PatientID;
timepointApi.retrieveTimepoints({ patientId });
timepointApi.retrieveTimepoints({ PatientID });
if (isStudyLoaded) {
this.measurementApi.retrieveMeasurements(patientId, [
this.measurementApi.retrieveMeasurements(PatientID, [
currentTimepointId,
]);
}
@@ -201,11 +201,11 @@ class Viewer extends Component {
});
}
if (isStudyLoaded && isStudyLoaded !== prevProps.isStudyLoaded) {
const patientId = studies[0] && studies[0].patientId;
const PatientID = studies[0] && studies[0].PatientID;
const { currentTimepointId } = this;
this.timepointApi.retrieveTimepoints({ patientId });
this.measurementApi.retrieveMeasurements(patientId, [currentTimepointId]);
this.timepointApi.retrieveTimepoints({ PatientID });
this.measurementApi.retrieveMeasurements(PatientID, [currentTimepointId]);
}
}
@@ -331,21 +331,21 @@ export default withDialog(Viewer);
*/
const _mapStudiesToThumbnails = function(studies) {
return studies.map(study => {
const { studyInstanceUid } = study;
const { StudyInstanceUID } = study;
const thumbnails = study.displaySets.map(displaySet => {
const {
displaySetInstanceUid,
seriesDescription,
seriesNumber,
instanceNumber,
displaySetInstanceUID,
SeriesDescription,
SeriesNumber,
InstanceNumber,
numImageFrames,
} = displaySet;
let imageId;
let altImageText;
if (displaySet.modality && displaySet.modality === 'SEG') {
if (displaySet.Modality && displaySet.Modality === 'SEG') {
// TODO: We want to replace this with a thumbnail showing
// the segmentation map on the image, but this is easier
// and better than what we have right now.
@@ -355,22 +355,22 @@ const _mapStudiesToThumbnails = function(studies) {
imageId = displaySet.images[imageIndex].getImageId();
} else {
altImageText = displaySet.modality ? displaySet.modality : 'UN';
altImageText = displaySet.Modality ? displaySet.Modality : 'UN';
}
return {
imageId,
altImageText,
displaySetInstanceUid,
seriesDescription,
seriesNumber,
instanceNumber,
displaySetInstanceUID,
SeriesDescription,
SeriesNumber,
InstanceNumber,
numImageFrames,
};
});
return {
studyInstanceUid,
StudyInstanceUID,
thumbnails,
};
});
@@ -10,7 +10,7 @@ import './ViewerLocalFileData.css';
import { withTranslation } from 'react-i18next';
const { OHIFStudyMetadata } = metadata;
const { studyMetadataManager, updateMetaDataManager } = utils;
const { studyMetadataManager } = utils;
const dropZoneLinkDialog = (onDrop, i18n, dir) => {
return (
@@ -69,7 +69,7 @@ class ViewerLocalFileData extends Component {
const updatedStudies = studies.map(study => {
const studyMetadata = new OHIFStudyMetadata(
study,
study.studyInstanceUid
study.StudyInstanceUID
);
const sopClassHandlerModules =
extensionManager.modules['sopClassHandlerModule'];
@@ -82,8 +82,6 @@ class ViewerLocalFileData extends Component {
studyMetadata.forEachDisplaySet(displayset => {
displayset.localFile = true;
});
// Updates WADO-RS metaDataManager
updateMetaDataManager(study);
studyMetadataManager.add(studyMetadata);
@@ -120,9 +118,9 @@ class ViewerLocalFileData extends Component {
{this.state.studies ? (
<ConnectedViewer
studies={this.state.studies}
studyInstanceUids={
studyInstanceUIDs={
this.state.studies &&
this.state.studies.map(a => a.studyInstanceUid)
this.state.studies.map(a => a.StudyInstanceUID)
}
/>
) : (
@@ -37,9 +37,9 @@ class ViewerMain extends Component {
return displaySets;
}
findDisplaySet(studies, studyInstanceUid, displaySetInstanceUid) {
findDisplaySet(studies, StudyInstanceUID, displaySetInstanceUID) {
const study = studies.find(study => {
return study.studyInstanceUid === studyInstanceUid;
return study.StudyInstanceUID === StudyInstanceUID;
});
if (!study) {
@@ -47,7 +47,7 @@ class ViewerMain extends Component {
}
return study.displaySets.find(displaySet => {
return displaySet.displaySetInstanceUid === displaySetInstanceUid;
return displaySet.displaySetInstanceUID === displaySetInstanceUID;
});
}
@@ -89,13 +89,13 @@ class ViewerMain extends Component {
const viewportPane = viewportSpecificData[i];
const isNonEmptyViewport =
viewportPane &&
viewportPane.studyInstanceUid &&
viewportPane.displaySetInstanceUid;
viewportPane.StudyInstanceUID &&
viewportPane.displaySetInstanceUID;
if (isNonEmptyViewport) {
dirtyViewportPanes.push({
studyInstanceUid: viewportPane.studyInstanceUid,
displaySetInstanceUid: viewportPane.displaySetInstanceUid,
StudyInstanceUID: viewportPane.StudyInstanceUID,
displaySetInstanceUID: viewportPane.displaySetInstanceUID,
});
continue;
@@ -105,7 +105,7 @@ class ViewerMain extends Component {
displaySets.find(
ds =>
!dirtyViewportPanes.some(
v => v.displaySetInstanceUid === ds.displaySetInstanceUid
v => v.displaySetInstanceUID === ds.displaySetInstanceUID
)
) || displaySets[displaySets.length - 1];
@@ -113,11 +113,11 @@ class ViewerMain extends Component {
}
dirtyViewportPanes.forEach((vp, i) => {
if (vp && vp.studyInstanceUid) {
if (vp && vp.StudyInstanceUID) {
this.setViewportData({
viewportIndex: i,
studyInstanceUid: vp.studyInstanceUid,
displaySetInstanceUid: vp.displaySetInstanceUid,
StudyInstanceUID: vp.StudyInstanceUID,
displaySetInstanceUID: vp.displaySetInstanceUID,
});
}
});
@@ -125,13 +125,13 @@ class ViewerMain extends Component {
setViewportData = ({
viewportIndex,
studyInstanceUid,
displaySetInstanceUid,
StudyInstanceUID,
displaySetInstanceUID,
}) => {
const displaySet = this.findDisplaySet(
this.props.studies,
studyInstanceUid,
displaySetInstanceUid
StudyInstanceUID,
displaySetInstanceUID
);
this.props.setViewportSpecificData(viewportIndex, displaySet);
@@ -9,7 +9,7 @@ import { useSnackbarContext } from '@ohif/ui';
const { OHIFStudyMetadata, OHIFSeriesMetadata } = metadata;
const { retrieveStudiesMetadata, deleteStudyMetadataPromise } = studies;
const { studyMetadataManager, updateMetaDataManager, makeCancelable } = utils;
const { studyMetadataManager, makeCancelable } = utils;
// Contexts
import AppContext from '../context/AppContext';
@@ -61,7 +61,7 @@ const _promoteStudyDisplaySet = (study, studyMetadata, filters) => {
const { seriesInstanceUID } = filters;
const _seriesLookup = (valueToCompare, displaySet) => {
return displaySet.seriesInstanceUid === valueToCompare;
return displaySet.SeriesInstanceUID === valueToCompare;
};
const promotedResponse = _promoteToFront(
studyMetadata.getDisplaySets(),
@@ -91,10 +91,10 @@ const _isQueryParamApplied = (study, filters = {}, isFilterStrategy) => {
return applied;
}
const { seriesList = [], displaySets = [] } = study;
const firstSeries = isFilterStrategy ? seriesList[0] : displaySets[0];
const { series = [], displaySets = [] } = study;
const firstSeries = isFilterStrategy ? series[0] : displaySets[0];
if (!firstSeries || firstSeries.seriesInstanceUid !== seriesInstanceUID) {
if (!firstSeries || firstSeries.SeriesInstanceUID !== seriesInstanceUID) {
applied = false;
}
@@ -105,7 +105,7 @@ const _showUserMessage = (queryParamApplied, message, dialog = {}) => {
return;
}
const { show: showUserMessage = () => { } } = dialog;
const { show: showUserMessage = () => {} } = dialog;
showUserMessage({
message,
});
@@ -123,15 +123,13 @@ const _addSeriesToStudy = (studyMetadata, series) => {
false
);
study.displaySets = studyMetadata.getDisplaySets();
_updateMetaDataManager(study, series.seriesInstanceUid);
_updateStudyMetadataManager(study, studyMetadata);
};
const _updateMetaDataManager = (study, studyMetadata, series) => {
updateMetaDataManager(study, series);
const _updateStudyMetadataManager = (study, studyMetadata) => {
const { StudyInstanceUID } = study;
const { studyInstanceUid } = study;
if (!studyMetadataManager.get(studyInstanceUid)) {
if (!studyMetadataManager.get(StudyInstanceUID)) {
studyMetadataManager.add(studyMetadata);
}
};
@@ -172,8 +170,8 @@ const _loadRemainingSeries = studyMetadata => {
function ViewerRetrieveStudyData({
server,
studyInstanceUids,
seriesInstanceUids,
studyInstanceUIDs,
seriesInstanceUIDs,
clearViewportSpecificData,
}) {
// hooks
@@ -235,14 +233,14 @@ function ViewerRetrieveStudyData({
const studies = studiesData.map(study => {
const studyMetadata = new OHIFStudyMetadata(
study,
study.studyInstanceUid
study.StudyInstanceUID
);
_updateStudyDisplaySets(study, studyMetadata);
_updateMetaDataManager(study, studyMetadata);
_updateStudyMetadataManager(study, studyMetadata);
// Attempt to load remaning series if any
cancelableSeriesPromises[study.studyInstanceUid] = makeCancelable(
cancelableSeriesPromises[study.StudyInstanceUID] = makeCancelable(
_loadRemainingSeries(studyMetadata)
)
.then(result => {
@@ -268,9 +266,9 @@ function ViewerRetrieveStudyData({
try {
const filters = {};
// Use the first, discard others
const seriesInstanceUID = seriesInstanceUids && seriesInstanceUids[0];
const seriesInstanceUID = seriesInstanceUIDs && seriesInstanceUIDs[0];
const retrieveParams = [server, studyInstanceUids];
const retrieveParams = [server, studyInstanceUIDs];
if (seriesInstanceUID) {
filters.seriesInstanceUID = seriesInstanceUID;
@@ -280,7 +278,7 @@ function ViewerRetrieveStudyData({
}
}
cancelableStudiesPromises[studyInstanceUids] = makeCancelable(
cancelableStudiesPromises[studyInstanceUIDs] = makeCancelable(
retrieveStudiesMetadata(...retrieveParams)
)
.then(result => {
@@ -303,31 +301,34 @@ function ViewerRetrieveStudyData({
};
const purgeCancellablePromises = () => {
for (let studyInstanceUids in cancelableStudiesPromises) {
if ('cancel' in cancelableStudiesPromises[studyInstanceUids]) {
cancelableStudiesPromises[studyInstanceUids].cancel();
for (let studyInstanceUIDs in cancelableStudiesPromises) {
if ('cancel' in cancelableStudiesPromises[studyInstanceUIDs]) {
cancelableStudiesPromises[studyInstanceUIDs].cancel();
}
}
for (let studyInstanceUids in cancelableSeriesPromises) {
if ('cancel' in cancelableSeriesPromises[studyInstanceUids]) {
cancelableSeriesPromises[studyInstanceUids].cancel();
deleteStudyMetadataPromise(studyInstanceUids);
studyMetadataManager.remove(studyInstanceUids);
for (let studyInstanceUIDs in cancelableSeriesPromises) {
if ('cancel' in cancelableSeriesPromises[studyInstanceUIDs]) {
cancelableSeriesPromises[studyInstanceUIDs].cancel();
deleteStudyMetadataPromise(studyInstanceUIDs);
studyMetadataManager.remove(studyInstanceUIDs);
}
}
};
const prevStudyInstanceUids = usePrevious(studyInstanceUids);
const prevStudyInstanceUIDs = usePrevious(studyInstanceUIDs);
useEffect(() => {
const hasStudyInstanceUidsChanged = !(prevStudyInstanceUids && prevStudyInstanceUids.every(e => studyInstanceUids.includes(e)));
const hasStudyInstanceUIDsChanged = !(
prevStudyInstanceUIDs &&
prevStudyInstanceUIDs.every(e => studyInstanceUIDs.includes(e))
);
if (hasStudyInstanceUidsChanged) {
if (hasStudyInstanceUIDsChanged) {
studyMetadataManager.purge();
purgeCancellablePromises();
}
}, [studyInstanceUids]);
}, [studyInstanceUIDs]);
useEffect(() => {
cancelableSeriesPromises = {};
@@ -347,14 +348,14 @@ function ViewerRetrieveStudyData({
<ConnectedViewer
studies={studies}
isStudyLoaded={isStudyLoaded}
studyInstanceUids={studyInstanceUids}
studyInstanceUIDs={studyInstanceUIDs}
/>
);
}
ViewerRetrieveStudyData.propTypes = {
studyInstanceUids: PropTypes.array.isRequired,
seriesInstanceUids: PropTypes.array,
studyInstanceUIDs: PropTypes.array.isRequired,
seriesInstanceUIDs: PropTypes.array,
server: PropTypes.object,
clearViewportSpecificData: PropTypes.func.isRequired,
};
@@ -1,6 +1,9 @@
import * as dcmjs from 'dcmjs';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import FileLoader from './fileLoader';
import OHIF from '@ohif/core';
const metadataProvider = OHIF.cornerstone.metadataProvider;
const DICOMFileLoader = new (class extends FileLoader {
fileType = 'application/dicom';
@@ -12,9 +15,13 @@ const DICOMFileLoader = new (class extends FileLoader {
let dataset = {};
try {
const dicomData = dcmjs.data.DicomMessage.readFile(image);
dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(
dicomData.dict
);
metadataProvider.addInstance(dataset);
dataset._meta = dcmjs.data.DicomMetaDictionary.namifyDataset(
dicomData.meta
);
@@ -44,145 +51,45 @@ const DICOMFileLoader = new (class extends FileLoader {
PatientSex,
StudyID,
StudyDescription,
/*
NumberOfStudyRelatedSeries,
NumberOfStudyRelatedInstances,
Modality,
ModalitiesInStudy,
*/
SeriesInstanceUID,
SeriesDescription,
SeriesNumber,
SOPInstanceUID,
SOPClassUID,
Rows,
Columns,
NumberOfFrames,
InstanceNumber,
imageId,
Modality,
/*ImageType,
InstanceNumber,
ImagePositionPatient,
ImageOrientationPatient,
FrameOfReferenceUID,
SliceLocation,
SamplesPerPixel,
PhotometricInterpretation,
PlanarConfiguration,
PixelSpacing,
PixelAspectRatio,
BitsAllocated,
BitsStored,
HighBit,
PixelRepresentation,
SmallestPixelValue,
LargestPixelValue,
WindowCenter,
WindowWidth,
RescaleIntercept,
RescaleSlope,
RescaleType,
Laterality,
ViewPosition,
AcquisitionDateTime,
FrameIncrementPointer,
FrameTime,
FrameTimeVector,
SliceThickness,
SpacingBetweenSlices,
LossyImageCompression,
DerivationDescription,
LossyImageCompressionRatio,
LossyImageCompressionMethod,
EchoNumber,
ContrastBolusAgent,
*/
} = dataset;
const instance = {
sopInstanceUid: SOPInstanceUID,
sopClassUid: SOPClassUID,
rows: Rows,
columns: Columns,
numberOfFrames: NumberOfFrames,
instanceNumber: InstanceNumber,
metadata: dataset,
url: imageId,
modality: Modality,
/*
TODO: in case necessary to uncoment this block, double check every property
imageType: ImageType || DICOMWeb.getString(dataset['00080008']),
instanceNumber: InstanceNumber || DICOMWeb.getNumber(dataset['00200013']),
imagePositionPatient: ImagePositionPatient || DICOMWeb.getString(dataset['00200032']),
imageOrientationPatient: ImageOrientationPatient || DICOMWeb.getString(dataset['00200037']),
frameOfReferenceUID: FrameOfReferenceUID || DICOMWeb.getString(dataset['00200052']),
sliceLocation: SliceLocation || DICOMWeb.getNumber(dataset['00201041']),
samplesPerPixel: SamplesPerPixel || DICOMWeb.getNumber(dataset['00280002']),
photometricInterpretation: PhotometricInterpretation || DICOMWeb.getString(dataset['00280004']),
planarConfiguration: PlanarConfiguration || DICOMWeb.getNumber(dataset['00280006']),
pixelSpacing: PixelSpacing || DICOMWeb.getString(dataset['00280030']),
pixelAspectRatio: PixelAspectRatio || DICOMWeb.getString(dataset['00280034']),
bitsAllocated: BitsAllocated || DICOMWeb.getNumber(dataset['00280100']),
bitsStored: BitsStored || DICOMWeb.getNumber(dataset['00280101']),
highBit: HighBit || DICOMWeb.getNumber(dataset['00280102']),
pixelRepresentation: PixelRepresentation || DICOMWeb.getNumber(dataset['00280103']),
smallestPixelValue: SmallestPixelValue || DICOMWeb.getNumber(dataset['00280106']),
largestPixelValue: LargestPixelValue || DICOMWeb.getNumber(dataset['00280107']),
windowCenter: WindowCenter || DICOMWeb.getString(dataset['00281050']),
windowWidth: WindowWidth || DICOMWeb.getString(dataset['00281051']),
rescaleIntercept: RescaleIntercept || DICOMWeb.getNumber(dataset['00281052']),
rescaleSlope: RescaleSlope || DICOMWeb.getNumber(dataset['00281053']),
rescaleType: RescaleType || DICOMWeb.getNumber(dataset['00281054']),
sourceImageInstanceUid: getSourceImageInstanceUid(dataset),
laterality: Laterality || DICOMWeb.getString(dataset['00200062']),
viewPosition: ViewPosition || DICOMWeb.getString(dataset['00185101']),
acquisitionDateTime: AcquisitionDateTime || DICOMWeb.getString(dataset['0008002A']),
frameIncrementPointer: FrameIncrementPointer || getFrameIncrementPointer(dataset['00280009']),
frameTime: FrameTime || DICOMWeb.getNumber(dataset['00181063']),
frameTimeVector: FrameTimeVector || parseFloatArray(
DICOMWeb.getString(dataset['00181065'])
),
sliceThickness: SliceThickness || DICOMWeb.getNumber(dataset['00180050']),
spacingBetweenSlices: SpacingBetweenSlices || DICOMWeb.getString(dataset['00180088']),
lossyImageCompression: LossyImageCompression || DICOMWeb.getString(dataset['00282110']),
derivationDescription: DerivationDescription || DICOMWeb.getString(dataset['00282111']),
lossyImageCompressionRatio: LossyImageCompressionRatio || DICOMWeb.getString(dataset['00282112']),
lossyImageCompressionMethod: LossyImageCompressionMethod || DICOMWeb.getString(dataset['00282114']),
echoNumber: EchoNumber || DICOMWeb.getString(dataset['00180086']),
contrastBolusAgent: ContrastBolusAgent || DICOMWeb.getString(dataset['00180010']),
radiopharmaceuticalInfo: getRadiopharmaceuticalInfo(dataset),
wadouri: WADOProxy.convertURL(wadouri, server),
wadorsuri: WADOProxy.convertURL(wadorsuri, server),*/
};
const series = {
seriesInstanceUid: SeriesInstanceUID,
seriesDescription: SeriesDescription,
seriesNumber: SeriesNumber,
SeriesInstanceUID: SeriesInstanceUID,
SeriesDescription: SeriesDescription,
SeriesNumber: SeriesNumber,
instances: [instance],
};
const study = {
studyInstanceUid: StudyInstanceUID,
studyDate: StudyDate,
studyTime: StudyTime,
accessionNumber: AccessionNumber,
referringPhysicianName: ReferringPhysicianName,
patientName: PatientName,
patientId: PatientID,
patientBirthdate: PatientBirthDate,
patientSex: PatientSex,
studyId: StudyID,
studyDescription: StudyDescription,
StudyInstanceUID,
StudyDate,
StudyTime,
AccessionNumber,
ReferringPhysicianName,
PatientName,
PatientID,
PatientBirthDate,
PatientSex,
StudyID,
StudyDescription,
/*
TODO: in case necessary to uncomment this block, double check every property
numberOfStudyRelatedSeries: NumberOfStudyRelatedSeries || DICOMWeb.getString(dataset['00201206']),
numberOfStudyRelatedInstances: NumberOfStudyRelatedInstances || DICOMWeb.getString(dataset['00201208']),
modality: Modality || DICOMWeb.getString(dataset['00080060']),
modalitiesInStudy: ModalitiesInStudy || DICOMWeb.getString(dataset['00080061']),
Modality: Modality || DICOMWeb.getString(dataset['00080060']),
ModalitiesInStudy: ModalitiesInStudy || DICOMWeb.getString(dataset['00080061']),
modalities:
*/
seriesList: [series],
series: [series],
};
return study;
@@ -36,16 +36,16 @@ class FileLoaderService extends FileLoader {
};
const studiesGrouped = Object.values(
groupBy(studies, 'studyInstanceUid', 'seriesList')
groupBy(studies, 'StudyInstanceUID', 'series')
);
const result = studiesGrouped.map(studyGroup => {
const seriesGrouped = groupBy(
studyGroup.seriesList,
'seriesInstanceUid',
studyGroup.series,
'SeriesInstanceUID',
'instances'
);
studyGroup.seriesList = Object.values(seriesGrouped);
studyGroup.series = Object.values(seriesGrouped);
return studyGroup;
});
@@ -19,30 +19,32 @@ const PDFFileLoader = new (class extends FileLoader {
getDefaultStudy(imageId) {
const study = {
studyInstanceUid: '',
studyDate: '',
studyTime: '',
accessionNumber: '',
referringPhysicianName: '',
patientName: '',
patientId: '',
patientBirthdate: '',
patientSex: '',
studyId: '',
studyDescription: '',
seriesList: [
StudyInstanceUID: '',
StudyDate: '',
StudyTime: '',
AccessionNumber: '',
ReferringPhysicianName: '',
PatientName: '',
PatientID: '',
PatientBirthdate: '',
PatientSex: '',
StudyId: '',
StudyDescription: '',
series: [
{
seriesInstanceUid: '',
seriesDescription: '',
seriesNumber: '',
SeriesInstanceUID: '',
SeriesDescription: '',
SeriesNumber: '',
instances: [
{
sopInstanceUid: '',
sopClassUid: '1.2.840.10008.5.1.4.1.1.104.1',
rows: '',
columns: '',
numberOfFrames: 0,
instanceNumber: 1,
metadata: {
SOPInstanceUID: '',
SOPClassUID: '1.2.840.10008.5.1.4.1.1.104.1',
Rows: '',
Columns: '',
NumberOfFrames: 0,
InstanceNumber: 1,
},
getImageId: () => imageId,
isLocalFile: true,
},
@@ -16,20 +16,20 @@ function IHEInvokeImageDisplay({ location }) {
case 'STUDY':
return (
<ConnectedViewerRetrieveStudyData
studyInstanceUids={studyUID.split(';')}
studyInstanceUIDs={studyUID.split(';')}
/>
);
case 'STUDYBASE64':
return (
<ConnectedViewerRetrieveStudyData
studyInstanceUids={UrlUtil.paramString.parseParam(studyUID)}
studyInstanceUIDs={UrlUtil.paramString.parseParam(studyUID)}
/>
);
case 'PATIENT':
// TODO: connect this to the StudyList when we have the filter parameters set up
// return <StudyList patientUids={patientID.split(';')} />;
// return <StudyList patientUIDs={patientID.split(';')} />;
return '';
default:
+62 -31
View File
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { log, metadata, utils } from '@ohif/core';
import OHIF from '@ohif/core';
import PropTypes from 'prop-types';
import qs from 'querystring';
@@ -8,15 +8,16 @@ import ConnectedViewer from '../connectedComponents/ConnectedViewer';
import ConnectedViewerRetrieveStudyData from '../connectedComponents/ConnectedViewerRetrieveStudyData';
import NotFound from '../routes/NotFound';
const { studyMetadataManager, updateMetaDataManager } = utils;
const { log, metadata, utils } = OHIF;
const { studyMetadataManager } = utils;
const { OHIFStudyMetadata } = metadata;
class StandaloneRouting extends Component {
state = {
studies: null,
server: null,
studyInstanceUids: null,
seriesInstanceUids: null,
studyInstanceUIDs: null,
seriesInstanceUIDs: null,
error: null,
loading: true,
};
@@ -63,7 +64,7 @@ class StandaloneRouting extends Component {
const data = JSON.parse(oReq.responseText);
if (data.servers) {
if (!query.studyInstanceUids) {
if (!query.studyInstanceUIDs) {
log.warn('No study instance uids specified');
reject(new Error('No study instance uids specified'));
}
@@ -74,12 +75,41 @@ class StandaloneRouting extends Component {
log.warn('Activating server', server);
this.props.activateServer(server);
const studyInstanceUids = query.studyInstanceUids.split(';');
const seriesInstanceUids = query.seriesInstanceUids ? query.seriesInstanceUids.split(';') : [];
const studyInstanceUIDs = query.studyInstanceUIDs.split(';');
const seriesInstanceUIDs = query.seriesInstanceUIDs
? query.seriesInstanceUIDs.split(';')
: [];
resolve({ server, studyInstanceUids, seriesInstanceUids });
resolve({ server, studyInstanceUIDs, seriesInstanceUIDs });
} else {
resolve({ studies: data.studies, studyInstanceUids: [] });
// Parse data here and add to metadata provider.
const metadataProvider = OHIF.cornerstone.metadataProvider;
let StudyInstanceUID;
let SeriesInstanceUID;
data.studies.forEach(study => {
StudyInstanceUID = study.StudyInstanceUID;
study.series.forEach(series => {
SeriesInstanceUID = series.SeriesInstanceUID;
series.instances.forEach(instance => {
const { url: imageId, metadata: naturalizedDicom } = instance;
// Add instance to metadata provider.
metadataProvider.addInstance(naturalizedDicom);
// Add imageId specific mapping to this data as the URL isn't necessarliy WADO-URI.
metadataProvider.addImageIdToUIDs(imageId, {
StudyInstanceUID,
SeriesInstanceUID,
SOPInstanceUID: naturalizedDicom.SOPInstanceUID,
});
});
});
});
resolve({ studies: data.studies, studyInstanceUIDs: [] });
}
});
@@ -106,24 +136,24 @@ class StandaloneRouting extends Component {
let {
server,
studies,
studyInstanceUids,
seriesInstanceUids,
studyInstanceUIDs,
seriesInstanceUIDs,
} = await this.parseQueryAndRetrieveDICOMWebData(query);
if (studies) {
const {
studies: updatedStudies,
studyInstanceUids: updatedStudiesInstanceUids,
studyInstanceUIDs: updatedStudiesInstanceUIDs,
} = _mapStudiesToNewFormat(studies);
studies = updatedStudies;
studyInstanceUids = updatedStudiesInstanceUids;
studyInstanceUIDs = updatedStudiesInstanceUIDs;
}
this.setState({
studies,
server,
studyInstanceUids,
seriesInstanceUids,
studyInstanceUIDs,
seriesInstanceUIDs,
loading: false,
});
} catch (error) {
@@ -132,7 +162,9 @@ class StandaloneRouting extends Component {
}
render() {
const message = this.state.error ? `Error: ${JSON.stringify(this.state.error)}` : 'Loading...';
const message = this.state.error
? `Error: ${JSON.stringify(this.state.error)}`
: 'Loading...';
if (this.state.error || this.state.loading) {
return <NotFound message={message} showGoBackButton={this.state.error} />;
}
@@ -140,12 +172,12 @@ class StandaloneRouting extends Component {
return this.state.studies ? (
<ConnectedViewer studies={this.state.studies} />
) : (
<ConnectedViewerRetrieveStudyData
studyInstanceUids={this.state.studyInstanceUids}
seriesInstanceUids={this.state.seriesInstanceUids}
server={this.state.server}
/>
);
<ConnectedViewerRetrieveStudyData
studyInstanceUIDs={this.state.studyInstanceUIDs}
seriesInstanceUIDs={this.state.seriesInstanceUIDs}
server={this.state.server}
/>
);
}
}
@@ -153,27 +185,26 @@ const _mapStudiesToNewFormat = studies => {
studyMetadataManager.purge();
/* Map studies to new format, update metadata manager? */
const uniqueStudyUids = new Set();
const uniqueStudyUIDs = new Set();
const updatedStudies = studies.map(study => {
const studyMetadata = new OHIFStudyMetadata(study, study.studyInstanceUid);
const studyMetadata = new OHIFStudyMetadata(study, study.StudyInstanceUID);
const sopClassHandlerModules = extensionManager.modules['sopClassHandlerModule'];
study.displaySets = study.displaySets ||
const sopClassHandlerModules =
extensionManager.modules['sopClassHandlerModule'];
study.displaySets =
study.displaySets ||
studyMetadata.createDisplaySets(sopClassHandlerModules);
studyMetadata.setDisplaySets(study.displaySets);
/* Updates WADO-RS metaDataManager */
updateMetaDataManager(study);
studyMetadataManager.add(studyMetadata);
uniqueStudyUids.add(study.studyInstanceUid);
uniqueStudyUIDs.add(study.StudyInstanceUID);
return study;
});
return {
studies: updatedStudies,
studyInstanceUids: Array.from(uniqueStudyUids),
studyInstanceUIDs: Array.from(uniqueStudyUIDs),
};
};
+13 -13
View File
@@ -7,15 +7,15 @@ const { urlUtil: UrlUtil } = OHIF.utils;
/**
* Get array of seriesUIDs from param or from queryString
* @param {*} seriesInstanceUids
* @param {*} seriesInstanceUIDs
* @param {*} location
*/
const getSeriesInstanceUIDs = (seriesInstanceUids, routeLocation) => {
const getSeriesInstanceUIDs = (seriesInstanceUIDs, routeLocation) => {
const queryFilters = UrlUtil.queryString.getQueryFilters(routeLocation);
const querySeriesUIDs = queryFilters && queryFilters['seriesInstanceUID'];
const _seriesInstanceUids = seriesInstanceUids || querySeriesUIDs;
const _seriesInstanceUIDs = seriesInstanceUIDs || querySeriesUIDs;
return UrlUtil.paramString.parseParam(_seriesInstanceUids);
return UrlUtil.paramString.parseParam(_seriesInstanceUIDs);
};
function ViewerRouting({ match: routeMatch, location: routeLocation }) {
@@ -24,19 +24,19 @@ function ViewerRouting({ match: routeMatch, location: routeLocation }) {
location,
dataset,
dicomStore,
studyInstanceUids,
seriesInstanceUids,
studyInstanceUIDs,
seriesInstanceUIDs,
} = routeMatch.params;
const server = useServer({ project, location, dataset, dicomStore });
const studyUids = UrlUtil.paramString.parseParam(studyInstanceUids);
const seriesUids = getSeriesInstanceUIDs(seriesInstanceUids, routeLocation);
const studyUIDs = UrlUtil.paramString.parseParam(studyInstanceUIDs);
const seriesUIDs = getSeriesInstanceUIDs(seriesInstanceUIDs, routeLocation);
if (server && studyUids) {
if (server && studyUIDs) {
return (
<ConnectedViewerRetrieveStudyData
studyInstanceUids={studyUids}
seriesInstanceUids={seriesUids}
studyInstanceUIDs={studyUIDs}
seriesInstanceUIDs={seriesUIDs}
/>
);
}
@@ -47,8 +47,8 @@ function ViewerRouting({ match: routeMatch, location: routeLocation }) {
ViewerRouting.propTypes = {
match: PropTypes.shape({
params: PropTypes.shape({
studyInstanceUids: PropTypes.string.isRequired,
seriesInstanceUids: PropTypes.string,
studyInstanceUIDs: PropTypes.string.isRequired,
seriesInstanceUIDs: PropTypes.string,
dataset: PropTypes.string,
dicomStore: PropTypes.string,
location: PropTypes.string,
+2 -2
View File
@@ -32,7 +32,7 @@ const reload = () => window.location.reload();
const ROUTES_DEF = {
default: {
viewer: {
path: '/viewer/:studyInstanceUids',
path: '/viewer/:studyInstanceUIDs',
component: ViewerRouting,
},
standaloneViewer: {
@@ -59,7 +59,7 @@ const ROUTES_DEF = {
gcloud: {
viewer: {
path:
'/projects/:project/locations/:location/datasets/:dataset/dicomStores/:dicomStore/study/:studyInstanceUids',
'/projects/:project/locations/:location/datasets/:dataset/dicomStores/:dicomStore/study/:studyInstanceUIDs',
component: ViewerRouting,
condition: appConfig => {
return !!appConfig.enableGoogleCloudAdapter;
+47 -47
View File
@@ -29,18 +29,18 @@ function StudyListRoute(props) {
const [t] = useTranslation('Common');
// ~~ STATE
const [sort, setSort] = useState({
fieldName: 'patientName',
fieldName: 'PatientName',
direction: 'desc',
});
const [filterValues, setFilterValues] = useState({
studyDateTo: null,
studyDateFrom: null,
patientName: '',
patientId: '',
accessionNumber: '',
studyDate: '',
PatientName: '',
PatientID: '',
AccessionNumber: '',
StudyDate: '',
modalities: '',
studyDescription: '',
StudyDescription: '',
//
patientNameOrId: '',
accessionOrModalityOrDescription: '',
@@ -251,7 +251,7 @@ function StudyListRoute(props) {
studies={studies}
onSelectItem={studyInstanceUID => {
const viewerPath = RoutesUtil.parseViewerPath(appConfig, server, {
studyInstanceUids: studyInstanceUID,
studyInstanceUIDs: studyInstanceUID,
});
history.push(viewerPath);
}}
@@ -268,7 +268,7 @@ function StudyListRoute(props) {
currentPage={pageNumber}
nextPageFunc={() => setPageNumber(pageNumber + 1)}
prevPageFunc={() => setPageNumber(pageNumber - 1)}
onRowsPerPageChange={rows => setRowsPerPage(rows)}
onRowsPerPageChange={Rows => setRowsPerPage(Rows)}
rowsPerPage={rowsPerPage}
recordCount={studies.length}
/>
@@ -279,7 +279,7 @@ function StudyListRoute(props) {
StudyListRoute.propTypes = {
filters: PropTypes.object,
patientId: PropTypes.string,
PatientID: PropTypes.string,
server: PropTypes.object,
user: PropTypes.object,
history: PropTypes.object,
@@ -332,7 +332,7 @@ async function getStudyList(
patientNameOrId,
accessionOrModalityOrDescription,
} = filters;
const sortFieldName = sort.fieldName || 'patientName';
const sortFieldName = sort.fieldName || 'PatientName';
const sortDirection = sort.direction || 'desc';
const studyDateFrom =
filters.studyDateFrom ||
@@ -342,11 +342,11 @@ async function getStudyList(
const studyDateTo = filters.studyDateTo || new Date();
const mappedFilters = {
patientId: filters.patientId,
patientName: filters.patientName,
accessionNumber: filters.accessionNumber,
studyDescription: filters.studyDescription,
modalitiesInStudy: filters.modalities,
PatientID: filters.PatientID,
PatientName: filters.PatientName,
AccessionNumber: filters.AccessionNumber,
StudyDescription: filters.StudyDescription,
ModalitiesInStudy: filters.modalities,
// NEVER CHANGE
studyDateFrom,
studyDateTo,
@@ -363,32 +363,32 @@ async function getStudyList(
// Only the fields we use
const mappedStudies = studies.map(study => {
const patientName =
typeof study.patientName === 'string' ? study.patientName : undefined;
const PatientName =
typeof study.PatientName === 'string' ? study.PatientName : undefined;
return {
accessionNumber: study.accessionNumber, // "1"
AccessionNumber: study.AccessionNumber, // "1"
modalities: study.modalities, // "SEG\\MR" ​​
// numberOfStudyRelatedInstances: "3"
// numberOfStudyRelatedSeries: "3"
// patientBirthdate: undefined
patientId: study.patientId, // "NOID"
patientName, // "NAME^NONE"
// patientSex: "M"
// PatientBirthdate: undefined
PatientID: study.PatientID, // "NOID"
PatientName, // "NAME^NONE"
// PatientSex: "M"
// referringPhysicianName: undefined
studyDate: study.studyDate, // "Jun 28, 2002"
studyDescription: study.studyDescription, // "BRAIN"
StudyDate: study.StudyDate, // "Jun 28, 2002"
StudyDescription: study.StudyDescription, // "BRAIN"
// studyId: "No Study ID"
studyInstanceUid: study.studyInstanceUid, // "1.3.6.1.4.1.5962.99.1.3814087073.479799962.1489872804257.3.0"
// studyTime: "160956.0"
StudyInstanceUID: study.StudyInstanceUID, // "1.3.6.1.4.1.5962.99.1.3814087073.479799962.1489872804257.3.0"
// StudyTime: "160956.0"
};
});
// For our smaller displays, map our field name to a single
// field we can actually sort by.
const sortFieldNameMapping = {
allFields: 'patientName',
patientNameOrId: 'patientName',
allFields: 'PatientName',
patientNameOrId: 'PatientName',
accessionOrModalityOrDescription: 'modalities',
};
const mappedSortFieldName =
@@ -401,7 +401,7 @@ async function getStudyList(
);
// Because we've merged multiple requests, we may have more than
// our rows per page. Let's `take` that number from our sorted array.
// our Rows per page. Let's `take` that number from our sorted array.
// This "might" cause paging issues.
const numToTake =
sortedStudies.length < rowsPerPage ? sortedStudies.length : rowsPerPage;
@@ -414,16 +414,16 @@ async function getStudyList(
*
*
* @param {object[]} studies - Array of studies to sort
* @param {string} studies.studyDate - Date in 'MMM DD, YYYY' format
* @param {string} studies.StudyDate - Date in 'MMM DD, YYYY' format
* @param {string} field - name of properties on study to sort by
* @param {string} order - 'asc' or 'desc'
* @returns
*/
function _sortStudies(studies, field, order) {
// Make sure our studyDate is in a valid format and create copy of studies array
// Make sure our StudyDate is in a valid format and create copy of studies array
const sortedStudies = studies.map(study => {
if (!moment(study.studyDate, 'MMM DD, YYYY', true).isValid()) {
study.studyDate = moment(study.studyDate, 'YYYYMMDD').format(
if (!moment(study.StudyDate, 'MMM DD, YYYY', true).isValid()) {
study.StudyDate = moment(study.StudyDate, 'YYYYMMDD').format(
'MMM DD, YYYY'
);
}
@@ -434,7 +434,7 @@ function _sortStudies(studies, field, order) {
sortedStudies.sort(function(a, b) {
let fieldA = a[field];
let fieldB = b[field];
if (field === 'studyDate') {
if (field === 'StudyDate') {
fieldA = moment(fieldA).toISOString();
fieldB = moment(fieldB).toISOString();
}
@@ -486,11 +486,11 @@ async function _fetchStudies(
const firstSet = _getQueryFiltersForValue(
filters,
[
'patientId',
'patientName',
'accessionNumber',
'studyDescription',
'modalitiesInStudy',
'PatientID',
'PatientName',
'AccessionNumber',
'StudyDescription',
'ModalitiesInStudy',
],
allFields
);
@@ -501,13 +501,13 @@ async function _fetchStudies(
} else if (displaySize === 'medium') {
const firstSet = _getQueryFiltersForValue(
filters,
['patientId', 'patientName'],
['PatientID', 'PatientName'],
patientNameOrId
);
const secondSet = _getQueryFiltersForValue(
filters,
['accessionNumber', 'studyDescription', 'modalitiesInStudy'],
['AccessionNumber', 'StudyDescription', 'ModalitiesInStudy'],
accessionOrModalityOrDescription
);
@@ -530,7 +530,7 @@ async function _fetchStudies(
lotsOfStudies.forEach(arrayOfStudies => {
if (arrayOfStudies) {
arrayOfStudies.forEach(study => {
if (!studies.some(s => s.studyInstanceUid === study.studyInstanceUid)) {
if (!studies.some(s => s.StudyInstanceUID === study.StudyInstanceUID)) {
studies.push(study);
}
});
@@ -557,11 +557,11 @@ function _getQueryFiltersForValue(filters, fields, value) {
fields.forEach(field => {
const filter = Object.assign(
{
patientId: '',
patientName: '',
accessionNumber: '',
studyDescription: '',
modalitiesInStudy: '',
PatientID: '',
PatientName: '',
AccessionNumber: '',
StudyDescription: '',
ModalitiesInStudy: '',
},
filters
);
@@ -15,8 +15,8 @@ function StudyListRouting({ match: routeMatch, location: routeLocation }) {
location,
dataset,
dicomStore,
studyInstanceUids,
seriesInstanceUids,
studyInstanceUIDs,
seriesInstanceUIDs,
} = routeMatch.params;
const server = useServer({ project, location, dataset, dicomStore });
const { appConfig = {} } = useContext(AppContext);