1 // @(#)root/minuit2:$Id$ 2 // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005 3 4 /********************************************************************** 5 * * 6 * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT * 7 * * 8 **********************************************************************/ 9 10 #ifndef ROOT_Minuit2_MnPrint 11 #define ROOT_Minuit2_MnPrint 12 13 #include "Minuit2/MnConfig.h" 14 15 #include <sstream> 16 #include <utility> 17 #include <cassert> 18 #include <string> 19 #include <ios> 20 21 namespace ROOT { 22 namespace Minuit2 { 23 24 /** 25 define std::ostream operators for output 26 */ 27 28 class FunctionMinimum; 29 std::ostream &operator<<(std::ostream &, const FunctionMinimum &); 30 31 class MinimumState; 32 std::ostream &operator<<(std::ostream &, const MinimumState &); 33 34 class LAVector; 35 std::ostream &operator<<(std::ostream &, const LAVector &); 36 37 class LASymMatrix; 38 std::ostream &operator<<(std::ostream &, const LASymMatrix &); 39 40 class MnUserParameters; 41 std::ostream &operator<<(std::ostream &, const MnUserParameters &); 42 43 class MnUserCovariance; 44 std::ostream &operator<<(std::ostream &, const MnUserCovariance &); 45 46 class MnGlobalCorrelationCoeff; 47 std::ostream &operator<<(std::ostream &, const MnGlobalCorrelationCoeff &); 48 49 class MnUserParameterState; 50 std::ostream &operator<<(std::ostream &, const MnUserParameterState &); 51 52 class MnMachinePrecision; 53 std::ostream &operator<<(std::ostream &, const MnMachinePrecision &); 54 55 class MinosError; 56 std::ostream &operator<<(std::ostream &, const MinosError &); 57 58 class ContoursError; 59 std::ostream &operator<<(std::ostream &, const ContoursError &); 60 61 // std::pair<double, double> is used by MnContour 62 std::ostream &operator<<(std::ostream &os, const std::pair<double, double> &point); 63 64 /* Design notes: 1) We want to delay the costly conversion from object references to 65 strings to a point after we have decided whether or not to 66 show that string to the user at all. 2) We want to offer a customization point for 67 external libraries that want to replace the MnPrint logging. The actual 68 implementation is in a separate file, MnPrintImpl.cxx file that external libraries 69 can replace with their own implementation. 70 */ 71 72 // logging class for messages of varying severity 73 class MnPrint { 74 public: 75 // want this to be an enum class for strong typing... 76 enum class Verbosity { Error = 0, Warn = 1, Info = 2, Debug = 3 }; 77 78 // ...but also want the values accessible from MnPrint scope for convenience 79 static constexpr auto eError = Verbosity::Error; 80 static constexpr auto eWarn = Verbosity::Warn; 81 static constexpr auto eInfo = Verbosity::Info; 82 static constexpr auto eDebug = Verbosity::Debug; 83 84 // used for one-line printing of fcn minimum state 85 class Oneline { 86 public: 87 Oneline(double fcn, double edm, int ncalls, int iter = -1); 88 Oneline(const MinimumState &state, int iter = -1); 89 Oneline(const FunctionMinimum &fmin, int iter = -1); 90 91 private: 92 double fFcn, fEdm; 93 int fNcalls, fIter; 94 95 friend std::ostream &operator<<(std::ostream &os, const Oneline &x); 96 }; 97 98 MnPrint(const char *prefix, int level = MnPrint::GlobalLevel()); 99 ~MnPrint(); 100 101 // set global print level and return the previous one 102 static int SetGlobalLevel(int level); 103 104 // return current global print level 105 static int GlobalLevel(); 106 107 // Whether to show the full prefix stack or only the end 108 static void ShowPrefixStack(bool yes); 109 110 static void AddFilter(const char *prefix); 111 static void ClearFilter(); 112 113 // set print level and return the previous one 114 int SetLevel(int level); 115 116 // return current print level 117 int Level() const; 118 119 template <class... Ts> Error(const Ts &...args)120 void Error(const Ts &... args) 121 { 122 Log(eError, args...); 123 } 124 125 template <class... Ts> Warn(const Ts &...args)126 void Warn(const Ts &... args) 127 { 128 Log(eWarn, args...); 129 } 130 131 template <class... Ts> Info(const Ts &...args)132 void Info(const Ts &... args) 133 { 134 Log(eInfo, args...); 135 } 136 137 template <class... Ts> Debug(const Ts &...args)138 void Debug(const Ts &... args) 139 { 140 Log(eDebug, args...); 141 } 142 143 private: 144 // low level logging 145 template <class... Ts> Log(Verbosity level,const Ts &...args)146 void Log(Verbosity level, const Ts &... args) 147 { 148 if (Level() < static_cast<int>(level)) 149 return; 150 if (Hidden()) 151 return; 152 153 std::ostringstream os; 154 StreamPrefix(os); 155 StreamArgs(os, args...); 156 Impl(level, os.str()); 157 } 158 159 static void StreamPrefix(std::ostringstream &os); 160 161 // returns true if filters are installed and message is not selected by any filter 162 static bool Hidden(); 163 164 // see MnPrintImpl.cxx 165 static void Impl(Verbosity level, const std::string &s); 166 167 // TMP to handle lambda argument correctly, exploiting overload resolution rules 168 template <class T> 169 static auto HandleLambda(std::ostream &os, const T &t, int) -> decltype(t(os), void()) 170 { 171 t(os); 172 } 173 174 template <class T> HandleLambda(std::ostream & os,const T & t,float)175 static void HandleLambda(std::ostream &os, const T &t, float) 176 { 177 os << t; 178 } 179 StreamArgs(std::ostringstream &)180 static void StreamArgs(std::ostringstream &) {} 181 182 // end of recursion 183 template <class T> StreamArgs(std::ostringstream & os,const T & t)184 static void StreamArgs(std::ostringstream &os, const T &t) 185 { 186 os << " "; 187 HandleLambda(os, t, 0); 188 } 189 190 template <class T, class... Ts> StreamArgs(std::ostringstream & os,const T & t,const Ts &...ts)191 static void StreamArgs(std::ostringstream &os, const T &t, const Ts &... ts) 192 { 193 os << " " << t; 194 StreamArgs(os, ts...); 195 } 196 197 int fLevel; 198 }; 199 200 } // namespace Minuit2 201 } // namespace ROOT 202 203 #endif // ROOT_Minuit2_MnPrint 204