15 #include <dcmtk/dcmdata/dcvrdt.h> 16 #include <dcmtk/ofstd/ofstd.h> 18 #define BOOST_DATE_TIME_NO_LIB 21 #if defined(BOOST_ALL_DYN_LINK) 22 #undef BOOST_ALL_DYN_LINK 25 #include <boost/date_time/posix_time/posix_time_types.hpp> 33 #include "dcmtk/dcmdata/dcvrda.h" 40 #define switch3DCase( IOType, T ) \ 42 return LoadDICOMByITK<T>( filenames, correctTilt, tiltInfo, io ); 46 MITK_DEBUG <<
"ITKDICOMSeriesReaderHelper::CanHandleFile " << filename;
47 itk::GDCMImageIO::Pointer tester = itk::GDCMImageIO::New();
48 return tester->CanReadFile( filename.c_str() );
55 if ( filenames.empty() )
58 <<
"Calling LoadDicomSeries with empty filename string container. Probably invalid application logic.";
62 typedef itk::GDCMImageIO DcmIoType;
63 DcmIoType::Pointer io = DcmIoType::New();
67 if ( io->CanReadFile( filenames.front().c_str() ) )
69 io->SetFileName( filenames.front().c_str() );
70 io->ReadImageInformation();
72 if ( io->GetPixelType() == itk::ImageIOBase::SCALAR )
74 switch ( io->GetComponentType() )
77 DcmIoType::USHORT,
unsigned short)
switch3DCase(DcmIoType::SHORT,
short)
79 DcmIoType::ULONG,
long unsigned int)
switch3DCase(DcmIoType::LONG,
long int)
82 <<
"Found unsupported DICOM scalar pixel type: (enum value) " 83 << io->GetComponentType();
86 else if ( io->GetPixelType() == itk::ImageIOBase::RGB )
88 switch ( io->GetComponentType() )
91 DcmIoType::CHAR, itk::RGBPixel<char>)
switch3DCase(DcmIoType::USHORT,
92 itk::RGBPixel<unsigned short>)
94 DcmIoType::UINT, itk::RGBPixel<unsigned int>)
switch3DCase(DcmIoType::INT, itk::RGBPixel<int>)
95 switch3DCase(DcmIoType::ULONG, itk::RGBPixel<long unsigned int>)
97 DcmIoType::FLOAT, itk::RGBPixel<float>)
switch3DCase(DcmIoType::DOUBLE,
98 itk::RGBPixel<double>) default
100 <<
"Found unsupported DICOM scalar pixel type: (enum value) " 101 << io->GetComponentType();
109 catch (
const itk::MemoryAllocationError& e )
111 MITK_ERROR <<
"Out of memory. Cannot load DICOM series: " << e.what();
113 catch (
const std::exception& e )
115 MITK_ERROR <<
"Error encountered when loading DICOM series:" << e.what();
119 MITK_ERROR <<
"Unspecified error encountered when loading DICOM series.";
125 #define switch3DnTCase( IOType, T ) \ 127 return LoadDICOMByITK3DnT<T>( filenamesLists, correctTilt, tiltInfo, io ); 133 if ( filenamesLists.empty() || filenamesLists.front().empty() )
136 <<
"Calling LoadDicomSeries with empty filename string container. Probably invalid application logic.";
140 typedef itk::GDCMImageIO DcmIoType;
141 DcmIoType::Pointer io = DcmIoType::New();
145 if ( io->CanReadFile( filenamesLists.front().front().c_str() ) )
147 io->SetFileName( filenamesLists.front().front().c_str() );
148 io->ReadImageInformation();
150 if ( io->GetPixelType() == itk::ImageIOBase::SCALAR )
152 switch ( io->GetComponentType() )
161 <<
"Found unsupported DICOM scalar pixel type: (enum value) " 162 << io->GetComponentType();
165 else if ( io->GetPixelType() == itk::ImageIOBase::RGB )
167 switch ( io->GetComponentType() )
171 DcmIoType::USHORT, itk::RGBPixel<unsigned short>)
switch3DnTCase(DcmIoType::SHORT,
172 itk::RGBPixel<short>)
174 DcmIoType::INT, itk::RGBPixel<int>)
switch3DnTCase(DcmIoType::ULONG,
175 itk::RGBPixel<long unsigned int>)
177 DcmIoType::FLOAT, itk::RGBPixel<float>)
switch3DnTCase(DcmIoType::DOUBLE,
178 itk::RGBPixel<double>) default
180 <<
"Found unsupported DICOM scalar pixel type: (enum value) " 181 << io->GetComponentType();
189 catch (
const itk::MemoryAllocationError& e )
191 MITK_ERROR <<
"Out of memory. Cannot load DICOM series: " << e.what();
193 catch (
const std::exception& e )
195 MITK_ERROR <<
"Error encountered when loading DICOM series:" << e.what();
199 MITK_ERROR <<
"Unspecified error encountered when loading DICOM series.";
206 const std::string& timeString,
209 OFString content( timeString.c_str() );
211 if ( !dateString.empty() )
213 content = OFString( dateString.c_str() ).append( content );
220 OFString currentDate;
221 DcmDate::getCurrentDate( currentDate );
222 content = currentDate.append( content );
225 const OFCondition result = DcmDateTime::getOFDateTimeFromString( content, time );
227 return result.good();
232 const boost::gregorian::date boostDate(
233 time.getDate().getYear(), time.getDate().getMonth(), time.getDate().getDay() );
235 const boost::posix_time::time_duration boostTime =
236 boost::posix_time::hours( time.getTime().getHour() )
237 + boost::posix_time::minutes( time.getTime().getMinute() )
238 + boost::posix_time::seconds( static_cast<int>(time.getTime().getSecond()) )
239 + boost::posix_time::milliseconds( time.getTime().getMilliSecond() );
241 boost::posix_time::ptime result( boostDate, boostTime );
248 OFDateTime result = time1;
250 if ( ( time2.getDate() < time1.getDate() )
251 || ( ( time2.getDate() == time1.getDate() ) && ( time2.getTime() < time1.getTime() ) ) )
261 OFDateTime result = time1;
263 if ( ( time2.getDate() > time1.getDate() )
264 || ( ( time2.getDate() == time1.getDate() ) && ( time2.getTime() > time1.getTime() ) ) )
277 ::boost::posix_time::time_duration duration = stopTime - startTime;
279 return duration.total_milliseconds();
282 bool mitk::ITKDICOMSeriesReaderHelper::ExtractDateTimeBoundsAndTriggerOfTimeStep(
286 filescanner->SetInputFiles(filenamesOfTimeStep);
300 for (
auto pos = frameList.cbegin(); pos != frameList.cend(); ++pos)
304 const std::string triggerTimeStr = (*pos)->GetTagValueAsString(
TriggerTimeTag).value;
306 OFDateTime aqDateTime;
309 OFBool convertTriggerResult;
310 mitk::ScalarType triggerTime = OFStandard::atof(triggerTimeStr.c_str(), &convertTriggerResult);
316 bounds[0] = aqDateTime;
317 bounds[1] = aqDateTime;
328 if (convertTriggerResult)
332 triggerBounds[0] = triggerTime;
333 triggerBounds[1] = triggerTime;
338 triggerBounds[0] =
std::min(triggerBounds[0], triggerTime);
339 triggerBounds[1] =
std::max(triggerBounds[1], triggerTime);
348 bool mitk::ITKDICOMSeriesReaderHelper::ExtractTimeBoundsOfTimeStep(
351 DateTimeBounds aqDTBounds;
354 bool result = ExtractDateTimeBoundsAndTriggerOfTimeStep(filenamesOfTimeStep, aqDTBounds, triggerBounds);
360 lowerBound = triggerBounds[0];
361 upperBound = triggerBounds[1];
364 bounds[0] = lowerBound;
365 bounds[1] = upperBound;
370 mitk::ITKDICOMSeriesReaderHelper::TimeBoundsList
371 mitk::ITKDICOMSeriesReaderHelper::ExtractTimeBoundsOfTimeSteps(
374 TimeBoundsList result;
379 DateTimeBounds baselineDateTimeBounds;
381 auto pos = filenamesOfTimeSteps.cbegin();
382 ExtractDateTimeBoundsAndTriggerOfTimeStep(*pos, baselineDateTimeBounds, triggerBounds);
383 baseLine = baselineDateTimeBounds[0];
387 result.push_back( bounds );
392 pos != filenamesOfTimeSteps.cend();
399 if ( ExtractTimeBoundsOfTimeStep( *pos, dateTimeBounds, baseLine ) )
402 bounds[0] = dateTimeBounds[0];
403 bounds[1] = dateTimeBounds[1];
406 result.push_back( bounds );
413 mitk::ITKDICOMSeriesReaderHelper::GenerateTimeGeometry(
const BaseGeometry* templateGeometry,
414 const TimeBoundsList& boundsList )
419 const auto boundListSize = boundsList.size();
420 for ( std::size_t pos = 0; pos < boundListSize; ++pos )
422 check += boundsList[pos][0];
423 check += boundsList[pos][1];
430 newTimeGeometry->Initialize( templateGeometry, boundListSize );
431 timeGeometry = newTimeGeometry.GetPointer();
436 newTimeGeometry->ClearAllGeometries();
437 newTimeGeometry->ReserveSpaceForGeometries( boundListSize );
439 for ( std::size_t pos = 0; pos < boundListSize; ++pos )
442 if ( pos + 1 < boundListSize )
446 bounds[1] = boundsList[pos + 1][0];
449 newTimeGeometry->AppendNewTimeStepClone(templateGeometry, bounds[0], bounds[1]);
451 timeGeometry = newTimeGeometry.GetPointer();
OFDateTime GetUpperDateTime(const OFDateTime &time1, const OFDateTime &time2)
itk::FixedArray< ScalarType, 2 > TimeBounds
Standard typedef for time-bounds.
static bool CanHandleFile(const std::string &filename)
static const DICOMTag AcquisitionTimeTag
Representation of a DICOM tag.
Image::Pointer Load(const StringContainer &filenames, bool correctTilt, const GantryTiltInformation &tiltInfo)
itk::SmartPointer< Self > Pointer
OFDateTime GetLowerDateTime(const OFDateTime &time1, const OFDateTime &time2)
Image::Pointer Load3DnT(const StringContainerList &filenamesLists, bool correctTilt, const GantryTiltInformation &tiltInfo)
#define switch3DnTCase(IOType, T)
bool ConvertDICOMDateTimeString(const std::string &dateString, const std::string &timeString, OFDateTime &time)
static const DICOMTag AcquisitionDateTag
std::list< StringContainer > StringContainerList
itk::SmartPointer< Self > Pointer
std::vector< DICOMDatasetAccessingImageFrameInfo::Pointer > DICOMDatasetAccessingImageFrameList
itk::SmartPointer< Self > Pointer
boost::posix_time::ptime ConvertOFDateTimeToPTime(const OFDateTime &time)
MITKCORE_EXPORT const ScalarType eps
static const DICOMTag TriggerTimeTag
double ComputeMiliSecDuration(const OFDateTime &start, const OFDateTime &stop)
std::vector< std::string > StringContainer
#define switch3DCase(IOType, T)