/*! * \file Tomato_sameAsShmolli_test.cpp * \author Konrad Werys * \date 2018/08/20 */ #include "CmakeConfigForTomato.h" #ifdef USE_PRIVATE_NR2 #ifdef USE_ITK #include "gtest/gtest.h" #include "Tomato.h" #include "itkImageFileReader.h" #include "itkTestingComparisonImageFilter.h" // TODO: make sure all SNR give the same results // TODO: make sure all nAmoebaFinalCall give the same results /** * \class ActeptanceTests_TomatoTest * \brief based on https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#sharing-resources-between-tests-in-the-same-test-case */ class ActeptanceTests_TomatoFixtureTest : public ::testing::Test { // primitive data types typedef int16_t PixelType; // image data types typedef itk::Image< PixelType, 2 > ImageType2D; typedef itk::ImageFileReader ReadImage2dFilterType; typedef itk::Testing::ComparisonImageFilter ComparisonImageFilter2dType; protected: // Per-test-case set-up. // Called before the first test in this test case. // Can be omitted if not needed. static void SetUpTestCase() { std::string configFilePath = "testData/tomatoConfig_Shmolli_inputFilePaths.yaml"; _tomato_object = new Ox::Tomato(configFilePath); _tomato_object->readAndSort(); _tomato_object->calculate(); _tomato_object->exportToDicom(); std::string output_map_series_number = KWUtil::NumberToString(_tomato_object->_opts->output_map_series_number); std::string output_fitparams_series_number = KWUtil::NumberToString(_tomato_object->_opts->output_fitparams_series_number); _calculatedFilePaths.push_back(_tomato_object->_opts->dir_output_map + KWUtil::PathSeparator() + output_map_series_number + "_T1.dcm"); _calculatedFilePaths.push_back(_tomato_object->_opts->dir_output_fitparams + KWUtil::PathSeparator() + output_fitparams_series_number + "_R2.dcm"); _calculatedFilePaths.push_back(_tomato_object->_opts->dir_output_fitparams + KWUtil::PathSeparator() + output_fitparams_series_number + "_A.dcm"); _calculatedFilePaths.push_back(_tomato_object->_opts->dir_output_fitparams + KWUtil::PathSeparator() + output_fitparams_series_number + "_B.dcm"); _calculatedFilePaths.push_back(_tomato_object->_opts->dir_output_fitparams + KWUtil::PathSeparator() + output_fitparams_series_number + "_T1star.dcm"); _calculatedFilePaths.push_back(_tomato_object->_opts->dir_output_fitparams + KWUtil::PathSeparator() + output_fitparams_series_number + "_ShMolliRange.dcm"); _calculatedFilePaths.push_back(_tomato_object->_opts->dir_output_fitparams + KWUtil::PathSeparator() + output_fitparams_series_number + "_RelSNRFinal.dcm"); _calculatedFilePaths.push_back(_tomato_object->_opts->dir_output_fitparams + KWUtil::PathSeparator() + output_fitparams_series_number + "_nAmebaCallFinal.dcm"); _originalFilePaths.push_back("testData/dicom/Hcmr_Phantom_1916_260C/Konrad_Shmolli/ShMOLLI_192i_e11_T1MAP_14/IM-0003-0001.dcm"); _originalFilePaths.push_back("testData/dicom/Hcmr_Phantom_1916_260C/Konrad_Shmolli/ShMOLLI_192i_e11_FITPARAMS_15/IM-0004-0001.dcm"); _originalFilePaths.push_back("testData/dicom/Hcmr_Phantom_1916_260C/Konrad_Shmolli/ShMOLLI_192i_e11_FITPARAMS_15/IM-0004-0002.dcm"); _originalFilePaths.push_back("testData/dicom/Hcmr_Phantom_1916_260C/Konrad_Shmolli/ShMOLLI_192i_e11_FITPARAMS_15/IM-0004-0003.dcm"); _originalFilePaths.push_back("testData/dicom/Hcmr_Phantom_1916_260C/Konrad_Shmolli/ShMOLLI_192i_e11_FITPARAMS_15/IM-0004-0004.dcm"); _originalFilePaths.push_back("testData/dicom/Hcmr_Phantom_1916_260C/Konrad_Shmolli/ShMOLLI_192i_e11_FITPARAMS_15/IM-0004-0005.dcm"); _originalFilePaths.push_back("testData/dicom/Hcmr_Phantom_1916_260C/Konrad_Shmolli/ShMOLLI_192i_e11_FITPARAMS_15/IM-0004-0006.dcm"); _originalFilePaths.push_back("testData/dicom/Hcmr_Phantom_1916_260C/Konrad_Shmolli/ShMOLLI_192i_e11_FITPARAMS_15/IM-0004-0007.dcm"); } // Per-test-case tear-down. // Called after the last test in this test case. // Can be omitted if not needed. static void TearDownTestCase() { delete _tomato_object; _tomato_object = NULL; } // You can define per-test set-up logic as usual. virtual void SetUp() { readerOriginalT1Map = ReadImage2dFilterType::New(); readerCalculatedT1Map = ReadImage2dFilterType::New(); diff = ComparisonImageFilter2dType::New(); } // You can define per-test tear-down logic as usual. virtual void TearDown() { } public: // Some expensive resource shared by all tests. static Ox::Tomato* _tomato_object; static std::vector _originalFilePaths; static std::vector _calculatedFilePaths; ReadImage2dFilterType::Pointer readerOriginalT1Map; ReadImage2dFilterType::Pointer readerCalculatedT1Map; ComparisonImageFilter2dType::Pointer diff; }; Ox::Tomato* ActeptanceTests_TomatoFixtureTest::_tomato_object = NULL; std::vector ActeptanceTests_TomatoFixtureTest::_originalFilePaths; std::vector ActeptanceTests_TomatoFixtureTest::_calculatedFilePaths; TEST_F(ActeptanceTests_TomatoFixtureTest, sameAsShmolli_T1) { int i = 0; // T1 map readerOriginalT1Map->SetFileName(_originalFilePaths.at(i)); readerCalculatedT1Map->SetFileName(_calculatedFilePaths.at(i)); // for comparing the images diff->SetValidInput(readerOriginalT1Map->GetOutput()); diff->SetTestInput(readerCalculatedT1Map->GetOutput()); diff->Update(); // compare diff->UpdateLargestPossibleRegion(); double tolerance = 2; if (diff->GetMaximumDifference() > tolerance) std::cout << "Number of unequal pixels = " << diff->GetNumberOfPixelsWithDifferences() << std::endl; ASSERT_LE(diff->GetMaximumDifference(), tolerance); } TEST_F(ActeptanceTests_TomatoFixtureTest, sameAsShmolli_R2) { int i = 1; // R2 map readerOriginalT1Map->SetFileName(_originalFilePaths.at(i)); readerCalculatedT1Map->SetFileName(_calculatedFilePaths.at(i)); // for comparing the images diff->SetValidInput(readerOriginalT1Map->GetOutput()); diff->SetTestInput(readerCalculatedT1Map->GetOutput()); diff->Update(); // compare diff->UpdateLargestPossibleRegion(); ASSERT_LE(diff->GetNumberOfPixelsWithDifferences(), 300); // max allowed error is 2 } TEST_F(ActeptanceTests_TomatoFixtureTest, sameAsShmolli_A) { int i = 2; // A map readerOriginalT1Map->SetFileName(_originalFilePaths.at(i)); readerCalculatedT1Map->SetFileName(_calculatedFilePaths.at(i)); // for comparing the images diff->SetValidInput(readerOriginalT1Map->GetOutput()); diff->SetTestInput(readerCalculatedT1Map->GetOutput()); diff->Update(); // compare diff->UpdateLargestPossibleRegion(); ASSERT_LE(diff->GetMaximumDifference(), 2); // max allowed error is 2 } TEST_F(ActeptanceTests_TomatoFixtureTest, sameAsShmolli_B) { int i = 3; // B map readerOriginalT1Map->SetFileName(_originalFilePaths.at(i)); readerCalculatedT1Map->SetFileName(_calculatedFilePaths.at(i)); // for comparing the images diff->SetValidInput(readerOriginalT1Map->GetOutput()); diff->SetTestInput(readerCalculatedT1Map->GetOutput()); diff->Update(); // compare diff->UpdateLargestPossibleRegion(); ASSERT_LE(diff->GetMaximumDifference(), 2); // max allowed error is 2 } TEST_F(ActeptanceTests_TomatoFixtureTest, sameAsShmolli_T1star) { int i = 4; // T1star map readerOriginalT1Map->SetFileName(_originalFilePaths.at(i)); readerCalculatedT1Map->SetFileName(_calculatedFilePaths.at(i)); // for comparing the images diff->SetValidInput(readerOriginalT1Map->GetOutput()); diff->SetTestInput(readerCalculatedT1Map->GetOutput()); diff->Update(); // compare diff->UpdateLargestPossibleRegion(); ASSERT_LE(diff->GetMaximumDifference(), 2); // max allowed error is 2 } TEST_F(ActeptanceTests_TomatoFixtureTest, sameAsShmolli_ShmolliRange) { int i = 5; // ShmolliRange map readerOriginalT1Map->SetFileName(_originalFilePaths.at(i)); readerCalculatedT1Map->SetFileName(_calculatedFilePaths.at(i)); // for comparing the images diff->SetValidInput(readerOriginalT1Map->GetOutput()); diff->SetTestInput(readerCalculatedT1Map->GetOutput()); diff->Update(); // compare diff->UpdateLargestPossibleRegion(); ASSERT_LE(diff->GetMaximumDifference(), 2); // max allowed error is 2 } #endif // USE_PRIVATE_NR2 #endif // USE_ITK