]> Creatis software - gdcm.git/blobdiff - Example/PhilipsToBrucker2.cxx
COMP: Fix compilation against VTK CVS
[gdcm.git] / Example / PhilipsToBrucker2.cxx
index 7f33f5075732ed0b53329dc1f40182be953963f8..0fded6d025489e81fc5a74f73822d9d516e9bc82 100755 (executable)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: PhilipsToBrucker2.cxx,v $
   Language:  C++
-  Date:      $Date: 2006/01/19 11:43:48 $
-  Version:   $Revision: 1.4 $
+  Date:      $Date: 2006/03/17 14:36:37 $
+  Version:   $Revision: 1.20 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -50,9 +50,9 @@ int main(int argc, char *argv[])
    " - orders the gdcm-readable found Files according to their                ",
    "           (0x0010, 0x0010) Patient's Name                                ",
    "           (0x0020, 0x000e) Series Instance UID                           ",
-   "           (0x0020, 0x0032) Image Position (Patient)                      ",
+   "           (0x0020, 0x0032)PhilipsToBrucker2. Image Position (Patient)    ",
    "           (0x0018, 0x1060) Trigger Time                                  ",
-   "           (0x0018, 0x1312) In-plane Phase Encoding Direction             ",
+   "           (0x0018, 0x1312) In-pl)ane Phase Encoding Direction             ",
    " - fills a single level (*) Directory with *all* the files,               ",
    "           converted into a Brucker-like Dicom, InTags compliant          ",
    "   (*) actually : creates as many directories as Patients                 ",
@@ -73,6 +73,7 @@ int main(int argc, char *argv[])
    "                  dirout=outputDirectoryName                              ",
    "                  {  [keep= list of seriesNumber to process]              ",
    "                   | [drop= list of seriesNumber to ignore] }             ",
+   "                  [taggrid] [skel]                                        ",
    "                  [input = {ACR|DCM}]                                     ", 
    "                  [extent=image suffix (.IMA, .NEMA, .DCM, ...)]          ",
    "                  [listonly] [split]                                      ",
@@ -84,8 +85,10 @@ int main(int argc, char *argv[])
    " drop : if user wants to ignore a limited number of series                ",
    "            he gives the list of 'SeriesNumber' (tag 0020|0011)           ",   
    "        SeriesNumber are short enough to be human readable                ",
-   "        e.g : 1030,1035,1043                                              ",
+   "        e.g : 1030,1035,1043                                              ", 
+   " taggrid : user knows all the images are 'grid' -ie : not 'col', not 'raw'",
    " extent : DO NOT forget the leading '.' !                                 ",
+   " skel: name skeleton eg : patName_1.nema -> skel=patName_                 ",
    " split: creates a tree-like structure of directories as :                 ",
    "        - Patient                                                         ",
    "        -- Serie                                                          ",
@@ -110,11 +113,11 @@ int main(int argc, char *argv[])
       return 0;
    }
 
-   char *dirNamein;   
-   dirNamein  = am->ArgMgrGetString("dirin",(char *)"."); 
+   const char *dirNamein;   
+   dirNamein  = am->ArgMgrGetString("dirin","."); 
 
-   char *dirNameout;   
-   dirNameout  = am->ArgMgrGetString("dirout",(char *)".");  
+   const char *dirNameout;   
+   dirNameout  = am->ArgMgrGetString("dirout",".");  
    
    int loadMode = gdcm::LD_ALL;
    if ( am->ArgMgrDefined("noshadowseq") )
@@ -146,10 +149,15 @@ int main(int argc, char *argv[])
       return 0;         
    }
    
-   char *extent  = am->ArgMgrGetString("extent",".DCM");
+   int taggrid = am->ArgMgrDefined("taggrid");
+   
+   int hasSkel = am->ArgMgrDefined("skel");
+   const char *skel;
+   if (hasSkel)
+      skel = am->ArgMgrGetString("skel");   
+      
+   const char *extent  = am->ArgMgrGetString("extent",".DCM");
    
-   char *input =  am->ArgMgrGetString("input","DCM"); 
-         
    // if unused Param we give up
    if ( am->ArgMgrPrintUnusedLabels() )
    { 
@@ -205,12 +213,13 @@ int main(int argc, char *argv[])
       std::cout << "------------List of found files ------------" << std::endl;
       dirList.Print();
    }
-
+   
    gdcm::DirListType fileNames;
    fileNames = dirList.GetFilenames();
    gdcm::SerieHelper *s;              // Needed only to may use SerieHelper::AddSeriesDetail()
    s = gdcm::SerieHelper::New();
 
