// @(#)root/minuit2:$Id$ // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005 /********************************************************************** * * * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT * * * **********************************************************************/ #ifndef ROOT_Minuit2_MinosError #define ROOT_Minuit2_MinosError #include "Minuit2/MnCross.h" #include namespace ROOT { namespace Minuit2 { //____________________________________________________________________________________ /** Class holding the result of Minos (lower and upper values) for a specific parameter */ class MinosError { public: MinosError() : fParameter(0), fMinParValue(0.), fUpper(MnCross()), fLower(MnCross()) {} MinosError(unsigned int par, double value, const MnCross &low, const MnCross &up) : fParameter(par), fMinParValue(value), fUpper(up), fLower(low) { } ~MinosError() {} MinosError(const MinosError &err) : fParameter(err.fParameter), fMinParValue(err.fMinParValue), fUpper(err.fUpper), fLower(err.fLower) { } MinosError &operator=(const MinosError &) = default; MinosError &operator()(const MinosError &err) { fParameter = err.fParameter; fMinParValue = err.fMinParValue; fUpper = err.fUpper; fLower = err.fLower; return *this; } std::pair operator()() const { return std::pair(Lower(), Upper()); } double Lower() const { if (AtLowerLimit()) return LowerState().Parameter(Parameter()).LowerLimit() - fMinParValue; if (LowerValid()) { // Minos error is value - error - aopt * error where aopt is MnCross.Value() // If value - error is below the limit, error must be truncated at limit double err = LowerState().Error(Parameter()); // error is truncated if over the limit if (LowerState().Parameter(Parameter()).HasLowerLimit()) err = std::min(err, fMinParValue - LowerState().Parameter(Parameter()).LowerLimit()); return -1. * err * (1. + fLower.Value()); } // return Hessian Error in case is invalid return -LowerState().Error(Parameter()); } double Upper() const { if (AtUpperLimit()) return UpperState().Parameter(Parameter()).UpperLimit() - fMinParValue; if (UpperValid()) { // Minos error is value + error + aopt * error where aopt is MnCross.Value() // If value + error is over the limit, err must be truncated at limit double err = UpperState().Error(Parameter()); if (UpperState().Parameter(Parameter()).HasUpperLimit()) err = std::min(err, UpperState().Parameter(Parameter()).UpperLimit() - fMinParValue); return err * (1. + fUpper.Value()); } // return Hessian Error in case is invalid return UpperState().Error(Parameter()); } unsigned int Parameter() const { return fParameter; } const MnUserParameterState &LowerState() const { return fLower.State(); } const MnUserParameterState &UpperState() const { return fUpper.State(); } bool IsValid() const { return fLower.IsValid() && fUpper.IsValid(); } bool LowerValid() const { return fLower.IsValid(); } bool UpperValid() const { return fUpper.IsValid(); } bool AtLowerLimit() const { return fLower.AtLimit(); } bool AtUpperLimit() const { return fUpper.AtLimit(); } bool AtLowerMaxFcn() const { return fLower.AtMaxFcn(); } bool AtUpperMaxFcn() const { return fUpper.AtMaxFcn(); } bool LowerNewMin() const { return fLower.NewMinimum(); } bool UpperNewMin() const { return fUpper.NewMinimum(); } unsigned int NFcn() const { return fUpper.NFcn() + fLower.NFcn(); } // return parameter value at the minimum double Min() const { return fMinParValue; } private: unsigned int fParameter; double fMinParValue; MnCross fUpper; MnCross fLower; }; } // namespace Minuit2 } // namespace ROOT #endif // ROOT_Minuit2_MinosError