diff --git a/code/algorithms/rttbDoseStatisticsCalculator.h b/code/algorithms/rttbDoseStatisticsCalculator.h index 138fc61..cabd8f4 100644 --- a/code/algorithms/rttbDoseStatisticsCalculator.h +++ b/code/algorithms/rttbDoseStatisticsCalculator.h @@ -1,199 +1,199 @@ // ----------------------------------------------------------------------- // 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_CALCULATOR_H #define __DOSE_STATISTICS_CALCULATOR_H #include #include #include #include "rttbDoseIteratorInterface.h" #include "rttbDoseStatistics.h" #include "RTTBAlgorithmsExports.h" #include "rttbDxVolumeToDoseMeasureCollectionCalculator.h" #include "rttbVxDoseToVolumeMeasureCollectionCalculator.h" #include "rttbMOHxVolumeToDoseMeasureCollectionCalculator.h" #include "rttbMOCxVolumeToDoseMeasureCollectionCalculator.h" #include "rttbMaxOHxVolumeToDoseMeasureCollectionCalculator.h" #include "rttbMinOCxVolumeToDoseMeasureCollectionCalculator.h" namespace rttb { namespace algorithms { /*! @class DoseStatisticsCalculator @brief Class for calculating different statistical values from a RT dose distribution @details These values range from standard statistical values such as minimum, maximum and mean to more complex dose specific measures such as Vx (volume irradiated with a dose >=x), Dx (minimal dose delivered to x% of the VOI) or MOHx (mean in the hottest volume). For a complete list, see calculateDoseStatistics(). @note the complex dose statistics are precomputed and cannot be computed "on the fly" lateron! The doses/volumes that should be used for precomputation have to be set in calculateDoseStatistics() */ class RTTBAlgorithms_EXPORT DoseStatisticsCalculator { public: typedef core::DoseIteratorInterface::DoseIteratorPointer DoseIteratorPointer; typedef DoseStatistics::ResultListPointer ResultListPointer; typedef DoseStatistics::DoseStatisticsPointer DoseStatisticsPointer; private: DoseIteratorPointer _doseIterator; /*! @brief Contains relevant dose values sorted in descending order. */ std::vector _doseVector; /*! @brief Contains the corresponding voxel proportions to the values in doseVector. */ std::vector _voxelProportionVector; /*! @brief The doseStatistics are stored here. */ DoseStatisticsPointer _statistics; bool _simpleDoseStatisticsCalculated; bool _complexDoseStatisticsCalculated; bool _multiThreading; ::boost::shared_ptr _mutex; ::boost::shared_ptr _Vx; ::boost::shared_ptr _Dx; ::boost::shared_ptr _MOHx; ::boost::shared_ptr _MOCx; ::boost::shared_ptr _MaxOHx; ::boost::shared_ptr _MinOCx; /*! @brief Calculates the positions where the dose has its maximum @param maxNumberMaximaPositions the maximal amount of computed positions @pre maximumDose must be defined in _statistics with the correct value */ ResultListPointer computeMaximumPositions(unsigned int maxNumberMaximaPositions) const; /*! @brief Calculates the positions where the dose has its minimum @param maxNumberMinimaPositions the maximal amount of computed positions (they are read sequentially using the iterator until maxNumberMinimaPositions have been read, other positions are not considered) @pre minimumDose must be defined in _statistics with the correct value */ ResultListPointer computeMinimumPositions(unsigned int maxNumberMinimaPositions) const; /*! @brief Calculates simple dose statistics (min, mean, max, stdDev, minDosePositions, maxDosePositions) @param maxNumberMinimaPositions the maximal amount of computed positions where the dose has its minimum that is computed @param maxNumberMaximaPositions the maximal amount of computed positions where the dose has its maximum that is computed */ void calculateSimpleDoseStatistics(unsigned int maxNumberMinimaPositions, unsigned int maxNumberMaximaPositions); /*! @brief Calculates complex dose statistics (Dx, Vx, MOHx, MOCx, MaxOHx, MinOCx) @warning computations can take quite long (>1 min) for large structures as many statistics are precomputed */ void calculateComplexDoseStatistics(DoseTypeGy referenceDose, const std::vector& precomputeDoseValues, const std::vector& precomputeVolumeValues); public: ~DoseStatisticsCalculator(); /*! @brief Constructor @param aDoseIterator the dose to be analyzed */ DoseStatisticsCalculator(DoseIteratorPointer aDoseIterator); DoseIteratorPointer getDoseIterator() const; /*! @brief Compute simple or complex dose statistics with default relative x values and the maximum dose as default reference dose (for Vx computation) @details The following statistics are calculated always (i.e. also if computeComplexMeasures=false):
  • minimum dose
  • mean dose
  • maximum dose
  • standard deviation dose
  • voxel positions of minimum dose
  • voxel positions of maximum dose
