From f8ad682c6c916a31d082591d744007411639794c Mon Sep 17 00:00:00 2001 From: tbaudier Date: Mon, 15 May 2017 15:33:00 +0200 Subject: [PATCH] Add GateSimulation2Dicom tool --- tools/CMakeLists.txt | 14 +- tools/clitkGateSimulation2Dicom.cxx | 53 +++ tools/clitkGateSimulation2Dicom.ggo | 17 + ...clitkGateSimulation2DicomGenericFilter.cxx | 39 ++ .../clitkGateSimulation2DicomGenericFilter.h | 121 +++++ ...clitkGateSimulation2DicomGenericFilter.txx | 430 ++++++++++++++++++ 6 files changed, 672 insertions(+), 2 deletions(-) create mode 100644 tools/clitkGateSimulation2Dicom.cxx create mode 100644 tools/clitkGateSimulation2Dicom.ggo create mode 100644 tools/clitkGateSimulation2DicomGenericFilter.cxx create mode 100644 tools/clitkGateSimulation2DicomGenericFilter.h create mode 100644 tools/clitkGateSimulation2DicomGenericFilter.txx diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index f2cc79c..96330d7 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -99,6 +99,16 @@ if(CLITK_BUILD_TOOLS) target_link_libraries(clitkWriteDicomSeries clitkCommon ) set(TOOLS_INSTALL ${TOOLS_INSTALL} clitkWriteDicomSeries) + WRAP_GGO(clitkGateSimulation2Dicom_GGO_C clitkGateSimulation2Dicom.ggo) + add_executable(clitkGateSimulation2Dicom clitkGateSimulation2Dicom.cxx ${clitkGateSimulation2Dicom_GGO_C}) + target_link_libraries(clitkGateSimulation2Dicom clitkCommon ) + set(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGateSimulation2Dicom) + + WRAP_GGO(clitkImage2DicomSeries_GGO_C clitkImage2DicomSeries.ggo) + add_executable(clitkImage2DicomSeries clitkImage2DicomSeries.cxx ${clitkImage2DicomSeries_GGO_C}) + target_link_libraries(clitkImage2DicomSeries clitkCommon ) + set(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImage2DicomSeries) + WRAP_GGO(clitkMedianTemporalDimension_GGO_C clitkMedianTemporalDimension.ggo) add_executable(clitkMedianTemporalDimension clitkMedianTemporalDimension.cxx ${clitkMedianTemporalDimension_GGO_C}) @@ -187,11 +197,11 @@ if(CLITK_BUILD_TOOLS) target_link_libraries(clitkDicomRTStruct2Image clitkDicomRTStruct) set(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicomRTStruct2Image) - if(CLITK_USE_SYSTEM_GDCM) + #if(CLITK_USE_SYSTEM_GDCM) WRAP_GGO(clitkImage2DicomRTStruct_GGO_C clitkImage2DicomRTStruct.ggo) add_executable(clitkImage2DicomRTStruct clitkImage2DicomRTStruct.cxx ${clitkImage2DicomRTStruct_GGO_C}) target_link_libraries(clitkImage2DicomRTStruct clitkDicomRTStruct) - endif() + #endif() WRAP_GGO(clitkComposeVF_GGO_C clitkComposeVF.ggo) add_executable(clitkComposeVF clitkComposeVFGenericFilter.cxx clitkComposeVF.cxx ${clitkComposeVF_GGO_C}) diff --git a/tools/clitkGateSimulation2Dicom.cxx b/tools/clitkGateSimulation2Dicom.cxx new file mode 100644 index 0000000..bf9cc01 --- /dev/null +++ b/tools/clitkGateSimulation2Dicom.cxx @@ -0,0 +1,53 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ + +/* ================================================= + * @file clitkGateSimulation2Dicom.cxx + * @author Jef Vandemeulebroucke + * @date 4th of August + * + * @brief Write a volume into a dicom with the header of another dicom + * + ===================================================*/ + + +// clitk +#include "clitkGateSimulation2Dicom_ggo.h" +#include "clitkIO.h" +#include "clitkGateSimulation2DicomGenericFilter.h" +#include "clitkCommon.h" + +//-------------------------------------------------------------------- +int main(int argc, char * argv[]) +{ + + // Init command line + GGO(clitkGateSimulation2Dicom, args_info); + CLITK_INIT; + + // Filter + typedef clitk::GateSimulation2DicomGenericFilter FilterType; + FilterType::Pointer genericFilter = FilterType::New(); + + genericFilter->SetArgsInfo(args_info); + genericFilter->Update(); + + return EXIT_SUCCESS; +}// end main + +//-------------------------------------------------------------------- diff --git a/tools/clitkGateSimulation2Dicom.ggo b/tools/clitkGateSimulation2Dicom.ggo new file mode 100644 index 0000000..563fb3d --- /dev/null +++ b/tools/clitkGateSimulation2Dicom.ggo @@ -0,0 +1,17 @@ +#File clitkGateSimulation2Dicom.ggo +package "clitkGateSimulation2Dicom" +version "1.0" +purpose "" + +option "config" - "Config file" string no +option "verbose" v "Verbose" flag off + +option "input" i "Input image filename" string yes +option "inputDir" d "Input dicom directory" string yes +option "outputDir" o "Output dicom directory" string yes +option "key" k "Keys of tags to modify" string no multiple default="0008|103e" +option "tag" t "Tags values" string no multiple default="MIDPOSITION" +option "newSeriesUID" e "Write the series with a new series UID (ignored if given in key/tag option)" flag off +option "newStudyUID" u "Write the series with a new study UID (ignored if given in key/tag option; forces newSeriesUID = true)" flag off +option "useSizeAsReference" s "Use the size of the dicom image as reference for an occasional resampling" flag off +option "preserve" p "Preserve private tags and keep original UID (eg: Xio)" flag off diff --git a/tools/clitkGateSimulation2DicomGenericFilter.cxx b/tools/clitkGateSimulation2DicomGenericFilter.cxx new file mode 100644 index 0000000..e7cdd2f --- /dev/null +++ b/tools/clitkGateSimulation2DicomGenericFilter.cxx @@ -0,0 +1,39 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ +#ifndef clitkGateSimulation2DicomGenericFilter_cxx +#define clitkGateSimulation2DicomGenericFilter_cxx + +/* ================================================= + * @file clitkGateSimulation2DicomGenericFilter.cxx + * @author + * @date + * + * @brief + * + ===================================================*/ + +#include "clitkGateSimulation2DicomGenericFilter.h" + + +namespace clitk +{ + + +} //end clitk + +#endif //#define clitkGateSimulation2DicomGenericFilter_cxx diff --git a/tools/clitkGateSimulation2DicomGenericFilter.h b/tools/clitkGateSimulation2DicomGenericFilter.h new file mode 100644 index 0000000..d495209 --- /dev/null +++ b/tools/clitkGateSimulation2DicomGenericFilter.h @@ -0,0 +1,121 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ +#ifndef clitkGateSimulation2DicomGenericFilter_h +#define clitkGateSimulation2DicomGenericFilter_h + +/* ================================================= + * @file clitkGateSimulation2DicomGenericFilter.h + * @author + * @date + * + * @brief + * + ===================================================*/ + + +// clitk include +#include "clitkIO.h" +#include "clitkImageCommon.h" +#include "clitkGateSimulation2Dicom_ggo.h" + +//itk include +#include "itkLightObject.h" +#include "itkGDCMImageIO.h" +#include "itkMetaDataDictionary.h" +#include "itkGDCMSeriesFileNames.h" +#include "itkImageSeriesReader.h" +#include "itkImageSeriesWriter.h" +#include "itkImageFileWriter.h" +#include +#include + +namespace clitk +{ + template + class ITK_EXPORT GateSimulation2DicomGenericFilter : public itk::LightObject + { + public: + //---------------------------------------- + // ITK + //---------------------------------------- + typedef GateSimulation2DicomGenericFilter Self; + typedef itk::LightObject Superclass; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer ConstPointer; + + // Method for creation through the object factory + itkNewMacro(Self); + + // Run-time type information (and related methods) + itkTypeMacro( GateSimulation2DicomGenericFilter, LightObject ); + + + //---------------------------------------- + // Typedefs + //---------------------------------------- + + + //---------------------------------------- + // Set & Get + //---------------------------------------- + void SetArgsInfo(const args_info_type & a) + { + m_ArgsInfo=a; + m_Verbose=m_ArgsInfo.verbose_flag; + m_InputFileName=m_ArgsInfo.input_arg; + } + + + //---------------------------------------- + // Update + //---------------------------------------- + void Update(); + + protected: + + //---------------------------------------- + // Constructor & Destructor + //---------------------------------------- + GateSimulation2DicomGenericFilter(); + ~GateSimulation2DicomGenericFilter() {}; + + + //---------------------------------------- + // Templated members + //---------------------------------------- + template void UpdateWithDim(std::string PixelType); + template void UpdateWithDimAndPixelType(); + + + //---------------------------------------- + // Data members + //---------------------------------------- + args_info_type m_ArgsInfo; + bool m_Verbose; + std::string m_InputFileName; + + }; + + +} // end namespace clitk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "clitkGateSimulation2DicomGenericFilter.txx" +#endif + +#endif // #define clitkGateSimulation2DicomGenericFilter_h diff --git a/tools/clitkGateSimulation2DicomGenericFilter.txx b/tools/clitkGateSimulation2DicomGenericFilter.txx new file mode 100644 index 0000000..ce1c1e3 --- /dev/null +++ b/tools/clitkGateSimulation2DicomGenericFilter.txx @@ -0,0 +1,430 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ +#ifndef clitkGateSimulation2DicomGenericFilter_txx +#define clitkGateSimulation2DicomGenericFilter_txx + +/* ================================================= + * @file clitkGateSimulation2DicomGenericFilter.txx + * @author + * @date + * + * @brief + * + ===================================================*/ + +// clitk +#include "clitkResampleImageWithOptionsFilter.h" +#if GDCM_MAJOR_VERSION >= 2 +#include "gdcmUIDGenerator.h" +#else +#include "gdcmFile.h" +#include "gdcmUtil.h" +#endif + + +namespace clitk +{ + + +//----------------------------------------------------------- +// Constructor +//----------------------------------------------------------- +template +GateSimulation2DicomGenericFilter::GateSimulation2DicomGenericFilter() +{ + m_Verbose=false; + m_InputFileName=""; +} + + +//----------------------------------------------------------- +// Update +//----------------------------------------------------------- +template +void GateSimulation2DicomGenericFilter::Update() +{ + // Read the Dimension and PixelType + int Dimension; + std::string PixelType; + ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType); + + + // Call UpdateWithDim + if(Dimension==2) UpdateWithDim<2>(PixelType); + else if(Dimension==3) UpdateWithDim<3>(PixelType); + // else if (Dimension==4)UpdateWithDim<4>(PixelType); + else { + std::cout<<"Error, Only for 2 or 3 Dimensions!!!"< +template +void +GateSimulation2DicomGenericFilter::UpdateWithDim(std::string PixelType) +{ + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + else if(PixelType == "unsigned_short"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + UpdateWithDimAndPixelType(); + } + + else if (PixelType == "unsigned_char") { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else if (PixelType == "double") { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and double..." << std::endl; + UpdateWithDimAndPixelType(); + } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } +} + +//------------------------------------------------------------------- +// Update with the number of dimensions and the pixeltype read from +// the dicom files. The MHD files may be resampled to match the +// dicom spacing (and number of slices). Rounding errors in resampling +// are handled by removing files when generating the output dicom +// series. +//------------------------------------------------------------------- +template +template +void +GateSimulation2DicomGenericFilter::UpdateWithDimAndPixelType() +{ + + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image OutputImageType; + + // Read the dicom directory + typedef itk::ImageSeriesReader< InputImageType > ReaderType; + typedef itk::GDCMImageIO ImageIOType; + typedef itk::GDCMSeriesFileNames NamesGeneratorType; + + ImageIOType::Pointer gdcmIO = ImageIOType::New(); + NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New(); + namesGenerator->SetInputDirectory( m_ArgsInfo.inputDir_arg ); + namesGenerator->SetOutputDirectory( m_ArgsInfo.outputDir_arg ); + typename ReaderType::FileNamesContainer filenames_in = namesGenerator->GetInputFileNames(); + typename ReaderType::FileNamesContainer filenames_out = namesGenerator->GetOutputFileNames(); + + // Output the dicom files + unsigned int numberOfFilenames = filenames_in.size(); + if (m_Verbose) { + std::cout << numberOfFilenames <<" were read in the directory "< InputReaderType; + typename InputReaderType::Pointer volumeReader = InputReaderType::New(); + volumeReader->SetFileName( m_InputFileName); + volumeReader->Update(); + + typename InputImageType::Pointer input = volumeReader->GetOutput(); + if ((!m_ArgsInfo.useSizeAsReference_flag && (input->GetSpacing() != reader->GetOutput()->GetSpacing())) || + (m_ArgsInfo.useSizeAsReference_flag && (input->GetLargestPossibleRegion().GetSize() != reader->GetOutput()->GetLargestPossibleRegion().GetSize()))) { + + // resampling is carried out on the fly if resolution or size between + // the input mhd and input dicom series is different + + // Filter + typedef clitk::ResampleImageWithOptionsFilter ResampleImageFilterType; + typename ResampleImageFilterType::Pointer filter = ResampleImageFilterType::New(); + filter->SetInput(input); + filter->SetVerboseOptions(m_Verbose); + filter->SetGaussianFilteringEnabled(false); + filter->SetDefaultPixelValue(0); + + if (!m_ArgsInfo.useSizeAsReference_flag) { + filter->SetOutputSpacing(input->GetSpacing()); + if (m_Verbose) { + std::cout << "Warning: The image spacing differs between the MHD file and the input dicom series. Performing resampling with default options using spacing as reference (for advanced options, use clitkResampleImage)." << std::endl; + std::cout << "MHD -> " << input->GetSpacing() << std::endl; + std::cout << "dicom -> " << reader->GetOutput()->GetSpacing() << std::endl; + } + } + else { + const SizeType& dicom_size = reader->GetOutput()->GetLargestPossibleRegion().GetSize(); + SizeType output_size; + for (unsigned int i = 0; i < Dimension; i++) + output_size[i] = dicom_size[i]; + filter->SetOutputSize(output_size); + if (m_Verbose) { + std::cout << "Warning: The image size differs between the MHD file and the input dicom series. Performing resampling with default options using size as reference (for advanced options, use clitkResampleImage)." << std::endl; + std::cout << "MHD -> " << input->GetLargestPossibleRegion().GetSize() << std::endl; + std::cout << "dicom -> " << reader->GetOutput()->GetLargestPossibleRegion().GetSize() << std::endl; + } + } + + try { + filter->Update(); + input = filter->GetOutput(); + } catch( itk::ExceptionObject & excp ) { + std::cerr << "Error: Exception thrown while resampling!!" << std::endl; + std::cerr << excp << std::endl; + } + } + std::cout << "RESAMPING FILTER DONE" << std::endl; + + // In some cases, due to resampling approximation issues, + // the number of slices in the MHD file may be different (smaller) + // from the number of files in the template dicom directory. + // To avoid ITK generating an exception, we reduce the number + // of DCM files to be considered, and a warning is printed + // in verbose mode + const RegionType volumeRegion = input->GetLargestPossibleRegion(); + const SizeType& volumeSize = volumeRegion.GetSize(); + if (m_Verbose) { + std::cout << volumeRegion << volumeSize << std::endl; + } + std::cout << Dimension << volumeSize[2] << numberOfFilenames << std::endl; + if (Dimension == 3 && volumeSize[2] < numberOfFilenames) { + if (m_Verbose) + std::cout << "Warning: The number of files in " << m_ArgsInfo.inputDir_arg << " (" << filenames_in.size() << " files) is greater than the number of slices in MHD (" << volumeSize[2] << " slices). Using only " << volumeSize[2] << " files." << std::endl; + + filenames_in.resize(volumeSize[2]); + filenames_out.resize(filenames_in.size()); + numberOfFilenames = filenames_in.size(); + } + + // Modify the meta dictionary + typedef itk::MetaDataDictionary DictionaryType; + const std::vector* dictionary = reader->GetMetaDataDictionaryArray(); + + // Get keys + unsigned int numberOfKeysGiven=m_ArgsInfo.key_given; + if (m_ArgsInfo.verbose_flag) + DD(numberOfKeysGiven); + + std::string seriesUID; + std::string frameOfReferenceUID; + std::string studyUID; + + // one pass through the keys given on the cmd-line, to check what will be recreated + std::string seriesUIDkey = "0020|000e"; + std::string seriesNumberKey = "0020|0011"; + std::string seriesDescriptionKey = "0008|103e"; + std::string frameOfReferenceUIDKey = "0020|0052"; + std::string studyUIDKey = "0020|000d"; + std::string studyIDKey = "0020|0010"; + std::string studyDescriptionKey = "0008|1030"; + bool seriesUIDGiven = false; + bool seriesNumberGiven = false; + bool seriesDescriptionGiven = false; + bool studyUIDGiven = false; + bool studyIDGiven = false; + bool studyDescriptionGiven = false; + for (unsigned int i = 0; i < numberOfKeysGiven; i++) { + std::string entryId( m_ArgsInfo.key_arg[i] ); + if (m_ArgsInfo.verbose_flag) + DD(entryId); + + seriesUIDGiven |= (entryId == seriesUIDkey || entryId == frameOfReferenceUIDKey); + seriesNumberGiven |= (entryId == seriesNumberKey); + seriesDescriptionGiven |= (entryId == seriesDescriptionKey); + studyUIDGiven |= (entryId == studyUIDKey); + studyIDGiven |= (entryId == studyIDKey); + studyDescriptionGiven |= (entryId == studyDescriptionKey); + } + + // force the creation of a new series if a new study was specified + if (!studyUIDGiven && m_ArgsInfo.newStudyUID_flag) { + m_ArgsInfo.newSeriesUID_flag = true; +#if GDCM_MAJOR_VERSION >= 2 + gdcm::UIDGenerator suid; + studyUID = suid.Generate(); +#else + studyUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix()); +#endif + } + + if (!seriesUIDGiven && m_ArgsInfo.newSeriesUID_flag) { +#if GDCM_MAJOR_VERSION >= 2 + gdcm::UIDGenerator suid; + seriesUID = suid.Generate(); + gdcm::UIDGenerator fuid; + frameOfReferenceUID = fuid.Generate(); +#else + seriesUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix()); + frameOfReferenceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix()); +#endif + } + + if (m_ArgsInfo.verbose_flag) { + DD(seriesUID); + DD(frameOfReferenceUID); + DD(studyUID); + } + + // check if file UIDs will be be preserved + bool useInputFileUID = true; + if (m_ArgsInfo.newSeriesUID_flag || m_ArgsInfo.newStudyUID_flag || seriesUIDGiven || studyUIDGiven) { + useInputFileUID = false; + } + else { +#if GDCM_MAJOR_VERSION < 2 + gdcmIO->SetKeepOriginalUID(true); +#endif + namesGenerator->SetOutputDirectory( m_ArgsInfo.outputDir_arg ); + } + + filenames_out.resize(numberOfFilenames); + + time_t t; + t = time(&t); + struct tm* instanceDateTimeTm = localtime(&t); + char datetime[16]; + strftime(datetime, 16, "%Y%m%d", instanceDateTimeTm); + std::ostringstream instanceDate; + instanceDate << datetime; + std::ostringstream instanceTime; + strftime(datetime, 16, "%H%M%S", instanceDateTimeTm); + instanceTime << datetime; + + // update output dicom keys/tags + for(unsigned int fni = 0; fni( *((*dictionary)[fni]), entryId, value ); + } + + // series UID + if (!seriesUIDGiven) { + if (m_ArgsInfo.newSeriesUID_flag) { + itk::EncapsulateMetaData( *((*dictionary)[fni]), seriesUIDkey, seriesUID ); + itk::EncapsulateMetaData( *((*dictionary)[fni]), frameOfReferenceUIDKey, frameOfReferenceUID ); + } + } + + // study UID + if (!studyUIDGiven) { + if (m_ArgsInfo.newStudyUID_flag) + itk::EncapsulateMetaData( *((*dictionary)[fni]), studyUIDKey, studyUID ); + } + + // study description + if (studyUIDGiven || m_ArgsInfo.newStudyUID_flag) { + if (!studyIDGiven) + itk::EncapsulateMetaData( *((*dictionary)[fni]), studyIDKey,itksys::SystemTools::GetFilenameName( m_ArgsInfo.outputDir_arg )); + if (!studyDescriptionGiven) + itk::EncapsulateMetaData( *((*dictionary)[fni]), studyDescriptionKey,itksys::SystemTools::GetFilenameName( m_ArgsInfo.outputDir_arg )); + + itk::EncapsulateMetaData( *((*dictionary)[fni]), "0008|0020", instanceDate.str() ); + itk::EncapsulateMetaData( *((*dictionary)[fni]), "0008|0030", instanceTime.str() ); + } + + // series description/number + if (seriesUIDGiven || m_ArgsInfo.newSeriesUID_flag) { + if (!seriesDescriptionGiven) + itk::EncapsulateMetaData( *((*dictionary)[fni]), seriesDescriptionKey, itksys::SystemTools::GetFilenameName(m_ArgsInfo.outputDir_arg) ); + if (!seriesNumberGiven) + itk::EncapsulateMetaData( *((*dictionary)[fni]), seriesNumberKey, itksys::SystemTools::GetFilenameName(m_ArgsInfo.outputDir_arg) ); + + itk::EncapsulateMetaData( *((*dictionary)[fni]), "0008|0012", instanceDate.str() ); + itk::EncapsulateMetaData( *((*dictionary)[fni]), "0008|0013", instanceTime.str() ); + } + + // file UIDs are recreated for new studies or series + if (!useInputFileUID) + { + if (m_ArgsInfo.verbose_flag) + std::cout << "Recreating file UIDs" << std::endl; + + std::string fileUID; +#if GDCM_MAJOR_VERSION >= 2 + gdcm::UIDGenerator fid; + fileUID = fid.Generate(); +#else + fileUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix()); +#endif + itk::EncapsulateMetaData( *((*dictionary)[fni]), "0008|0018", fileUID ); + itk::EncapsulateMetaData( *((*dictionary)[fni]), "0002|0003", fileUID ); + + filenames_out[fni] = itksys::SystemTools::CollapseFullPath(fileUID.c_str(), m_ArgsInfo.outputDir_arg) + std::string(".dcm"); + } + } + + // Output directory and filenames + itksys::SystemTools::MakeDirectory( m_ArgsInfo.outputDir_arg ); // create if it doesn't exist + typedef itk::ImageFileWriter SeriesWriterType; + typename SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New(); + + seriesWriter->SetInput( input ); + seriesWriter->SetImageIO( gdcmIO ); + + seriesWriter->SetFileName( filenames_out[0] ); + seriesWriter->SetMetaDataDictionary( *((*dictionary)[0]) ); + + // Write + try { + if (m_ArgsInfo.verbose_flag) + std::cout << seriesWriter << std::endl; + seriesWriter->Update(); + } catch( itk::ExceptionObject & excp ) { + std::cerr << "Error: Exception thrown while writing the series!!" << std::endl; + std::cerr << excp << std::endl; + } + +} + +}//end clitk + +#endif //#define clitkGateSimulation2DicomGenericFilter_txx -- 2.45.2