Creating MammographyCADSR file

All other questions regarding DCMTK

Moderator: Moderator Team

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

Creating MammographyCADSR file

#1 Post by zappy1 »

Hello all,

I am trying to write a C++ test application which takes a Dicom image file as input and outputs a sample Dicom CAD SR file (with given coordinates of my choice for the points and/or polylines).
I am using mainly Linux OS for building and testing purposes, but the application should ultimately be architecture independent, so portability does count.

My first choice is to use dcmtk libraries (dcmsr) within the code, not to generate the CAD SR from an intermediate xml file (via xml2dsr). Is this choice rational? (in terms of portability, flexibility and power of use) Is there any other clever way to create Dicom CAD SR files under dcmtk I am not aware of?

I tried to find pieces of C++ code matching my purpose, but I found only codes corresponding to generic Dicom SR templates. The attempts of adapting these codes to my intentions have failed, since inserting supplementary lines in the code makes invalid the resulting Dicom SR file (the error I get is "dsr2xml: error (Invalid Document Tree) parsing file: SRF" - I'm using dsr2xml for visualizing contents of the resulting file, SRF). The essential part of the code (obviously inspired from dcmtk mkreport source code) is:

Code: Select all

doc->createNewDocument(DSRTypes::DT_MammographyCadSR);
    doc->getStudyInstanceUID(studyUID_01);
    doc->setStudyID(studyID);
    doc->setStudyDescription("Test Mammography CAD Reporting Template");
    doc->setSeriesDescription("My Dicom SR test");
    doc->setSeriesNumber(seriesNumber);
    doc->setSpecificCharacterSetType(DSRTypes::CS_Latin1);

    doc->setPatientID(patientID);
    doc->setPatientsName(patientsName);
    doc->setPatientsBirthDate(patientsBirthDate);
    doc->setPatientsSex(patientsSex);
/////
    doc->getTree().addContentItem(DSRTypes::RT_isRoot, DSRTypes::VT_Container);
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111036", "DCM", "Mammography CAD Report"));
    doc->getTree().addContentItem(DSRTypes::RT_hasObsContext, DSRTypes::VT_PName, DSRTypes::AM_belowCurrent);
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("IHE.04", OFFIS_CODING_SCHEME_DESIGNATOR, "Observer Name"));
    doc->getTree().getCurrentContentItem().setStringValue("Test_CAD");
    doc->getTree().addContentItem(DSRTypes::RT_hasObsContext, DSRTypes::VT_Text);
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("IHE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Observer Organization Name"));
    doc->getTree().getCurrentContentItem().setStringValue("Noname");

    doc->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Image);
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("CODE_27", OFFIS_CODING_SCHEME_DESIGNATOR, "Blabla"));
    doc->getTree().getCurrentContentItem().setImageReference(DSRImageReferenceValue(UID_DigitalMammographyXRayImageStorageForProcessing, seriesInstanceUID));
    doc->getCurrentRequestedProcedureEvidence().addItem(seriesInstanceUID, seriesInstanceUID, UID_DigitalMammographyXRayImageStorageForProcessing, seriesInstanceUID);
Is it possible to add similar lines (containing coordinates of the points, information about findings, other data, etc.) in this code without corrupting the resulting SR? If the answer is positive, how is that done? Is there any (minimal) sample code available on the net? Is this approach the right one?

Thank you for your answers.

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 »

My first choice is to use dcmtk libraries (dcmsr) within the code, not to generate the CAD SR from an intermediate xml file (via xml2dsr). Is this choice rational? (in terms of portability, flexibility and power of use)
Short answer: Yes :-)
The attempts of adapting these codes to my intentions have failed, since inserting supplementary lines in the code makes invalid the resulting Dicom SR file
What does "dsrdump" say in verbose/debug mode?

General comment: Creating a Mammo CAD SR document, you should follow the relevant Templates defined in part 16 of the DICOM standard. You probably also need to specify the template identifier for the root container.

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

#3 Post by zappy1 »

Jörg Riesmeier wrote: Short answer: Yes :-)
Danke. :-)
The attempts of adapting these codes to my intentions have failed, since inserting supplementary lines in the code makes invalid the resulting Dicom SR file
What does "dsrdump" say in verbose/debug mode?
For instance, inserting two code lines

Code: Select all

