Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDICOMReaderConfigurator.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 
19 #include "mitkDICOMSortByTag.h"
21 
24 {
25 }
26 
29 {
30 }
31 
34 ::CreateFromConfigFile(const std::string& filename) const
35 {
36  TiXmlDocument doc (filename);
37  if (doc.LoadFile())
38  {
39  return this->CreateFromTiXmlDocument( doc );
40  }
41  else
42  {
43  MITK_ERROR << "Unable to load file at '" << filename <<"'";
44  return DICOMFileReader::Pointer();
45  }
46 }
47 
50 ::CreateFromUTF8ConfigString(const std::string& xmlContents) const
51 {
52  TiXmlDocument doc;
53  doc.Parse(xmlContents.c_str(), nullptr, TIXML_ENCODING_UTF8);
54 
55  return this->CreateFromTiXmlDocument( doc );
56 }
57 
59 mitk::DICOMReaderConfigurator
60 ::CreateFromTiXmlDocument(TiXmlDocument& doc) const
61 {
62  TiXmlHandle root(doc.RootElement());
63 
64  if (TiXmlElement* rootElement = root.ToElement())
65  {
66  if (strcmp(rootElement->Value(), "DICOMFileReader")) // :-( no std::string methods
67  {
68  MITK_ERROR << "File should contain a <DICOMFileReader> tag at top-level! Found '"
69  << (rootElement->Value() ? std::string(rootElement->Value()) : std::string("!nothing!")) << "' instead";
70  return nullptr;
71  }
72 
73  const char* classnameC = rootElement->Attribute("class");
74  if (!classnameC)
75  {
76  MITK_ERROR << "File should name a reader class in the class attribute: <DICOMFileReader class=\"...\">. Found nothing instead";
77  return nullptr;
78  }
79 
80  int version(1);
81  if ( rootElement->QueryIntAttribute("version", &version) == TIXML_SUCCESS)
82  {
83  if (version != 1)
84  {
85  MITK_WARN << "This reader is only capable of creating DICOMFileReaders of version 1. "
86  << "Will not continue, because given configuration is meant for version " << version << ".";
87  return nullptr;
88  }
89  }
90  else
91  {
92  MITK_ERROR << "File should name the version of the reader class in the version attribute: <DICOMFileReader class=\"" << classnameC << "\" version=\"...\">."
93  << " Found nothing instead, assuming version 1!";
94  version = 1;
95  }
96 
97  std::string classname(classnameC);
98 
99  double decimalPlacesForOrientation(5);
100  bool useDecimalPlacesForOrientation(false);
101  useDecimalPlacesForOrientation =
102  rootElement->QueryDoubleAttribute("decimalPlacesForOrientation", &decimalPlacesForOrientation) == TIXML_SUCCESS; // attribute present and a double value
103 
104  if (classname == "ClassicDICOMSeriesReader")
105  {
107  this->ConfigureCommonPropertiesOfDICOMITKSeriesGDCMReader(reader.GetPointer(), rootElement);
108  this->ConfigureCommonPropertiesOfThreeDnTDICOMSeriesReader(reader.GetPointer(), rootElement);
109  return reader.GetPointer();
110  }
111  if (classname == "ThreeDnTDICOMSeriesReader")
112  {
114  if (useDecimalPlacesForOrientation)
115  reader = mitk::ThreeDnTDICOMSeriesReader::New(decimalPlacesForOrientation);
116  else
118 
119  return ConfigureThreeDnTDICOMSeriesReader(reader, rootElement).GetPointer();
120  }
121  else
122  if (classname == "DICOMITKSeriesGDCMReader")
123  {
125  if (useDecimalPlacesForOrientation)
126  reader = mitk::DICOMITKSeriesGDCMReader::New(decimalPlacesForOrientation);
127  else
129 
130  return ConfigureDICOMITKSeriesGDCMReader(reader, rootElement).GetPointer();
131  }
132  else
133  {
134  MITK_ERROR << "DICOMFileReader tag names unknown class '" << classname << "'";
135  return nullptr;
136  }
137  }
138  else
139  {
140  MITK_ERROR << "Great confusion: no root element in XML document. Expecting a DICOMFileReader tag at top-level.";
141  return nullptr;
142  }
143 }
144 
145 #define boolStringTrue(s) \
146  ( s == "true" || s == "on" || s == "1" \
147  || s == "TRUE" || s == "ON")
148 
149 void
150 mitk::DICOMReaderConfigurator
151 ::ConfigureCommonPropertiesOfThreeDnTDICOMSeriesReader(ThreeDnTDICOMSeriesReader::Pointer reader, TiXmlElement* element) const
152 {
153  // add the "group3DnT" flag
154  bool group3DnT(true);
155  const char* group3DnTC = element->Attribute("group3DnT");
156  if (group3DnTC)
157  {
158  std::string group3DnTS(group3DnTC);
159  group3DnT = boolStringTrue(group3DnTS);
160  }
161 
162  reader->SetGroup3DandT( group3DnT );
163 }
164 
166 mitk::DICOMReaderConfigurator
167 ::ConfigureThreeDnTDICOMSeriesReader(ThreeDnTDICOMSeriesReader::Pointer reader, TiXmlElement* element) const
168 {
169  assert(element);
170 
171  // use all the base class configuration
172  if (this->ConfigureDICOMITKSeriesGDCMReader( reader.GetPointer(), element ).IsNull())
173  {
174  return nullptr;
175  }
176 
177  this->ConfigureCommonPropertiesOfThreeDnTDICOMSeriesReader(reader,element);
178  return reader;
179 }
180 
181 void
182 mitk::DICOMReaderConfigurator
183 ::ConfigureCommonPropertiesOfDICOMITKSeriesGDCMReader(DICOMITKSeriesGDCMReader::Pointer reader, TiXmlElement* element) const
184 {
185  assert(element);
186 
187  const char* configLabelC = element->Attribute("label");
188  if (configLabelC)
189  {
190  std::string configLabel(configLabelC);
191  reader->SetConfigurationLabel(configLabel);
192  }
193 
194  const char* configDescriptionC = element->Attribute("description");
195  if (configDescriptionC)
196  {
197  std::string configDescription(configDescriptionC);
198  reader->SetConfigurationDescription(configDescriptionC);
199  }
200 
201  // "fixTiltByShearing" flag
202  bool fixTiltByShearing(false);
203  const char* fixTiltByShearingC = element->Attribute("fixTiltByShearing");
204  if (fixTiltByShearingC)
205  {
206  std::string fixTiltByShearingS(fixTiltByShearingC);
207  fixTiltByShearing = boolStringTrue(fixTiltByShearingS);
208  }
209 
210  reader->SetFixTiltByShearing( fixTiltByShearing );
211 
212 }
213 
215 mitk::DICOMReaderConfigurator
216 ::ConfigureDICOMITKSeriesGDCMReader(DICOMITKSeriesGDCMReader::Pointer reader, TiXmlElement* element) const
217 {
218  assert(element);
219 
220  this->ConfigureCommonPropertiesOfDICOMITKSeriesGDCMReader(reader, element);
221 
222  // "acceptTwoSlicesGroups" flag
223  bool acceptTwoSlicesGroups(true);
224  const char* acceptTwoSlicesGroupsC = element->Attribute("acceptTwoSlicesGroups");
225  if (acceptTwoSlicesGroupsC)
226  {
227  std::string acceptTwoSlicesGroupsS(acceptTwoSlicesGroupsC);
228  acceptTwoSlicesGroups = boolStringTrue(acceptTwoSlicesGroupsS);
229  }
230 
231  reader->SetAcceptTwoSlicesGroups( acceptTwoSlicesGroups );
232 
233  // "toleratedOriginError" attribute (double)
234  bool toleratedOriginErrorIsAbsolute(false);
235  const char* toleratedOriginErrorIsAbsoluteC = element->Attribute("toleratedOriginErrorIsAbsolute");
236  if (toleratedOriginErrorIsAbsoluteC)
237  {
238  std::string toleratedOriginErrorIsAbsoluteS(toleratedOriginErrorIsAbsoluteC);
239  toleratedOriginErrorIsAbsolute = boolStringTrue(toleratedOriginErrorIsAbsoluteS);
240  }
241 
242  double toleratedOriginError(0.3);
243  if (element->QueryDoubleAttribute("toleratedOriginError", &toleratedOriginError) == TIXML_SUCCESS) // attribute present and a double value
244  {
245  if (toleratedOriginErrorIsAbsolute)
246  {
247  reader->SetToleratedOriginOffset( toleratedOriginError );
248  }
249  else
250  {
251  reader->SetToleratedOriginOffsetToAdaptive( toleratedOriginError );
252  }
253  }
254 
255  // DICOMTagBasedSorters are the only thing we create at this point
256  // TODO for-loop over all child elements of type DICOMTagBasedSorter, BUT actually a single sorter of this type is enough.
257  TiXmlElement* dElement = element->FirstChildElement("DICOMDatasetSorter");
258  if (dElement)
259  {
260  const char* classnameC = dElement->Attribute("class");
261  if (!classnameC)
262  {
263  MITK_ERROR << "File should name a DICOMDatasetSorter class in the class attribute of <DICOMDatasetSorter class=\"...\">. Found nothing instead";
264  return nullptr;
265  }
266 
267  std::string classname(classnameC);
268 
269  if (classname == "DICOMTagBasedSorter")
270  {
271  DICOMTagBasedSorter::Pointer tagSorter = CreateDICOMTagBasedSorter(dElement);
272  if (tagSorter.IsNotNull())
273  {
274  reader->AddSortingElement( tagSorter );
275  }
276  }
277  else
278  {
279  MITK_ERROR << "DICOMDatasetSorter tag names unknown class '" << classname << "'";
280  return nullptr;
281  }
282  }
283 
284  return reader;
285 }
286 
288 mitk::DICOMReaderConfigurator
289 ::CreateDICOMTagBasedSorter(TiXmlElement* element) const
290 {
292 
293  // "strictSorting" parameter!
294  bool strictSorting(true);
295  const char* strictSortingC = element->Attribute("strictSorting");
296  if (strictSortingC)
297  {
298  std::string strictSortingS(strictSortingC);
299  strictSorting = boolStringTrue(strictSortingS);
300  }
301  tagSorter->SetStrictSorting(strictSorting);
302 
303  // "strictSorting" parameter!
304  bool expectDistanceOne(true);
305  const char* expectDistanceOneC = element->Attribute("expectDistanceOne");
306  if (expectDistanceOneC)
307  {
308  std::string expectDistanceOneS(expectDistanceOneC);
309  expectDistanceOne = boolStringTrue(expectDistanceOneS);
310  }
311  tagSorter->SetExpectDistanceOne(expectDistanceOne);
312 
313  TiXmlElement* dElement = element->FirstChildElement("Distinguishing");
314  if (dElement)
315  {
316  for ( TiXmlElement* tChild = dElement->FirstChildElement();
317  tChild != nullptr;
318  tChild = tChild->NextSiblingElement() )
319  {
320  try
321  {
322  mitk::DICOMTag tag = tagFromXMLElement(tChild);
323  int i(5);
324  if (tChild->QueryIntAttribute("cutDecimalPlaces", &i) == TIXML_SUCCESS)
325  {
326  tagSorter->AddDistinguishingTag( tag, new mitk::DICOMTagBasedSorter::CutDecimalPlaces(i) );
327  }
328  else
329  {
330  tagSorter->AddDistinguishingTag( tag );
331  }
332  }
333  catch(...)
334  {
335  return nullptr;
336  }
337  }
338  }
339 
340  // "sorting tags"
341  TiXmlElement* sElement = element->FirstChildElement("Sorting");
342  if (sElement)
343  {
344  DICOMSortCriterion::Pointer previousCriterion;
345  DICOMSortCriterion::Pointer currentCriterion;
346 
347  for ( TiXmlNode* tChildNode = sElement->LastChild();
348  tChildNode != nullptr;
349  tChildNode = tChildNode->PreviousSibling() )
350  {
351  TiXmlElement* tChild = tChildNode->ToElement();
352  if (!tChild) continue;
353 
354  if (!strcmp(tChild->Value(), "Tag"))
355  {
356  try
357  {
358  currentCriterion = this->CreateDICOMSortByTag(tChild, previousCriterion);
359  }
360  catch(...)
361  {
362  std::stringstream ss;
363  ss << "Could not parse <Tag> element at (input line " << tChild->Row() << ", col. " << tChild->Column() << ")!";
364  MITK_ERROR << ss.str();
365  return nullptr;
366  }
367  }
368  else
369  if (!strcmp(tChild->Value(), "ImagePositionPatient"))
370  {
371  try
372  {
373  currentCriterion = this->CreateSortByImagePositionPatient(tChild, previousCriterion);
374  }
375  catch(...)
376  {
377  std::stringstream ss;
378  ss << "Could not parse <ImagePositionPatient> element at (input line " << tChild->Row() << ", col. " << tChild->Column() << ")!";
379  MITK_ERROR << ss.str();
380  return nullptr;
381  }
382  }
383  else
384  {
385  MITK_ERROR << "File contain unknown tag <" << tChild->Value() << "> tag as child to <Sorting>! Cannot interpret...";
386  }
387 
388  previousCriterion = currentCriterion;
389  }
390 
391  tagSorter->SetSortCriterion( currentCriterion.GetPointer() );
392  }
393 
394  return tagSorter;
395 }
396 
397 std::string
398 mitk::DICOMReaderConfigurator
399 ::requiredStringAttribute(TiXmlElement* xmlElement, const std::string& key) const
400 {
401  assert(xmlElement);
402 
403  const char* gC = xmlElement->Attribute(key.c_str());
404  if (gC)
405  {
406  std::string gS(gC);
407  return gS;
408  }
409  else
410  {
411  std::stringstream ss;
412  ss << "Expected an attribute '" << key << "' at this position "
413  "(input line " << xmlElement->Row() << ", col. " << xmlElement->Column() << ")!";
414  MITK_ERROR << ss.str();
415  throw std::invalid_argument( ss.str() );
416  }
417 }
418 
419 unsigned int
420 mitk::DICOMReaderConfigurator
421 ::hexStringToUInt(const std::string& s) const
422 {
423  std::stringstream converter(s);
424  unsigned int ui;
425  converter >> std::hex >> ui;
426  MITK_DEBUG << "Converted string '" << s << "' to unsigned int " << ui;
427  return ui;
428 }
429 
431 mitk::DICOMReaderConfigurator
432 ::tagFromXMLElement(TiXmlElement* xmlElement) const
433 {
434  assert(xmlElement);
435 
436  if (strcmp(xmlElement->Value(), "Tag")) // :-( no std::string methods
437  {
438  std::stringstream ss;
439  ss << "Expected a <Tag group=\"..\" element=\"..\"> tag at this position "
440  "(input line " << xmlElement->Row() << ", col. " << xmlElement->Column() << ")!";
441  MITK_ERROR << ss.str();
442  throw std::invalid_argument( ss.str() );
443  }
444 
445  std::string name = requiredStringAttribute(xmlElement, "name");
446  std::string groupS = requiredStringAttribute(xmlElement, "group");
447  std::string elementS = requiredStringAttribute(xmlElement, "element");
448 
449  try
450  {
451  // convert string to int (assuming string is in hex format with leading "0x" like "0x0020")
452  unsigned int group = hexStringToUInt(groupS);
453  unsigned int element = hexStringToUInt(elementS);
454  return DICOMTag(group, element);
455  }
456  catch(...)
457  {
458  std::stringstream ss;
459  ss << "Expected group and element values in <Tag group=\"..\" element=\"..\"> to be hexadecimal with leading 0x, e.g. '0x0020'"
460  "(input line " << xmlElement->Row() << ", col. " << xmlElement->Column() << ")!";
461  MITK_ERROR << ss.str();
462  throw std::invalid_argument( ss.str() );
463  }
464 }
465 
467 mitk::DICOMReaderConfigurator
468 ::CreateDICOMSortByTag(TiXmlElement* xmlElement, DICOMSortCriterion::Pointer secondaryCriterion) const
469 {
470  mitk::DICOMTag tag = tagFromXMLElement(xmlElement);
471  return DICOMSortByTag::New(tag, secondaryCriterion).GetPointer();
472 }
473 
475 mitk::DICOMReaderConfigurator
476 ::CreateSortByImagePositionPatient(TiXmlElement*, DICOMSortCriterion::Pointer secondaryCriterion) const
477 {
478  return SortByImagePositionPatient::New(secondaryCriterion).GetPointer();
479 }
480 
481 
482 
483 std::string
486 {
487  // check possible sub-classes from the most-specific one up to the most generic one
488  const DICOMFileReader* cPointer = reader;
489  TiXmlElement* root;
490  if (const ClassicDICOMSeriesReader* specificReader = dynamic_cast<const ClassicDICOMSeriesReader*>(cPointer))
491  {
492  root = this->CreateConfigStringFromReader(specificReader);
493  }
494  else
495  if (const ThreeDnTDICOMSeriesReader* specificReader = dynamic_cast<const ThreeDnTDICOMSeriesReader*>(cPointer))
496  {
497  root = this->CreateConfigStringFromReader(specificReader);
498  }
499  else
500  if (const DICOMITKSeriesGDCMReader* specificReader = dynamic_cast<const DICOMITKSeriesGDCMReader*>(cPointer))
501  {
502  root = this->CreateConfigStringFromReader(specificReader);
503  }
504  else
505  {
506  MITK_WARN << "Unknown reader class passed to DICOMReaderConfigurator::CreateConfigStringFromReader(). Cannot serialize.";
507  return ""; // no serialization, what a pity
508  }
509 
510  if (root)
511  {
512  TiXmlDocument document;
513  document.LinkEndChild( root );
514 
515  TiXmlPrinter printer;
516  printer.SetIndent( " " );
517 
518  document.Accept( &printer );
519  std::string xmltext = printer.CStr();
520  return xmltext;
521  }
522  else
523  {
524  MITK_WARN << "DICOMReaderConfigurator::CreateConfigStringFromReader() created empty serialization. Problem?";
525  return "";
526  }
527 }
528 
529 TiXmlElement*
532 {
533  TiXmlElement* root = this->CreateDICOMFileReaderTag(reader);
534  assert(root);
535 
536  root->SetAttribute("fixTiltByShearing", toString(reader->GetFixTiltByShearing()));
537  root->SetAttribute("acceptTwoSlicesGroups", toString(reader->GetAcceptTwoSlicesGroups()));
538  root->SetDoubleAttribute("toleratedOriginError", reader->GetToleratedOriginError());
539  root->SetAttribute("toleratedOriginErrorIsAbsolute", toString(reader->IsToleratedOriginOffsetAbsolute()));
540  root->SetDoubleAttribute("decimalPlacesForOrientation", reader->GetDecimalPlacesForOrientation());
541 
542  // iterate DICOMDatasetSorter objects
544  for(auto sorterIter = sorterList.begin();
545  sorterIter != sorterList.end();
546  ++sorterIter)
547  {
548  const DICOMDatasetSorter* sorter = *sorterIter;
549  if (const DICOMTagBasedSorter* specificSorter = dynamic_cast<const DICOMTagBasedSorter*>(sorter))
550  {
551  TiXmlElement* sorterTag = this->CreateConfigStringFromDICOMDatasetSorter(specificSorter);
552  root->LinkEndChild(sorterTag);
553  }
554  else
555  {
556  MITK_WARN << "Unknown DICOMDatasetSorter class passed to DICOMReaderConfigurator::CreateConfigStringFromReader(). Cannot serialize.";
557  return nullptr;
558  }
559  }
560 
561  return root;
562 }
563 
564 TiXmlElement*
565 mitk::DICOMReaderConfigurator
566 ::CreateConfigStringFromDICOMDatasetSorter(const DICOMTagBasedSorter* sorter) const
567 {
568  assert(sorter);
569 
570  auto sorterTag = new TiXmlElement("DICOMDatasetSorter");
571  sorterTag->SetAttribute("class", sorter->GetNameOfClass());
572  sorterTag->SetAttribute("strictSorting", toString(sorter->GetStrictSorting()));
573  sorterTag->SetAttribute("expectDistanceOne", toString(sorter->GetExpectDistanceOne()));
574 
575  auto distinguishingTagsElement = new TiXmlElement("Distinguishing");
576  sorterTag->LinkEndChild(distinguishingTagsElement);
577  mitk::DICOMTagList distinguishingTags = sorter->GetDistinguishingTags();
578  for (auto tagIter = distinguishingTags.begin();
579  tagIter != distinguishingTags.end();
580  ++tagIter)
581  {
582  TiXmlElement* tag = this->CreateConfigStringFromDICOMTag(*tagIter);
583  distinguishingTagsElement->LinkEndChild(tag);
584 
585  const DICOMTagBasedSorter::TagValueProcessor* processor = sorter->GetTagValueProcessorForDistinguishingTag(*tagIter);
586  if (const DICOMTagBasedSorter::CutDecimalPlaces* specificProcessor = dynamic_cast<const DICOMTagBasedSorter::CutDecimalPlaces*>(processor))
587  {
588  tag->SetDoubleAttribute("cutDecimalPlaces", specificProcessor->GetPrecision());
589  }
590  }
591 
592  auto sortingElement = new TiXmlElement("Sorting");
593  sorterTag->LinkEndChild(sortingElement);
594  mitk::DICOMSortCriterion::ConstPointer sortCriterion = sorter->GetSortCriterion();
595  while (sortCriterion.IsNotNull())
596  {
597  std::string classname = sortCriterion->GetNameOfClass();
598  if (classname == "SortByImagePositionPatient")
599  {
600  sortingElement->LinkEndChild( new TiXmlElement("ImagePositionPatient") ); // no parameters
601  }
602  else
603  if (classname == "DICOMSortByTag")
604  {
605  DICOMTagList pseudoTagList = sortCriterion->GetTagsOfInterest();
606  if (pseudoTagList.size() == 1)
607  {
608  DICOMTag firstTag = pseudoTagList.front();
609 
610  TiXmlElement* tagElement = this->CreateConfigStringFromDICOMTag(firstTag);
611 
612  sortingElement->LinkEndChild( tagElement );
613  }
614  else
615  {
616  MITK_ERROR << "Encountered SortByTag class with MULTIPLE tag in CreateConfigStringFromDICOMDatasetSorter. Cannot serialize.";
617  return nullptr;
618  }
619  }
620  else
621  {
622  MITK_ERROR << "Encountered unknown class '" << classname << "' in CreateConfigStringFromDICOMDatasetSorter. Cannot serialize.";
623  return nullptr;
624  }
625 
626  sortCriterion = sortCriterion->GetSecondaryCriterion();
627  }
628 
629  return sorterTag;
630 }
631 
632 TiXmlElement*
633 mitk::DICOMReaderConfigurator
634 ::CreateConfigStringFromDICOMTag(const DICOMTag& tag) const
635 {
636  auto tagElement = new TiXmlElement("Tag"); // name group element
637  tagElement->SetAttribute("name", tag.GetName().c_str());
638  tagElement->SetAttribute("group", toHexString(tag.GetGroup()));
639  tagElement->SetAttribute("element", toHexString(tag.GetElement()));
640  return tagElement;
641 }
642 
643 std::string
644 mitk::DICOMReaderConfigurator
645 ::toHexString(unsigned int i) const
646 {
647  std::stringstream ss;
648  ss << "0x" << std::setfill ('0') << std::setw(4) << std::hex << i;
649  return ss.str();
650 }
651 
652 
653 TiXmlElement*
655 ::CreateConfigStringFromReader(const ThreeDnTDICOMSeriesReader* reader) const
656 {
657  TiXmlElement* root = this->CreateConfigStringFromReader(static_cast<const DICOMITKSeriesGDCMReader*>(reader));
658  assert(root);
659 
660  root->SetAttribute("group3DnT", toString(reader->GetGroup3DandT()));
661 
662  return root;
663 }
664 
665 const char*
666 mitk::DICOMReaderConfigurator
667 ::toString(bool b) const
668 {
669  return b ? "true" : "false";
670 }
671 
672 TiXmlElement*
674 ::CreateConfigStringFromReader(const ClassicDICOMSeriesReader* reader) const
675 {
676  return this->CreateDICOMFileReaderTag(reader);
677 }
678 
679 TiXmlElement*
680 mitk::DICOMReaderConfigurator
681 ::CreateDICOMFileReaderTag(const DICOMFileReader* reader) const
682 {
683  auto readerTag = new TiXmlElement("DICOMFileReader");
684  readerTag->SetAttribute("class", reader->GetNameOfClass());
685  readerTag->SetAttribute("label", reader->GetConfigurationLabel().c_str());
686  readerTag->SetAttribute("description", reader->GetConfigurationDescription().c_str());
687  readerTag->SetAttribute("version", "1");
688 
689  return readerTag;
690 }
Sorting and grouping like mitk::DicomSeriesReader until 2013.
itk::SmartPointer< Self > Pointer
#define boolStringTrue(s)
The sorting/splitting building-block of DICOMITKSeriesGDCMReader.
Flexible reader based on itk::ImageSeriesReader and GDCM, for single-slice modalities like CT...
#define MITK_ERROR
Definition: mitkLogMacros.h:24
std::vector< DICOMTag > DICOMTagList
Definition: mitkDICOMTag.h:64
Representation of a DICOM tag.
Definition: mitkDICOMTag.h:37
ConstSorterList GetFreelyConfiguredSortingElements() const
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
std::string CreateConfigStringFromReader(DICOMFileReader::ConstPointer reader) const
itk::SmartPointer< const Self > ConstPointer
const std::list< DICOMDatasetSorter::ConstPointer > ConstSorterList
#define MITK_WARN
Definition: mitkLogMacros.h:23
static const std::string filename
DICOMFileReader::Pointer CreateFromUTF8ConfigString(const std::string &xmlContents) const
DICOMFileReader::Pointer CreateFromConfigFile(const std::string &filename) const
Extends DICOMITKSeriesGDCMReader by sorting/grouping into 3D+t image blocks.
Cuts a number after configured number of decimal places. An instance of this class can be used to avo...
Sort DICOM datasets based on configurable tags.
Interface for DICOM readers that produce mitk::Images.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.