]> Creatis software - gdcm.git/blobdiff - vtk/vtkGdcm4DSplitter.cxx
Fixes (Sort on tag still buggy...)
[gdcm.git] / vtk / vtkGdcm4DSplitter.cxx
index 6ab01f6aad2ecc941319fc0cd8dd4ce8c8f90b86..3f632c28c2d575274924f1c0cd26392df6f7bee2 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: vtkGdcm4DSplitter.cxx,v $
   Language:  C++
-  Date:      $Date: 2011/03/29 12:49:27 $
-  Version:   $Revision: 1.1 $
+  Date:      $Date: 2011/03/30 14:49:04 $
+  Version:   $Revision: 1.5 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -27,6 +27,76 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas <rogerbramon@gmail.com>
     (ImageSeriesReader::GenerateData() line 393).
 */
 
+
+/* ====================================================================
+vtkGdcm4DSplitter
+
+3D, 2D+T, 3D+T, n*2D+T, 4D images are not always stored the same way :
+        a single 'Dicom Serie', 
+        several 'Dicom series' within a single directory
+        several 'Dicom series' within several directories
+A 'Dicom Serie' doesn't mean always the same thing :
+        a given Slice along the time
+        a given Volume at a given time
+Sometimes, an image within a serie is so artefacted than user decides to replace
+it by an other image.
+
+User needs to be aware, *only him* knows want he wants to do.
+vtkGdcm4DSplitter class does the job for hom
+(despite its name, it works on 3D or 2D+T images too)
+
+User will have to specify some points
+
+. Choose input data
+------------------- 
+
+- a single directory
+       bool setDirName(std::string &dirName);
+- a list of directories
+       bool setVectDirName(std::vector<std::string> &vectDirName);
+- a list of files       
+       bool setVectFileName(std::vector<std::string> &vectFileName);
+
+- Recursive directory exploration
+       void setRecursive(bool recursive);
+. Choose 'split' criterion :
+---------------------------
+
+ - ImagePositionPatient
+        void setSplitOnPosition();
+ - ImageOrientationPatient
+        void setSplitOnOrientation();
+ - User choosen tag
+        ==> WARNING : This one has troubles; do NOT use it, right now!
+        void setSplitOnTag(unsigned short splitGroup, unsigned short splitElem);
+        void setSplitConvertToFloat(bool conv);
+ - UserDefined Function
+        void setSortOnUserFunction (FoncComp f);
+. Choose 'sort' criterion :
+--------------------------
+
+ - ImagePositionPatient
+        void setSortOnPosition();
+ - User choosen tag
+        void setSortOnTag(unsigned short sortGroup, unsigned short sortElem);
+        void setSortConvertToFloat(bool conv)
+
+. Execute
+-----------
+        bool Go();
+
+. Get the result
+----------------
+
+ -a single vtkImageData:
+        vtkImageData *GetImageData();
+- a vector of vtkImageData
+        std::vector<vtkImageData*> *GetImageDataVector();
+
+  ===================================================================== */
+
 #include "gdcmSerieHelper.h"
 
 #include "vtkGdcmReader.h"
@@ -119,18 +189,20 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas <rogerbramon@gmail.com>
     return true;
  }      
 
- bool vtkGdcm4DSplitter::CompareOnSortTagConvertToFloat(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2)
/*static */bool vtkGdcm4DSplitter::CompareOnSortTagConvertToFloat(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2)
  { 
-   if (verbose) printf ("%04x %04x\n", this->SortGroup,this->SortElem);
+  /* if (verbose) printf ("%04x %04x\n", this->SortGroup,this->SortElem);
    if (verbose) std :: cout << file1->GetEntryString(SortGroup,SortElem).c_str() << " : " 
                             << atof(file1->GetEntryString(SortGroup,SortElem).c_str())
                             << std::endl;
-   return atof(file1->GetEntryString(SortGroup,SortElem).c_str()) < atof(file2->GetEntryString(SortGroup,SortElem).c_str());  
+*/
+//   return atof(file1->GetEntryString(vtkGdcm4DSplitter::SortGroup,vtkGdcm4DSplitter::SortElem).c_str()) < atof(file2->GetEntryString(vtkGdcm4DSplitter::SortGroup,vtkGdcm4DSplitter::SortElem).c_str()); 
+   return atof(file1->GetEntryString(SortGroup,SortElem).c_str()) < atof(file2->GetEntryString(SortGroup,SortElem).c_str()); 
  } 
 
- bool vtkGdcm4DSplitter::CompareOnSortTag(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2)
/*static */bool vtkGdcm4DSplitter::CompareOnSortTag(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2)
  {
-   return file1->GetEntryString(SortGroup,SortElem) < file2->GetEntryString(SortGroup,SortElem);  
+   return file1->GetEntryString(vtkGdcm4DSplitter::SortGroup,vtkGdcm4DSplitter::SortElem) < file2->GetEntryString(vtkGdcm4DSplitter::SortGroup,vtkGdcm4DSplitter::SortElem);  
  }
    
  bool vtkGdcm4DSplitter::Go()
@@ -245,7 +317,8 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas <rogerbramon@gmail.com>
       TypeResult=2;
 
    ImageDataVector = new std::vector<vtkImageData*>;
-   vtkGdcmReader *reader = vtkGdcmReader::New();
+  // vtkGdcmReader *reader = vtkGdcmReader::New(); // move inside the loop, or be clever using vtk!
+   
    for (GDCM_NAME_SPACE::XCoherentFileSetmap::iterator i = xcm.begin(); 
                                                   i != xcm.end();
                                                 ++i)
