/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/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 notice for more information. =========================================================================*/ #include "vtkGDCMImageWriter.h" #include "vtkImageReader.h" #include "vtkImageCast.h" #include "vtkImageData.h" #include "vtkPointData.h" #include "vtkDataArray.h" #include "vtkMedicalImageProperties.h" #include "gdcmTrace.h" #include "gdcmReader.h" #include "gdcmWriter.h" #include "gdcmAttribute.h" /* * Minimal example to create a fake RTDOSE file. The data contains a sphere * just for testing. * The vtkMedicalImageProperties is not properly filled, but only contains a * single field which is required to set the proper SOP Class */ int main(int, char *[]) { //gdcm::Trace::DebugOn(); const vtkIdType xSize = 512; const vtkIdType ySize = 512; const vtkIdType zSize = 512; vtkImageData *image = vtkImageData::New(); image->SetDimensions(xSize,ySize,zSize); image->SetOrigin(-350.684,350.0,890.76); image->SetSpacing(5.4688,-5.4688,-3.27); #if VTK_MAJOR_VERSION <= 5 image->SetNumberOfScalarComponents(1); image->SetScalarTypeToDouble(); #else image->AllocateScalars(VTK_DOUBLE ,1); #endif double pt[3]; for( int z = 0; z < zSize; ++z ) for( int y = 0; y < ySize; ++y ) for( int x = 0; x < xSize; ++x ) { pt[0] = x; pt[1] = y; pt[2] = z; pt[0] -= xSize / 2; pt[1] -= ySize / 2; pt[2] -= zSize / 2; pt[0] /= xSize / 2; pt[1] /= ySize / 2; pt[2] /= zSize / 2; const double unit = pt[0] * pt[0] + pt[1] * pt[1] + pt[2] * pt[2]; const double inval = unit <= 1. ? (3 * unit + 7) : 0.; // just for fun => max == 10. double* pixel= static_cast(image->GetScalarPointer(x,y,z)); pixel[0] = inval; } vtkGDCMImageWriter *writer = vtkGDCMImageWriter::New(); writer->SetFileDimensionality( 3 ); writer->SetFileName( "rtdose.dcm" ); #if (VTK_MAJOR_VERSION >= 6) writer->SetInputData( image ); #else writer->SetInput( image ); #endif writer->GetMedicalImageProperties()->SetSliceThickness("1.5"); writer->GetMedicalImageProperties()->AddUserDefinedValue( "Dose Units", "GY"); writer->GetMedicalImageProperties()->AddUserDefinedValue( "Dose Summation Type", "PLAN"); writer->GetMedicalImageProperties()->AddUserDefinedValue( "Dose Type", "PHYSICAL"); writer->GetMedicalImageProperties()->AddUserDefinedValue( "Frame of Reference UID", "1.3.12.2.1107.5.6.1.68100.30270111041215391275000000001"); writer->GetMedicalImageProperties()->SetModality( "RTDOSE" ); //writer->GetMedicalImageProperties()->SetModality( "PT" ); // debug writer->SetScale( 0.0042 ); // why not writer->Write(); image->Delete(); writer->Delete(); // BEGIN HACK // In GDCM version 2.4.3 and before, the following tag was missing which caused issue with some RTDose software: // Open the DICOM file that was temporarily created. This will allows me to used // GDCM to append specific tags that allows the RTDOSE to be associated with the // relevant CT images. gdcm::Reader reader2; reader2.SetFileName("rtdose.dcm" ); reader2.Read(); gdcm::File &file = reader2.GetFile(); gdcm::DataSet &ds = file.GetDataSet(); // Required by some software and not automagically added by GDCM in old version gdcm::Attribute<0x0028,0x0009> framePointer; framePointer.SetNumberOfValues(1); framePointer.SetValue( gdcm::Tag(0x3004,0x000C) ); ds.Replace( framePointer.GetAsDataElement() ); gdcm::Writer writer2; writer2.CheckFileMetaInformationOff(); writer2.SetFileName("rtdose2.dcm"); writer2.SetFile( file ); writer2.Write(); // END HACK return 0; }