diff --git a/testing/validation/VoxelizationDVHComparisonTest.cpp b/testing/validation/VoxelizationDVHComparisonTest.cpp index 11260a3..6d4aa17 100644 --- a/testing/validation/VoxelizationDVHComparisonTest.cpp +++ b/testing/validation/VoxelizationDVHComparisonTest.cpp @@ -1,176 +1,170 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 1333 $ (last changed revision) -// @date $Date: 2016-04-22 11:12:14 +0200 (Fr, 22 Apr 2016) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include #include "litCheckMacros.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbDVHCalculator.h" #include "rttbBoostMaskAccessor.h" #include "rttbDVHXMLFileWriter.h" #include "rttbDVHXMLFileReader.h" #include "../io/other/CompareDVH.h" namespace rttb { namespace testing { /*! @brief VoxelizationDVHComparisonTests. Computes the DVH difference of different voxelizations (OTB/Boost legacy/Boost) Writes the difference in a DVH and saves in a file */ core::DoseIteratorInterface::Pointer createMaskDoseIterator(masks::boost::BoostMaskAccessor::StructTypePointer rtstruct, core::GenericDoseIterator::DoseAccessorPointer doseAccessor, const std::string& voxelizationType) { core::GenericMaskedDoseIterator::MaskAccessorPointer spMaskAccessor; if (voxelizationType == "Boost"){ auto spBoostRedesignMaskAccessor = ::boost::make_shared(rtstruct, doseAccessor->getGeometricInfo()); spBoostRedesignMaskAccessor->updateMask(); spMaskAccessor = spBoostRedesignMaskAccessor; } auto spMaskedDoseIteratorTmp = ::boost::make_shared(spMaskAccessor, doseAccessor); core::DoseIteratorInterface::Pointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); return spMaskedDoseIterator; } rttb::core::DVH calcDVH(core::DVHCalculator::DoseIteratorPointer doseIterator, const IDType& structUID, const IDType& doseUID) { rttb::core::DVHCalculator calc(doseIterator, structUID, doseUID); rttb::core::DVH dvh = *(calc.generateDVH()); return dvh; } void writeCumulativeDVH(const std::string& filename, rttb::core::DVH dvh) { DVHType typeCum = { DVHType::Cumulative }; io::other::DVHXMLFileWriter dvhWriter(filename, typeCum); dvhWriter.writeDVH(boost::make_shared(dvh)); } int VoxelizationDVHComparisonTest(int argc, char* argv[]) { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::StructureSet::Pointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; std::string RTSTRUCT_FILENAME; std::string RTDOSE_FILENAME; std::string RTDVH_XML_OTB_DIRECTORY; std::string RTDVH_XML_BOOST_LEGACY_DIRECTORY; std::string RTDVH_XML_BOOST_DIRECTORY; if (argc > 5) { RTSTRUCT_FILENAME = argv[1]; RTDOSE_FILENAME = argv[2]; RTDVH_XML_OTB_DIRECTORY = argv[3]; RTDVH_XML_BOOST_LEGACY_DIRECTORY = argv[4]; RTDVH_XML_BOOST_DIRECTORY = argv[5]; } // read dicom-rt dose io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //create a vector of MaskAccessors (one for each structure) StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); //create directory boost::filesystem::create_directories(RTDVH_XML_BOOST_DIRECTORY); //start evaluation clock_t start(clock()); if (rtStructureSet->getNumberOfStructures() > 0) { for (int j = 0; j < static_cast(rtStructureSet->getNumberOfStructures()); j++) { std::cout << rtStructureSet->getStructure(j)->getLabel() << std::endl; auto spMaskedDoseIteratorBoostRedesign = createMaskDoseIterator(rtStructureSet->getStructure(j), doseAccessor1, "Boost"); auto label = rtStructureSet->getStructure(j)->getLabel(); ::boost::replace_all(label, "/", "_"); boost::filesystem::path dvhOTBFilename(RTDVH_XML_OTB_DIRECTORY); dvhOTBFilename /= "DVH_" + label + ".xml"; boost::filesystem::path dvhBoostFilename(RTDVH_XML_BOOST_LEGACY_DIRECTORY); dvhBoostFilename /= "DVH_" + label + ".xml"; io::other::DVHXMLFileReader dvhReaderOTB(dvhOTBFilename.string()); auto dvhOTB = dvhReaderOTB.generateDVH(); io::other::DVHXMLFileReader dvhReaderBoost(dvhBoostFilename.string()); auto dvhBoost = dvhReaderBoost.generateDVH(); auto dvhBoostRedesign = calcDVH(spMaskedDoseIteratorBoostRedesign, (rtStructureSet->getStructure(j))->getUID(), doseAccessor1->getUID()); boost::filesystem::path dvhBoostRedesignFilename(RTDVH_XML_BOOST_DIRECTORY); dvhBoostRedesignFilename /= "DVH_" + label + ".xml"; writeCumulativeDVH(dvhBoostRedesignFilename.string(), dvhBoostRedesign); std::cout << "=== Dose 1 Structure " << j << "===" << std::endl; std::cout << "with OTB voxelization: " << std::endl; std::cout << dvhOTB << std::endl; std::cout << "with Boost_LEGACY voxelization: " << std::endl; std::cout << dvhBoost << std::endl; std::cout << "with Boost voxelization: " << std::endl; std::cout << dvhBoostRedesign << std::endl; //compare DVH for different voxelizations auto diffDVH = computeDiffDVH(dvhOTB, boost::make_shared(dvhBoostRedesign)); boost::filesystem::path dvhBoostRedesignDiffFilename(RTDVH_XML_BOOST_DIRECTORY); dvhBoostRedesignDiffFilename /= "DVHDiff_" + label + ".xml"; writeCumulativeDVH(dvhBoostRedesignDiffFilename.string(), *diffDVH); } } clock_t finish(clock()); std::cout << "DVH Calculation time: " << finish - start << " ms" << std::endl; RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/validation/VoxelizationValidationTest.cpp b/testing/validation/VoxelizationValidationTest.cpp index 2d3ff95..ae8808a 100644 --- a/testing/validation/VoxelizationValidationTest.cpp +++ b/testing/validation/VoxelizationValidationTest.cpp @@ -1,160 +1,154 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 1495 $ (last changed revision) -// @date $Date: 2016-09-29 16:17:47 +0200 (Do, 29 Sep 2016) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #include #include #include #include "litCheckMacros.h" #include "rttbBaseType.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbDicomDoseAccessor.h" #include "rttbDicomFileDoseAccessorGenerator.h" #include "rttbDicomFileStructureSetGenerator.h" #include "rttbBoostMaskAccessor.h" #include "rttbITKImageMaskAccessorConverter.h" #include "rttbImageWriter.h" #include "rttbBoostMask.h" #include "rttbBoostMaskAccessor.h" #include "rttbITKImageAccessorGenerator.h" #include "rttbITKImageFileAccessorGenerator.h" #include "rttbInvalidParameterException.h" #include "itkSubtractImageFilter.h" #include "itkImageFileReader.h" namespace rttb { namespace testing { io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer subtractImages(const io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer image1, const io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer image2) { typedef itk::SubtractImageFilter SubtractImageFilterType; SubtractImageFilterType::Pointer subtractFilter = SubtractImageFilterType::New(); subtractFilter->SetInput1(image1); subtractFilter->SetInput2(image2); //since the image origin may be modified through the writing process a bit subtractFilter->SetCoordinateTolerance(5e-2); subtractFilter->Update(); return subtractFilter->GetOutput(); } /*! @brief VoxelizationValidationTest. Compare the new boost voxelization to the OTB voxelization Check the creating of new boost masks for files where the old boost voxelization failed. */ int VoxelizationValidationTest(int argc, char* argv[]) { PREPARE_DEFAULT_TEST_REPORTING; typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; typedef core::StructureSet::Pointer StructureSetPointer; std::string RTSTRUCT_FILENAME; std::string RTDOSE_FILENAME; std::string BoostMask_DIRNAME; std::string OTBMask_DIRNAME; if (argc > 4) { RTSTRUCT_FILENAME = argv[1]; RTDOSE_FILENAME = argv[2]; BoostMask_DIRNAME = argv[3]; OTBMask_DIRNAME = argv[4]; } //create directory boost::filesystem::create_directories(BoostMask_DIRNAME); /* read dicom-rt dose */ io::dicom::DicomFileDoseAccessorGenerator doseAccessorGenerator1(RTDOSE_FILENAME.c_str()); DoseAccessorPointer doseAccessor1(doseAccessorGenerator1.generateDoseAccessor()); //create a vector of MaskAccessors (one for each structure) StructureSetPointer rtStructureSet = io::dicom::DicomFileStructureSetGenerator( RTSTRUCT_FILENAME.c_str()).generateStructureSet(); if (rtStructureSet->getNumberOfStructures() > 0) { //do not compute structure "Aussenkontur" since it is very large (15000 cm³) for (size_t j = 1; j < rtStructureSet->getNumberOfStructures(); j++) { std::cout << j << ": " << rtStructureSet->getStructure(j)->getLabel() << std::endl; //read OTB mask image boost::filesystem::path otbMaskFilename(OTBMask_DIRNAME); otbMaskFilename /= boost::lexical_cast(j)+".mhd"; typedef itk::ImageFileReader ReaderType; ReaderType::Pointer readerOTB = ReaderType::New(); readerOTB->SetFileName(otbMaskFilename.string()); readerOTB->Update(); const io::itk::ITKImageMaskAccessor::ITKMaskImageType::Pointer otbMaskImage = readerOTB->GetOutput(); //create Boost MaskAccessor clock_t startR(clock()); MaskAccessorPointer boostMaskRPtr = ::boost::make_shared (rtStructureSet->getStructure(j), doseAccessor1->getGeometricInfo()); CHECK_NO_THROW(boostMaskRPtr->updateMask()); clock_t finishR(clock()); std::cout << "Boost Mask Calculation: " << finishR - startR << " ms" << std::endl; rttb::io::itk::ITKImageMaskAccessorConverter itkConverterR(boostMaskRPtr); CHECK(itkConverterR.process()); boost::filesystem::path redesignFilename(BoostMask_DIRNAME); redesignFilename /= boost::lexical_cast(j)+".nrrd"; rttb::io::itk::ImageWriter writerR(redesignFilename.string(), itkConverterR.getITKImage().GetPointer()); CHECK(writerR.writeFile()); auto subtractedRedesignImage = subtractImages(otbMaskImage, itkConverterR.getITKImage()); boost::filesystem::path subtractRedesignFilename(BoostMask_DIRNAME); subtractRedesignFilename /= boost::lexical_cast(j)+"_subtracted.nrrd"; rttb::io::itk::ImageWriter writerRSubtracted(subtractRedesignFilename.string(), subtractedRedesignImage.GetPointer()); CHECK(writerRSubtracted.writeFile()); } } RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb diff --git a/testing/validation/rttbValidationTests.cpp b/testing/validation/rttbValidationTests.cpp index 352b629..5575cb1 100644 --- a/testing/validation/rttbValidationTests.cpp +++ b/testing/validation/rttbValidationTests.cpp @@ -1,65 +1,58 @@ // ----------------------------------------------------------------------- // RTToolbox - DKFZ radiotherapy quantitative evaluation library // // Copyright (c) German Cancer Research Center (DKFZ), // Software development for Integrated Diagnostics and Therapy (SIDT). // ALL RIGHTS RESERVED. // See rttbCopyright.txt or // http://www.dkfz.de/en/sidt/projects/rttb/copyright.html [^] // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notices for more information. // //------------------------------------------------------------------------ -/*! -// @file -// @version $Revision: 1388 $ (last changed revision) -// @date $Date: 2016-07-04 14:03:35 +0200 (Mo, 04 Jul 2016) $ (last change date) -// @author $Author: hentsch $ (last changed by) -*/ // this file defines the rttbCoreTests for the test driver // and all it expects is that you have a function called RegisterTests #if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif - #include "litMultiTestsMain.h" #include "RTToolboxConfigure.h" namespace rttb { namespace testing { void registerTests() { LIT_REGISTER_TEST(VoxelizationDVHComparisonTest); LIT_REGISTER_TEST(VoxelizationValidationTest); } } } int main(int argc, char* argv[]) { int result = 0; rttb::testing::registerTests(); try { result = lit::multiTestsMain(argc, argv); } catch (const std::exception& /*e*/) { result = -1; } catch (...) { result = -1; } return result; }