ami-cjs.js
Version:
<p align="center"> <img src="https://cloud.githubusercontent.com/assets/214063/23213764/78ade038-f90c-11e6-8208-4fcade5f3832.png" width="60%"> </p>
385 lines (326 loc) • 13.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _loaders = require('./loaders.base');
var _loaders2 = _interopRequireDefault(_loaders);
var _core = require('../core/core.utils');
var _core2 = _interopRequireDefault(_core);
var _models = require('../models/models.series');
var _models2 = _interopRequireDefault(_models);
var _models3 = require('../models/models.stack');
var _models4 = _interopRequireDefault(_models3);
var _models5 = require('../models/models.frame');
var _models6 = _interopRequireDefault(_models5);
var _parsers = require('../parsers/parsers.dicom');
var _parsers2 = _interopRequireDefault(_parsers);
var _parsers3 = require('../parsers/parsers.mhd');
var _parsers4 = _interopRequireDefault(_parsers3);
var _parsers5 = require('../parsers/parsers.nifti');
var _parsers6 = _interopRequireDefault(_parsers5);
var _parsers7 = require('../parsers/parsers.nrrd');
var _parsers8 = _interopRequireDefault(_parsers7);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/** * Imports ***/
var PAKO = require('pako');
/**
*
* 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}
*
* @module loaders/volumes
* @extends LoadersBase
* @example
* var files = ['/data/dcm/fruit'];
*
* // Instantiate a dicom loader
* var lDicomoader = new dicom();
*
* // load a resource
* loader.load(
* // resource URL
* files[0],
* // Function when resource is loaded
* function(object) {
* //scene.add( object );
* window.console.log(object);
* }
* );
*/
var LoadersVolumes = function (_LoadersBase) {
_inherits(LoadersVolumes, _LoadersBase);
function LoadersVolumes() {
_classCallCheck(this, LoadersVolumes);
return _possibleConstructorReturn(this, (LoadersVolumes.__proto__ || Object.getPrototypeOf(LoadersVolumes)).apply(this, arguments));
}
_createClass(LoadersVolumes, [{
key: 'parse',
/**
* Parse response.
* response is formated as:
* {
* url: 'resource url',
* buffer: xmlresponse,
* }
* @param {object} response - response
* @return {promise} promise
*/
value: function parse(response) {
var _this2 = this;
// emit 'parse-start' event
this.emit('parse-start', {
file: response.url,
time: new Date()
});
// give a chance to the UI to update because
// after the rendering will be blocked with intensive JS
// will be removed after eventer set up
if (this._progressBar) {
this._progressBar.update(0, 100, 'parse');
}
return new Promise(function (resolve, reject) {
window.setTimeout(function () {
resolve(new Promise(function (resolve, reject) {
var data = response;
if (!Array.isArray(data)) {
data = [data];
}
data.forEach(function (dataset) {
_this2._preprocess(dataset);
});
if (data.length === 1) {
data = data[0];
} else {
// if raw/mhd pair
var mhdFile = data.filter(_this2._filterByExtension.bind(null, 'MHD'));
var rawFile = data.filter(_this2._filterByExtension.bind(null, 'RAW'));
if (data.length === 2 && mhdFile.length === 1 && rawFile.length === 1) {
data.url = mhdFile[0].url;
data.extension = mhdFile[0].extension;
data.mhdBuffer = mhdFile[0].buffer;
data.rawBuffer = rawFile[0].buffer;
}
}
var Parser = _this2._parser(data.extension);
if (!Parser) {
// emit 'parse-error' event
_this2.emit('parse-error', {
file: response.url,
time: new Date(),
error: data.filename + 'can not be parsed.'
});
reject(data.filename + ' can not be parsed.');
}
// check extension
var volumeParser = null;
try {
volumeParser = new Parser(data, 0);
} catch (e) {
window.console.log(e);
// emit 'parse-error' event
_this2.emit('parse-error', {
file: response.url,
time: new Date(),
error: e
});
reject(e);
}
// create a series
var series = new _models2.default();
series.seriesInstanceUID = volumeParser.seriesInstanceUID();
series.numberOfFrames = volumeParser.numberOfFrames();
if (!series.numberOfFrames) {
series.numberOfFrames = 1;
}
series.numberOfChannels = volumeParser.numberOfChannels();
series.modality = volumeParser.modality();
// if it is a segmentation, attach extra information
if (series.modality === 'SEG') {
// colors
// labels
// etc.
series.segmentationType = volumeParser.segmentationType();
series.segmentationSegments = volumeParser.segmentationSegments();
}
// just create 1 dummy stack for now
var stack = new _models4.default();
stack.numberOfChannels = volumeParser.numberOfChannels();
stack.pixelRepresentation = volumeParser.pixelRepresentation();
stack.pixelType = volumeParser.pixelType();
stack.invert = volumeParser.invert();
stack.spacingBetweenSlices = volumeParser.spacingBetweenSlices();
stack.modality = series.modality;
// if it is a segmentation, attach extra information
if (stack.modality === 'SEG') {
// colors
// labels
// etc.
stack.segmentationType = series.segmentationType;
stack.segmentationSegments = series.segmentationSegments;
}
series.stack.push(stack);
// recursive call for each frame
// better than for loop to be able
// to update dom with "progress" callback
setTimeout(_this2.parseFrame(series, stack, response.url, 0, volumeParser, resolve, reject), 0);
}));
}, 10);
});
}
/**
* recursive parse frame
* @param {ModelsSeries} series - data series
* @param {ModelsStack} stack - data stack
* @param {string} url - resource url
* @param {number} i - frame index
* @param {parser} dataParser - selected parser
* @param {promise.resolve} resolve - promise resolve args
* @param {promise.reject} reject - promise reject args
*/
}, {
key: 'parseFrame',
value: function parseFrame(series, stack, url, i, dataParser, resolve, reject) {
var frame = new _models6.default();
frame.sopInstanceUID = dataParser.sopInstanceUID(i);
frame.url = url;
frame.index = i;
frame.rows = dataParser.rows(i);
frame.columns = dataParser.columns(i);
frame.numberOfChannels = stack.numberOfChannels;
frame.pixelRepresentation = stack.pixelRepresentation;
frame.pixelType = stack.pixelType;
frame.pixelData = dataParser.extractPixelData(i);
frame.pixelSpacing = dataParser.pixelSpacing(i);
frame.spacingBetweenSlices = dataParser.spacingBetweenSlices(i);
frame.sliceThickness = dataParser.sliceThickness(i);
frame.imageOrientation = dataParser.imageOrientation(i);
frame.rightHanded = dataParser.rightHanded();
stack.rightHanded = frame.rightHanded;
if (frame.imageOrientation === null) {
frame.imageOrientation = [1, 0, 0, 0, 1, 0];
}
frame.imagePosition = dataParser.imagePosition(i);
if (frame.imagePosition === null) {
frame.imagePosition = [0, 0, i];
}
frame.dimensionIndexValues = dataParser.dimensionIndexValues(i);
frame.bitsAllocated = dataParser.bitsAllocated(i);
frame.instanceNumber = dataParser.instanceNumber(i);
frame.windowCenter = dataParser.windowCenter(i);
frame.windowWidth = dataParser.windowWidth(i);
frame.rescaleSlope = dataParser.rescaleSlope(i);
frame.rescaleIntercept = dataParser.rescaleIntercept(i);
// should pass frame index for consistency...
frame.minMax = dataParser.minMaxPixelData(frame.pixelData);
// if series.mo
if (series.modality === 'SEG') {
frame.referencedSegmentNumber = dataParser.referencedSegmentNumber(i);
}
stack.frame.push(frame);
// update status
this._parsed = i + 1;
this._totalParsed = series.numberOfFrames;
// will be removed after eventer set up
if (this._progressBar) {
this._progressBar.update(this._parsed, this._totalParsed, 'parse');
}
// emit 'parsing' event
this.emit('parsing', {
file: url,
total: this._totalParsed,
parsed: this._parsed,
time: new Date()
});
if (this._parsed === this._totalParsed) {
// emit 'parse-success' event
this.emit('parse-success', {
file: url,
total: this._totalParsed,
parsed: this._parsed,
time: new Date()
});
resolve(series);
} else {
setTimeout(this.parseFrame(series, stack, url, this._parsed, dataParser, resolve, reject), 0);
}
}
/**
* Return parser given an extension
* @param {string} extension - extension
* @return {parser} selected parser
*/
}, {
key: '_parser',
value: function _parser(extension) {
var Parser = null;
switch (extension.toUpperCase()) {
case 'NII':
case 'NII_':
Parser = _parsers6.default;
break;
case 'DCM':
case 'DICOM':
case 'IMA':
case '':
Parser = _parsers2.default;
break;
case 'MHD':
Parser = _parsers4.default;
break;
case 'NRRD':
Parser = _parsers8.default;
break;
default:
window.console.log('unsupported extension: ' + extension);
return false;
}
return Parser;
}
/**
* Pre-process data to be parsed (find data type and de-compress)
* @param {*} data
*/
}, {
key: '_preprocess',
value: function _preprocess(data) {
var parsedUrl = _core2.default.parseUrl(data.url);
// update data
data.filename = parsedUrl.filename;
data.extension = parsedUrl.extension;
data.pathname = parsedUrl.pathname;
data.query = parsedUrl.query;
// unzip if extension is '.gz'
if (data.extension === 'gz') {
data.gzcompressed = true;
data.extension = data.filename.split('.gz').shift().split('.').pop();
var decompressedData = PAKO.inflate(data.buffer);
data.buffer = decompressedData.buffer;
} else {
data.gzcompressed = false;
}
}
/**
* Filter data by extension
* @param {*} extension
* @param {*} item
* @returns Boolean
*/
}, {
key: '_filterByExtension',
value: function _filterByExtension(extension, item) {
if (item.extension.toUpperCase() === extension.toUpperCase()) {
return true;
}
return false;
}
}]);
return LoadersVolumes;
}(_loaders2.default);
exports.default = LoadersVolumes;
module.exports = exports['default'];