diff --git a/Core/Code/Algorithms/mitkDataNodeFactory.cpp b/Core/Code/Algorithms/mitkDataNodeFactory.cpp index 82ce5baac2..05605cb244 100644 --- a/Core/Code/Algorithms/mitkDataNodeFactory.cpp +++ b/Core/Code/Algorithms/mitkDataNodeFactory.cpp @@ -1,459 +1,457 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include // C-Standard library includes #include #include // STL-related includes #include #include #include #include #include // VTK-related includes #include #include #include #include #include #include #include #include #include #include #if ((VTK_MAJOR_VERSION > 4) || ((VTK_MAJOR_VERSION==4) && (VTK_MINOR_VERSION>=4) )) #include #endif // ITK-related includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include // MITK-related includes #include "mitkSurface.h" #include "mitkPointSet.h" #include "mitkStringProperty.h" #include "mitkProperties.h" //#include "mitkMaterialProperty.h" #include "mitkLevelWindowProperty.h" #include "mitkVtkRepresentationProperty.h" #include "mitkVtkInterpolationProperty.h" #include "mitkVtkScalarModeProperty.h" #include "mitkImage.h" #include "mitkLookupTableProperty.h" #include "mitkLookupTable.h" #include "mitkImageChannelSelector.h" #include "mitkImageSliceSelector.h" #include "mitkCoreObjectFactory.h" #include "mitkTransferFunctionProperty.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkProgressBar.h" #include bool mitk::DataNodeFactory::m_TextureInterpolationActive = false; // default value for texture interpolation if nothing is defined in global options (see QmitkMainTemplate.ui.h) mitk::DataNodeFactory::DataNodeFactory() { m_Serie = false; m_OldProgress = 0; this->Modified(); //ensure that a CoreObjectFactory has been instantiated mitk::CoreObjectFactory::GetInstance(); } mitk::DataNodeFactory::~DataNodeFactory() {} void mitk::DataNodeFactory::SetImageSerie(bool serie) { m_Serie = serie; } void mitk::DataNodeFactory::GenerateData() { // IF filename is something.pic, and something.pic does not exist, try to read something.pic.gz // if there are both, something.pic and something.pic.gz, only the requested file is read // not only for images, but for all formats std::ifstream exists(m_FileName.c_str()); if (!exists) { std::string testfilename = m_FileName + ".gz"; std::ifstream exists(testfilename.c_str()); if (exists.good()) { m_FileName += ".gz"; } else { testfilename = m_FileName + ".GZ"; std::ifstream exists(testfilename.c_str()); if (exists.good()) { m_FileName += ".GZ"; } else { std::string message("File does not exist, or cannot be read. Filename = "); message += m_FileName; MITK_ERROR << message; itkExceptionMacro( << message ); } } } // part for DICOM // const char *numbers = "0123456789."; // std::string::size_type first_non_number; // first_non_number = itksys::SystemTools::GetFilenameName(m_FileName).find_first_not_of ( numbers ); if (DicomSeriesReader::IsDicom(this->m_FileName) /*|| first_non_number == std::string::npos*/) { this->ReadFileSeriesTypeDCM(); } else { bool usedNewDTNF = false; // the mitkBaseDataIO class returns a pointer of a vector of BaseData objects std::vector baseDataVector = mitk::BaseDataIO::LoadBaseDataFromFile( m_FileName, m_FilePrefix, m_FilePattern, m_Serie ); if( !baseDataVector.empty() ) this->ResizeOutputs((unsigned int)baseDataVector.size()); for(int i=0; i<(int)baseDataVector.size(); i++) { mitk::BaseData::Pointer baseData = baseDataVector.at(i); if( baseData.IsNotNull() ) { usedNewDTNF = true; mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(baseData); this->SetDefaultCommonProperties( node ); this->SetOutput(i, node); } } if(!usedNewDTNF && ( m_FileName != "" ) && !(m_Serie == false)) ReadFileSeriesTypeITKImageSeriesReader(); } } void mitk::DataNodeFactory::ResizeOutputs( const unsigned int& num ) { unsigned int prevNum = this->GetNumberOfOutputs(); this->SetNumberOfOutputs( num ); for ( unsigned int i = prevNum; i < num; ++i ) { this->SetNthOutput( i, this->MakeOutput( i ).GetPointer() ); } } bool mitk::DataNodeFactory::FileNameEndsWith( const std::string& name ) { if (m_FileName.size() < name.size()) return false; return m_FileName.substr(m_FileName.size() - name.size()) == name; } bool mitk::DataNodeFactory::FilePatternEndsWith( const std::string& name ) { return m_FilePattern.find( name ) != std::string::npos; } std::string mitk::DataNodeFactory::GetBaseFileName() { return itksys::SystemTools::GetFilenameName( m_FileName ); } std::string mitk::DataNodeFactory::GetBaseFilePrefix() { return itksys::SystemTools::GetFilenameName( m_FilePrefix ); } std::string mitk::DataNodeFactory::GetDirectory() { if ( !m_FileName.empty() ) return itksys::SystemTools::GetFilenamePath( m_FileName ); if ( !m_FilePrefix.empty() ) return itksys::SystemTools::GetFilenamePath( m_FilePrefix ); return std::string(); } void mitk::DataNodeFactory::ReadFileSeriesTypeDCM() { const char* previousCLocale = setlocale(LC_NUMERIC, NULL); setlocale(LC_NUMERIC, "C"); std::locale previousCppLocale( std::cin.getloc() ); std::locale l( "C" ); std::cin.imbue(l); - #if GDCM_MAJOR_VERSION >= 2 if ( DicomSeriesReader::IsPhilips3DDicom(this->GetFileName()) ) { MITK_INFO << "it is a Philips3D US Dicom file" << std::endl; this->ResizeOutputs(1); DataNode::Pointer node = this->GetOutput(0); mitk::DicomSeriesReader::StringContainer stringvec; stringvec.push_back(this->GetFileName()); if (DicomSeriesReader::LoadDicomSeries(stringvec, *node)) { node->SetName(this->GetBaseFileName()); } setlocale(LC_NUMERIC, previousCLocale); std::cin.imbue(previousCppLocale); return; } - #endif DicomSeriesReader::UidFileNamesMap names_map = DicomSeriesReader::GetSeries(this->GetDirectory(), this->m_SeriesRestrictions); const unsigned int size = names_map.size(); this->ResizeOutputs(size); ProgressBar::GetInstance()->AddStepsToDo(size); ProgressBar::GetInstance()->Progress(); unsigned int i = 0u; const DicomSeriesReader::UidFileNamesMap::const_iterator n_end = names_map.end(); for (DicomSeriesReader::UidFileNamesMap::const_iterator n_it = names_map.begin(); n_it != n_end; ++n_it) { const std::string &uid = n_it->first; DataNode::Pointer node = this->GetOutput(i); MITK_INFO << "Reading series " << i << ": " << uid << std::endl; if (DicomSeriesReader::LoadDicomSeries(n_it->second, *node)) { ++i; node->SetName(uid); } else { MITK_ERROR << "Skipping series " << i << " due to exception" << std::endl; } ProgressBar::GetInstance()->Progress(); } setlocale(LC_NUMERIC, previousCLocale); std::cin.imbue(previousCppLocale); } void mitk::DataNodeFactory::ReadFileSeriesTypeITKImageSeriesReader() { typedef itk::Image ImageType; typedef itk::ImageSeriesReader< ImageType > ReaderType; typedef itk::NumericSeriesFileNames NameGenerator; if ( ! this->GenerateFileList() ) { itkWarningMacro( "Sorry, file list could not be generated!" ); return ; } if ( m_MatchedFileNames.size() == 0 ) { itkWarningMacro( "Sorry, no files matched the given filename ("<< m_FileName <<")!" ); return ; } // // Finally, initialize the ITK-reader and load the files! // ReaderType::Pointer reader = ReaderType::New(); reader->SetFileNames( m_MatchedFileNames ); try { reader->Update(); ResizeOutputs( reader->GetNumberOfOutputs() ); for ( unsigned int i = 0; i < reader->GetNumberOfOutputs(); ++i ) { //Initialize mitk image from itk mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( reader->GetOutput( i ) ); image->SetVolume( reader->GetOutput( i )->GetBufferPointer() ); //add the mitk image to the node mitk::DataNode::Pointer node = this->GetOutput( i ); node->SetData( image ); mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New( m_FileName ); node->SetProperty( "name", nameProp ); } } catch ( const std::exception & e ) { itkWarningMacro( << e.what() ); return ; } } mitk::ColorProperty::Pointer mitk::DataNodeFactory::DefaultColorForOrgan( const std::string& organ ) { static bool initialized = false; static std::map< std::string, std::string > s_ColorMap; if (!initialized) { // all lowercase here, please! s_ColorMap.insert( std::make_pair( "ankle", "0xe38686") ); s_ColorMap.insert( std::make_pair( "appendix", "0xe38686") ); s_ColorMap.insert( std::make_pair( "blood vessels", "0xff3131") ); s_ColorMap.insert( std::make_pair( "bronchial tree", "0x3168ff") ); s_ColorMap.insert( std::make_pair( "bone", "0xd5d5d5") ); s_ColorMap.insert( std::make_pair( "brain", "0xff9cca") ); s_ColorMap.insert( std::make_pair( "coccyx", "0xe38686") ); s_ColorMap.insert( std::make_pair( "colon", "0xe38686") ); s_ColorMap.insert( std::make_pair( "cyst", "0xe38686") ); s_ColorMap.insert( std::make_pair( "elbow", "0xe38686") ); s_ColorMap.insert( std::make_pair( "eye", "0xe38686") ); s_ColorMap.insert( std::make_pair( "fallopian tube", "0xe38686") ); s_ColorMap.insert( std::make_pair( "fat", "0xff2bee") ); s_ColorMap.insert( std::make_pair( "hand", "0xe38686") ); s_ColorMap.insert( std::make_pair( "gall bladder", "0x567f18") ); s_ColorMap.insert( std::make_pair( "heart", "0xeb1d32") ); s_ColorMap.insert( std::make_pair( "hip", "0xe38686") ); s_ColorMap.insert( std::make_pair( "kidney", "0xd33f00") ); s_ColorMap.insert( std::make_pair( "knee", "0xe38686") ); s_ColorMap.insert( std::make_pair( "larynx", "0xe38686") ); s_ColorMap.insert( std::make_pair( "liver", "0xffcc3d") ); s_ColorMap.insert( std::make_pair( "lung", "0x6bdcff") ); s_ColorMap.insert( std::make_pair( "lymph node", "0xff0000") ); s_ColorMap.insert( std::make_pair( "muscle", "0xff456a") ); s_ColorMap.insert( std::make_pair( "nerve", "0xffea4f") ); s_ColorMap.insert( std::make_pair( "nose", "0xe38686") ); s_ColorMap.insert( std::make_pair( "oesophagus", "0xe38686") ); s_ColorMap.insert( std::make_pair( "ovaries", "0xe38686") ); s_ColorMap.insert( std::make_pair( "pancreas", "0xf9ab3d") ); s_ColorMap.insert( std::make_pair( "pelvis", "0xe38686") ); s_ColorMap.insert( std::make_pair( "penis", "0xe38686") ); s_ColorMap.insert( std::make_pair( "pharynx", "0xe38686") ); s_ColorMap.insert( std::make_pair( "prostate", "0xe38686") ); s_ColorMap.insert( std::make_pair( "rectum", "0xe38686") ); s_ColorMap.insert( std::make_pair( "sacrum", "0xe38686") ); s_ColorMap.insert( std::make_pair( "seminal vesicle", "0xe38686") ); s_ColorMap.insert( std::make_pair( "shoulder", "0xe38686") ); s_ColorMap.insert( std::make_pair( "spinal cord", "0xf5f93d") ); s_ColorMap.insert( std::make_pair( "spleen", "0xf96c3d") ); s_ColorMap.insert( std::make_pair( "stomach", "0xf96c3d") ); s_ColorMap.insert( std::make_pair( "teeth", "0xfffcd8") ); s_ColorMap.insert( std::make_pair( "testicles", "0xe38686") ); s_ColorMap.insert( std::make_pair( "thyroid", "0xfff694") ); s_ColorMap.insert( std::make_pair( "tongue", "0xe38686") ); s_ColorMap.insert( std::make_pair( "tumor", "0x937011") ); s_ColorMap.insert( std::make_pair( "urethra", "0xf8ff32") ); s_ColorMap.insert( std::make_pair( "urinary bladder", "0xf8ff32") ); s_ColorMap.insert( std::make_pair( "uterus", "0xe38686") ); s_ColorMap.insert( std::make_pair( "vagina", "0xe38686") ); s_ColorMap.insert( std::make_pair( "vertebra", "0xe38686") ); s_ColorMap.insert( std::make_pair( "wrist", "0xe38686") ); initialized = true; } std::string lowercaseOrgan(organ); for(unsigned int i = 0; i < organ.length(); i++) { lowercaseOrgan[i] = tolower(lowercaseOrgan[i]); } std::map< std::string, std::string >::iterator iter = s_ColorMap.find( lowercaseOrgan ); if ( iter != s_ColorMap.end() ) { std::string hexColor = iter->second; std::string hexRed = std::string("0x") + hexColor.substr( 2, 2 ); std::string hexGreen = std::string("0x") + hexColor.substr( 4, 2 ); std::string hexBlue = std::string("0x") + hexColor.substr( 6, 2 ); long int red = strtol( hexRed.c_str(), NULL, 16 ); long int green = strtol( hexGreen.c_str(), NULL, 16 ); long int blue = strtol( hexBlue.c_str(), NULL, 16 ); return ColorProperty::New( (float)red/ 255.0, (float)green/ 255.0, (float)blue/ 255.0 ); } else { // a default color (green) return ColorProperty::New( 0.0, 1.0, 0.0 ); } } void mitk::DataNodeFactory::SetDefaultCommonProperties(mitk::DataNode::Pointer &node) { // path mitk::StringProperty::Pointer pathProp = mitk::StringProperty::New( itksys::SystemTools::GetFilenamePath( m_FileName ) ); node->SetProperty( StringProperty::PATH, pathProp ); // name already defined? mitk::StringProperty::Pointer nameProp = dynamic_cast(node->GetProperty("name")); if(nameProp.IsNull() || (strcmp(nameProp->GetValue(),"No Name!")==0)) { // name already defined in BaseData mitk::StringProperty::Pointer baseDataNameProp = dynamic_cast(node->GetData()->GetProperty("name").GetPointer() ); if(baseDataNameProp.IsNull() || (strcmp(baseDataNameProp->GetValue(),"No Name!")==0)) { // name neither defined in node, nor in BaseData -> name = filename if (FileNameEndsWith( ".gz" )) m_FileName = m_FileName.substr( 0, m_FileName.length()-3 ); nameProp = mitk::StringProperty::New( itksys::SystemTools::GetFilenameWithoutLastExtension( m_FileName ) ); node->SetProperty( "name", nameProp ); } else { // name defined in BaseData! nameProp = mitk::StringProperty::New( baseDataNameProp->GetValue() ); node->SetProperty( "name", nameProp ); } } // visibility if(!node->GetProperty("visible")) node->SetVisibility(true); } diff --git a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp index 967cc5ed80..1ddb8532ae 100644 --- a/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp @@ -1,672 +1,629 @@ /*========================================================================= Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #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" // diffusion module includes #include "mitkDicomDiffusionImageHeaderReader.h" #include "mitkGroupDiffusionHeadersFilter.h" #include "mitkDicomDiffusionImageReader.h" #include "mitkDiffusionImage.h" #include "mitkNrrdDiffusionImageWriter.h" -#if GDCM_MAJOR_VERSION >= 2 -#define DGDCM2 -#endif - -#ifdef DGDCM2 #include "gdcmDirectory.h" #include "gdcmScanner.h" #include "gdcmSorter.h" #include "gdcmIPPSorter.h" #include "gdcmAttribute.h" #include "gdcmVersion.h" -#endif 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() {} 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(true); m_Controls->m_DicomLoadAverageDuplicatesCheckbox->setChecked(false); -#ifdef DGDCM2 m_Controls->m_DicomLoadRecursiveCheckbox->setVisible(false); -#endif 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_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()) ); } } 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); } void QmitkDiffusionDicomImport::OutputClear() { m_OutputFolderName = ""; m_OutputFolderNameSet = false; m_Controls->m_OutputLabel->setText("... optional out-folder ..."); } 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()); } -#ifdef DGDCM2 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(0).Trim(); std::string str2 = at2.GetValue(0).Trim(); return std::lexicographical_compare(str1.begin(), str1.end(), str2.begin(), str2.end() ); } -#endif 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::DicomLoadStartLoad() { itk::TimeProbesCollectorBase clock; try { int nrFolders = m_Controls->listWidget->count(); if(!nrFolders) { Error(QString("No input folders were selected. ABORTING.")); return; } -#ifndef DGDCM2 - Status(QString("GDCM 1.x used for DICOM parsing and sorting!")); -#else Status(QString("GDCM %1 used for DICOM parsing and sorting!").arg(gdcm::Version::GetVersion())); -#endif PrintMemoryUsage(); QString status; mitk::DataNode::Pointer node; mitk::ProgressBar::GetInstance()->AddStepsToDo(3*nrFolders); while(m_Controls->listWidget->count()) { // RETREIVE FOLDERNAME QListWidgetItem * item = m_Controls->listWidget->takeItem(0); QString folderName = item->text(); // PARSING DIRECTORY PrintMemoryUsage(); clock.Start(folderName.toAscii()); std::vector seriesUIDs(0); std::vector > seriesFilenames(0); -#ifndef DGDCM2 - Status(QString("Parsing directory %1").arg(folderName)); - typedef itk::GDCMSeriesFileNames InputNamesType; - InputNamesType::Pointer inputNames = InputNamesType::New(); - - ////////////////////////////////////////////////////// - //// - //// if you get seg-faults around here, make sure - //// to set the itk GDCM_DIR variable in cmake - //// correctly when building ITK - //// ( e.g. [itk binary dir]/Utilities/gdcm - //// if not using system gdcm ) - //// - ////////////////////////////////////////////////////// - - inputNames->SetRecursive(m_Controls->m_DicomLoadRecursiveCheckbox->isChecked()); - inputNames->SetUseSeriesDetails(true); - inputNames->AddSeriesRestriction( "0020|0012" ); - inputNames->SetInputDirectory( folderName.toAscii() ); - mitk::ProgressBar::GetInstance()->Progress(); - seriesUIDs = inputNames->GetSeriesUIDs(); - unsigned int size = seriesUIDs.size(); - for ( unsigned int i = 0 ; i < size ; ++i ) - { - seriesFilenames.push_back(inputNames->GetFileNames(seriesUIDs[i])); - } -#else Status("== Initial Directory Scan =="); gdcm::Directory d; d.Load( folderName.toStdString().c_str(), true ); // recursive ! const gdcm::Directory::FilenamesType &l1 = d.GetFilenames(); const unsigned int ntotalfiles = l1.size(); Status(QString(" ... found %1 different files").arg(ntotalfiles)); Status("Scanning Headers"); gdcm::Scanner s; const gdcm::Tag t1(0x0020,0x000d); // Study Instance UID const gdcm::Tag t2(0x0020,0x000e); // Series Instance UID const gdcm::Tag t5(0x0028, 0x0010); // number rows const gdcm::Tag t6(0x0028, 0x0011); // number cols s.AddTag( t1 ); s.AddTag( t2 ); s.AddTag( t5 ); s.AddTag( t6 ); bool b = s.Scan( d.GetFilenames() ); if( !b ) { Error("Scanner failed"); continue; } // Only get the DICOM files: gdcm::Directory::FilenamesType l2 = s.GetKeys(); const int nfiles = l2.size(); if(nfiles < 1) { Error("No DICOM files found"); continue; } Status(QString(" ... successfully scanned %1 headers.").arg(nfiles)); Status("Sorting"); const gdcm::Scanner::ValuesType &values1 = s.GetValues(t1); int nvalues = values1.size(); if(nvalues>1) { Error("Multiple studies found. Please limit to 1 study per folder"); continue; } const gdcm::Scanner::ValuesType &values5 = s.GetValues(t5); const gdcm::Scanner::ValuesType &values6 = s.GetValues(t6); if(values5.size()>1 || values6.size()>1) { Error("Folder contains images of unequal dimensions that cannot be combined in one 3d volume. ABORTING."); continue; } const gdcm::Scanner::ValuesType &values2 = s.GetValues(t2); int nSeries = values2.size(); gdcm::Directory::FilenamesType files; if(nSeries > 1) { gdcm::Sorter sorter; sorter.SetSortFunction( SortBySeriesUID ); sorter.StableSort( l2 ); files = sorter.GetFilenames(); } else { files = l2; } unsigned int nTotalAcquis = 0; if(nfiles % nSeries != 0) { Error("Number of files in series not equal, ABORTING"); continue; } int filesPerSeries = nfiles / nSeries; gdcm::Scanner::ValuesType::const_iterator it2 = values2.begin(); for(int i=0; i & list = ippsorter.GetFilenames(); seriesFilenames.push_back(list); seriesUIDs.push_back(identifier.c_str()); } ++it2; } if(nfiles % nTotalAcquis != 0) { Error("Number of files per acquisition differs between series, ABORTING"); continue; } int slices = nfiles/nTotalAcquis; Status(QString("Series is composed of %1 different 3D volumes with %2 slices.").arg(nTotalAcquis).arg(slices)); -#endif - // READING HEADER-INFOS PrintMemoryUsage(); Status(QString("Reading Headers %1").arg(folderName)); mitk::DicomDiffusionImageHeaderReader::Pointer headerReader; mitk::GroupDiffusionHeadersFilter::InputType inHeaders; unsigned int size2 = seriesUIDs.size(); for ( unsigned int i = 0 ; i < size2 ; ++i ) { Status(QString("Reading header image #%1/%2").arg(i+1).arg(size2)); headerReader = mitk::DicomDiffusionImageHeaderReader::New(); headerReader->SetSeriesDicomFilenames(seriesFilenames[i]); headerReader->Update(); inHeaders.push_back(headerReader->GetOutput()); //Status(std::endl; } mitk::ProgressBar::GetInstance()->Progress(); // // GROUP HEADERS // mitk::GroupDiffusionHeadersFilter::Pointer grouper // = mitk::GroupDiffusionHeadersFilter::New(); // mitk::GroupDiffusionHeadersFilter::OutputType outHeaders; // grouper->SetInput(inHeaders); // grouper->Update(); // outHeaders = grouper->GetOutput(); // READ VOLUMES PrintMemoryUsage(); Status(QString("Loading Volumes %1").arg(folderName)); typedef short PixelValueType; typedef mitk::DicomDiffusionImageReader< PixelValueType, 3 > VolumesReader; VolumesReader::Pointer vReader = VolumesReader::New(); VolumesReader::HeaderContainer hc = inHeaders; // hc.insert(hc.end(), outHeaders[1].begin(), outHeaders[1].end() ); // hc.insert(hc.end(), outHeaders[2].begin(), outHeaders[2].end() ); if(hc.size()>1) { vReader->SetHeaders(hc); vReader->Update(); VolumesReader::OutputImageType::Pointer vecImage; vecImage = vReader->GetOutput(); Status(QString("Volumes Loaded (%1)").arg(folderName)); // CONSTRUCT CONTAINER WITH DIRECTIONS typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef itk::VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; GradientDirectionContainerType::Pointer directions = GradientDirectionContainerType::New(); std::vector b_vals; double maxb = 0; for(unsigned int i=0; ibValue; if(maxb vect = hc[i]->DiffusionVector; vect.normalize(); vect *= sqrt(b_vals[i]/maxb); directions->push_back(vect); } // DWI TO DATATREE PrintMemoryUsage(); Status(QString("Initializing Diffusion Image")); typedef mitk::DiffusionImage DiffVolumesType; DiffVolumesType::Pointer diffImage = DiffVolumesType::New(); diffImage->SetDirections(directions); diffImage->SetOriginalDirections(directions); if(m_Controls->m_DicomLoadDKFZ->isChecked()) { diffImage->CorrectDKFZBrokenGradientScheme(m_Controls->m_Blur->value()); } diffImage->SetVectorImage(vecImage); diffImage->SetB_Value(maxb); diffImage->InitializeFromVectorImage(); Status(QString("Diffusion Image initialized")); if(m_Controls->m_DicomLoadAverageDuplicatesCheckbox->isChecked()) { PrintMemoryUsage(); Status(QString("Averaging gradient directions")); diffImage->AverageRedundantGradients(m_Controls->m_Blur->value()); } //if(m_Controls->m_DicomLoadDuplicateIfSingleSliceCheckbox->isChecked()) // diffVolumes->DuplicateIfSingleSlice(); QString descr = QString("%1_%2_%3") .arg(((inHeaders)[0])->seriesDescription.c_str()) .arg(((inHeaders)[0])->seriesNumber) .arg(((inHeaders)[0])->patientName.c_str()); descr = descr.trimmed(); descr = descr.replace(" ", "_"); if(!m_OutputFolderNameSet) { node=mitk::DataNode::New(); node->SetData( diffImage ); GetDefaultDataStorage()->Add(node); SetDwiNodeProperties(node, descr.toStdString().c_str()); Status(QString("Image %1 added to datastorage").arg(descr)); } else { typedef mitk::NrrdDiffusionImageWriter WriterType; WriterType::Pointer writer = WriterType::New(); QString fullpath = QString("%1/%2.dwi") .arg(m_OutputFolderName) .arg(descr); std::string pathstring = itksys::SystemTools::ConvertToOutputPath(fullpath.toStdString().c_str()); writer->SetFileName(pathstring); writer->SetInput(diffImage); try { writer->Update(); } 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())); continue ; } Status(QString("Image %1 written to disc (%1)").arg(fullpath.toStdString().c_str())); } } else { Status(QString("No diffusion information found (%1)").arg(folderName)); } Status(QString("Finished processing %1 with memory:").arg(folderName)); PrintMemoryUsage(); clock.Stop(folderName.toAscii()); mitk::ProgressBar::GetInstance()->Progress(); } Status("Timing information"); clock.Report(); if(!m_OutputFolderNameSet && node.IsNotNull()) { mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } 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 ; } 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 ); } diff --git a/Modules/DiffusionImaging/DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp b/Modules/DiffusionImaging/DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp index 77adc61bfd..6daa3e5b90 100644 --- a/Modules/DiffusionImaging/DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp +++ b/Modules/DiffusionImaging/DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp @@ -1,192 +1,174 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $ Version: $Revision: 13129 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkGEDicomDiffusionImageHeaderReader.h" #include "gdcmGlobal.h" //#include "gdcmVersion.h" -#if GDCM_MAJOR_VERSION >= 2 - #define DGDCM2 -#endif - -#ifndef DGDCM2 - -#include "gdcm.h" -// relevant Siemens private tags -// relevant GE private tags -const gdcm::DictEntry GEDictBValue( 0x0043, 0x1039, "IS", "1", "B Value of diffusion weighting" ); -const gdcm::DictEntry GEDictXGradient( 0x0019, 0x10bb, "DS", "1", "X component of gradient direction" ); -const gdcm::DictEntry GEDictYGradient( 0x0019, 0x10bc, "DS", "1", "Y component of gradient direction" ); -const gdcm::DictEntry GEDictZGradient( 0x0019, 0x10bd, "DS", "1", "Z component of gradient direction" ); - -#else - #include "gdcmDict.h" #include "gdcmDicts.h" #include "gdcmDictEntry.h" #include "gdcmDictEntry.h" #include "gdcmDict.h" #include "gdcmFile.h" #include "gdcmSerieHelper.h" //const gdcm::DictEntry GEDictBValue( "0043,1039", gdcm::VR::IS, gdcm::VM::VM1, "B Value of diffusion weighting" ); //const gdcm::DictEntry GEDictXGradient( "0019,10bb", gdcm::VR::DS, gdcm::VM::VM1 , "X component of gradient direction" ); //const gdcm::DictEntry GEDictYGradient( "0019,10bc", gdcm::VR::DS, gdcm::VM::VM1 , "Y component of gradient direction" ); //const gdcm::DictEntry GEDictZGradient( "0019,10bd", gdcm::VR::DS, gdcm::VM::VM1 , "Z component of gradient direction" ); -#endif - mitk::GEDicomDiffusionImageHeaderReader::GEDicomDiffusionImageHeaderReader() { } mitk::GEDicomDiffusionImageHeaderReader::~GEDicomDiffusionImageHeaderReader() { } // do the work void mitk::GEDicomDiffusionImageHeaderReader::Update() { // check if there are filenames if(m_DicomFilenames.size()) { 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; } } // adapted from namic-sandbox // DicomToNrrdConverter.cxx VolumeReaderType::DictionaryArrayRawPointer inputDict = m_VolumeReader->GetMetaDataDictionaryArray(); #ifndef DGDCM2 if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GEDictBValue.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(GEDictBValue); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GEDictXGradient.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(GEDictXGradient); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GEDictYGradient.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(GEDictYGradient); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GEDictZGradient.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(GEDictZGradient); #endif ReadPublicTags(); //int mMosaic; // number of raws in each mosaic block; //int nMosaic; // number of columns in each mosaic block float x0, y0, z0; float x1, y1, z1; std::string tag; tag.clear(); itk::ExposeMetaData ( *(*inputDict)[0], "0020|0032", tag ); sscanf( tag.c_str(), "%f\\%f\\%f", &x0, &y0, &z0 ); std::cout << "Slice 0: " << tag << std::endl; tag.clear(); // assume volume interleaving, i.e. the second dicom file stores // the second slice in the same volume as the first dicom file itk::ExposeMetaData ( *(*inputDict)[1], "0020|0032", tag ); sscanf( tag.c_str(), "%f\\%f\\%f", &x1, &y1, &z1 ); std::cout << "Slice 1: " << tag << std::endl; x1 -= x0; y1 -= y0; z1 -= z0; x0 = x1*this->m_Output->xSlice + y1*this->m_Output->ySlice + z1*this->m_Output->zSlice; if (x0 < 0) { m_SliceOrderIS = false; } ReadPublicTags2(); int nSliceInVolume; int nVolume; nSliceInVolume = m_sliceLocations.size(); nVolume = m_nSlice/nSliceInVolume; // assume volume interleaving std::cout << "Number of Slices: " << m_nSlice << std::endl; std::cout << "Number of Volume: " << nVolume << std::endl; std::cout << "Number of Slices in each volume: " << nSliceInVolume << std::endl; for (int k = 0; k < m_nSlice; k += nSliceInVolume) { tag.clear(); bool exist = itk::ExposeMetaData ( *(*inputDict)[k], "0043|1039", tag); float b = atof( tag.c_str() ); this->m_Output->bValue = b; vnl_vector_fixed vect3d; if (!exist || b == 0) { vect3d.fill( 0 ); this->m_Output->DiffusionVector = vect3d; continue; } vect3d.fill( 0 ); tag.clear(); itk::ExposeMetaData ( *(*inputDict)[k], "0019|10bb", tag); vect3d[0] = atof( tag.c_str() ); tag.clear(); itk::ExposeMetaData ( *(*inputDict)[k], "0019|10bc", tag); vect3d[1] = atof( tag.c_str() ); tag.clear(); itk::ExposeMetaData ( *(*inputDict)[k], "0019|10bd", tag); vect3d[2] = atof( tag.c_str() ); vect3d.normalize(); this->m_Output->DiffusionVector = vect3d; } TransformGradients(); 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; } } } //header = new mitk::DWIHeader(nRows, nCols, xRes, yRes, xOrigin,yOrigin, // zOrigin, sliceThickness, sliceSpacing,nSliceInVolume, xRow, yRow, // zRow, xCol,yCol, zCol, xSlice, ySlice, zSlice,bValues[0], DiffusionVectors[0], // vendor,SliceMosaic); diff --git a/Modules/DiffusionImaging/DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp b/Modules/DiffusionImaging/DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp index 445f1de484..b89f252f2f 100644 --- a/Modules/DiffusionImaging/DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp +++ b/Modules/DiffusionImaging/DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp @@ -1,692 +1,680 @@ /*========================================================================= Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkSiemensDicomDiffusionImageHeaderReader.h" #include "gdcmGlobal.h" //#include -#if GDCM_MAJOR_VERSION >= 2 -#define DGDCM2 -#endif - -#ifndef DGDCM2 - -#include "gdcm.h" - -#else - #include "gdcmFile.h" #include "gdcmImageReader.h" #include "gdcmDictEntry.h" #include "gdcmDicts.h" #include "gdcmTag.h" -#endif - mitk::SiemensDicomDiffusionImageHeaderReader::SiemensDicomDiffusionImageHeaderReader() { } mitk::SiemensDicomDiffusionImageHeaderReader::~SiemensDicomDiffusionImageHeaderReader() { } int mitk::SiemensDicomDiffusionImageHeaderReader::ExtractSiemensDiffusionInformation( std::string tagString, std::string nameString, std::vector& valueArray, int startPos ) { std::string::size_type atPosition = tagString.find( nameString, startPos ); if ( atPosition == std::string::npos) { return 0; } else { std::string infoAsString = tagString.substr( atPosition, tagString.size()-atPosition+1 ); const char * infoAsCharPtr = infoAsString.c_str(); int vm = *(infoAsCharPtr+64); std::string vr = infoAsString.substr( 68, 4 ); //int syngodt = *(infoAsCharPtr+72); //int nItems = *(infoAsCharPtr+76); //int localDummy = *(infoAsCharPtr+80); int offset = 84; for (int k = 0; k < vm; k++) { int itemLength = *(infoAsCharPtr+offset+4); int strideSize = static_cast (ceil(static_cast(itemLength)/4) * 4); std::string valueString = infoAsString.substr( offset+16, itemLength ); valueArray.push_back( atof(valueString.c_str()) ); offset += 16+strideSize; } return vm; } } int mitk::SiemensDicomDiffusionImageHeaderReader::ExtractSiemensDiffusionGradientInformation( std::string tagString, std::string nameString, std::vector& valueArray ) { int nItems = 0; std::string::size_type pos = -1; while(nItems != 3) { nItems = ExtractSiemensDiffusionInformation( tagString, nameString, valueArray, pos+1 ); pos = tagString.find( nameString, pos+1 ); if ( pos == std::string::npos ) { break; } } return nItems; } // do the work void mitk::SiemensDicomDiffusionImageHeaderReader::Update() { // check if there are filenames if(m_DicomFilenames.size()) { 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; } } // adapted from slicer // DicomToNrrdConverter.cxx VolumeReaderType::DictionaryArrayRawPointer inputDict = m_VolumeReader->GetMetaDataDictionaryArray(); #ifndef DGDCM2 // relevant Siemens private tags gdcm::DictEntry SiemensDictBValue( 0x0019, 0x100c, "IS", "1", "B Value of diffusion weighting" ); gdcm::DictEntry SiemensDictDiffusionDirection( 0x0019, 0x100e, "FD", "3", "Diffusion Gradient Direction" ); gdcm::DictEntry SiemensDictDiffusionMatrix( 0x0019, 0x1027, "FD", "6", "Diffusion Matrix" ); gdcm::DictEntry SiemensDictShadowInfo( 0x0029, 0x1010, "OB", "1", "Siemens DWI Info" ); //if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensMosiacParameters.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensMosiacParameters); //if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictNMosiac.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictNMosiac); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictBValue.GetName())==0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictBValue); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictDiffusionDirection.GetName()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictDiffusionDirection); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictDiffusionMatrix.GetName()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictDiffusionMatrix); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictShadowInfo.GetName()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictShadowInfo); #else // gdcm::DictEntry SiemensDictBValue( "0019,100c", "B Value of diffusion weighting", gdcm::VR::IS, gdcm::VM::VM1 ); // gdcm::DictEntry SiemensDictDiffusionDirection( "0019,100e", "Diffusion Gradient Direction", gdcm::VR::FD, gdcm::VM::VM3 ); // gdcm::DictEntry SiemensDictDiffusionMatrix( "0019,1027", "Diffusion Matrix", gdcm::VR::FD, gdcm::VM::VM6 ); // gdcm::DictEntry SiemensDictShadowInfo( "0029,1010", "Siemens DWI Info", gdcm::VR::OB, gdcm::VM::VM1 ); // //if(gdcm::Global::GetInstance().GetDicts().GetPublicDict().GetDictEntry(gdcm::Tag(0x0019,0x100c)) == 0) // gdcm::Global::GetInstance().GetDicts().GetPublicDict().AddDictEntry(gdcm::Tag(0x0019,0x100c),SiemensDictBValue); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictDiffusionDirection.GetName()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictDiffusionDirection); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictDiffusionMatrix.GetName()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictDiffusionMatrix); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictShadowInfo.GetName()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictShadowInfo); #endif ReadPublicTags(); //int mMosaic; // number of raws in each mosaic block; //int nMosaic; // number of columns in each mosaic block float x0, y0, z0; float x1, y1, z1; std::string tag; tag.clear(); itk::ExposeMetaData ( *(*inputDict)[0], "0020|0032", tag ); sscanf( tag.c_str(), "%f\\%f\\%f", &x0, &y0, &z0 ); //MITK_INFO << "Slice 0: " << tag << std::endl; tag.clear(); // assume volume interleaving, i.e. the second dicom file stores // the second slice in the same volume as the first dicom file if((*inputDict).size() > 1) { itk::ExposeMetaData ( *(*inputDict)[1], "0020|0032", tag ); sscanf( tag.c_str(), "%f\\%f\\%f", &x1, &y1, &z1 ); //MITK_INFO << "Slice 1: " << tag << std::endl; x1 -= x0; y1 -= y0; z1 -= z0; x0 = x1*this->m_Output->xSlice + y1*this->m_Output->ySlice + z1*this->m_Output->zSlice; if (x0 < 0) { m_SliceOrderIS = false; } } ReadPublicTags2(); int nStride = 1; //MITK_INFO << orthoSliceSpacing << std::endl; this->m_Output->nSliceInVolume = m_sliceLocations.size(); //nVolume = nSlice/this->m_Output->nSliceInVolume; //MITK_INFO << "Number of Slices: " << m_nSlice << std::endl; //MITK_INFO << "Number of Volume: " << nVolume << std::endl; //MITK_INFO << "Number of Slices in each volume: " << this->m_Output->nSliceInVolume << std::endl; nStride = this->m_Output->nSliceInVolume; MITK_INFO << m_DicomFilenames[0] << std::endl; MITK_INFO << "Dims " << this->m_Output->nRows << "x" << this->m_Output->nCols << "x" << this->m_Output->nSliceInVolume << " " << std::endl; for (int k = 0; k < m_nSlice; k += nStride ) { #ifndef DGDCM2 gdcm::File *header0 = new gdcm::File; gdcm::BinEntry* binEntry; header0->SetMaxSizeLoadEntry(65536); header0->SetFileName( m_DicomFilenames[k] ); header0->SetLoadMode( gdcm::LD_ALL ); header0->Load(); // copy information stored in 0029,1010 into a string for parsing gdcm::DocEntry* docEntry = header0->GetFirstEntry(); while(docEntry) { if ( docEntry->GetKey() == "0029|1010" ) { binEntry = dynamic_cast ( docEntry ); int binLength = binEntry->GetFullLength(); tag.resize( binLength ); uint8_t * tagString = binEntry->GetBinArea(); for (int n = 0; n < binLength; n++) { tag[n] = *(tagString+n); } break; } docEntry = header0->GetNextEntry(); } #else gdcm::ImageReader reader; reader.SetFileName( m_DicomFilenames[k].c_str() ); if( !reader.Read() ) { itkExceptionMacro(<< "Cannot read requested file"); } const gdcm::File &f = reader.GetFile(); const gdcm::DataSet &ds = f.GetDataSet(); // gdcm::DataSet ds = header0->GetDataSet(); gdcm::DataSet::ConstIterator it = ds.Begin(); // Copy of the header->content // copy information stored in 0029,1010 into a string for parsing for(; it != ds.End(); ++it) { const gdcm::DataElement &ref = *it; if (ref.GetTag() == gdcm::Tag(0x0029,0x1010)) { tag = std::string(ref.GetByteValue()->GetPointer(),ref.GetByteValue()->GetLength()); } } #endif // parse B_value from 0029,1010 tag std::vector valueArray(0); vnl_vector_fixed vect3d; int nItems = ExtractSiemensDiffusionInformation(tag, "B_value", valueArray); if (nItems != 1 || valueArray[0] == 0) // did not find enough information { tag.clear(); MITK_INFO << "Reading diffusion info from 0019|100c and 0019|100e tags" << std::endl; bool success = false; #ifndef DGDCM2 success = itk::ExposeMetaData ( *(*inputDict)[0], "0019|100c", tag ); this->m_Output->bValue = atof( tag.c_str() ); #else for(it = ds.Begin(); it != ds.End(); ++it) { const gdcm::DataElement &ref = *it; if (ref.GetTag() == gdcm::Tag(0x0019,0x100c)) { tag = std::string(ref.GetByteValue()->GetPointer(),ref.GetByteValue()->GetLength()); this->m_Output->bValue = atof( tag.c_str() ); success = true; } } #endif tag.clear(); if(success) { if(this->m_Output->bValue == 0) { MITK_INFO << "BV: 0 (Baseline image)"; continue; } #ifndef DGDCM2 success = itk::ExposeMetaData ( *(*inputDict)[k], "0019|100e", tag); #else success = false; for(it = ds.Begin(); it != ds.End(); ++it) { const gdcm::DataElement &ref = *it; if (ref.GetTag() == gdcm::Tag(0x0019,0x100e)) { tag = std::string(ref.GetByteValue()->GetPointer(),ref.GetByteValue()->GetLength()); success = true; } } #endif if(success) { memcpy( &vect3d[0], tag.c_str()+0, 8 ); memcpy( &vect3d[1], tag.c_str()+8, 8 ); memcpy( &vect3d[2], tag.c_str()+16, 8 ); vect3d.normalize(); this->m_Output->DiffusionVector = vect3d; TransformGradients(); MITK_INFO << "BV: " << this->m_Output->bValue; MITK_INFO << " GD: " << this->m_Output->DiffusionVector; continue; } } } else { MITK_INFO << "Reading diffusion info from 0029,1010 tag" << std::endl; this->m_Output->bValue = valueArray[0]; if(this->m_Output->bValue == 0) { MITK_INFO << "BV: 0 (Baseline image)"; continue; } valueArray.resize(0); nItems = ExtractSiemensDiffusionGradientInformation(tag, "DiffusionGradientDirection", valueArray); if (nItems == 3) { vect3d[0] = valueArray[0]; vect3d[1] = valueArray[1]; vect3d[2] = valueArray[2]; vect3d.normalize(); this->m_Output->DiffusionVector = vect3d; TransformGradients(); MITK_INFO << "BV: " << this->m_Output->bValue; MITK_INFO << " GD: " << this->m_Output->DiffusionVector; continue; } } MITK_ERROR << "No diffusion info found, forcing to BASELINE image." << std::endl; this->m_Output->bValue = 0.0; vect3d.fill( 0.0 ); this->m_Output->DiffusionVector = vect3d; } 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; } } } //header = new mitk::DWIHeader(nRows, nCols, xRes, yRes, xOrigin,yOrigin, // zOrigin, sliceThickness, sliceSpacing,nSliceInVolume, xRow, yRow, // zRow, xCol,yCol, zCol, xSlice, ySlice, zSlice,bValues[0], DiffusionVectors[0], // vendor,SliceMosaic); // //// do the work //void DicomDiffusionImageHeaderReader::Update() //{ // // // check if there are filenames // if(m_DicomFilenames.IsNotNull() // && m_DicomFilenames->size() > 0) // { // // adapted from namic-sandbox // // DicomToNrrdConverter.cxx // // bool SliceOrderIS = true; // bool SingleSeries = true; // // VolumeReaderType::DictionaryArrayRawPointer inputDict // = m_VolumeReader->GetMetaDataDictionaryArray(); // // if ( vendor.find("GE") != std::string::npos ) // { // // for GE data // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GEDictBValue.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(GEDictBValue); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GEDictXGradient.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(GEDictXGradient); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GEDictYGradient.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(GEDictYGradient); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(GEDictZGradient.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(GEDictZGradient); // } // else if( vendor.find("SIEMENS") != std::string::npos ) // { // // for Siemens data // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensMosiacParameters.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensMosiacParameters); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictNMosiac.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictNMosiac); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictBValue.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictBValue); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictDiffusionDirection.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictDiffusionDirection); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictDiffusionMatrix.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictDiffusionMatrix); // if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictShadowInfo.GetKey()) == 0) // gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictShadowInfo); // // } // else if( vendor.find("PHILIPS") != std::string::npos ) // { // // for philips data // } // else // { // std::cerr << "Unrecognized vendor.\n" << std::endl; // } // // ReadPublicTags(); // // int mMosaic; // number of raws in each mosaic block; // int nMosaic; // number of columns in each mosaic block // int nSliceInVolume; // // // figure out slice order and mosaic arrangement. // if ( vendor.find("GE") != std::string::npos || // (vendor.find("SIEMENS") != std::string::npos && !SliceMosaic) ) // { // float x0, y0, z0; // float x1, y1, z1; // tag.clear(); // itk::ExposeMetaData ( *(*inputDict)[0], "0020|0032", tag ); // sscanf( tag.c_str(), "%f\\%f\\%f", &x0, &y0, &z0 ); // MITK_INFO << "Slice 0: " << tag << std::endl; // tag.clear(); // // // assume volume interleaving, i.e. the second dicom file stores // // the second slice in the same volume as the first dicom file // itk::ExposeMetaData ( *(*inputDict)[1], "0020|0032", tag ); // sscanf( tag.c_str(), "%f\\%f\\%f", &x1, &y1, &z1 ); // MITK_INFO << "Slice 1: " << tag << std::endl; // x1 -= x0; y1 -= y0; z1 -= z0; // x0 = x1*xSlice + y1*ySlice + z1*zSlice; // if (x0 < 0) // { // SliceOrderIS = false; // } // } // else if ( vendor.find("SIEMENS") != std::string::npos && SliceMosaic ) // { // MITK_INFO << "Siemens SliceMosaic......" << std::endl; // // SliceOrderIS = false; // // // for siemens mosaic image, figure out mosaic slice order from 0029|1010 // tag.clear(); // gdcm::File *header0 = new gdcm::File; // gdcm::BinEntry* binEntry; // // header0->SetMaxSizeLoadEntry(65536); // header0->SetFileName( filenames[0] ); // header0->SetLoadMode( gdcm::LD_ALL ); // header0->Load(); // // // copy information stored in 0029,1010 into a string for parsing // gdcm::DocEntry* docEntry = header0->GetFirstEntry(); // while(docEntry) // { // if ( docEntry->GetKey() == "0029|1010" ) // { // binEntry = dynamic_cast ( docEntry ); // int binLength = binEntry->GetFullLength(); // tag.resize( binLength ); // uint8_t * tagString = binEntry->GetBinArea(); // // for (int k = 0; k < binLength; k++) // { // tag[k] = *(tagString+k); // } // break; // } // docEntry = header0->GetNextEntry(); // } // // // parse SliceNormalVector from 0029,1010 tag // std::vector valueArray(0); // int nItems = ExtractSiemensDiffusionInformation(tag, "SliceNormalVector", valueArray); // if (nItems != 3) // did not find enough information // { // MITK_INFO << "Warning: Cannot find complete information on SliceNormalVector in 0029|1010\n"; // MITK_INFO << " Slice order may be wrong.\n"; // } // else if (valueArray[2] > 0) // { // SliceOrderIS = true; // } // // // parse NumberOfImagesInMosaic from 0029,1010 tag // valueArray.resize(0); // nItems = ExtractSiemensDiffusionInformation(tag, "NumberOfImagesInMosaic", valueArray); // if (nItems == 0) // did not find enough information // { // MITK_INFO << "Warning: Cannot find complete information on NumberOfImagesInMosaic in 0029|1010\n"; // MITK_INFO << " Resulting image may contain empty slices.\n"; // } // else // { // nSliceInVolume = static_cast(valueArray[0]); // mMosaic = static_cast (ceil(sqrt(valueArray[0]))); // nMosaic = mMosaic; // } // MITK_INFO << "Mosaic in " << mMosaic << " X " << nMosaic << " blocks (total number of blocks = " << valueArray[0] << ").\n"; // } // else // { // } // // ReadPublicTags2(); // // //////////////////////////////////////////////////////////// // // vendor dependent tags. // // read in gradient vectors and determin nBaseline and nMeasurement // // if ( vendor.find("GE") != std::string::npos ) // { // nSliceInVolume = sliceLocations.size(); // nVolume = nSlice/nSliceInVolume; // // // assume volume interleaving // MITK_INFO << "Number of Slices: " << nSlice << std::endl; // MITK_INFO << "Number of Volume: " << nVolume << std::endl; // MITK_INFO << "Number of Slices in each volume: " << nSliceInVolume << std::endl; // // for (int k = 0; k < nSlice; k += nSliceInVolume) // { // tag.clear(); // bool exist = itk::ExposeMetaData ( *(*inputDict)[k], "0043|1039", tag); // float b = atof( tag.c_str() ); // bValues.push_back(b); // // vnl_vector_fixed vect3d; // if (!exist || b == 0) // { // vect3d.fill( 0 ); // DiffusionVectors.push_back(vect3d); // DiffusionVectorsOrig.push_back(vect3d); // continue; // } // // vect3d.fill( 0 ); // tag.clear(); // itk::ExposeMetaData ( *(*inputDict)[k], "0019|10bb", tag); // vect3d[0] = atof( tag.c_str() ); // // tag.clear(); // itk::ExposeMetaData ( *(*inputDict)[k], "0019|10bc", tag); // vect3d[1] = atof( tag.c_str() ); // // tag.clear(); // itk::ExposeMetaData ( *(*inputDict)[k], "0019|10bd", tag); // vect3d[2] = atof( tag.c_str() ); // // DiffusionVectorsOrig.push_back(vect3d); // vect3d.normalize(); // DiffusionVectors.push_back(vect3d); // } // } // else if ( vendor.find("SIEMENS") != std::string::npos ) // { // // int nStride = 1; // if ( !SliceMosaic ) // { // MITK_INFO << orthoSliceSpacing << std::endl; // nSliceInVolume = sliceLocations.size(); // nVolume = nSlice/nSliceInVolume; // MITK_INFO << "Number of Slices: " << nSlice << std::endl; // MITK_INFO << "Number of Volume: " << nVolume << std::endl; // MITK_INFO << "Number of Slices in each volume: " << nSliceInVolume << std::endl; // nStride = nSliceInVolume; // } // else // { // MITK_INFO << "Data in Siemens Mosaic Format\n"; // nVolume = nSlice; // MITK_INFO << "Number of Volume: " << nVolume << std::endl; // MITK_INFO << "Number of Slices in each volume: " << nSliceInVolume << std::endl; // nStride = 1; // } // // // for (int k = 0; k < nSlice; k += nStride ) // { // // gdcm::File *header0 = new gdcm::File; // gdcm::BinEntry* binEntry; // // header0->SetMaxSizeLoadEntry(65536); // header0->SetFileName( filenames[k] ); // header0->SetLoadMode( gdcm::LD_ALL ); // header0->Load(); // // // copy information stored in 0029,1010 into a string for parsing // gdcm::DocEntry* docEntry = header0->GetFirstEntry(); // while(docEntry) // { // if ( docEntry->GetKey() == "0029|1010" ) // { // binEntry = dynamic_cast ( docEntry ); // int binLength = binEntry->GetFullLength(); // tag.resize( binLength ); // uint8_t * tagString = binEntry->GetBinArea(); // // for (int n = 0; n < binLength; n++) // { // tag[n] = *(tagString+n); // } // break; // } // docEntry = header0->GetNextEntry(); // } // // // parse B_value from 0029,1010 tag // std::vector valueArray(0); // vnl_vector_fixed vect3d; // int nItems = ExtractSiemensDiffusionInformation(tag, "B_value", valueArray); // if (nItems != 1 || valueArray[0] == 0) // did not find enough information // { // MITK_INFO << "Warning: Cannot find complete information on B_value in 0029|1010\n"; // bValues.push_back( 0.0 ); // vect3d.fill( 0.0 ); // DiffusionVectors.push_back(vect3d); // DiffusionVectorsOrig.push_back(vect3d); // continue; // } // else // { // bValues.push_back( valueArray[0] ); // } // // // parse DiffusionGradientDirection from 0029,1010 tag // valueArray.resize(0); // nItems = ExtractSiemensDiffusionInformation(tag, "DiffusionGradientDirection", valueArray); // if (nItems != 3) // did not find enough information // { // MITK_INFO << "Warning: Cannot find complete information on DiffusionGradientDirection in 0029|1010\n"; // vect3d.fill( 0 ); // DiffusionVectors.push_back(vect3d); // DiffusionVectorsOrig.push_back(vect3d); // } // else // { // vect3d[0] = valueArray[0]; // vect3d[1] = valueArray[1]; // vect3d[2] = valueArray[2]; // DiffusionVectorsOrig.push_back(vect3d); // vect3d.normalize(); // DiffusionVectors.push_back(vect3d); // int p = bValues.size(); // MITK_INFO << "Image#: " << k << " BV: " << bValues[p-1] << " GD: " << DiffusionVectors[p-1] << std::endl; // } // } // } // else // { // } // // TransformGradients(); // // /////////////////////////////////////////////// // // construct header info // // header = new mitk::DWIHeader(nRows, nCols, xRes, yRes, xOrigin,yOrigin, // zOrigin, sliceThickness, sliceSpacing,nSliceInVolume, xRow, yRow, // zRow, xCol,yCol, zCol, xSlice, ySlice, zSlice,bValues[0], DiffusionVectors[0], // vendor,SliceMosaic); // // // set m_Output // // } // //} // diff --git a/Modules/DiffusionImaging/DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp b/Modules/DiffusionImaging/DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp index 53cab78a25..85351ae92b 100644 --- a/Modules/DiffusionImaging/DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp +++ b/Modules/DiffusionImaging/DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp @@ -1,342 +1,322 @@ /*========================================================================= Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkSiemensMosaicDicomDiffusionImageHeaderReader.h" #include "gdcmGlobal.h" //#include "gdcmVersion.h" -#if GDCM_MAJOR_VERSION >= 2 -#define DGDCM2 -#endif - -#ifndef DGDCM2 - -#include "gdcm.h" - -// relevant Siemens private tags -const gdcm::DictEntry SiemensMosiacParameters( 0x0051, 0x100b, "IS", "1", "Mosiac Matrix Size" ); -const gdcm::DictEntry SiemensDictNMosiac( 0x0019, 0x100a, "US", "1", "Number of Images In Mosaic" ); -const gdcm::DictEntry SiemensDictBValue( 0x0019, 0x100c, "IS", "1", "B Value of diffusion weighting" ); -const gdcm::DictEntry SiemensDictDiffusionDirection( 0x0019, 0x100e, "FD", "3", "Diffusion Gradient Direction" ); -const gdcm::DictEntry SiemensDictDiffusionMatrix( 0x0019, 0x1027, "FD", "6", "Diffusion Matrix" ); -const gdcm::DictEntry SiemensDictShadowInfo( 0x0029, 0x1010, "OB", "1", "Siemens DWI Info" ); - -#else - #include "gdcmFile.h" #include "gdcmImageReader.h" #include "gdcmDict.h" #include "gdcmDicts.h" #include "gdcmDictEntry.h" #include "gdcmDictEntry.h" #include "gdcmDict.h" #include "gdcmFile.h" #include "gdcmSerieHelper.h" -#endif - mitk::SiemensMosaicDicomDiffusionImageHeaderReader::SiemensMosaicDicomDiffusionImageHeaderReader() { } mitk::SiemensMosaicDicomDiffusionImageHeaderReader::~SiemensMosaicDicomDiffusionImageHeaderReader() { } int mitk::SiemensMosaicDicomDiffusionImageHeaderReader::ExtractSiemensDiffusionInformation( std::string tagString, std::string nameString, std::vector& valueArray ) { std::string::size_type atPosition = tagString.find( nameString ); if ( atPosition == std::string::npos) { return 0; } else { std::string infoAsString = tagString.substr( atPosition, tagString.size()-atPosition+1 ); const char * infoAsCharPtr = infoAsString.c_str(); int vm = *(infoAsCharPtr+64); std::string vr = infoAsString.substr( 68, 4 ); //int syngodt = *(infoAsCharPtr+72); //int nItems = *(infoAsCharPtr+76); //int localDummy = *(infoAsCharPtr+80); int offset = 84; for (int k = 0; k < vm; k++) { int itemLength = *(infoAsCharPtr+offset+4); int strideSize = static_cast (ceil(static_cast(itemLength)/4) * 4); std::string valueString = infoAsString.substr( offset+16, itemLength ); valueArray.push_back( atof(valueString.c_str()) ); offset += 16+strideSize; } return vm; } } // do the work void mitk::SiemensMosaicDicomDiffusionImageHeaderReader::Update() { // check if there are filenames if(m_DicomFilenames.size()) { // adapted from namic-sandbox // DicomToNrrdConverter.cxx VolumeReaderType::DictionaryArrayRawPointer inputDict = m_VolumeReader->GetMetaDataDictionaryArray(); #ifndef DGDCM2 if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensMosiacParameters.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensMosiacParameters); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictNMosiac.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictNMosiac); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictBValue.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictBValue); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictDiffusionDirection.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictDiffusionDirection); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictDiffusionMatrix.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictDiffusionMatrix); if(gdcm::Global::GetDicts()->GetDefaultPubDict()->GetEntry(SiemensDictShadowInfo.GetKey()) == 0) gdcm::Global::GetDicts()->GetDefaultPubDict()->AddEntry(SiemensDictShadowInfo); #endif ReadPublicTags(); int mMosaic = 0; // number of raws in each mosaic block; int nMosaic = 0; // number of columns in each mosaic block std::cout << "Siemens SliceMosaic......" << std::endl; m_SliceOrderIS = false; // for siemens mosaic image, figure out mosaic slice order from 0029|1010 std::string tag; tag.clear(); #ifndef DGDCM2 gdcm::File *header0 = new gdcm::File; gdcm::BinEntry* binEntry; header0->SetMaxSizeLoadEntry(65536); header0->SetFileName( m_DicomFilenames[0] ); header0->SetLoadMode( gdcm::LD_ALL ); header0->Load(); // copy information stored in 0029,1010 into a string for parsing gdcm::DocEntry* docEntry = header0->GetFirstEntry(); while(docEntry) { if ( docEntry->GetKey() == "0029|1010" ) { binEntry = dynamic_cast ( docEntry ); int binLength = binEntry->GetFullLength(); tag.resize( binLength ); uint8_t * tagString = binEntry->GetBinArea(); for (int n = 0; n < binLength; n++) { tag[n] = *(tagString+n); } break; } docEntry = header0->GetNextEntry(); } #else gdcm::ImageReader reader; reader.SetFileName( m_DicomFilenames[0].c_str() ); if( !reader.Read() ) { itkExceptionMacro(<< "Cannot read requested file"); } const gdcm::File &f = reader.GetFile(); const gdcm::DataSet &ds = f.GetDataSet(); // gdcm::DataSet ds = header0->GetDataSet(); gdcm::DataSet::ConstIterator it = ds.Begin(); // Copy of the header->content // copy information stored in 0029,1010 into a string for parsing for(; it != ds.End(); ++it) { const gdcm::DataElement &ref = *it; if (ref.GetTag() == gdcm::Tag(0x0029,0x1010)) { tag = std::string(ref.GetByteValue()->GetPointer(),ref.GetByteValue()->GetLength()); } } #endif // parse SliceNormalVector from 0029,1010 tag std::vector valueArray(0); int nItems = ExtractSiemensDiffusionInformation(tag, "SliceNormalVector", valueArray); if (nItems != 3) // did not find enough information { std::cout << "Warning: Cannot find complete information on SliceNormalVector in 0029|1010\n"; std::cout << " Slice order may be wrong.\n"; } else if (valueArray[2] > 0) { m_SliceOrderIS = true; } // parse NumberOfImagesInMosaic from 0029,1010 tag valueArray.resize(0); nItems = ExtractSiemensDiffusionInformation(tag, "NumberOfImagesInMosaic", valueArray); if (nItems == 0) // did not find enough information { std::cout << "Warning: Cannot find complete information on NumberOfImagesInMosaic in 0029|1010\n"; std::cout << " Resulting image may contain empty slices.\n"; } else { this->m_Output->nSliceInVolume = static_cast(valueArray[0]); mMosaic = static_cast (ceil(sqrt(valueArray[0]))); nMosaic = mMosaic; } std::cout << "Mosaic in " << mMosaic << " X " << nMosaic << " blocks (total number of blocks = " << valueArray[0] << ").\n"; ReadPublicTags2(); int nStride = 1; std::cout << "Data in Siemens Mosaic Format\n"; //nVolume = nSlice; //std::cout << "Number of Volume: " << nVolume << std::endl; std::cout << "Number of Slices in each volume: " << this->m_Output->nSliceInVolume << std::endl; nStride = 1; for (int k = 0; k < m_nSlice; k += nStride ) { #ifndef DGDCM2 gdcm::File *header0 = new gdcm::File; gdcm::BinEntry* binEntry; header0->SetMaxSizeLoadEntry(65536); header0->SetFileName( m_DicomFilenames[0] ); header0->SetLoadMode( gdcm::LD_ALL ); header0->Load(); // copy information stored in 0029,1010 into a string for parsing gdcm::DocEntry* docEntry = header0->GetFirstEntry(); while(docEntry) { if ( docEntry->GetKey() == "0029|1010" ) { binEntry = dynamic_cast ( docEntry ); int binLength = binEntry->GetFullLength(); tag.resize( binLength ); uint8_t * tagString = binEntry->GetBinArea(); for (int n = 0; n < binLength; n++) { tag[n] = *(tagString+n); } break; } docEntry = header0->GetNextEntry(); } #else gdcm::ImageReader reader; reader.SetFileName( m_DicomFilenames[0].c_str() ); if( !reader.Read() ) { itkExceptionMacro(<< "Cannot read requested file"); } const gdcm::File &f = reader.GetFile(); const gdcm::DataSet &ds = f.GetDataSet(); // gdcm::DataSet ds = header0->GetDataSet(); gdcm::DataSet::ConstIterator it = ds.Begin(); // Copy of the header->content // copy information stored in 0029,1010 into a string for parsing for(; it != ds.End(); ++it) { const gdcm::DataElement &ref = *it; if (ref.GetTag() == gdcm::Tag(0x0029,0x1010)) { tag = std::string(ref.GetByteValue()->GetPointer(),ref.GetByteValue()->GetLength()); } } #endif // parse B_value from 0029,1010 tag std::vector valueArray(0); vnl_vector_fixed vect3d; int nItems = ExtractSiemensDiffusionInformation(tag, "B_value", valueArray); if (nItems != 1 || valueArray[0] == 0) // did not find enough information { MITK_INFO << "Reading diffusion info from 0019|100c and 0019|100e tags"; tag.clear(); bool success = itk::ExposeMetaData ( *(*inputDict)[0], "0019|100c", tag ); if(success) { this->m_Output->bValue = atof( tag.c_str() ); tag.clear(); success = itk::ExposeMetaData ( *(*inputDict)[k], "0019|100e", tag); if(success) { memcpy( &vect3d[0], tag.c_str()+0, 8 ); memcpy( &vect3d[1], tag.c_str()+8, 8 ); memcpy( &vect3d[2], tag.c_str()+16, 8 ); vect3d.normalize(); this->m_Output->DiffusionVector = vect3d; TransformGradients(); MITK_INFO << "BV: " << this->m_Output->bValue; MITK_INFO << " GD: " << this->m_Output->DiffusionVector << std::endl; continue; } } } else { MITK_INFO << "Reading diffusion info from 0029|1010 tags"; this->m_Output->bValue = valueArray[0]; // parse DiffusionGradientDirection from 0029,1010 tag valueArray.resize(0); nItems = ExtractSiemensDiffusionInformation(tag, "DiffusionGradientDirection", valueArray); if (nItems == 3) { vect3d[0] = valueArray[0]; vect3d[1] = valueArray[1]; vect3d[2] = valueArray[2]; vect3d.normalize(); this->m_Output->DiffusionVector = vect3d; TransformGradients(); MITK_INFO << "BV: " << this->m_Output->bValue; MITK_INFO << " GD: " << this->m_Output->DiffusionVector; continue; } } MITK_ERROR << "No diffusion info found, assuming BASELINE" << std::endl; this->m_Output->bValue = 0.0; vect3d.fill( 0.0 ); this->m_Output->DiffusionVector = vect3d; } } }