doc->getTree().addContentItem(DSRTypes::RT_hasObsContext, DSRTypes::VT_Text, DSRTypes::AM_belowCurrent);
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("121049", "DCM", "Language of Content Item and Descendants"));
triggers the following output in dsrdump
-----------------------------------
$ dsrdump -dd SRF
DCMSR - Warning: Check for template constraints not yet supported
DCMSR - Warning: ContentTemplateSequence missing or empty, TemplateIdentifier 4000 (DCMR) expected
DCMSR - Warning: TextValue empty in content item (type 1)
DCMSR - Warning: Reading invalid/incomplete content item TEXT "1.1"
DCMSR - Error: Reading content item TEXT "1.1" (Invalid Value)
------------------------------- DICOM DATA SET -------------------------------
(fffe,e000) na (Item with undefined length #=5) # u/l, 1 Item
(0040,a010) CS [HAS OBS CONTEXT] # 16, 1 RelationshipType
(0040,a040) CS [TEXT] # 4, 1 ValueType
(0040,a043) SQ (Sequence with undefined length #=1) # u/l, 1 ConceptNameCodeSequence
(fffe,e000) na (Item with undefined length #=3) # u/l, 1 Item
(0008,0100) SH [121049] # 6, 1 CodeValue
(0008,0102) SH [DCM] # 4, 1 CodingSchemeDesignator
(0008,0104) LO [Language of Content Item and Descendants] # 40, 1 CodeMeaning
(fffe,e00d) na (ItemDelimitationItem) # 0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem) # 0, 0 SequenceDelimitationItem
(0040,a160) UT (no value available) # 0, 0 TextValue
(0040,a730) SQ (Sequence with undefined length #=2) # u/l, 1 ContentSequence
(fffe,e000) na (Item with undefined length #=4) # u/l, 1 Item
(0040,a010) CS [HAS OBS CONTEXT] # 16, 1 RelationshipType
(0040,a040) CS [PNAME] # 6, 1 ValueType
(0040,a043) SQ (Sequence with undefined length #=1) # u/l, 1 ConceptNameCodeSequence
(fffe,e000) na (Item with undefined length #=3) # u/l, 1 Item
(0008,0100) SH [IHE.04] # 6, 1 CodeValue
(0008,0102) SH [99_OFFIS_DCMTK] # 14, 1 CodingSchemeDesignator
(0008,0104) LO [Observer Name] # 14, 1 CodeMeaning
(fffe,e00d) na (ItemDelimitationItem) # 0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem) # 0, 0 SequenceDelimitationItem
(0040,a123) PN [Test_CAD] # 8, 1 PersonName
(fffe,e00d) na (ItemDelimitationItem) # 0, 0 ItemDelimitationItem
(fffe,e000) na (Item with undefined length #=4) # u/l, 1 Item
(0040,a010) CS [HAS OBS CONTEXT] # 16, 1 RelationshipType
(0040,a040) CS [TEXT] # 4, 1 ValueType
(0040,a043) SQ (Sequence with undefined length #=1) # u/l, 1 ConceptNameCodeSequence
(fffe,e000) na (Item with undefined length #=3) # u/l, 1 Item
(0008,0100) SH [CODE_29] # 8, 1 CodeValue
(0008,0102) SH [99_OFFIS_DCMTK] # 14, 1 CodingSchemeDesignator
(0008,0104) LO [Other] # 6, 1 CodeMeaning
(fffe,e00d) na (ItemDelimitationItem) # 0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem) # 0, 0 SequenceDelimitationItem
(0040,a160) UT [Noname] # 6, 1 TextValue
(fffe,e00d) na (ItemDelimitationItem) # 0, 0 ItemDelimitationItem
(fffe,e0dd) na (SequenceDelimitationItem) # 0, 0 SequenceDelimitationItem
(fffe,e00d) na (ItemDelimitationItem) # 0, 0 ItemDelimitationItem
------------------------------------------------------------------------------
dsrdump: error (Invalid Value) parsing file: SRF

General comment: Creating a Mammo CAD SR document, you should follow the relevant Templates defined in part 16 of the DICOM standard. You probably also need to specify the template identifier for the root container.
I've already read the relevant pages (from 135 to 157 in PS 3.16 - 2004), I know in principle what I should insert in the CAD but I don't know how to do that -- at least within this approach of gradually changing the mkreport inspired source. :( Is there any other possibility?

For the template identifier, I suppose that the line

Code: Select all

doc->createNewDocument(DSRTypes::DT_MammographyCadSR);
should be enough since the dsr2xml (performed on the file without supplementary adds) provides the right output,

<report type="Mammography CAD SR" >
<sopclass uid="1.2.840.10008.5.1.4.1.1.88.50" >MammographyCADSR</sopclass> [...]

just as for a sample Mammography CAD SR file provided on the net.

Thank you for your answer.

Z.B.

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 »

DCMSR - Warning: Check for template constraints not yet supported
This means that there are contraints for this specific IOD based on a template but these constraints are not (yet) checked.
DCMSR - Warning: ContentTemplateSequence missing or empty, TemplateIdentifier 4000 (DCMR) expected
This means that this IOD/SOP class requires to be based on the root template TID 4000 from the DICOM Content Mapping Resource (DCMR). However, you did not specify this in the dataset (see below).
DCMSR - Warning: TextValue empty in content item (type 1)
This means that you did not specify a non-empty value for a mandatory TEXT content item - this is a clear violation.
DCMSR - Warning: Reading invalid/incomplete content item TEXT "1.1"
DCMSR - Error: Reading content item TEXT "1.1" (Invalid Value)
These messages are just a follow-up of the missing text value.
I've already read the relevant pages (from 135 to 157 in PS 3.16 - 2004)
General advice: You should read the current edition of the standard (2008) plus any relevant Supplements and Correction proposals.
at least within this approach of gradually changing the mkreport inspired source. Is there any other possibility?
I would sugegst to start from scratch, i.e. with an empty document.
For the template identifier, I suppose that the line Code ... should be enough since the dsr2xml (performed on the file without supplementary adds) provides the right output,
No this is not sufficient. You should also specify the template identifier for the root content item (container). Use setTemplateIdentification() on this content item for this purpose.

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

#5 Post by zappy1 »

Jörg Riesmeier wrote: [...]
DCMSR - Warning: TextValue empty in content item (type 1)
This means that you did not specify a non-empty value for a mandatory TEXT content item - this is a clear violation.
Well, I guessed that adding a similar entry should have been benign. Anyway, I'll skip this out since I am dealing out with the SR in the other way.
I've already read the relevant pages (from 135 to 157 in PS 3.16 - 2004)
General advice: You should read the current edition of the standard (2008) plus any relevant Supplements and Correction proposals.
The TID 4000 didn't change from 2004 to 2008, there are several minor changes (essentially just some added fields) in a few other TIDs of PS 3.16. I gave the pages only for a precise reference I actually had on a printout, I could've say also pages 164-188 from the latest edition. :-)
at least within this approach of gradually changing the mkreport inspired source. Is there any other possibility?
I would sugegst to start from scratch, i.e. with an empty document.
For the template identifier, I suppose that the line Code ... should be enough since the dsr2xml (performed on the file without supplementary adds) provides the right output,
No this is not sufficient. You should also specify the template identifier for the root content item (container). Use setTemplateIdentification() on this content item for this purpose.
[/quote]

Ok, up till now the relevant lines of code are simply:

Code: Select all

    doc->getTree().addContentItem(DSRTypes::RT_isRoot, DSRTypes::VT_Container); 
    doc->getTree().getCurrentContentItem().setTemplateIdentification("4000","DCMR");
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111036", "DCM", "Mammography CAD Report"));
    doc->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Container, DSRTypes::AM_belowCurrent); 
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111028", "DCM", "Image library"));
This works well (i.e. no dsrdump or dsr2xml errors), but it's obviously insufficient for any practical purposes. :-)
At this stage, my questions would be:
  • 1. How can I correctly insert the DTID 1204 ("Language of Content Item and Descendants") for this document root? (VT = INCLUDE, I tried several code lines but all of them miserably failed to produce regular SR files);
    2. How does one insert the referene to some image (and further DTID 4020 "CAD Image Library Entry") in the "Image Library" subnode?
I think that once understood these two issues, I will be able to figure out how to implement most of the remaining parts of the CAD SR.

Thank you very much for your really precious help.

Regards,
Z.B.

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 »

1. How can I correctly insert the DTID 1204 ("Language of Content Item and Descendants") for this document root? (VT = INCLUDE, I tried several code lines but all of them miserably failed to produce regular SR files);
You have to include all (required) content items of the included template manually, i.e. there is no mechanism in DCMTK that would support the INCLUDE statement. This is mainly because the DCMTK currently does not include the numerous template and context group definitions of part 16.
2. How does one insert the referene to some image (and further DTID 4020 "CAD Image Library Entry") in the "Image Library" subnode?
There are examples for IMAGE content items in "mkreport.cc".

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

#7 Post by zappy1 »

Jörg Riesmeier wrote:
1. How can I correctly insert the DTID 1204 ("Language of Content Item and Descendants") for this document root? (VT = INCLUDE, I tried several code lines but all of them miserably failed to produce regular SR files);
You have to include all (required) content items of the included template manually, i.e. there is no mechanism in DCMTK that would support the INCLUDE statement. This is mainly because the DCMTK currently does not include the numerous template and context group definitions of part 16.
Ok, probably I was too ambiguous and confusing. At this glance, my relevant code lines are

Code: Select all

    doc->getTree().addContentItem(DSRTypes::RT_isRoot, DSRTypes::VT_Container); 
    doc->getTree().getCurrentContentItem().setTemplateIdentification("4000","DCMR");
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111036", "DCM", "Mammography CAD Report"));

    doc->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Container, DSRTypes::AM_belowCurrent); 
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111028", "DCM", "Image library"));

    doc->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Image, DSRTypes::AM_belowCurrent);
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("meep", "beep", "deep"));
    doc->getTree().getCurrentContentItem().setImageReference(DSRImageReferenceValue(UID_DigitalMammographyXRayImageStorageForProcessing, actualSOPInstanceUID));
With this code I produce a DSR which dsrdumps as follows:
--------------------------------------------------
Mammography CAD SR Document

Patient : SBI2007^Scenario 6 (F, 19010101, #SBIPT008)
Completion Flag : PARTIAL
Verification Flag : UNVERIFIED
Content Date/Time : 20080710 150617

<CONTAINER:(,,"Mammography CAD Report")=SEPARATE>
<contains CONTAINER:(,,"Image library")=SEPARATE>
<contains IMAGE:(,,"deep")=(DPm image,)>

--------------------------------------------------

Now, if I take the (provided) original CAD SR, convert it to xml, and back to a regenerated CAD SR, by using xml2dsr (executable belonging to the dcmtk package), the dsrdump of the dcmtk-generated CAD SR looks like this:
--------------------------------------------------
Mammography CAD SR Document

Patient : SBI2007^Scenario 6 (F, 19010101, #SBIPT008)
Manufacturer : R2 Technology, Inc.
Completion Flag : COMPLETE
Verification Flag : UNVERIFIED
Content Date/Time : 20070329 114448

<CONTAINER:(,,"Mammography CAD Report")=SEPARATE>

<has concept mod CODE:(,,"Language of Content Item and Descendants")=(eng,ISO639_2,"English")>
<has concept mod CODE:(,,"Country of Language")=(US,ISO3166_1,"UNITED STATES")>

<contains CONTAINER:(,,"Image Library")=SEPARATE>
<contains IMAGE:=(DPm image,)>

<has acq context CODE:(,,"Image Laterality")=(T-04020,SNM3,"Right breast")>
<has acq context CODE:(,,"Image View")=(R-10242,SNM3,"cranio-caudal")>
<has acq context TEXT:(,,"Patient Orientation Row")="P">
<has acq context TEXT:(,,"Patient Orientation Column")="L">
<has acq context DATE:(,,"Study Date")="20070115">
<has acq context TIME:(,,"Study Time")="000000">
<has acq context DATE:(,,"Content Date")="20070115">
<has acq context TIME:(,,"Content Time")="200532">
<has acq context NUM:(,,"Horizontal Imager Pixel Spacing")="70" (um,UCUM[1.4],"micrometer")>
<has acq context NUM:(,,"Vertical Imager Pixel Spacing")="70" (um,UCUM[1.4],"micrometer")>
[...]
<contains CODE:(,,"CAD Processing and Findings Summary")=(111242,DCM,"All algorithms succeeded; with findings")>
<inferred from CONTAINER:(,,"Individual Impression/Recommendation")=SEPARATE>
<has concept mod CODE:(,,"Rendering Intent")=(111150,DCM,"Presentation Required: Rendering device is expected to present")>
<contains CODE:(,,"Single Image Finding")=(F-01796,SRT[1.1],"Mammography breast density")>
<has concept mod CODE:(,,"Rendering Intent")=(111150,DCM,"Presentation Required: Rendering device is expected to present")>
<has properties TEXT:(,,"Algorithm Name")="R2_MAMMO_DENSITY">
<has properties TEXT:(,,"Algorithm Version")="Mammo 8.3">
<has properties TEXT:(,,"Algorithm Parameters")="[1]">
<has properties SCOORD:(,,"Center")=(POINT,2449/3077)>
<selected from 1.2.1>

[...]
--------------------------------------------------

By comparison of the results, one can note the part about "Language of Content Item and Descendants" at the beginning, which has been created in some way by xml2dsr (I suppose this command uses the methods and the classes provided by dcmtk).
Admitted that INCLUDE statement and some of part 16 templates are not currently supported by dcmtk, there is still an useful CAD SR file which can be obtained by using one of its commands. My aim is to obtain something more or less similar and an important step would be to generate the initial missing part (i.e. the first two missing lines) with dcmtk libraries.
I am willing to write manually any piece of code, but I don't know what to write in in order to get those two lines. Any tip would be highly appreciated.
It might be of some utility the relevant part of the intermediate xml file:

Code: Select all

<content>
    <date>2007-03-29</date>
    <time>11:44:48</time>
    <item flag="SEPARATE" valType="CONTAINER" >
      <concept codScheme="DCM" codValue="111036" >Mammography CAD Report</concept>
      <item relType="HAS CONCEPT MOD" valType="CODE" >
        <concept codScheme="DCM" codValue="121049" >Language of Content Item and Descendants</concept>
        <item relType="HAS CONCEPT MOD" valType="CODE" >
          <concept codScheme="DCM" codValue="121046" >Country of Language</concept>
          <value codScheme="ISO3166_1" codValue="US" >UNITED STATES</value>
        </item>
        <value codScheme="ISO639_2" codValue="eng" >English</value>
      </item>
      <item relType="CONTAINS" flag="SEPARATE" valType="CONTAINER" >
        <concept codScheme="DCM" codValue="111028" >Image Library</concept>
        <item relType="CONTAINS" id="5" valType="IMAGE" >
          <item relType="HAS ACQ CONTEXT" valType="CODE" >
            <concept codScheme="DCM" codValue="111027" >Image Laterality</concept>
            <value codScheme="SNM3" codValue="T-04020" >Right breast</value>
          </item>
          <item relType="HAS ACQ CONTEXT" valType="CODE" >
            <concept codScheme="DCM" codValue="111031" >Image View</concept>
            <value codScheme="SNM3" codValue="R-10242" >cranio-caudal</value>
          </item>
          <item relType="HAS ACQ CONTEXT" valType="TEXT" >
            <concept codScheme="DCM" codValue="111044" >Patient Orientation Row</concept>
            <value>P</value>
          </item>
[...]
Alternatively, one could look directly in the dcmtk source files and try to figure out how is generated that part, but that would require several supplementary orders of magnitude of extra time. :-)
2. How does one insert the reference to some image (and further DTID 4020 "CAD Image Library Entry") in the "Image Library" subnode?
There are examples for IMAGE content items in "mkreport.cc".
As it can be noticed from the above quotes, the insertion is ok, there are some problems with further implementation of RT_hasAcqContext. Maybe answering to the first question would put me on the right track for solving the second implementation issue.

Thank you very much for your time and your help.

Regards,
Z.B.

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

#8 Post by Jörg Riesmeier »

By comparison of the results, one can note the part about "Language of Content Item and Descendants" at the beginning, which has been created in some way by xml2dsr (I suppose this command uses the methods and the classes provided by dcmtk).
The two additional content items have not been created "in some way" by xml2dsr, they have been created by xml2dsr because they are part of the XML input file.
Admitted that INCLUDE statement and some of part 16 templates are not currently supported by dcmtk, there is still an useful CAD SR file which can be obtained by using one of its commands.
Actually, the "INCLUDE statement" is not part of the SR document tree, it is just a way of the authors of part 16 to specify the inclusion of a sub-template. For you as a software developer, it means that you have to expand all content items of the sub-template at the line where the INCLUDE statement is found.
I am willing to write manually any piece of code, but I don't know what to write in in order to get those two lines. Any tip would be highly appreciated.
Just add the corresponding content items ("has concept mod CODE") in the same way as you did that before :-)

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

#9 Post by zappy1 »

Thank you for the quick reply.
Jörg Riesmeier wrote:
By comparison of the results, one can note the part about "Language of Content Item and Descendants" at the beginning, which has been created in some way by xml2dsr (I suppose this command uses the methods and the classes provided by dcmtk).
The two additional content items have not been created "in some way" by xml2dsr, they have been created by xml2dsr because they are part of the XML input file.
That was overwhelmingly obvious (otherwise why would I've quoted from the xml file?!). The words "in some way" refer to the sequence of code statements translating the xml lines

Code: Select all

<item relType="HAS CONCEPT MOD" valType="CODE" > 
        <concept codScheme="DCM" codValue="121049" >Language of Content Item and Descendants</concept> 
        <item relType="HAS CONCEPT MOD" valType="CODE" > 
          <concept codScheme="DCM" codValue="121046" >Country of Language</concept> 
          <value codScheme="ISO3166_1" codValue="US" >UNITED STATES</value> 
        </item> 
        <value codScheme="ISO639_2" codValue="eng" >English</value> 
      </item>
in the dicom sequence of bytes inserted at the right point, dsrdumped as
<has concept mod CODE:(,,"Language of Content Item and Descendants")=(eng,ISO639_2,"English")>
<has concept mod CODE:(,,"Country of Language")=(US,ISO3166_1,"UNITED STATES")>

a sequence I cannot guess yet.
Actually, the "INCLUDE statement" is not part of the SR document tree, it is just a way of the authors of part 16 to specify the inclusion of a sub-template. For you as a spftware developer, it means that you have to expand all content items of the sub-template at the line where the INCLUDE statement is found.
Ok, that was quite clear since the starting from scratch.
I am willing to write manually any piece of code, but I don't know what to write in in order to get those two lines. Any tip would be highly appreciated.
Just add the corresponding content items ("has concept mod CODE") in the same way as you did that before :-)
Ummm... have I done that before?!
Actually, I did (the "has concept mod CODE" part), and I wasn't satisfied at all with the result. If after

Code: Select all

doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111036", "DCM", "Mammography CAD Report"));
I insert the following two lines

Code: Select all

doc->getTree().addContentItem(DSRTypes::RT_hasConceptMod, DSRTypes::VT_Code, DSRTypes::AM_belowCurrent);
doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("121049", "DCM", "Language of Content Item and Descendants"));
the resulting SR is not valid:
$dsrdump -dd SRF
DCMSR - Warning: Check for template constraints not yet supported
DCMSR - Warning: ConceptCodeSequence empty in content item (type 1)
DCMSR - Warning: Reading invalid/incomplete content item CODE "1.1"
DCMSR - Error: Reading content item CODE "1.1" (Invalid Document Tree)
------------------------------- DICOM DATA SET -------------------------------
(fffe,e000) na (Item with undefined length #=4) # u/l, 1 Item
(0040,a010) CS [HAS CONCEPT MOD] # 16, 1 RelationshipType
(0040,a040) CS

Code: Select all

                                   #   4, 1 ValueType
  (0040,a043) SQ (Sequence with undefined length #=1)     # u/l, 1 ConceptNameCodeSequence
    (fffe,e000) na (Item with undefined length #=3)         # u/l, 1 Item
      (0008,0100) SH [meep]                                   #   4, 1 CodeValue
      (0008,0102) SH [beep]                                   #   4, 1 CodingSchemeDesignator
      (0008,0104) LO [deep]                                   #   4, 1 CodeMeaning
    (fffe,e00d) na (ItemDelimitationItem)                   #   0, 0 ItemDelimitationItem
  (fffe,e0dd) na (SequenceDelimitationItem)               #   0, 0 SequenceDelimitationItem
  (0040,a168) SQ (Sequence with undefined length #=0)     # u/l, 1 ConceptCodeSequence
  (fffe,e0dd) na (SequenceDelimitationItem)               #   0, 0 SequenceDelimitationItem
(fffe,e00d) na (ItemDelimitationItem)                   #   0, 0 ItemDelimitationItem
------------------------------------------------------------------------------
dsrdump: error (Invalid Document Tree) parsing file: SRF[/color]

  If I change the first inserted line into 
[i]doc->getTree().addContentItem(DSRTypes::RT_hasConceptMod, DSRTypes::VT_Code, DSRTypes::AM_afterCurrent);[/i] or in 
[i]doc->getTree().addContentItem(DSRTypes::RT_hasConceptMod, DSRTypes::VT_Code);[/i] the result becomes valid but does not match my intentions:
[color=red]$dsrdump -dd SRF
 DCMSR - Warning: Check for template constraints not yet supported
Mammography CAD SR Document

Patient            : SBI2007^Scenario 6 (F, 19010101, #SBIPT008)
Completion Flag    : PARTIAL
Verification Flag  : UNVERIFIED
Content Date/Time  : 20080710 170707

<CONTAINER:(,,"Language of Content Item and Descendants")=SEPARATE>
  <contains CONTAINER:(,,"Image library")=SEPARATE>
    <contains IMAGE:(,,"deep")=(DPm image,)>[/color]

 and I lose the information about "Mammography CAD Report" in the first container.
 What am I doing wrong?

  Thank you again.

    Regards,
                   Z.B.

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

#10 Post by Jörg Riesmeier »

Since I still do not understand where your problem is, here's an example that I wrote from scratch:

Code: Select all

#include "dcmtk/config/osconfig.h"

#include "dcmtk/dcmsr/dsrdoc.h"
#include "dcmtk/dcmdata/dcfilefo.h"


int main()
{
  DSRDocument *doc = new DSRDocument();
  if (doc != NULL)
  {
    doc->createNewDocument(DSRTypes::DT_MammographyCadSR);

    doc->setPatientsName("Last Name^First Name");
    doc->setPatientsSex("O");
    doc->setManufacturer("OFFIS e.V.");
    doc->setReferringPhysiciansName("Last Name^First Name");

    doc->getTree().addContentItem(DSRTypes::RT_isRoot, DSRTypes::VT_Container);
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111036", "DCM", "Mammography CAD Report"));
    doc->getTree().getCurrentContentItem().setTemplateIdentification("4000","DCMR"); 

    doc->getTree().addContentItem(DSRTypes::RT_hasConceptMod, DSRTypes::VT_Code, DSRTypes::AM_belowCurrent); 
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("121049", "DCM", "Language of Content Item and Descendants"));
    doc->getTree().getCurrentContentItem().setCodeValue(DSRCodedEntryValue("eng","ISO639_2","English"));

    doc->getTree().addContentItem(DSRTypes::RT_hasConceptMod, DSRTypes::VT_Code, DSRTypes::AM_belowCurrent); 
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("121046", "DCM", "Country of Language"));
    doc->getTree().getCurrentContentItem().setCodeValue(DSRCodedEntryValue("US","ISO3166_1","UNITED STATES"));

    doc->getTree().goUp();

    doc->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Container); 
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111028", "DCM", "Image Library"));

    /* proceed with adding content items according to TID 4000 ... */

    DcmFileFormat *fileformat = new DcmFileFormat();
    DcmDataset *dataset = NULL;
    if (fileformat != NULL)
      dataset = fileformat->getDataset();
    if (dataset != NULL)
    {
      if (doc->write(*dataset).good())
        fileformat->saveFile("mamcadsr.dcm", EXS_LittleEndianExplicit);
    }
    delete fileformat;
  }
  delete doc;
   
  return 0; 
}
This creates the following SR document (output by dsrdump):

Code: Select all

Mammography CAD SR Document

Patient            : Last Name^First Name (O)
Referring Physician: Last Name^First Name
Manufacturer       : OFFIS e.V.
Completion Flag    : PARTIAL
Verification Flag  : UNVERIFIED
Content Date/Time  : 20080710 175805

<CONTAINER:(111036,DCM,"Mammography CAD Report")=SEPARATE>  # TID 4000 (DCMR)
  <has concept mod CODE:(121049,DCM,"Language of Content Item and Descendants")=(eng,ISO639_2,"English")>
    <has concept mod CODE:(121046,DCM,"Country of Language")=(US,ISO3166_1,"UNITED STATES")>
  <contains CONTAINER:(111028,DCM,"Image Library")=SEPARATE>
  ...
I hope this helps.

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

#11 Post by zappy1 »

Jörg Riesmeier wrote:Since I still do not understand where your problem is, here's an example that I wrote from scratch:

Code: Select all

   [...]
    doc->getTree().addContentItem(DSRTypes::RT_hasConceptMod, DSRTypes::VT_Code, DSRTypes::AM_belowCurrent); 
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("121049", "DCM", "Language of Content Item and Descendants"));
    doc->getTree().getCurrentContentItem().setCodeValue(DSRCodedEntryValue("eng","ISO639_2","English"));

    doc->getTree().addContentItem(DSRTypes::RT_hasConceptMod, DSRTypes::VT_Code, DSRTypes::AM_belowCurrent); 
    doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("121046", "DCM", "Country of Language"));
    doc->getTree().getCurrentContentItem().setCodeValue(DSRCodedEntryValue("US","ISO3166_1","UNITED STATES"));

    doc->getTree().goUp();
 [...]
Ok, I got the point. The problem was the compulsory use of the method setCodeValue() in a VT_Code entry, after setConceptName(), use which was sadly missing in my previous codes. In the xml file, the value part is at the very end of the subtree, and it looks like its setting should be the last operation; actually, it isn't.
I hope this helps.
Yes, it was very helpful. Thank you very much for your answers.

Regards,
Z.B.

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

#12 Post by Jörg Riesmeier »

The problem was the compulsory use of the method setCodeValue() in a VT_Code entry, after setConceptName(), use which was sadly missing in my previous codes.
Of course, you have to specify the code value for a CODE content items - this is the content of this node!
In the xml file, the value part is at the very end of the subtree, and it looks like its setting should be the last operation; actually, it isn't.
The order of calling setConceptName() and setCodeValue() is arbitrary, if this was the question. The structure of the XML file (created by dsr2xml) is only indirectly related to the internal structure of the DICOM SR document or the order in which you calling the methods of the dcmsr module.

So, basically, you have to understand the underlying DICOM SR model first ...

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

#13 Post by zappy1 »

Jörg Riesmeier wrote:
The problem was the compulsory use of the method setCodeValue() in a VT_Code entry, after setConceptName(), use which was sadly missing in my previous codes.
Of course, you have to specify the code value for a CODE content items - this is the content of this node!
Of course, but I was thinking at writing the code value in a second moment (that is: insert code line, compile, check result->ok, insert next code line, compile, check result->ok, usw.); it turns out that some code lines must come together, otherwise the resulting SR is not valid.
In the xml file, the value part is at the very end of the subtree, and it looks like its setting should be the last operation; actually, it isn't.
The order of calling setConceptName() and setCodeValue() is arbitrary, if this was the question.[...]
It was not a question but the explanation of my error. :-)

Meanwhile, my CAD SR grew up with several dozens of code lines. I am now trying to write SCOORD data (that is: something to be dsrdumped as

Code: Select all

<has properties SCOORD:(,,"Center")=(POINT,2449/3077)>
It should supposedly start like

Code: Select all

doc->getTree().addContentItem(DSRTypes::RT_hasProperties, DSRTypes::VT_SCoord, DSRTypes::AM_afterCurrent);
doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("111010", "DCM", "Center"));
and contain another line(s) for the data. What classes and methods should I use, and what new objects should I define?!

Thank you again for your patience.

Regards,
Z.B.

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

#14 Post by Jörg Riesmeier »

Here's another code fragment that I copied from a small test program.

Basically, there are two ways of adding and filling an SCOORD content item:

Code: Select all

 doc->getTree().addContentItem(DSRTypes::RT_hasProperties, DSRTypes::VT_SCoord);
 doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("1234", OFFIS_CODING_SCHEME_DESIGNATOR, "SCoord Code"));
 DSRSpatialCoordinatesValue *scoordPtr = doc->getTree().getCurrentContentItem().getSpatialCoordinatesPtr();
 if (scoordPtr != NULL)
 {
     scoordPtr->setGraphicType(DSRTypes::GT_Circle);
     scoordPtr->getGraphicDataList().addItem(0, 0);
     scoordPtr->getGraphicDataList().addItem(255, 255);
 }
or

Code: Select all

 doc->getTree().addContentItem(DSRTypes::RT_hasProperties, DSRTypes::VT_SCoord);
 doc->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("1234", OFFIS_CODING_SCHEME_DESIGNATOR, "SCoord Code"));
 DSRSpatialCoordinatesValue spatialCoord(DSRTypes::GT_Circle);
 spatialCoord.getGraphicDataList().addItem(0, 0);
 spatialCoord.getGraphicDataList().addItem(255, 255);
 doc->getTree().getCurrentContentItem().setSpatialCoordinates(spatialCoord);

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

#15 Post by zappy1 »

Jörg Riesmeier wrote:Here's another code fragment that I copied from a small test program.
Basically, there are two ways of adding and filling an SCOORD content item:
[...]
Thank you very much again, that was exactly one of the essential missing parts.
At this very moment, I generated a minimal CAD SR file, something dsrdumping out this:

Code: Select all

Mammography CAD SR Document

Patient            : SBI2007^Scenario 6 (F, 19010101, #SBIPT008)
Completion Flag    : PARTIAL
Verification Flag  : UNVERIFIED
Content Date/Time  : 20080714 125024

<CONTAINER:(,,"Mammography CAD Report")=SEPARATE>
  <has concept mod CODE:(,,"Language of Content Item and Descendants")=(eng,ISO639_2,"English")>
    <has concept mod CODE:(,,"Country of Language")=(US,ISO3166_1,"UNITED STATES")>
  <contains CONTAINER:(,,"Image library")=SEPARATE>
    <contains IMAGE:=(DPm image,)>
      <has acq context CODE:(,,"Image Laterality")=(T-04030,SNM3,"Left breast")>
  <contains CODE:(,,"CAD Processing and Findings Summary")=(111242,DCM,"All algorithms succeeded; with findings")>
    <inferred from CONTAINER:(,,"Individual Impression/Recommendation")=SEPARATE>
      <has concept mod CODE:(,,"Rendering Intent")=(111150,DCM,"Presentation Required: Rendering device is expected to present")>
      <contains CODE:(,,"Single Image Finding")=(F-01796,SRT[1.1],"Mammography breast density")>
        <has concept mod CODE:(,,"Rendering Intent")=(111150,DCM,"Presentation Required: Rendering device is expected to present")>
        <has properties TEXT:(,,"Algorithm Name")="My_CAD">
        <has properties TEXT:(,,"Algorithm Version")="1.0.0">
        <has properties TEXT:(,,"Algorithm Parameters")="none">
        <has properties SCOORD:(,,"SCoord Code")=(POINT,2200/3000)>
The JiveX interface does not display the point on the chosen image, this being my first aimed result. :(
As far as I can see, there can be two main reasons for this behaviour:
  • 1. I have to insert all image tags in the CAD SR file (including Image View, Patient Orientation, Pixel Spacings...) in order to make it fully compatible with coresponding image;
    2. From the XML file corresponding to the original R2 produced CAD SR, the images seem to have been assigned an internal conventional ID (the first one is "5", then "16/27/38") which doesn't appear in the dsrdump. The reference appears as <image id="5" > in the "IMAGE" declaration, then it's called in the "SCOORD" node:

Code: Select all

<scoord type="POINT" >
    <relationship>HAS PROPERTIES</relationship>
    <concept>
      <value>111010</value>
      <scheme>
        <designator>DCM</designator>
      </scheme>
      <meaning>Center</meaning>
    </concept>
    <reference ref="5" >
      <relationship>SELECTED FROM</relationship>
    </reference>
    <data>2449/3077</data>
  </scoord>
My first guess would be that referencing is the essential issue.
Related questions:
  • 1. should one use a conventional reference system (R2-like, with "5" for RCC, "16" for LCC, "27" for RMLO, "38" for LMLO) or one can use an absolute system based on unique instance uid of the image?!
    2. how does one introduce a conventional reference id for the IMAGE item and in the SCOORD content item?
Thank you again for your most valuable help.

Regards,
Z.B.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Majestic-12 [Bot] and 1 guest