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 
14 #include "MLDicomToMLToolsSystem.h"
15 #include <mlModuleIncludes.h>
16 #include <DCMTree_Lib.h>
17 #include <DCMTree_Exception.h>
18 #include <DCMTree_Tag.h>
19 #include <DCMTree_Tree.h>
20 #include <DCMTree_StructuredMF.h>
21 
22 ML_START_NAMESPACE
23 
28 namespace DicomToMLTools {
29 
34  {
35  pos.resize(3);
36  pos[0] = 0;
37  pos[1] = 0;
38  pos[2] = 0;
39  }
40 
43  DCMTree::RawTagId rawTagIdIn = 0,
45  bool isFromRootIn = false)
46  {
47  pos.resize(3);
48  pos = posIn;
49  tagId = rawTagIdIn;
50  tagPtr = tagPtrIn;
51  isFromRoot = isFromRootIn;
52  }
53 
55  inline FrameSpecificTag(const FrameSpecificTag &inputInfos) = default;
56 
58  inline FrameSpecificTag& operator=(const FrameSpecificTag &inputInfos) = default;
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;
87  bool frameExistsAtPos = doFrameExistsAtPosCheck ? (smfTree.tagTree() ? true : false) : frameExistsAtPosIn;
88 
89  // Determine at most z, t, and u dimension extents if they are available.
90  const DCMTree::StructuredMF::IndexVector gridExtent = smfTree.getGridExtent();
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 
175  DCMTree::RawTagId tagId = 0;
176 
179 
181  bool isFromRoot = false;
182  };
183 
186  template <typename VALUE_TYPE>
190 
192  inline FrameSpecificValueTag(const FrameSpecificValueTag &inputInfos) = default;
193 
195  inline FrameSpecificValueTag& operator=(const FrameSpecificValueTag &inputInfos) = default;
196 
198  inline FrameSpecificValueTag(const FrameSpecificTag& frameSpecificTagIn, VALUE_TYPE valueIn, bool valueIsValidIn) :
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,
208  const GET_VALUE_FUNC_TYPE & getTagValueFunc)
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 
229  VALUE_TYPE value;
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,
241  FrameSpecificValueTag<double> &valTagInfos)
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 
258 ML_END_NAMESPACE
Project global and OS specific declarations.
Exception class for DCMTree.
Support for structured multi-frame (SMF) DICOM objects.
const IndexVector & getGridExtent() const
Get the extents of the logical grid (i.e. the size in each dimension)
Const_TreePtr tagTree() const
Return a const pointer to the contained tag tree.
Const_TagPtr tagForGridPosition(TagId tagId, IndexVector gridPosition) const
Get a pointer to the specified tag for a given grid position.
boost::uint32_t getGridDimension() const
Get the dimension of the logical grid (i.e. the number of dimensions)
std::vector< unsigned int > IndexVector
Index vector type, ordered as (z, t, u1, u2, ...)
boost::shared_ptr< const Tag > Const_TagPtr
Definition: DCMTree_Lib.h:63
unsigned int RawTagId
Definition: DCMTree_Lib.h:147
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(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...
FrameSpecificValueTag & operator=(const FrameSpecificValueTag &inputInfos)=default
Default assignment operator.