Code Monkey home page Code Monkey logo

dcmjs's Introduction

dcmjs

JavaScript implementation of DICOM manipulation. This code is an outgrowth of several efforts to implement web applications for medical imaging.


CI

Note: this code is a work-in-progress and should not be used for production or clinical purposes

This is a community effort so please help improve support for a wide range of DICOM data and use cases.

See live examples here

Goals

Overall the code should:

  • Support reading and writing of correct DICOM objects in JavaScript for browser or node environments
  • Provide a programmer-friendly JavaScript environment for using and manipulating DICOM objects
  • Include a set of useful demos to encourage correct usage of dcmjs and modern DICOM objects
  • Encourage correct referencing of instances and composite context when creating derived objects
  • Current target is modern web browsers, but a set of node-based utilities also makes sense someday

Architectural goals include:

  • Use modern JavaScript programming methods (currently ES6) but avoid heavy frameworks
  • Leverage modern DICOM standards but avoid legacy parts
  • Support straightforward integration with multiple JavaScript deployment targets (browser, node, etc) and frameworks.

Parts of DICOM that dcmjs will focus on:

  • Enhanced Multiframe Images
  • Segmentation Objects
  • Parametric Maps
  • Structured Reports

Parts of DICOM that dcmjs will not focus on:

  • DIMSE (legacy networking like C-STORE, C-FIND, C-MOVE, etc). See the dcmjs-dimse project for that.
  • Physical Media (optical disks). See this FAQ if you need to work with those.
  • Image rendering. See dcmjs-imaging for this.
  • 3D rendering. See vtk.js.
  • Radiology review application - see OHIF.

Usage

In Browser

<script type="text/javascript" src="https://unpkg.com/dcmjs"></script>

In Node

// To install latest _stable_ release
npm install --save dcmjs

// To install latest code merged to master
npm install --save dcmjs@dev

For Developers

git clone https://github.com/dcmjs-org/dcmjs
cd dcmjs
npm install
npm run build
npm test

For Maintainers and Contributors

Publish new version automatically from commit:

Use the following "Commit Message Format" when drafting commit messages. If you're merging a 3rd party's PR, you have the ability to override the supplied commit messages by doing a "Squash & Merge":

Note: Be wary of BREAKING_CHANGE in commit message descriptions, as this can force a major version bump.

Be sure to use lower case for the first letter of your semantic commit message, so use fix not Fix or feat not Feat, have a space after the : and make the PR github review title follow the SAME rules. It is the PR review title that determins the final commit message and will be used for semantic detection.

Note: a new package version will be published only if the commit comes from a PR.

Optional Tooling

It is advised to use the git-cz, i.e.:

  • install git-cz
npm install -g git-cz
  • how to commit
git-cz --non-interactive --type=fix --subject="commit message"

More info at git-cz.

Community Participation

Use this repository's issues page to report any bugs. Please follow SSCCE guidelines when submitting issues.

Use github pull requests to make contributions.

Unit Tests

Tests are written using the Jest testing framework and live in the test/ folder. Test file names must end with .test.js.

Pull requests should either update existing tests or add new tests in order to ensure good test coverage of the changes being made.

To run all tests use npm run test. To only run specific tests use Jest's .only feature. If you're using VS Code, an extension such as firsttris.vscode-jest-runner can be used to step through specific tests in the debugger.

Read all about unit testing best practices here.

Status

Currently dcmjs is an early-stage development experiment, but already has valuable functionality.

Implemented

  • Bidirectional conversion to and from part 10 binary DICOM and DICOM standard JSON encoding (as in DICOMweb)
  • Bidirectional convertion to and from DICOM standard JSON and a programmer-friendly high-level version (high-level form is called the "naturalized" form in the code).

In development

  • Creation of (correct) enhanced multiframe DICOM objects from legacy image objects
  • Creation of (correct) derived DICOM objects such as Segmentations and Structured Reports

TODO

  • Create a test suite of input and output DICOM objects
  • Test interoperability with other DICOM implementations
  • Add documentation

History

Support

The developers gratefully acknowledge their research support:

dcmjs's People

Contributors

