Most JS files, all helpers and simple reconciliations

This commit is contained in:
Emanuel F. Oliveira committed 2017-01-29 22:11:17 -02:00
1 parent 21400c5836
commit 9e69c43dda
58 files changed
+776 -1025

No files matched your search

@@ -1,28 +1,86 @@
import { Meteor } from 'meteor/meteor';
import { OHIF } from 'meteor/ohif:core';
import { viewportUtils } from './viewportUtils';
applyWLPreset = function(presetName, element) {
OHIF.log.info("Applying WL Preset: " + presetName);
var viewport = cornerstone.getViewport(element);
// TODO: add this to a namespace definition
Meteor.startup(function() {
OHIF.viewer.defaultWLPresets = {
SoftTissue: {
wc: 40,
ww: 400
},
Lung: {
wc: -600,
ww: 1500
},
Liver: {
wc: 90,
ww: 150
},
Bone: {
wc: 480,
ww: 2500
},
Brain: {
wc: 40,
ww: 80
}
};
if (presetName === 'Default') {
var enabledElement = cornerstone.getEnabledElement(element);
viewport.voi.windowWidth = enabledElement.image.windowWidth;
viewport.voi.windowCenter = enabledElement.image.windowCenter;
} else {
var preset = OHIF.viewer.wlPresets[presetName];
viewport.voi.windowWidth = preset.ww;
viewport.voi.windowCenter = preset.wc;
// For now
OHIF.viewer.wlPresets = OHIF.viewer.defaultWLPresets;
});
function applyWLPreset(presetName, element) {
OHIF.log.info('Applying WL Preset: ' + presetName);
if (presetName !== 'Custom') {
const viewport = cornerstone.getViewport(element);
if (presetName === 'Default') {
const enabledElement = cornerstone.getEnabledElement(element);
viewport.voi.windowWidth = enabledElement.image.windowWidth;
viewport.voi.windowCenter = enabledElement.image.windowCenter;
} else {
const preset = OHIF.viewer.wlPresets[presetName];
if(preset) {
viewport.voi.windowWidth = preset.ww;
viewport.voi.windowCenter = preset.wc;
}
}
// Update the viewport
cornerstone.setViewport(element, viewport);
}
}
// Update the viewport
cornerstone.setViewport(element, viewport);
};
applyWLPresetToActiveElement = function(presetName) {
var element = getActiveViewportElement();
function applyWLPresetToActiveElement(presetName) {
const element = viewportUtils.getActiveViewportElement();
if (!element) {
return;
}
applyWLPreset(presetName, element);
// To perform reactivity in other components
Session.set('WLPresetActiveElement', presetName);
}
/**
* Overrides OHIF's wlPresets
* @param {Object} wlPresets Object with wlPresets mapping
*/
function setOHIFWLPresets(wlPresets) {
OHIF.viewer.wlPresets = wlPresets;
}
/**
* Export functions inside WLPresets namespace.
*/
const WLPresets = {
applyWLPreset,
applyWLPresetToActiveElement,
setOHIFWLPresets
};
export { WLPresets };
@@ -1,3 +1,6 @@
import { ImageSet } from './classes/ImageSet';
import { isImage } from './isImage';
/**
* Creates a set of series to be placed in the Study Browser
* The series that appear in the Study Browser must represent
@@ -10,7 +13,7 @@
* @param study The study instance to be used
* @returns {Array} An array of series to be placed in the Study Browser
*/
createStacks = function(study) {
function createStacks(study) {
// Define an empty array of display sets
var displaySets = [];
@@ -38,33 +41,21 @@ createStacks = function(study) {
let displaySet;
if (isMultiFrame(instance)) {
displaySet = makeDisplaySet(series, [ instance ]);
displaySet.isClip = true;
// Include the study instance Uid for drag/drop purposes
displaySet.studyInstanceUid = study.studyInstanceUid;
// Override the default value of instances.length
displaySet.numImageFrames = instance.numFrames;
// Include the instance number
displaySet.instanceNumber = instance.instanceNumber;
// Include the acquisition datetime
displaySet.acquisitionDatetime = instance.acquisitionDatetime;
displaySet.setAttributes({
isClip: true,
studyInstanceUid: study.studyInstanceUid, // Include the study instance Uid for drag/drop purposes
numImageFrames: instance.numFrames, // Override the default value of instances.length
instanceNumber: instance.instanceNumber, // Include the instance number
acquisitionDatetime: instance.acquisitionDatetime // Include the acquisition datetime
});
displaySets.push(displaySet);
} else if (isSingleImageModality(instance.modality)) {
displaySet = makeDisplaySet(series, [ instance ]);
// Include the study instance Uid
displaySet.studyInstanceUid = study.studyInstanceUid;
// Include the instance number
displaySet.instanceNumber = instance.instanceNumber;
// Include the acquisition datetime
displaySet.acquisitionDatetime = instance.acquisitionDatetime;
displaySet.setAttributes({
studyInstanceUid: study.studyInstanceUid, // Include the study instance Uid
instanceNumber: instance.instanceNumber, // Include the instance number
acquisitionDatetime: instance.acquisitionDatetime // Include the acquisition datetime
});
displaySets.push(displaySet);
} else {
stackableInstances.push(instance);
@@ -73,7 +64,7 @@ createStacks = function(study) {
if (stackableInstances.length) {
let displaySet = makeDisplaySet(series, stackableInstances);
displaySet.studyInstanceUid = study.studyInstanceUid;
displaySet.setAttribute('studyInstanceUid', study.studyInstanceUid);
displaySets.push(displaySet);
}
});
@@ -84,32 +75,32 @@ createStacks = function(study) {
function makeDisplaySet(series, instances) {
const instance = instances[0];
let displaySet = {
const imageSet = new ImageSet(instances);
// set appropriate attributes to image set...
imageSet.setAttributes({
displaySetInstanceUid: imageSet.uid, // create a local alias for the imageSet UID
seriesInstanceUid: series.seriesInstanceUid,
seriesNumber: series.seriesNumber,
seriesDescription: series.seriesDescription,
numImageFrames: instances.length,
frameRate: instance.frameTime,
images: instances,
modality: series.modality,
isMultiFrame: isMultiFrame(instance)
};
});
// Sort the images in this series
displaySet.images.sort(function(a, b) {
imageSet.sortBy(function(a, b) {
if (a.instanceNumber && b.instanceNumber &&
a.instanceNumber !== b.instanceNumber) {
return a.instanceNumber - b.instanceNumber;
}
});
// Include the first image instance number
displaySet.instanceNumber = displaySet.images[0].instanceNumber;
// Include the first image instance number (after sorted)
imageSet.setAttribute('instanceNumber', imageSet.getImage(0).instanceNumber);
// Create a unique ID for this stack so we can reference it
displaySet.displaySetInstanceUid = Random.id();
return displaySet;
return imageSet;
}
function isSingleImageModality(modality) {
@@ -121,3 +112,9 @@ function isSingleImageModality(modality) {
function isMultiFrame(instance) {
return instance.numFrames > 1;
}
/**
* Expose "createStacks"...
*/
export { createStacks };
@@ -7,21 +7,30 @@ import { OHIF } from 'meteor/ohif:core';
*
* @param element {node} DOM Node representing the viewport element
*/
displayReferenceLines = element => {
OHIF.log.info("imageViewerViewport displayReferenceLines");
export function displayReferenceLines(element) {
// Check if image plane (orientation / loction) data is present for the current image
const enabledElement = cornerstone.getEnabledElement(element);
const imageId = enabledElement.image.imageId;
const imagePlane = cornerstoneTools.metaData.get('imagePlane', imageId);
if (!OHIF.viewer.refLinesEnabled || !imagePlane || !imagePlane.frameOfReferenceUID) {
// Check if element is already enabled and it's image was rendered
if(!enabledElement || !enabledElement.image) {
OHIF.log.info('displayReferenceLines enabled element is undefined or it\'s image is not rendered');
return;
}
const imageId = enabledElement.image.imageId;
const imagePlane = cornerstoneTools.metaData.get('imagePlane', imageId);
// Disable reference lines for the current element
cornerstoneTools.referenceLines.tool.disable(element);
if (!OHIF.viewer.refLinesEnabled || !imagePlane || !imagePlane.frameOfReferenceUID) {
OHIF.log.info('displayReferenceLines refLinesEnabled is not enabled, no imagePlane or no frameOfReferenceUID');
return;
}
OHIF.log.info(`displayReferenceLines for image with id: ${imageId}`);
// Loop through all other viewport elements and enable reference lines
$('.imageViewerViewport').not(element).each((index, viewportElement) => {
let imageId;
@@ -40,4 +49,4 @@ displayReferenceLines = element => {
cornerstoneTools.referenceLines.tool.enable(viewportElement, OHIF.viewer.updateImageSynchronizer);
}
});
};
}
@@ -1,4 +1,5 @@
import { Meteor } from "meteor/meteor";
import { getWADORSImageId } from './getWADORSImageId';
/**
* Obtain an imageId for Cornerstone from an image instance
@@ -6,17 +7,17 @@ import { Meteor } from "meteor/meteor";
* @param instance
* @returns {string} The imageId to be used by Cornerstone
*/
getImageId = function(instance, frame) {
export function getImageId(instance, frame) {
if (!instance) {
return;
}
if (instance.url) {
return instance.url;
return instance.url;
}
if (instance.wadouri) {
var imageId = 'dicomweb:' + Meteor.absoluteUrl(instance.wadouri); // WADO-URI;
var imageId = 'dicomweb:' + Meteor.absoluteUrl(instance.wadouri);
if (frame !== undefined) {
imageId += '&frame=' + frame;
}
@@ -26,4 +27,4 @@ getImageId = function(instance, frame) {
// TODO= Check multiframe image support with WADO-RS
return getWADORSImageId(instance); // WADO-RS Retrieve Frame
}
};
}
@@ -8,7 +8,7 @@ import { OHIF } from 'meteor/ohif:core';
* @returns {string} The imageId to be used by Cornerstone
*/
getWADORSImageId = function(instance) {
export function getWADORSImageId(instance) {
var columnPixelSpacing = 1.0;
var rowPixelSpacing = 1.0;
if (instance.pixelSpacing) {
@@ -1,3 +1,5 @@
import { Blaze } from 'meteor/blaze';
/**
* A global Blaze UI helper to capitalizes the first letter of an input String
*
@@ -5,10 +7,10 @@
*
* http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript
*/
UI.registerHelper('capitalizeFirstLetter', function (context) {
Blaze.registerHelper('capitalizeFirstLetter', function (context) {
if (!context) {
return;
}
return context.charAt(0).toUpperCase() + context.slice(1);
});
});
@@ -1,7 +1,11 @@
import { Blaze } from 'meteor/blaze';
import { moment } from 'meteor/momentjs:moment';
/**
* A global Blaze UI helper function to format DICOM Dates using the Moment library
*/
UI.registerHelper('formatDA', function (context, format, options) {
const formatDA = (context, format, options) => {
if (!context) {
return undefined;
}
@@ -11,4 +15,8 @@ UI.registerHelper('formatDA', function (context, format, options) {
strFormat = format;
}
return dateAsMoment.format(strFormat);
});
};
Blaze.registerHelper('formatDA', formatDA);
export { formatDA };
@@ -1,7 +1,10 @@
import { Blaze } from 'meteor/blaze';
import { moment } from 'meteor/momentjs:moment';
/**
* A global Blaze UI helper function to format JavaScript Dates using the Moment library
*/
UI.registerHelper('formatJSDate', function(context, format, options) {
Blaze.registerHelper('formatJSDate', function(context, format, options) {
if (!context) {
return;
}
@@ -1,8 +1,10 @@
import { Blaze } from 'meteor/blaze';
/**
* A global Blaze UI helper to format a float value to a specified precision
*/
UI.registerHelper('formatNumberPrecision', function(context, precision) {
Blaze.registerHelper('formatNumberPrecision', function(context, precision) {
if (context != null) {
return parseFloat(context).toFixed(precision);
}
});
});
@@ -1,7 +1,8 @@
import { Blaze } from 'meteor/blaze';
/**
* Formats a patient name for display purposes
*/
formatPN = function(context) {
const formatPN = context => {
if (!context) {
return;
}
@@ -11,4 +12,6 @@ formatPN = function(context) {
/**
* A global Blaze UI helper to format a patient name for display purposes
*/
UI.registerHelper('formatPN', formatPN);
Blaze.registerHelper('formatPN', formatPN);
export { formatPN };
@@ -1,7 +1,11 @@
import { Blaze } from 'meteor/blaze';
import { moment } from 'meteor/momentjs:moment';
/**
* A global Blaze UI helper to format a DICOM Time for display using the Moment library
*/
UI.registerHelper('formatTM', function(context, options) {
const formatTM = (context, options) => {
if (!context) {
return;
}
@@ -21,4 +25,8 @@ UI.registerHelper('formatTM', function(context, options) {
}
return dateTime.format(format);
});
};
Blaze.registerHelper('formatTM', formatTM);
export { formatTM };
@@ -1,7 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { Blaze } from 'meteor/blaze';
/**
* Helper for retrieving username given userId
*/
UI.registerHelper('getUsername', function(userId) {
Blaze.registerHelper('getUsername', function(userId) {
var user = Meteor.users.findOne({
userId: userId
});
@@ -1,7 +1,9 @@
import { Blaze } from 'meteor/blaze';
/**
* Helper for checking datatype of a variable
*/
UI.registerHelper('ifTypeIs', function(value, match, attributeName) {
Blaze.registerHelper('ifTypeIs', function(value, match, attributeName) {
if (typeof(value) === match) {
return attributeName;
}
@@ -1,3 +1,5 @@
UI.registerHelper('inc', function(value) {
import { Blaze } from 'meteor/blaze';
Blaze.registerHelper('inc', function(value) {
return parseInt(value) + 1;
});
@@ -1,3 +1,11 @@
import { Template } from 'meteor/templating';
import { Session } from 'meteor/session';
import { $ } from 'meteor/jquery';
import { viewportUtils } from '../viewportUtils';
import { OHIF } from 'meteor/ohif:core';
import 'meteor/ohif:viewerbase';
/**
* Boolean helper to identify if a series instance is active in some viewport
*/
@@ -6,7 +14,7 @@ Template.registerHelper('isDisplaySetActive', (displaySetInstanceUid, viewportIn
Session.get('LayoutManagerUpdated');
// Stop here if layoutManager is not defined yet
if (!window.layoutManager) {
if (!OHIF.viewerbase.layoutManager) {
return;
}
@@ -22,22 +30,28 @@ Template.registerHelper('isDisplaySetActive', (displaySetInstanceUid, viewportIn
if (_.isUndefined(viewportIndex)) {
// Get the number of viewports that are currently displayed
// (Note, viewportData may have more entries!)
const currentNumberOfViewports = layoutManager.getNumberOfViewports();
const currentNumberOfViewports = OHIF.viewerbase.layoutManager.getNumberOfViewports();
// Get active viewport element
const activeViewport = viewportUtils.getActiveViewportElement();
// Get viewports elements
const viewportsElement = $('.imageViewerViewport');
// Loop through the viewport data up until the currently displayed
// number of viewports
let viewportData = window.layoutManager.viewportData;
const viewportData = OHIF.viewerbase.layoutManager.viewportData;
for (let i = 0; i < currentNumberOfViewports; i++) {
const data = viewportData[i];
// If the display set is displayed in this viewport, stop here
if (data && data.displaySetInstanceUid === displaySetInstanceUid) {
// If the display set is displayed in this viewport and is active, stop here
if (data && data.displaySetInstanceUid === displaySetInstanceUid && viewportsElement.get(data.viewportIndex) === activeViewport) {
result = true;
break;
}
}
} else {
const data = window.layoutManager.viewportData[viewportIndex];
const data = OHIF.viewerbase.layoutManager.viewportData[viewportIndex];
// If the display set is displayed in this viewport, stop here
if (data && data.displaySetInstanceUid === displaySetInstanceUid) {
@@ -1,3 +1,5 @@
import { Blaze } from 'meteor/blaze';
/**
* Helper function to determine if the current client devices
* is touch-capable. This can be used to modify certain aspects of the UI.
@@ -6,7 +8,7 @@
*
* @returns {boolean} true if the client device is touch-capable, false otherwise
*/
isTouchDevice = function() {
const isTouchDevice = () => {
return (('ontouchstart' in window) ||
(navigator.MaxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0));
@@ -17,4 +19,6 @@ isTouchDevice = function() {
*
* @returns {boolean} true if the client device is touch-capable, false otherwise
*/
UI.registerHelper('isTouchDevice', isTouchDevice);
Blaze.registerHelper('isTouchDevice', isTouchDevice);
export { isTouchDevice };
@@ -1,7 +1,11 @@
import { Blaze } from 'meteor/blaze';
import { Session } from 'meteor/session';
import { moment } from 'meteor/momentjs:moment';
/**
* A global Blaze UI helper function to format JavaScript Dates using the Moment library
*/
UI.registerHelper('jsDateFromNow', function(context, format, options) {
Blaze.registerHelper('jsDateFromNow', function(context, format, options) {
if (!context) {
return;
}
@@ -1,4 +1,7 @@
UI.registerHelper('objectEach', function(object) {
import { Blaze } from 'meteor/blaze';
import { _ } from 'meteor/underscore';
Blaze.registerHelper('objectEach', function(object) {
// http://stackoverflow.com/questions/30234732/how-to-print-key-and-values-in-meteor-template
return _.map(object, function(value, key) {
return _.extend({key: key}, value);
@@ -1,4 +1,7 @@
UI.registerHelper('objectToPairs', function(object) {
import { Blaze } from 'meteor/blaze';
import { _ } from 'meteor/underscore';
Blaze.registerHelper('objectToPairs', function(object) {
// http://stackoverflow.com/questions/30234732/how-to-print-key-and-values-in-meteor-template
return _.map(object, function(value, key) {
return {
@@ -1,3 +1,5 @@
import { Blaze } from 'meteor/blaze';
/**
* A global Blaze UI helper to Stringify a JavaScript object
*
@@ -5,7 +7,7 @@
*
* http://stackoverflow.com/questions/1026069/capitalize-the-first-letter-of-string-in-javascript
*/
UI.registerHelper('prettyPrintStringify', function(context) {
Blaze.registerHelper('prettyPrintStringify', function(context) {
if (!context) {
return;
}
@@ -1,5 +1,5 @@
import { _ } from 'meteor/underscore';
import { Template } from 'meteor/templating';
import { _ } from 'meteor/underscore';
/**
* Global Blaze UI helper to sort array elements
@@ -54,4 +54,4 @@ function getKeyValue(object, keyPath) {
}
}
return object;
}
}
@@ -1,3 +1,6 @@
import { Template } from 'meteor/templating';
import { _ } from 'meteor/underscore';
/**
* A global Blaze UI helper to get the thumbnails for the given study
*/
@@ -1,6 +1,8 @@
var instanceClassViewportSettingsFunctions = {};
getInstanceClassDefaultViewport = function(series, enabledElement, imageId) {
var instanceClass = series.sopClassUid;
const instanceClassViewportSettingsFunctions = {};
const getInstanceClassDefaultViewport = (series, enabledElement, imageId) => {
let instanceClass = series.sopClassUid;
if (!instanceClassViewportSettingsFunctions[instanceClass]) {
return;
@@ -9,6 +11,8 @@ getInstanceClassDefaultViewport = function(series, enabledElement, imageId) {
return instanceClassViewportSettingsFunctions[instanceClass](series, enabledElement, imageId);
};
setInstanceClassDefaultViewportFunction = function(instanceClass, fn) {
const setInstanceClassDefaultViewportFunction = (instanceClass, fn) => {
instanceClassViewportSettingsFunctions[instanceClass] = fn;
};
};
export { getInstanceClassDefaultViewport, setInstanceClassDefaultViewportFunction };
+52 -50
View File
@@ -1,59 +1,61 @@
import { sopClassDictionary } from './sopClassDictionary';
/**
* Checks whether dicom files with specified SOP Class UID have image data
* @param {string} sopClassUid - SOP Class UID to be checked
* @returns {boolean} - true if it has image data
*/
isImage = function(sopClassUid) {
if (sopClassUid == sopClassDictionary.ComputedRadiographyImageStorage
|| sopClassUid == sopClassDictionary.DigitalXRayImageStorageForPresentation
|| sopClassUid == sopClassDictionary.DigitalXRayImageStorageForProcessing
|| sopClassUid == sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation
|| sopClassUid == sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing
|| sopClassUid == sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation
|| sopClassUid == sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing
|| sopClassUid == sopClassDictionary.CTImageStorage
|| sopClassUid == sopClassDictionary.EnhancedCTImageStorage
|| sopClassUid == sopClassDictionary.LegacyConvertedEnhancedCTImageStorage
|| sopClassUid == sopClassDictionary.UltrasoundMultiframeImageStorage
|| sopClassUid == sopClassDictionary.MRImageStorage
|| sopClassUid == sopClassDictionary.EnhancedMRImageStorage
|| sopClassUid == sopClassDictionary.EnhancedMRColorImageStorage
|| sopClassUid == sopClassDictionary.LegacyConvertedEnhancedMRImageStorage
|| sopClassUid == sopClassDictionary.UltrasoundImageStorage
|| sopClassUid == sopClassDictionary.SecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage
|| sopClassUid == sopClassDictionary.XRayAngiographicImageStorage
|| sopClassUid == sopClassDictionary.EnhancedXAImageStorage
|| sopClassUid == sopClassDictionary.XRayRadiofluoroscopicImageStorage
|| sopClassUid == sopClassDictionary.EnhancedXRFImageStorage
|| sopClassUid == sopClassDictionary.XRay3DAngiographicImageStorage
|| sopClassUid == sopClassDictionary.XRay3DCraniofacialImageStorage
|| sopClassUid == sopClassDictionary.BreastTomosynthesisImageStorage
|| sopClassUid == sopClassDictionary.BreastProjectionXRayImageStorageForPresentation
|| sopClassUid == sopClassDictionary.BreastProjectionXRayImageStorageForProcessing
|| sopClassUid == sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation
|| sopClassUid == sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing
|| sopClassUid == sopClassDictionary.NuclearMedicineImageStorage
|| sopClassUid == sopClassDictionary.VLEndoscopicImageStorage
|| sopClassUid == sopClassDictionary.VideoEndoscopicImageStorage
|| sopClassUid == sopClassDictionary.VLMicroscopicImageStorage
|| sopClassUid == sopClassDictionary.VideoMicroscopicImageStorage
|| sopClassUid == sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage
|| sopClassUid == sopClassDictionary.VLPhotographicImageStorage
|| sopClassUid == sopClassDictionary.VideoPhotographicImageStorage
|| sopClassUid == sopClassDictionary.OphthalmicPhotography8BitImageStorage
|| sopClassUid == sopClassDictionary.OphthalmicPhotography16BitImageStorage
|| sopClassUid == sopClassDictionary.OphthalmicTomographyImageStorage
|| sopClassUid == sopClassDictionary.VLWholeSlideMicroscopyImageStorage
|| sopClassUid == sopClassDictionary.PositronEmissionTomographyImageStorage
|| sopClassUid == sopClassDictionary.EnhancedPETImageStorage
|| sopClassUid == sopClassDictionary.LegacyConvertedEnhancedPETImageStorage
|| sopClassUid == sopClassDictionary.RTImageStorage) {
export function isImage(sopClassUid) {
if (sopClassUid === sopClassDictionary.ComputedRadiographyImageStorage
|| sopClassUid === sopClassDictionary.DigitalXRayImageStorageForPresentation
|| sopClassUid === sopClassDictionary.DigitalXRayImageStorageForProcessing
|| sopClassUid === sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation
|| sopClassUid === sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing
|| sopClassUid === sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation
|| sopClassUid === sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing
|| sopClassUid === sopClassDictionary.CTImageStorage
|| sopClassUid === sopClassDictionary.EnhancedCTImageStorage
|| sopClassUid === sopClassDictionary.LegacyConvertedEnhancedCTImageStorage
|| sopClassUid === sopClassDictionary.UltrasoundMultiframeImageStorage
|| sopClassUid === sopClassDictionary.MRImageStorage
|| sopClassUid === sopClassDictionary.EnhancedMRImageStorage
|| sopClassUid === sopClassDictionary.EnhancedMRColorImageStorage
|| sopClassUid === sopClassDictionary.LegacyConvertedEnhancedMRImageStorage
|| sopClassUid === sopClassDictionary.UltrasoundImageStorage
|| sopClassUid === sopClassDictionary.SecondaryCaptureImageStorage
|| sopClassUid === sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage
|| sopClassUid === sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage
|| sopClassUid === sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage
|| sopClassUid === sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage
|| sopClassUid === sopClassDictionary.XRayAngiographicImageStorage
|| sopClassUid === sopClassDictionary.EnhancedXAImageStorage
|| sopClassUid === sopClassDictionary.XRayRadiofluoroscopicImageStorage
|| sopClassUid === sopClassDictionary.EnhancedXRFImageStorage
|| sopClassUid === sopClassDictionary.XRay3DAngiographicImageStorage
|| sopClassUid === sopClassDictionary.XRay3DCraniofacialImageStorage
|| sopClassUid === sopClassDictionary.BreastTomosynthesisImageStorage
|| sopClassUid === sopClassDictionary.BreastProjectionXRayImageStorageForPresentation
|| sopClassUid === sopClassDictionary.BreastProjectionXRayImageStorageForProcessing
|| sopClassUid === sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation
|| sopClassUid === sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing
|| sopClassUid === sopClassDictionary.NuclearMedicineImageStorage
|| sopClassUid === sopClassDictionary.VLEndoscopicImageStorage
|| sopClassUid === sopClassDictionary.VideoEndoscopicImageStorage
|| sopClassUid === sopClassDictionary.VLMicroscopicImageStorage
|| sopClassUid === sopClassDictionary.VideoMicroscopicImageStorage
|| sopClassUid === sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage
|| sopClassUid === sopClassDictionary.VLPhotographicImageStorage
|| sopClassUid === sopClassDictionary.VideoPhotographicImageStorage
|| sopClassUid === sopClassDictionary.OphthalmicPhotography8BitImageStorage
|| sopClassUid === sopClassDictionary.OphthalmicPhotography16BitImageStorage
|| sopClassUid === sopClassDictionary.OphthalmicTomographyImageStorage
|| sopClassUid === sopClassDictionary.VLWholeSlideMicroscopyImageStorage
|| sopClassUid === sopClassDictionary.PositronEmissionTomographyImageStorage
|| sopClassUid === sopClassDictionary.EnhancedPETImageStorage
|| sopClassUid === sopClassDictionary.LegacyConvertedEnhancedPETImageStorage
|| sopClassUid === sopClassDictionary.RTImageStorage) {
return true;
}
return false;
};
}
@@ -1,6 +1,7 @@
import {parsingUtils} from './parsingUtils'
import { Meteor } from 'meteor/meteor';
import { parsingUtils } from './parsingUtils';
var metaDataLookup = {};
const metaDataLookup = {};
/**
* Cornerstone MetaData provider to store image meta data
@@ -14,14 +15,14 @@ var metaDataLookup = {};
* @param {String} imageId The Cornerstone ImageId
* @param {Object} data An object containing instance, series, and study metaData
*/
addMetaData = function(imageId, data) {
var instanceMetaData = data.instance;
var seriesMetaData = data.series;
var studyMetaData = data.study;
var imageIndex = data.imageIndex;
var numImages = data.numImages;
const addMetaData = (imageId, data) => {
let instanceMetaData = data.instance;
let seriesMetaData = data.series;
let studyMetaData = data.study;
let imageIndex = data.imageIndex;
let numImages = data.numImages;
var metaData = {};
let metaData = {};
metaData.study = {
patientId: studyMetaData.patientId,
@@ -66,8 +67,8 @@ addMetaData = function(imageId, data) {
* @param type (e.g. series, instance, tagDisplay)
* @param data
*/
addSpecificMetadata = function(imageId, type, data) {
var metaData = {};
const addSpecificMetadata = (imageId, type, data) => {
let metaData = {};
metaData[type] = data;
metaDataLookup[imageId] = $.extend(metaDataLookup[imageId], metaData);
@@ -92,8 +93,8 @@ function getFromDataSet(dataSet, type, tag) {
*
* @param image
*/
updateMetaData = function(image) {
var imageMetaData = metaDataLookup[image.imageId];
const updateMetaData = image => {
const imageMetaData = metaDataLookup[image.imageId];
if (!imageMetaData) {
return;
}
@@ -141,13 +142,13 @@ function getImagePlane(instance) {
return;
}
var imageOrientation = instance.imageOrientationPatient.split('\\');
var imagePosition = instance.imagePositionPatient.split('\\');
let imageOrientation = instance.imageOrientationPatient.split('\\');
let imagePosition = instance.imagePositionPatient.split('\\');
var columnPixelSpacing = 1.0;
var rowPixelSpacing = 1.0;
let columnPixelSpacing = 1.0;
let rowPixelSpacing = 1.0;
if (instance.pixelSpacing) {
var split = instance.pixelSpacing.split('\\');
let split = instance.pixelSpacing.split('\\');
rowPixelSpacing = parseFloat(split[0]);
columnPixelSpacing = parseFloat(split[1]);
}
@@ -178,9 +179,9 @@ function getImagePlane(instance) {
* @param dataSet {Object} An instance of dicomParser.DataSet object where multiframe information can be found.
* @return {Object} An object containing multiframe image metadata (frameIncrementPointer, frameTime, frameTimeVector, etc).
*/
getMultiframeModuleMetaData = function(dataSet) {
function getMultiframeModuleMetaData(dataSet) {
var numberOfFrames,
let numberOfFrames,
frameIncrementPointer,
frameTime,
frameTimeVector,
@@ -232,7 +233,7 @@ getMultiframeModuleMetaData = function(dataSet) {
}
return imageInfo;
};
}
/**
* Looks up metaData for Cornerstone Tools given a specified type and imageId
@@ -244,7 +245,7 @@ getMultiframeModuleMetaData = function(dataSet) {
* @returns {Object} Relevant metaData of the specified type
*/
function provider(type, imageId) {
var imageMetaData = metaDataLookup[imageId];
let imageMetaData = metaDataLookup[imageId];
if (!imageMetaData) {
return;
}
@@ -257,3 +258,9 @@ function provider(type, imageId) {
Meteor.startup(function() {
cornerstoneTools.metaData.addProvider(provider);
});
/**
* Export relevant symbols
*/
export { addMetaData, addSpecificMetadata, updateMetaData };
@@ -1,14 +1,32 @@
import { Session } from 'meteor/session';
import { $ } from 'meteor/jquery';
import { OHIF } from 'meteor/ohif:core';
import { enablePrefetchOnElement } from './enablePrefetchOnElement';
import { displayReferenceLines } from './displayReferenceLines';
setActiveViewport = element => {
/**
* Sets a viewport element active
* @param {node} element DOM element to be activated
*/
export function setActiveViewport(element) {
if (!element) {
OHIF.log.info('setActiveViewport element does not exist');
return;
}
const viewportIndex = $('.imageViewerViewport').index(element);
const viewerports = $('.imageViewerViewport');
const viewportIndex = viewerports.index(element);
const jQueryElement = $(element);
// When an ActivateViewport event is fired, update the Meteor Session
OHIF.log.info(`setActiveViewport setting viewport index: ${viewportIndex}`);
// If viewport is not active
if(!jQueryElement.parents('.viewportContainer').hasClass('active')) {
// Trigger an event for compatibility with other systems
jQueryElement.trigger('OHIFBeforeActivateViewport');
}
// When an OHIFActivateViewport event is fired, update the Meteor Session
// with the viewport index that it was fired from.
Session.set('activeViewport', viewportIndex);
@@ -28,11 +46,19 @@ setActiveViewport = element => {
const domElement = jQueryElement.get(0);
enablePrefetchOnElement(domElement);
displayReferenceLines(domElement);
OHIF.viewer.stackImagePositionOffsetSynchronizer.update();
// @TODO Add this to OHIFAfterActivateViewport handler...
if (OHIF.viewer.stackImagePositionOffsetSynchronizer) {
OHIF.viewer.stackImagePositionOffsetSynchronizer.update();
}
}
// Set the div to focused, so keypress events are handled
//$(element).focus();
//.focus() event breaks in FF&IE
jQueryElement.triggerHandler('focus');
};
// Trigger OHIFAfterActivateViewport event on activated instance
// for compatibility with other systems
jQueryElement.trigger('OHIFAfterActivateViewport');
}
@@ -1,19 +1,24 @@
import { Session } from 'meteor/session';
import { $ } from 'meteor/jquery';
/**
* Restores the browser focus to the currently specified active viewport
* as determined from Meteor's Session variable.
*
* This is allows keydown events to be captured on the focused element
* This is allows keydown events to be captured on the focused element.
*/
setFocusToActiveViewport = function() {
const setFocusToActiveViewport = () => {
// Get the list of viewports
var viewports = $('.imageViewerViewport');
const viewports = $('.imageViewerViewport');
// Get the current active viewport index from Session
var activeViewportIndex = Session.get('activeViewport');
const activeViewportIndex = Session.get('activeViewport');
// Find the div from the list of viewports
var activeViewport = viewports.eq(activeViewportIndex);
const activeViewport = viewports.eq(activeViewportIndex);
// Set the browser focus to this div
activeViewport.focus();
};
};
export { setFocusToActiveViewport };
@@ -1,19 +1,24 @@
setMammogramViewportAlignment = function(series, enabledElement, imageId) {
// Don't apply the MG viewport alignment to other series types
var viewTypes = ['MLO', 'CC', 'LM', 'ML', 'XCCL'];
var requiresInversion = ['LM']; // Tomo series are flipped
import { Meteor } from 'meteor/meteor';
import { $ } from 'meteor/jquery';
import { setInstanceClassDefaultViewportFunction } from './instanceClassSpecificViewport';
import { addSpecificMetadata } from './metaDataProvider';
var instance = cornerstoneTools.metaData.get('instance', imageId);
const setMammogramViewportAlignment = (series, enabledElement, imageId) => {
// Don't apply the MG viewport alignment to other series types
let viewTypes = ['MLO', 'CC', 'LM', 'ML', 'XCCL'];
let requiresInversion = ['LM']; // Tomo series are flipped
let instance = cornerstoneTools.metaData.get('instance', imageId);
if (!instance) {
return;
}
var laterality = instance.laterality;
var element = enabledElement.element;
var position;
let laterality = instance.laterality;
let element = enabledElement.element;
let position;
var left = $(enabledElement.canvas).offset().left;
var right = left + enabledElement.canvas.width;
let left = $(enabledElement.canvas).offset().left;
let right = left + enabledElement.canvas.width;
if (viewTypes.indexOf(instance.viewPosition) < 0) {
return;
@@ -58,4 +63,6 @@ setMammogramViewportAlignment = function(series, enabledElement, imageId) {
Meteor.startup(function() {
setInstanceClassDefaultViewportFunction("1.2.840.10008.5.1.4.1.1.1.2", setMammogramViewportAlignment);
});
});
export { setMammogramViewportAlignment };
@@ -1,4 +1,5 @@
sopClassDictionary = {
export const sopClassDictionary = {
ComputedRadiographyImageStorage: "1.2.840.10008.5.1.4.1.1.1",
DigitalXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.1",
DigitalXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.1.1",
@@ -112,4 +113,4 @@ sopClassDictionary = {
GenericImplantTemplateStorage: "1.2.840.10008.5.1.4.43.1",
ImplantAssemblyTemplateStorage: "1.2.840.10008.5.1.4.44.1",
ImplantTemplateGroupStorage: "1.2.840.10008.5.1.4.45.1"
};
};
@@ -1,21 +1,19 @@
import { OHIFError } from './classes/OHIFError';
/**
* Sorts the series and instances inside a study instance by their series
* and instance numbers in ascending order.
*
* @param {Object} study The study instance
*/
sortStudy = function(study) {
export function sortStudy(study) {
if (!study || !study.seriesList) {
throw "Insufficient study data was provided to sortStudy";
throw new OHIFError('Insufficient study data was provided to sortStudy');
}
study.seriesList.sort(function(a, b) {
return a.seriesNumber - b.seriesNumber;
});
study.seriesList.forEach(function(series){
series.instances.sort(function(a, b) {
return a.instanceNumber - b.instanceNumber;
});
study.seriesList.sort((a, b) => a.seriesNumber - b.seriesNumber);
study.seriesList.forEach(series => {
series.instances.sort((a, b) => a.instanceNumber - b.instanceNumber);
});
};
}
@@ -1,3 +1,5 @@
import { viewportUtils } from './viewportUtils';
/**
* This function switches to an image given an element and the index of the image in the current stack
* Note: Negative indexing is supported:
@@ -7,7 +9,7 @@
* @param element
* @param {number} [newImageIdIndex] The image index in the stack to switch to.
*/
switchToImageByIndex = function(newImageIdIndex) {
var element = getActiveViewportElement();
export function switchToImageByIndex(newImageIdIndex) {
var element = viewportUtils.getActiveViewportElement();
cornerstoneTools.scrollToIndex(element, newImageIdIndex);
};
}
@@ -1,3 +1,5 @@
import { viewportUtils } from './viewportUtils';
/**
* This function switches to an image given an element and
* the relative distance from the current image in the stack
@@ -7,7 +9,7 @@
* @param element
* @param {number} [distanceFromCurrentIndex] The image index in the stack to switch to.
*/
switchToImageRelative = function(distanceFromCurrentIndex) {
var element = getActiveViewportElement();
export function switchToImageRelative(distanceFromCurrentIndex) {
var element = viewportUtils.getActiveViewportElement();
cornerstoneTools.scroll(element, distanceFromCurrentIndex);
};
}
@@ -1,6 +1,8 @@
updateAllViewports = function() {
import { $ } from 'meteor/jquery';
export function updateAllViewports() {
var viewports = $('.imageViewerViewport').not('.empty');
viewports.each(function(index, element) {
cornerstone.updateImage(element);
});
};
}
@@ -3,6 +3,7 @@ import { Random } from 'meteor/random';
import { $ } from 'meteor/jquery';
import { _ } from 'meteor/underscore';
// Local Modules
import { OHIF } from 'meteor/ohif:core';
import { updateOrientationMarkers } from './updateOrientationMarkers';
import { getInstanceClassDefaultViewport } from './instanceClassSpecificViewport';
@@ -120,6 +121,16 @@ function clearTools() {
cornerstone.updateImage(element);
}
function linkStackScroll() {
const synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer;
if(synchronizer.isActive()) {
synchronizer.deactivate();
} else {
synchronizer.activate();
}
}
// This function was originally defined alone inside client/lib/toggleDialog.js
// and has been moved here to avoid circular dependency issues.
function toggleDialog(element) {
@@ -238,6 +249,17 @@ function stopAllClips() {
}
function isStackScrollLinkingDisabled() {
// Its called everytime active viewport and/or layout change
Session.get('activeViewport');
Session.get('LayoutManagerUpdated');
const synchronizer = OHIF.viewer.stackImagePositionOffsetSynchronizer;
const linkableViewports = synchronizer.getLinkableViewports();
return linkableViewports.length <= 1;
}
// Create an event listener to update playing state when a clip stops playing
$(window).on('CornerstoneToolsClipStopped', () => Session.set('UpdateCINE', Random.id()));
@@ -257,12 +279,14 @@ const viewportUtils = {
flipH,
resetViewport,
clearTools,
linkStackScroll,
toggleDialog,
toggleCinePlay,
toggleCineDialog,
isPlaying,
hasMultipleFrames,
stopAllClips
stopAllClips,
isStackScrollLinkingDisabled
};
export { viewportUtils };