@@ -259,19 +332,22 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas <rogerbramon@gmail.com>
                                                   i != xcm.end();
                                                 ++i)
    {
-           if (verbose)
+   
+      vtkGdcmReader *reader = vtkGdcmReader::New(); /// \FIXME : unable to delete!
+       
+      if (verbose)
                std::cout << "==========================================xCoherentName = [" << (*i).first << "]" << std::endl;
 
-           if (SortOnPosition)
-           {
+      if (SortOnPosition)
+      {
               if (verbose) std::cout << "SortOnPosition" << std::endl;
               // (will be IPPSorter, in GDCM2)
               s->ImagePositionPatientOrdering((*i).second);
-              if (verbose) std::cout << "out of SortOnPosition" << std::endl      
-            }
+              if (verbose) std::cout << "out of SortOnPosition" << std::endl;     
+      }
 
-           if (SortOnOrientation)
-           {
+      else if (SortOnOrientation)
+      {
               if (verbose) std::cout << "SortOnOrientation" << std::endl;
              /// \TODO SortOnOrientation()
            // Within a 'just to see' program, 
@@ -284,48 +360,70 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas <rogerbramon@gmail.com>
            // 0020,0030 : Image Position (RET)
       
             // we still miss an algo to sort an Orientation, given by 6 cosines!
-    //  Anything like this, in GDCM2? 
-      std::cout << "SortOnOrientation : not so easy - I(mage)O(rientation)P(atient)Sorter still missing! -" << std::endl;
-    // have a look at SerieHelper::SplitOnPosition() to have an idea of the mess!
+            //  Anything like this, in GDCM2? 
+            std::cout << "SortOnOrientation : not so easy - I(mage)O(rientation)P(atient)Sorter still missing! -" << std::endl;
+            // have a look at SerieHelper::SplitOnOrientation() to have an idea of the mess!
 
-      //Better sort on the file name, right now...
-      s->FileNameOrdering((*i).second);   
-   }
+            //Better sort on the file name, right now...
+             s->FileNameOrdering((*i).second);   
+      }
 
-   if (SortOnFileName)
-   {
-      if (verbose) std::cout << "SortOnFileName" << std::endl;
-      if (verbose) std::cout << "taille " << ((*i).second)->size() << std::endl;
-      s->FileNameOrdering((*i).second);
-      if (verbose) std::cout << "Out of SortOnFileName" << std::endl;
-   }
+      else if (SortOnFileName)
+      {
+         if (verbose) std::cout << "SortOnFileName" << std::endl;
+         if (verbose) std::cout << "taille " << ((*i).second)->size() << std::endl;
 
-   if (SortOnTag)
-   {  
-      if (verbose) std::cout << "SortOnTag" << std::endl;   
-      printf ("--> %04x %04x\n", SortGroup,SortElem);
-              if ( SortConvertToFloat )
-         s->SetUserLessThanFunction( reinterpret_cast<bool (*)(gdcm13::File*, gdcm13::File*)> 
-                                                              ( &vtkGdcm4DSplitter::CompareOnSortTagConvertToFloat));     
-      else
-         s->SetUserLessThanFunction( reinterpret_cast<bool (*)(gdcm13::File*, gdcm13::File*)>
-                                                              ( &vtkGdcm4DSplitter::CompareOnSortTag)); 
+         s->FileNameOrdering((*i).second);
+         if (verbose) std::cout << "Out of SortOnFileName" << std::endl;
+      }
+
+      else if (SortOnTag)
+      {  
+         if (verbose) std::cout << "SortOnTag" << std::endl;   
+         printf ("--> %04x %04x\n", SortGroup,SortElem);
+         std::cout << "Sorry, troubles not solved yet; use SortOnUserFunction, right now!" << std::endl;
+        /*        ==> WARNING : This one has troubles; do NOT use it, right now!
+         if ( SortConvertToFloat )
+            s->SetUserLessThanFunction( reinterpret_cast<bool (*)(gdcm13::File*, gdcm13::File*)> 
+                                                                 ( &vtkGdcm4DSplitter::CompareOnSortTagConvertToFloat));     
+         else
+            s->SetUserLessThanFunction( reinterpret_cast<bool (*)(gdcm13::File*, gdcm13::File*)>
+                                                                 ( &vtkGdcm4DSplitter::CompareOnSortTag)); 
        
-      // Anything like this, in GDCM2? 
-      s->UserOrdering((*i).second);
-      if (verbose) std::cout << "Out of SortOnTag" << std::endl;
-   }
+         // Anything like this, in GDCM2? 
+         s->UserOrdering((*i).second);
+        */
+
+         //if (verbose) std::cout << "Out of SortOnTag" << std::endl;
+         std::cout << "NO ordering performed  :-( " << std::endl;
+      }
+      
+      else if (SortOnUserFunction)
+      {   
+          if (verbose) std::cout << "SortOnUserFunction" << std::endl;
+          s->SetUserLessThanFunction( UserCompareFunction );
+         // Anything like this, in GDCM2? 
+         s->UserOrdering((*i).second);
+         if (verbose) std::cout << "Out of SortOnUserFunction" << std::endl;   
+      }
 
-    reader->SetCoherentFileList((*i).second);
-    reader->Update();
-            ImageDataVector->push_back(reader->GetOutput() );
+       reader->SetCoherentFileList((*i).second);
+       reader->Update();
+       
+       /// \TODO : remove the following
+       //if (verbose) reader->GetOutput()->PrintSelf(std::cout, vtkIndent(2));
+       
+       ImageDataVector->push_back(reader->GetOutput() );
 
-         std::cout << std::endl;
+       std::cout << std::endl;
    }
 
-   reader->Delete();
+   //reader->Delete();  // \TODO : fix
    s->Delete(); 
    f->Delete();
    delete l;
+   
+   return true;
  }