Create DICOMDIR from source

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
zappy1
Posts: 28
Joined: Fri, 2008-06-27, 11:27

#1 Post by zappy1 »

Hello all,

(Long time, no C. :-))

I'm still working on the creation of a valid CAD SR file. I want to take into account the case of studies with DICOMDIR; of course, I have to add the newly created CAD SR in the existing DICOMDIR file.
Up till now, the situation is rather strange: I can generate with the shell command a new DICOMDIR (e.g.:

Code: Select all

$dcmgpdir --verbose 001 002 003 004 CADSR
creating DICOMDIR file using STD-GEN-CD/DVD-RAM profile: DICOMDIR
checking file: 001                                               
adding file: 001                                                 
checking file: 002                                               
adding file: 002                                                 
checking file: 003                                               
adding file: 003                                                 
checking file: 004                                               
adding file: 004                                                 
checking file: CADSR                                             
adding file: CADSR                                               
writing file: DICOMDIR

or, equivalent:

Code: Select all

$dcmmkdir 001 002 003 004 CADSR
... but when trying to implement the procedure with DCMTK libraries, in the way suggested here:

Code: Select all

DicomDirInterface dicomdir;
OFCondition status = dicomdir.appendToDicomDir(DicomDirInterface::AP_Default,ddir);
if (status.good()) {
  if (dicomdir.checkDicomFile(cdf)==EC_Normal)
  cout <<  "the file " << cdf << " is OK for including in dicomdir" << endl;
  else {
    cout <<  "the file " << cdf << " is not OK" << endl;
    if (dicomdir.checkDicomFile(cdf)==EC_IllegalParameter) cout << "EC_IllegalParameter\n";
  }  
  if (dicomdir.addDicomFile(cdf)==EC_Normal) cout << "sucessfully added CADSR to dicomdir\n";
  else {
    cout << "can't add CADSR to dicomdir file\n";   
  }  
  status = dicomdir.writeDicomDir();
  if (status.bad()) {
    cerr << "Error: cannot write DICOMDIR (" << status.text() << ")" << endl;
  }  
} 
else {
  cerr << "Error: cannot create DICOMDIR (" << status.text() << ")" << endl;
}  
I am receiving a rude answer:

Code: Select all

the file CADSR is not OK
EC_IllegalParameter
can't add CADSR to dicomdir file
I get the same answer if replacing the second line of code with
OFCondition status = dicomdir.createNewDicomDir();
It looks like there is still something wrong with my CADSR file, but I cannot figure out where is the problem. Of course, I could call the shell command within the procedure to avoid the use of DCMTK libraries, but that would be rather unprofessional.

Here follows the dcmdump of the interesting part of the CADSR file:

Code: Select all

$dcmdump +L CADSR | more

# Dicom-File-Format

# Dicom-Meta-Information-Header
# Used TransferSyntax: LittleEndianExplicit
(0002,0000) UL 198                                      #   4, 1 MetaElementGroupLength
(0002,0001) OB 00\01                                    #   2, 1 FileMetaInformationVersion
(0002,0002) UI =MammographyCADSR                        #  30, 1 MediaStorageSOPClassUID
(0002,0003) UI [1.2.276.0.7230010.3.1.4.8323328.29852.1227891203.7] #  50, 1 MediaStorageSOPInstanceUID
(0002,0010) UI =LittleEndianExplicit                    #  20, 1 TransferSyntaxUID
(0002,0012) UI [1.2.276.0.7230010.3.0.3.5.4]            #  28, 1 ImplementationClassUID
(0002,0013) SH [OFFIS_DCMTK_354]                        #  16, 1 ImplementationVersionName

# Dicom-Data-Set
# Used TransferSyntax: LittleEndianExplicit
(0008,0005) CS [ISO_IR 100]                             #  10, 1 SpecificCharacterSet
(0008,0012) DA [20081128]                               #   8, 1 InstanceCreationDate
(0008,0013) TM [175323]                                 #   6, 1 InstanceCreationTime
(0008,0014) UI [1.2.276.0.7230010.3.0.3.5.4]            #  28, 1 InstanceCreatorUID
(0008,0016) UI =MammographyCADSR                        #  30, 1 SOPClassUID
(0008,0018) UI [1.2.276.0.7230010.3.1.4.8323328.29852.1227891203.7] #  50, 1 SOPInstanceUID
(0008,0020) DA [20060322]                               #   8, 1 StudyDate
(0008,0023) DA [20081128]                               #   8, 1 ContentDate
(0008,0030) TM [143447.0]                               #   8, 1 StudyTime
(0008,0033) TM [175318]                                 #   6, 1 ContentTime
(0008,0050) SH (no value available)                     #   0, 0 AccessionNumber
(0008,0060) CS [SR]                                     #   2, 1 Modality
(0008,0070) LO [My Company]                            #  11, 1 Manufacturer
(0008,0090) PN (no value available)                     #   0, 0 ReferringPhysiciansName
(0008,1030) LO [Mammography Study CAD Report]           #  28, 1 StudyDescription
(0008,103e) LO [Dicom SR]                               #   8, 1 SeriesDescription
(0008,1111) SQ (Sequence with explicit length #=0)      #   0, 1 ReferencedPerformedProcedureStepSequence
(fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
(0010,0010) PN [ANONY^MOUS]                             #  10, 1 PatientsName
(0010,0020) LO [61734]                                  #   6, 1 PatientID
(0010,0030) DA [19570203]                               #   8, 1 PatientsBirthDate
(0010,0040) CS [F]                                      #   2, 1 PatientsSex                             
(0020,000d) UI [1.2.124.113532.147.163.65.63.20060322.80025.398568] #  50, 1 StudyInstanceUID            
(0020,000e) UI [1.2.276.0.7230010.3.1.3.8323328.29852.1227891203.8] #  50, 1 SeriesInstanceUID           
(0020,0010) SH [60585673]                               #   8, 1 StudyID                                 
(0020,0011) IS [1]                                      #   2, 1 SeriesNumber                            
(0020,0013) IS [1]                                      #   2, 1 InstanceNumber                          
(0040,a040) CS [CONTAINER]                              #  10, 1 ValueType                               
(0040,a043) SQ (Sequence with explicit length #=1)      #  64, 1 ConceptNameCodeSequence                 
  (fffe,e000) na (Item with explicit length #=3)          #  56, 1 Item                                  
    (0008,0100) SH [111036]                                 #   6, 1 CodeValue                           
    (0008,0102) SH [DCM]                                    #   4, 1 CodingSchemeDesignator              
    (0008,0104) LO [Mammography CAD Report]                 #  22, 1 CodeMeaning                         
  (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem                  
(fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem                
(0040,a050) CS [SEPARATE]                               #   8, 1 ContinuityOfContent                     
(0040,a372) SQ (Sequence with explicit length #=0)      #   0, 1 PerformedProcedureCodeSequence          
(fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem                
(0040,a375) SQ (Sequence with explicit length #=1)      # 716, 1 CurrentRequestedProcedureEvidenceSequence
  (fffe,e000) na (Item with explicit length #=2)          # 708, 1 Item                                   
    (0008,1115) SQ (Sequence with explicit length #=4)      # 680, 1 ReferencedSeriesSequence             
      (fffe,e000) na (Item with explicit length #=2)          # 162, 1 Item                               
        (0008,1199) SQ (Sequence with explicit length #=1)      #  98, 1 ReferencedSOPSequence            
          (fffe,e000) na (Item with explicit length #=2)          #  90, 1 Item                           
            (0008,1150) UI =DigitalMammographyXRayImageStorageForProcessing #  30, 1 ReferencedSOPClassUID
            (0008,1155) UI [1.2.840.113681.2204868360.730.3320319618.585] #  44, 1 ReferencedSOPInstanceUID
          (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem            
        (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem          
        (0020,000e) UI [1.2.840.113681.2204868360.730.3320319618.581] #  44, 1 SeriesInstanceUID           
      (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem                
      (fffe,e000) na (Item with explicit length #=2)          # 162, 1 Item                                
        (0008,1199) SQ (Sequence with explicit length #=1)      #  98, 1 ReferencedSOPSequence             
          (fffe,e000) na (Item with explicit length #=2)          #  90, 1 Item                            
            (0008,1150) UI =DigitalMammographyXRayImageStorageForProcessing #  30, 1 ReferencedSOPClassUID 
            (0008,1155) UI [1.2.840.113681.2204868360.730.3320319618.587] #  44, 1 ReferencedSOPInstanceUID
          (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
        (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
        (0020,000e) UI [1.2.840.113681.2204868360.730.3320319618.582] #  44, 1 SeriesInstanceUID
      (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
      (fffe,e000) na (Item with explicit length #=2)          # 162, 1 Item
        (0008,1199) SQ (Sequence with explicit length #=1)      #  98, 1 ReferencedSOPSequence
          (fffe,e000) na (Item with explicit length #=2)          #  90, 1 Item
            (0008,1150) UI =DigitalMammographyXRayImageStorageForProcessing #  30, 1 ReferencedSOPClassUID
            (0008,1155) UI [1.2.840.113681.2204868360.730.3320319618.589] #  44, 1 ReferencedSOPInstanceUID
          (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
        (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
        (0020,000e) UI [1.2.840.113681.2204868360.730.3320319618.583] #  44, 1 SeriesInstanceUID
      (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
      (fffe,e000) na (Item with explicit length #=2)          # 162, 1 Item
        (0008,1199) SQ (Sequence with explicit length #=1)      #  98, 1 ReferencedSOPSequence
          (fffe,e000) na (Item with explicit length #=2)          #  90, 1 Item
            (0008,1150) UI =DigitalMammographyXRayImageStorageForProcessing #  30, 1 ReferencedSOPClassUID
            (0008,1155) UI [1.2.840.113681.2204868360.730.3320319618.591] #  44, 1 ReferencedSOPInstanceUID
          (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
        (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
        (0020,000e) UI [1.2.840.113681.2204868360.730.3320319618.584] #  44, 1 SeriesInstanceUID
      (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
    (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
    (0020,000d) UI [60585673]                               #   8, 1 StudyInstanceUID
  (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
(0040,a491) CS [PARTIAL]                                #   8, 1 CompletionFlag
(0040,a493) CS [UNVERIFIED]                             #  10, 1 VerificationFlag
(0040,a504) SQ (Sequence with explicit length #=1)      #  32, 1 ContentTemplateSequence
  (fffe,e000) na (Item with explicit length #=2)          #  24, 1 Item
    (0008,0105) CS [DCMR]                                   #   4, 1 MappingResource
    (0040,db00) CS [4000]                                   #   4, 1 TemplateIdentifier
  (fffe,e00d) na (ItemDelimitationItem for re-encoding)   #   0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
[...]
or, in short:

Code: Select all

$ dsrdump +Pn CCADF | more
Mammography CAD SR Document

Patient            : ANONY^MOUS (F, 19570203, #61734)
Manufacturer       : My Company
Completion Flag    : PARTIAL
Verification Flag  : UNVERIFIED
Content Date/Time  : 20081128 175318

1  <CONTAINER:(,,"Mammography CAD Report")=SEPARATE>
1.1  <has concept mod CODE:(,,"Language of Content Item and Descendants")=(eng,ISO639_2,"English")>
1.1.1  <has concept mod CODE:(,,"Country of Language")=(US,ISO3166_1,"UNITED STATES")>
1.2  <contains CONTAINER:(,,"Image library")=SEPARATE>
1.2.1  <contains IMAGE:=(DPm image,)>
1.2.1.1  <has acq context CODE:(,,"Image Laterality")=(T-04020,SNM3,"Right breast")>
1.2.2  <contains IMAGE:=(DPm image,)>
1.2.2.1  <has acq context CODE:(,,"Image Laterality")=(T-04030,SNM3,"Left breast")>
1.2.3  <contains IMAGE:=(DPm image,)>
1.2.3.1  <has acq context CODE:(,,"Image Laterality")=(T-04020,SNM3,"Right breast")>
1.2.4  <contains IMAGE:=(DPm image,)>
1.2.4.1  <has acq context CODE:(,,"Image Laterality")=(T-04030,SNM3,"Left breast")>
1.3  <contains CODE:(,,"CAD Processing and Findings Summary")=(111242,DCM,"All algorithms succeeded; with findin
gs")>
1.3.1  <inferred from CONTAINER:(,,"Individual Impression/Recommendation")=SEPARATE>
1.3.1.1  <has concept mod CODE:(,,"Rendering Intent")=(111150,DCM,"Presentation Required: Rendering device is ex
pected to present")>
1.3.1.2  <contains CODE:(,,"Single Image Finding")=(F-01775,SRT[1.1],"Calcification Cluster")>
1.3.1.2.1  <has concept mod CODE:(,,"Rendering Intent")=(111150,DCM,"Presentation Required: Rendering device is
expected to present")>
1.3.1.2.2  <has properties TEXT:(,,"Algorithm Name")="MyCAD">
1.3.1.2.3  <has properties TEXT:(,,"Algorithm Version")="1.0">
1.3.1.2.4  <has properties TEXT:(,,"Algorithm Parameters")="70.0">
1.3.1.2.5  <has properties NUM:(,,"Number of calcifications")="24" (1,UCUM[1.4],"no units")>
1.3.1.2.6  <has properties SCOORD:(,,"Center")=(POINT,3868/4140)>
1.3.1.2.6.1  <selected from 1.2.1>
 [...]
Why the library call fails when shell call succeeds and what seems to be wrong with my CADSR file?!
Any help would be highly appreciated.

Thank you,
Z.B.

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#2 Post by Jörg Riesmeier »

What does the log stream show in verbose/debug mode?

zappy1
Posts: 28
Joined: Fri, 2008-06-27, 11:27

#3 Post by zappy1 »

Jörg Riesmeier wrote:What does the log stream show in verbose/debug mode?
I don't have a special log stream, the messages are only those already mentioned, from the shell window which displays also the output of "cerr".
How can I get more messages?

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#4 Post by Jörg Riesmeier »

You should use DicomDirInterface::setLogStream () for this purpose.

zappy1
Posts: 28
Joined: Fri, 2008-06-27, 11:27

#5 Post by zappy1 »

Jörg Riesmeier wrote:You should use DicomDirInterface::setLogStream () for this purpose.
OK, I made a slight improvement to the above code which now reads

Code: Select all

DicomDirInterface dicomdir; 
OFCondition status = dicomdir.appendToDicomDir(DicomDirInterface::AP_Default,ddir); 
if (status.good()) { 
  dicomdir.setLogStream (&(OFConsole::instance()));
  dicomdir.enableVerboseMode(OFTrue);
  if (dicomdir.checkDicomFile(cdf)==EC_Normal) 
  cout <<  "the file " << cdf << " is OK for including in dicomdir" << endl; 
  else { 
    cout <<  "the file " << cdf << " is not OK" << endl; 
    if (dicomdir.checkDicomFile(cdf)==EC_IllegalParameter) cout << "EC_IllegalParameter\n"; 
  }  
  if (dicomdir.addDicomFile(cdf)==EC_Normal) cout << "sucessfully added CADSR to dicomdir\n"; 
  else { 
    cout << "can't add CADSR to dicomdir file\n";    
  }  
  status = dicomdir.writeDicomDir(); 
  if (status.bad()) { 
    cerr << "Error: cannot write DICOMDIR (" << status.text() << ")" << endl; 
  }  
} 
else { 
  cerr << "Error: cannot create DICOMDIR (" << status.text() << ")" << endl; 
} 
And for the files i have the following error output:

Code: Select all

Error: invalid character(s) in filename: /home/database/dicom/teststudy/CADSR
                                         ^                  
Error: invalid character(s) in filename: /home/database/dicom/teststudy/001
                                         ^             

usw. (the "^" sign points on the first "/").
Under Windows, the same error shows up, the invalid character is ":" (from E:\database\...)

So it looks like the library command doesn't like the full path in the name of the files.
How can I add files from a certain directory $study_path to a DICOMDIR file in the same $study_path without mentioning the path part in the name of the files (which seem otherwise regular at this point)? Does this $study_path take as default value the second argument (if any) of DicomDirInterface::addDicomFile(file,directory)?
Thank you for the help.

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#6 Post by Jörg Riesmeier »

So it looks like the library command doesn't like the full path in the name of the files.
This is because the DICOM standard does not like absolute paths in the DICOMDIR :-) However, you could use the second parameter of addDicomFile() and checkDicomFile() in order to specify the input directory (see documentation and dcmgpdir.cc for details). In your case, the input directory would probably be "/home/database/dicom/teststudy/" on Unix and "E:\database\" on Windows systems.

Btw, "setLogStream(&ofConsole)" should also work ...

zappy1
Posts: 28
Joined: Fri, 2008-06-27, 11:27

#7 Post by zappy1 »

Jörg Riesmeier wrote:
So it looks like the library command doesn't like the full path in the name of the files.
This is because the DICOM standard does not like absolute paths in the DICOMDIR :-) However, you could use the second parameter of addDicomFile() and checkDicomFile() in order to specify the input directory (see documentation and dcmgpdir.cc for details).
OK, it worked, case closed (I feared my CADSR wasn't yet dicom-compliant, but it seems there was no reason to worry about).

Thank you again for your help.

Z.B.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 1 guest