'use strict';
var VJS = VJS || {};
VJS.loaders = VJS.loaders || {};
/*** Imports ***/
VJS.parsers = VJS.parsers || {};
VJS.parsers.dicom = VJS.parsers.dicom || require('../parsers/parsers.dicom');
VJS.models = VJS.models || {};
VJS.models.series = VJS.models.series || require('../models/models.series');
VJS.models.stack = VJS.models.stack || require('../models/models.stack');
VJS.models.frame = VJS.models.frame || require('../models/models.frame');
/**
*
* It is typically used to load a DICOM image. Use loading manager for
* advanced usage, such as multiple files handling.
*
* Demo: {@link https://fnndsc.github.io/vjs#loader_dicom}
*
* @constructor
* @class
* @memberOf VJS.loaders
* @public
*
* @param {THREE.DefaultLoadingManager=} manager - Manager for advanced users.
*
* @example
* var files = ['/data/dcm/fruit'];
*
* // Instantiate a dicom loader
* var dicomLoader = new VJS.loaders.dicom();
*
* // load a resource
* loader.load(
* // resource URL
* files[0],
* // Function when resource is loaded
* function(object) {
* //scene.add( object );
* window.console.log(object);
* }
* );
*/
VJS.loaders.dicom = function(manager) {
this.manager =
(manager !== undefined) ? manager : THREE.DefaultLoadingManager;
this.crossOrigin = true;
this.responseType = 'arraybuffer';
this._imageHelper = null;
this._image = null;
};
VJS.loaders.dicom.prototype.constructor = VJS.loaders.dicom;
/**
*
* Load target file and attach necessary callbacks.
*
* @todo Might want to implement onError extra layer like for "onLoad".
* @public
*
* @param {string} url - Url of the file to be pulled.
* @param {function} onLoad - On load callback, after response has been parsed by VJS.loaders.dicom.parse.
* @param {function} onProgress - On progress callback.
* @param {function} onError - On error callback.
*
* @returns {Array<Promise>} Loading sequence for each file.
*
*/
VJS.loaders.dicom.prototype.load = function(file, onLoad, onProgress, onError) {
// no more promises...!
//
var scope = this;
// scope._imageHelper = new Array(files.length);
// scope._image = new Array(files.length);
var loader = new THREE.XHRLoader(scope.manager);
loader.setCrossOrigin(this.crossOrigin);
loader.setResponseType(this.responseType);
loader.load(file, function(response) {
onLoad(scope.parse(response));
}, onProgress, onError);
// Build the promise sequence for each file
// return files.map(function(url, i) {
// var loader = new VJS.loader.xhrpromise(scope.manager);
// loader.setCrossOrigin(scope.crossOrigin);
// loader.setResponseType(scope.responseType);
// // 1- get the data
// // return an array buffer
// return loader.load(url, onProgress)
// .catch(function(error) {
// window.console.log(error);
// if (onError) {
// onError(error);
// }
// })
// // 2- parse the array buffer
// // return an image model
// .then(function(response) {
// var imageHelper = new VJS.helpers.image();
// scope._imageHelper[i] = imageHelper;
// var dicomParser = new VJS.parsers.dicom(response, imageHelper.id);
// return dicomParser.parse();
// })
// // 3- create helper with image
// // return the image helper
// .then(function(image) {
// scope._imageHelper[i].addImage(image);
// scope._image[i] = image;
// // a helper is an object we can directly add to the scene and visualize
// window.console.log('ALL SET');
// return scope._imageHelper[i];
// })
// // 4- run onLoad callback
// // input is imageHelper
// // (should it be the image?)
// .then(function(imageHelper) {
// if (onLoad) {
// window.console.log('onLoad callback (i.e. add to scene or play with helper)');
// onLoad(imageHelper);
// }
// return imageHelper;
// });
// });
};
/**
*
* Parse the response and returned a well formatted VJS Image Helper;
*
* @public
*
* @param {arraybuffer} response - Data to be parsed.
*
* @returns {VJS.Helper.Image}
*
*/
VJS.loaders.dicom.prototype.parse = function(response) {
window.console.log('file downloaded yay!');
// parse DICOM
var dicomParser = null;
try {
dicomParser = new VJS.parsers.dicom(response, 0);
}
catch (e) {
window.console.log('error cought in dicom loader');
window.console.log(e);
// throw new Error('My message')
return null;
}
// create a series
var series = new VJS.models.series();
series._seriesInstanceUID = dicomParser.seriesInstanceUID();
series._numberOfFrames = dicomParser.numberOfFrames();
if(!series._numberOfFrames){
series._numberOfFrames = 1;
}
series._numberOfChannels = dicomParser.numberOfChannels();
// just create 1 dummy stack for now
var stack = new VJS.models.stack();
stack._numberOfChannels = dicomParser.numberOfChannels();
series._stack.push(stack);
// loop through all the frames!
for (var i = 0; i < series._numberOfFrames; i++) {
// shoud check for target stack
// should check if frame was already added in stack
// etc.
var frame = new VJS.models.frame();
frame._rows = dicomParser.rows(i);
frame._columns = dicomParser.columns(i);
frame._pixelData = dicomParser.extractPixelData(i);
frame._pixelSpacing = dicomParser.pixelSpacing(i);
frame._sliceThickness = dicomParser.sliceThickness(i);
frame._imageOrientation = dicomParser.imageOrientation(i);
frame._imagePosition = dicomParser.imagePosition(i);
frame._dimensionIndexValues = dicomParser.dimensionIndexValues(i);
frame._bitsAllocated = dicomParser.bitsAllocated(i);
frame._instanceNumber = dicomParser.instanceNumber(i);
frame._windowCenter = dicomParser.windowCenter(i);
frame._windowWidth = dicomParser.windowWidth(i);
// should pass frame index for consistency...
frame._minMax = dicomParser.minMaxPixelData(frame._pixelData);
stack._frame.push(frame);
}
// var image = dicomParser.parse();
// VJS.parsers.dicom._arrayBuffer = null;
// VJS.parsers.dicom._dataSet = null;
return series;
//var self = this;
//return new Promise(function(resolve) {
// console.time('LoaderDicom');
// // use response as input to image helper.
// // can provide an image or not...
// var imageHelper = new VJS.helpers.image();
// var dicomParser = new VJS.parsers.dicom(response, imageHelper.id);
// //var image = dicomParser.parse();
// var sequence = Promise.resolve();
// sequence
// .then(function() {
// return dicomParser.parse();
// })
// .then(function(image) {
// imageHelper.add(image);
// console.timeEnd('LoaderDicom');
// return (imageHelper);
// });
// return sequence;
//imageHelper.add(dicomParser.parse());
//
// Create A dicom parser to help us fill the Image Helper!
//
// var dicomParser = new VJS.parsers.dicom(name, jQueryDom);
// var object, objects = [];
// var geometry, material;
// for ( var i = 0, l = objects.length; i < l; i ++ ) {
// object = objects[ i ];
// geometry = object.geometry;
// var buffergeometry = new THREE.BufferGeometry();
// buffergeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( geometry.vertices ), 3 ) );
// if ( geometry.normals.length > 0 ) {
// buffergeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( geometry.normals ), 3 ) );
// }
// if ( geometry.uvs.length > 0 ) {
// buffergeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( geometry.uvs ), 2 ) );
// }
// material = new THREE.MeshLambertMaterial();
// material.name = object.material.name;
// var mesh = new THREE.Mesh( buffergeometry, material );
// mesh.name = object.name;
// container.add( mesh );
// }
//resolve(imageHelper);
//});
// VJS.parsers.dicom.prototype.parsePromise = function() {
// var self = this;
// console.time('Parsing Dicom');
// var imageNameFS = 'image_' + self._id;
// var frameNameFS = imageNameFS + '-raw.8b';
// //
// // Promises in action!
// //
// var sequence = Promise.resolve();
// return sequence
// .then(function() {
// // same image to Virtual FS
// return self.fileToFS(imageNameFS, self._arrayBuffer);
// })
// .then(function() {
// // extract frames from image and save it on Vistual FS
// return self.framesToFS(imageNameFS, frameNameFS);
// })
// .then(function() {
// // extract dicom header from image and convert it to XML
// return self.dumpToXML(imageNameFS);
// })
// .then(function(xml) {
// // parse XML Header and build VJS objects
// var $dicomDom = $.parseXML(xml);
// //window.console.log($dicomDom);
// var image = self.domToImage($dicomDom, frameNameFS);
// //resolve(self.domToImage($dicomDom, frameNameFS));
// // Dom to image it!
// return image;
// });
// };
};
/** Exports **/
var moduleType = typeof module;
if ((moduleType !== 'undefined') && module.exports) {
module.exports = VJS.loaders.dicom;
}