]> Creatis software - clitk.git/blob - tools/clitkSpect2DicomGenericFilter.txx
03e2b055e04e4df3c1734b2f14ca48f86c874423
[clitk.git] / tools / clitkSpect2DicomGenericFilter.txx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to:
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18 #ifndef clitkSpect2DicomGenericFilter_txx
19 #define clitkSpect2DicomGenericFilter_txx
20
21 /* =================================================
22  * @file   clitkSpect2DicomGenericFilter.txx
23  * @author
24  * @date
25  *
26  * @brief
27  *
28  ===================================================*/
29
30 // clitk
31 #include "clitkResampleImageWithOptionsFilter.h"
32 #if GDCM_MAJOR_VERSION >= 2
33 #include "gdcmUIDGenerator.h"
34 #else
35 #include "gdcmFile.h"
36 #include "gdcmUtil.h"
37 #endif
38 #include "itkVersion.h"
39  
40 #include "itkImage.h"
41 #include "itkMinimumMaximumImageFilter.h"
42  
43 #include "itkGDCMImageIO.h"
44 #include "itkGDCMSeriesFileNames.h"
45 #include "itkNumericSeriesFileNames.h"
46  
47 #include "itkImageSeriesReader.h"
48 #include "itkImageSeriesWriter.h"
49
50 #include <itkThresholdImageFilter.h>
51  
52 #include "itkResampleImageFilter.h"
53  
54 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
55 #include "itkShiftScaleImageFilter.h"
56 #endif
57  
58 #include "itkIdentityTransform.h"
59 #include "itkLinearInterpolateImageFunction.h"
60  
61 #include <itksys/SystemTools.hxx>
62  
63 #if ITK_VERSION_MAJOR >= 4
64 #include "gdcmUIDGenerator.h"
65 #else
66 #include "gdcm/src/gdcmFile.h"
67 #include "gdcm/src/gdcmUtil.h"
68 #endif
69  
70 #include <string>
71 #include <sstream>
72 #if GDCM_MAJOR_VERSION >= 2
73 #include "gdcmUIDGenerator.h"
74 #include <gdcmImageHelper.h>
75 #include <gdcmAttribute.h>
76 #include <gdcmReader.h>
77 #include <gdcmWriter.h>
78 #include <gdcmDataElement.h>
79 #include <gdcmTag.h>
80 #endif
81
82 namespace clitk
83 {
84
85
86 //-----------------------------------------------------------
87 // Constructor
88 //-----------------------------------------------------------
89 template<class args_info_type>
90 Spect2DicomGenericFilter<args_info_type>::Spect2DicomGenericFilter()
91 {
92   m_Verbose=false;
93   m_InputFileName="";
94 }
95
96
97 //-----------------------------------------------------------
98 // Update
99 //-----------------------------------------------------------
100 template<class args_info_type>
101 void Spect2DicomGenericFilter<args_info_type>::Update()
102 {
103   // Read the Dimension and PixelType
104   int Dimension;
105   std::string PixelType;
106   ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
107
108
109   // Call UpdateWithDim
110   if(Dimension==2) UpdateWithDim<2>(PixelType);
111   else if(Dimension==3) UpdateWithDim<3>(PixelType);
112   // else if (Dimension==4)UpdateWithDim<4>(PixelType);
113   else {
114     std::cout<<"Error, Only for 2 or 3  Dimensions!!!"<<std::endl ;
115     return;
116   }
117 }
118
119 //-------------------------------------------------------------------
120 // Update with the number of dimensions
121 //-------------------------------------------------------------------
122 template<class args_info_type>
123 template<unsigned int Dimension>
124 void
125 Spect2DicomGenericFilter<args_info_type>::UpdateWithDim(std::string PixelType)
126 {
127   if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
128
129   if(PixelType == "short") {
130     if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
131     UpdateWithDimAndPixelType<Dimension, signed short>();
132   }
133   else if(PixelType == "unsigned_short"){
134     if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
135     UpdateWithDimAndPixelType<Dimension, unsigned short>();
136   }
137
138   else if (PixelType == "unsigned_char") {
139     if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
140     UpdateWithDimAndPixelType<Dimension, unsigned char>();
141   }
142
143   //     else if (PixelType == "char"){
144   //       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
145   //       UpdateWithDimAndPixelType<Dimension, signed char>();
146   //     }
147   else if (PixelType == "double") {
148     if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and double..." << std::endl;
149     UpdateWithDimAndPixelType<Dimension, double>();
150   }
151   else {
152     if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
153     UpdateWithDimAndPixelType<Dimension, float>();
154   }
155 }
156
157 //-------------------------------------------------------------------
158 // Update with the number of dimensions and the pixeltype read from
159 // the dicom files. The MHD files may be resampled to match the
160 // dicom spacing (and number of slices). Rounding errors in resampling
161 // are handled by removing files when generating the output dicom
162 // series.
163 //-------------------------------------------------------------------
164 template<class args_info_type>
165 template <unsigned int Dimension, class  PixelType>
166 void
167 Spect2DicomGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
168 {
169
170
171 // Resample a DICOM study
172 //   Usage: ResampleDICOM InputDirectory OutputDirectory
173 //                        xSpacing ySpacing zSpacing
174 //
175 //   Example: ResampleDICOM CT CTResample 0 0 1.5
176 //            will read a series from the CT directory and create a
177 //            new series in the CTResample directory. The new series
178 //            will have the same x,y spacing as the input series, but
179 //            will have a z-spacing of 1.5.
180 //
181 // Description:
182 // ResampleDICOM resamples a DICOM series with user-specified
183 // spacing. The program outputs a new DICOM series with a series
184 // number set to 1001. All non-private DICOM tags are moved from the input
185 // series to the output series. The Image Position Patient is adjusted
186 // for each slice to reflect the z-spacing. The number of slices in
187 // the output series may be larger or smaller due to changes in the
188 // z-spacing. To retain the spacing for a given dimension, specify 0.
189 //
190 // The program progresses as follows:
191 // 1) Read the input series
192 // 2) Resample the series according to the user specified x-y-z
193 //    spacing.
194 // 3) Create a MetaDataDictionary for each slice.
195 // 4) Shift data to undo the effect of a rescale intercept by the
196 //    DICOM reader (only for ITK < 4.6)
197 // 5) Write the new DICOM series
198 //
199  
200
201  
202  
203   // Validate input parameters
204  
205   const unsigned int InputDimension = 3;
206   const unsigned int OutputDimension = 3;
207  
208  
209   typedef itk::Image< PixelType, InputDimension >
210     InputImageType;
211   typedef itk::Image< PixelType, OutputDimension >
212     OutputImageType;
213   typedef itk::ImageSeriesReader< InputImageType >
214     ReaderType;
215   typedef itk::GDCMImageIO
216     ImageIOType;
217   typedef itk::GDCMSeriesFileNames
218     InputNamesGeneratorType;
219   typedef itk::NumericSeriesFileNames
220     OutputNamesGeneratorType;
221   typedef itk::IdentityTransform< double, InputDimension >
222     TransformType;
223   typedef itk::LinearInterpolateImageFunction< InputImageType, double >
224     InterpolatorType;
225   typedef itk::ResampleImageFilter< InputImageType, InputImageType >
226     ResampleFilterType;
227 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
228   typedef itk::ShiftScaleImageFilter< InputImageType, InputImageType >
229     ShiftScaleType;
230 #endif
231   typedef itk::ImageSeriesWriter< InputImageType, OutputImageType >
232     SeriesWriterType;
233  
234 ////////////////////////////////////////////////
235 // 1) Read the input series
236
237 // Read the input (MHD file)
238   typedef typename InputImageType::RegionType RegionType;
239   typedef typename RegionType::SizeType SizeType;
240   typedef itk::ImageFileReader<InputImageType> InputReaderType;
241   typename InputReaderType::Pointer volumeReader = InputReaderType::New();
242   volumeReader->SetFileName( m_ArgsInfo.input_arg );
243   volumeReader->Update();
244   
245   typename InputImageType::Pointer input = volumeReader->GetOutput();
246  
247   ImageIOType::Pointer gdcmIO = ImageIOType::New();
248   gdcmIO->LoadPrivateTagsOn();
249   InputNamesGeneratorType::Pointer inputNames = InputNamesGeneratorType::New();
250   inputNames->SetInputDirectory( m_ArgsInfo.inputDir_arg );
251  
252   const typename ReaderType::FileNamesContainer & filenames =
253                             inputNames->GetInputFileNames();
254  
255   typename ReaderType::Pointer reader = ReaderType::New();
256  
257   reader->SetImageIO( gdcmIO );
258   reader->SetFileNames( filenames );
259   try
260     {
261     reader->Update();
262     }
263   catch (itk::ExceptionObject &excp)
264     {
265     std::cerr << "Exception thrown while reading the series" << std::endl;
266     std::cerr << excp << std::endl;
267     return;
268     }
269     typename InputImageType::SpacingType outputSpacing;
270     typename InputImageType::SizeType   outputSize;
271     for (unsigned int i = 0; i < 3; i++)
272     {
273       outputSpacing[i] = input->GetSpacing()[i];
274       outputSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
275     }
276
277 ////////////////////////////////////////////////
278 // 2) Ensure to have value >= -1024
279
280   typedef itk::ThresholdImageFilter <InputImageType> ThresholdImageFilterType;
281   typename ThresholdImageFilterType::Pointer thresholdFilter = ThresholdImageFilterType::New();
282   thresholdFilter->SetInput(input);
283   thresholdFilter->ThresholdBelow(-1024);
284   thresholdFilter->SetOutsideValue(-1024);
285   thresholdFilter->Update();
286
287   input=thresholdFilter->GetOutput();
288
289
290
291 ////////////////////////////////////////////////
292 // 2) Resample the series
293 /*  typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
294  
295   TransformType::Pointer transform = TransformType::New();
296   transform->SetIdentity();
297  
298   const typename InputImageType::SpacingType& inputSpacing =
299     reader->GetOutput()->GetSpacing();
300   const typename InputImageType::RegionType& inputRegion =
301     reader->GetOutput()->GetLargestPossibleRegion();
302   const typename InputImageType::SizeType& inputSize =
303     inputRegion.GetSize();
304  
305   std::cout << "The input series in directory " << m_ArgsInfo.inputDir_arg
306             << " has " << filenames.size() << " files with spacing "
307             << inputSpacing
308             << std::endl;
309  
310   // Compute the size of the output. The user specifies a spacing on
311   // the command line. If the spacing is 0, the input spacing will be
312   // used. The size (# of pixels) in the output is recomputed using
313   // the ratio of the input and output sizes.
314   typename InputImageType::SpacingType outputSpacing;
315  
316   bool changeInSpacing = false;
317   for (unsigned int i = 0; i < 3; i++)
318     {
319       outputSpacing[i] = inputSpacing[i];
320     }
321   typename InputImageType::SizeType   outputSize;
322   typedef typename InputImageType::SizeType::SizeValueType SizeValueType;
323   outputSize[0] = static_cast<SizeValueType>(inputSize[0] * inputSpacing[0] / outputSpacing[0] + .5);
324   outputSize[1] = static_cast<SizeValueType>(inputSize[1] * inputSpacing[1] / outputSpacing[1] + .5);
325   outputSize[2] = static_cast<SizeValueType>(inputSize[2] * inputSpacing[2] / outputSpacing[2] + .5);
326  
327   typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
328   resampler->SetInput( reader->GetOutput() );
329   resampler->SetTransform( transform );
330   resampler->SetInterpolator( interpolator );
331   resampler->SetOutputOrigin ( reader->GetOutput()->GetOrigin());
332   resampler->SetOutputSpacing ( outputSpacing );
333   resampler->SetOutputDirection ( reader->GetOutput()->GetDirection());
334   resampler->SetSize ( outputSize );
335   resampler->Update ();
336  
337  */
338  
339 ////////////////////////////////////////////////
340 // 3) Create a MetaDataDictionary for each slice.
341  
342   // Copy the dictionary from the first image and override slice
343   // specific fields
344   typename ReaderType::DictionaryRawPointer inputDict = (*(reader->GetMetaDataDictionaryArray()))[0];
345   typename ReaderType::DictionaryArrayType outputArray;
346  
347   // To keep the new series in the same study as the original we need
348   // to keep the same study UID. But we need new series and frame of
349   // reference UID's.
350 #if ITK_VERSION_MAJOR >= 4
351   gdcm::UIDGenerator suid;
352   std::string seriesUID = suid.Generate();
353   gdcm::UIDGenerator fuid;
354   std::string frameOfReferenceUID = fuid.Generate();
355 #else
356   std::string seriesUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
357   std::string frameOfReferenceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
358 #endif
359   std::string studyUID;
360   std::string sopClassUID;
361   itk::ExposeMetaData<std::string>(*inputDict, "0020|000d", studyUID);
362   itk::ExposeMetaData<std::string>(*inputDict, "0008|0016", sopClassUID);
363   gdcmIO->KeepOriginalUIDOn();
364   int nbFile(1);
365   for (unsigned int f = 0; f < nbFile; f++)
366     {
367     // Create a new dictionary for this slice
368     typename ReaderType::DictionaryRawPointer dict = new typename ReaderType::DictionaryType;
369  
370     // Copy the dictionary from the first slice
371     //CopyDictionary (*inputDict, *dict);
372     
373     typedef itk::MetaDataDictionary DictionaryType;
374
375     DictionaryType::ConstIterator itrDic = (*inputDict).Begin();
376     DictionaryType::ConstIterator endDic = (*inputDict).End();
377     typedef itk::MetaDataObject< std::string > MetaDataStringType;
378  
379     while( itrDic != endDic )
380     {
381       itk::MetaDataObjectBase::Pointer  entry = itrDic->second;
382  
383       MetaDataStringType::Pointer entryvalue =
384       dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;
385       if( entryvalue )
386       {
387         std::string tagkey   = itrDic->first;
388         std::string tagvalue = entryvalue->GetMetaDataObjectValue();
389         itk::EncapsulateMetaData<std::string>(*dict, tagkey, tagvalue);
390       }
391       ++itrDic;
392     }
393  
394     // Set the UID's for the study, series, SOP  and frame of reference
395     itk::EncapsulateMetaData<std::string>(*dict,"0020|000d", studyUID);
396     itk::EncapsulateMetaData<std::string>(*dict,"0020|000e", seriesUID);
397     itk::EncapsulateMetaData<std::string>(*dict,"0020|0052", frameOfReferenceUID);
398  
399 #if ITK_VERSION_MAJOR >= 4
400     gdcm::UIDGenerator sopuid;
401     std::string sopInstanceUID = sopuid.Generate();
402 #else
403     std::string sopInstanceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
404 #endif
405     itk::EncapsulateMetaData<std::string>(*dict,"0008|0018", sopInstanceUID);
406     itk::EncapsulateMetaData<std::string>(*dict,"0002|0003", sopInstanceUID);
407  
408     // Change fields that are slice specific
409     std::ostringstream value;
410     value.str("");
411     //unsigned int f = 0;
412     value << f + 1;
413  
414     // Image Number
415     itk::EncapsulateMetaData<std::string>(*dict,"0020|0013", value.str());
416  
417     // Series Description - Append new description to current series
418     // description
419     std::string oldSeriesDesc;
420     itk::ExposeMetaData<std::string>(*inputDict, "0008|103e", oldSeriesDesc);
421  
422     value.str("");
423     value << oldSeriesDesc
424           << ": Resampled with pixel spacing "
425           << outputSpacing[0] << ", "
426           << outputSpacing[1] << ", "
427           << outputSpacing[2];
428     // This is an long string and there is a 64 character limit in the
429     // standard
430     unsigned lengthDesc = value.str().length();
431  
432     std::string seriesDesc( value.str(), 0,
433                             lengthDesc > 64 ? 64
434                             : lengthDesc);
435     itk::EncapsulateMetaData<std::string>(*dict,"0008|103e", seriesDesc);
436  
437     // Series Number
438     value.str("");
439     value << 1001;
440     itk::EncapsulateMetaData<std::string>(*dict,"0020|0011", value.str());
441  
442     // Derivation Description - How this image was derived
443     value.str("");
444
445     value << ": " << ITK_SOURCE_VERSION;
446  
447     lengthDesc = value.str().length();
448     std::string derivationDesc( value.str(), 0,
449                                 lengthDesc > 1024 ? 1024
450                                 : lengthDesc);
451     itk::EncapsulateMetaData<std::string>(*dict,"0008|2111", derivationDesc);
452  
453     // Image Position Patient: This is calculated by computing the
454     // physical coordinate of the first pixel in each slice.
455     typename InputImageType::PointType position;
456     typename InputImageType::IndexType index;
457     index[0] = 0;
458     index[1] = 0;
459     index[2] = f;
460     input->TransformIndexToPhysicalPoint(index, position);
461  
462     value.str("");
463     value << position[0] << "\\" << position[1] << "\\" << position[2];
464     itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str());
465     // Slice Location: For now, we store the z component of the Image
466     // Position Patient.
467     value.str("");
468     value << position[2];
469     itk::EncapsulateMetaData<std::string>(*dict,"0020|1041", value.str());
470  
471
472       // Slice Thickness: For now, we store the z spacing
473       value.str("");
474       value << outputSpacing[2];
475       itk::EncapsulateMetaData<std::string>(*dict,"0018|0050",
476                                             value.str());
477       // Spacing Between Slices
478       itk::EncapsulateMetaData<std::string>(*dict,"0018|0088",
479                                             value.str());
480       
481       /*
482       value.str("");
483       value << 0.999987 << "\\" << -0.005061 << "\\" << 0.000000 << "\\" << 0.000000 << "\\" << 0.000000 << "\\" << -1.000000;
484       itk::EncapsulateMetaData<std::string>(*dict, "0020|0037", value.str());
485        
486       value.str("");
487       value << 196;
488       itk::EncapsulateMetaData<std::string>(*dict, "0002|0000", value.str());
489       value.str("");
490       value << 510;
491       itk::EncapsulateMetaData<std::string>(*dict, "0008|0000", value.str());
492       value.str("");
493       value << 362;
494       itk::EncapsulateMetaData<std::string>(*dict, "0009|0000", value.str());
495       value.str("");
496       value << 116;
497       itk::EncapsulateMetaData<std::string>(*dict, "0010|0000", value.str());
498       value.str("");
499       value << 1008;
500       itk::EncapsulateMetaData<std::string>(*dict, "0011|0000", value.str());
501       value.str("");
502       value << 0 << "\\" << 0;
503       itk::EncapsulateMetaData<std::string>(*dict, "0011|1011", value.str());
504       value.str("");
505       value << 1 << "\\" << 1;
506       itk::EncapsulateMetaData<std::string>(*dict, "0011|1015", value.str());
507       value.str("");
508       value << 1 << "\\" << 2;
509       itk::EncapsulateMetaData<std::string>(*dict, "0011|1016", value.str());
510       value.str("");
511       value << 0 << "\\" << 0;
512       itk::EncapsulateMetaData<std::string>(*dict, "0011|1017", value.str());
513       value.str("");
514       value << 0 << "\\" << 0;
515       itk::EncapsulateMetaData<std::string>(*dict, "0011|1018", value.str());
516       value.str("");
517       value << 0 << "\\" << 0;
518       itk::EncapsulateMetaData<std::string>(*dict, "0011|1019", value.str());
519       value.str("");
520       value << 0 << "\\" << 0;
521       itk::EncapsulateMetaData<std::string>(*dict, "0011|101a", value.str());
522       value.str("");
523       value << 0 << "\\" << 0;
524       itk::EncapsulateMetaData<std::string>(*dict, "0011|101f", value.str());
525       value.str("");
526       value << 0 << "\\" << 0;
527       itk::EncapsulateMetaData<std::string>(*dict, "0011|1026", value.str());
528       value.str("");
529       value << 0 << "\\" << 0 << "\\" << 0 << "\\" << 0;
530       itk::EncapsulateMetaData<std::string>(*dict, "0011|1027", value.str());
531       value.str("");
532       value << 0 << "\\" << 0 << "\\" << 0 << "\\" << 0;
533       itk::EncapsulateMetaData<std::string>(*dict, "0011|1028", value.str());
534       value.str("");
535       value << 0 << "\\" << 0;
536       itk::EncapsulateMetaData<std::string>(*dict, "0011|102c", value.str());
537       value.str("");
538       value << 0 << "\\" << 0;
539       itk::EncapsulateMetaData<std::string>(*dict, "0011|102d", value.str());
540       value.str("");
541       value << 0 << "\\" << 0;
542       itk::EncapsulateMetaData<std::string>(*dict, "0011|102e", value.str());
543       std::ostringstream valueVec[2];
544       valueVec[0].str("");
545       valueVec[0] << 32767;
546       valueVec[1].str("");
547       valueVec[1] << 32767;
548       std::string valueVec2[2];
549       valueVec2[0]=valueVec[0].str();
550       valueVec2[1]=valueVec[1].str();
551       itk::EncapsulateMetaData<std::string*>(*dict, "0011|102f", valueVec2);
552       value.str("");
553       value << 1 ;
554       itk::EncapsulateMetaData<std::string>(*dict, "0020|1011", value.str());
555       value.str("");
556       value << 63 ;
557       itk::EncapsulateMetaData<std::string>(*dict, "0028|0107", value.str());
558       
559       value.str("");
560       value << 0 ;
561       itk::EncapsulateMetaData<std::string>(*dict, "0018|1130", value.str());
562       value.str("");
563       value << 563.7 ;
564       itk::EncapsulateMetaData<std::string>(*dict, "0018|1131", value.str());
565       value.str("");
566       value << "CC" ;
567       itk::EncapsulateMetaData<std::string>(*dict, "0018|1140", value.str());
568       value.str("");
569       value << 243.5 ;
570       itk::EncapsulateMetaData<std::string>(*dict, "0018|1142", value.str());
571       value.str("");
572       value << 360 ;
573       itk::EncapsulateMetaData<std::string>(*dict, "0018|1143", value.str());
574       value.str("");
575       value << 6 ;
576       itk::EncapsulateMetaData<std::string>(*dict, "0018|1144", value.str());
577       value.str("");
578       value << 10000 ;
579       itk::EncapsulateMetaData<std::string>(*dict, "0018|1242", value.str());
580       value.str("");
581       value << 60 ;
582       itk::EncapsulateMetaData<std::string>(*dict, "0054|0053", value.str());
583       value.str("");
584       value << 180.29 ;
585       itk::EncapsulateMetaData<std::string>(*dict, "0054|0200", value.str());
586       value.str("");
587       value << "F-10450" ;
588       itk::EncapsulateMetaData<std::string>(*dict, "0008|0100", value.str());
589       value.str("");
590       value << "99SDM" ;
591       itk::EncapsulateMetaData<std::string>(*dict, "0008|0102", value.str());
592       value.str("");
593       value << "recumbent" ;
594       itk::EncapsulateMetaData<std::string>(*dict, "0008|0104", value.str());
595       value.str("");
596       value << 114 ;
597       itk::EncapsulateMetaData<std::string>(*dict, "0054|0014", value.str());
598       value.str("");
599       value << 126 ;
600       itk::EncapsulateMetaData<std::string>(*dict, "0054|0015", value.str());
601       value.str("");
602       value << "Tc99m_SC" ;
603       itk::EncapsulateMetaData<std::string>(*dict, "0054|0018", value.str());
604       value.str("");
605       value << 0 ;
606       itk::EncapsulateMetaData<std::string>(*dict, "0018|1120", value.str());
607       value.str("");
608       value << 0 ;
609       itk::EncapsulateMetaData<std::string>(*dict, "0018|1145", value.str());
610       value.str("");
611       value << 0 << "\\" << 0;
612       itk::EncapsulateMetaData<std::string>(*dict, "0018|1149", value.str());
613       value.str("");
614       value << "LEHR" ;
615       itk::EncapsulateMetaData<std::string>(*dict, "0018|1180", value.str());
616       value.str("");
617       value << "PARA" ;
618       itk::EncapsulateMetaData<std::string>(*dict, "0018|1181", value.str());
619       value.str("");
620       value << 0 ;
621       itk::EncapsulateMetaData<std::string>(*dict, "0018|1182", value.str());
622       value.str("");
623       value << 0 ;
624       itk::EncapsulateMetaData<std::string>(*dict, "0018|1183", value.str());
625       value.str("");
626       value << 0 ;
627       itk::EncapsulateMetaData<std::string>(*dict, "0018|1184", value.str());
628       value.str("");
629       value << 1.000000 << "\\" << 1.000000 ;
630       itk::EncapsulateMetaData<std::string>(*dict, "0028|0031", value.str());
631       value.str("");
632       value << 0.000000 << "\\" << 0.000000 ;
633       itk::EncapsulateMetaData<std::string>(*dict, "0028|0032", value.str());
634       value.str("");
635       value << 0 ;
636       itk::EncapsulateMetaData<std::string>(*dict, "0011|101c", value.str());
637       value.str("");
638       value << 0 ;
639       itk::EncapsulateMetaData<std::string>(*dict, "0011|101d", value.str());
640       value.str("");
641       value << 0 ;
642       itk::EncapsulateMetaData<std::string>(*dict, "0013|1016", value.str());
643       value.str("");
644       value << 0 ;
645       itk::EncapsulateMetaData<std::string>(*dict, "0013|1017", value.str());
646       value.str("");
647       value << 0 ;
648       itk::EncapsulateMetaData<std::string>(*dict, "0011|1023", value.str());
649       value.str("");
650       value << 0 ;
651       itk::EncapsulateMetaData<std::string>(*dict, "0011|1024", value.str());
652       value.str("");
653       value << 0 ;
654       itk::EncapsulateMetaData<std::string>(*dict, "0011|1025", value.str());
655       value.str("");
656       value << 0 ;
657       itk::EncapsulateMetaData<std::string>(*dict, "0011|1029", value.str());
658       value.str("");
659       value << 0 ;
660       itk::EncapsulateMetaData<std::string>(*dict, "0011|103e", value.str());
661       value.str("");
662       value << 0 ;
663       itk::EncapsulateMetaData<std::string>(*dict, "0013|1018", value.str());
664       value.str("");
665       value << 0 ;
666       itk::EncapsulateMetaData<std::string>(*dict, "0013|1019", value.str());
667       value.str("");
668       value << 0 ;
669       itk::EncapsulateMetaData<std::string>(*dict, "0013|101a", value.str());
670       value.str("");
671       value << "GEMS_GENIE_1" ;
672       itk::EncapsulateMetaData<std::string>(*dict, "0035|0010", value.str());
673       value.str("");
674       value << 29 ;
675       itk::EncapsulateMetaData<std::string>(*dict, "0035|1001", value.str());
676       
677  */
678     // Save the dictionary
679     outputArray.push_back(inputDict);
680     }
681  
682 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
683 ////////////////////////////////////////////////
684 // 4) Shift data to undo the effect of a rescale intercept by the
685 //    DICOM reader
686   std::string interceptTag("0028|1052");
687   typedef itk::MetaDataObject< std::string > MetaDataStringType;
688   itk::MetaDataObjectBase::Pointer entry = (*inputDict)[interceptTag];
689  
690   MetaDataStringType::ConstPointer interceptValue =
691     dynamic_cast<const MetaDataStringType *>( entry.GetPointer() ) ;
692  
693   int interceptShift = 0;
694   if( interceptValue )
695     {
696     std::string tagValue = interceptValue->GetMetaDataObjectValue();
697     interceptShift = -atoi ( tagValue.c_str() );
698     }
699  
700   ShiftScaleType::Pointer shiftScale = ShiftScaleType::New();
701   shiftScale->SetInput( resampler->GetOutput());
702   shiftScale->SetShift( interceptShift );
703 #endif
704  
705 ////////////////////////////////////////////////
706 // 5) Write the new DICOM series
707  
708   // Make the output directory and generate the file names.
709   itksys::SystemTools::MakeDirectory( m_ArgsInfo.outputDir_arg );
710  
711   // Generate the file names
712   OutputNamesGeneratorType::Pointer outputNames = OutputNamesGeneratorType::New();
713   std::string seriesFormat(m_ArgsInfo.outputDir_arg);
714   seriesFormat = seriesFormat + "/" + "IM%03d.dcm";
715   outputNames->SetSeriesFormat (seriesFormat.c_str());
716   outputNames->SetStartIndex (1);
717   outputNames->SetEndIndex (nbFile);
718   //outputNames->SetEndIndex (outputSize[2]);
719   typename ReaderType::FileNamesContainer fileNamesOutput;
720   std::string extension = "output.dcm";
721   fileNamesOutput.push_back(extension);
722   //seriesWriter->SetFileNames( fileNamesOutput );
723  
724   typename SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();
725 #if ( ( ITK_VERSION_MAJOR == 4 ) && ( ITK_VERSION_MINOR < 6 ) )
726   seriesWriter->SetInput( input );
727 #else
728   seriesWriter->SetInput( input );
729 #endif
730     seriesWriter->SetImageIO( gdcmIO );
731     seriesWriter->SetFileNames( outputNames->GetFileNames() );
732     seriesWriter->SetMetaDataDictionaryArray( &outputArray );
733   try
734     {
735     seriesWriter->Update();
736     }
737   catch( itk::ExceptionObject & excp )
738     {
739     std::cerr << "Exception thrown while writing the series " << std::endl;
740     std::cerr << excp << std::endl;
741     return;
742     }
743   std::cout << "The output series in directory " << m_ArgsInfo.outputDir_arg
744             << " has " << nbFile << " files with spacing "
745             << outputSpacing
746             << std::endl;
747
748   gdcm::Reader readerModel, readerOutput;
749   readerModel.SetFileName( inputNames->GetInputFileNames()[0].c_str() );
750   readerOutput.SetFileName( outputNames->GetFileNames()[0].c_str() );
751   readerModel.Read();
752   readerOutput.Read();
753   gdcm::File &fileModel = readerModel.GetFile();
754   gdcm::File &fileOutput = readerOutput.GetFile();
755   gdcm::DataSet &dsModel = fileModel.GetDataSet();
756   gdcm::DataSet &dsOutput = fileOutput.GetDataSet();
757   const unsigned int ptr_len = 42;
758   char *ptr = new char[ptr_len];
759   memset(ptr,0,ptr_len);
760
761   const gdcm::DataElement &dataOutput = dsOutput.GetDataElement(gdcm::Tag(0x7fe0, 0x10));
762   dsModel.Replace(dataOutput);
763   gdcm::Writer w;
764   w.SetFile( fileModel );
765   w.SetFileName( outputNames->GetFileNames()[0].c_str() );
766   w.Write();
767   return;
768 }
769
770  
771 /*void CopyDictionary (itk::MetaDataDictionary &fromDict, itk::MetaDataDictionary &toDict)
772 {
773   typedef itk::MetaDataDictionary DictionaryType;
774  
775   DictionaryType::ConstIterator itr = fromDict.Begin();
776   DictionaryType::ConstIterator end = fromDict.End();
777   typedef itk::MetaDataObject< std::string > MetaDataStringType;
778  
779   while( itr != end )
780     {
781     itk::MetaDataObjectBase::Pointer  entry = itr->second;
782  
783     MetaDataStringType::Pointer entryvalue =
784       dynamic_cast<MetaDataStringType *>( entry.GetPointer() ) ;
785     if( entryvalue )
786       {
787       std::string tagkey   = itr->first;
788       std::string tagvalue = entryvalue->GetMetaDataObjectValue();
789       itk::EncapsulateMetaData<std::string>(toDict, tagkey, tagvalue);
790       }
791     ++itr;
792     }
793 } */
794
795
796 }//end clitk
797
798 #endif //#define clitkSpect2DicomGenericFilter_txx