biharck avatar codepage949 avatar dannyrb avatar dependabot[bot] avatar dmlambo avatar emelalkim avatar florianlink avatar galelis avatar hackermd avatar igoroctaviano avatar jamesapetts avatar jmhmd avatar juliencastelneau avatar kursawero avatar ladeirarodolfo avatar md-prog avatar ouwen avatar pantelisgeorgiadis avatar pieper avatar punzo avatar richard-viney avatar rvantklooster avatar sedghi avatar swederik avatar tostein avatar tw4204 avatar wayfarer3130 avatar whatwilliam avatar wheresvic avatar woonchancho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dcmjs's Issues

DecimalString are not correctly written to buffer

I am working on anonymization of DICOM files and observed that Decimal Strings are not written properly to the output DICOM. I did some debugging and I noticed the following while testing with DICOM tag (0018,0050), SliceThickness, DS. If the input DICOM has a value of 4.8, then nothing if written to the output.

Dcmjs correctly reads the decimal 4.8 as Number from the input file. Then I use dicomDict.write() to write a new file buffer. Inside dicomDict.write(), it uses writeString for Decimal Strings, which in turn uses toUTF8Array(str) to convert the Number 4.8. toUTF8Array() expects a string as input and returns an empty array when having a Number as input.

Another observation, the value of a decimal String is read in correctly, put but stored as array. The value stored is [4.8], I would assume 4.8 . Maybe it is a design choice, but for me it was surprising.

STOW-RS is not encoding the "Content-Type" according to standard

In OHIF viewer the store measurements is failing when storing to DICOMlcoud server. see this issue for reference.

I traced this and it is caused by the server not recognizing the "Content-Type" header ( Built-in .NET library) because it is not not formatted properly.

For STOW-RS, the Content-Type is being sent as:
Content-Type: multipart/related; type=application/dicom; boundary=2afeebaf-038d-792a-f952-d8e249ba8e96

The correct format should be:
Content-Type: multipart/related; type="application/dicom"; boundary="2afeebaf-038d-792a-f952-d8e249ba8e96"

Notice the "Quotation mark" around the type and boundary parameters: type="application/dicom"

This used to be a bug in the DICOM standard when DICOMweb was initially released but then they corrected it to match the HTTP RFC specs:
I think this is the new reference: http://dicom.nema.org/medical/dicom/current/output/html/part18.html#sect_8.7.3.5.1
and
https://tools.ietf.org/html/rfc2387

writing dicom to file results in corrupted pixel data

The end goal is to read in the dicom, modify PHI from the header using strings of equal length as those in the tags, and modify the pixel data to remove PHI from pixels
I followed the instructions here #64

The input test image (contains PHI, so I will not upload it) is 97 frames, 600 rows, 800 columns, and 3 samples per pixel

From pydicom, header information is:

(0028, 0002) Samples per Pixel                   US: 3
(0028, 0004) Photometric Interpretation          CS: 'YBR_FULL_422'
(0028, 0006) Planar Configuration                US: 0
(0028, 0008) Number of Frames                    IS: "97"
(0028, 0009) Frame Increment Pointer             AT: (0018, 1063)
(0028, 0010) Rows                                US: 600
(0028, 0011) Columns                             US: 800
(0028, 0014) Ultrasound Color Data Present       US: 0
(0028, 0100) Bits Allocated                      US: 8
(0028, 0101) Bits Stored                         US: 8
(0028, 0102) High Bit                            US: 7
(0028, 0103) Pixel Representation                US: 0
(0028, 0301) Burned In Annotation                CS: 'YES'
(0028, 2110) Lossy Image Compression             CS: '01'
(0028, 2112) Lossy Image Compression Ratio       DS: "0.0"
(7fe0, 0010) Pixel Data                          OB: Array of 6465010 elements
(0002, 0000) File Meta Information Group Length  UL: 208
(0002, 0001) File Meta Information Version       OB: b'\x00\x01'
(0002, 0002) Media Storage SOP Class UID         UI: Ultrasound Multi-frame Image Storage
(0002, 0003) Media Storage SOP Instance UID      UI: 1.2.840.113663.1500.1.313573945.3.2.20190710.111922.593
(0002, 0010) Transfer Syntax UID                 UI: JPEG Baseline (Process 1)
(0002, 0012) Implementation Class UID            UI: 1.2.840.113857.4
(0002, 0013) Implementation Version Name         SH: 'IC2_MC3_470'
(0002, 0016) Source Application Entity Title     AE: 'SHOWCASE_SCP'

