Allowing loading prior timepoints without the need of baseline data
This commit is contained in:
parent
84bcffe860
commit
823a422c26
@ -86,12 +86,12 @@ class MeasurementApi {
|
||||
|
||||
// Get the current location (if already defined)
|
||||
let location;
|
||||
const baselineTimepoint = timepointApi.baseline();
|
||||
const baselineGroupEntry = groupCollection.findOne({
|
||||
timepointId: baselineTimepoint.timepointId
|
||||
const previousTimepoint = timepointApi.priorOrBaseline();
|
||||
const previousGroupEntry = groupCollection.findOne({
|
||||
timepointId: previousTimepoint.timepointId
|
||||
});
|
||||
if (baselineGroupEntry) {
|
||||
const tool = this.tools[baselineGroupEntry.toolId];
|
||||
if (previousGroupEntry) {
|
||||
const tool = this.tools[previousGroupEntry.toolId];
|
||||
const found = tool.findOne({ measurementNumber });
|
||||
if (found) {
|
||||
location = found.location;
|
||||
@ -273,7 +273,7 @@ class MeasurementApi {
|
||||
});
|
||||
}
|
||||
|
||||
sortMeasurements(baselineTimepointId) {
|
||||
sortMeasurements() {
|
||||
const tools = configuration.measurementTools;
|
||||
|
||||
const includedTools = tools.filter(tool => {
|
||||
|
||||
@ -167,6 +167,11 @@ class TimepointApi {
|
||||
});
|
||||
}
|
||||
|
||||
// Return the prior timepoint or baseline if not found
|
||||
priorOrBaseline() {
|
||||
return this.prior() || this.baseline();
|
||||
}
|
||||
|
||||
// Return only the current and prior Timepoints
|
||||
currentAndPrior() {
|
||||
const timepoints = [];
|
||||
|
||||
@ -83,8 +83,8 @@ Template.measurementTableRow.events({
|
||||
measurementApi.deleteMeasurements(measurementTypeId, { measurementNumber });
|
||||
|
||||
// Sync the new measurement data with cornerstone tools
|
||||
const baseline = timepointApi.baseline();
|
||||
measurementApi.sortMeasurements(baseline.timepointId);
|
||||
const previous = timepointApi.priorOrBaseline();
|
||||
measurementApi.sortMeasurements(previous.timepointId);
|
||||
|
||||
// Repaint the images on all viewports without the removed measurements
|
||||
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
||||
|
||||
@ -111,8 +111,8 @@ Template.measurementTableTimepointCell.events({
|
||||
});
|
||||
|
||||
// Sync the new measurement data with cornerstone tools
|
||||
const baseline = timepointApi.baseline();
|
||||
measurementApi.sortMeasurements(baseline.timepointId);
|
||||
const previous = timepointApi.priorOrBaseline();
|
||||
measurementApi.sortMeasurements(previous.timepointId);
|
||||
|
||||
// Repaint the images on all viewports without the removed measurements
|
||||
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
||||
|
||||
@ -55,27 +55,26 @@ Template.measurementTableView.helpers({
|
||||
newMeasurements(toolGroup) {
|
||||
const { measurementApi, timepointApi } = Template.instance().data;
|
||||
const current = timepointApi.current();
|
||||
const baseline = timepointApi.baseline();
|
||||
const previous = timepointApi.priorOrBaseline();
|
||||
|
||||
if (!measurementApi || !timepointApi || !current || !baseline) return;
|
||||
if (!measurementApi || !timepointApi || !current || !previous) return;
|
||||
|
||||
// If this is a baseline, stop here since there are no new measurements to display
|
||||
|
||||
if (!current || current.timepointType === 'baseline') {
|
||||
OHIF.log.info('Skipping New Measurements section');
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve all the data for this Measurement type (e.g. 'targets')
|
||||
// which was recorded at baseline.
|
||||
// which was recorded at previous timepoint.
|
||||
const measurementTypeId = toolGroup.measurementTypeId;
|
||||
const atBaseline = measurementApi.fetch(measurementTypeId, {
|
||||
timepointId: baseline.timepointId
|
||||
const atPrevious = measurementApi.fetch(measurementTypeId, {
|
||||
timepointId: previous.timepointId
|
||||
});
|
||||
|
||||
// Obtain a list of the Measurement Numbers from the
|
||||
// measurements which have baseline data
|
||||
const numbers = atBaseline.map(m => m.measurementNumber);
|
||||
// measurements which have previous timepoint's data
|
||||
const numbers = atPrevious.map(m => m.measurementNumber);
|
||||
|
||||
// Retrieve all the data for this Measurement type which
|
||||
// do NOT match the Measurement Numbers obtained above
|
||||
|
||||
@ -26,6 +26,7 @@ export class BaseCriterion {
|
||||
if (options.newTarget) {
|
||||
_.each(data.targets, target => {
|
||||
const { measurementNumber } = target.measurement;
|
||||
// FIXME we might not have the baseline timepoint
|
||||
if (target.timepoint.timepointType === 'baseline') {
|
||||
baselineMeasurementNumbers.push(measurementNumber);
|
||||
}
|
||||
|
||||
@ -139,8 +139,8 @@ class MeasurementHandlers {
|
||||
});
|
||||
|
||||
// Sync the new measurement data with cornerstone tools
|
||||
const baseline = timepointApi.baseline();
|
||||
measurementApi.sortMeasurements(baseline.timepointId);
|
||||
const previous = timepointApi.priorOrBaseline();
|
||||
measurementApi.sortMeasurements(previous.timepointId);
|
||||
|
||||
// Repaint the images on all viewports without the removed measurements
|
||||
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
|
||||
|
||||
@ -40,22 +40,22 @@ OHIF.measurements.getMeasurementsGroupedByNumber = (measurementApi, timepointApi
|
||||
// Create the result object
|
||||
const groupedMeasurements = [];
|
||||
|
||||
const baseline = timepointApi.baseline();
|
||||
if (!baseline) return;
|
||||
const previous = timepointApi.priorOrBaseline();
|
||||
if (!previous) return;
|
||||
|
||||
configuration.measurementTools.forEach(toolGroup => {
|
||||
// Skip this tool group if it should not be displayed
|
||||
if (!displayToolGroupMap[toolGroup.id]) return;
|
||||
|
||||
// Retrieve all the data for this Measurement type (e.g. 'targets')
|
||||
// which was recorded at baseline.
|
||||
const atBaseline = measurementApi.fetch(toolGroup.id, {
|
||||
timepointId: baseline.timepointId
|
||||
// which was recorded at previous timepoint.
|
||||
const atPrevious = measurementApi.fetch(toolGroup.id, {
|
||||
timepointId: previous.timepointId
|
||||
});
|
||||
|
||||
// Obtain a list of the Measurement Numbers from the
|
||||
// measurements which have baseline data
|
||||
const numbers = atBaseline.map(m => m.measurementNumber);
|
||||
// measurements which have previous timepoint's data
|
||||
const numbers = atPrevious.map(m => m.measurementNumber);
|
||||
|
||||
// Retrieve all the data for this Measurement type which
|
||||
// match the Measurement Numbers obtained above
|
||||
|
||||
@ -25,10 +25,38 @@ const getTimepointType = study => {
|
||||
return timepoint[0].timepointType;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the timpoint key (prior/current/baseline) for a given study metadata
|
||||
* @param {StudyMetadata} study StudyMetadata instance
|
||||
* @return {String|undefined} Timepoint key if found or undefined if not found or any error/missing information
|
||||
*/
|
||||
const getTimepointKey = study => {
|
||||
const { timepointApi } = OHIF.viewer;
|
||||
|
||||
if (!timepointApi || !(study instanceof InstanceMetadata || study instanceof StudySummary)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const timepoint = timepointApi.study(study.getStudyInstanceUID());
|
||||
if (!timepoint || !(timepoint instanceof Array) || timepoint.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const timepointId = timepoint[0]._id;
|
||||
if (timepointApi.current()._id === timepointId) {
|
||||
return 'current';
|
||||
} else if (timepointApi.prior()._id === timepointId) {
|
||||
return 'prior';
|
||||
} else if (timepointApi.baseline()._id === timepointId) {
|
||||
return 'baseline';
|
||||
}
|
||||
};
|
||||
|
||||
Meteor.startup(() => {
|
||||
HP = HP || false;
|
||||
|
||||
if (HP) {
|
||||
HP.addCustomAttribute('timepointType', 'Timepoint Type', getTimepointType);
|
||||
HP.addCustomAttribute('timepointKey', 'Timepoint Key', getTimepointKey);
|
||||
}
|
||||
});
|
||||
|
||||
@ -89,12 +89,11 @@ const getDataFromTimepoint = timepoint => {
|
||||
};
|
||||
}
|
||||
|
||||
// Otherwise, this is a follow-up exam, so we should also find the baseline timepoint,
|
||||
// and all studies related to it. We also enforce that the Baseline should have a studyDate
|
||||
// Otherwise, this is a follow-up exam, so we should also find the prior timepoint,
|
||||
// and all studies related to it. We also enforce that the Prior should have a studyDate
|
||||
// prior to the latest studyDate in the current (Follow-up) Timepoint.
|
||||
const Timepoints = OHIF.studylist.timepointApi.timepoints;
|
||||
const baseline = Timepoints.findOne({
|
||||
timepointType: 'baseline',
|
||||
const priorTimepoint = Timepoints.findOne({
|
||||
patientId: timepoint.patientId,
|
||||
latestDate: {
|
||||
$lte: timepoint.latestDate
|
||||
@ -102,11 +101,11 @@ const getDataFromTimepoint = timepoint => {
|
||||
});
|
||||
|
||||
let timepointIds = [];
|
||||
if (baseline) {
|
||||
relatedStudies = relatedStudies.concat(baseline.studyInstanceUids);
|
||||
timepointIds.push(baseline.timepointId);
|
||||
if (priorTimepoint) {
|
||||
relatedStudies = relatedStudies.concat(priorTimepoint.studyInstanceUids);
|
||||
timepointIds.push(priorTimepoint.timepointId);
|
||||
} else {
|
||||
OHIF.log.warn('No Baseline found while opening a Follow-up Timepoint');
|
||||
OHIF.log.warn('No prior Timepoint found while opening a Follow-up Timepoint');
|
||||
}
|
||||
|
||||
timepointIds.push(timepoint.timepointId);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user