diff --git a/Modules/DiffusionImaging/DiffusionCore/DicomImport/mitkDiffusionDICOMFileReader.cpp b/Modules/DiffusionImaging/DiffusionCore/DicomImport/mitkDiffusionDICOMFileReader.cpp index 7546241c44..48dd51d526 100644 --- a/Modules/DiffusionImaging/DiffusionCore/DicomImport/mitkDiffusionDICOMFileReader.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/DicomImport/mitkDiffusionDICOMFileReader.cpp @@ -1,246 +1,285 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDiffusionDICOMFileReader.h" #include "mitkDiffusionDICOMFileReaderHelper.h" #include "mitkDiffusionHeaderSiemensDICOMFileReader.h" #include "mitkDiffusionHeaderSiemensMosaicDICOMFileReader.h" #include "mitkDiffusionHeaderGEDICOMFileReader.h" #include "mitkDiffusionHeaderPhilipsDICOMFileReader.h" static void PerformHeaderAnalysis( mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType headers ) { unsigned int images = headers.size(); unsigned int unweighted_images = 0; unsigned int weighted_images = 0; mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType::const_iterator c_iter = headers.begin(); while( c_iter != headers.end() ) { const mitk::DiffusionImageDICOMHeaderInformation h = *c_iter; if( h.baseline ) unweighted_images++; if( h.b_value > 0 ) weighted_images++; ++c_iter; } MITK_INFO << " :: Analyzed volumes " << images << "\n" << " :: \t"<< unweighted_images << " b = 0" << "\n" << " :: \t"<< weighted_images << " b > 0"; } mitk::DiffusionDICOMFileReader::DiffusionDICOMFileReader() { m_IsMosaicData = false; } mitk::DiffusionDICOMFileReader::~DiffusionDICOMFileReader() { } bool mitk::DiffusionDICOMFileReader ::LoadImages() +{ + unsigned int numberOfOutputs = this->GetNumberOfOutputs(); + bool success = true; + + for(unsigned int o = 0; o < numberOfOutputs; ++o) + { + success &= this->LoadSingleOutputImage( this->m_OutputHeaderContainer.at(o), + this->InternalGetOutput(o) ); + } + + return success; +} + +bool mitk::DiffusionDICOMFileReader +::LoadSingleOutputImage( DiffusionHeaderDICOMFileReader::DICOMHeaderListType retrievedHeader, + DICOMImageBlockDescriptor& block ) { // prepare data reading DiffusionDICOMFileReaderHelper helper; DiffusionDICOMFileReaderHelper::VolumeFileNamesContainer filenames; - const size_t number_of_outputs = this->GetNumberOfOutputs(); + const DICOMImageFrameList& frames = block.GetImageFrameList(); + int numberOfDWImages = block.GetIntProperty("timesteps", 1); - for( size_t idx = 0; idx < number_of_outputs; idx++ ) - { - DICOMImageFrameList flist = this->GetOutput(idx).GetImageFrameList(); + int numberOfFramesPerDWImage = frames.size() / numberOfDWImages; + assert( int( double((double) frames.size() / (double) numberOfDWImages)) == numberOfFramesPerDWImage ); + for( int idx = 0; idx < numberOfDWImages; idx++ ) + { std::vector< std::string > FileNamesPerVolume; - DICOMImageFrameList::const_iterator cIt = flist.begin(); - while( cIt != flist.end() ) + DICOMImageFrameList::const_iterator timeStepStart = frames.begin() + idx * numberOfFramesPerDWImage; + DICOMImageFrameList::const_iterator timeStepEnd = frames.begin() + (idx+1) * numberOfFramesPerDWImage; + for (DICOMImageFrameList::const_iterator frameIter = timeStepStart; + frameIter != timeStepEnd; + ++frameIter) { - FileNamesPerVolume.push_back( (*cIt)->Filename ); - ++cIt; + FileNamesPerVolume.push_back( (*frameIter)->Filename ); } filenames.push_back( FileNamesPerVolume ); } // TODO : only prototyping to test loading of diffusion images // we need some solution for the different types typedef mitk::DiffusionImage DiffusionImageType; DiffusionImageType::Pointer output_image = DiffusionImageType::New(); DiffusionImageType::GradientDirectionContainerType::Pointer directions = DiffusionImageType::GradientDirectionContainerType::New(); double max_bvalue = 0; - for( size_t idx = 0; idx < number_of_outputs; idx++ ) + for( int idx = 0; idx < numberOfDWImages; idx++ ) { - DiffusionImageDICOMHeaderInformation header = this->m_RetrievedHeader.at(idx); + DiffusionImageDICOMHeaderInformation header = retrievedHeader.at(idx); if( max_bvalue < header.b_value ) max_bvalue = header.b_value; } // normalize the retrieved gradient directions according to the set b-value (maximal one) - for( size_t idx = 0; idx < number_of_outputs; idx++ ) + for( int idx = 0; idx < numberOfDWImages; idx++ ) { - DiffusionImageDICOMHeaderInformation header = this->m_RetrievedHeader.at(idx); + DiffusionImageDICOMHeaderInformation header = retrievedHeader.at(idx); DiffusionImageType::GradientDirectionType grad = header.g_vector; grad.normalize(); grad *= sqrt( header.b_value / max_bvalue ); directions->push_back( grad ); } // initialize the output image output_image->SetReferenceBValue( max_bvalue ); output_image->SetDirections( directions ); if( this->m_IsMosaicData ) { - mitk::DiffusionHeaderSiemensMosaicDICOMFileReader::Pointer mosaic_reader = - dynamic_cast< mitk::DiffusionHeaderSiemensMosaicDICOMFileReader* >( this->m_HeaderReader.GetPointer() ); + mitk::DiffusionHeaderSiemensMosaicDICOMFileReader::New(); // retrieve the remaining meta-information needed for mosaic reconstruction // it suffices to get it exemplatory from the first file in the file list mosaic_reader->RetrieveMosaicInformation( filenames.at(0).at(0) ); mitk::MosaicDescriptor mdesc = mosaic_reader->GetMosaicDescriptor(); output_image->SetVectorImage( helper.LoadMosaicToVector( filenames, mdesc ) ); } else { output_image->SetVectorImage( helper.LoadToVector( filenames ) ); } output_image->InitializeFromVectorImage(); //output_image->UpdateBValueMap(); // reduce the number of outputs to 1 as we will produce a single image - this->SetNumberOfOutputs(1); + //this->SetNumberOfOutputs(1); // set the image to output - DICOMImageBlockDescriptor& block = this->InternalGetOutput(0); + //DICOMImageBlockDescriptor& block = this->InternalGetOutput(0); block.SetMitkImage( (mitk::Image::Pointer) output_image ); return block.GetMitkImage().IsNotNull(); } void mitk::DiffusionDICOMFileReader ::AnalyzeInputFiles() { + this->SetGroup3DandT(true); + Superclass::AnalyzeInputFiles(); // collect output from superclass size_t number_of_outputs = this->GetNumberOfOutputs(); if(number_of_outputs == 0) { MITK_ERROR << "Failed to parse input, retrieved 0 outputs from SeriesGDCMReader "; } - DICOMImageBlockDescriptor block_0 = this->GetOutput(0); - - MITK_INFO << "Retrieved " << number_of_outputs << "outputs."; - - // collect vendor ID from the first output, first image - StringList inputFilename; - DICOMImageFrameInfo::Pointer frame_0 = block_0.GetImageFrameList().at(0); - inputFilename.push_back( frame_0->Filename ); - - gdcm::Scanner gdcmScanner; - - gdcm::Tag t_vendor(0x008, 0x0070); - gdcm::Tag t_imagetype(0x008, 0x008); - - // add DICOM Tag for vendor - gdcmScanner.AddTag( t_vendor ); - // add DICOM Tag for image type - gdcmScanner.AddTag( t_imagetype ); - gdcmScanner.Scan( inputFilename ); + MITK_INFO("diffusion.dicomreader") << "Retrieved " << number_of_outputs << "outputs."; - // retrieve both vendor and image type - std::string vendor = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_vendor ); - std::string image_type = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_imagetype ); - MITK_INFO << "Got vendor: " << vendor << " image type " << image_type; - - - // parse vendor tag - if( vendor.find("SIEMENS") != std::string::npos ) + for( unsigned int outputidx = 0; outputidx < this->GetNumberOfOutputs(); outputidx++ ) { - if( image_type.find("MOSAIC") != std::string::npos ) - { - m_HeaderReader = mitk::DiffusionHeaderSiemensMosaicDICOMFileReader::New(); - this->m_IsMosaicData = true; - } - else - { - m_HeaderReader = mitk::DiffusionHeaderSiemensDICOMFileReader::New(); - } + DICOMImageBlockDescriptor block_0 = this->GetOutput(outputidx); + + // collect vendor ID from the first output, first image + StringList inputFilename; + DICOMImageFrameInfo::Pointer frame_0 = block_0.GetImageFrameList().at(0); + inputFilename.push_back( frame_0->Filename ); + + gdcm::Scanner gdcmScanner; + + gdcm::Tag t_vendor(0x008, 0x0070); + gdcm::Tag t_imagetype(0x008, 0x008); + + // add DICOM Tag for vendor + gdcmScanner.AddTag( t_vendor ); + // add DICOM Tag for image type + gdcmScanner.AddTag( t_imagetype ); + gdcmScanner.Scan( inputFilename ); + + // retrieve both vendor and image type + std::string vendor = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_vendor ); + std::string image_type = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_imagetype ); + MITK_INFO("diffusion.dicomreader") << "Output " << outputidx+1 << "Got vendor: " << vendor << " image type " << image_type; + + mitk::DiffusionHeaderDICOMFileReader::Pointer headerReader; + + // parse vendor tag + if( vendor.find("SIEMENS") != std::string::npos ) + { + if( image_type.find("MOSAIC") != std::string::npos ) + { + headerReader = mitk::DiffusionHeaderSiemensMosaicDICOMFileReader::New(); + this->m_IsMosaicData = true; + } + else + { + headerReader = mitk::DiffusionHeaderSiemensDICOMFileReader::New(); + } + + } + else if( vendor.find("GE") != std::string::npos ) + { + headerReader = mitk::DiffusionHeaderGEDICOMFileReader::New(); + } + else if( vendor.find("Philips") != std::string::npos ) + { + headerReader = mitk::DiffusionHeaderPhilipsDICOMFileReader::New(); + } + else + { + // unknown vendor + } + + if( headerReader.IsNull() ) + { + MITK_ERROR << "No header reader for given vendor. "; + return; + } + + bool canread = false; + // iterate over the threeD+t block + + int numberOfTimesteps = block_0.GetIntProperty("timesteps", 1); + int framesPerTimestep = block_0.GetImageFrameList().size() / numberOfTimesteps; + + for( int idx = 0; idx < numberOfTimesteps; idx++ ) + { + int access_idx = idx * framesPerTimestep; + DICOMImageFrameInfo::Pointer frame = this->GetOutput( outputidx ).GetImageFrameList().at( access_idx ); + canread = headerReader->ReadDiffusionHeader( frame->Filename ); + } + + // collect the information + mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType retrievedHeader = headerReader->GetHeaderInformation(); + m_OutputHeaderContainer.push_back( retrievedHeader ); } - else if( vendor.find("GE") != std::string::npos ) - { - m_HeaderReader = mitk::DiffusionHeaderGEDICOMFileReader::New(); - } - else if( vendor.find("Philips") != std::string::npos ) - { - m_HeaderReader = mitk::DiffusionHeaderPhilipsDICOMFileReader::New(); - } - else - { - // unknown vendor - } - if( m_HeaderReader.IsNull() ) + for( unsigned int outputidx = 0; outputidx < this->GetNumberOfOutputs(); outputidx++ ) { - MITK_ERROR << "No header reader for given vendor. "; - return; - } + // TODO : Analyze outputs + header information, i.e. for the loading confidence + MITK_INFO << "----- Diffusion DICOM Analysis Report ---- "; - bool canread = false; - for( size_t idx = 0; idx < number_of_outputs; idx++ ) - { - DICOMImageFrameInfo::Pointer frame = this->GetOutput( idx ).GetImageFrameList().at(0); - canread = m_HeaderReader->ReadDiffusionHeader(frame->Filename); - } + PerformHeaderAnalysis( this->m_OutputHeaderContainer.at( outputidx) ); - // collect the information - m_RetrievedHeader = m_HeaderReader->GetHeaderInformation(); + MITK_INFO << "==========================================="; - // TODO : Analyze outputs + header information, i.e. for the loading confidence - MITK_INFO << "----- Diffusion DICOM Analysis Report ---- "; + } - PerformHeaderAnalysis( m_RetrievedHeader ); - MITK_INFO << "==========================================="; } bool mitk::DiffusionDICOMFileReader ::CanHandleFile(const std::string &filename) { //FIXME : return true; } diff --git a/Modules/DiffusionImaging/DiffusionCore/DicomImport/mitkDiffusionDICOMFileReader.h b/Modules/DiffusionImaging/DiffusionCore/DicomImport/mitkDiffusionDICOMFileReader.h index b1ab0e1018..e69f57f664 100644 --- a/Modules/DiffusionImaging/DiffusionCore/DicomImport/mitkDiffusionDICOMFileReader.h +++ b/Modules/DiffusionImaging/DiffusionCore/DicomImport/mitkDiffusionDICOMFileReader.h @@ -1,57 +1,62 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKDIFFUSIONDICOMFILEREADER_H #define MITKDIFFUSIONDICOMFILEREADER_H #include "MitkDiffusionCoreExports.h" #include "mitkDICOMITKSeriesGDCMReader.h" #include "mitkDiffusionHeaderDICOMFileReader.h" +#include "mitkThreeDnTDICOMSeriesReader.h" namespace mitk { class MitkDiffusionCore_EXPORT DiffusionDICOMFileReader - : public DICOMITKSeriesGDCMReader + : public ThreeDnTDICOMSeriesReader { public: mitkClassMacro( DiffusionDICOMFileReader, DICOMITKSeriesGDCMReader ) mitkCloneMacro( DiffusionDICOMFileReader ) itkNewMacro( DiffusionDICOMFileReader ) virtual void AnalyzeInputFiles(); virtual bool LoadImages(); virtual bool CanHandleFile(const std::string &filename); protected: DiffusionDICOMFileReader(); virtual ~DiffusionDICOMFileReader(); - mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType m_RetrievedHeader; + bool LoadSingleOutputImage( DiffusionHeaderDICOMFileReader::DICOMHeaderListType, DICOMImageBlockDescriptor&); - mitk::DiffusionHeaderDICOMFileReader::Pointer m_HeaderReader; + //mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType m_RetrievedHeader; + + std::vector< mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType > m_OutputHeaderContainer; + + //mitk::DiffusionHeaderDICOMFileReader::Pointer headerReader; bool m_IsMosaicData; }; } #endif // MITKDIFFUSIONDICOMFILEREADER_H diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp index d40a18d044..53537d08a2 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp @@ -1,529 +1,538 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDiffusionDicomImportView.h" // qt includes #include // itk includes #include "itkTimeProbesCollectorBase.h" #include "itkGDCMSeriesFileNames.h" #include "itksys/SystemTools.hxx" // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" #include "mitkMemoryUtilities.h" #include "mitkIOUtil.h" // diffusion module includes #include "mitkDicomDiffusionImageHeaderReader.h" #include "mitkDicomDiffusionImageReader.h" #include "mitkDiffusionImage.h" #include "mitkDiffusionDICOMFileReader.h" #include "mitkDICOMTagBasedSorter.h" #include "mitkDICOMSortByTag.h" #include "gdcmDirectory.h" #include "gdcmScanner.h" #include "gdcmSorter.h" #include "gdcmIPPSorter.h" #include "gdcmAttribute.h" #include "gdcmVersion.h" #include #include #include const std::string QmitkDiffusionDicomImport::VIEW_ID = "org.mitk.views.diffusiondicomimport"; QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(QObject* /*parent*/, const char* /*name*/) : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL), m_OutputFolderName(""), m_OutputFolderNameSet(false) { } QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(const QmitkDiffusionDicomImport& other) { Q_UNUSED(other) throw std::runtime_error("Copy constructor not implemented"); } QmitkDiffusionDicomImport::~QmitkDiffusionDicomImport() {} void QmitkDiffusionDicomImport::CreateQtPartControl(QWidget *parent) { m_Parent = parent; if (m_Controls == NULL) { m_Controls = new Ui::QmitkDiffusionDicomImportControls; m_Controls->setupUi(parent); this->CreateConnections(); m_Controls->m_DicomLoadRecursiveCheckbox->setChecked(false); m_Controls->m_DicomLoadAverageDuplicatesCheckbox->setChecked(false); m_Controls->m_DicomLoadRecursiveCheckbox->setVisible(true); m_Controls->m_OverrideOptionCheckbox->setVisible(false); m_Controls->m_SubdirPrefixLineEdit->setVisible(false); m_Controls->m_SetPrefixButton->setVisible(false); m_Controls->m_ResetPrefixButton->setVisible(false); AverageClicked(); } } void QmitkDiffusionDicomImport::CreateConnections() { if ( m_Controls ) { connect( m_Controls->m_AddFoldersButton, SIGNAL(clicked()), this, SLOT(DicomLoadAddFolderNames()) ); connect( m_Controls->m_DeleteFoldersButton, SIGNAL(clicked()), this, SLOT(DicomLoadDeleteFolderNames()) ); //connect( m_Controls->m_DicomLoadStartLoadButton, SIGNAL(clicked()), this, SLOT(DicomLoadStartLoad()) ); connect( m_Controls->m_DicomLoadStartLoadButton, SIGNAL(clicked()), this, SLOT(NewDicomLoadStartLoad()) ); connect( m_Controls->m_DicomLoadAverageDuplicatesCheckbox, SIGNAL(clicked()), this, SLOT(AverageClicked()) ); connect( m_Controls->m_OutputSetButton, SIGNAL(clicked()), this, SLOT(OutputSet()) ); connect( m_Controls->m_OutputClearButton, SIGNAL(clicked()), this, SLOT(OutputClear()) ); connect( m_Controls->m_Remove, SIGNAL(clicked()), this, SLOT(Remove()) ); connect( m_Controls->m_SetPrefixButton, SIGNAL(clicked()), this, SLOT(SetPrefixButtonPushed())); connect( m_Controls->m_ResetPrefixButton, SIGNAL(clicked()), this, SLOT(ResetPrefixButtonPushed())); connect( m_Controls->m_DicomLoadRecursiveCheckbox, SIGNAL(clicked()), this, SLOT(RecursiveSettingsChanged()) ); } } void QmitkDiffusionDicomImport::RecursiveSettingsChanged() { m_Controls->m_SubdirPrefixLineEdit->setVisible( m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ); m_Controls->m_SetPrefixButton->setVisible( m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ); m_Controls->m_SubdirPrefixLineEdit->clear(); this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(true); } void QmitkDiffusionDicomImport::SetPrefixButtonPushed() { m_Prefix = this->m_Controls->m_SubdirPrefixLineEdit->text().toStdString(); if( !this->m_Controls->m_ResetPrefixButton->isVisible() ) this->m_Controls->m_ResetPrefixButton->setVisible(true); this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(false); this->m_Controls->m_ResetPrefixButton->setEnabled(true); this->m_Controls->m_SetPrefixButton->setEnabled(false); } void QmitkDiffusionDicomImport::ResetPrefixButtonPushed() { m_Controls->m_SubdirPrefixLineEdit->clear(); this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(true); this->m_Controls->m_ResetPrefixButton->setEnabled(false); this->m_Controls->m_SetPrefixButton->setEnabled(true); } void QmitkDiffusionDicomImport::Remove() { int i = m_Controls->listWidget->currentRow(); m_Controls->listWidget->takeItem(i); } void QmitkDiffusionDicomImport::OutputSet() { // SELECT FOLDER DIALOG QFileDialog* w = new QFileDialog( m_Parent, QString("Select folders containing DWI data") ); w->setFileMode( QFileDialog::Directory ); // RETRIEVE SELECTION if ( w->exec() != QDialog::Accepted ) return; m_OutputFolderName = w->selectedFiles()[0]; m_OutputFolderNameSet = true; m_Controls->m_OutputLabel->setText(m_OutputFolderName); // show file override option checkbox m_Controls->m_OverrideOptionCheckbox->setVisible(true); } void QmitkDiffusionDicomImport::OutputClear() { m_OutputFolderName = ""; m_OutputFolderNameSet = false; m_Controls->m_OutputLabel->setText("... optional out-folder ..."); // hide file override option checkbox - no output specified m_Controls->m_OverrideOptionCheckbox->setVisible(false); } void QmitkDiffusionDicomImport::AverageClicked() { m_Controls->m_Blur->setEnabled(m_Controls->m_DicomLoadAverageDuplicatesCheckbox->isChecked()); } void QmitkDiffusionDicomImport::Activated() { QmitkFunctionality::Activated(); } void QmitkDiffusionDicomImport::DicomLoadDeleteFolderNames() { m_Controls->listWidget->clear(); } void QmitkDiffusionDicomImport::DicomLoadAddFolderNames() { // SELECT FOLDER DIALOG QFileDialog* w = new QFileDialog( m_Parent, QString("Select folders containing DWI data") ); w->setFileMode( QFileDialog::Directory ); // RETRIEVE SELECTION if ( w->exec() != QDialog::Accepted ) return; m_Controls->listWidget->addItems(w->selectedFiles()); } bool SortBySeriesUID(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0020,0x000e> at1; at1.Set( ds1 ); gdcm::Attribute<0x0020,0x000e> at2; at2.Set( ds2 ); return at1 < at2; } bool SortByAcquisitionNumber(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0020,0x0012> at1; at1.Set( ds1 ); gdcm::Attribute<0x0020,0x0012> at2; at2.Set( ds2 ); return at1 < at2; } bool SortBySeqName(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0018, 0x0024> at1; at1.Set( ds1 ); gdcm::Attribute<0x0018, 0x0024> at2; at2.Set( ds2 ); std::string str1 = at1.GetValue().Trim(); std::string str2 = at2.GetValue().Trim(); return std::lexicographical_compare(str1.begin(), str1.end(), str2.begin(), str2.end() ); } void QmitkDiffusionDicomImport::Status(QString status) { mitk::StatusBar::GetInstance()->DisplayText(status.toAscii()); MITK_INFO << status.toStdString().c_str(); } void QmitkDiffusionDicomImport::Status(std::string status) { mitk::StatusBar::GetInstance()->DisplayText(status.c_str()); MITK_INFO << status.c_str(); } void QmitkDiffusionDicomImport::Status(const char* status) { mitk::StatusBar::GetInstance()->DisplayText(status); MITK_INFO << status; } void QmitkDiffusionDicomImport::Error(QString status) { mitk::StatusBar::GetInstance()->DisplayErrorText(status.toAscii()); MITK_ERROR << status.toStdString().c_str(); } void QmitkDiffusionDicomImport::Error(std::string status) { mitk::StatusBar::GetInstance()->DisplayErrorText(status.c_str()); MITK_ERROR << status.c_str(); } void QmitkDiffusionDicomImport::Error(const char* status) { mitk::StatusBar::GetInstance()->DisplayErrorText(status); MITK_ERROR << status; } void QmitkDiffusionDicomImport::PrintMemoryUsage() { size_t processSize = mitk::MemoryUtilities::GetProcessMemoryUsage(); size_t totalSize = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam(); float percentage = ( (float) processSize / (float) totalSize ) * 100.0; MITK_INFO << "Current memory usage: " << GetMemoryDescription( processSize, percentage ); } std::string QmitkDiffusionDicomImport::FormatMemorySize( size_t size ) { double val = size; std::string descriptor("B"); if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "KB"; } if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "MB"; } if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "GB"; } std::ostringstream str; str << std::fixed << std::setprecision(2) << val << " " << descriptor; return str.str(); } std::string QmitkDiffusionDicomImport::FormatPercentage( double val ) { std::ostringstream str; str << std::fixed << std::setprecision(2) << val << " " << "%"; return str.str(); } std::string QmitkDiffusionDicomImport::GetMemoryDescription( size_t processSize, float percentage ) { std::ostringstream str; str << FormatMemorySize(processSize) << " (" << FormatPercentage( percentage ) <<")" ; return str.str(); } void QmitkDiffusionDicomImport::NewDicomLoadStartLoad() { itk::TimeProbesCollectorBase clock; bool imageSuccessfullySaved = true; bool has_prefix = true; try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { MITK_INFO << " ** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'"; setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } int nrFolders = m_Controls->listWidget->count(); if(!nrFolders) { Error(QString("No input folders were selected. ABORTING.")); return; } Status(QString("GDCM %1 used for DICOM parsing and sorting!").arg(gdcm::Version::GetVersion())); PrintMemoryUsage(); QString status; mitk::DataNode::Pointer node; mitk::ProgressBar::GetInstance()->AddStepsToDo(2*nrFolders); gdcm::Directory::FilenamesType complete_list; while(m_Controls->listWidget->count()) { // RETREIVE FOLDERNAME QListWidgetItem * item = m_Controls->listWidget->takeItem(0); QString folderName = item->text(); if( this->m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ) { std::string subdir_prefix = ""; if( has_prefix ) { subdir_prefix = this->m_Prefix; } itksys::Directory rootdir; rootdir.Load( folderName.toStdString().c_str() ); for( unsigned int idx=0; idxm_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ); // recursive ! const gdcm::Directory::FilenamesType &l1 = d.GetFilenames(); const unsigned int ntotalfiles = l1.size(); Status(QString(" ... found %1 different files").arg(ntotalfiles)); for( unsigned int i=0; i< ntotalfiles; i++) { complete_list.push_back( l1.at(i) ); } } } { mitk::DiffusionDICOMFileReader::Pointer gdcmReader = mitk::DiffusionDICOMFileReader::New(); mitk::DICOMTagBasedSorter::Pointer tagSorter = mitk::DICOMTagBasedSorter::New(); // Use tags as in Qmitk // all the things that split by tag in DicomSeriesReader tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0010) ); // Number of Rows tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0011) ); // Number of Columns tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0030) ); // Pixel Spacing tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x1164) ); // Imager Pixel Spacing tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0037) ); // Image Orientation (Patient) // TODO add tolerance parameter (l. 1572 of original code) // TODO handle as real vectors! cluster with configurable errors! //tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x000e) ); // Series Instance UID tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x0050) ); // Slice Thickness tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0008) ); // Number of Frames tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0052) ); // Frame of Reference UID // gdcmReader->AddSortingElement( tagSorter ); //mitk::DICOMFileReaderTestHelper::TestOutputsContainInputs( gdcmReader ); mitk::DICOMSortCriterion::ConstPointer sorting = mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0013), // instance number mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0012), // aqcuisition number mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0032), // aqcuisition time mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0018, 0x1060), // trigger time mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0018) // SOP instance UID (last resort, not really meaningful but decides clearly) ).GetPointer() ).GetPointer() ).GetPointer() ).GetPointer() ).GetPointer(); tagSorter->SetSortCriterion( sorting ); gdcmReader->AddSortingElement( tagSorter ); gdcmReader->SetInputFiles( complete_list ); gdcmReader->AnalyzeInputFiles(); gdcmReader->LoadImages(); - mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(0).GetMitkImage(); - mitk::DiffusionImage::Pointer d_img = static_cast*>( loaded_image.GetPointer() ); - - node=mitk::DataNode::New(); - node->SetData( d_img ); - GetDefaultDataStorage()->Add(node); - SetDwiNodeProperties(node, "ImportedData"); - //Status(QString("Image %1 added to datastorage").arg(descr)); + for( int o = 0; o < gdcmReader->GetNumberOfOutputs(); o++ ) + { + mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(o).GetMitkImage(); + mitk::DiffusionImage::Pointer d_img = static_cast*>( loaded_image.GetPointer() ); + + std::stringstream ss; + ss << "ImportedData_" << o; + + node = mitk::DataNode::New(); + node->SetData( d_img ); + + GetDefaultDataStorage()->Add(node); + SetDwiNodeProperties(node, ss.str() ); + //Status(QString("Image %1 added to datastorage").arg(descr)); + } + + } Status("Timing information"); clock.Report(); if(!m_OutputFolderNameSet && node.IsNotNull()) { mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); try { MITK_INFO << " ** Changing locale back from " << setlocale(LC_ALL, NULL) << " to '" << currLocale << "'"; setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } catch (itk::ExceptionObject &ex) { Error(QString("%1\n%2\n%3\n%4\n%5\n%6").arg(ex.GetNameOfClass()).arg(ex.GetFile()).arg(ex.GetLine()).arg(ex.GetLocation()).arg(ex.what()).arg(ex.GetDescription())); return ; } if (!imageSuccessfullySaved) QMessageBox::warning(NULL,"WARNING","One or more files could not be saved! The according files where moved to the datastorage."); Status(QString("Finished import with memory:")); PrintMemoryUsage(); } void QmitkDiffusionDicomImport::SetDwiNodeProperties(mitk::DataNode::Pointer node, std::string name) { node->SetProperty( "IsDWIRawVolume", mitk::BoolProperty::New( true ) ); // set foldername as string property mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New( name ); node->SetProperty( "name", nameProp ); }