diff --git a/inc/LauAbsRValue.hh b/inc/LauAbsRValue.hh index f19d3f6..477fe36 100644 --- a/inc/LauAbsRValue.hh +++ b/inc/LauAbsRValue.hh @@ -1,141 +1,149 @@ /* Copyright 2014 University of Warwick Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Laura++ package authors: John Back Paul Harrison Thomas Latham */ /*! \file LauAbsRValue.hh \brief File containing declaration of LauAbsRValue class. */ /*! \class LauAbsRValue \brief Pure abstract base class for defining a parameter containing an R value Pure abstract base class for defining a parameter containing an R value, either a LauParameter or a LauFormulaPar */ #ifndef LAU_ABSRVALUE #define LAU_ABSRVALUE #include +#include "Rtypes.h" + class LauParameter; class LauAbsRValue { public: //! Constructor - LauAbsRValue() {} + LauAbsRValue() = default; //! Destructor - virtual ~LauAbsRValue() {} + virtual ~LauAbsRValue() = default; //! Copy constructor - LauAbsRValue(const LauAbsRValue& /*rhs*/) {} + LauAbsRValue(const LauAbsRValue& rhs) = default; //! Copy assignment operator - LauAbsRValue& operator=(const LauAbsRValue& /*rhs*/) {return *this;} + LauAbsRValue& operator=(const LauAbsRValue& rhs) = default; + + //! Move constructor + LauAbsRValue(LauAbsRValue&& rhs) = default; + + //! Move assignment operator + LauAbsRValue& operator=(LauAbsRValue&& rhs) = default; //! Return the name of the parameter /*! \return the name of the parameter */ virtual const TString& name() const =0; //! Set the parameter name /*! \param [in] newName the name of the parameter */ virtual void name(const TString& newName) =0; //! Return the value of the parameter /*! \return the value of the parameter */ virtual Double_t value() const =0; //! The unblinded value of the parameter /*! \return the unblinded value of the parameter */ virtual Double_t unblindValue() const =0; //! The value generated for the parameter /*! \return the value generated for the parameter */ virtual Double_t genValue() const =0; //! The initial value of the parameter /*! \return the initial value of the parameter given to the fitter */ virtual Double_t initValue() const =0; //! Check whether a Gaussian constraints is applied /*! \return the boolean flag true/false whether a Gaussian constraint is applied */ virtual Bool_t gaussConstraint() const =0; //! The mean of the Gaussian constraint /*! \return the mean value of the Gaussian constraint */ virtual Double_t constraintMean() const =0; //! The width of the Gaussian constraint /*! \return the width of the Gaussian constraint */ virtual Double_t constraintWidth() const =0; //! Return the list of LauParameters on which the LauAbsRValue depends /*! \return the list of LauParameters */ virtual std::vector getPars() =0; //! Is the parameter also an L value or not /*! \return whether the parameter is also an L value */ virtual Bool_t isLValue() const =0; //! Check is the parameter is fixed or floated /*! \return the boolean flag whether the parameter is fixed */ virtual Bool_t fixed() const =0; //! The blinding state /*! \return the blinding state: kTRUE means that it is blinded, kFALSE that it is not blinded */ virtual Bool_t blind() const =0; private: ClassDef(LauAbsRValue,1) // Abstract base class for R parameters }; #endif diff --git a/inc/LauParameter.hh b/inc/LauParameter.hh index 9254ee2..391a472 100644 --- a/inc/LauParameter.hh +++ b/inc/LauParameter.hh @@ -1,560 +1,589 @@ /* Copyright 2006 University of Warwick Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Laura++ package authors: John Back Paul Harrison Thomas Latham */ /*! \file LauParameter.hh \brief File containing declaration of LauParameter class. */ /*! \class LauParameter \brief Class for defining the fit parameter objects. Holds all relevant information for the parameters for both generation and fitting step: current, initial and generated value, maximum and minimum range, error, asymmetric error, fix and float and etc. */ #ifndef LAU_PARAMETER #define LAU_PARAMETER #include #include +#include #include #include "TObject.h" #include "TString.h" + #include "LauAbsRValue.hh" #include "LauBlind.hh" -class LauParameter : public TObject, public LauAbsRValue { +class LauParameter final : public TObject, public LauAbsRValue { public: //! Default constructor - LauParameter(); + LauParameter() = default; //! Constructor for named parameter /*! \param [in] parName the parameter name */ explicit LauParameter(const TString& parName); //! Constructor for parameter value /*! \param [in] parValue the parameter value */ - explicit LauParameter(Double_t parValue); + explicit LauParameter(const Double_t parValue); //! Constructor double limit parameter /*! \param [in] parValue the parameter value \param [in] min the minimum value of the parameter \param [in] max the maximum value of the parameter */ - LauParameter(Double_t parValue, Double_t min, Double_t max); + LauParameter(const Double_t parValue, const Double_t min, const Double_t max); //! Constructor double limit fixed parameter /*! \param [in] parValue the parameter value \param [in] min the minimum value of the parameter \param [in] max the maximum value of the parameter \param [in] parFixed boolean flag to fix or float parameter */ - LauParameter(Double_t parValue, Double_t min, Double_t max, Bool_t parFixed); + LauParameter(const Double_t parValue, const Double_t min, const Double_t max, const Bool_t parFixed); //! Constructor for double error and limit parameter /*! \param [in] parValue the parameter value \param [in] parError the parameter error \param [in] min the minimum value of the parameter \param [in] max the maximum value of the parameter */ - LauParameter(Double_t parValue, Double_t parError, Double_t min, Double_t max); + LauParameter(const Double_t parValue, const Double_t parError, const Double_t min, const Double_t max); //! Constructor for parameter value and name /*! \param [in] parName the parameter name \param [in] parValue the parameter value */ - LauParameter(const TString& parName, Double_t parValue); + LauParameter(const TString& parName, const Double_t parValue); //! Constructor double limit parameter and name /*! \param [in] parName the parameter name \param [in] parValue the parameter value \param [in] min the minimum value of the parameter \param [in] max the maximum value of the parameter */ - LauParameter(const TString& parName, Double_t parValue, Double_t min, Double_t max); + LauParameter(const TString& parName, const Double_t parValue, const Double_t min, const Double_t max); //! Constructor double limit fixed parameter and name /*! \param [in] parName the parameter name \param [in] parValue the parameter value \param [in] min the minimum value of the parameter \param [in] max the maximum value of the parameter \param [in] parFixed boolean flag to fix (kTRUE) or float (kFALSE) the parameter */ - LauParameter(const TString& parName, Double_t parValue, Double_t min, Double_t max, Bool_t parFixed); + LauParameter(const TString& parName, const Double_t parValue, const Double_t min, const Double_t max, const Bool_t parFixed); //! Constructor double error and limit parameter and name /*! \param [in] parName the parameter name \param [in] parValue the parameter value \param [in] parError the parameter error \param [in] min the minimum value of the parameter \param [in] max the maximum value of the parameter */ - LauParameter(const TString& parName, Double_t parValue, Double_t parError, Double_t min, Double_t max); + LauParameter(const TString& parName, const Double_t parValue, const Double_t parError, const Double_t min, const Double_t max); // Destructor - virtual ~LauParameter(); + virtual ~LauParameter() noexcept; //! Copy constructor /*! \param [in] rhs the parameter to be copied */ LauParameter(const LauParameter& rhs); //! Copy assignment operator /*! \param [in] rhs the parameter to be copied */ LauParameter& operator=(const LauParameter& rhs); + //! Move constructor + /*! + \param [in] rhs the parameter to be moved from + */ + LauParameter(LauParameter&& rhs) = default; + + //! Move assignment operator + /*! + \param [in] rhs the parameter to be moved from + */ + LauParameter& operator=(LauParameter&& rhs) = default; + // the simple accessor functions //! The parameter name /*! \return the name of the parameter */ - inline const TString& name() const {return name_;} + const TString& name() const override {return name_;} //! The blinding state /*! \return the blinding state: kTRUE means that it is blinded, kFALSE that it is not blinded */ - inline Bool_t blind() const {return (blinder_ != 0);} + Bool_t blind() const override {return (blinder_ != nullptr);} //! Access the blinder object /*! \return the blinder */ - inline const LauBlind* blinder() const {return blinder_;} + const LauBlind* blinder() const {return blinder_.get();} //! The value of the parameter /*! \return the value of the parameter */ - inline Double_t value() const {return value_;} + Double_t value() const override {return value_;} //! The unblinded value of the parameter /*! \return the unblinded value of the parameter */ - inline Double_t unblindValue() const {return (blinder_==0) ? value_ : blinder_->unblind(value_);} + Double_t unblindValue() const override {return (blinder_==nullptr) ? value_ : blinder_->unblind(value_);} //! The error on the parameter /*! \return the error on the parameter */ - inline Double_t error() const {return error_;} + Double_t error() const {return error_;} //! The lower error on the parameter /*! \return the lower error on the parameter */ - inline Double_t negError() const {return negError_;} + Double_t negError() const {return negError_;} //! The upper error on the parameter /*! \return the upper error on the parameter */ - inline Double_t posError() const {return posError_;} + Double_t posError() const {return posError_;} //! The value generated for the parameter /*! \return the value generated for the parameter */ - inline Double_t genValue() const {return genValue_;} + Double_t genValue() const override {return genValue_;} //! The initial value of the parameter /*! \return the initial value of the parameter given to the fitter */ - inline Double_t initValue() const {return initValue_;} + Double_t initValue() const override {return initValue_;} //! The minimum value allowed for the parameter /*! \return the minimum value allowed for the parameter */ - inline Double_t minValue() const {return minValue_;} + Double_t minValue() const {return minValue_;} //! The maximum value allowed for the parameter /*! \return the maximum value allowed for the parameter */ - inline Double_t maxValue() const {return maxValue_;} + Double_t maxValue() const {return maxValue_;} //! The range allowed for the parameter /*! \return the range allowed for the parameters, defined as the difference between the max and min value */ - inline Double_t range() const {return this->maxValue() - this->minValue();} + Double_t range() const {return this->maxValue() - this->minValue();} //! Check whether the parameter is fixed or floated /*! \return the boolean flag true/false whether the parameter is fixed */ - inline Bool_t fixed() const {return fixed_;} + Bool_t fixed() const override {return fixed_;} //! Check whether the parameter should be floated only in the second stage of a two stage fit /*! \return the boolean flag true/false whether it floats only in the second stage */ - inline Bool_t secondStage() const {return secondStage_;} + Bool_t secondStage() const {return secondStage_;} //! Check whether a Gaussian constraints is applied /*! \return the boolean flag true/false whether a Gaussian constraint is applied */ - inline Bool_t gaussConstraint() const {return gaussConstraint_;} + Bool_t gaussConstraint() const override {return gaussConstraint_;} //! The mean of the Gaussian constraint /*! \return the mean value of the Gaussian constraint */ - inline Double_t constraintMean() const {return constraintMean_;} + Double_t constraintMean() const override {return constraintMean_;} //! The width of the Gaussian constraint /*! \return the width of the Gaussian constraint */ - inline Double_t constraintWidth() const {return constraintWidth_;} + Double_t constraintWidth() const override {return constraintWidth_;} //! The parameter global correlation coefficient /*! \return the global correlation coefficient */ - inline Double_t globalCorrelationCoeff() const {return gcc_;} + Double_t globalCorrelationCoeff() const {return gcc_;} //! The bias in the parameter /*! \return the bias in the parameter, defined as the difference between the value and the generated value */ - inline Double_t bias() const {return bias_;} + Double_t bias() const {return bias_;} //! The pull value for the parameter /*! \return the pull value for the parameter, defined as the bias divided by the error */ - inline Double_t pull() const {return pull_;} + Double_t pull() const {return pull_;} //! Boolean to say it is an L value /*! \return kTRUE, LauParameters are L values */ - inline Bool_t isLValue() const {return kTRUE;} + Bool_t isLValue() const override {return kTRUE;} //! Get the LauParameter itself /*! \return a vector of the LauParameter */ - std::vector getPars(); + std::vector getPars() override; // the simple "setter" functions //! Set the parameter name /*! \param [in] newName the name of the parameter */ - void name(const TString& newName); + void name(const TString& newName) override; //! Set the value of the parameter /*! \param [in] newValue the value of the parameter */ - void value(Double_t newValue); + void value(const Double_t newValue); //! Set the error on the parameter /*! \param [in] newError the error on the parameter */ - void error(Double_t newError); + void error(const Double_t newError); //! Set the lower error on the parameter /*! \param [in] newNegError the lower error on the parameter */ - void negError(Double_t newNegError); + void negError(const Double_t newNegError); //! Set the upper error on the parameter /*! \param [in] newPosError the upper error on the parameter */ - void posError(Double_t newPosError); + void posError(const Double_t newPosError); //! Set the error values on the parameter /*! \param [in] newError the error on the parameter \param [in] newNegError the lower error on the parameter \param [in] newPosError the upper error on the parameter */ - void errors(Double_t newError, Double_t newNegError, Double_t newPosError); + void errors(const Double_t newError, const Double_t newNegError, const Double_t newPosError); //! Set the value and errors on the parameter /*! \param [in] newValue the value of the parameter \param [in] newError the error on the parameter \param [in] newNegError the lower error on the parameter (default set to zero) \param [in] newPosError the upper error on the parameter (default set to zero) */ - void valueAndErrors(Double_t newValue, Double_t newError, Double_t newNegError = 0.0, Double_t newPosError = 0.0); + void valueAndErrors(const Double_t newValue, const Double_t newError, const Double_t newNegError = 0.0, const Double_t newPosError = 0.0); //! Set the global correlation coefficient /*! \param [in] newGCCValue the value of the coefficient */ - void globalCorrelationCoeff(Double_t newGCCValue); + void globalCorrelationCoeff(const Double_t newGCCValue); //! Set the generated value for the parameter /*! \param [in] newGenValue the generated value for the parameter */ - void genValue(Double_t newGenValue); + void genValue(const Double_t newGenValue); //! Set the inital value for the parameter /*! \param [in] newInitValue the initial value for the parameter */ - void initValue(Double_t newInitValue); + void initValue(const Double_t newInitValue); //! Set the minimum value for the parameter /*! \param [in] newMinValue the minimum value for the parameter */ - void minValue(Double_t newMinValue); + void minValue(const Double_t newMinValue); //! Set the maximum value for the parameter /*! \param [in] newMaxValue the maximum value for the parameter */ - void maxValue(Double_t newMaxValue); + void maxValue(const Double_t newMaxValue); //! Set the range for the parameter /*! \param [in] newMinValue the minimum value for the parameter \param [in] newMaxValue the maximum value for the parameter */ - void range(Double_t newMinValue, Double_t newMaxValue); + void range(const Double_t newMinValue, const Double_t newMaxValue); //! Set the value and range for the parameter /*! \param [in] newValue the value of the parameter \param [in] newMinValue the minimum value for the parameter \param [in] newMaxValue the maximum value for the parameter */ - void valueAndRange(Double_t newValue, Double_t newMinValue, Double_t newMaxValue); + void valueAndRange(const Double_t newValue, const Double_t newMinValue, const Double_t newMaxValue); //! Fix or float the given parameter /*! \param [in] parFixed boolean flag to fix or float the parameter */ - void fixed(Bool_t parFixed); + void fixed(const Bool_t parFixed); //! Set parameter as second-stage or not of the fit /*! \param [in] secondStagePar boolean flag to check whether is a second-stage parameter */ - void secondStage(Bool_t secondStagePar); + void secondStage(const Bool_t secondStagePar); //! Add a Gaussian constraint (or modify an existing one) /*! \param [in] newGaussMean the new value of the Gaussian constraint mean \param [in] newGaussWidth the new value of the Gaussian constraint width */ - void addGaussianConstraint(Double_t newGaussMean, Double_t newGaussWidth); + void addGaussianConstraint(const Double_t newGaussMean, const Double_t newGaussWidth); //! Remove the Gaussian constraint void removeGaussianConstraint(); //! Blind the parameter /*! See LauBlind documentation for details of blinding procedure \param [in] blindingString the unique blinding string used to seed the random number generator \param [in] width the width of the Gaussian from which the offset should be sampled */ void blindParameter(const TString& blindingString, const Double_t width); // functions for the cloning mechanism //! Check whether is a clone or not /*! \return true/false whether is a clone */ - inline Bool_t clone() const {return clone_;} + Bool_t clone() const {return clone_;} //! Method to create a clone from the parent parameter using the copy constructor /*! \param [in] constFactor the optional constant factor by which the clone shold be multiplied \return the cloned parameter */ - LauParameter* createClone(Double_t constFactor = 1.0); + LauParameter* createClone(const Double_t constFactor = 1.0); //! Method to create a clone from the parent parameter using the copy constructor and setting a new name /*! \param [in] newName the new name of the cloned parameter \param [in] constFactor the optional constant factor by which the clone shold be multiplied \return the cloned parameter */ - LauParameter* createClone(const TString& newName, Double_t constFactor = 1.0); + LauParameter* createClone(const TString& newName, const Double_t constFactor = 1.0); //! The parent parameter /*! \return the parent parameter */ - inline LauParameter* parent() const {return parent_;} + LauParameter* parent() const {return parent_;} //! Call to update the bias and pull values void updatePull(); //! Randomise the value of the parameter (if it is floating). /*! The pre-defined parameter range is used as the randomisation range. */ void randomiseValue(); //! Randomise the value of the parameter (if it is floating). /*! Use the given range unless either of the given values are outside the range of the parameter, in which case that value will be altered to the current max or min. \param [in] minVal the minimum value for the parameter \param [in] maxVal the maximum value for the parameter */ - void randomiseValue(Double_t minVal, Double_t maxVal); + void randomiseValue(const Double_t minVal, const Double_t maxVal); protected: //! Method to check whether value provided is within the range and that the minimum and maximum limits make sense /*! \param [in] val the value of the parameter \param [in] minVal the minimum value allowed \param [in] maxVal the maximum value allowed */ - void checkRange(Double_t val, Double_t minVal, Double_t maxVal); + void checkRange(const Double_t val, const Double_t minVal, const Double_t maxVal); //! Method to check whether value provided is whithin the range and that the minimum and maximum limits make sense - inline void checkRange() + void checkRange() { this->checkRange(this->value(),this->minValue(),this->maxValue()); } //! Mark this as a clone of the given parent /*! \param theparent the parent parameter */ - inline void clone(LauParameter* theparent) { + void clone(LauParameter* theparent) + { parent_ = theparent; - clone_ = (parent_==0) ? kFALSE : kTRUE; + clone_ = (parent_==nullptr) ? kFALSE : kTRUE; + } + + //! Method to remove a clone from the list of clones + /*! + This is used in the destructor to allow a clone to inform its parent it is no longer around + + \param [in] clone the clone to be removed from the list + */ + void removeFromCloneList(LauParameter* clone) + { + auto iter = clones_.find( clone ); + if ( iter != clones_.end() ) { + clones_.erase( iter ); + } } //! Method to clear the clone parameters - inline void wipeClones() {clones_.clear();} + void wipeClones() {clones_.clear();} //! Method to update clone values /*! \param [in] justValue boolean flag to determine whether it is necessary to update all the parameter settings or only its value. */ - void updateClones(Bool_t justValue); + void updateClones(const Bool_t justValue); private: //! LauFitNtuple is a friend class friend class LauFitNtuple; //! The parameter name TString name_; //! The parameter value - Double_t value_; + Double_t value_{0.0}; //! The error on the parameter - Double_t error_; + Double_t error_{0.0}; //! The lower error on the parameter - Double_t negError_; + Double_t negError_{0.0}; //! The upper error on the parameter - Double_t posError_; + Double_t posError_{0.0}; //! Toy generation value - Double_t genValue_; + Double_t genValue_{0.0}; //! Initial fit value - Double_t initValue_; + Double_t initValue_{0.0}; //! Minimum value for the parameter - Double_t minValue_; + Double_t minValue_{0.0}; //! Maximum value for the parameter - Double_t maxValue_; + Double_t maxValue_{0.0}; //! Fix/float option for parameter - Bool_t fixed_; + Bool_t fixed_{kTRUE}; //! Flag whether it is floated only in the second stage of the fit - Bool_t secondStage_; + Bool_t secondStage_{kFALSE}; //! Choice to use Gaussian constraint - Bool_t gaussConstraint_; + Bool_t gaussConstraint_{kFALSE}; //! Mean value of the Gaussian constraint - Double_t constraintMean_; + Double_t constraintMean_{0.0}; //! Width of the Gaussian constraint - Double_t constraintWidth_; + Double_t constraintWidth_{0.0}; //! Global correlation coefficient - Double_t gcc_; + Double_t gcc_{0.0}; //! Parameter bias - Double_t bias_; + Double_t bias_{0.0}; //! Parameter pull - Double_t pull_; + Double_t pull_{0.0}; //! Flag whether the parameter is a clone - Bool_t clone_; + Bool_t clone_{kFALSE}; //! The parent parameter - LauParameter* parent_; + LauParameter* parent_{nullptr}; //! The clones of this parameter std::map clones_; //! The blinding engine - LauBlind* blinder_; + std::unique_ptr blinder_; - ClassDef(LauParameter, 3) + ClassDefOverride(LauParameter, 4) }; //! Output stream operator std::ostream& operator << (std::ostream& stream, const LauParameter& par); //! Type to define an array of parameters typedef std::vector< std::vector > LauParArray; #endif diff --git a/src/LauParameter.cc b/src/LauParameter.cc index 70791ca..0266296 100644 --- a/src/LauParameter.cc +++ b/src/LauParameter.cc @@ -1,733 +1,595 @@ /* Copyright 2006 University of Warwick Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Laura++ package authors: John Back Paul Harrison Thomas Latham */ /*! \file LauParameter.cc \brief File containing implementation of LauParameter class. */ #include #include -using std::cout; -using std::cerr; -using std::endl; -using std::map; #include "TRandom.h" #include "LauParameter.hh" #include "LauRandom.hh" ClassImp(LauParameter) -LauParameter::LauParameter() : - name_(""), - value_(0.0), - error_(0.0), - negError_(0.0), - posError_(0.0), - genValue_(0.0), - initValue_(0.0), - minValue_(0.0), - maxValue_(0.0), - fixed_(kTRUE), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) +LauParameter::LauParameter(const TString& parName) : + name_{parName} { } -LauParameter::LauParameter(const TString& parName) : - name_(parName), - value_(0.0), - error_(0.0), - negError_(0.0), - posError_(0.0), - genValue_(0.0), - initValue_(0.0), - minValue_(0.0), - maxValue_(0.0), - fixed_(kTRUE), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) -{ -} - -LauParameter::LauParameter(Double_t parValue) : - name_(""), - value_(parValue), - error_(0.0), - negError_(0.0), - posError_(0.0), - genValue_(parValue), - initValue_(parValue), - minValue_(parValue-1e-6), - maxValue_(parValue+1e-6), - fixed_(kTRUE), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) -{ -} - -LauParameter::LauParameter(const TString& parName, Double_t parValue) : - name_(parName), - value_(parValue), - error_(0.0), - negError_(0.0), - posError_(0.0), - genValue_(parValue), - initValue_(parValue), - minValue_(parValue-1e-6), - maxValue_(parValue+1e-6), - fixed_(kTRUE), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) -{ -} - -LauParameter::LauParameter(Double_t parValue, Double_t min, Double_t max) : - name_(""), - value_(parValue), - error_(0.0), - negError_(0.0), - posError_(0.0), - genValue_(parValue), - initValue_(parValue), - minValue_(min), - maxValue_(max), - fixed_(kTRUE), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) +LauParameter::LauParameter(const Double_t parValue) : + value_{parValue}, + genValue_{parValue}, + initValue_{parValue}, + minValue_{parValue-1e-6}, + maxValue_{parValue+1e-6} +{ +} + +LauParameter::LauParameter(const TString& parName, const Double_t parValue) : + name_{parName}, + value_{parValue}, + genValue_{parValue}, + initValue_{parValue}, + minValue_{parValue-1e-6}, + maxValue_{parValue+1e-6} +{ +} + +LauParameter::LauParameter(const Double_t parValue, const Double_t min, const Double_t max) : + value_{parValue}, + genValue_{parValue}, + initValue_{parValue}, + minValue_{min}, + maxValue_{max} { this->checkRange(); } -LauParameter::LauParameter(Double_t parValue, Double_t parError, Double_t min, Double_t max) : - name_(""), - value_(parValue), - error_(parError), - negError_(0.0), - posError_(0.0), - genValue_(parValue), - initValue_(parValue), - minValue_(min), - maxValue_(max), - fixed_(kTRUE), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) +LauParameter::LauParameter(const Double_t parValue, const Double_t parError, const Double_t min, const Double_t max) : + value_{parValue}, + error_{parError}, + genValue_{parValue}, + initValue_{parValue}, + minValue_{min}, + maxValue_{max} { this->checkRange(); } -LauParameter::LauParameter(Double_t parValue, Double_t min, Double_t max, Bool_t parFixed) : - name_(""), - value_(parValue), - error_(0.0), - negError_(0.0), - posError_(0.0), - genValue_(parValue), - initValue_(parValue), - minValue_(min), - maxValue_(max), - fixed_(parFixed), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) +LauParameter::LauParameter(const Double_t parValue, const Double_t min, const Double_t max, const Bool_t parFixed) : + value_{parValue}, + genValue_{parValue}, + initValue_{parValue}, + minValue_{min}, + maxValue_{max}, + fixed_{parFixed} { this->checkRange(); } -LauParameter::LauParameter(const TString& parName, Double_t parValue, Double_t min, Double_t max) : - name_(parName), - value_(parValue), - error_(0.0), - negError_(0.0), - posError_(0.0), - genValue_(parValue), - initValue_(parValue), - minValue_(min), - maxValue_(max), - fixed_(kTRUE), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) +LauParameter::LauParameter(const TString& parName, const Double_t parValue, const Double_t min, const Double_t max) : + name_{parName}, + value_{parValue}, + genValue_{parValue}, + initValue_{parValue}, + minValue_{min}, + maxValue_{max} { this->checkRange(); } -LauParameter::LauParameter(const TString& parName, Double_t parValue, Double_t min, Double_t max, Bool_t parFixed) : - name_(parName), - value_(parValue), - error_(0.0), - negError_(0.0), - posError_(0.0), - genValue_(parValue), - initValue_(parValue), - minValue_(min), - maxValue_(max), - fixed_(parFixed), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) +LauParameter::LauParameter(const TString& parName, const Double_t parValue, const Double_t min, const Double_t max, const Bool_t parFixed) : + name_{parName}, + value_{parValue}, + genValue_{parValue}, + initValue_{parValue}, + minValue_{min}, + maxValue_{max}, + fixed_{parFixed} { this->checkRange(); } -LauParameter::LauParameter(const TString& parName, Double_t parValue, Double_t parError, Double_t min, Double_t max) : - name_(parName), - value_(parValue), - error_(parError), - negError_(0.0), - posError_(0.0), - genValue_(parValue), - initValue_(parValue), - minValue_(min), - maxValue_(max), - fixed_(kTRUE), - secondStage_(kFALSE), - gaussConstraint_(kFALSE), - constraintMean_(0.0), - constraintWidth_(0.0), - gcc_(0.0), - bias_(0.0), - pull_(0.0), - clone_(kFALSE), - parent_(0), - blinder_(0) +LauParameter::LauParameter(const TString& parName, const Double_t parValue, const Double_t parError, const Double_t min, const Double_t max) : + name_{parName}, + value_{parValue}, + error_{parError}, + genValue_{parValue}, + initValue_{parValue}, + minValue_{min}, + maxValue_{max} { this->checkRange(); } LauParameter::LauParameter(const LauParameter& rhs) : TObject(rhs), LauAbsRValue(rhs), - name_(rhs.name_), - value_(rhs.value_), - error_(rhs.error_), - negError_(rhs.negError_), - posError_(rhs.posError_), - genValue_(rhs.genValue_), - initValue_(rhs.initValue_), - minValue_(rhs.minValue_), - maxValue_(rhs.maxValue_), - fixed_(rhs.fixed_), - secondStage_(rhs.secondStage_), - gaussConstraint_(rhs.gaussConstraint_), - constraintMean_(rhs.constraintMean_), - constraintWidth_(rhs.constraintWidth_), - gcc_(rhs.gcc_), - bias_(rhs.bias_), - pull_(rhs.pull_), - clone_(rhs.clone_), - parent_(rhs.parent_), - clones_(rhs.clones_), - blinder_((rhs.blinder_==0) ? 0 : new LauBlind(*(rhs.blinder_))) + name_{rhs.name_}, + value_{rhs.value_}, + error_{rhs.error_}, + negError_{rhs.negError_}, + posError_{rhs.posError_}, + genValue_{rhs.genValue_}, + initValue_{rhs.initValue_}, + minValue_{rhs.minValue_}, + maxValue_{rhs.maxValue_}, + fixed_{rhs.fixed_}, + secondStage_{rhs.secondStage_}, + gaussConstraint_{rhs.gaussConstraint_}, + constraintMean_{rhs.constraintMean_}, + constraintWidth_{rhs.constraintWidth_}, + gcc_{rhs.gcc_}, + bias_{rhs.bias_}, + pull_{rhs.pull_}, + clone_{rhs.clone_}, + parent_{rhs.parent_}, + clones_{rhs.clones_}, + blinder_{(rhs.blinder_) ? std::make_unique(*(rhs.blinder_)) : nullptr} { } LauParameter& LauParameter::operator=(const LauParameter& rhs) { if (&rhs != this) { TObject::operator=(rhs); LauAbsRValue::operator=(rhs); name_ = rhs.name_; value_ = rhs.value_; error_ = rhs.error_; negError_ = rhs.negError_; posError_ = rhs.posError_; genValue_ = rhs.genValue_; initValue_ = rhs.initValue_; minValue_ = rhs.minValue_; maxValue_ = rhs.maxValue_; fixed_ = rhs.fixed_; secondStage_ = rhs.secondStage_; gaussConstraint_ = rhs.gaussConstraint_; constraintMean_ = rhs.constraintMean_; constraintWidth_ = rhs.constraintWidth_; gcc_ = rhs.gcc_; bias_ = rhs.bias_; pull_ = rhs.pull_; clone_ = rhs.clone_; parent_ = rhs.parent_; clones_ = rhs.clones_; - delete blinder_; - blinder_ = (rhs.blinder_==0) ? 0 : new LauBlind(*(rhs.blinder_)); + blinder_.reset(); + if ( rhs.blinder_ ) { + blinder_ = std::make_unique(*(rhs.blinder_)); + } } return *this; } -LauParameter::~LauParameter() +LauParameter::~LauParameter() noexcept { - delete blinder_; + // if we're a clone, we just need to inform our parent of our demise + if ( this->clone() ) { + parent_->removeFromCloneList(this); + return; + } + + // if we have no clones there's nothing to do + if ( clones_.empty() ) { + return; + } + + // otherwise if we have clones we need to make one of them the new parent and inform the rest of the change + + // let's (arbitrarily) make the first parameter in the map the new parent + auto iter = clones_.begin(); + auto [ newParent, constFactor ] { *iter }; + + // remove that entry in the map + clones_.erase(iter); + + // for all the other entries, we need to tell them they are clones of the new parent + // and also rescale the constants so that they are relative to the new parent + for ( auto& [ theClone, theFactor ] : clones_ ) { + theClone->clone(newParent); + theFactor /= constFactor; + } + + // transfer the list of clones to the new parent + newParent->clones_ = std::move(clones_); + + // finally, the new parent has to be told that it isn't a clone anymore + newParent->clone(nullptr); } std::vector LauParameter::getPars() { std::vector list; list.push_back(this); return list; } -void LauParameter::value(Double_t newValue) +void LauParameter::value(const Double_t newValue) { if (this->clone()) { parent_->value(newValue); } else { this->checkRange(newValue,this->minValue(),this->maxValue()); this->updateClones(kTRUE); } } -void LauParameter::error(Double_t newError) +void LauParameter::error(const Double_t newError) { if (this->clone()) { parent_->error(newError); } else { error_ = TMath::Abs(newError); this->updateClones(kFALSE); } } -void LauParameter::negError(Double_t newNegError) +void LauParameter::negError(const Double_t newNegError) { if (this->clone()) { parent_->negError(newNegError); } else { negError_ = TMath::Abs(newNegError); this->updateClones(kFALSE); } } -void LauParameter::posError(Double_t newPosError) +void LauParameter::posError(const Double_t newPosError) { if (this->clone()) { parent_->posError(newPosError); } else { posError_ = TMath::Abs(newPosError); this->updateClones(kFALSE); } } -void LauParameter::errors(Double_t newError, Double_t newNegError, Double_t newPosError) +void LauParameter::errors(const Double_t newError, const Double_t newNegError, const Double_t newPosError) { if (this->clone()) { parent_->errors(newError,newNegError,newPosError); } else { error_ = TMath::Abs(newError); negError_ = TMath::Abs(newNegError); posError_ = TMath::Abs(newPosError); this->updateClones(kFALSE); } } -void LauParameter::valueAndErrors(Double_t newValue, Double_t newError, Double_t newNegError, Double_t newPosError) +void LauParameter::valueAndErrors(const Double_t newValue, const Double_t newError, const Double_t newNegError, const Double_t newPosError) { if (this->clone()) { parent_->valueAndErrors(newValue,newError,newNegError,newPosError); } else { this->checkRange(newValue,this->minValue(),this->maxValue()); error_ = TMath::Abs(newError); negError_ = TMath::Abs(newNegError); posError_ = TMath::Abs(newPosError); this->updateClones(kFALSE); } } -void LauParameter::globalCorrelationCoeff(Double_t newGCCValue) +void LauParameter::globalCorrelationCoeff(const Double_t newGCCValue) { if (this->clone()) { parent_->globalCorrelationCoeff(newGCCValue); } else { gcc_ = newGCCValue; this->updateClones(kFALSE); } } -void LauParameter::genValue(Double_t newGenValue) +void LauParameter::genValue(const Double_t newGenValue) { if (this->clone()) { parent_->genValue(newGenValue); } else { genValue_ = newGenValue; this->updateClones(kFALSE); } } -void LauParameter::initValue(Double_t newInitValue) +void LauParameter::initValue(const Double_t newInitValue) { if (this->clone()) { parent_->initValue(newInitValue); } else { initValue_ = newInitValue; this->updateClones(kFALSE); } } -void LauParameter::minValue(Double_t newMinValue) +void LauParameter::minValue(const Double_t newMinValue) { if (this->clone()) { parent_->minValue(newMinValue); } else { this->checkRange(this->value(),newMinValue,this->maxValue()); this->updateClones(kFALSE); } } -void LauParameter::maxValue(Double_t newMaxValue) +void LauParameter::maxValue(const Double_t newMaxValue) { if (this->clone()) { parent_->maxValue(newMaxValue); } else { this->checkRange(this->value(),this->minValue(),newMaxValue); this->updateClones(kFALSE); } } -void LauParameter::range(Double_t newMinValue, Double_t newMaxValue) +void LauParameter::range(const Double_t newMinValue, const Double_t newMaxValue) { if (this->clone()) { parent_->range(newMinValue,newMaxValue); } else { this->checkRange(this->value(),newMinValue,newMaxValue); this->updateClones(kFALSE); } } -void LauParameter::valueAndRange(Double_t newValue, Double_t newMinValue, Double_t newMaxValue) +void LauParameter::valueAndRange(const Double_t newValue, const Double_t newMinValue, const Double_t newMaxValue) { if (this->clone()) { parent_->valueAndRange(newValue,newMinValue,newMaxValue); } else { this->checkRange(newValue,newMinValue,newMaxValue); this->updateClones(kFALSE); } } void LauParameter::name(const TString& newName) { // no need to update clones here // clones are allowed to have different names name_ = newName; } -void LauParameter::fixed(Bool_t parFixed) +void LauParameter::fixed(const Bool_t parFixed) { if (this->clone()) { parent_->fixed(parFixed); } else { fixed_ = parFixed; this->updateClones(kFALSE); } } -void LauParameter::secondStage(Bool_t secondStagePar) +void LauParameter::secondStage(const Bool_t secondStagePar) { if (this->clone()) { parent_->secondStage(secondStagePar); } else { secondStage_ = secondStagePar; this->updateClones(kFALSE); } } -void LauParameter::addGaussianConstraint(Double_t newGaussMean, Double_t newGaussWidth) +void LauParameter::addGaussianConstraint(const Double_t newGaussMean, const Double_t newGaussWidth) { if (this->clone()) { parent_->addGaussianConstraint(newGaussMean,newGaussWidth); } else { gaussConstraint_ = kTRUE; constraintMean_ = newGaussMean; constraintWidth_ = newGaussWidth; this->updateClones(kFALSE); } } void LauParameter::removeGaussianConstraint() { if (this->clone()) { parent_->removeGaussianConstraint(); } else { gaussConstraint_ = kFALSE; this->updateClones(kFALSE); } } void LauParameter::blindParameter(const TString& blindingString, const Double_t width) { if (this->clone()) { parent_->blindParameter(blindingString,width); return; } - if ( blinder_ != 0 ) { + if ( blinder_ ) { std::cerr << "WARNING in LauParameter::blindParameter : blinding has already been set up for this parameter" << std::endl; return; } - blinder_ = new LauBlind(blindingString,width); + blinder_ = std::make_unique(blindingString,width); - for (map::iterator iter = clones_.begin(); iter != clones_.end(); ++iter) { - LauParameter* clonePar = iter->first; - if ( clonePar->blinder_ != 0 ) { + for ( auto& [ clonePar, _ ] : clones_ ) { + if ( clonePar->blinder_ != nullptr ) { std::cerr << "WARNING in LauParameter::blindParameter : blinding has already been set up for a clone of this parameter - it will be replaced!" << std::endl; - delete clonePar->blinder_; - clonePar->blinder_ = 0; + clonePar->blinder_.reset(); } - clonePar->blinder_ = new LauBlind(*blinder_); + clonePar->blinder_ = std::make_unique(*blinder_); } } void LauParameter::updatePull() { if (this->clone()) { parent_->updatePull(); return; } // calculate the bias bias_ = value_ - genValue_; // if we have errors calculated then calculate // the pull using the best error available if ((bias_ > 0.0) && (negError_ > 1e-10)) { pull_ = bias_ / negError_; } else if ((bias_ < 0.0) && (posError_ > 1e-10)) { pull_ = bias_ / posError_; } else if (error_ > 1e-10) { pull_ = bias_ / error_; } else { pull_ = 0.0; } this->updateClones(kFALSE); } -void LauParameter::checkRange(Double_t val, Double_t minVal, Double_t maxVal) +void LauParameter::checkRange(const Double_t val, const Double_t minVal, const Double_t maxVal) { // first check that min is less than max (or they are the same - this is allowed) if (minVal > maxVal) { - cerr<<"ERROR in LauParameter::checkRange : minValue: "< maxValue_) { minValue_ = maxValue_; - cerr<<" : Setting both to "< maxVal)) { if (name_ != "") { - cerr<<"ERROR in LauParameter::checkRange : value: "<clone()) { LauParameter* clonePar = parent_->createClone(constFactor); clonePar->name(this->name()); return clonePar; } // clone ourselves using the copy-constructor LauParameter* clonePar = new LauParameter(*this); Double_t newValue = clonePar->value() * constFactor; clonePar->value( newValue ); clonePar->wipeClones(); clonePar->clone(this); clones_.insert( std::make_pair( clonePar, constFactor ) ); return clonePar; } -LauParameter* LauParameter::createClone(const TString& newName, Double_t constFactor) +LauParameter* LauParameter::createClone(const TString& newName, const Double_t constFactor) { // self message to create the clone LauParameter* clonePar = this->createClone(constFactor); // set the new name clonePar->name(newName); // and return return clonePar; } -void LauParameter::updateClones(Bool_t justValue) +void LauParameter::updateClones(const Bool_t justValue) { // if we don't have any clones then there's nothing to do if ( clones_.empty() ) { return; } // we have to set the values directly rather than using member functions because otherwise we'd get into an infinite loop if (justValue) { - for (map::iterator iter = clones_.begin(); iter != clones_.end(); ++iter) { - LauParameter* clonePar = iter->first; - Double_t constFactor = iter->second; - clonePar->value_ = constFactor*this->value(); + for ( auto& [ clonePar, constFactor ] : clones_ ) { + clonePar->value_ = constFactor*value_; } } else { - for (map::iterator iter = clones_.begin(); iter != clones_.end(); ++iter) { - LauParameter* clonePar = iter->first; - Double_t constFactor = iter->second; - clonePar->value_ = constFactor*this->value(); - clonePar->error_ = constFactor*this->error(); - clonePar->negError_ = constFactor*this->negError(); - clonePar->posError_ = constFactor*this->posError(); - clonePar->genValue_ = constFactor*this->genValue(); - clonePar->initValue_ = constFactor*this->initValue(); - clonePar->minValue_ = constFactor*this->minValue(); - clonePar->maxValue_ = constFactor*this->maxValue(); - clonePar->fixed_ = this->fixed(); - clonePar->secondStage_ = this->secondStage(); - clonePar->gaussConstraint_ = this->gaussConstraint(); - clonePar->constraintMean_ = this->constraintMean(); - clonePar->constraintWidth_ = this->constraintWidth(); - clonePar->gcc_ = this->globalCorrelationCoeff(); - clonePar->bias_ = this->bias(); - clonePar->pull_ = this->pull(); + for ( auto& [ clonePar, constFactor ] : clones_ ) { + clonePar->value_ = constFactor*value_; + clonePar->error_ = constFactor*error_; + clonePar->negError_ = constFactor*negError_; + clonePar->posError_ = constFactor*posError_; + clonePar->genValue_ = constFactor*genValue_; + clonePar->initValue_ = constFactor*initValue_; + clonePar->minValue_ = constFactor*minValue_; + clonePar->maxValue_ = constFactor*maxValue_; + clonePar->fixed_ = fixed_; + clonePar->secondStage_ = secondStage_; + clonePar->gaussConstraint_ = gaussConstraint_; + clonePar->constraintMean_ = constraintMean_; + clonePar->constraintWidth_ = constraintWidth_; + clonePar->gcc_ = gcc_; + clonePar->bias_ = bias_; + clonePar->pull_ = pull_; } } } void LauParameter::randomiseValue() { this->randomiseValue(this->minValue(), this->maxValue()); } -void LauParameter::randomiseValue(Double_t minVal, Double_t maxVal) +void LauParameter::randomiseValue(const Double_t minVal, const Double_t maxVal) { // if we're fixed then do nothing if (this->fixed()) { return; } // check supplied values are sensible if (maxVal < minVal) { - cerr<<"ERROR in LauParameter::randomiseValue : Supplied maximum value smaller than minimum value."< this->maxValue()) { - maxVal = this->maxValue(); - } - if (minVal < this->minValue()) { - minVal = this->minValue(); - } // use the zero-seed random number generator to get values that are - // uniformly distributed over the given range - Double_t randNo = LauRandom::zeroSeedRandom()->Rndm(); - Double_t val = randNo*(maxVal - minVal) + minVal; + // uniformly distributed over the given range (truncating to ensure it is within our nominal range) + const Double_t val { LauRandom::zeroSeedRandom()->Uniform( TMath::Max( minVal, this->minValue() ), TMath::Min( maxVal, this->maxValue() ) ) }; + this->initValue(val); } // ostream operator std::ostream& operator << (std::ostream& stream, const LauParameter& par) { stream << par.value(); return stream; } -