+   std::string token = "%%%"; // Hope it's enough!
 /*       
    std::cout << "---------------Print Serie--------------" << std::endl; 
    s->SetDirectory(dirNamein, true); // true : recursive exploration 
@@ -221,12 +230,14 @@ int main(int argc, char *argv[])
   
    gdcm::File *f;
    gdcm::FileHelper *fh;
+   std::vector<std::string> tokens;
+   std::vector<std::string> tokensForFileName;
 /*   
    std::cout << "---------------Print Unique Series identifiers---------"  
              << std::endl;     
    std::string uniqueSeriesIdentifier;
  
-   for (gdcm::DirListType::iterator it = fileNames.begin();  
+   for (gdcm::DirListType::iterator it) = fileNames.begin();  
                                     it != fileNames.end();
                                   ++it)
    {
@@ -310,16 +321,40 @@ int main(int argc, char *argv[])
       }      
 
       userFileIdentifier=s->CreateUserDefinedFileIdentifier(f); 
-     // userFileIdentifier += "_";
-      //userFileIdentifier += *it;       
-      std::cout << "                           [" <<
-              userFileIdentifier  << "]" << std::endl;
+      tokens.clear();
+      gdcm::Util::Tokenize (userFileIdentifier, tokens, token); 
+   
+      int imageNum; // Within FileName
+      char newName[1024];
       
+      if ( tokens[3] == "gdcmUnfound")  // sometimes Trigger Time is not found. CreateUserDefinedFileIdentifier is not aware of the pb.
+      {
+         ///this is a trick to build up a lexicographical compliant name :
+         ///     eg : fich001.ima vs fich100.ima as opposed to fich1.ima vs fich100.ima
+         std::string name = gdcm::Util::GetName( *it );
+         if (hasSkel)
+         {
+            gdcm::Util::Tokenize (name, tokensForFileName, skel);
+            imageNum = atoi ( tokensForFileName[0].c_str() );
+            // probabely we could write something much more complicated using C++ !
+            sprintf (newName, "%s%06d%s", skel, imageNum, extent);
+            tokens[3] = newName;
+            tokensForFileName.clear();    
+         }
+         else
+            tokens[3] = name;
+         userFileIdentifier = tokens[0] + token + tokens[1] + token + tokens[2] + token 
+                    + tokens[3] + token + tokens[4] + token;
+      }   
+      if (verbose) 
+         std::cout << "[" << userFileIdentifier  << "]" << std::endl;
+               
       // storing in a map ensures automatic sorting !      
       sf[userFileIdentifier] = f;
    }
       
-   std::vector<std::string> tokens;
    std::string fullFilename, lastFilename;
    std::string previousPatientName, currentPatientName;
    std::string previousSerieInstanceUID, currentSerieInstanceUID;
@@ -343,7 +378,7 @@ int main(int argc, char *argv[])
    previousPhaseEncodingDirection = "";
    previousTriggerTime            = "";
    
-   int sliceIndex = 1;
+   int sliceIndex = 0; // Is incremented *at the beginning* of processing
    int frameIndex = 1;
    int flag       = 0;
        
@@ -355,17 +390,17 @@ int main(int argc, char *argv[])
        
       fullFilename =  currentFile->GetFileName();
       lastFilename =  gdcm::Util::GetName( fullFilename ); 
-      std::cout << "Try to write" <<lastFilename << std::endl;
+      std::cout << "Rewrite [" <<lastFilename << "]" << std::endl;
      
       tokens.clear();
-      gdcm::Util::Tokenize (it2->first, tokens, "_");
+      gdcm::Util::Tokenize (it2->first, tokens, token);
       
       currentPatientName            = tokens[0];
       currentSerieInstanceUID       = tokens[1];
       currentImagePosition          = tokens[2];
       currentTriggerTime            = tokens[3];
-      currentPhaseEncodingDirection = tokens[4];           
-      
+      currentPhaseEncodingDirection = tokens[4]; 
+
       if ( currentImagePosition[0] == '-')
           currentImagePosition[0] = 'M';
       if ( currentImagePosition[0] == '+')
@@ -426,7 +461,10 @@ int main(int argc, char *argv[])
          }
          previousImagePosition          = currentImagePosition;
          previousPhaseEncodingDirection = ""; //currentPhaseEncodingDirection;
-         sliceIndex += 1;
+         if (split)
+            sliceIndex = 1; // only *one* slice in a given directory
+         else
+            sliceIndex += 1;
       }      
 
 // We don't split on Row/Column!
@@ -469,37 +507,69 @@ int main(int argc, char *argv[])
       float pxSzY = currentFile->GetYSpacing();
       char fov[64];
       sprintf(fov, "%f\\%f",nX*pxSzX, nY*pxSzY);
-      currentFile->InsertEntryString(fov, 0x0019, 0x1000, "DS");
+      if (currentFile->IsVRCoherent(0x0019) == 1 )
+         currentFile->InsertEntryString(fov, 0x0019, 0x1000, "  ");
+      else     
+         currentFile->InsertEntryString(fov, 0x0019, 0x1000, "DS");
+
      
       // Deal with 0x0020, 0x0012 : 'SESSION INDEX'  (Acquisition Number)
       std::string chSessionIndex;
-      if (currentPhaseEncodingDirection == "ROW")
+      // CLEANME
+      if (taggrid) 
          chSessionIndex = "1";
       else
-         chSessionIndex = "2"; // suppose it's "COLUMN" !
-      currentFile->InsertEntryString(chSessionIndex, 0x0020, 0x0012, "IS");
-   
+      {
+         if (currentPhaseEncodingDirection == "COL" || currentPhaseEncodingDirection == "COL " || currentPhaseEncodingDirection == " COL")
+            chSessionIndex = "1";
+         else if (currentPhaseEncodingDirection == "ROW" || currentPhaseEncodingDirection == "ROW "|| currentPhaseEncodingDirection == " ROW")
+            chSessionIndex = "2"; 
+         else
+         {
+            std::cout << "====================== PhaseEncodingDirection "
+                      << " neither COL nor ROW (?!?) : [ "
+                      << currentPhaseEncodingDirection << "]" << std::endl;
+            chSessionIndex = "1";
+         }
+      }
+       if (currentFile->IsVRCoherent(0x0020) == 1 )     
+         currentFile->InsertEntryString(chSessionIndex, 0x0020, 0x0012, "  ");
+       else
+         currentFile->InsertEntryString(chSessionIndex, 0x0020, 0x0012, "IS");
       // Deal with  0x0021, 0x1020 : 'SLICE INDEX'
       char chSliceIndex[5];
       sprintf(chSliceIndex, "%04d", sliceIndex);
       std::string strChSliceIndex(chSliceIndex);
-      currentFile->InsertEntryString(strChSliceIndex, 0x0021, 0x1020, "IS");
        
       // Deal with  0x0021, 0x1040 : 'FRAME INDEX' 
       char chFrameIndex[5];
       sprintf(chFrameIndex, "%04d", frameIndex);
-      currentFile->InsertEntryString(chFrameIndex, 0x0021, 0x1040, "IS"); 
-      
-      if (flag == 0)
-      {       
-         flag = 1;
-      }
+
+      std::string stringVR;       
+      if (currentFile->IsVRCoherent(0x0021) == 1 )
+         stringVR = "  ";
       else
-      {
+        stringVR = "IS";
+  
+      currentFile->InsertEntryString(strChSliceIndex, 0x0021, 0x1020, stringVR);
+      currentFile->InsertEntryString(chFrameIndex, 0x0021, 0x1040, stringVR); 
+      
+      if (taggrid)
          frameIndex++;
-         flag = 0;
-      }
-                    
+      else     
+      {     
+         if (flag == 0)
+         {       
+            flag = 1;
+         }
+         else
+         {
+            frameIndex++;
+            flag = 0;
+         }
+      } 
+                 
       if (split)
       
          //fullWriteFilename = currentPhaseEncodingDirectionWriteDir + gdcm::GDCM_FILESEPARATOR 
@@ -521,6 +591,12 @@ int main(int argc, char *argv[])
       fh = gdcm::FileHelper::New(currentFile);     
       fh->GetImageDataRaw(); // Don't convert (Gray Pixels + LUT) into (RGB pixels) ?!?
       fh->SetWriteTypeToDcmExplVR();
+      // We didn't modify pixels -> keep unchanged the following :
+      // 'Media Storage SOP Class UID' (0x0002,0x0002)
+      // 'SOP Class UID'               (0x0008,0x0016)
+      // 'Image Type'                  (0x0008,0x0008)
+      // 'Conversion Type'             (0x0008,0x0064)
+      fh->SetContentType(gdcm::UNMODIFIED_PIXELS_IMAGE);
       if (!fh->Write(fullWriteFilename))
       {
          std::cout << "Fail to write :[" << fullWriteFilename << "]"