X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmSerieHelper.cxx;h=9ba06874c528efa1c51983436b38519473196ad0;hb=0e88aff6bcac1c201b50acb285ba079f3a6b1a6c;hp=412d719e82c7aecbd4bb68e27804dd5379c178b8;hpb=98cf38e32be18dc2b7d3d1a13e45f60717b008bc;p=gdcm.git diff --git a/src/gdcmSerieHelper.cxx b/src/gdcmSerieHelper.cxx index 412d719e..9ba06874 100644 --- a/src/gdcmSerieHelper.cxx +++ b/src/gdcmSerieHelper.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmSerieHelper.cxx,v $ Language: C++ - Date: $Date: 2005/12/16 13:48:46 $ - Version: $Revision: 1.40 $ + Date: $Date: 2006/01/31 11:29:41 $ + Version: $Revision: 1.45 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -214,8 +214,8 @@ void SerieHelper::AddGdcmFile(File *header) * directory which would have a particular EchoTime==4.0. * This method is a user level, value is not required to be formatted as a DICOM * string - * \todo find a trick to allow user if he wants the Rectrictions to be *ored* - * (and not only *anded*) + * \todo find a trick to allow user to say if he wants the Rectrictions + * to be *ored* (and not only *anded*) * @param key Target tag we want restrict on a given value * @param value value to be checked to exclude File * @param op operator we want to use to check @@ -259,15 +259,17 @@ void SerieHelper::AddRestriction(uint16_t group, uint16_t elem, * \brief add an extra 'SerieDetail' for building a 'Serie Identifier' * that ensures (hope so) File constistency (Series Instance UID doesn't. * @param group tag group number we want restrict on a given value - * @param elem tag element number we want restrict on a given value + * @param elem tag element number we want restrict on a given value + * @param convert wether we want 'convertion', to allow further ordering + * e.g : 100 would be *before* 20; 000020.00 vs 00100.00 : OK */ -void SerieHelper::AddSeriesDetail(uint16_t group, uint16_t elem) +void SerieHelper::AddSeriesDetail(uint16_t group, uint16_t elem, bool convert) { - m_UseSeriesDetails = true; ExDetail d; - d.group = group; - d.elem = elem; + d.group = group; + d.elem = elem; + d.convert = convert; ExDetails.push_back( d ); } /** @@ -766,11 +768,13 @@ bool SerieHelper::ImageNumberOrdering(FileList *fileList) return false; } if (DirectOrder) - std::sort(fileList->begin(), fileList->end(), - SerieHelper::ImageNumberLessThan ); + Sort(fileList,SerieHelper::ImageNumberLessThan); +// std::sort(fileList->begin(), fileList->end(), +// SerieHelper::ImageNumberLessThan ); else - std::sort(fileList->begin(), fileList->end(), - SerieHelper::ImageNumberGreaterThan ); + Sort(fileList,SerieHelper::ImageNumberGreaterThan); +// std::sort(fileList->begin(), fileList->end(), +// SerieHelper::ImageNumberGreaterThan ); return true; } @@ -792,11 +796,13 @@ bool SerieHelper::FileNameGreaterThan(File *file1, File *file2) bool SerieHelper::FileNameOrdering(FileList *fileList) { if (DirectOrder) - std::sort(fileList->begin(), fileList->end(), - SerieHelper::FileNameLessThan); + Sort(fileList,SerieHelper::FileNameLessThan); +// std::sort(fileList->begin(), fileList->end(), +// SerieHelper::FileNameLessThan); else - std::sort(fileList->begin(), fileList->end(), - SerieHelper::FileNameGreaterThan); + Sort(fileList,SerieHelper::FileNameGreaterThan); +// std::sort(fileList->begin(), fileList->end(), +// SerieHelper::FileNameGreaterThan); return true; } @@ -808,8 +814,9 @@ bool SerieHelper::FileNameOrdering(FileList *fileList) */ bool SerieHelper::UserOrdering(FileList *fileList) { - std::sort(fileList->begin(), fileList->end(), - SerieHelper::UserLessThanFunction); + Sort(fileList,SerieHelper::UserLessThanFunction); +// std::sort(fileList->begin(), fileList->end(), +// SerieHelper::UserLessThanFunction); if (!DirectOrder) { std::reverse(fileList->begin(), fileList->end()); @@ -818,10 +825,12 @@ bool SerieHelper::UserOrdering(FileList *fileList) } /** - * \brief Heuritics to *try* to build a Serie Identifier that would ensure + * \brief Heuristics to *try* to build a Serie Identifier that would ensure * all the images are coherent. * - * We allow user to add his own critierions, using AddSerieDetail + * By default, uses the SeriesUID. If UseSeriesDetails(true) has been called, + * then additional identifying information is used. + * We allow user to add his own critierions, using AddSeriesDetail * (he knows more than we do about his images!) * ex : in tagging series, the only pertnent tag is * 0018|1312 [In-plane Phase Encoding Direction] value : ROW/COLUMN @@ -857,6 +866,10 @@ std::string SerieHelper::CreateUniqueSeriesIdentifier( File *inFile ) { sName = ""; } + + // You can think on checking Image Orientation (0020,0037), as well. + + // 0018 0050 Slice Thickness // On some CT systems, scout scans and subsequence volume scans will // have the same SeriesUID and Series Number - YET the slice @@ -894,15 +907,15 @@ std::string SerieHelper::CreateUniqueSeriesIdentifier( File *inFile ) // We allow user to add his own critierions // (he knows more than we do about his images!) // ex : in tagging series, the only pertinent tag is - // 0018|1312 [In-plane Phase Encoding Direction] value : ROW/COLUMN + // 0018|1312 [In-plane Phase Encoding Direction] values : ROW/COLUMN - std::string s; + std::string s; for(SeriesExDetails::iterator it2 = ExDetails.begin(); it2 != ExDetails.end(); ++it2) { const ExDetail &r = *it2; - s = inFile->GetEntryString( r.group, r.elem ); + s = inFile->GetEntryString( r.group, r.elem ); num += s.c_str(); } @@ -911,12 +924,12 @@ std::string SerieHelper::CreateUniqueSeriesIdentifier( File *inFile ) id += num.c_str(); } - // Eliminate non-alnum characters, including whitespace... + // Eliminate non-alphanum characters, including whitespace... // that may have been introduced by concats. for(unsigned int i=0; i= 'a' && id[i] <= 'z') || (id[i] >= '0' && id[i] <= '9') || (id[i] >= 'A' && id[i] <= 'Z'))) @@ -934,7 +947,64 @@ std::string SerieHelper::CreateUniqueSeriesIdentifier( File *inFile ) } } - +/** + * \brief Allow user to build is own File Identifier (to be able to sort + * temporal series just as he wants) + * Criterions will be set with AddSeriesDetail. + * (Maybe the method should be moved elsewhere + * -File class? FileHelper class?- + * @return FileIdentifier (Tokenizable on '%%%'. Hope it's enough !) + */ +std::string SerieHelper::CreateUserDefinedFileIdentifier( File * inFile ) +{ + // Deal with all user supplied tags. + // (user knows more than we do about his images!) + + double converted; + std::string id; + std::string s; + char charConverted[17]; + + for(SeriesExDetails::iterator it2 = ExDetails.begin(); + it2 != ExDetails.end(); + ++it2) + { + const ExDetail &r = *it2; + s = inFile->GetEntryString( r.group, r.elem ); + + // User is allowed to ask 'convertion', to allow further ordering + // e.g : 100 would be *before* 20; 000020.00 vs 00100.00 : OK + if (it2->convert) + { + if ( s != GDCM_UNFOUND) // Don't convert unfound fields ! + { + converted = atof(s.c_str()); + // probabely something much more complicated is possible, + // using C++ features + /// \todo check the behaviour when there are >0 and <0 numbers + sprintf(charConverted, "%016.6f",converted); + s = charConverted; + } + } + // Eliminate non-alphanum characters, including whitespace. + for(unsigned int i=0; i= 'a' && s[i] <= 'z') + || (s[i] >= '0' && s[i] <= '9') + || (s[i] >= 'A' && s[i] <= 'Z'))) + { + s.erase(i, 1); + } + } + + id += s.c_str(); + id += "%%%"; // make the FileIdentifier Tokenizable + } + + return id; +} //----------------------------------------------------------------------------- // Print /** @@ -964,5 +1034,15 @@ void SerieHelper::Print(std::ostream &os, std::string const &indent) } } +//----------------------------------------------------------------------------- +// Sort +/** + * \brief Sort FileList. + */ +void SerieHelper::Sort(FileList *fileList, bool (*pt2Func)( File *file1, File *file2) ) +{ + std::sort(fileList->begin(), fileList->end(), pt2Func ); +} + //----------------------------------------------------------------------------- } // end namespace gdcm