In order to rule out anything wrong in my logic, I wrote the following to simply read and write

const arrayBuffer = fs.readFileSync(filename).buffer; 
const DicomDict = dcmjs.data.DicomMessage.readFile(arrayBuffer); 
const dataSet = dcmjs.data.DicomMetaDictionary.naturalizeDataset(DicomDict.dict);
DicomDict.dict = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataSet);
let new_file_WriterBuffer = DicomDict.dict.write();
const outputFilename = './test.dcm';
fs.writeFileSync(outputFilename, new Buffer(new_file_WriterBuffer));

I noticed the following:

  1. Viewing the input image in Horos, or even in python results in a corrupt pixel data. In Horos the image is displayed well for the first couple of frames. Afterwards, the image is blank.
  2. In python, the new header information shows the Pixel Data Array of elements has changed
(7fe0, 0010) Pixel Data                          OB: Array of 6467338 elements

Any help pointing me in the right direction is much appreciated!!

Miguel

Convert JSON TO dicom object

Hi, i want to convert JSON to dicom object. i read #64 but input is a dicom file in that thread.

my JSON would be like
"00080018" : {
"vr" : "UI",
"Value" : [
"1.3.12.2.1107.5.4.3.321890.19960124.162922.29"
]
},
"00080020" : {
"vr" : "DA",
"Value" : [
"19511013"
]
}......

[Question] Is dcmjs production ready?

Is this note in the readme still true?

Note: this code is a work-in-progress and should not be used for production or clinical purposes

I am looking for a javascript library for creating dcm files and most resources point to this library.

Linear measurements SR has duplicate image reference entries

Multiple linear measurements in an SR from https://dcmjs-org.github.io/dcmjs/examples/linearMeasurements/index.html results in duplicate entries in both the Current Requested Procedure Evidence sequence and the Image Library Group container within the SR content.

Current Requeseted Procedure Evidence:

>(0008,1115) SQ #-1 [1 item] Referenced Series Sequence
>>(0008,1199) SQ #-1 [1 item] Referenced SOP Sequence
>>>(0008,1150) UI #28 [1.2.840.10008.5.1.4.1.1.4.1] Referenced SOP Class UID
>>>(0008,1155) UI #44 [2.25.500344585412579404970070655256084067295] Referenced SOP Instance UID
>>>(0008,1160) IS #2 [1] Referenced Frame Number
>>(0020,000E) UI #44 [2.25.840193827043248548801581830021610793828] Series Instance UID
>(0020,000D) UI #60 [1.3.6.1.4.1.5962.99.1.3814087073.479799962.1489872804257.3.0] Study Instance UID
>(0008,1115) SQ #-1 [1 item] Referenced Series Sequence
>>(0008,1199) SQ #-1 [1 item] Referenced SOP Sequence
>>>(0008,1150) UI #28 [1.2.840.10008.5.1.4.1.1.4.1] Referenced SOP Class UID
>>>(0008,1155) UI #44 [2.25.500344585412579404970070655256084067295] Referenced SOP Instance UID
>>>(0008,1160) IS #2 [1] Referenced Frame Number
>>(0020,000E) UI #44 [2.25.840193827043248548801581830021610793828] Series Instance UID
>(0020,000D) UI #60 [1.3.6.1.4.1.5962.99.1.3814087073.479799962.1489872804257.3.0] Study Instance UID

Image Library Group:

