X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmSerieHelper.cxx;h=d16d52635b5c573f5d25f34233d97f99736d9f00;hb=0317a9372b19b712e4033acbe257d92d5747c31b;hp=81358a14bab663ce27c47b04da0943de58a8a84c;hpb=906464b1c71b1b623f8202a693e75a358a5bd965;p=gdcm.git diff --git a/src/gdcmSerieHelper.cxx b/src/gdcmSerieHelper.cxx index 81358a14..d16d5263 100644 --- a/src/gdcmSerieHelper.cxx +++ b/src/gdcmSerieHelper.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSerieHelper.cxx,v $ Language: C++ - Date: $Date: 2006/02/16 20:06:15 $ - Version: $Revision: 1.47 $ + Date: $Date: 2006/05/30 08:10:19 $ + Version: $Revision: 1.53 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -19,7 +19,7 @@ #include "gdcmSerieHelper.h" #include "gdcmDirList.h" #include "gdcmFile.h" -#include "gdcmDictEntry.h" // for TranslateToKey +//#include "gdcmDictEntry.h" // for TranslateToKey : no more ! #include "gdcmDebug.h" #include "gdcmUtil.h" @@ -163,7 +163,7 @@ bool SerieHelper::AddFile(File *header) if ( SingleSerieUIDFileSetHT.count(id) == 0 ) { - gdcmDebugMacro(" New Serie UID :[" << id << "]"); + gdcmDebugMacro(" New/gdcmSerieHelper.cxx Serie UID :[" << id << "]"); // create a std::list in 'id' position SingleSerieUIDFileSetHT[id] = new FileList; } @@ -209,7 +209,7 @@ void SerieHelper::AddRestriction(TagKey const &key) ExRefine.push_back( r ); } -#ifndef GDCM_LEGACY_REMOVE +//#ifndef GDCM_LEGACY_REMOVE /** * \brief add a rule for restricting a DICOM file to be in the serie we are * trying to find. For example you can select only the DICOM files from a @@ -223,13 +223,15 @@ void SerieHelper::AddRestriction(TagKey const &key) * @deprecated use : AddRestriction(TagKey const &key, * std::string const &value, int op); */ + void SerieHelper::AddRestriction(uint16_t group, uint16_t elem, std::string const &value, int op) { TagKey t(group, elem); AddRestriction(t, value, op); } -#endif + +//#endif /** * \brief add an extra 'SerieDetail' for building a 'Serie Identifier' @@ -274,7 +276,10 @@ void SerieHelper::SetDirectory(std::string const &dir, bool recursive) */ void SerieHelper::OrderFileList(FileList *fileSet) { - + // Only computed during ImagePositionPatientOrdering + // (need to sort the FileList using IPP and IOP !) + ZSpacing = -1.0; + if ( SerieHelper::UserLessThanFunction ) { UserOrdering( fileSet ); @@ -327,12 +332,13 @@ bool SerieHelper::IsCoherent(FileList *fileSet) return true; } -#ifndef GDCM_LEGACY_REMOVE +//#ifndef GDCM_LEGACY_REMOVE /** * \brief accessor (DEPRECATED : use GetFirstSingleSerieUIDFileSet ) * Warning : 'coherent' means here they have the same Serie UID * @return The first FileList if found, otherwhise NULL */ + /* FileList *SerieHelper::GetFirstCoherentFileList() { ItFileSetHt = SingleSerieUIDFileSetHT.begin(); @@ -340,13 +346,14 @@ FileList *SerieHelper::GetFirstCoherentFileList() return ItFileSetHt->second; return NULL; } - +*/ /** * \brief accessor (DEPRECATED : use GetNextSingleSerieUIDFileSet ) * Warning : 'coherent' means here they have the same Serie UID * \note : meaningfull only if GetFirstCoherentFileList() already called * @return The next FileList if found, otherwhise NULL */ + /* FileList *SerieHelper::GetNextCoherentFileList() { gdcmAssertMacro (ItFileSetHt != SingleSerieUIDFileSetHT.end()); @@ -356,6 +363,7 @@ FileList *SerieHelper::GetNextCoherentFileList() return ItFileSetHt->second; return NULL; } +*/ /** * \brief accessor (DEPRECATED : use GetSingleSerieUIDFileSet ) @@ -363,13 +371,15 @@ FileList *SerieHelper::GetNextCoherentFileList() * @param SerieUID SerieUID * \return pointer to the FileList if found, otherwhise NULL */ + /* FileList *SerieHelper::GetCoherentFileList(std::string SerieUID) { if ( SingleSerieUIDFileSetHT.count(SerieUID) == 0 ) return 0; return SingleSerieUIDFileSetHT[SerieUID]; } -#endif +*/ +//#endif /** @@ -539,7 +549,7 @@ XCoherentFileSetmap SerieHelper::SplitOnPosition(FileList *fileSet) * value of a given Tag * @param fileSet File Set to be splitted * @param group group number of the target Element - * @param elem element number of the target Element + * @param element element number of the target Element * \return std::map of 'Xcoherent' File sets */ @@ -585,7 +595,8 @@ XCoherentFileSetmap SerieHelper::SplitOnTagValue(FileList *fileSet, // Private /** * \brief sorts the images, according to their Patient Position. - * + * As a side effect, it computes the ZSpacing, according to Jolinda Smith' + * algorithm. (get it with double GetZSpacing() !) * We may order, considering : * -# Image Position Patient * -# Image Number @@ -598,6 +609,9 @@ XCoherentFileSetmap SerieHelper::SplitOnTagValue(FileList *fileSet, bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) //based on Jolinda Smith's algorithm { +//Tags always use the same coordinate system, where "x" is left +//to right, "y" is posterior to anterior, and "z" is foot to head (RAH). + //iop is calculated based on the file file float cosines[6]; double normal[3]; @@ -605,6 +619,7 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) double dist; double min = 0, max = 0; bool first = true; + ZSpacing = -1.0; // will be updated if process doesn't fail std::multimap distmultimap; // Use a multimap to sort the distances from 0,0,0 @@ -615,7 +630,20 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) if ( first ) { (*it)->GetImageOrientationPatient( cosines ); - + + // The "Image Orientation Patient" tag gives the direction cosines + // for the rows and columns for the three axes defined above. + // Typical axial slices will have a value 1/0/0/0/1/0: + // rows increase from left to right, + // columns increase from posterior to anterior. This is your everyday + // "looking up from the bottom of the head with the eyeballs up" image. + + // The "Image Position Patient" tag gives the coordinates of the first + // voxel in the image in the "RAH" coordinate system, relative to some + // origin. + + // First, calculate the slice normal from IOP : + // You only have to do this once for all slices in the volume. Next, // for each slice, calculate the distance along the slice normal // using the IPP ("Image Position Patient") tag. @@ -623,7 +651,10 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) normal[0] = cosines[1]*cosines[5] - cosines[2]*cosines[4]; normal[1] = cosines[2]*cosines[3] - cosines[0]*cosines[5]; normal[2] = cosines[0]*cosines[4] - cosines[1]*cosines[3]; - + + // For each slice (here : the first), calculate the distance along + // the slice normal using the IPP tag + ipp[0] = (*it)->GetXOrigin(); ipp[1] = (*it)->GetYOrigin(); ipp[2] = (*it)->GetZOrigin(); @@ -641,6 +672,8 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) } else { + // Next, for each slice, calculate the distance along the slice normal + // using the IPP tag ipp[0] = (*it)->GetXOrigin(); ipp[1] = (*it)->GetYOrigin(); ipp[2] = (*it)->GetZOrigin(); @@ -688,8 +721,23 @@ bool SerieHelper::ImagePositionPatientOrdering( FileList *fileList ) return false; } +// Now, we could calculate Z Spacing as the difference +// between the "dist" values for the first two slices. + +// The following (un)-commented out code is let here +// to be re-used by whomsoever is interested... + + std::multimap::iterator it5 = distmultimap.begin(); + double d1 = (*it5).first; + it5++; + double d2 = (*it5).first; + ZSpacing = d1-d2; + if (ZSpacing < 0.0) + ZSpacing = - ZSpacing; + fileList->clear(); // doesn't delete list elements, only nodes +// Acording to user requierement, we sort direct order or reverse order. if (DirectOrder) { for (std::multimap::iterator it3 = distmultimap.begin(); @@ -991,5 +1039,14 @@ void SerieHelper::Sort(FileList *fileList, bool (*pt2Func)( File *file1, File *f std::sort(fileList->begin(), fileList->end(), pt2Func ); } +/* +#ifndef GDCM_LEGACY_REMOVE +bool SerieHelper::AddGdcmFile(File* header) +{ + return AddFile(header); +} +#endif +*/ + //----------------------------------------------------------------------------- } // end namespace gdcm