Additionally, these statistics are computed if computeComplexMeasures=true:
  • Dx (the minimal dose delivered to a volume >= x)
  • Vx (the volume irradiated with a dose >= x)
  • MOHx (mean dose of the hottest x volume)
  • MOCx (mean dose of the coldest x volume)
  • MaxOHx (Maximum outside of the hottest x volume)
  • MinOCx (Minimum outside of the coldest x volume)
Default x values for Vx are 0.02, 0.05, 0.1, 0.9, 0.95 and 0.98, with respect to maxDose. Default x values for Dx, MOHx, MOCx, MaxOHx and MinOCx are 0.02, 0.05, 0.1, 0.9, 0.95 and 0.98, with respect to volume. @param computeComplexMeasures should complex statistics be calculated? If it is true, the complex dose statistics will be calculated with default relative x values and the maximum dose as reference dose @param maxNumberMinimaPositions the maximal amount of computed positions where the dose has its minimum that is computed @param maxNumberMaximaPositions the maximal amount of computed positions where the dose has its maximum that is computed @warning If computeComplexMeasures==true, computations can take quite long (>1 min) for large structures as many statistics are precomputed @note The complex dose statistics are precomputed and cannot be computed "on the fly" lateron! Only the default x values can be requested in DoseStatistics! */ DoseStatisticsPointer calculateDoseStatistics(bool computeComplexMeasures = false, unsigned int maxNumberMinimaPositions = 10, unsigned int maxNumberMaximaPositions = 10); /*! @brief Compute complex dose statistics with given reference dose and default relative x values @param referenceDose the reference dose to compute Vx, normally it should be the prescribed dose @param maxNumberMinimaPositions the maximal amount of computed positions where the dose has its minimum that is computed @param maxNumberMaximaPositions the maximal amount of computed positions where the dose has its maximum that is computed @exception InvalidParameterException thrown if referenceDose <= 0 @warning Computations can take quite long (>1 min) for large structures as many statistics are precomputed @note The complex dose statistics are precomputed and cannot be computed "on the fly" lateron! Only the default x values can be requested in DoseStatistics! */ DoseStatisticsPointer calculateDoseStatistics(DoseTypeGy referenceDose, unsigned int maxNumberMinimaPositions = 10, unsigned int maxNumberMaximaPositions = 10); /*! @brief Compute complex dose statistics with given relative x values and reference dose @param precomputeDoseValues the relative dose values for Vx precomputation, e.g. 0.02, 0.05, 0.95... @param precomputeVolumeValues the relative volume values for Dx, MOHx, MOCx, MaxOHx and MinOCx precomputation, e.g. 0.02, 0.05, 0.95... @param referenceDose the reference dose to compute Vx, normally it should be the prescribed dose. Default value is the maximum dose. @param maxNumberMinimaPositions the maximal amount of computed positions where the dose has its minimum that is computed @param maxNumberMaximaPositions the maximal amount of computed positions where the dose has its maximum that is computed @warning Computations can take quite long (>1 min) for large structures as many statistics are precomputed @note The complex dose statistics are precomputed and cannot be computed "on the fly" lateron! The doses/volumes that should be used for precomputation have to be set by in precomputeDoseValues and precomputeVolumeValues. Only these values can be requested in DoseStatistics! */ DoseStatisticsPointer calculateDoseStatistics(const std::vector& precomputeDoseValues, const std::vector& precomputeVolumeValues, DoseTypeGy referenceDose = -1, unsigned int maxNumberMinimaPositions = 10, unsigned int maxNumberMaximaPositions = 10); - /*! @brief Adds additonal precompute values for all complext Dose Statistics + /*! @brief Adds additonal precompute values for all complex Dose Statistics @exception InvalidDoseException if complexDoseStatistics are not already calculated */ void addPrecomputeValues(const std::vector& values); - /*! @brief Recalculates the DoseMeasures for all complext Dose Statistics + /*! @brief Recalculates the DoseMeasures for all complex Dose Statistics @exception InvalidDoseException if complexDoseStatistics are not already calculated */ void recalculateDoseStatistics(); void setMultiThreading(bool choice); }; } } #endif diff --git a/code/algorithms/rttbDoseToVolumeMeasureCollection.cpp b/code/algorithms/rttbDoseToVolumeMeasureCollection.cpp index 895124a..dc8840e 100644 --- a/code/algorithms/rttbDoseToVolumeMeasureCollection.cpp +++ b/code/algorithms/rttbDoseToVolumeMeasureCollection.cpp @@ -1,95 +1,102 @@ // ----------------------------------------------------------------------- // 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: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbDoseToVolumeMeasureCollection.h" #include "rttbInvalidParameterException.h" #include "rttbDataNotAvailableException.h" namespace rttb { namespace algorithms { DoseToVolumeMeasureCollection::DoseToVolumeMeasureCollection(complexStatistics name, DoseTypeGy referenceDose) : _name(name), _values(std::map()), _referenceDose(referenceDose) {} void DoseToVolumeMeasureCollection::setReferenceDose(DoseTypeGy referenceDose) { this->_referenceDose = referenceDose; } void DoseToVolumeMeasureCollection::insertValue(DoseTypeGy dose, VolumeType volume) { this->_values.insert(std::pair(dose, volume)); } VolumeType DoseToVolumeMeasureCollection::getValue(DoseTypeGy xVolumeAbsolute) const { VolumeType dummy; return getSpecificValue(_values, xVolumeAbsolute, false, dummy); } VolumeType DoseToVolumeMeasureCollection::getValue(DoseTypeGy xDoseAbsolute, bool findNearestValue, DoseTypeGy & nearestXDose) const { return getSpecificValue(_values, xDoseAbsolute, findNearestValue, nearestXDose); } VolumeType DoseToVolumeMeasureCollection::getValueRelative(DoseTypeGy xDoseRelative) const { if (_referenceDose != -1 && xDoseRelative >= 0 && xDoseRelative <= 1) { DoseTypeGy xDoseAbsolute = xDoseRelative * _referenceDose; DoseTypeGy dummy; return getSpecificValue(_values, xDoseAbsolute, false, dummy); } else { throw rttb::core::InvalidParameterException("Reference dose must be > 0 and 0 <= relative Dose <= 1"); } } VolumeType DoseToVolumeMeasureCollection::getValueRelative(DoseTypeGy xDoseRelative, bool findNearestValue, DoseTypeGy & nearestXDose) const { if (_referenceDose != -1 && xDoseRelative >= 0 && xDoseRelative <= 1) { DoseTypeGy xDoseAbsolute = xDoseRelative * _referenceDose; return getSpecificValue(_values, xDoseAbsolute, findNearestValue, nearestXDose); } else { throw rttb::core::InvalidParameterException("Reference dose must be > 0 and 0 <= relative Dose <= 1"); } } DoseToVolumeMeasureCollection::DoseToVolumeFunctionType DoseToVolumeMeasureCollection::getAllValues() const { return this->_values; } bool DoseToVolumeMeasureCollection::isInCollection(DoseTypeGy value) const { - return this->_values.find(value) != this->_values.end(); + double doubleImprecision = 1e-5; + for (auto const& collectionElements : _values) { + if (collectionElements.first - doubleImprecision <= value && value <= collectionElements.first + doubleImprecision) + { + return true; + } + } + return false; } bool operator==(const DoseToVolumeMeasureCollection& volumeToDoseMesureCollection, const DoseToVolumeMeasureCollection& otherVolumeToDoseMesureCollection) { if (volumeToDoseMesureCollection.getName() == otherVolumeToDoseMesureCollection.getName() && volumeToDoseMesureCollection.getAllValues() == otherVolumeToDoseMesureCollection.getAllValues()) { return true; } return false; } } } diff --git a/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.cpp b/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.cpp index c40bc95..c65f876 100644 --- a/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.cpp +++ b/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.cpp @@ -1,85 +1,99 @@ // ----------------------------------------------------------------------- // 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: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbDoseToVolumeMeasureCollectionCalculator.h" #include #include "rttbInvalidParameterException.h" #include //#include namespace rttb { namespace algorithms { DoseToVolumeMeasureCollectionCalculator::DoseToVolumeMeasureCollectionCalculator(const std::vector& precomputeDoseValues, const DoseTypeGy referenceDose, const core::DoseIteratorInterface::DoseIteratorPointer doseIterator, DoseToVolumeMeasureCollection::complexStatistics name, bool multiThreading) : _measureCollection(::boost::make_shared(name)), _precomputeDoseValues(precomputeDoseValues), _referenceDose(referenceDose), _doseIterator(doseIterator), _multiThreading(multiThreading) {} void DoseToVolumeMeasureCollectionCalculator::compute() { std::vector threads; for (size_t i = 0; i < _precomputeDoseValues.size(); ++i) { double xAbsolute = _precomputeDoseValues.at(i) * _referenceDose; if (!_measureCollection->isInCollection(xAbsolute)) { if (_multiThreading) { throw rttb::core::InvalidParameterException("MultiThreading is not implemented yet."); //threads.push_back(boost::thread(&DoseToVolumeMeasureCollectionCalculator::insertIntoMeasureCollection, this , xAbsolute, computeSpecificValue(xAbsolute))); } else { insertIntoMeasureCollection(xAbsolute, this->computeSpecificValue(xAbsolute)); } } } for (unsigned int i = 0; i& values) { for (size_t i = 0; i < values.size(); ++i) { if (values.at(i) > 1 || values.at(i) < 0) { throw rttb::core::InvalidParameterException("Values must be between 1 and 0!"); } - _precomputeDoseValues.push_back(values.at(i)); + if (!isInVector(values.at(i))) { + _precomputeDoseValues.push_back(values.at(i)); + } } } + bool DoseToVolumeMeasureCollectionCalculator::isInVector(double value) + { + double doubleImprecision = 1e-5; + for (size_t i = 0; i < _precomputeDoseValues.size(); ++i) { + if (_precomputeDoseValues.at(i) - doubleImprecision <= value && value <= _precomputeDoseValues.at(i) + doubleImprecision) + { + return true; + } + } + return false; + } + DoseStatistics::DoseToVolumeMeasureCollectionPointer DoseToVolumeMeasureCollectionCalculator::getMeasureCollection() { return _measureCollection; } void DoseToVolumeMeasureCollectionCalculator::insertIntoMeasureCollection(DoseTypeGy xAbsolute, VolumeType resultVolume) { _measureCollection->insertValue(xAbsolute, resultVolume); } } } diff --git a/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.h b/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.h index 7b545b0..5350f75 100644 --- a/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.h +++ b/code/algorithms/rttbDoseToVolumeMeasureCollectionCalculator.h @@ -1,90 +1,93 @@ // ----------------------------------------------------------------------- // 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: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __DOSE_TO_VOLUME_MEASURE_COLLECTION_CALCULATOR_H #define __DOSE_TO_VOLUME_MEASURE_COLLECTION_CALCULATOR_H #include #include #include "rttbBaseType.h" #include "RTTBAlgorithmsExports.h" #include "rttbDoseToVolumeMeasureCollection.h" #include "rttbDoseIteratorInterface.h" #include #include "rttbDoseStatistics.h" namespace rttb { namespace algorithms { /*! @class DoseToVolumeMeasureCollectionCalculator @brief Class for calculating DoseToVolume measures @details This class is used as a basis for DoseToVolumeMeasureCollectionCalculators. It implements the compute() method that is the same for every inheriting subclass, it accesses computeSpecificValue, which has to be implemented for each different complex statistic. */ class RTTBAlgorithms_EXPORT DoseToVolumeMeasureCollectionCalculator { public: typedef std::map VolumeToDoseFunctionType; protected: core::DoseIteratorInterface::DoseIteratorPointer _doseIterator; private: DoseTypeGy _referenceDose; DoseStatistics::DoseToVolumeMeasureCollectionPointer _measureCollection; std::vector _precomputeDoseValues; bool _multiThreading; public: - /*! @brief Computes not already comupted values for the measureCollection. Algorithm for the specific complex Statistic has to be implemented in the corresponding subclass. + /*! @brief Computes not already computed values for the measureCollection. Algorithm for the specific complex Statistic has to be implemented in the corresponding subclass. */ void compute(); /*! @brief Adds additional values to the _precomputeDoseValues vector. @exception InvalidParameterException If values vector contains values that are not between 0 and 1 */ void addPrecomputeDoseValues(const std::vector& values); DoseStatistics::DoseToVolumeMeasureCollectionPointer getMeasureCollection(); protected: DoseToVolumeMeasureCollectionCalculator(const std::vector& precomputeDoseValues, const DoseTypeGy referenceDose, const core::DoseIteratorInterface::DoseIteratorPointer doseIterator, DoseToVolumeMeasureCollection::complexStatistics name, bool multiThreading); void insertIntoMeasureCollection(DoseTypeGy xAbsolute, VolumeType resultVolume); /*! @brief Computes the specific VolumeType depending on the complext statistic @note has to be overwritten */ virtual VolumeType computeSpecificValue(double xAbsolute) const = 0; + + private: + bool isInVector(double value); }; } } #endif diff --git a/code/algorithms/rttbVolumeToDoseMeasureCollection.cpp b/code/algorithms/rttbVolumeToDoseMeasureCollection.cpp index 226256e..d711393 100644 --- a/code/algorithms/rttbVolumeToDoseMeasureCollection.cpp +++ b/code/algorithms/rttbVolumeToDoseMeasureCollection.cpp @@ -1,102 +1,110 @@ // ----------------------------------------------------------------------- // 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: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbVolumeToDoseMeasureCollection.h" #include "rttbInvalidParameterException.h" #include "rttbDataNotAvailableException.h" namespace rttb { namespace algorithms { VolumeToDoseMeasureCollection::VolumeToDoseMeasureCollection(complexStatistics name, VolumeType volume) : _name(name), _values(std::map()), _volume(volume) {} void VolumeToDoseMeasureCollection::setVolume(VolumeType volume) { this->_volume = volume; } void VolumeToDoseMeasureCollection::insertValue(VolumeType volume, DoseTypeGy dose) { this->_values.insert(std::pair(volume, dose)); } DoseTypeGy VolumeToDoseMeasureCollection::getValue(VolumeType xVolumeAbsolute) const { VolumeType dummy; return getSpecificValue(_values, xVolumeAbsolute, false, dummy); } DoseTypeGy VolumeToDoseMeasureCollection::getValue(VolumeType xVolumeAbsolute, bool findNearestValue, VolumeType & nearestXVolume) const { return getSpecificValue(_values, xVolumeAbsolute, findNearestValue, nearestXVolume); } DoseTypeGy VolumeToDoseMeasureCollection::getValueRelative(VolumeType xVolumeRelative) const { if (_volume == -1) { throw rttb::core::DataNotAvailableException("Volume is not set"); } if (xVolumeRelative >= 0 && xVolumeRelative <= 1) { DoseTypeGy xVolumeAbsolute = xVolumeRelative * _volume; VolumeType dummy; return getSpecificValue(_values, xVolumeAbsolute, false, dummy); } else { throw rttb::core::InvalidParameterException("Relative Volume must be >= 0 and <=1"); } } DoseTypeGy VolumeToDoseMeasureCollection::getValueRelative(VolumeType xVolumeRelative, bool findNearestValue, VolumeType & nearestXVolume) const { if (_volume == -1) { throw rttb::core::DataNotAvailableException("Volume is not set"); } if (xVolumeRelative >= 0 && xVolumeRelative <= 1) { DoseTypeGy xVolumeAbsolute = xVolumeRelative * _volume; return getSpecificValue(_values, xVolumeAbsolute, findNearestValue, nearestXVolume); } else { throw rttb::core::InvalidParameterException("Relative Volume must be >= 0 and <=1"); } } VolumeToDoseMeasureCollection::VolumeToDoseFunctionType VolumeToDoseMeasureCollection::getAllValues() const { return this->_values; } - bool VolumeToDoseMeasureCollection::isInCollection(VolumeType value) const { - return this->_values.find(value) != this->_values.end(); + bool VolumeToDoseMeasureCollection::isInCollection(VolumeType value) const + { + double doubleImprecision = 1e-5; + for (auto const& collectionElements : _values) { + if (collectionElements.first - doubleImprecision <= value && value <= collectionElements.first + doubleImprecision) + { + return true; + } + } + return false; } bool operator==(const VolumeToDoseMeasureCollection& volumeToDoseMesureCollection,const VolumeToDoseMeasureCollection& otherVolumeToDoseMesureCollection) { if (volumeToDoseMesureCollection.getName() == otherVolumeToDoseMesureCollection.getName() && volumeToDoseMesureCollection.getAllValues() == otherVolumeToDoseMesureCollection.getAllValues()) { return true; } return false; } } } diff --git a/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.cpp b/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.cpp index 1e61659..442eb08 100644 --- a/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.cpp +++ b/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.cpp @@ -1,84 +1,98 @@ // ----------------------------------------------------------------------- // 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: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #include "rttbVolumeToDoseMeasureCollectionCalculator.h" #include #include "rttbInvalidParameterException.h" #include //#include namespace rttb { namespace algorithms { VolumeToDoseMeasureCollectionCalculator::VolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, VolumeToDoseMeasureCollection::complexStatistics name, bool multiThreading) : _measureCollection(::boost::make_shared(name)), _precomputeVolumeValues(precomputeVolumeValues), _volume(volume), _doseVector(doseVector), _voxelProportionVector(voxelProportionVector), _currentVoxelVolume(currentVoxelVolume), _multiThreading(multiThreading) {} void VolumeToDoseMeasureCollectionCalculator::compute() { std::vector threads; for (size_t i = 0; i < _precomputeVolumeValues.size(); ++i) { double xAbsolute = _precomputeVolumeValues.at(i) * _volume; if (!_measureCollection->isInCollection(xAbsolute)) { if (_multiThreading) { throw rttb::core::InvalidParameterException("MultiThreading is not implemented yet."); //threads.push_back(boost::thread(&VolumeToDoseMeasureCollectionCalculator::insertIntoMeasureCollection, this, xAbsolute, computeSpecificValue(xAbsolute))); } else { insertIntoMeasureCollection(xAbsolute, this->computeSpecificValue(xAbsolute)); } } } for (unsigned int i = 0; i& values) { for (size_t i = 0; i < values.size(); ++i) { if (values.at(i) > 1 || values.at(i) < 0) { throw rttb::core::InvalidParameterException("Values must be between 1 and 0!"); } - _precomputeVolumeValues.push_back(values.at(i)); + if (!isInVector(values.at(i))) { + _precomputeVolumeValues.push_back(values.at(i)); + } + } + } + + bool VolumeToDoseMeasureCollectionCalculator::isInVector(double value) + { + double doubleImprecision = 1e-5; + for (size_t i = 0; i < _precomputeVolumeValues.size(); ++i) { + if (_precomputeVolumeValues.at(i) - doubleImprecision <= value && value <= _precomputeVolumeValues.at(i) + doubleImprecision) + { + return true; + } } + return false; } DoseStatistics::VolumeToDoseMeasureCollectionPointer VolumeToDoseMeasureCollectionCalculator::getMeasureCollection() { return _measureCollection; } void VolumeToDoseMeasureCollectionCalculator::insertIntoMeasureCollection(VolumeType xAbsolute, DoseTypeGy resultDose) { _measureCollection->insertValue(xAbsolute, resultDose); } } } diff --git a/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.h b/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.h index f0f8cb0..0db4f63 100644 --- a/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.h +++ b/code/algorithms/rttbVolumeToDoseMeasureCollectionCalculator.h @@ -1,83 +1,86 @@ // ----------------------------------------------------------------------- // 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: 1674 $ (last changed revision) // @date $Date: 2017-01-27 10:34:46 +0100 (Fr, 27 Jan 2017) $ (last change date) // @author $Author: hentsch $ (last changed by) */ #ifndef __VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #define __VOLUME_TO_DOSE_MEASURE_COLLECTION_CALCULATOR_H #include "rttbVolumeToDoseMeasureCollection.h" #include #include "rttbDoseStatistics.h" namespace rttb { namespace algorithms { /*! @class VolumeToDoseMeasureCollectionCalculator @brief Class for calculating VolumeToDose measures @details This class is used as a basis for VolumeToDoseMeasureCollectionCalculator. It implements the compute() method that is the same for every inheriting subclass, it accesses computeSpecificValue, which has to be implemented for each different complex statistic. */ class RTTBAlgorithms_EXPORT VolumeToDoseMeasureCollectionCalculator { public: typedef std::map VolumeToDoseFunctionType; protected: std::vector _doseVector; DoseVoxelVolumeType _currentVoxelVolume; std::vector _voxelProportionVector; private: VolumeType _volume; DoseStatistics::VolumeToDoseMeasureCollectionPointer _measureCollection; std::vector _precomputeVolumeValues; bool _multiThreading; public: - /*! @brief Computes not already comupted values for the measureCollection. Algorithm for the specific complex Statistic has to be implemented in the corresponding subclass. + /*! @brief Computes not already computed values for the measureCollection. Algorithm for the specific complex Statistic has to be implemented in the corresponding subclass. */ void compute(); /*! @brief Adds additional values to the _precomputeVolumeValues vector. @exception InvalidParameterException If values vector contains values that are not between 0 and 1 */ void addPrecomputeVolumeValues(const std::vector& values); DoseStatistics::VolumeToDoseMeasureCollectionPointer getMeasureCollection(); protected: VolumeToDoseMeasureCollectionCalculator(const std::vector& precomputeVolumeValues, const VolumeType volume, const std::vector& doseVector, const std::vector& voxelProportionVector, const DoseVoxelVolumeType currentVoxelVolume, VolumeToDoseMeasureCollection::complexStatistics name, bool multiThreading); void insertIntoMeasureCollection(VolumeType xAbsolute, DoseTypeGy resultDose); /*! @brief Computes the specific DoseTypeGy depending on the complext statistic @note has to be overwritten */ virtual DoseTypeGy computeSpecificValue(double xAbsolute) const = 0; + + private: + bool VolumeToDoseMeasureCollectionCalculator::isInVector(double value); }; } } #endif