>>(0040,A040) CS #10 [CONTAINER] Value Type
>>(0040,A043) SQ #-1 [1 item] Concept Name Code Sequence
>>>(0008,0100) SH #6 [126200] Code Value
>>>(0008,0102) SH #4 [DCM] Coding Scheme Designator
>>>(0008,0104) LO #20 [Image Library Group] Code Meaning
>>(0040,A050) CS #8 [SEPARATE] Continuity Of Content
>>(0040,A730) SQ #-1 [6 items] Content Sequence
>>>(0008,1199) SQ #-1 [1 item] Referenced SOP Sequence
>>>>(0008,1150) UI #28 [1.2.840.10008.5.1.4.1.1.4.1] Referenced SOP Class UID
>>>>(0008,1155) UI #44 [2.25.500344585412579404970070655256084067295] Referenced SOP Instance UID
>>>>(0008,1160) IS #2 [1] Referenced Frame Number
>>>(0040,A010) CS #8 [CONTAINS] Relationship Type
>>>(0040,A040) CS #6 [IMAGE] Value Type
>>>(0008,1199) SQ #-1 [1 item] Referenced SOP Sequence
>>>>(0008,1150) UI #28 [1.2.840.10008.5.1.4.1.1.4.1] Referenced SOP Class UID
>>>>(0008,1155) UI #44 [2.25.500344585412579404970070655256084067295] Referenced SOP Instance UID
>>>>(0008,1160) IS #2 [1] Referenced Frame Number
>>>(0040,A010) CS #8 [CONTAINS] Relationship Type
>>>(0040,A040) CS #6 [IMAGE] Value Type

RangeError: Offset is outside the bounds of the DataView

The goal is to read the dicom, read patient health information, deidentify it (using the same number of characters, although that may not be necessary), and modify the dataSet tags with the new de-identified values

Following the instructions in #64:

let filename = ' /path/to/image/image.dcm'; //I've opened this in python and my overall procedure works
let arrayBuffer = fs.readFileSync(filename).buffer; 
let DicomDict = dcmjs.data.DicomMessage.readFile(arrayBuffer);

Leads to:

Invalid vr type � - using UN

RangeError: Offset is outside the bounds of the DataView

Any help is greatly appreciated!

DICOM Tag Length are Modified using dcmjs

I am using dcmjs package for inserting some new elements in Dicom files. New tag datas are inserted successfully, But the exisiting tag data say CTExposureSequence length is changing from 152 to -1.

Any one knows the cause of it?

(0018,9321) CTExposureSequence SQ 1 102 || (0018,9321) CTExposureSequence SQ 1 -1

this how i have utilized the dcm package to write the two new tags
`router.post("/updateDicomTagDatas", function(req,res,next)
{
var WorkFlow= req.body.workFlow;
var dcmEmail=req.body.dcmEmail;

for(let i=0;i<allFilePaths.length;i++)
{
let arrayBuffer = fs.readFileSync(allFilePaths[i]).buffer;    
let DicomDict = dcmjs.data.DicomMessage.readFile(arrayBuffer);

const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(DicomDict.dict);

 DicomDict.dict = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset);
  DicomDict.upsertTag("00090114","ST",dcmEmail);
  DicomDict.upsertTag("00090115","ST",WorkFlow);
let new_file_WriterBuffer = DicomDict.write();

 fs.writeFileSync(allFilePaths[i], Buffer.from(new_file_WriterBuffer));
}
 res.send({'status':200}); 

});`

code needs to be refactored

Add comments here with things that need to be changed in the code base:

  • consistent capitalization Dicom -> DICOM
  • remove abbreviations unless they are standard
  • dynamically load the data dictionary rather than hard-coding it in the class

please add more below...

Cant require from nodejs, window is not defined

Doing the following :

