Main Page | File List | Related Pages

gdcmHeaderHelper.cxx

00001 // gdcmHeaderHelper.cxx
00002 //-----------------------------------------------------------------------------
00003 #include "gdcmHeaderHelper.h"
00004 #include "gdcmDirList.h"
00005 
00006 #include "gdcmUtil.h" //for debug
00007 #include <math.h>
00008 #include <algorithm>
00009 
00010 //-----------------------------------------------------------------------------
00011 // gdcmHeaderHelper
00012 //-----------------------------------------------------------------------------
00013 // Constructor / Destructor
00018 gdcmHeaderHelper::gdcmHeaderHelper() : gdcmHeader( ) {
00019 
00020 }
00021 
00033 gdcmHeaderHelper::gdcmHeaderHelper(const char *InFilename, 
00034                                    bool exception_on_error,
00035                                    bool enable_sequences,
00036                                    bool ignore_shadow)                             
00037                  : gdcmHeader( InFilename, 
00038                                exception_on_error,
00039                                enable_sequences,
00040                                ignore_shadow)
00041 {
00042 }
00043 
00044 //-----------------------------------------------------------------------------
00045 // Print
00046 
00047 //-----------------------------------------------------------------------------
00048 // Public
00055 int gdcmHeaderHelper::GetPixelSize() {
00056 
00057      // 0028 0100 US IMG Bits Allocated
00058      // (in order no to be messed up by old RGB images)
00059    if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
00060       return 3;
00061          
00062    std::string PixelType = GetPixelType();
00063    if (PixelType == "8U"  || PixelType == "8S")
00064       return 1;
00065    if (PixelType == "16U" || PixelType == "16S")
00066       return 2;
00067    if (PixelType == "32U" || PixelType == "32S")
00068       return 4;
00069    if (PixelType == "FD") // to help unfortunate users to manage DOUBLE
00070       return 8;
00071    dbg.Verbose(0, "gdcmHeader::GetPixelSize: Unknown pixel type");
00072    return 0;
00073 }
00074 
00093 std::string gdcmHeaderHelper::GetPixelType() {
00094    std::string BitsAlloc;
00095    BitsAlloc = GetEntryByNumber(0x0028, 0x0100);
00096    if (BitsAlloc == GDCM_UNFOUND) { // Bits Allocated
00097       dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
00098       BitsAlloc = std::string("16");
00099    }
00100    if (BitsAlloc == "12")           // It will be unpacked
00101       BitsAlloc = std::string("16");
00102    else if (BitsAlloc == "24")      // (in order no to be messed up
00103       BitsAlloc = std::string("8"); // by old RGB images)
00104     
00105    std::string Signed;
00106    Signed = GetEntryByNumber(0x0028, 0x0103);
00107    if (Signed == GDCM_UNFOUND) { // "Pixel Representation"
00108       dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
00109       BitsAlloc = std::string("0");
00110    }
00111    if (BitsAlloc == "64") // to help users that want to deal with DOUBLE
00112       return("FD");
00113       
00114    if (Signed == "0")
00115       Signed = std::string("U");
00116    else
00117       Signed = std::string("S");
00118 
00119    return( BitsAlloc + Signed);
00120 }
00121 
00128 float gdcmHeaderHelper::GetXSpacing() {
00129     float xspacing, yspacing;
00130     std::string StrSpacing = GetEntryByNumber(0x0028,0x0030);
00131     
00132    if (StrSpacing == GDCM_UNFOUND) {
00133       dbg.Verbose(0, "gdcmHeader::GetXSpacing: unfound Pixel Spacing (0028,0030)");
00134       return 1.;
00135     }
00136   if( sscanf( StrSpacing.c_str(), "%f\\%f", &yspacing, &xspacing) != 2)
00137     return 0.;
00138   if (xspacing == 0.) {
00139     dbg.Verbose(0, "gdcmHeader::GetYSpacing: gdcmData/CT-MONO2-8-abdo.dcm problem");
00140     // seems to be a bug in the header ...
00141     sscanf( StrSpacing.c_str(), "%f\\0\\%f", &yspacing, &xspacing);
00142   }
00143   return xspacing;
00144 }
00145 
00152 float gdcmHeaderHelper::GetYSpacing() {
00153    float xspacing, yspacing;
00154    std::string StrSpacing = GetEntryByNumber(0x0028,0x0030);
00155   
00156    if (StrSpacing == GDCM_UNFOUND) {
00157       dbg.Verbose(0, "gdcmHeader::GetYSpacing: unfound Pixel Spacing (0028,0030)");
00158       return 1.;
00159     }
00160   if( sscanf( StrSpacing.c_str(), "%f\\%f", &yspacing, &xspacing) != 2)
00161     return 0.;
00162   if (xspacing == 0.) {
00163     dbg.Verbose(0, "gdcmHeader::GetYSpacing: gdcmData/CT-MONO2-8-abdo.dcm problem");
00164     // seems to be a bug in the header ...
00165     sscanf( StrSpacing.c_str(), "%f\\0\\%f", &yspacing, &xspacing);
00166   }
00167   return yspacing;
00168 } 
00169 
00177 float gdcmHeaderHelper::GetZSpacing() {
00178    // Spacing Between Slices : distance entre le milieu de chaque coupe
00179    // Les coupes peuvent etre :
00180    //   jointives     (Spacing between Slices = Slice Thickness)
00181    //   chevauchantes (Spacing between Slices < Slice Thickness)
00182    //   disjointes    (Spacing between Slices > Slice Thickness)
00183    // Slice Thickness : epaisseur de tissus sur laquelle est acquis le signal
00184    //   ca interesse le physicien de l'IRM, pas le visualisateur de volumes ...
00185    //   Si le Spacing Between Slices est absent, 
00186    //   on suppose que les coupes sont jointives
00187    
00188    std::string StrSpacingBSlices = GetEntryByNumber(0x0018,0x0088);
00189 
00190    if (StrSpacingBSlices == GDCM_UNFOUND) {
00191       dbg.Verbose(0, "gdcmHeader::GetZSpacing: unfound StrSpacingBSlices");
00192       std::string StrSliceThickness = GetEntryByNumber(0x0018,0x0050);       
00193       if (StrSliceThickness == GDCM_UNFOUND)
00194          return 1.;
00195       else
00196          // if no 'Spacing Between Slices' is found, 
00197          // we assume slices join together
00198          // (no overlapping, no interslice gap)
00199          // if they don't, we're fucked up
00200          return atof(StrSliceThickness.c_str());  
00201    } else {
00202       return atof(StrSpacingBSlices.c_str());
00203    }
00204 }
00205 
00211 float gdcmHeaderHelper::GetRescaleIntercept() {
00212   float resInter = 0.;
00213   std::string StrRescInter = GetEntryByNumber(0x0028,0x1052); //0028 1052 DS IMG Rescale Intercept
00214   if (StrRescInter != GDCM_UNFOUND) {
00215       if( sscanf( StrRescInter.c_str(), "%f", &resInter) != 1) {
00216          dbg.Verbose(0, "gdcmHeader::GetRescaleIntercept: Rescale Slope is empty");
00217            // bug in the element 0x0028,0x1052
00218       }    
00219    }
00220   return resInter;
00221 }
00222 
00228  float gdcmHeaderHelper::GetRescaleSlope() {
00229   float resSlope = 1.;
00230   std::string StrRescSlope = GetEntryByNumber(0x0028,0x1053); //0028 1053 DS IMG Rescale Slope
00231   if (StrRescSlope != GDCM_UNFOUND) {
00232       if( sscanf( StrRescSlope.c_str(), "%f", &resSlope) != 1) {
00233          dbg.Verbose(0, "gdcmHeader::GetRescaleSlope: Rescale Slope is empty");
00234            // bug in the element 0x0028,0x1053
00235       }    
00236    }  
00237    return resSlope;
00238 }
00239 
00248 int gdcmHeaderHelper::GetNumberOfScalarComponents() {
00249    if (GetSamplesPerPixel() ==3)
00250       return 3;
00251       
00252      // 0028 0100 US IMG Bits Allocated
00253      // (in order no to be messed up by old RGB images)
00254    if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
00255       return 3;
00256        
00257    std::string PhotometricInterpretation = 
00258                   gdcmHeader::GetEntryByNumber(0x0028,0x0004);
00259 
00260    if ( ( PhotometricInterpretation == "PALETTE COLOR ") ) {
00261       if (HasLUT())   // PALETTE COLOR is NOT enough
00262          return 3;
00263       else
00264          return 1;       
00265    }   
00266                   
00267       //beware of trailing space at end of string                                               
00268    if (PhotometricInterpretation.find(GDCM_UNFOUND) < 
00269                            PhotometricInterpretation.length() || 
00270        PhotometricInterpretation.find("MONOCHROME1") < 
00271                            PhotometricInterpretation.length() || 
00272        PhotometricInterpretation.find("MONOCHROME2") < 
00273                            PhotometricInterpretation.length() ) 
00274        return 1;
00275     else
00276     // we assume that *all* kinds of YBR are dealt with
00277       return 3;
00278 }
00279 
00288 int gdcmHeaderHelper::GetNumberOfScalarComponentsRaw() {
00289       
00290      // 0028 0100 US IMG Bits Allocated
00291      // (in order no to be messed up by old RGB images)
00292    if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
00293       return 3;
00294 
00295     // we assume that *all* kinds of YBR are dealt with
00296       return GetSamplesPerPixel();
00297 }
00298 
00305  std::string gdcmHeaderHelper::GetStudyUID(){
00306   return GetEntryByNumber(0x0020,0x000d); //0020 000d UI REL Study Instance UID
00307 }
00308 
00315  std::string gdcmHeaderHelper::GetSeriesUID(){
00316   return GetEntryByNumber(0x0020,0x000e); //0020 000e UI REL Series Instance UID
00317 }
00318 
00325  std::string gdcmHeaderHelper::GetClassUID(){
00326   return GetEntryByNumber(0x0008,0x0016); //0008 0016 UI ID SOP Class UID
00327 }
00328 
00335  std::string gdcmHeaderHelper::GetInstanceUID(){
00336   return GetEntryByNumber(0x0008,0x0018); //0008 0018 UI ID SOP Instance UID
00337 }
00338 //
00339 // --------------  Remember ! ----------------------------------
00340 //
00341 // Image Position Patient                              (0020,0032):
00342 // If not found (ACR_NEMA) we try Image Position       (0020,0030)
00343 // If not found (ACR-NEMA), we consider Slice Location (0020,1041)
00344 //                                   or Location       (0020,0050) 
00345 // as the Z coordinate, 
00346 // 0. for all the coordinates if nothing is found
00347 
00348 // TODO : find a way to inform the caller nothing was found
00349 // TODO : How to tell the caller a wrong number of values was found?
00350 //
00351 // ---------------------------------------------------------------
00352 //
00353 
00362 float gdcmHeaderHelper::GetXOrigin() {
00363     float xImPos, yImPos, zImPos;  
00364     std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
00365 
00366     if (StrImPos == GDCM_UNFOUND) {
00367        dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position Patient (0020,0032)");
00368        StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
00369        if (StrImPos == GDCM_UNFOUND) {
00370           dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position (RET) (0020,0030)");
00371           // How to tell the caller nothing was found ?
00372          return 0.;
00373        }  
00374      }
00375    if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
00376      return 0.;
00377    return xImPos;
00378 }
00379 
00387 float gdcmHeaderHelper::GetYOrigin() {
00388     float xImPos, yImPos, zImPos;
00389     std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
00390 
00391     if (StrImPos == GDCM_UNFOUND) {
00392        dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position Patient (0020,0032)");
00393        StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
00394        if (StrImPos == GDCM_UNFOUND) {
00395           dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position (RET) (0020,0030)");
00396           // How to tell the caller nothing was found ?
00397            return 0.;
00398        }  
00399      }
00400    if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
00401      return 0.;
00402    return yImPos;
00403 }
00404 
00414 float gdcmHeaderHelper::GetZOrigin() {
00415    float xImPos, yImPos, zImPos; 
00416    std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
00417    if (StrImPos != GDCM_UNFOUND) {
00418       if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
00419          dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position Patient (0020,0032)");
00420          return 0.;  // bug in the element 0x0020,0x0032
00421       } else {
00422          return zImPos;
00423       }    
00424    }  
00425    StrImPos = GetEntryByNumber(0x0020,0x0030); // For ACR-NEMA images
00426    if (StrImPos != GDCM_UNFOUND) {
00427       if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
00428          dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position (RET) (0020,0030)");
00429          return 0.;  // bug in the element 0x0020,0x0032
00430       } else {
00431          return zImPos;
00432       }    
00433    }                
00434    std::string StrSliceLocation = GetEntryByNumber(0x0020,0x1041);// for *very* old ACR-NEMA images
00435    if (StrSliceLocation != GDCM_UNFOUND) {
00436       if( sscanf( StrSliceLocation.c_str(), "%f", &zImPos) !=1) {
00437          dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Slice Location (0020,1041)");
00438          return 0.;  // bug in the element 0x0020,0x1041
00439       } else {
00440          return zImPos;
00441       }
00442    }   
00443    dbg.Verbose(0, "gdcmHeader::GetZImagePosition: unfound Slice Location (0020,1041)");
00444    std::string StrLocation = GetEntryByNumber(0x0020,0x0050);
00445    if (StrLocation != GDCM_UNFOUND) {
00446       if( sscanf( StrLocation.c_str(), "%f", &zImPos) !=1) {
00447          dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Location (0020,0050)");
00448          return 0.;  // bug in the element 0x0020,0x0050
00449       } else {
00450          return zImPos;
00451       }
00452    }
00453    dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Location (0020,0050)");  
00454    return 0.; // Hopeless
00455 }
00456 
00463 int gdcmHeaderHelper::GetImageNumber() {
00464   //The function i atoi() takes the address of an area of memory as parameter and converts 
00465   //the string stored at that location to an integer using the external decimal to internal
00466   //binary conversion rules. This may be preferable to sscanf() since atoi() is a much smaller,
00467   // simpler and faster function. sscanf() can do all possible conversions whereas atoi() can 
00468   //only do single decimal integer conversions.
00469   std::string StrImNumber = GetEntryByNumber(0x0020,0x0013); //0020 0013 IS REL Image Number
00470   if (StrImNumber != GDCM_UNFOUND) {
00471     return atoi( StrImNumber.c_str() );
00472   }
00473   return 0;   //Hopeless
00474 }
00475 
00481 ModalityType gdcmHeaderHelper::GetModality(void) {
00482   std::string StrModality = GetEntryByNumber(0x0008,0x0060); //0008 0060 CS ID Modality
00483   if (StrModality != GDCM_UNFOUND) {
00484          if ( StrModality.find("AU") < StrModality.length()) return AU;
00485     else if ( StrModality.find("AS") < StrModality.length()) return AS;
00486     else if ( StrModality.find("BI") < StrModality.length()) return BI;
00487     else if ( StrModality.find("CF") < StrModality.length()) return CF;
00488     else if ( StrModality.find("CP") < StrModality.length()) return CP;
00489     else if ( StrModality.find("CR") < StrModality.length()) return CR;
00490     else if ( StrModality.find("CT") < StrModality.length()) return CT;
00491     else if ( StrModality.find("CS") < StrModality.length()) return CS;
00492     else if ( StrModality.find("DD") < StrModality.length()) return DD;
00493     else if ( StrModality.find("DF") < StrModality.length()) return DF;
00494     else if ( StrModality.find("DG") < StrModality.length()) return DG;
00495     else if ( StrModality.find("DM") < StrModality.length()) return DM;
00496     else if ( StrModality.find("DS") < StrModality.length()) return DS;
00497     else if ( StrModality.find("DX") < StrModality.length()) return DX;
00498     else if ( StrModality.find("ECG") < StrModality.length()) return ECG;
00499     else if ( StrModality.find("EPS") < StrModality.length()) return EPS;
00500     else if ( StrModality.find("FA") < StrModality.length()) return FA;
00501     else if ( StrModality.find("FS") < StrModality.length()) return FS;
00502     else if ( StrModality.find("HC") < StrModality.length()) return HC;
00503     else if ( StrModality.find("HD") < StrModality.length()) return HD;
00504     else if ( StrModality.find("LP") < StrModality.length()) return LP;
00505     else if ( StrModality.find("LS") < StrModality.length()) return LS;
00506     else if ( StrModality.find("MA") < StrModality.length()) return MA;
00507     else if ( StrModality.find("MR") < StrModality.length()) return MR;
00508     else if ( StrModality.find("NM") < StrModality.length()) return NM;
00509     else if ( StrModality.find("OT") < StrModality.length()) return OT;
00510     else if ( StrModality.find("PT") < StrModality.length()) return PT;
00511     else if ( StrModality.find("RF") < StrModality.length()) return RF;
00512     else if ( StrModality.find("RG") < StrModality.length()) return RG;
00513     else if ( StrModality.find("RTDOSE")  < StrModality.length()) return RTDOSE;
00514     else if ( StrModality.find("RTIMAGE") < StrModality.length()) return RTIMAGE;
00515     else if ( StrModality.find("RTPLAN")  < StrModality.length()) return RTPLAN;
00516     else if ( StrModality.find("RTSTRUCT")< StrModality.length()) return RTSTRUCT;
00517     else if ( StrModality.find("SM") < StrModality.length()) return SM;
00518     else if ( StrModality.find("ST") < StrModality.length()) return ST;
00519     else if ( StrModality.find("TG") < StrModality.length()) return TG;
00520     else if ( StrModality.find("US") < StrModality.length()) return US;
00521     else if ( StrModality.find("VF") < StrModality.length()) return VF;
00522     else if ( StrModality.find("XA") < StrModality.length()) return XA;
00523     else if ( StrModality.find("XC") < StrModality.length()) return XC;
00524 
00525     else
00526     {
00527       //throw error return value ???
00528       // specified <> unknow in our database
00529       return Unknow;
00530     }
00531   }
00532   return Unknow;
00533 }
00534 
00541 void gdcmHeaderHelper::GetImageOrientationPatient( float* iop ) {
00542 
00543   //iop is supposed to be float[6]
00544   iop[0] = iop[1] = iop[2] = iop[3] = iop[4] = iop[5] = 0;
00545   
00546   std::string StrImOriPat = GetEntryByNumber(0x0020,0x0037); // 0020 0037 DS REL Image Orientation (Patient)
00547   if (StrImOriPat != GDCM_UNFOUND) {
00548     if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", 
00549             &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
00550          dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0037)");
00551          return ;  // bug in the element 0x0020,0x0037
00552     } 
00553     else
00554       return ;
00555   }
00556   
00557   //For ACR-NEMA
00558   StrImOriPat = GetEntryByNumber(0x0020,0x0035); //0020 0035 DS REL Image Orientation (RET)
00559   if (StrImOriPat != GDCM_UNFOUND) {
00560     if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f", 
00561             &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
00562          dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0035)");
00563          return ;  // bug in the element 0x0020,0x0035
00564     } 
00565     else
00566       return ;
00567   }
00568 }
00569 
00570 //-----------------------------------------------------------------------------
00571 // Protected
00572 
00573 //-----------------------------------------------------------------------------
00574 // Private
00575 
00576 //-----------------------------------------------------------------------------
00577 
00578 
00579 
00580 //-----------------------------------------------------------------------------
00581 // gdcmSerieHeaderHelper
00582 //-----------------------------------------------------------------------------
00583 // Constructor / Destructor
00584 gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper(){
00586   for (std::list<gdcmHeaderHelper*>::iterator it  = CoherentGdcmFileList.begin();
00587         it != CoherentGdcmFileList.end(); it++)
00588   {
00589     delete *it;
00590   }
00591   CoherentGdcmFileList.clear();
00592 }
00593 
00594 //-----------------------------------------------------------------------------
00595 // Print
00596 
00597 //-----------------------------------------------------------------------------
00598 // Public
00604 void gdcmSerieHeaderHelper::AddFileName(std::string filename) {
00605   gdcmHeaderHelper *GdcmFile = new gdcmHeaderHelper( filename.c_str() );
00606   this->CoherentGdcmFileList.push_back( GdcmFile );
00607 }
00608 
00614 void gdcmSerieHeaderHelper::AddGdcmFile(gdcmHeaderHelper *file){
00615   this->CoherentGdcmFileList.push_back( file );
00616 }
00617 
00623 void gdcmSerieHeaderHelper::SetDirectory(std::string dir){
00624   gdcmDirList filenames_list(dir);  //OS specific
00625   
00626   for(gdcmDirList::iterator it = filenames_list.begin(); 
00627       it !=filenames_list.end(); it++)
00628   {
00629     gdcmHeaderHelper *file = new gdcmHeaderHelper( it->c_str() );
00630     this->CoherentGdcmFileList.push_back( file );
00631   }
00632 }
00633 
00641 void gdcmSerieHeaderHelper::OrderGdcmFileList(){
00642   if( ImagePositionPatientOrdering() ) {
00643     return ;
00644   }
00645   else if( ImageNumberOrdering() ) {
00646     return ;
00647   } else  {
00648     FileNameOrdering();
00649   }
00650 }
00651 
00657 std::list<gdcmHeaderHelper*> &gdcmSerieHeaderHelper::GetGdcmFileList() {
00658   return CoherentGdcmFileList;
00659 }
00660 
00661 //-----------------------------------------------------------------------------
00662 // Protected
00663 
00664 //-----------------------------------------------------------------------------
00665 // Private
00675 bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering()
00676 //based on Jolinda's algorithm
00677 {
00678   //iop is calculated based on the file file
00679   float *cosines = new float[6];
00680   float normal[3];
00681   float ipp[3];
00682   float dist;
00683   float min, max;
00684   bool first = true;
00685   int n=0;
00686   std::vector<float> distlist;
00687 
00689   for (std::list<gdcmHeaderHelper*>::iterator it  = CoherentGdcmFileList.begin();
00690         it != CoherentGdcmFileList.end(); it++)
00691   {
00692     if(first) {
00693       (*it)->GetImageOrientationPatient(cosines);
00694       
00695       //You only have to do this once for all slices in the volume. Next, for
00696       //each slice, calculate the distance along the slice normal using the IPP
00697       //tag ("dist" is initialized to zero before reading the first slice) :
00698       normal[0] = cosines[1]*cosines[5] - cosines[2]*cosines[4];
00699       normal[1] = cosines[2]*cosines[3] - cosines[0]*cosines[5];
00700       normal[2] = cosines[0]*cosines[4] - cosines[1]*cosines[3];
00701   
00702       ipp[0] = (*it)->GetXOrigin();
00703       ipp[1] = (*it)->GetYOrigin();
00704       ipp[2] = (*it)->GetZOrigin();
00705 
00706       dist = 0;
00707       for (int i = 0; i < 3; ++i)
00708           dist += normal[i]*ipp[i];
00709     
00710       if( dist == 0 )
00711       {
00712         delete[] cosines;
00713         return false;
00714       }
00715 
00716       distlist.push_back( dist );
00717 
00718       max = min = dist;
00719       first = false;
00720     }
00721     else {
00722       ipp[0] = (*it)->GetXOrigin();
00723       ipp[1] = (*it)->GetYOrigin();
00724       ipp[2] = (*it)->GetZOrigin();
00725   
00726       dist = 0;
00727       for (int i = 0; i < 3; ++i)
00728           dist += normal[i]*ipp[i];
00729 
00730       if( dist == 0 )
00731       {
00732         delete[] cosines;
00733         return false;
00734       }
00735       
00736       distlist.push_back( dist );
00737 
00738       min = (min < dist) ? min : dist;
00739       max = (max > dist) ? max : dist;
00740     }
00741     n++;
00742   }
00743 
00744     //Then I order the slices according to the value "dist". Finally, once
00745     //I've read in all the slices, I calculate the z-spacing as the difference
00746     //between the "dist" values for the first two slices.
00747     std::vector<gdcmHeaderHelper*> CoherentGdcmFileVector(n);
00748     //CoherentGdcmFileVector.reserve( n );
00749     CoherentGdcmFileVector.resize( n );
00750     //assert( CoherentGdcmFileVector.capacity() >= n );
00751 
00752     float step = (max - min)/(n - 1);
00753     int pos;
00754     n = 0;
00755     
00756     //VC++ don't understand what scope is !! it -> it2
00757     for (std::list<gdcmHeaderHelper*>::iterator it2  = CoherentGdcmFileList.begin();
00758         it2 != CoherentGdcmFileList.end(); it2++, n++)
00759     {
00760       //2*n sort algo !!
00761       //Assumption: all files are present (no one missing)
00762       pos = (int)( fabs( (distlist[n]-min)/step) + .5 );
00763             
00764       CoherentGdcmFileVector[pos] = *it2;
00765     }
00766 
00767   CoherentGdcmFileList.clear();  //this doesn't delete list's element, node only
00768   
00769   //VC++ don't understand what scope is !! it -> it3
00770   for (std::vector<gdcmHeaderHelper*>::iterator it3  = CoherentGdcmFileVector.begin();
00771         it3 != CoherentGdcmFileVector.end(); it3++)
00772   {
00773     CoherentGdcmFileList.push_back( *it3 );
00774   }
00775 
00776   distlist.clear();
00777   CoherentGdcmFileVector.clear();
00778   delete[] cosines;
00779   
00780   return true;
00781 }
00782 
00789 bool gdcmSerieHeaderHelper::ImageNumberOrdering() {
00790   int min, max, pos;
00791   int n = 0;//CoherentGdcmFileList.size(); //O(N) operation !!
00792   unsigned char *partition;
00793   
00794   std::list<gdcmHeaderHelper*>::iterator it  = CoherentGdcmFileList.begin();
00795   min = max = (*it)->GetImageNumber();
00796 
00797   for (; it != CoherentGdcmFileList.end(); it++, n++)
00798   {
00799     pos = (*it)->GetImageNumber();
00800 
00801     //else
00802     min = (min < pos) ? min : pos;
00803   }
00804 
00805   //bzeros(partition, n); //Cette fonction est déconseillée, utilisez plutôt memset.
00806   partition = new unsigned char[n];
00807   memset(partition, 0, n);
00808 
00809   std::vector<gdcmHeaderHelper*> CoherentGdcmFileVector(n);
00810 
00811   //VC++ don't understand what scope is !! it -> it2
00812   for (std::list<gdcmHeaderHelper*>::iterator it2  = CoherentGdcmFileList.begin();
00813         it2 != CoherentGdcmFileList.end(); it2++)
00814   {
00815     pos = (*it2)->GetImageNumber();
00816     CoherentGdcmFileVector[pos - min] = *it2;
00817     partition[pos - min]++;
00818   }
00819   
00820   unsigned char mult = 1;
00821   for(int i=0; i<n ; i++)
00822   {
00823     mult *= partition[i];
00824   }
00825 
00826   //VC++ don't understand what scope is !! it -> it3
00827   CoherentGdcmFileList.clear();  //this doesn't delete list's element, node only
00828   for (std::vector<gdcmHeaderHelper*>::iterator it3  = CoherentGdcmFileVector.begin();
00829         it3 != CoherentGdcmFileVector.end(); it3++)
00830   {
00831     CoherentGdcmFileList.push_back( *it3 );
00832   }
00833   CoherentGdcmFileVector.clear();
00834   
00835   delete[] partition;
00836   return (mult!=0);
00837 }
00838 
00839 
00845  bool gdcmSerieHeaderHelper::FileNameOrdering() {
00846   //using the sort
00847   //sort(CoherentGdcmFileList.begin(), CoherentGdcmFileList.end());
00848   return true;
00849 }
00850 
00851 //-----------------------------------------------------------------------------

Generated on Mon Feb 14 16:13:44 2005 for gdcm by doxygen 1.3.6