// // itkReadFileListFilter.h // TomatoLib // // Created by Konrad Werys on 07/11/19. // Copyright © 2017 Konrad Werys. All rights reserved. // #ifndef TomatoLIB_ITKREADFILELISTFILTER_HXX #define TomatoLIB_ITKREADFILELISTFILTER_HXX #include "CmakeConfigForTomato.h" #include "gdcmTomatoReadTags.h" #ifdef USE_ITK #include #include #include "itkGDCMImageIO.h" #include "itkStatisticsImageFilter.h" #include "KWUtil.h" #include "itkReadFileListFilter.h" #include "itkDirectory.h" #include "gdcmBase64.h" #include "gdcmTomatoReadTags.h" namespace itk { template< typename TImage > ReadFileListFilter:: ReadFileListFilter(){ m_Verbose = false; } template< typename TImage > void ReadFileListFilter ::SetFileList(const std::vector fileList){ m_FileList = fileList; } template void ReadFileListFilter::SetDirName(const std::string dirName) { m_DirName = dirName; if (m_DirName.empty()) { return; } typename itk::Directory::Pointer directory = itk::Directory::New(); directory->Load(m_DirName.c_str()); for (size_t i = 0; i < directory->GetNumberOfFiles(); i++){ std::string fileName = directory->GetFile(i); if (fileName == "." || fileName == ".." || fileName == ".DS_Store"){ continue; } m_FileList.push_back(m_DirName + KWUtil::PathSeparator() + fileName); } } template< typename TImage > template< typename TYPE > vnl_vector ReadFileListFilter ::GetVnlVectorFromStdVector(std::vector stdVector){ if (stdVector.size() == 0){ return vnl_vector(); } else { return vnl_vector(&stdVector.front(), stdVector.size()); } } template< typename TImage > vnl_vector ReadFileListFilter ::GetInvTimes(){ vnl_vector invTimesVnl = GetVnlVectorFromStdVector(m_InvTimes); vnl_vector invTimesVnl20051572 = GetVnlVectorFromStdVector(m_InvTimes20051572); vnl_vector invTimesVnl00211189 = GetVnlVectorFromStdVector(m_InvTimes00211189); vnl_vector invTimesVnlFromImageCommentsVnl = GetVnlVectorFromStdVector(m_InvTimesFromImageComments); vnl_vector triggerTimesVnl = GetVnlVectorFromStdVector(m_TriggerTimes); if (invTimesVnl.min_value() != invTimesVnl.max_value()) { return invTimesVnl; } else if (invTimesVnl20051572.min_value() != invTimesVnl20051572.max_value()) { return invTimesVnl20051572; } else if (invTimesVnl00211189.min_value() != invTimesVnl00211189.max_value()) { return invTimesVnl00211189; } else if (invTimesVnlFromImageCommentsVnl.min_value() != invTimesVnlFromImageCommentsVnl.max_value()) { return invTimesVnlFromImageCommentsVnl; } else if (triggerTimesVnl.min_value() != triggerTimesVnl.max_value()) { return triggerTimesVnl; } else { return invTimesVnl; } } template< typename TImage > vnl_vector ReadFileListFilter ::GetRepTimes(){ return GetVnlVectorFromStdVector(m_RepTimes); } template< typename TImage > vnl_vector ReadFileListFilter ::GetEchoTimes(){ vnl_vector echoTimesVnl = GetVnlVectorFromStdVector(m_EchoTimes); vnl_vector echoTimes00191016Vnl = GetVnlVectorFromStdVector(m_EchoTimes00191016); vnl_vector echoTimes00209158Vnl = GetVnlVectorFromStdVector(m_EchoTimes00209158); vnl_vector echoTimesFromImageCommentsVnl = GetVnlVectorFromStdVector(m_EchoTimesFromImageComments); if (echoTimesVnl.min_value() != echoTimesVnl.max_value()) { return echoTimesVnl; } else if (echoTimesFromImageCommentsVnl.min_value() != echoTimesFromImageCommentsVnl.max_value()) { return echoTimesFromImageCommentsVnl; } else if (echoTimes00191016Vnl.min_value() != echoTimes00191016Vnl.max_value()) { return echoTimes00191016Vnl; } else if (echoTimes00209158Vnl.min_value() != echoTimes00209158Vnl.max_value()) { return echoTimes00209158Vnl; } else { return echoTimesVnl; } } template< typename TImage > vnl_vector ReadFileListFilter ::GetTriggerTimes(){ return GetVnlVectorFromStdVector(m_TriggerTimes); } template< typename TImage > vnl_vector ReadFileListFilter ::GetAcqTimes(){ return GetVnlVectorFromStdVector(m_AcqTimes); } template< typename TImage > vnl_vector ReadFileListFilter ::GetRelAcqTimes(){ vnl_vector temp = GetAcqTimes(); double mymin = temp.min_value(); for (unsigned int i = 0; i < temp.size(); ++i){ temp[i] = temp[i] - mymin; } return temp; } template< class TImage > void ReadFileListFilter< TImage > ::GenerateData() { // see https://itk.org/Wiki/ITK/Examples/ImageProcessing/TileImageFilter_CreateVolume typename ImageType3D::Pointer outputImage; m_DicomIO = GDCMImageIO::New(); m_DicomIO->LoadPrivateTagsOn(); itk::FixedArray< PixelType, 3 > layout; layout[0] = 1; layout[1] = 1; layout[2] = m_FileList.size(); // tiler typename TileImageType::Pointer tiler = TileImageType::New(); tiler->SetLayout( layout ); typename ReaderType::Pointer reader; // the main loop unsigned int inputImageNumber = 0; for ( unsigned int i = 0; i < m_FileList.size(); ++i ){ //reader reader = ReaderType::New(); reader->SetImageIO(m_DicomIO); reader->SetFileName( m_FileList[i] ); m_DicomIO->SetFileName(m_FileList[i]); m_DicomIO->ReadImageInformation(); reader->Update(); tiler->SetInput(i, reader->GetOutput()); try { tiler->Update(); //std::cout << std::setprecision(9) << reader->GetOutput()->GetOrigin() << std::endl; m_MetaDataDictionaryArray.push_back(reader->GetMetaDataDictionary()); m_InvTimes.push_back(FindInversionTime(reader)); m_InvTimes20051572.push_back(FindInversionTime20051572(reader)); m_InvTimes00211189.push_back(FindInversionTime00211189(reader)); m_InvTimesFromImageComments.push_back(FindInversionTimeFromImageComments(reader)); m_RepTimes.push_back(FindRepetitionTime(reader)); m_EchoTimes.push_back(FindEchoTime(reader)); m_EchoTimes00191016.push_back(FindEchoTime00191016(reader)); m_EchoTimes00209158.push_back(FindEchoTime00209158(reader)); m_EchoTimesFromImageComments.push_back(FindEchoTimeFromImageComments(reader)); m_TriggerTimes.push_back(FindTriggerTime(reader)); m_AcqTimes.push_back(FindAcqTime(reader)); inputImageNumber++; } catch( itk::ExceptionObject & err ) { std::cerr << "Unable to read file: " << m_FileList[i] << std::endl; std::cerr << "ExceptionObject caught!" << std::endl << err << std::endl; } } if (inputImageNumber == 0) return; tiler->UpdateLargestPossibleRegion(); // the final update outputImage = tiler->GetOutput(); //outputImage->SetOrigin(reader->GetOutput()->GetOrigin()); //outputImage->SetDirection(reader->GetOutput()->GetDirection()); try { outputImage->Update(); } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught!" << std::endl; std::cerr << err << std::endl; } if (GetVerbose()) { // typename ImageType3D::PixelType rescaleIntercept = m_DicomIO->GetRescaleIntercept(); typename ImageType3D::PixelType rescaleSlope = m_DicomIO->GetRescaleSlope(); typedef itk::StatisticsImageFilter StatisticsImageFilterType; typename StatisticsImageFilterType::Pointer statisticsImageFilter = StatisticsImageFilterType::New(); statisticsImageFilter->SetInput(outputImage); statisticsImageFilter->Update(); std::cout << "Mean: " << statisticsImageFilter->GetMean(); std::cout << ", Std.: " << statisticsImageFilter->GetSigma(); std::cout << ", Min: " << statisticsImageFilter->GetMinimum(); std::cout << ", Max: " << statisticsImageFilter->GetMaximum(); std::cout << ", RescaleIntercept: " << rescaleIntercept << ", RescaleSlope: " << rescaleSlope << std::endl; //std::cout << outputImage << std::endl; vcl_cout << "Inversion Times: " << GetInvTimes() << vcl_endl; vcl_cout << "Repetition Times: " << GetRepTimes() << vcl_endl; vcl_cout << "Echo Times: " << GetEchoTimes() << vcl_endl; vcl_cout << "Trigger Times: " << GetTriggerTimes() << vcl_endl; vcl_cout << "Rel Acq Times: " << GetRelAcqTimes() << vcl_endl; } this->GraftOutput(outputImage); } template< class TImage> double ReadFileListFilter< TImage> ::FindInversionTime(ReaderType* reader) { double invTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "0018|0082"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); invTime = KWUtil::StringToNumber(tagvalue); } } return invTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindInversionTime20051572(ReaderType* reader) { double invTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "2005|1572"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string decoded; std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); int dlen = gdcm::Base64::GetDecodeLength(tagvalue.c_str(), tagvalue.size() ); decoded.resize(dlen); gdcm::Base64::Decode(&decoded[0], decoded.size(), tagvalue.c_str(), tagvalue.size()); float * fDecoded = (float *)&decoded[0]; invTime = (double)(*fDecoded); } } return invTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindInversionTime00211189(ReaderType *reader) { double invTime = 0; std::vector > tags; tags.push_back(std::pair(0x5200, 0x9230)); tags.push_back(std::pair(0x0021, 0x11fe)); tags.push_back(std::pair(0x0021, 0x1189)); std::string tagvalue; if (gdcmTomatoReadTags(tags, reader->GetFileName(), tagvalue) == 0) { // EXIT_SUCCESS invTime = *(double*)&tagvalue[0]; } return invTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindInversionTimeFromImageComments(ReaderType* reader) { int invTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "0020|4000"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); std::sscanf(tagvalue.c_str(), "TIeff %i ms ", &invTime); } } return (double)invTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindRepetitionTime(ReaderType* reader) { double repTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "0018|0080"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); repTime = KWUtil::StringToNumber(tagvalue); } } return repTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindEchoTime(ReaderType* reader) { double echoTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "0018|0081"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); echoTime = KWUtil::StringToNumber(tagvalue); } } return echoTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindEchoTime00191016(ReaderType* reader) { double echoTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "0019|1016"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); echoTime = KWUtil::StringToNumber(tagvalue); } } return echoTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindEchoTime00209158(ReaderType* reader) { int echoTime = 0; std::vector > tags; tags.push_back(std::pair(0x5200, 0x9230)); tags.push_back(std::pair(0x0020, 0x9111)); tags.push_back(std::pair(0x0020, 0x9158)); std::string tagvalue; if ( gdcmTomatoReadTags(tags, reader->GetFileName(), tagvalue) == 0) { // EXIT_SUCCESS std::sscanf(tagvalue.c_str(), "T2 prep. duration = %i ms", &echoTime); } return (double)echoTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindEchoTimeFromImageComments(ReaderType* reader) { int echoTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "0020|4000"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); std::sscanf(tagvalue.c_str(), "T2 prep. duration = %i ms ", &echoTime); } } return (double)echoTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindTriggerTime(ReaderType* reader) { double triggerTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "0018|1060"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); triggerTime = KWUtil::StringToNumber(tagvalue); } } return triggerTime; }; template< class TImage> double ReadFileListFilter< TImage> ::FindAcqTime(ReaderType* reader) { double acqTime = 0; const DictionaryType & dictionary = reader->GetMetaDataDictionary(); DictionaryType::ConstIterator end = dictionary.End(); std::string entryId = "0008|0032"; DictionaryType::ConstIterator tagItr = dictionary.Find(entryId); if ( tagItr != end ) { MetaDataStringType::ConstPointer entryvalueStr = dynamic_cast(tagItr->second.GetPointer()); if (entryvalueStr) { std::string tagvalue = entryvalueStr->GetMetaDataObjectValue(); acqTime = KWUtil::dicomTime2Seconds(tagvalue); } } return acqTime; } template const std::vector &ReadFileListFilter::GetFileList() const { return m_FileList; } template const std::string &ReadFileListFilter::GetDirName() const { return m_DirName; } } #endif // USE_ITK #endif //TomatoLIB_ITKREADFILELISTFILTER_HXX