Slicer 5.6
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
Loading...
Searching...
No Matches
vtkITKArchetypeImageSeriesReader.h
Go to the documentation of this file.
1/*=========================================================================
2
3Copyright Brigham and Women's Hospital (BWH) All Rights Reserved.
4
5See COPYRIGHT.txt
6or http://www.slicer.org/copyright/copyright.txt for details.
7
8Program: vtkITK
9Module: $HeadURL$
10Date: $Date$
11Version: $Revision$
12
13==========================================================================*/
14
15#ifndef __vtkITKArchetypeImageSeriesReader_h
16#define __vtkITKArchetypeImageSeriesReader_h
17
18// VTKITK includes
19#include "vtkITK.h"
20
21// VTK includes
22#include "vtkImageAlgorithm.h"
23class vtkMatrix4x4;
24
25// ITK includes
26#include "itkImageIOBase.h"
27#include "itkMetaDataDictionary.h"
28#include "itkSpatialOrientation.h"
29
30// STD includes
31#include <algorithm>
32#include <string>
33#include <vector>
34
45class VTK_ITK_EXPORT vtkITKArchetypeImageSeriesReader : public vtkImageAlgorithm
46{
47public:
49 vtkTypeMacro(vtkITKArchetypeImageSeriesReader,vtkImageAlgorithm);
50 void PrintSelf(ostream& os, vtkIndent indent) override;
51
52 typedef itk::SpatialOrientation::ValidCoordinateOrientationFlags CoordinateOrientationCode;
53
56 vtkSetStringMacro(Archetype);
57 vtkGetStringMacro(Archetype);
58
61 unsigned int GetNumberOfFileNames();
64 const std::vector<std::string>& GetFileNames();
65
70 unsigned int AddFileName( const char* filename );
71 const char* GetFileName( unsigned int n );
73
77 vtkSetVector3Macro(DefaultDataSpacing,double);
78 vtkGetVector3Macro(DefaultDataSpacing,double);
79
84 vtkSetVector3Macro(DefaultDataOrigin,double);
85 vtkGetVector3Macro(DefaultDataOrigin,double);
86
90 vtkSetMacro(FileNameSliceOffset,int);
91 vtkGetMacro(FileNameSliceOffset,int);
92
97 vtkSetMacro(FileNameSliceSpacing,int);
98 vtkGetMacro(FileNameSliceSpacing,int);
99
103 vtkSetMacro(FileNameSliceCount,int);
104 vtkGetMacro(FileNameSliceCount,int);
105
107 virtual int CanReadFile(const char* filename);
108
112 {
113 this->DesiredCoordinateOrientation =
114 itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RAI;
116 this->UseNativeCoordinateOrientation = 0;
117 this->Modified();
118 }
120 {
121 this->DesiredCoordinateOrientation =
122 itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RSA;
124 this->UseNativeCoordinateOrientation = 0;
125 this->Modified();
126 }
128 {
129 this->DesiredCoordinateOrientation =
130 itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ASL;
132 this->UseNativeCoordinateOrientation = 0;
133 this->Modified();
134 }
136 {
137 this->UseNativeCoordinateOrientation = 1;
138 this->Modified();
139 }
140 vtkGetMacro(DesiredCoordinateOrientation, CoordinateOrientationCode);
141 vtkGetMacro(UseNativeCoordinateOrientation, char);
142
148 {
149 UseNativeScalarType = 0;
150 this->SetOutputScalarType(VTK_DOUBLE);
151 }
153 {
154 UseNativeScalarType = 0;
155 this->SetOutputScalarType(VTK_FLOAT);
156 }
158 {
159 UseNativeScalarType = 0;
160 this->SetOutputScalarType(VTK_LONG);
161 }
163 {
164 UseNativeScalarType = 0;
165 this->SetOutputScalarType(VTK_UNSIGNED_LONG);
166 }
168 {
169 UseNativeScalarType = 0;
170 this->SetOutputScalarType(VTK_INT);
171 }
173 {
174 UseNativeScalarType = 0;
175 this->SetOutputScalarType(VTK_UNSIGNED_INT);
176 }
178 {
179 UseNativeScalarType = 0;
180 this->SetOutputScalarType(VTK_SHORT);
181 }
183 {
184 UseNativeScalarType = 0;
185 this->SetOutputScalarType(VTK_UNSIGNED_SHORT);
186 }
188 {
189 UseNativeScalarType = 0;
190 this->SetOutputScalarType(VTK_CHAR);
191 }
193 {
194 UseNativeScalarType = 0;
195 this->SetOutputScalarType(VTK_UNSIGNED_CHAR);
196 }
198 {
199 UseNativeScalarType = 1;
200 this->Modified();
201 }
202
206 {
207 UseNativeOrigin = true;
208 }
209
213 {
214 UseNativeOrigin = false;
215 }
216
219 enum
220 {
221 GDCM = 0,
222 DCMTK
223 };
225 vtkGetMacro(DICOMImageIOApproach, int);
228
231 vtkSetMacro(OutputScalarType, int);
232 vtkGetMacro(OutputScalarType, int);
233
236 vtkSetMacro(NumberOfComponents, unsigned int);
237 vtkGetMacro(NumberOfComponents, unsigned int);
238
241 vtkSetMacro(SingleFile, int);
242 vtkGetMacro(SingleFile, int);
243
246 vtkSetMacro(AnalyzeHeader, bool);
247 vtkGetMacro(AnalyzeHeader, bool);
248
251 vtkSetMacro(UseOrientationFromFile, int);
252 vtkGetMacro(UseOrientationFromFile, int);
253
256 vtkMatrix4x4* GetRasToIjkMatrix();
257
261
263 vtkSetMacro(VoxelVectorType, int);
264 vtkGetMacro(VoxelVectorType, int);
265
268 const itk::MetaDataDictionary &GetMetaDataDictionary() const;
269 std::vector<std::string> Tags;
270 std::vector<std::string> TagValues;
272
274 bool HasKey( char* tag );
275 const char* GetNthKey( unsigned int n );
276 const char* GetNthValue( unsigned int n );
277 const char* GetTagValue( char* tag );
278
281 {
282 return GroupingByTags;
283 }
284
286 {
287 GroupingByTags = true;
288 }
289
291 {
292 GroupingByTags = false;
293 }
294
297 {
298 return SelectedUID;
299 }
300
301 void SetSelectedUID( int v )
302 {
303 SelectedUID = v;
304 SetGroupingByTagsOn();
305 }
306
309 {
310 return SelectedContentTime;
311 }
312
314 {
315 SelectedContentTime = v;
316 SetGroupingByTagsOn();
317 }
318
321 {
322 return SelectedTriggerTime;
323 }
324
326 {
327 SelectedTriggerTime = v;
328 SetGroupingByTagsOn();
329 }
330
333 {
334 return SelectedEchoNumbers;
335 }
336
338 {
339 SelectedEchoNumbers = v;
340 SetGroupingByTagsOn();
341 }
342
343
346 {
347 return SelectedDiffusion;
348 }
349
351 {
352 SelectedDiffusion = v;
353 SetGroupingByTagsOn();
354 }
355
358 {
359 return SelectedSlice;
360 }
361
362 void SetSelectedSlice( int v )
363 {
364 SelectedSlice = v;
365 SetGroupingByTagsOn();
366 }
367
370 {
371 return SelectedOrientation;
372 }
373
375 {
376 SelectedOrientation = v;
377 SetGroupingByTagsOn();
378 }
379
382 {
383 return this->SeriesInstanceUIDs.size();
384 }
385
387 {
388 return this->ContentTime.size();
389 }
390
392 {
393 return this->TriggerTime.size();
394 }
395
397 {
398 return this->EchoNumbers.size();
399 }
400
402 {
403 return this->SliceLocation.size();
404 }
405
407 {
408 return this->DiffusionGradientOrientation.size();
409 };
410
412 {
413 return this->ImageOrientationPatient.size();
414 };
415
417 {
418 return this->ImagePositionPatient.size();
419 }
420
422 int ExistSeriesInstanceUID( const char* SeriesInstanceUID )
423 {
424 for (unsigned int k = 0; k < GetNumberOfSeriesInstanceUIDs(); k++)
425 {
426 if ( this->SeriesInstanceUIDs[k].find(SeriesInstanceUID) != std::string::npos )
427 {
428 return k;
429 }
430 }
431 return -1;
432 }
433
434 int ExistContentTime( const char* contentTime )
435 {
436 for (unsigned int k = 0; k < GetNumberOfContentTime(); k++)
437 {
438 if ( this->ContentTime[k].find(contentTime) != std::string::npos )
439 {
440 return k;
441 }
442 }
443 return -1;
444 }
445
446 int ExistTriggerTime( const char* triggerTime )
447 {
448 for (unsigned int k = 0; k < GetNumberOfTriggerTime(); k++)
449 {
450 if ( this->TriggerTime[k].find(triggerTime) != std::string::npos )
451 {
452 return k;
453 }
454 }
455 return -1;
456 }
457
458 int ExistEchoNumbers( const char* echoNumbers )
459 {
460 for (unsigned int k = 0; k < GetNumberOfEchoNumbers(); k++)
461 {
462 if ( this->EchoNumbers[k].find(echoNumbers) != std::string::npos )
463 {
464 return k;
465 }
466 }
467 return -1;
468 }
469
471 {
472 float a = 0;
473 for (int n = 0; n < 3; n++)
474 {
475 a += dgo[n]*dgo[n];
476 }
477
478 for (unsigned int k = 0; k < GetNumberOfDiffusionGradientOrientation(); k++)
479 {
480 float b = 0;
481 float c = 0;
482 for (int n = 0; n < 3; n++)
483 {
484 b += this->DiffusionGradientOrientation[k][n] * this->DiffusionGradientOrientation[k][n];
485 c += this->DiffusionGradientOrientation[k][n] * dgo[n];
486 }
487 c = fabs(c)/sqrt(a*b);
488
489 if ( c > 0.99999 )
490 {
491 return k;
492 }
493 }
494 return -1;
495 }
496
497 int ExistSliceLocation( float sliceLocation )
498 {
499 std::vector<float>::iterator iter =
500 std::find(this->SliceLocation.begin(), this->SliceLocation.end(), sliceLocation);
501 return iter != this->SliceLocation.end() ?
502 std::distance(this->SliceLocation.begin(), iter) : -1;
503 }
504
505 int ExistImageOrientationPatient( float * directionCosine )
506 {
508 float a = sqrt( directionCosine[0]*directionCosine[0] + directionCosine[1]*directionCosine[1] + directionCosine[2]*directionCosine[2] );
509 for (int k = 0; k < 3; k++)
510 {
511 directionCosine[k] /= a;
512 }
513 a = sqrt( directionCosine[3]*directionCosine[3] + directionCosine[4]*directionCosine[4] + directionCosine[5]*directionCosine[5] );
514 for (int k = 3; k < 6; k++)
515 {
516 directionCosine[k] /= a;
517 }
518
519 for (unsigned int k = 0; k < GetNumberOfImageOrientationPatient(); k++)
520 {
521 std::vector<float> aVec = ImageOrientationPatient[k];
522 a = sqrt( aVec[0]*aVec[0] + aVec[1]*aVec[1] + aVec[2]*aVec[2] );
523 float b = (directionCosine[0]*aVec[0] + directionCosine[1]*aVec[1] + directionCosine[2]*aVec[2])/a;
524 if ( b < 0.99999 )
525 {
526 continue;
527 }
528
529 a = sqrt( aVec[3]*aVec[3] + aVec[4]*aVec[4] + aVec[5]*aVec[5] );
530 b = (directionCosine[3]*aVec[3] + directionCosine[4]*aVec[4] + directionCosine[5]*aVec[5])/a;
531 if ( b > 0.99999 )
532 {
533 return k;
534 }
535 }
536 return -1;
537 }
538
540 {
541 float a = 0;
542 for (int n = 0; n < 3; n++)
543 {
544 a += ipp[n]*ipp[n];
545 }
546
547 for (unsigned int k = 0; k < GetNumberOfImagePositionPatient(); k++)
548 {
549 float b = 0;
550 float c = 0;
551 for (int n = 0; n < 3; n++)
552 {
553 b += this->ImagePositionPatient[k][n] * this->ImagePositionPatient[k][n];
554 c += this->ImagePositionPatient[k][n] * ipp[n];
555 }
556 c = fabs(c)/sqrt(a*b);
557 if ( c > 0.99999 )
558 {
559 return k;
560 }
561 }
562 return -1;
563 }
564
566 const char* GetNthSeriesInstanceUID( unsigned int n )
567 {
568 if ( n >= this->GetNumberOfSeriesInstanceUIDs() )
569 {
570 return nullptr;
571 }
572 return this->SeriesInstanceUIDs[n].c_str();
573 }
574
575 const char* GetNthContentTime( unsigned int n )
576 {
577 if ( n >= this->GetNumberOfContentTime() )
578 {
579 return nullptr;
580 }
581 return this->ContentTime[n].c_str();
582 }
583
584 const char* GetNthTriggerTime( unsigned int n )
585 {
586 if ( n >= this->GetNumberOfTriggerTime() )
587 {
588 return nullptr;
589 }
590 return this->TriggerTime[n].c_str();
591 }
592
593 const char* GetNthEchoNumbers( unsigned int n )
594 {
595 if ( n >= this->GetNumberOfEchoNumbers() )
596 {
597 return nullptr;
598 }
599 return this->EchoNumbers[n].c_str();
600 }
601
602 float* GetNthDiffusionGradientOrientation( unsigned int n )
603 {
604 if ( n >= this->GetNumberOfDiffusionGradientOrientation() )
605 {
606 return nullptr;
607 }
608 float *dgo = new float [3];
609 for (int k = 0; k <3; k++)
610 {
611 dgo[k] = this->DiffusionGradientOrientation[n][k];
612 }
613 return dgo;
614 }
615
616 float GetNthSliceLocation( unsigned int n )
617 {
618 if ( n >= this->GetNumberOfSliceLocation() )
619 {
620 return this->SliceLocation[0];
621 }
622 return this->SliceLocation[0];
623 }
624
625 float* GetNthImageOrientationPatient( unsigned int n )
626 {
627 if ( n >= this->GetNumberOfImageOrientationPatient() )
628 {
629 return nullptr;
630 }
631 float *dgo = new float [6];
632 for (int k = 0; k <6; k++)
633 {
634 dgo[k] = this->ImageOrientationPatient[n][k];
635 }
636 return dgo;
637 }
638
639 float* GetNthImagePositionPatient( unsigned int n )
640 {
641 if (n >= this->GetNumberOfImagePositionPatient() )
642 {
643 return nullptr;
644 }
645 float *ipp = new float [3];
646 for (int k = 0; k <3; k++)
647 {
648 ipp[k] = this->ImagePositionPatient[n][k];
649 }
650 return ipp;
651 }
652
655 int InsertSeriesInstanceUIDs ( const char * aUID )
656 {
657 int k = ExistSeriesInstanceUID( aUID );
658 if ( k >= 0 )
659 {
660 return k;
661 }
662
663 std::string aVector(aUID);
664 this->SeriesInstanceUIDs.push_back( aVector );
665 return (this->SeriesInstanceUIDs.size()-1);
666 }
667
668 int InsertContentTime ( const char * aTime )
669 {
670 int k = ExistContentTime( aTime );
671 if ( k >= 0 )
672 {
673 return k;
674 }
675
676 std::string aVector(aTime);
677 this->ContentTime.push_back( aVector );
678 return (this->ContentTime.size()-1);
679 }
680
681 int InsertTriggerTime ( const char * aTime )
682 {
683 int k = ExistTriggerTime( aTime );
684 if ( k >= 0 )
685 {
686 return k;
687 }
688
689 std::string aVector(aTime);
690 this->TriggerTime.push_back( aVector );
691 return (this->TriggerTime.size()-1);
692 }
693
694 int InsertEchoNumbers ( const char * aEcho )
695 {
696 int k = ExistEchoNumbers( aEcho );
697 if ( k >= 0 )
698 {
699 return k;
700 }
701
702 std::string aVector(aEcho);
703 this->EchoNumbers.push_back( aVector );
704 return (this->EchoNumbers.size()-1);
705 }
706
708 {
709 int k = ExistDiffusionGradientOrientation( a );
710 if ( k >= 0 )
711 {
712 return k;
713 }
714 std::vector< float > aVector(3);
715 float aMag = sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
716 for (k = 0; k < 3; k++)
717 {
718 aVector[k] = a[k]/aMag;
719 }
720
721 this->DiffusionGradientOrientation.push_back( aVector );
722 return (this->DiffusionGradientOrientation.size()-1);
723 }
724
728 int InsertSliceLocation ( float a )
729 {
730 int k = ExistSliceLocation( a );
731 if ( k >= 0 )
732 {
733 return k;
734 }
735
736 this->SliceLocation.push_back( a );
737 return (this->SliceLocation.size()-1);
738 }
742 {
743 int size = this->SliceLocation.size();
744 this->SliceLocation.push_back(
745 size > 0 ? this->SliceLocation.back() + 1 : 0.f);
746 return size;
747 }
748
750 {
751 int k = ExistImageOrientationPatient( a );
752 if ( k >= 0 )
753 {
754 return k;
755 }
756 std::vector< float > aVector(6);
757 float aMag = sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
758 float bMag = sqrt(a[3]*a[3]+a[4]*a[4]+a[5]*a[5]);
759 for (k = 0; k < 3; k++)
760 {
761 aVector[k] = a[k]/aMag;
762 aVector[k+3] = a[k+3]/bMag;
763 }
764
765 this->ImageOrientationPatient.push_back( aVector );
766 return (this->ImageOrientationPatient.size()-1);
767 }
768
770 {
771 int k = ExistImagePositionPatient( a );
772 if ( k >= 0 )
773 {
774 return k;
775 }
776
777 std::vector< float > aVector(3);
778 for ( unsigned int i = 0; i < 3; i++ ) aVector[i] = a[i];
779 this->ImagePositionPatient.push_back( aVector );
780 return (this->ImagePositionPatient.size()-1);
781 }
782
784
785 void AssembleNthVolume( int n );
787
788 void GroupFiles ( int idxSeriesInstanceUID,
789 int idxContentTime,
790 int idxTriggerTime,
791 int idxEchoNumbers,
792 int idxDiffusionGradientOrientation,
793 int idxSliceLocation,
794 int idxImageOrientationPatient );
795
796 const char* GetNthFileName ( int idxSeriesInstanceUID,
797 int idxContentTime,
798 int idxTriggerTime,
799 int idxEchoNumbers,
800 int idxDiffusionGradientOrientation,
801 int idxSliceLocation,
802 int idxImageOrientationPatient,
803 int n );
804
805
806protected:
809
811 static std::string GetMetaDataWithoutSpaces(const itk::MetaDataDictionary &dict, const std::string& tag);
812
814 itk::ImageIOBase::Pointer GetImageIO(const char* filename);
815
819 int DataExtent[6];
820
822 unsigned int NumberOfComponents;
823
824 std::vector<double> MetaDataScalarRangeMinima;
825 std::vector<double> MetaDataScalarRangeMaxima;
826 void GetScalarRangeMetaDataKeys(itk::ImageIOBase::Pointer imageIO,
827 std::string range_keys[2]);
829
830 double DefaultDataSpacing[3];
831 double DefaultDataOrigin[3];
832 float ScanAxis[3];
833 float ScanOrigin[3];
834
838
839 vtkMatrix4x4* RasToIjkMatrix;
841
845
847
856
857 unsigned int IndexArchetype;
858
859 std::vector<std::string> FileNames;
860 std::vector<std::pair <double, int> > FileNameSliceKey;
862 int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
863
864 itk::MetaDataDictionary Dictionary;
865
879
880 std::vector<std::string> AllFileNames;
884
885 std::vector<std::string> SeriesInstanceUIDs;
886 std::vector<std::string> ContentTime;
887 std::vector<std::string> TriggerTime;
888 std::vector<std::string> EchoNumbers;
889 std::vector< std::vector<float> > DiffusionGradientOrientation;
890 std::vector<float> SliceLocation;
891 std::vector< std::vector<float> > ImageOrientationPatient;
892 std::vector< std::vector<float> > ImagePositionPatient;
893
895 std::vector<long int> IndexSeriesInstanceUIDs;
896 std::vector<long int> IndexContentTime;
897 std::vector<long int> IndexTriggerTime;
898 std::vector<long int> IndexEchoNumbers;
900 std::vector<long int> IndexSliceLocation;
901 std::vector<long int> IndexImageOrientationPatient;
902 std::vector<long int> IndexImagePositionPatient;
903
905
906private:
908 void operator=(const vtkITKArchetypeImageSeriesReader&) = delete;
909};
910
911#endif
Read a series of files that have a common naming convention.
bool GetGroupingByTags()
set/get functions for grouping by tags
void GetScalarRangeMetaDataKeys(itk::ImageIOBase::Pointer imageIO, std::string range_keys[2])
const char * GetNthFileName(int idxSeriesInstanceUID, int idxContentTime, int idxTriggerTime, int idxEchoNumbers, int idxDiffusionGradientOrientation, int idxSliceLocation, int idxImageOrientationPatient, int n)
std::vector< std::vector< float > > DiffusionGradientOrientation
virtual int CanReadFile(const char *filename)
is the given file name a NRRD file?
unsigned int AddFileName(const char *filename)
int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override
void SetMetaDataScalarRangeToPointDataInfo(vtkImageData *data)
void SetDesiredCoordinateOrientationToAxial()
Set the orientation of the output image.
unsigned int GetNumberOfFileNames()
See how many file names were generated during ExecuteInformation.
void SetUseNativeOriginOn()
Use image origin from the file.
void PrintSelf(ostream &os, vtkIndent indent) override
int ExistImageOrientationPatient(float *directionCosine)
static vtkITKArchetypeImageSeriesReader * New()
std::vector< std::vector< float > > ImageOrientationPatient
static std::string GetMetaDataWithoutSpaces(const itk::MetaDataDictionary &dict, const std::string &tag)
Get MetaData from dictionary, removing all whitespaces from the string.
vtkMatrix4x4 * GetRasToIjkMatrix()
Returns an IJK to RAS transformation matrix.
int ExistSeriesInstanceUID(const char *SeriesInstanceUID)
check the existence of given discriminator
const char * GetNthValue(unsigned int n)
unsigned int GetNumberOfItemsInDictionary()
void SetUseNativeOriginOff()
Use image center as origin.
const char * GetTagValue(char *tag)
const char * GetNthSeriesInstanceUID(unsigned int n)
methods to get N-th discriminator
const itk::MetaDataDictionary & GetMetaDataDictionary() const
Return the MetaDataDictionary from the ITK layer.
const char * GetNthKey(unsigned int n)
void GroupFiles(int idxSeriesInstanceUID, int idxContentTime, int idxTriggerTime, int idxEchoNumbers, int idxDiffusionGradientOrientation, int idxSliceLocation, int idxImageOrientationPatient)
std::vector< std::vector< float > > ImagePositionPatient
unsigned int GetNumberOfSeriesInstanceUIDs()
get number of certain discriminators in the directory
itk::SpatialOrientation::ValidCoordinateOrientationFlags CoordinateOrientationCode
vtkMatrix4x4 * GetMeasurementFrameMatrix()
Returns the Measurement frame matrix.
itk::ImageIOBase::Pointer GetImageIO(const char *filename)
Get the image IO for the specified filename.
const char * GetFileName(unsigned int n)
const std::vector< std::string > & GetFileNames()
Return all the file names.
std::vector< std::pair< double, int > > FileNameSliceKey
std::vector< long int > IndexSeriesInstanceUIDs
index of each dicom file into the above arrays