Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Order of tags gets messed up when edition DICOM SEG #365

Open
emelalkim opened this issue Sep 12, 2023 · 7 comments
Open

Order of tags gets messed up when edition DICOM SEG #365

emelalkim opened this issue Sep 12, 2023 · 7 comments

Comments

@emelalkim
Copy link
Contributor

          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)); 

Originally posted by @pieper in #64 (comment)

Hi, We are using this method to create copies of DICOM objects with different UIDs.
The MRIs are OK, but the segmentations throws this when I run dciodvfy
Error - Tags out of order - trailing garbage, wrong transfer syntax, or not valid DICOM
Error - MediaStorageSOPInstanceUID but missing SOPInstanceUID and not a directory
Error - MediaStorageSOPClassUID but missing SOPClassUID and not a directory

I was able to reproduce it locally using this code

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

const filePath = "/Users/ealkim/bra45-4510-413-ser/orj.dcm"

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

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

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

dataset.SeriesInstanceUID = '2.25.23542678765445654764635245765';
dataset.SOPInstanceUID = '2.25.23542678765445654764635245769';
dataset.MediaStorageSOPInstanceUID = '2.25.23542678765445654764635245769';

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

let new_file_WriterBuffer = DicomDict.write();

fs.writeFileSync("/Users/ealkim/bra45-4510-413-ser/orj_editedlocal.dcm", Buffer.from(new_file_WriterBuffer)); 
@emelalkim
Copy link
Contributor Author

Sample original and edited files
orj_editedlocal.dcm is the file created by using the code snippet given above
edited_by_epad.dcm is the file created by ePAD using a similar code to the code snippet given above

@emelalkim
Copy link
Contributor Author

@pieper any ideas?

@pieper
Copy link
Collaborator

pieper commented Sep 26, 2023

Hi @emelalkim thanks for your patience - I think the issue is that MediaStorageSOPInstanceUID is only supposed to be in the part10 (dicom file) metaheader and not in the dataset itself.

In dcmjs that's stored in the _meta field in the the javascript object, like in this code that parses a part10 from an array of bytes. Let me know if that approach solves the issue.

@emelalkim
Copy link
Contributor Author

Hi @pieper, thank you for the feedback
I tried modifying the code as below but it doesn't edit the MediaStorageSOPInstanceUID now

const fs = require("fs");

const filePath = "/Users/ealkim/bra45-4510-413-ser/orj.dcm"

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

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

const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(DicomDict.dict);
dataset._meta = dcmjs.data.DicomMetaDictionary.namifyDataset(DicomDict.meta);
    
dataset.SeriesInstanceUID = '2.25.23542678765445654764635245765';
dataset.SOPInstanceUID = '2.25.23542678765445654764635245769';
dataset._meta.MediaStorageSOPInstanceUID = '2.25.23542678765445654764635245769';

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

let new_file_WriterBuffer = DicomDict.write();

fs.writeFileSync("/Users/ealkim/bra45-4510-413-ser/orj_editedlocal2.dcm", Buffer.from(new_file_WriterBuffer)); 

Am I doing it wrong?
And I think it is actually about the data itself. I mean '2.25.23542678765445654764635245769'. There is no issue with ones 1.3... something. I believe it should be valid DICOM UID. What do you think?

@pieper
Copy link
Collaborator

pieper commented Sep 26, 2023

Hmm, either 2.25.xxx or 1.3.xxx should be fine. There are rules in the standard about what's allowed in these strings of numbers but software like dcmjs shouldn't care. (We use the 2.25 form since it's considered to be the correct way to prefix a random number, while the 1.xxx forms are related to registered prefixes).

In addition to

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

Maybe you need to add

DicomDict.meta = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset._meta);

?

If it's still a problem the code to write the data shouldn't be too hard to trace through.

@emelalkim
Copy link
Contributor Author

hi @pieper,
It is been quite a while but I was just able to get back to this.
Adding
DicomDict.meta = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset._meta); doesn't work.
I get this error

/Users/ealkim/bra45-4510-413-ser/node_modules/dcmjs/build/dcmjs.js:7545
            this.view = new DataView(this.buffer);
                        ^

TypeError: First argument to DataView constructor must be an ArrayBuffer
    at new DataView (<anonymous>)

I was able to resolve my problem with adding
DicomDict.meta['00020003'].Value[0] = dataset._meta.MediaStorageSOPInstanceUID; instead of that.
Here is the working code

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

const filePath = "/Users/ealkim/bra45-4510-413-ser/orj.dcm"

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

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

const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(DicomDict.dict);
dataset._meta = dcmjs.data.DicomMetaDictionary.namifyDataset(DicomDict.meta);
    
dataset.SeriesInstanceUID = '2.25.235426787654456547646352457651';
dataset.SOPInstanceUID = '2.25.235426787654456547646352457691898';
dataset._meta.MediaStorageSOPInstanceUID = '2.25.235426787654456547646352457691898';

DicomDict.dict = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset);
DicomDict.meta['00020003'].Value[0] = dataset._meta.MediaStorageSOPInstanceUID;

let new_file_WriterBuffer = DicomDict.write();

fs.writeFileSync("/Users/ealkim/bra45-4510-413-ser/orj_editedlocal3.dcm", Buffer.from(new_file_WriterBuffer)); 

I don't know which part in the library needs to be fixed if any, and I don't have time to work on it right now but if you give me pointers I will try to work on it later

@pieper
Copy link
Collaborator

pieper commented Aug 15, 2024

I'm glad you found a good solution @emelalkim. I agree it's not clear if this requires a change in the library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants