DICOM @ OFFIS

Discussion Forum for OFFIS DICOM Tools - For registration, send email with desired user name to the OFFIS DICOM team
It is currently Fri, 2018-01-19, 20:33

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Tue, 2017-12-19, 17:29 
Offline

Joined: Wed, 2015-09-02, 09:24
Posts: 34
Hi,
For multiframe dicom file, we often see groups of repeating tags, which are meant for individual frames:
Quote:
0018,0060 KVP: 27
0018,1405 Relative X-Ray Exposure: 2738
0018,1510 Positioner Primary Angle: 10.850034
0018,1511 Positioner Secondary Angle: 0
0018,9328 Exposure Time in ms: 88.0
0018,9330 X-Ray Tube Current in mA: 133.0
0018,9332 Exposure in mAs: 11.82
0040,0316 Organ Dose: 0.00135
0040,8302 Entrance Dose in mGy: 0.407
0018,0060 KVP: 27
0018,1405 Relative X-Ray Exposure: 2638
0018,1510 Positioner Primary Angle: 13.624145
0018,1511 Positioner Secondary Angle: 0
0018,9328 Exposure Time in ms: 87.0
0018,9330 X-Ray Tube Current in mA: 133.0
0018,9332 Exposure in mAs: 11.75
0040,0316 Organ Dose: 0.00134
0040,8302 Entrance Dose in mGy: 0.405
0018,0060 KVP: 27
0018,1405 ...
Even worse, for many cases, we find all of these tags appearing in every single file if the original multiframe file is expanded at the time of export (from the system).

I wonder what would be the best way to read such information? Does DCMTK has an interface that aligns such data in an array or a list? I wouldn't mind making one but it seems only one (first) value is returned by e.g. DcmItem::findAndGetOFString(). Can the 'searchIntoSub' flag help in such cases? Thanks!


Top
 Profile  
 
PostPosted: Thu, 2017-12-21, 21:52 
Offline
DCMTK Developer

Joined: Fri, 2004-11-05, 13:47
Posts: 1661
Location: Oldenburg, Germany
Hi,

just to be sure...all thee attributes actually appear on the same level, i.e. not in different items of a Sequence?

Best,
Michael


Top
 Profile  
 
PostPosted: Fri, 2017-12-22, 13:39 
Offline

Joined: Wed, 2015-09-02, 09:24
Posts: 34
Hi Michael,
Sorry for the confusion. They can be nested in a sequence, enclosed with (fffe,e000) and (fffe,e00d). Does it make a difference? Instead of iterating over all items, is there an interface to read and organize them directly?
Thanks!


Top
 Profile  
 
PostPosted: Fri, 2017-12-22, 13:42 
Offline
DCMTK Developer

Joined: Fri, 2004-11-05, 13:47
Posts: 1661
Location: Oldenburg, Germany
Hi,

kind of. There is a module called dcmfg which permits you to access each of these items (called Functional Groups in DICOM, hence the name dcmfg) by frame number, using a dedicated API. However, not all functional groups (i.e. attribute collections) are supported. But some common ones are there.

The main interface is in the class FGInterface.

Best regards,
Michael


Top
 Profile  
 
PostPosted: Fri, 2017-12-22, 14:27 
Offline

Joined: Wed, 2015-09-02, 09:24
Posts: 34
Thanks for the hint!
Suppose the functional groups are supported, I should first use
Code:
FGInterface::read(DcmItem &dataset)
to create the list and next
Code:
FGBase * FGInterface::get(const Uint32 frameNo, const DcmFGTypes::E_FGType fgType)
to obtain the per-frame information, right? Then, how do I go from each group to individual tags? Do I rewrite by
Code:
FGBase::write(DcmItem & item)
to a new DcmItem?


Top
 Profile  
 
PostPosted: Fri, 2017-12-22, 15:49 
Offline
DCMTK Developer

Joined: Fri, 2004-11-05, 13:47
Posts: 1661
Location: Oldenburg, Germany
Yes, that's how it works. For FGInterface::read() you should provide the main dataset. FGInterface will extract the data from the Per-Frame and Shared Functional Group Sequence which are part of the main dataset level. Thus the whole dcmfg library is meant for working with these two sequences (for the general purpose approach see my notes about dcmdata below).

After FGInterface read the data, you do not need to write the attributes into another item to access them (this is functionality needed if you want to create functional groups from scratch and to write them into a new image dataset, for example). For reading, it's the idea of the dcmfg module to have a more explicit API to access each "well-known" tags in that functional group.

All Functional Group classes allow you to call getType() (via base class FGBase) which returns an enum. Based on that enum you can cast the FGBase pointer to the related FGBase-derived class. E.g. the DcmSegmentation class does that in segdoc.cc (removed extra cast for count):
Code:
FGSegmentation* fg = OFstatic_cast(FGSegmentation*, m_FGInterface.get(count, DcmFGTypes::EFG_SEGMENTATION)); // count is the frame number

Look at fgfact.cc for the mapping of FG enum types to class names.

General Purpose dcmdata API:

If you know exactly, what you need, i.e. you dont want to handle every attribute in the item(s) but only selected ones you know beforehand, look at the general dcmdata API demonstrated here and here for the sequence part. The most important class is DcmItem.

If you actually want to iterate over the sequences/items and all of their attributes then you can see different approaches here.

Last but not least DCMTK allows you to specify your attribute search as a string "path" to the target attribute (e.g. "PerFrameFunctionalGroupsSequence[5].PixelMeasuresSequence[0].PixelSpacing", or use tag numbers if you want), you can use DcmPathProcessor. Look at the findOrCreatePath() methods. Note that this is slower than navigating through the dataset via pointers yourself since the path string has to interpreted and some extra data structures are created.

Best,
Michael


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: Bing [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group