> npm init -y
> npm install npmjs
> node
>> const dcmjs = require('dcmjs')
ReferenceError: window is not defined
    at Object.<anonymous> (/home/jpambrun/tmp/dcmjs_test/node_modules/dcmjs/build/dcmjs.js:1:262)
    at Module._compile (internal/modules/cjs/loader.js:722:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:733:10)
    at Module.load (internal/modules/cjs/loader.js:620:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
    at Function.Module._load (internal/modules/cjs/loader.js:552:3)
    at Module.require (internal/modules/cjs/loader.js:658:17)
    at require (internal/modules/cjs/helpers.js:22:18)

Support for single frame segmentation

During our work with segmentation creation with @muakdogan, NormalizeMultiframe rejects single frame segmentations with "Single frame instance of multiframe class not supported" error message. We have seen use cases where people just want to segment single slice, whether to use as a seed for auto segmentation algorithms or as they are only interested in the largest section of the lesion. What is the reasoning behind this limitation? Any ideas @pieper? Can we make a PR to remove it?

Is there a way to force-read a file if the DICM Tag in the header is missing?

Hey. JS and DICOM noobie here. I am trying to parse the contents of files originating from two different RT-planning softwares.
With the DICOM files originating from software A there is no problem at all and i can get the values i need.
When i try to parse the headers of dicom files from software B i get the error "Error: Invalid a dicom file". It looks like planning software B alters the dicom header and removes some parts of it so that the "DICM" tag is missing.

currently using this code:

var filePath = 'dicomfile.dcm';
var arrayBuffer = fs.readFileSync(filePath).buffer;
var dicomDict = dcmjs.data.DicomMessage.readFile(arrayBuffer);
var dataSet = dcmjs.data.DicomMetaDictionary.naturalizeDataset(dicomDict.dict);
console.log(dataSet.PatientName);

Is there any way to force-read those DICOM files anyway?

I appreciate any help since i am hard-stuck at this for days.

Insert DICOM Tag

I need to Insert the new Tag Datas inside the DICOM files using Node js- dcmjs npm package. Currently I could able to insert the Tag's VR type, Tag ID, Tag Value and Tag Length, using the upsert tag. Now i need to add the Tag Description also for the Tag Value. How can I do it?

Currently I have used Below syntax in node API

router.post("/updateDicomTagDatas", function(req,res,next)
{
var WorkFlow= req.body.workFlow;
var dcmEmail=req.body.dcmEmail;
for(let i=0;i<allFilePaths.length;i++)
{
let arrayBuffer = fs.readFileSync(allFilePaths[i]).buffer;
let DicomDict = dcmjs.data.DicomMessage.readFile(arrayBuffer);
DicomDict.upsertTag("00090114", "ST", dcmEmail);
DicomDict.upsertTag("00090115", "ST", WorkFlow);
let new_file_WriterBuffer = DicomDict.write();
fs.writeFileSync(allFilePaths[i], Buffer.from(new_file_WriterBuffer));
}
});

And if I do upsertTag, I get the tag value and other properties inserted but in Tag Description Property I get unkown Tag & Data

Referenced Series Sequence is missing required fields

SEG generated by dcmjs is missing required fields in Referenced Series Sequence (0x0x00081115)

DICOM part 3 - C.12.2 Common Instance Reference Module

  • Study Instance UID (0x0020000D) required but missing.
  • Referenced Instance Sequence (0x0008114A) required but missing.

Related to issue #4?

Labeling output as research

It probably makes sense to initialize this attribute:

(0018,9004) CS [RESEARCH]                               #   8, 1 ContentQualification

toUTF8Array will convert ° into °

When using the write function of DicomDict, writeString uses toUTF8Array. This function takes in the degree symbol and spits it out as 2 bytes. Is there something that I'm missing? I fixed this in my implementation by changing it to something like Buffer.from(str, 'binary') for Node.js.

Normalization makes writing adapters fiddly for multi-volume series

(Related to #4)

Some scanners produce multi-volume series, whereby the instance number linearly increases, but there may be multiple volumes with e.g. different b-values or multiple phases.

Normalizers in dcmjs currently sort by ImagePositionPatient, such that if you have two sub volumes in the same series and your images are single-framed, Normalizer.normalizeToDataset returns a multiframe dataset which contains two interspliced volumes.

This makes writing adapters difficult/awkward if the source lib orders by instance number. Currently the cornerstone segmentation adapter will produce a segmentation with incorrect PerFrameFunctionalGroups for such multi-volume images.

There are a few solutions I can think of off the top of my head, which each have different drawbacks.

  • Normalizer.normalizeToDataset returns both a dataset and a map of input dataset indicies to frames within the normalized set.
    • One can then make sure that, for derived images and adapters, the reordering is accounted for. However this feels like it kind of defeats the purpose of normalization.
    • Using dcmjs just to convert single frame to multiframe will still result in interspliced volumes.
  • Optional argument on Normalizer.normalizeToDataset to not-reorder slices .
    • Adapters that know this problem will cause issues on a particular platform can choose not to re-order slices.
    • Numerically, sub volumes are very difficult to differentiate from badly indexed slices of a single volume, so there is no good programmatic way to know when to not sort the data. I acknowledge this is a common problem across the space. Do we want to/even have the resources to maintain private field filtering in dcmjs to try to work out what to do?
  • You can use a metadata provider in a cornerstone adapter to match slices of the source data to the derived dataset via the ReferencedSOPClassUID.
    • This would be the easiest to "tack on", but its a huge waste of resources to re-order the slices just to search through them and effectively re-re-order them.
    • Same issue about using dcmjs to convert from singleframe to multiframe.

As you can see all approaches are rather unsatisfactory, thoughts?

Slice Thickness Field is absent in created SEGs.

Tag – 0x00180050DICOM
Standard part 3 (IODs) - C.7.6.16.2.1 Pixel Measures Macro:

Slice Thickness is type 1C. Required if SOP Class UID is Segmentation Storage ("1.2.840.10008.5.1.4.1.1.66.4") and Frame of Reference UID (0020,0052) is present.

For SEGs generated with dcmjs The FoR field is present, but the required Slice Thickness field is absent.

Apologies for any brevity, writing this here for further notice!

create Segementation does not work for single frame images.

Its throwing here. This is because we convert all the datasets to a multiframe before passing it to the Segmentation class constructor. Its probably just a case of iterating through the the ReferencedInstanceSequence of the dataset, and grabbing the info from there.

DICOM SEG IO is still quite rudimentary.

TODO: Only extract slices from cornerstone that have data, to make smaller segs if possible.
TODO: Add more helpers to the segmentation class to add the appropriate fields to the PerFrameFunctionalGroupsSequence when adding multiple segments.

meta-TODO: ctrl + f through all the TODOs in the Segmentation derivation and see if any issues remain.

LT does not allow multiple

Add LT to singleVRs

A character string that may contain one or more paragraphs. It may contain the Graphic Character set and the Control Characters, CR, LF, FF, and ESC. It may be padded with trailing spaces, which may be ignored, but leading spaces are considered to be significant. Data Elements with this VR shall not be multi-valued and therefore character code 5CH (the BACKSLASH "" in ISO-IR 6) may be used.

modifying dicom tags

I am completely newbie to DICOM and was assigned to modify DICOM tags ;) so please bear with me.

My question is very simple, how do we modify DICOM tags and save it as file?

We will be using this module in Electron App so will have access to Node's fs module. I tried it on my own, something like:

const dcmjs = require("dcmjs");
const fs = require("fs");

let arrayBuffer = fs.readFileSync("C:\\tmp\\attachment.file.9a386d4b4506001a.646374303035372e64636d.dcm").buffer;

let DicomDict = dcmjs.data.DicomMessage.readFile(arrayBuffer);

DicomDict.upsertTag("x00100010", "PN", "JAYKUMAR THAKER");

let new_file_WriterBuffer = DicomDict.write();

fs.writeFileSync("C:\\tmp\\attachment_test.dcm", new Buffer(new_file_WriterBuffer));

With this, file get saved correctly but when I read the DICOM again, it has added new tag like:
x00000010 length=16; VR=PN; "JAYKUMAR THAKER" rather than modifying "x00100010"

I am sure this might not be the correct way. However any level of guidance would be really appreciated.

Handle MappingResource and MappingResourceUID

Because the naturalize/denaturalize process currently drops UID from value names
like SOPClassUID to improve readability, it leads to ambiguity in the special case
of MappingResource and MappingResourceUID where both versions exist in
the data dictionary.

In a related issue, dropping "Sequence" from the end of value names is also seeming
like it adds a bit of confusion for things like ContentSequence.

Before wider release of dcmjs it's seeming preferable to have a hard and fast rule that
we stick strictly to the names in the data dictionary.

UIDs with root 2.25 should be derived from UUID

PS 3.5 Sect B2 specifies that UIDs with root "2.25" shall be derived from a UUID. According to ITU-T X.667 this can be achieved as follows:

To obtain the single integer value of the UUID, the 16 octets of the binary representation shall be treated as an unsigned integer encoding with the most significant bit of the integer encoding as the most significant bit (bit 7) of the first of the sixteen octets (octet 15) and the least significant bit as the least significant bit (bit 0) of the last of the sixteen octets (octet 0).

Release cycle/notes

I've been waiting on a few bug fixes to make their way into an NPM release. Since 0.10.0 there has been a 0.10.1 NPM version with no accompanying Git tag, and then a 0.11.0 version with no apparent changes to source v0.10.0...v0.11.0. It would be excellent if there were signed releases in Github that correspond to packages that are published to NPM, with a summary of all the PRs included.

Alternatively, since this is a volatile project, would it be possible to include the src directory within the published NPM package so that we would be to install directly from a Git repo without having to update our import strings?

iterate through dataset with forEach instead of for...in

In some environments (e.g. the meteor-based OHIFViewer) the Object prototype has enumerable properties added and these should not be considered part of the dataset.

So patterns like:

for (let tag in dataset) {}

Need to change to:

Object.keys(dataset).forEach(tag => {})

Which also means that the body needs to change to a function, so continue needs to become return etc.

Ungraceful errors when undefined values comes to DicomMetaDictionary.denaturalizeValue

There is an edge case where an array of null elements comes to denaturalizeValue method at

value = value.map(entry =>

When this situation occurs, this method fails ungraceful:
Uncaught TypeError: Cannot read property 'constructor' of undefined

Perhaps when there is an array that contains only null values we should throw an exception:
[undefined, undefined, undefined]
throw new Error("naturalValue is completely undefined at DicomMetaDictionary.denaturalizeValue")

One question not defined yet is, how should behave this method when only some values have undefined values on the array:
[2.25, undefined, 1.15, undefined, 10.5]

Text encoding, how to do it?

Hi,
thanks for the library. I am having problems with string encodings, see this example:

var dcmjs = require("dcmjs");
const { DicomDict, DicomMessage} = dcmjs.data;
var ds = new DicomDict({})
ds.upsertTag("0008103E", "LO", "ä")
buf = ds.write()
ds2 = DicomMessage.readFile(buf)
ds2.dict["0008103E"].Value[0] == 'ä'

What is the right way to write DICOM files with proper encoding? Reading DICOM files containing special characters which were created with pydicom (without explicitly specifying the character set) works well in my case.

PixelData for DICOMSEG is encoded incorrectly when frame length is not divisible by 8 for > 1 segment

This issue with DCMTK, which now looks like it is fixed, brought to my attention that perhaps we might be doing something similar in dcmjs, as segmentation support is still rather new.

We tested on series from TCIA that usually always has at least either rows or columns as a power of 2 (we did actually test on non-square images).

For DICOMSEG creation we are binarizing each segment as its added to the pixelData. If we have one segment on a stack of non-8-divisible frames we have no issue, as we bitpack the whole segment in one go. If we have multiple segments on such an image stack, there will be image frame length % 8 voxels of unintentional packing after each segment. This will cause the pixel data to be read incorrectly after the first segment.

State of encoding for DICOMSEGs created by dcmjs:

rows * columns % 8 = 0 rows * columns % 8 != 0
Single Segment Correct Correct
Multiple Segments Correct Offset PixelData

Naturalize and DenaturalizeDataset failed image result

I'd suggest something more like this:

const dcmjs = require("dcmjs");
const fs = require("fs");

const filePath = "/Users/pieper/data/public-dicom/MRHead-multiframe+seg/MRHead-multiframe.dcm"

let arrayBuffer = fs.readFileSync(filePath).buffer;

let DicomDict = dcmjs.data.DicomMessage.readFile(arrayBuffer);

const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(DicomDict.dict);

dataset.PatientName = "Name^Somebody's"

DicomDict.dict = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset);

let new_file_WriterBuffer = DicomDict.write();

fs.writeFileSync("/tmp/file.dcm", new Buffer(new_file_WriterBuffer)); 

Hi Piper, after I used your code, i got the wrong image like this.

2

As you can see, the image become red flag. How to fix it ? thanks

Originally posted by @ikhwanafath in #64 (comment)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.