diff --git a/Modules/DiffusionImaging/DiffusionCore/autoload/IO/mitkDiffusionImageDicomReaderService.cpp b/Modules/DiffusionImaging/DiffusionCore/autoload/IO/mitkDiffusionImageDicomReaderService.cpp index 49635e0ee6..a57dabb4f4 100644 --- a/Modules/DiffusionImaging/DiffusionCore/autoload/IO/mitkDiffusionImageDicomReaderService.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/autoload/IO/mitkDiffusionImageDicomReaderService.cpp @@ -1,303 +1,337 @@ /*=================================================================== 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 __mitkDiffusionImageDicomReaderService_cpp #define __mitkDiffusionImageDicomReaderService_cpp #include "mitkDiffusionImageDicomReaderService.h" #include #include // Diffusion properties #include #include #include #include #include #include #include "itksys/SystemTools.hxx" #include "itkImageFileReader.h" #include "itkMetaDataObject.h" #include "itkNrrdImageIO.h" #include "mitkCustomMimeType.h" #include "mitkDiffusionCoreIOMimeTypes.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace mitk { DiffusionImageDicomReaderService:: DiffusionImageDicomReaderService(const DiffusionImageDicomReaderService & other) : AbstractFileReader(other) { } DiffusionImageDicomReaderService* DiffusionImageDicomReaderService::Clone() const { return new DiffusionImageDicomReaderService(*this); } DiffusionImageDicomReaderService:: ~DiffusionImageDicomReaderService() {} DiffusionImageDicomReaderService:: DiffusionImageDicomReaderService() : mitk::AbstractFileReader( CustomMimeType( mitk::DiffusionCoreIOMimeTypes::DWI_DICOM_MIMETYPE() ), mitk::DiffusionCoreIOMimeTypes::DWI_DICOM_MIMETYPE_DESCRIPTION() ) { Options defaultOptions; defaultOptions["Load recursive"] = false; defaultOptions["Split mosaic"] = true; this->SetDefaultOptions(defaultOptions); m_ServiceReg = this->RegisterService(); } std::vector > DiffusionImageDicomReaderService::Read() { return InternalRead(); } std::vector > DiffusionImageDicomReaderService::InternalRead() { std::vector > result_images; OutputType::Pointer outputForCache = OutputType::New(); if ( this->GetInputLocation() == "") { throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename to be read is empty!"); } else { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, nullptr ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } try { Options options = this->GetOptions(); bool load_recursive = us::any_cast(options["Load recursive"]); bool split_mosaic = us::any_cast(options["Split mosaic"]); gdcm::Directory::FilenamesType complete_list; std::string folderName = itksys::SystemTools::GetFilenamePath( this->GetInputLocation() ); if( load_recursive ) { std::string subdir_prefix = ""; itksys::Directory rootdir; rootdir.Load( folderName.c_str() ); for( unsigned int idx=0; idxAddDistinguishingTag( 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::SortByImagePositionPatient::New( // Image Position (Patient) //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() ).GetPointer(); tagSorter->SetSortCriterion( sorting ); // mosaic gdcmReader->SetResolveMosaic( split_mosaic ); gdcmReader->AddSortingElement( tagSorter ); gdcmReader->SetInputFiles( complete_list ); try { gdcmReader->AnalyzeInputFiles(); } catch( const itk::ExceptionObject &e) { MITK_ERROR << "Failed to analyze data. " << e.what(); } catch( const std::exception &se) { MITK_ERROR << "Std Exception " << se.what(); } gdcmReader->LoadImages(); for( unsigned int o = 0; o < gdcmReader->GetNumberOfOutputs(); o++ ) { mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(o).GetMitkImage(); - std::stringstream ss; - ss << "ImportedData_" << o; - StringProperty::Pointer nameProp; if (gdcmReader->GetSeriesName(o)!="-") nameProp = StringProperty::New(gdcmReader->GetSeriesName(o)); else if (gdcmReader->GetStudyName(o)!="-") nameProp = StringProperty::New(gdcmReader->GetStudyName(o)); else nameProp = StringProperty::New(folderName); loaded_image->SetProperty("name", nameProp); + std::string val = "-"; + + if (gdcmReader->patient_ids().size()>o) + { + val = gdcmReader->patient_ids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.patient_id",val.c_str()); + } + + if (gdcmReader->patient_names().size()>o) + { + val = gdcmReader->patient_names().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.patient_name",val.c_str()); + } + + if (gdcmReader->study_instance_uids().size()>o) + { + val = gdcmReader->study_instance_uids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.study_instance_uid",val.c_str()); + } + + if (gdcmReader->series_instance_uids().size()>o) + { + val = gdcmReader->series_instance_uids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.series_instance_uid",val.c_str()); + } + + if (gdcmReader->sop_instance_uids().size()>o) + { + val = gdcmReader->sop_instance_uids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.sop_instance_uid",val.c_str()); + } + + if (gdcmReader->frame_of_reference_uids().size()>o) + { + val = gdcmReader->frame_of_reference_uids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.frame_of_reference_uid",val.c_str()); + } + result_images.push_back(loaded_image.GetPointer()); } // Since we have already read the tree, we can store it in a cache variable // so that it can be assigned to the DataObject in GenerateData(); m_OutputCache = outputForCache; m_CacheTime.Modified(); try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } catch(std::exception& e) { try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } MITK_INFO << "Std::Exception while reading file!!"; MITK_INFO << e.what(); throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what()); } catch(...) { try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } MITK_INFO << "Exception while reading file!!"; throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested vessel tree file!"); } } return result_images; } } //namespace MITK #endif diff --git a/Modules/DiffusionImaging/DiffusionCore/include/DicomImport/mitkDiffusionDICOMFileReader.h b/Modules/DiffusionImaging/DiffusionCore/include/DicomImport/mitkDiffusionDICOMFileReader.h index dc14d42a91..fb3cb334d4 100644 --- a/Modules/DiffusionImaging/DiffusionCore/include/DicomImport/mitkDiffusionDICOMFileReader.h +++ b/Modules/DiffusionImaging/DiffusionCore/include/DicomImport/mitkDiffusionDICOMFileReader.h @@ -1,72 +1,86 @@ /*=================================================================== 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 "mitkClassicDICOMSeriesReader.h" namespace mitk { class MITKDIFFUSIONCORE_EXPORT DiffusionDICOMFileReader - : public ClassicDICOMSeriesReader + : public ClassicDICOMSeriesReader { public: mitkClassMacro( DiffusionDICOMFileReader, ClassicDICOMSeriesReader ) mitkCloneMacro( DiffusionDICOMFileReader ) itkNewMacro( DiffusionDICOMFileReader ) virtual void AnalyzeInputFiles() override; virtual bool LoadImages() override; virtual bool CanHandleFile(const std::string &filename) override; void SetResolveMosaic( bool flag ) { m_ResolveMosaic = flag; } std::string GetStudyName(int i){ return m_Study_names.at(i); } std::string GetSeriesName(int i){ return m_Series_names.at(i); } + std::vector sop_instance_uids() const; + std::vector frame_of_reference_uids() const; + std::vector series_instance_uids() const; + std::vector study_instance_uids() const; + std::vector patient_names() const; + std::vector patient_ids() const; + protected: - DiffusionDICOMFileReader(); - virtual ~DiffusionDICOMFileReader(); + DiffusionDICOMFileReader(); + virtual ~DiffusionDICOMFileReader(); + + bool LoadSingleOutputImage( DiffusionHeaderDICOMFileReader::DICOMHeaderListType, DICOMImageBlockDescriptor&, bool); - bool LoadSingleOutputImage( DiffusionHeaderDICOMFileReader::DICOMHeaderListType, DICOMImageBlockDescriptor&, bool); + //mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType m_RetrievedHeader; - //mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType m_RetrievedHeader; + std::vector< mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType > m_OutputHeaderContainer; + std::vector< mitk::DiffusionHeaderDICOMFileReader::Pointer> m_OutputReaderContainer; + std::vector< bool > m_IsMosaicData; + std::vector< std::string > m_Study_names; + std::vector< std::string > m_Series_names; - std::vector< mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType > m_OutputHeaderContainer; - std::vector< mitk::DiffusionHeaderDICOMFileReader::Pointer> m_OutputReaderContainer; - std::vector< bool > m_IsMosaicData; - std::vector< std::string > m_Study_names; - std::vector< std::string > m_Series_names; + bool m_ResolveMosaic; - bool m_ResolveMosaic; + std::vector< std::string > m_sop_instance_uids; + std::vector< std::string > m_frame_of_reference_uids; + std::vector< std::string > m_series_instance_uids; + std::vector< std::string > m_study_instance_uids; + std::vector< std::string > m_patient_names; + std::vector< std::string > m_patient_ids; }; } #endif // MITKDIFFUSIONDICOMFILEREADER_H diff --git a/Modules/DiffusionImaging/DiffusionCore/src/DicomImport/mitkDiffusionDICOMFileReader.cpp b/Modules/DiffusionImaging/DiffusionCore/src/DicomImport/mitkDiffusionDICOMFileReader.cpp index b8626e475a..04db08099b 100644 --- a/Modules/DiffusionImaging/DiffusionCore/src/DicomImport/mitkDiffusionDICOMFileReader.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/src/DicomImport/mitkDiffusionDICOMFileReader.cpp @@ -1,356 +1,437 @@ /*=================================================================== 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" #include #include #include "mitkStringProperty.h" #include 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() { } 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), this->m_IsMosaicData.at(o) ); } return success; } bool mitk::DiffusionDICOMFileReader ::LoadSingleOutputImage( DiffusionHeaderDICOMFileReader::DICOMHeaderListType retrievedHeader, DICOMImageBlockDescriptor& block, bool is_mosaic) { // prepare data reading DiffusionDICOMFileReaderHelper helper; DiffusionDICOMFileReaderHelper::VolumeFileNamesContainer filenames; const DICOMImageFrameList& frames = block.GetImageFrameList(); int numberOfDWImages = block.GetIntProperty("timesteps", 1); 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; auto timeStepStart = frames.begin() + idx * numberOfFramesPerDWImage; auto timeStepEnd = frames.begin() + (idx+1) * numberOfFramesPerDWImage; for (auto frameIter = timeStepStart; frameIter != timeStepEnd; ++frameIter) { 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 mitk::Image::Pointer output_image = mitk::Image::New(); mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer directions = mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::New(); double max_bvalue = 0; for( int idx = 0; idx < numberOfDWImages; 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( int idx = 0; idx < numberOfDWImages; idx++ ) { DiffusionImageDICOMHeaderInformation header = retrievedHeader.at(idx); mitk::DiffusionPropertyHelper::GradientDirectionType grad = header.g_vector; grad.normalize(); grad *= sqrt( header.b_value / max_bvalue ); directions->push_back( grad ); } // initialize the output image output_image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( directions ) ); output_image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( max_bvalue ) ); if( is_mosaic && this->m_ResolveMosaic ) { mitk::DiffusionHeaderSiemensMosaicDICOMFileReader::Pointer mosaic_reader = 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(); mitk::CastToMitkImage( helper.LoadMosaicToVector( filenames, mdesc ), output_image ); } else { mitk::CastToMitkImage( helper.LoadToVector( filenames ), output_image ); } mitk::DiffusionPropertyHelper propertyHelper( output_image ); propertyHelper.InitializeImage(); output_image->SetProperty("diffusion.dicom.importname", mitk::StringProperty::New( helper.GetOutputName(filenames) ) ); block.SetMitkImage( (mitk::Image::Pointer) output_image ); return block.GetMitkImage().IsNotNull(); } +std::vector mitk::DiffusionDICOMFileReader::patient_ids() const +{ + return m_patient_ids; +} + +std::vector mitk::DiffusionDICOMFileReader::patient_names() const +{ + return m_patient_names; +} + +std::vector mitk::DiffusionDICOMFileReader::study_instance_uids() const +{ + return m_study_instance_uids; +} + +std::vector mitk::DiffusionDICOMFileReader::series_instance_uids() const +{ + return m_series_instance_uids; +} + +std::vector mitk::DiffusionDICOMFileReader::frame_of_reference_uids() const +{ + return m_frame_of_reference_uids; +} + +std::vector mitk::DiffusionDICOMFileReader::sop_instance_uids() const +{ + return m_sop_instance_uids; +} + void mitk::DiffusionDICOMFileReader ::AnalyzeInputFiles() { m_Study_names.clear(); m_Series_names.clear(); 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 "; } MITK_INFO("diffusion.dicomreader") << "Retrieved " << number_of_outputs << " outputs."; std::vector< bool > valid_input_list; for( unsigned int outputidx = 0; outputidx < this->GetNumberOfOutputs(); outputidx++ ) { 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 ); mitk::DiffusionHeaderDICOMFileReader::Pointer headerReader; bool isMosaic = false; gdcm::Scanner gdcmScanner; + gdcm::Tag t_sop_instance_uid(0x0008, 0x0018); + gdcm::Tag t_frame_of_reference_uid(0x0020, 0x0052); + gdcm::Tag t_series_instance_uid(0x0020, 0x000E); + gdcm::Tag t_study_instance_uid(0x0020, 0x000D); + gdcm::Tag t_patient_name(0x0010, 0x0010); + gdcm::Tag t_patient_id(0x0010, 0x0020); + gdcm::Tag t_vendor(0x008, 0x0070); gdcm::Tag t_imagetype(0x0008, 0x0008); gdcm::Tag t_StudyDescription(0x0008, 0x1030); gdcm::Tag t_SeriesDescription(0x0008, 0x103E); // add DICOM Tag for vendor gdcmScanner.AddTag( t_vendor ); // add DICOM Tag for image type gdcmScanner.AddTag( t_imagetype ); gdcmScanner.AddTag( t_StudyDescription ); gdcmScanner.AddTag( t_SeriesDescription ); + + gdcmScanner.AddTag( t_sop_instance_uid ); + gdcmScanner.AddTag( t_frame_of_reference_uid ); + gdcmScanner.AddTag( t_series_instance_uid ); + gdcmScanner.AddTag( t_study_instance_uid ); + gdcmScanner.AddTag( t_patient_name ); + gdcmScanner.AddTag( t_patient_id ); + if( gdcmScanner.Scan( inputFilename ) ) { // retrieve both vendor and image type const char* ch_vendor = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_vendor ); const char* ch_image_type = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_imagetype ); + const char* temp = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_sop_instance_uid ); + if (temp!=nullptr) + m_sop_instance_uids.push_back(std::string(temp)); + else + m_sop_instance_uids.push_back("-"); + + temp = nullptr; temp = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_frame_of_reference_uid ); + if (temp!=nullptr) + m_frame_of_reference_uids.push_back(std::string(temp)); + else + m_frame_of_reference_uids.push_back("-"); + + temp = nullptr; temp = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_series_instance_uid ); + if (temp!=nullptr) + m_series_instance_uids.push_back(std::string(temp)); + else + m_series_instance_uids.push_back("-"); + + temp = nullptr; temp = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_study_instance_uid ); + if (temp!=nullptr) + m_study_instance_uids.push_back(std::string(temp)); + else + m_study_instance_uids.push_back("-"); + + temp = nullptr; temp = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_patient_name ); + if (temp!=nullptr) + m_patient_names.push_back(std::string(temp)); + else + m_patient_names.push_back("-"); + + temp = nullptr; temp = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_patient_id ); + if (temp!=nullptr) + m_patient_ids.push_back(std::string(temp)); + else + m_patient_ids.push_back("-"); + if( ch_vendor == nullptr || ch_image_type == nullptr ) { MITK_WARN << "Unable to retrieve vendor/image information from " << frame_0->Filename.c_str() << "\n" << "Output " << outputidx+1 << " is not valid, skipping analysis."; valid_input_list.push_back(false); continue; } std::string vendor = std::string( ch_vendor ); std::string image_type = std::string( ch_image_type ); MITK_INFO("diffusion.dicomreader") << "Output " << outputidx+1 << " Got vendor: " << vendor << " image type " << image_type; // parse vendor tag if( vendor.find("SIEMENS") != std::string::npos ) //&& image_type.find("DIFFUSION") != std::string::npos ) { if( image_type.find("MOSAIC") != std::string::npos ) { headerReader = mitk::DiffusionHeaderSiemensMosaicDICOMFileReader::New(); isMosaic = 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. "; valid_input_list.push_back(false); continue; } } else { valid_input_list.push_back(false); continue; } 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 ); } if( canread ) { // collect the information mitk::DiffusionHeaderDICOMFileReader::DICOMHeaderListType retrievedHeader = headerReader->GetHeaderInformation(); m_IsMosaicData.push_back(isMosaic); m_OutputHeaderContainer.push_back( retrievedHeader ); m_OutputReaderContainer.push_back( headerReader ); valid_input_list.push_back(true); const char* ch_StudyDescription = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_StudyDescription ); const char* ch_SeriesDescription = gdcmScanner.GetValue( frame_0->Filename.c_str(), t_SeriesDescription ); if( ch_StudyDescription != nullptr ) m_Study_names.push_back(ch_StudyDescription); else m_Study_names.push_back("-"); if( ch_SeriesDescription != nullptr ) m_Series_names.push_back(ch_SeriesDescription); else m_Series_names.push_back("-"); } } // check status of the outputs and remove the non-valid std::vector< DICOMImageBlockDescriptor > valid_outputs; for ( unsigned int outputidx = 0; outputidx < this->GetNumberOfOutputs(); ++outputidx ) { if( valid_input_list.at(outputidx) ) { valid_outputs.push_back( this->InternalGetOutput( outputidx ) ); } } // clear complete list this->ClearOutputs(); this->SetNumberOfOutputs( valid_outputs.size() ); // insert only the valid ones for ( unsigned int outputidx = 0; valid_outputs.size(); ++outputidx ) this->SetOutput( outputidx, valid_outputs.at( outputidx ) ); for( unsigned int outputidx = 0; outputidx < this->GetNumberOfOutputs(); outputidx++ ) { // TODO : Analyze outputs + header information, i.e. for the loading confidence MITK_INFO("diffusion.dicomreader") << "---- DICOM Analysis Report ---- :: Output " << outputidx+1 << " of " << this->GetNumberOfOutputs(); try{ PerformHeaderAnalysis( this->m_OutputHeaderContainer.at( outputidx) ); } catch( const std::exception& se) { MITK_ERROR << "STD Exception " << se.what(); } MITK_INFO("diffusion.dicomreader") << "==========================================="; } } bool mitk::DiffusionDICOMFileReader ::CanHandleFile(const std::string & /* filename */) { //FIXME : return true; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorView.cpp index 04cff2405f..ad23944fa2 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorView.cpp @@ -1,165 +1,185 @@ /*=================================================================== 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. ===================================================================*/ // Blueberry #include #include #include // Qmitk #include "QmitkDicomTractogramTagEditorView.h" #include "QmitkStdMultiWidget.h" // Qt #include // MITK -#include #include #include #include #include const std::string QmitkDicomTractogramTagEditorView::VIEW_ID = "org.mitk.views.dicomtractogramtageditor"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace berry; QmitkDicomTractogramTagEditorView::QmitkDicomTractogramTagEditorView() : m_Controls(nullptr) { m_TagList = {"DICOM.patient_id", "DICOM.patient_name", "DICOM.study_instance_uid", "DICOM.series_instance_uid", "DICOM.sop_instance_uid", "DICOM.frame_of_reference_uid", "DICOM.algo_code.value", "DICOM.algo_code.meaning", "DICOM.model_code.value", "DICOM.model_code.meaning", "DICOM.anatomy.value", "DICOM.anatomy.meaning"}; } // Destructor QmitkDicomTractogramTagEditorView::~QmitkDicomTractogramTagEditorView() { } void QmitkDicomTractogramTagEditorView::CreateQtPartControl( QWidget *parent ) { if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkDicomTractogramTagEditorViewControls; m_Controls->setupUi( parent ); m_Controls->m_TractogramBox->SetDataStorage(this->GetDataStorage()); mitk::TNodePredicateDataType::Pointer isFibPredicate = mitk::TNodePredicateDataType::New(); m_Controls->m_TractogramBox->SetPredicate( isFibPredicate ); m_Controls->m_TractogramBox->SetZeroEntryText("--"); m_Controls->m_TagTable->setColumnCount(2); m_Controls->m_TagTable->setRowCount(m_TagList.size()); m_Controls->m_TagTable->verticalHeader()->setVisible(false); m_Controls->m_TagTable->setSelectionMode(QAbstractItemView::SingleSelection); QStringList tableHeader; tableHeader <<"Tag"<<"Value"; m_Controls->m_TagTable->setHorizontalHeaderLabels(tableHeader); m_Controls->m_TagTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - connect( (QObject*)(m_Controls->m_TractogramBox), SIGNAL(OnSelectionChanged(const mitk::DataNode*)), - this, SLOT(OnTractSelectionChanged()) ); - - - connect( (QObject*)(m_Controls->m_TagTable), SIGNAL(itemChanged(QTableWidgetItem*)), - this, SLOT(OnItemChanged(QTableWidgetItem*)) ); - + m_Controls->m_CopyPropsButton->setEnabled(false); + connect( (QObject*)(m_Controls->m_TractogramBox), SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnTractSelectionChanged()) ); + connect( (QObject*)(m_Controls->m_TagTable), SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(OnItemChanged(QTableWidgetItem*)) ); + connect( m_Controls->m_CopyPropsButton, SIGNAL(clicked()), this, SLOT(CopyProperties())); UpdateGui(); } } +void QmitkDicomTractogramTagEditorView::CopyProperties() +{ + if (m_Controls->m_TractogramBox->GetSelectedNode()==nullptr) + return; + mitk::FiberBundle::Pointer fib = dynamic_cast(m_Controls->m_TractogramBox->GetSelectedNode()->GetData()); + if (fib.IsNull()) + return; + if (m_Image.IsNull()) + return; + fib->SetPropertyList(m_Image->GetPropertyList()->Clone()); +} + void QmitkDicomTractogramTagEditorView::OnItemChanged(QTableWidgetItem* item) { if (m_Controls->m_TractogramBox->GetSelectedNode()==nullptr) { UpdateGui(); return; } int col = item->column(); if (col==1) { std::string tag = m_TagList.at(item->row()); mitk::FiberBundle::Pointer fib = dynamic_cast(m_Controls->m_TractogramBox->GetSelectedNode()->GetData()); mitk::PropertyList* p_list = fib->GetPropertyList(); p_list->SetStringProperty(tag.c_str(), item->text().toStdString().c_str()); - MITK_INFO << tag.c_str(); } UpdateGui(); } void QmitkDicomTractogramTagEditorView::OnTractSelectionChanged() { UpdateGui(); } void QmitkDicomTractogramTagEditorView::UpdateGui() { + m_Controls->m_CopyPropsButton->setEnabled(false); m_Controls->m_TagTable->blockSignals(true); if (m_Controls->m_TractogramBox->GetSelectedNode()==nullptr) { int row = 0; for (std::string tag : m_TagList) { m_Controls->m_TagTable->setItem(row, 0, new QTableWidgetItem(tag.c_str())); m_Controls->m_TagTable->setItem(row, 1, new QTableWidgetItem("-")); ++row; } m_Controls->m_TagTable->blockSignals(false); return; } mitk::FiberBundle::Pointer fib = dynamic_cast(m_Controls->m_TractogramBox->GetSelectedNode()->GetData()); mitk::PropertyList* p_list = fib->GetPropertyList(); int row = 0; for (std::string tag : m_TagList) { std::string val = "-"; p_list->GetStringProperty(tag.c_str(), val); m_Controls->m_TagTable->setItem(row, 0, new QTableWidgetItem(tag.c_str())); m_Controls->m_TagTable->setItem(row, 1, new QTableWidgetItem(val.c_str())); ++row; } + + if (m_Image.IsNotNull()) + m_Controls->m_CopyPropsButton->setEnabled(true); m_Controls->m_TagTable->blockSignals(false); } -void QmitkDicomTractogramTagEditorView::OnSelectionChanged( berry::IWorkbenchPart::Pointer , const QList& ) +void QmitkDicomTractogramTagEditorView::OnSelectionChanged( berry::IWorkbenchPart::Pointer , const QList& nodes) { - + m_Image = nullptr; + for (auto node : nodes) + { + mitk::Image::Pointer img = dynamic_cast(node->GetData()); + if (img.IsNotNull()) + { + m_Image = img; + } + } + UpdateGui(); } void QmitkDicomTractogramTagEditorView::SetFocus() { } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorView.h index 036b96fad2..2ef6897d91 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorView.h @@ -1,72 +1,74 @@ /*=================================================================== 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 QmitkDicomTractogramTagEditorView_h #define QmitkDicomTractogramTagEditorView_h #include #include "ui_QmitkDicomTractogramTagEditorViewControls.h" - +#include /*! \brief View for tensor based deterministic streamline fiber tracking. */ class QmitkDicomTractogramTagEditorView : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: static const std::string VIEW_ID; QmitkDicomTractogramTagEditorView(); virtual ~QmitkDicomTractogramTagEditorView(); virtual void CreateQtPartControl(QWidget *parent) override; /// /// Sets the focus to an internal widget. /// virtual void SetFocus() override; protected slots: void OnTractSelectionChanged(); + void CopyProperties(); void OnItemChanged(QTableWidgetItem * item); protected: void UpdateGui(); /// \brief called by QmitkAbstractView when DataManager's selection has changed virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes) override; Ui::QmitkDicomTractogramTagEditorViewControls* m_Controls; std::vector< std::string > m_TagList; + mitk::Image::Pointer m_Image; protected slots: private: }; #endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorViewControls.ui index 7178e021b1..84408ed504 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDicomTractogramTagEditorViewControls.ui @@ -1,146 +1,156 @@ QmitkDicomTractogramTagEditorViewControls 0 0 397 366 0 0 QmitkTemplate 3 3 0 - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 220 - - - - QFrame::NoFrame QFrame::Raised 0 0 0 9 Tractogram: Seed points are only placed inside the mask image. If no seed mask is selected, the whole image is seeded. QComboBox::AdjustToMinimumContentsLength - Tractography DICOM Tags 0 0 0 0 0 QFrame::NoFrame Qt::ScrollBarAlwaysOff QAbstractScrollArea::AdjustToContents + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 220 + + + + + + + + Copies the DICOM properties of the tractogram selected in this view to the one selected in the datamanager. + + + Copy Properties From Image + + + QmitkDataStorageComboBoxWithSelectNone QComboBox
QmitkDataStorageComboBoxWithSelectNone.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 510ff59b8b..11df473bc1 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp @@ -1,564 +1,600 @@ /*=================================================================== 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 "mitkImage.h" #include #include "mitkDiffusionDICOMFileReader.h" #include "mitkDICOMTagBasedSorter.h" #include "mitkDICOMSortByTag.h" #include "mitkSortByImagePositionPatient.h" #include "gdcmDirectory.h" #include "gdcmScanner.h" #include "gdcmSorter.h" #include "gdcmIPPSorter.h" #include "gdcmAttribute.h" #include "gdcmVersion.h" #include #include #include #include +#include const std::string QmitkDiffusionDicomImport::VIEW_ID = "org.mitk.views.diffusiondicomimport"; QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(QObject* /*parent*/, const char* /*name*/) : m_Controls(nullptr) , m_OutputFolderName("") , m_OutputFolderNameSet(false) { } QmitkDiffusionDicomImport::~QmitkDiffusionDicomImport() {} void QmitkDiffusionDicomImport::CreateQtPartControl(QWidget *parent) { m_Parent = parent; if (m_Controls == nullptr) { 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::SetFocus() { m_Controls->textBrowser->setFocus(); } 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::DicomLoadDeleteFolderNames() { m_Controls->listWidget->clear(); } void QmitkDiffusionDicomImport::DicomLoadAddFolderNames() { // SELECT FOLDER DIALOG QFileDialog w( m_Parent, QString("Select folders containing DWI data") ); w.setFileMode( QFileDialog::DirectoryOnly ); w.setOption(QFileDialog::DontUseNativeDialog,true); QListView *l = w.findChild("listView"); if (l) { l->setSelectionMode(QAbstractItemView::MultiSelection); } QTreeView *t = w.findChild(); if (t) { t->setSelectionMode(QAbstractItemView::MultiSelection); } // 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.toLatin1()); 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.toLatin1()); 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, nullptr ); if ( locale.compare(currLocale)!=0 ) { try { MITK_INFO << " ** Changing locale from " << setlocale(LC_ALL, nullptr) << " 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::SortByImagePositionPatient::New( // Image Position (Patient) //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() ).GetPointer(); tagSorter->SetSortCriterion( sorting ); // mosaic gdcmReader->SetResolveMosaic( this->m_Controls->m_SplitMosaicCheckBox->isChecked() ); gdcmReader->AddSortingElement( tagSorter ); gdcmReader->SetInputFiles( complete_list ); try { gdcmReader->AnalyzeInputFiles(); } catch( const itk::ExceptionObject &e) { MITK_ERROR << "Failed to analyze data. " << e.what(); } catch( const std::exception &se) { MITK_ERROR << "Std Exception " << se.what(); } gdcmReader->LoadImages(); for( unsigned int o = 0; o < gdcmReader->GetNumberOfOutputs(); o++ ) { mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(o).GetMitkImage(); - std::stringstream ss; - ss << "ImportedData_" << o; + std::string outname; + if (gdcmReader->GetSeriesName(o)!="-") + outname = gdcmReader->GetSeriesName(o); + else if (gdcmReader->GetStudyName(o)!="-") + outname = gdcmReader->GetStudyName(o); + else + loaded_image->GetPropertyList()->GetStringProperty("diffusion.dicom.importname", outname ); + + std::string val = "-"; + + if (gdcmReader->patient_ids().size()>o) + { + val = gdcmReader->patient_ids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.patient_id",val.c_str()); + } + + if (gdcmReader->patient_names().size()>o) + { + val = gdcmReader->patient_names().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.patient_name",val.c_str()); + } + + if (gdcmReader->study_instance_uids().size()>o) + { + val = gdcmReader->study_instance_uids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.study_instance_uid",val.c_str()); + } + + if (gdcmReader->series_instance_uids().size()>o) + { + val = gdcmReader->series_instance_uids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.series_instance_uid",val.c_str()); + } + + if (gdcmReader->sop_instance_uids().size()>o) + { + val = gdcmReader->sop_instance_uids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.sop_instance_uid",val.c_str()); + } + + if (gdcmReader->frame_of_reference_uids().size()>o) + { + val = gdcmReader->frame_of_reference_uids().at(o); + loaded_image->GetPropertyList()->SetStringProperty("DICOM.frame_of_reference_uid",val.c_str()); + } node = mitk::DataNode::New(); node->SetData( loaded_image ); - std::string outname; - loaded_image->GetPropertyList()->GetStringProperty("diffusion.dicom.importname", outname ); - node->SetName( outname.c_str() ); GetDataStorage()->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, nullptr) << " 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(nullptr,"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 ); }