Update viewer to use prior studies for Hanging Protocols initialization and using those studies in HP Match Image process (added getStudyPriors and getStudyPriorsMap)
This commit is contained in:
1 parent
b9a3cf9da3
commit
4df18233c4
10 files changed
+335
-155
No files matched your search
@@ -188,7 +188,8 @@ Viewerbase.ResizeViewportManager = ResizeViewportManager;
|
||||
import { StudyMetadata } from './lib/classes/metadata/StudyMetadata';
|
||||
import { SeriesMetadata } from './lib/classes/metadata/SeriesMetadata';
|
||||
import { InstanceMetadata } from './lib/classes/metadata/InstanceMetadata';
|
||||
Viewerbase.metadata = { StudyMetadata, SeriesMetadata, InstanceMetadata };
|
||||
import { StudySummary } from './lib/classes/metadata/StudySummary';
|
||||
Viewerbase.metadata = { StudyMetadata, SeriesMetadata, InstanceMetadata, StudySummary };
|
||||
|
||||
// TypeSafeCollection
|
||||
import { TypeSafeCollection } from './lib/classes/TypeSafeCollection';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
const NUMBER = 'number';
|
||||
const STRING = 'string';
|
||||
const REGEX_TAG = /^x[0-9a-fx]{8}$/;
|
||||
|
||||
const DICOMTagDescriptions = Object.create(Object.prototype, {
|
||||
_descriptions: {
|
||||
@@ -9,22 +10,94 @@ const DICOMTagDescriptions = Object.create(Object.prototype, {
|
||||
writable: false,
|
||||
value: Object.create(null)
|
||||
},
|
||||
tagNumberToString: {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function tagNumberToString(tag) {
|
||||
let string; // by default, undefined is returned...
|
||||
if (this.isValidTagNumber(tag)) {
|
||||
// if it's a number, build its hexadecimal representation...
|
||||
string = 'x' + ('00000000' + tag.toString(16)).substr(-8);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
},
|
||||
isValidTagNumber: {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function isValidTagNumber(tag) {
|
||||
return (typeof tag === NUMBER && tag >= 0 && tag <= 0xFFFFFFFF);
|
||||
}
|
||||
},
|
||||
isValidTag: {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function isValidTag(tag) {
|
||||
return (typeof tag === STRING ? REGEX_TAG.test(tag) : this.isValidTagNumber(tag));
|
||||
}
|
||||
},
|
||||
find: {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function find(name) {
|
||||
let description; // by default, undefined...
|
||||
if (typeof name === NUMBER) {
|
||||
// if it's a number, build its hexadecimal representation...
|
||||
name = 'x' + ('00000000' + name.toString(16)).substr(-8);
|
||||
let description; // by default, undefined is returned...
|
||||
if (typeof name !== STRING) {
|
||||
// if it's a number, a tag string will be returned...
|
||||
name = this.tagNumberToString(name);
|
||||
}
|
||||
if (typeof name === STRING) {
|
||||
description = this._descriptions[name];
|
||||
}
|
||||
return description;
|
||||
}
|
||||
}
|
||||
},
|
||||
init: {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: function init(descriptionMap) {
|
||||
const _hasOwn = Object.prototype.hasOwnProperty;
|
||||
const _descriptions = this._descriptions;
|
||||
for (let tag in descriptionMap) {
|
||||
if (_hasOwn.call(descriptionMap, tag)) {
|
||||
if (!this.isValidTag(tag)) {
|
||||
// Skip in case tag is not valid...
|
||||
console.info(`DICOMTagDescriptions: Invalid tag "${tag}"...`);
|
||||
continue;
|
||||
}
|
||||
if (tag in _descriptions) {
|
||||
// Skip in case the tag is duplicated...
|
||||
console.info(`DICOMTagDescriptions: Duplicated tag "${tag}"...`);
|
||||
continue;
|
||||
}
|
||||
// Save keyword...
|
||||
const keyword = descriptionMap[tag];
|
||||
// Create a description entry and freeze it...
|
||||
const entry = Object.create(null);
|
||||
entry.tag = tag;
|
||||
entry.keyword = keyword;
|
||||
Object.freeze(entry);
|
||||
// Add tag references to entry...
|
||||
_descriptions[tag] = entry;
|
||||
// Add keyword references to entry (if not present already)...
|
||||
if (keyword in _descriptions) {
|
||||
const currentEntry = _descriptions[keyword];
|
||||
console.info(`DICOMTagDescriptions: Using <${currentEntry.tag},${currentEntry.keyword}> instead of <${entry.tag},${entry.keyword}> for keyword "${keyword}"...`);
|
||||
} else {
|
||||
_descriptions[keyword] = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Freeze internal description map...
|
||||
Object.freeze(_descriptions);
|
||||
// Freeze itself...
|
||||
Object.freeze(this);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -3179,41 +3252,7 @@ let initialTagDescriptionMap = {
|
||||
xfffee0dd: 'EndOfSequence'
|
||||
};
|
||||
|
||||
// Safely populate DICOMTagDescriptions object
|
||||
(function(initialTagDescriptionMap) {
|
||||
const _hasOwn = Object.prototype.hasOwnProperty;
|
||||
const descriptionMap = DICOMTagDescriptions._descriptions;
|
||||
for (let tag in initialTagDescriptionMap) {
|
||||
if (_hasOwn.call(initialTagDescriptionMap, tag)) {
|
||||
if (tag in descriptionMap) {
|
||||
// Skip in case the tag is duplicated...
|
||||
console.info(`DICOMTagDescriptions: Duplicated tag ${tag}...`);
|
||||
continue;
|
||||
}
|
||||
// Save keyword...
|
||||
const keyword = initialTagDescriptionMap[tag];
|
||||
// Create a description entry and freeze it...
|
||||
const entry = Object.create(null);
|
||||
entry.tag = tag;
|
||||
entry.keyword = keyword;
|
||||
Object.freeze(entry);
|
||||
// Add tag references to entry...
|
||||
descriptionMap[tag] = entry;
|
||||
// Add keyword references to entry (if not present already)...
|
||||
if (keyword in descriptionMap) {
|
||||
const currentEntry = descriptionMap[keyword];
|
||||
console.info(`DICOMTagDescriptions: Using <${currentEntry.tag},${currentEntry.keyword}> instead of <${entry.tag},${entry.keyword}> for keyword "${keyword}"...`);
|
||||
} else {
|
||||
descriptionMap[keyword] = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Freeze internal description map (nothing should be changed in this object afterwords)...
|
||||
Object.freeze(descriptionMap);
|
||||
}(initialTagDescriptionMap));
|
||||
|
||||
// Freeze exported object...
|
||||
Object.freeze(DICOMTagDescriptions);
|
||||
DICOMTagDescriptions.init(initialTagDescriptionMap);
|
||||
|
||||
// Discard original map...
|
||||
initialTagDescriptionMap = null;
|
||||
|
||||
@@ -4,7 +4,6 @@ import { OHIFError } from '../OHIFError';
|
||||
const UNDEFINED = 'undefined';
|
||||
const NUMBER = 'number';
|
||||
const STRING = 'string';
|
||||
const REGEX_TAG = /^x[0-9a-fx]{8}$/;
|
||||
|
||||
export class InstanceMetadata extends Metadata {
|
||||
|
||||
|
||||
@@ -1,42 +1,94 @@
|
||||
import { DICOMTagDescriptions } from '../../DICOMTagDescriptions';
|
||||
|
||||
class StudySummary {
|
||||
const StudyInstanceUID = 'x0020000D';
|
||||
|
||||
constructor(propertyMap) {
|
||||
export class StudySummary {
|
||||
|
||||
constructor(tagMap, propertyMap) {
|
||||
|
||||
// Define the main immutable "_data" private property.
|
||||
Object.defineProperty(this, '_data', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: Object.create(null)
|
||||
Object.defineProperties(this, {
|
||||
_tags: {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: Object.create(null)
|
||||
},
|
||||
_properties: {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: Object.create(null)
|
||||
}
|
||||
});
|
||||
|
||||
const hasOwn = Object.prototype.hasOwnProperty;
|
||||
const data = this._data;
|
||||
for (let property in propertyMap) {
|
||||
if (hasOwn.call(propertyMap, property)) {
|
||||
data[property] = propertyMap[property];
|
||||
}
|
||||
// Initialize internal tag map if first argument is given.
|
||||
if (tagMap !== void 0) {
|
||||
this.addTags(tagMap);
|
||||
}
|
||||
|
||||
// Initialize internal property map if second argument is given.
|
||||
if (propertyMap !== void 0) {
|
||||
this.addProperties(addProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getStudyInstanceUID() {
|
||||
// This method should return null if StudyInstanceUID is not available to keep compatibility StudyMetadata API
|
||||
return this.getTagValue(StudyInstanceUID) || null;
|
||||
}
|
||||
|
||||
addProperties(propertyMap) {
|
||||
const _hasOwn = Object.prototype.hasOwnProperty;
|
||||
const _properties = this._properties;
|
||||
for (let property in propertyMap) {
|
||||
if (_hasOwn.call(propertyMap, property)) {
|
||||
_properties[property] = propertyMap[property];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addTags(tagMap) {
|
||||
const _hasOwn = Object.prototype.hasOwnProperty;
|
||||
const _tags = this._tags;
|
||||
for (let tag in tagMap) {
|
||||
if (_hasOwn.call(tagMap, tag)) {
|
||||
const description = DICOMTagDescriptions.find(tag);
|
||||
// When a description is available, use its tag as internal key...
|
||||
if (description) {
|
||||
_tags[description.tag] = tagMap[tag];
|
||||
} else {
|
||||
_tags[tag] = tagMap[tag];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tagExists(tagName) {
|
||||
const _tags = this._tags;
|
||||
const description = DICOMTagDescriptions.find(tagName);
|
||||
if (description) {
|
||||
return (description.tag in _tags);
|
||||
}
|
||||
return (tagName in _tags);
|
||||
}
|
||||
|
||||
getTagValue(tagName) {
|
||||
const _tags = this._tags;
|
||||
const description = DICOMTagDescriptions.find(tagName);
|
||||
if (description) {
|
||||
return _tags[description.tag];
|
||||
}
|
||||
return _tags[tagName];
|
||||
}
|
||||
|
||||
propertyExists(propertyName) {
|
||||
const internalPropertyName = this.getInternalPropertyName(propertyName);
|
||||
return (internalPropertyName in this._data);
|
||||
return (propertyName in this._properties);
|
||||
}
|
||||
|
||||
getPropertyValue(propertyName) {
|
||||
const internalPropertyName = this.getInternalPropertyName(propertyName);
|
||||
return this._data[internalPropertyName];
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is supposed to translate external property names into internal property names.
|
||||
* By default it implements the simplest translation possible.
|
||||
*/
|
||||
getInternalPropertyName(propertyName) {
|
||||
return propertyName;
|
||||
return this._properties[propertyName];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user