28 void mitk::TestDCMLoading::SetDefaultLocale()
31 if (m_PreviousCLocale ==
nullptr)
33 m_PreviousCLocale = setlocale(LC_NUMERIC,
nullptr);
36 setlocale(LC_NUMERIC,
"C");
38 m_PreviousCppLocale = std::cin.getloc();
46 void mitk::TestDCMLoading::ResetUserLocale()
48 if (m_PreviousCLocale)
50 setlocale(LC_NUMERIC, m_PreviousCLocale);
52 std::cin.imbue(m_PreviousCppLocale);
53 std::cout.imbue(m_PreviousCppLocale);
55 m_PreviousCLocale =
nullptr;
62 for (
auto iter = files.begin(); iter != files.end(); ++iter)
73 for (DicomSeriesReader::FileNamesGrouping::const_iterator seriesIter = seriesInFiles.begin();
74 seriesIter != seriesInFiles.end();
80 files,
true,
true,
true,
nullptr, preLoadedVolume);
86 result.push_back(image);
96 std::string mitk::TestDCMLoading::ComponentTypeToString(
int type)
98 if (type == itk::ImageIOBase::UCHAR)
100 else if (type == itk::ImageIOBase::CHAR)
102 else if (type == itk::ImageIOBase::USHORT)
104 else if (type == itk::ImageIOBase::SHORT)
106 else if (type == itk::ImageIOBase::UINT)
108 else if (type == itk::ImageIOBase::INT)
110 else if (type == itk::ImageIOBase::ULONG)
112 else if (type == itk::ImageIOBase::LONG)
114 else if (type == itk::ImageIOBase::FLOAT)
116 else if (type == itk::ImageIOBase::DOUBLE)
123 #define DumpLine(field, data) DumpILine(0, field, data)
126 #define DumpILine(indent, field, data) \
129 std::string DumpLine_INDENT; \
130 DumpLine_INDENT.resize(indent, ' '); \
131 result << DumpLine_INDENT << field << ": " << data << "\n"; \
137 std::stringstream result;
139 if (image ==
nullptr)
149 result <<
"Dimensions: ";
150 for (
unsigned int dim = 0; dim < image->
GetDimension(); ++dim)
155 result <<
"Geometry: \n";
164 const AffineTransform3D::MatrixType &matrix = transform->GetMatrix();
165 for (
unsigned int i = 0; i < 3; ++i)
166 for (
unsigned int j = 0; j < 3; ++j)
167 result << matrix[i][j] <<
" ";
172 const AffineTransform3D::OutputVectorType &
offset = transform->GetOffset();
173 for (
unsigned int i = 0; i < 3; ++i)
174 result << offset[i] <<
" ";
179 const AffineTransform3D::InputPointType ¢er = transform->GetCenter();
180 for (
unsigned int i = 0; i < 3; ++i)
181 result << center[i] <<
" ";
186 const AffineTransform3D::OutputVectorType &translation = transform->GetTranslation();
187 for (
unsigned int i = 0; i < 3; ++i)
188 result << translation[i] <<
" ";
193 const double *scale = transform->GetScale();
194 for (
unsigned int i = 0; i < 3; ++i)
195 result << scale[i] <<
" ";
201 for (
unsigned int i = 0; i < 3; ++i)
202 result << origin[i] <<
" ";
208 for (
unsigned int i = 0; i < 3; ++i)
209 result << spacing[i] <<
" ";
215 for (
unsigned int i = 0; i < 2; ++i)
216 result << timeBounds[i] <<
" ";
226 std::string mitk::TestDCMLoading::trim(
const std::string &pString,
const std::string &pWhitespace)
228 const size_t beginStr = pString.find_first_not_of(pWhitespace);
229 if (beginStr == std::string::npos)
235 const size_t endStr = pString.find_last_not_of(pWhitespace);
236 const size_t range = endStr - beginStr + 1;
238 return pString.substr(beginStr, range);
241 std::string mitk::TestDCMLoading::reduce(
const std::string &pString,
242 const std::string &pFill,
243 const std::string &pWhitespace)
246 std::string result(trim(pString, pWhitespace));
249 size_t beginSpace = result.find_first_of(pWhitespace);
250 while (beginSpace != std::string::npos)
252 const size_t endSpace = result.find_first_not_of(pWhitespace, beginSpace);
253 const size_t range = endSpace - beginSpace;
255 result.replace(beginSpace, range, pFill);
257 const size_t newStart = beginSpace + pFill.length();
258 beginSpace = result.find_first_of(pWhitespace, newStart);
264 bool mitk::TestDCMLoading::CompareSpacedValueFields(
const std::string &reference,
265 const std::string &
test,
271 std::stringstream referenceStream(reduce(reference));
272 std::stringstream testStream(reduce(test));
274 std::string refToken;
275 std::string testToken;
276 while (std::getline(referenceStream, refToken,
' ') && std::getline(testStream, testToken,
' '))
280 if (this->StringToNumber(refToken, refNumber))
282 if (this->StringToNumber(testToken, testNumber))
285 MITK_DEBUG <<
"Reference Token '" << refToken <<
"'"
286 <<
" value " << refNumber <<
", test Token '" << testToken <<
"'"
287 <<
" value " << testNumber;
289 bool old_result = result;
291 result &= (fabs(refNumber - testNumber) < 0.0001 );
293 if (old_result != result)
295 MITK_ERROR << std::setprecision(16) <<
"Reference Token '" << refToken <<
"'"
296 <<
" value " << refNumber <<
", test Token '" << testToken <<
"'"
297 <<
" value " << testNumber;
299 MITK_ERROR <<
"[FALSE] - difference: " << std::setprecision(16) << fabs(refNumber - testNumber)
300 <<
" EPS: " << 0.0001;
305 MITK_ERROR << refNumber <<
" cannot be compared to '" << testToken <<
"'";
311 <<
" handled as string";
312 result &= refToken == testToken;
316 if (std::getline(referenceStream, refToken,
' '))
318 MITK_ERROR <<
"Reference string still had values when test string was already parsed: ref '" << reference
319 <<
"', test '" << test <<
"'";
322 else if (std::getline(testStream, testToken,
' '))
324 MITK_ERROR <<
"Test string still had values when reference string was already parsed: ref '" << reference
325 <<
"', test '" << test <<
"'";
334 KeyValueMap reference = ParseDump(referenceDump);
335 KeyValueMap test = ParseDump(testDump);
337 bool testResult(
true);
340 for (KeyValueMap::const_iterator refIter = reference.begin(); refIter != reference.end(); ++refIter)
342 const std::string &refKey = refIter->first;
343 const std::string &refValue = refIter->second;
345 if (test.find(refKey) != test.end())
347 const std::string &testValue = test[refKey];
349 bool thisTestResult = CompareSpacedValueFields(refValue, testValue);
350 testResult &= thisTestResult;
352 MITK_DEBUG << refKey <<
": '" << refValue <<
"' == '" << testValue <<
"' ? " << (thisTestResult ?
"YES" :
"NO");
356 MITK_ERROR <<
"Reference dump contains a key'" << refKey <<
"' (value '" << refValue <<
"').";
357 MITK_ERROR <<
"This key is expected to be generated for tests (but was not). Most probably you need to update "
364 for (KeyValueMap::const_iterator testIter = test.begin(); testIter != test.end(); ++testIter)
366 const std::string &key = testIter->first;
367 const std::string &value = testIter->second;
369 if (reference.find(key) == reference.end())
371 MITK_ERROR <<
"Test dump contains an unexpected key'" << key <<
"' (value '" << value <<
"').";
372 MITK_ERROR <<
"This key is not expected. Most probably you need to update your test data.";
380 mitk::TestDCMLoading::KeyValueMap mitk::TestDCMLoading::ParseDump(
const std::string &dump)
382 KeyValueMap parsedResult;
384 std::string shredder(dump);
386 std::stack<std::string> surroundingKeys;
388 std::stack<std::string::size_type> expectedIndents;
389 expectedIndents.push(0);
393 std::string::size_type newLinePos = shredder.find(
'\n');
394 if (newLinePos == std::string::npos || newLinePos == 0)
397 std::string
line = shredder.substr(0, newLinePos);
398 shredder = shredder.erase(0, newLinePos + 1);
400 std::string::size_type keyPosition = line.find_first_not_of(
' ');
401 std::string::size_type colonPosition = line.find(
':');
403 std::string key = line.substr(keyPosition, colonPosition - keyPosition);
404 std::string::size_type firstSpacePosition = key.find_first_of(
" ");
405 if (firstSpacePosition != std::string::npos)
407 key.erase(firstSpacePosition);
410 if (keyPosition > expectedIndents.top())
413 expectedIndents.push(keyPosition);
415 else if (keyPosition == expectedIndents.top())
417 if (!surroundingKeys.empty())
419 surroundingKeys.pop();
426 expectedIndents.pop();
427 while (expectedIndents.top() != keyPosition);
430 if (!surroundingKeys.empty())
432 key = surroundingKeys.top() +
"." + key;
435 surroundingKeys.push(key);
437 std::string value = line.substr(colonPosition + 1);
439 MITK_DEBUG <<
" Key: '" << key <<
"' value '" << value <<
"'";
441 parsedResult[key] = value;
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
itk::FixedArray< ScalarType, 2 > TimeBounds
Standard typedef for time-bounds.
std::string DumpImageInformation(const Image *image)
Dump relevant image information for later comparison.
Follow Up Storage - Class to facilitate loading/accessing structured follow-up data.
static DataNode::Pointer LoadDicomSeries(const StringContainer &filenames, bool sort=true, bool load4D=true, bool correctGantryTilt=true, UpdateCallBackMethod callback=nullptr, itk::SmartPointer< Image > preLoadedImageBlock=nullptr)
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
DicomSeriesReader::StringContainer StringContainer
vcl_size_t GetBpe() const
Get the number of bits per element (of an element)
virtual TimeBounds GetTimeBounds() const =0
Get the time bounds (in ms)
static FileNamesGrouping GetSeries(const std::string &dir, bool groupImagesWithGantryTilt, const StringContainer &restrictions=StringContainer())
see other GetSeries().
Image class for storing images.
int GetComponentType() const
Get the component type (the scalar (!) type). Each element may contain m_NumberOfComponents (more tha...
itk::AffineGeometryFrame< ScalarType, 3 >::TransformType AffineTransform3D
const mitk::PixelType GetPixelType(int n=0) const
Returns the PixelType of channel n.
bool CompareImageInformationDumps(const std::string &reference, const std::string &test)
Compare two image information dumps.
std::map< std::string, ImageBlockDescriptor > FileNamesGrouping
std::list< itk::SmartPointer< Image > > ImageList
#define DumpLine(field, data)
unsigned int GetDimension() const
Get dimension of the image.
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
ImageList LoadFiles(const StringContainer &files, itk::SmartPointer< Image > preLoadedVolume=nullptr)
BaseGeometry Describes the geometry of a data object.
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.