diff --git a/code/io/other/rttbDoseStatisticsXMLWriter.cpp b/code/io/other/rttbDoseStatisticsXMLWriter.cpp index 9529669..7cad904 100644 --- a/code/io/other/rttbDoseStatisticsXMLWriter.cpp +++ b/code/io/other/rttbDoseStatisticsXMLWriter.cpp @@ -1,278 +1,284 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #include #include #include "rttbDoseStatisticsXMLWriter.h" #include "rttbInvalidParameterException.h" #include "rttbDataNotAvailableException.h" namespace rttb { namespace io { namespace other { static const std::string xmlattrXTag = ".x"; static const std::string xmlattrNameTag = ".name"; static const std::string statisticsTag = "statistics.results"; static const std::string propertyTag = "property"; static const std::string columnSeparator = "@"; boost::property_tree::ptree writeDoseStatistics(DoseStatisticsPtr aDoseStatistics) { using boost::property_tree::ptree; ptree pt; ptree numberOfVoxelsNode = createNodeWithNameAttribute(aDoseStatistics->getNumberOfVoxels(), "numberOfVoxels"); pt.add_child(statisticsTag + "." + propertyTag, numberOfVoxelsNode); - ptree volumeNode = createNodeWithNameAttribute(aDoseStatistics->getVolume(), "volume"); + ptree volumeNode = createNodeWithNameAttribute(static_cast(aDoseStatistics->getVolume()), + "volume"); pt.add_child(statisticsTag + "." + propertyTag, volumeNode); - ptree minimumNode = createNodeWithNameAttribute(aDoseStatistics->getMinimum(), "minimum"); + ptree minimumNode = createNodeWithNameAttribute(static_cast(aDoseStatistics->getMinimum()), + "minimum"); auto minimumPositions = aDoseStatistics->getMinimumPositions(); std::vector >::iterator pairItMin = minimumPositions->begin(); int count = 0; for (; pairItMin != minimumPositions->end() && count < 100; ++pairItMin) //output max. 100 minimum { VoxelGridID voxelID = pairItMin->second; ptree voxelMinPositions; voxelMinPositions.add("voxelGridID", voxelID); minimumNode.add_child("voxel", voxelMinPositions); count++; } pt.add_child(statisticsTag + "." + propertyTag, minimumNode); - ptree maximumNode = createNodeWithNameAttribute(aDoseStatistics->getMaximum(), "maximum"); + ptree maximumNode = createNodeWithNameAttribute(static_cast(aDoseStatistics->getMaximum()), + "maximum"); auto maximumPositions = aDoseStatistics->getMaximumPositions(); std::vector >::iterator pairItMax = maximumPositions->begin(); count = 0; for (; pairItMax != maximumPositions->end() && count < 100; ++pairItMax) //output max. 100 maximum { VoxelGridID voxelID = pairItMax->second; ptree voxelMaxPositions; voxelMaxPositions.add("voxelGridID", voxelID); maximumNode.add_child("voxel", voxelMaxPositions); count++; } pt.add_child(statisticsTag + "." + propertyTag, maximumNode); - ptree meanNode = createNodeWithNameAttribute(aDoseStatistics->getMean(), "mean"); + ptree meanNode = createNodeWithNameAttribute(static_cast(aDoseStatistics->getMean()), + "mean"); pt.add_child(statisticsTag + "." + propertyTag, meanNode); - ptree sdNode = createNodeWithNameAttribute(aDoseStatistics->getStdDeviation(), "standardDeviation"); + ptree sdNode = createNodeWithNameAttribute(static_cast(aDoseStatistics->getStdDeviation()), + "standardDeviation"); pt.add_child(statisticsTag + "." + propertyTag, sdNode); - ptree varianceNode = createNodeWithNameAttribute(aDoseStatistics->getVariance(), "variance"); + ptree varianceNode = createNodeWithNameAttribute(static_cast(aDoseStatistics->getVariance()), + "variance"); pt.add_child(statisticsTag + "." + propertyTag, varianceNode); double absoluteVolume = aDoseStatistics->getVolume(); double referenceDose = aDoseStatistics->getReferenceDose(); rttb::algorithms::DoseStatistics::DoseToVolumeFunctionType AllVx = aDoseStatistics->getAllVx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllDx = aDoseStatistics->getAllDx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllMOHx = aDoseStatistics->getAllMOHx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllMOCx = aDoseStatistics->getAllMOCx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllMaxOHx = aDoseStatistics->getAllMaxOHx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllMinOCx = aDoseStatistics->getAllMinOCx(); rttb::algorithms::DoseStatistics::DoseToVolumeFunctionType::iterator vxIt; rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType::iterator it; for (it = AllDx.begin(); it != AllDx.end(); ++it) { - ptree DxNode = createNodeWithNameAndXAttribute((*it).second, "Dx", + ptree DxNode = createNodeWithNameAndXAttribute(static_cast((*it).second), "Dx", static_cast((*it).first / absoluteVolume * 100)); pt.add_child(statisticsTag + "." + propertyTag, DxNode); } for (vxIt = AllVx.begin(); vxIt != AllVx.end(); ++vxIt) { - ptree VxNode = createNodeWithNameAndXAttribute((*vxIt).second, "Vx", + ptree VxNode = createNodeWithNameAndXAttribute(static_cast((*vxIt).second), "Vx", static_cast((*vxIt).first / referenceDose * 100)); pt.add_child(statisticsTag + "." + propertyTag, VxNode); } for (it = AllMOHx.begin(); it != AllMOHx.end(); ++it) { - ptree mohxNode = createNodeWithNameAndXAttribute((*it).second, "MOHx", + ptree mohxNode = createNodeWithNameAndXAttribute(static_cast((*it).second), "MOHx", static_cast((*it).first / absoluteVolume * 100)); pt.add_child(statisticsTag + "." + propertyTag, mohxNode); } for (it = AllMOCx.begin(); it != AllMOCx.end(); ++it) { - ptree mocxNode = createNodeWithNameAndXAttribute((*it).second, "MOCx", + ptree mocxNode = createNodeWithNameAndXAttribute(static_cast((*it).second), "MOCx", static_cast((*it).first / absoluteVolume * 100)); pt.add_child(statisticsTag + "." + propertyTag, mocxNode); } for (it = AllMaxOHx.begin(); it != AllMaxOHx.end(); ++it) { - ptree maxOhxNode = createNodeWithNameAndXAttribute((*it).second, "MaxOHx", + ptree maxOhxNode = createNodeWithNameAndXAttribute(static_cast((*it).second), "MaxOHx", static_cast((*it).first / absoluteVolume * 100)); pt.add_child(statisticsTag + "." + propertyTag, maxOhxNode); } for (it = AllMinOCx.begin(); it != AllMinOCx.end(); ++it) { - ptree minOCxNode = createNodeWithNameAndXAttribute((*it).second, "MinOCx", + ptree minOCxNode = createNodeWithNameAndXAttribute(static_cast((*it).second), "MinOCx", static_cast((*it).first / absoluteVolume * 100)); pt.add_child(statisticsTag + "." + propertyTag, minOCxNode); } return pt; } void writeDoseStatistics(DoseStatisticsPtr aDoseStatistics, FileNameString aFileName) { boost::property_tree::ptree pt = writeDoseStatistics(aDoseStatistics); try { boost::property_tree::xml_parser::write_xml(aFileName, pt, std::locale(), boost::property_tree::xml_writer_make_settings('\t', 1)); } catch (boost::property_tree::xml_parser_error& /*e*/) { throw core::InvalidParameterException("Write xml failed: xml_parser_error!"); } } XMLString writerDoseStatisticsToString(DoseStatisticsPtr aDoseStatistics) { boost::property_tree::ptree pt = writeDoseStatistics(aDoseStatistics); std::stringstream sstr; try { boost::property_tree::xml_parser::write_xml(sstr, pt, boost::property_tree::xml_writer_make_settings('\t', 1)); } catch (boost::property_tree::xml_parser_error& /*e*/) { throw core::InvalidParameterException("Write xml to string failed: xml_parser_error!"); } return sstr.str(); } StatisticsString writerDoseStatisticsToTableString(DoseStatisticsPtr aDoseStatistics) { std::stringstream sstr; - sstr << aDoseStatistics->getVolume() * 1000 << columnSeparator; // cm3 to mm3 - sstr << aDoseStatistics->getMaximum() << columnSeparator; - sstr << aDoseStatistics->getMinimum() << columnSeparator; + sstr << static_cast(aDoseStatistics->getVolume() * 1000) << columnSeparator; // cm3 to mm3 + sstr << static_cast(aDoseStatistics->getMaximum()) << columnSeparator; + sstr << static_cast(aDoseStatistics->getMinimum()) << columnSeparator; - sstr << aDoseStatistics->getMean() << columnSeparator; - sstr << aDoseStatistics->getStdDeviation() << columnSeparator; - sstr << aDoseStatistics->getVariance() << columnSeparator; + sstr << static_cast(aDoseStatistics->getMean()) << columnSeparator; + sstr << static_cast(aDoseStatistics->getStdDeviation()) << columnSeparator; + sstr << static_cast(aDoseStatistics->getVariance()) << columnSeparator; rttb::algorithms::DoseStatistics::DoseToVolumeFunctionType AllVx = aDoseStatistics->getAllVx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllDx = aDoseStatistics->getAllDx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllMOHx = aDoseStatistics->getAllMOHx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllMOCx = aDoseStatistics->getAllMOCx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllMaxOHx = aDoseStatistics->getAllMaxOHx(); rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType AllMinOCx = aDoseStatistics->getAllMinOCx(); rttb::algorithms::DoseStatistics::DoseToVolumeFunctionType::iterator vxIt; rttb::algorithms::DoseStatistics::VolumeToDoseFunctionType::iterator it; for (it = AllDx.begin(); it != AllDx.end(); ++it) { - sstr << (*it).second << columnSeparator; + sstr << static_cast((*it).second) << columnSeparator; } for (vxIt = AllVx.begin(); vxIt != AllVx.end(); ++vxIt) { // *1000 because of conversion cm3 to mm3 - sstr << (*vxIt).second * 1000 << columnSeparator; + sstr << static_cast((*vxIt).second * 1000) << columnSeparator; } for (it = AllMOHx.begin(); it != AllMOHx.end(); ++it) { - sstr << (*it).second << columnSeparator; + sstr << static_cast((*it).second) << columnSeparator; } for (it = AllMOCx.begin(); it != AllMOCx.end(); ++it) { - sstr << (*it).second << columnSeparator; + sstr << static_cast((*it).second) << columnSeparator; } for (it = AllMaxOHx.begin(); it != AllMaxOHx.end(); ++it) { - sstr << (*it).second << columnSeparator; + sstr << static_cast((*it).second) << columnSeparator; } for (it = AllMinOCx.begin(); it != AllMinOCx.end(); ++it) { - sstr << (*it).second << columnSeparator; + sstr << static_cast((*it).second) << columnSeparator; } return sstr.str(); } boost::property_tree::ptree createNodeWithNameAttribute(DoseTypeGy doseValue, const std::string& attributeName) { boost::property_tree::ptree node; node.put("", doseValue); node.put(xmlattrNameTag, attributeName); return node; } boost::property_tree::ptree createNodeWithNameAndXAttribute(DoseTypeGy doseValue, const std::string& attributeName, int xValue) { boost::property_tree::ptree node; node.put("", doseValue); node.put(xmlattrNameTag, attributeName); node.put(xmlattrXTag, xValue); return node; } }//end namespace other }//end namespace io }//end namespace rttb \ No newline at end of file diff --git a/code/io/other/rttbDoseStatisticsXMLWriter.h b/code/io/other/rttbDoseStatisticsXMLWriter.h index f97c1b3..48e944e 100644 --- a/code/io/other/rttbDoseStatisticsXMLWriter.h +++ b/code/io/other/rttbDoseStatisticsXMLWriter.h @@ -1,99 +1,103 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (last changed by) */ #ifndef __DOSE_STATISTICS_XML_WRITER_H #define __DOSE_STATISTICS_XML_WRITER_H #include "rttbDoseStatistics.h" #include "rttbBaseType.h" /*boost includes*/ #include #include #include #include namespace rttb { namespace io { namespace other { typedef boost::shared_ptr DoseStatisticsPtr; typedef rttb::algorithms::DoseStatistics::ResultListPointer ResultListPointer; /*! @brief Write statistics to boost::property_tree::ptree. @param aReferenceDose A reference dose for the calculation of Vx @param aDoseStatistics DoseStatistics to write @pre aReferenceDose must >0 @exception InvalidParameterException Thrown if aReferenceDose<=0 or xml_parse_error + @note The precision is float */ boost::property_tree::ptree writeDoseStatistics(DoseStatisticsPtr aDoseStatistics); /*! @brief Write statistics to String. @param aReferenceDose A reference dose for the calculation of Vx @param aDoseStatistics DoseStatistics to write @pre aReferenceDose must >0 @exception InvalidParameterException Thrown if aReferenceDose<=0 or xml_parse_error + @note The precision is float */ XMLString writerDoseStatisticsToString(DoseStatisticsPtr aDoseStatistics); /*! @brief Write statistics to xml file, including numberOfVoxels, volume, minimum, maximum, mean, standard deviation, variance, D2,D5,D10,D90,D95,D98, V2,V5,V10,V90,V95,V98, MOH2,MOH5,MOH10, MOC2,MOC5,MOC10, MaxOH2,MaxOH5,MaxOH10, MinOC2,MinOC5,MinOC10. @param aReferenceDose A reference dose for the calculation of Vx @param aDoseStatistics DoseStatistics to write @param aFileName To write dose statistics @pre aReferenceDose must >0 @exception InvalidParameterException Thrown if aReferenceDose<=0 or xml_parse_error + @note The precision is float */ void writeDoseStatistics(DoseStatisticsPtr aDoseStatistics, FileNameString aFileName); boost::property_tree::ptree createNodeWithNameAttribute(DoseTypeGy doseValue, const std::string& attributeName); boost::property_tree::ptree createNodeWithNameAndXAttribute(DoseTypeGy doseValue, const std::string& attributeName, int xValue); /*! @brief Write statistics to String to generate a table: "Volume mm3@Max@Min@Mean@Std.Dev.@Variance@D2@D5@D10@D90@D95@D98@V2@V5@V10@V90@V95@V98@MOH2@MOH5@MOH10@MOC2@MOC5@MOC10@MaxOH2@MaxOH5@MaxOH10@MinOC2@MinOC5@MinOC10" @param aReferenceDose A reference dose for the calculation of Vx @param aDoseStatistics DoseStatistics to write @pre aReferenceDose must >0 @exception InvalidParameterException Thrown if aReferenceDose<=0 or xml_parse_error @note is used for the Mevislab-Linking of RTTB + @note The precision is float */ StatisticsString writerDoseStatisticsToTableString(DoseStatisticsPtr aDoseStatistics); } } } #endif diff --git a/testing/io/virtuos/VirtuosDVHCalculatorExampleTest.cpp b/testing/io/virtuos/VirtuosDVHCalculatorExampleTest.cpp index db9751f..7c5406a 100644 --- a/testing/io/virtuos/VirtuosDVHCalculatorExampleTest.cpp +++ b/testing/io/virtuos/VirtuosDVHCalculatorExampleTest.cpp @@ -1,131 +1,132 @@ // ----------------------------------------------------------------------- // 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$ (last changed revision) // @date $Date$ (last change date) // @author $Author$ (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 "rttbDVHCalculator.h" #include "rttbGenericMaskedDoseIterator.h" #include "rttbGenericDoseIterator.h" #include "rttbBoostMaskAccessor.h" #include "rttbVirtuosPlanFileDoseAccessorGenerator.h" #include "rttbVirtuosDoseAccessor.h" #include "rttbVirtuosFileStructureSetGenerator.h" namespace rttb { namespace testing { /*! @brief VirtuosDVHCalculatorExampleTest. Test if calculation in new architecture returns similar results to the original implementation. WARNING: The values for comparison need to be adjusted if the input files are changed! */ int VirtuosDVHCalculatorExampleTest(int argc, char* argv[]) { typedef core::GenericDoseIterator::DoseAccessorPointer DoseAccessorPointer; typedef core::GenericMaskedDoseIterator::MaskAccessorPointer MaskAccessorPointer; typedef core::DVHCalculator::DoseIteratorPointer DoseIteratorPointer; typedef masks::boost::BoostMaskAccessor::StructTypePointer StructTypePointer; typedef core::DVH::DVHPointer DVHPointer; typedef core::StructureSetGeneratorInterface::StructureSetPointer StructureSetPointer; PREPARE_DEFAULT_TEST_REPORTING; //ARGUMENTS: 1: virtuos dose file name // 2: virtuos structure file name // 3: virtuos plan file name // 4: virtuos CT file name std::string Virtuos_Dose_File; std::string Virtuos_Structure_File; std::string Virtuos_Plan_File; std::string Virtuos_CT_File; if (argc > 4) { Virtuos_Dose_File = argv[1]; Virtuos_Structure_File = argv[2]; Virtuos_Plan_File = argv[3]; Virtuos_CT_File = argv[4]; } //Virtuos DVH Test io::virtuos::VirtuosPlanFileDoseAccessorGenerator doseAccessorGeneratorVirtuos(Virtuos_Dose_File, Virtuos_Plan_File); DoseAccessorPointer doseAccessorVirtuos(doseAccessorGeneratorVirtuos.generateDoseAccessor()); StructureSetPointer rtStructureSetVirtuos = io::virtuos::VirtuosFileStructureSetGenerator( Virtuos_Structure_File, Virtuos_CT_File).generateStructureSet(); //create MaskAccessor for structure DARM boost::shared_ptr spMaskAccessorVirtuos = boost::make_shared(rtStructureSetVirtuos->getStructure(4), doseAccessorVirtuos->getGeometricInfo()); spMaskAccessorVirtuos->updateMask(); MaskAccessorPointer spMaskAccessor(spMaskAccessorVirtuos); //create corresponding MaskedDoseIterator boost::shared_ptr spMaskedDoseIteratorTmp = boost::make_shared(spMaskAccessor, doseAccessorVirtuos); DoseIteratorPointer spMaskedDoseIterator(spMaskedDoseIteratorTmp); rttb::core::DVHCalculator* calc; CHECK_NO_THROW(calc = new rttb::core::DVHCalculator(spMaskedDoseIterator, (rtStructureSetVirtuos->getStructure(4))->getUID(), doseAccessorVirtuos->getUID())); DVHPointer dvhPtr; CHECK_NO_THROW(dvhPtr = calc->generateDVH()); CHECK_CLOSE(4.08178, dvhPtr->getMaximum(), errorConstant); CHECK_CLOSE(0.0151739, dvhPtr->getMinimum(), errorConstant); CHECK_CLOSE(0.755342, dvhPtr->getMean(), errorConstant); CHECK_CLOSE(0.440044, dvhPtr->getMedian(), errorConstant); CHECK_CLOSE(0.0151739, dvhPtr->getModal(), errorConstant); CHECK_CLOSE(0.835792, dvhPtr->getStdDeviation(), errorConstant); CHECK_CLOSE(0.698549, dvhPtr->getVariance(), errorConstant); CHECK_CLOSE(46573.0193175, dvhPtr->getNumberOfVoxels(), errorConstant); + RETURN_AND_REPORT_TEST_SUCCESS; } }//testing }//rttb