MeVisLab Toolbox Reference
mlDicomSingleFrameSelectionTools.h
Go to the documentation of this file.
1// Copyright (c) Fraunhofer MEVIS, Germany. All rights reserved.
2// **InsertLicense** code
3//----------------------------------------------------------------------------------
5
10//----------------------------------------------------------------------------------
11
12#pragma once
13
15#include <mlModuleIncludes.h>
16#include <DCMTree_Lib.h>
17#include <DCMTree_Exception.h>
18#include <DCMTree_Tag.h>
19#include <DCMTree_Tree.h>
21
23
28namespace DicomToMLTools {
29
34 {
35 pos.resize(3);
36 pos[0] = 0;
37 pos[1] = 0;
38 pos[2] = 0;
39 }
40
45 bool isFromRootIn = false)
46 {
47 pos.resize(3);
48 pos = posIn;
49 tagId = rawTagIdIn;
50 tagPtr = tagPtrIn;
51 isFromRoot = isFromRootIn;
52 }
53
56
59
61 inline void setPos(unsigned int z, unsigned int t, unsigned int u)
62 {
63 pos.resize(3);
64 pos[0] = z;
65 pos[1] = t;
66 pos[2] = u;
67 }
68
76 bool doFrameExistsAtPosCheck = true,
77 bool frameExistsAtPosIn = false)
78 {
79 // Check whether we have a specific frame to search the tags.
80 boost::uint32_t gridDimension = smfTree.getGridDimension();
82 //localPos.resize(gridDimension);
83 //std::cerr << "gridDimension = " << gridDimension << std::endl;
84 //std::cerr << "doFrameExistsAtPosCheck = " << doFrameExistsAtPosCheck << std::endl;
85 //std::cerr << "frameExistsAtPosIn = " << frameExistsAtPosIn << std::endl;
86 //std::cerr << "checking at ( " << localPos[0] << ", " << localPos[1] << ", " << localPos[2] << ")" << std::endl;
88
89 // Determine at most z, t, and u dimension extents if they are available.
91 const unsigned int zExt = gridExtent.size() > 0u ? gridExtent[0] : 1u;
92 const unsigned int tExt = gridExtent.size() > 1u ? gridExtent[1] : 1u;
93 const unsigned int uExt = gridExtent.size() > 2u ? gridExtent[2] : 1u;
94
95 // Clamp position to an existing frame position, which, however, is difficult to understand.
96 // Important for understanding: The highest existing grid dimension (often the temporal one) is the highest level in SMF dicom
97 // (i.e. the entries in root-nearest SMF-sequence), and spatial tags are entries of an SMF sequence
98 // inside of items of the temporal ones (i.e. often the leaves).
99 // Examples:
100 // gridExtent=(5,10,1), position=(0,0,10): u-frame does not exist and is outside valid dimensions, the tree root should be taken instead.
101 // gridExtent=(1,10,1), position=(10,2,0): z-frame does not exist, however, it is located inside a valid temporal extent, i.e.
102 // it should be taken from frame (0,2,0), because the temporal tree level contains tags also
103 // valid for its spatial subtrees.
104 // That means: Spatial spatial positions should be clamped to the maximum grid extent in z if its temporal extent is located inside a valid range,
105 // but a temporal location outside the valid range should return no valid frame if there is no valid u-dimension.
106 // u-locations outside always should return no valid frame.
107 // Anyway: If temporal or spatial dimensions in tree do not match the extents of the image, these checks do not really make sense any more.
108 // Therefore: getting reliable rescale/slope values, for example, will only work reliably if the tree has real frame entries and the tree
109 // really matches the image extents.
110 if (gridDimension > 0){
111 // spatial dimension is valid.
112 if (localPos[0] >= zExt){
113 if (gridDimension < 2){
114 // temporal dimension does not exist, i.e. z is also out of range.
115 frameExistsAtPos = false;
116 }
117 else{
118 // t exist, i.e. z can be clamped if t location is in valid range.
119 if (localPos[1] < tExt) {
120 localPos[0] = zExt-1;
121 }
122 }
123 }
124 }
125 if (gridDimension > 1){
126 // temporal dimension is valid.
127 if (localPos[1] >= tExt){
128 if (gridDimension < 3){
129 // u dimension does not exist, i.e. t is also out of range.
130 frameExistsAtPos = false;
131 }
132 else{
133 // u dimension exists, i.e. t can be clamped if u location is in valid range.
134 if (localPos[2] < uExt) {
135 localPos[1] = uExt-1;
136 }
137 }
138 }
139 }
140 if (localPos[2] >= uExt){
141 // u locations outside are never part of higher dimensions and thefore are always out of range if not in corresponding grid extent.
142 frameExistsAtPos = false;
143 }
144 //std::cerr << "gridExt = (" << zExt << ", "<< tExt << ", "<< uExt << ")" << std::endl;
145
146 //std::cerr << "calculated frameExistsAtPos = " << frameExistsAtPos << std::endl;
147 tagPtr.reset();
148 isFromRoot = false;
149 try {
150 // Get the tag from the frame if it exists; if not then get it from the normal tree.
151 if (frameExistsAtPos) {
152 //std::cerr << "Frame exists at localPos, getting tag for grid position" << std::endl;
153 tagPtr = smfTree.tagForGridPosition(tagId, localPos);
154 if (!tagPtr){
155 // Here we have the same problem as we have it with validity of frames, we need to look for the tags
156 // e.g. in the temporal tree level if the spatial does not exist.
157 //std::cerr << "tag not found, checking upper dimension! TODO/TOTEST!" << std::endl;
158 }
159 }
160 if(!tagPtr && smfTree.tagTree()){
161 tagPtr = smfTree.tagTree()->getTag(tagId);
162 if (tagPtr){ isFromRoot = true; }
163 }
164 }
165 catch (DCMTree::Exception&) {
166 // Ignore, the frame does not exist or the tag was not found.
167 //std::cerr << "Exiting with exception from getTagForGridPosition!" << std::endl;
168 }
169 }
170
173
176
179
181 bool isFromRoot = false;
182 };
183
186 template <typename VALUE_TYPE>
190
193
196
199 frameSpecificTag(frameSpecificTagIn),
200 value(valueIn),
201 valueIsValid(valueIsValidIn){}
202
204 template <typename GET_VALUE_FUNC_TYPE>
206 const unsigned int z, const unsigned int t, const unsigned int u,
207 const DCMTree::RawTagId rawTagId,
209 {
210 frameSpecificTag.setPos(z,t,u);
211 frameSpecificTag.tagId = rawTagId;
212 // Determine pos and isFromRoot.
213 frameSpecificTag.setUpFrameSpecificTagInfos(smfTree, true, false);
214
215 try{
216 if (frameSpecificTag.tagPtr){
217 // Try to convert/get the tag value; throws on failure.
218 value = getTagValueFunc(frameSpecificTag.tagPtr);
219 valueIsValid = true;
220 }
221 }
222 catch(const DCMTree::Exception &){}
223 }
224
227
230
232 bool valueIsValid = false;
233 };
234
239 const unsigned int z, const unsigned int t, const unsigned int u,
240 const DCMTree::RawTagId rawTagId,
242 {
243 valTagInfos.getFrameSpecificValueTag(smfTree, z,t,u, rawTagId, [](DCMTree::Const_TagPtr tagPtr) { return tagPtr ? tagPtr->toDouble() : 0.; } );
244 }
245
246
249 const unsigned int z, const unsigned int t, const unsigned int u,
250 const DCMTree::RawTagId rawTagId,
252 {
253 valTagInfos.getFrameSpecificValueTag(smfTree, z,t,u, rawTagId, [](DCMTree::Const_TagPtr tagPtr) { return tagPtr ? tagPtr->toString() : std::string(); } );
254 }
255
256};
257
Project global and OS specific declarations.
Exception class for DCMTree.
Support for structured multi-frame (SMF) DICOM objects.
std::vector< unsigned int > IndexVector
Index vector type, ordered as (z, t, u1, u2, ...)
Target mlrange_cast(Source arg)
Generic version of checked ML casts.
boost::shared_ptr< const Tag > Const_TagPtr
Definition DCMTree_Lib.h:63
unsigned int RawTagId
void getFrameSpecificStringTag(const DCMTree::StructuredMF &smfTree, const unsigned int z, const unsigned int t, const unsigned int u, const DCMTree::RawTagId rawTagId, FrameSpecificValueTag< std::string > &valTagInfos)
Same as getFrameSpecificDoubleTag() but for std::string values.
void getFrameSpecificDoubleTag(const DCMTree::StructuredMF &smfTree, const unsigned int z, const unsigned int t, const unsigned int u, const DCMTree::RawTagId rawTagId, FrameSpecificValueTag< double > &valTagInfos)
Retrieves a double tag value from a frame specific tag with id rawTagId at (z,t,u) from smfTree,...
A struct containing a information about a specific frame (position, tagId, tagPtr,...
FrameSpecificTag(const DCMTree::StructuredMF::IndexVector &posIn, DCMTree::RawTagId rawTagIdIn=0, DCMTree::Const_TagPtr tagPtrIn=DCMTree::Const_TagPtr(), bool isFromRootIn=false)
Convenience constructor, posIn must have three entries.
void setPos(unsigned int z, unsigned int t, unsigned int u)
Sets pos to the three components z, t, and u.
DCMTree::StructuredMF::IndexVector pos
The position of the tag in the frame tree; must always be scaled to 3 components.
void setUpFrameSpecificTagInfos(const DCMTree::StructuredMF &smfTree, bool doFrameExistsAtPosCheck=true, bool frameExistsAtPosIn=false)
Sets up tagPtr and isFromRoot by using corresponding information from smfTree, pos,...
FrameSpecificTag(const FrameSpecificTag &inputInfos)=default
Default copy constructor.
FrameSpecificTag & operator=(const FrameSpecificTag &inputInfos)=default
Default assignment operator.
DCMTree::Const_TagPtr tagPtr
The ConstTagPtr to the tag.
A struct containing a information about a specific frame (position, tagId, tagPtr,...
FrameSpecificValueTag(const FrameSpecificValueTag &inputInfos)=default
Default copy constructor.
FrameSpecificValueTag & operator=(const FrameSpecificValueTag &inputInfos)=default
Default assignment operator.
FrameSpecificValueTag(const FrameSpecificTag &frameSpecificTagIn, VALUE_TYPE valueIn, bool valueIsValidIn)
Convenience constructor, initializing all members.
void getFrameSpecificValueTag(const DCMTree::StructuredMF &smfTree, const unsigned int z, const unsigned int t, const unsigned int u, const DCMTree::RawTagId rawTagId, const GET_VALUE_FUNC_TYPE &getTagValueFunc)
Get a tag with if tagId from a given subtree in smfTree at (z,t,u) by using the getTagValueFunc as ac...