00001 #ifndef PhysicsTools_Utilities_MultiHistoChiSquare_h 00002 #define PhysicsTools_Utilities_MultiHistoChiSquare_h 00003 #include "PhysicsTools/Utilities/interface/RootMinuitResultPrinter.h" 00004 #include "TMath.h" 00005 #include "TH1.h" 00006 00007 namespace fit { 00008 namespace helper { 00009 struct MultiHistoChiSquareNoArg { }; 00010 } 00011 00012 template<typename T1, 00013 typename T2 = helper::MultiHistoChiSquareNoArg, 00014 typename T3 = helper::MultiHistoChiSquareNoArg, 00015 typename T4 = helper::MultiHistoChiSquareNoArg, 00016 typename T5 = helper::MultiHistoChiSquareNoArg, 00017 typename T6 = helper::MultiHistoChiSquareNoArg> 00018 class MultiHistoChiSquare { 00019 public: 00020 MultiHistoChiSquare() { } 00021 template<typename TT1, typename TT2, typename TT3, typename TT4, typename TT5, typename TT6> 00022 MultiHistoChiSquare(TT1 & t1, TH1 *histo1, 00023 TT2 & t2, TH1 *histo2, 00024 TT3 & t3, TH1 *histo3, 00025 TT4 & t4, TH1 *histo4, 00026 TT5 & t5, TH1 *histo5, 00027 TT6 & t6, TH1 *histo6, 00028 double rangeMin, double rangeMax) : 00029 chi1_(t1, histo1, rangeMin, rangeMax), 00030 chi2_(t2, histo2, rangeMin, rangeMax), 00031 chi3_(t3, histo3, rangeMin, rangeMax), 00032 chi4_(t4, histo4, rangeMin, rangeMax), 00033 chi5_(t5, histo5, rangeMin, rangeMax), 00034 chi6_(t6, histo6, rangeMin, rangeMax) { 00035 } 00036 double operator()() const { 00037 double chi2 = chi1_() + chi2_() + chi3_() + chi4_() + chi5_() + chi6_(); 00038 static size_t count = 0; 00039 ++count; 00040 if(count % 10 == 0) 00041 return chi2; 00042 00043 } 00044 void setHistos(TH1 *histo1, TH1 *histo2, TH1 *histo3, TH1 * histo4, TH1 * histo5, TH1 * histo6 ) { 00045 chi1_.setHistos(histo1); 00046 chi2_.setHistos(histo2); 00047 chi3_.setHistos(histo3); 00048 chi4_.setHistos(histo4); 00049 chi5_.setHistos(histo5); 00050 chi6_.setHistos(histo6); 00051 } 00052 size_t numberOfBins() const { 00053 return 00054 chi1_.numberOfBins() + 00055 chi2_.numberOfBins() + 00056 chi3_.numberOfBins() + 00057 chi4_.numberOfBins() + 00058 chi5_.numberOfBins() + 00059 chi6_.numberOfBins() ; 00060 } 00061 T1 & function1() { return chi1_.function(); } 00062 const T1 & function1() const { return chi1_.function(); } 00063 T2 & function2() { return chi2_.function(); } 00064 const T2 & function2() const { return chi2_.function(); } 00065 T3 & function3() { return chi3_.function(); } 00066 const T3 & function3() const { return chi3_.function(); } 00067 T4 & function4() { return chi4_.function(); } 00068 const T4 & function4() const { return chi4_.function(); } 00069 T5 & function5() { return chi5_.function(); } 00070 const T5 & function5() const { return chi5_.function(); } 00071 T6 & function6() { return chi6_.function(); } 00072 const T6 & function6() const { return chi6_.function(); } 00073 private: 00074 T1 chi1_; 00075 T2 chi2_; 00076 T3 chi3_; 00077 T4 chi4_; 00078 T5 chi5_; 00079 T6 chi6_; 00080 }; 00081 00082 00083 00084 template<typename T1, typename T2, typename T3, typename T4, typename T5> 00085 class MultiHistoChiSquare<T1, T2, T3, T4, T5, 00086 helper::MultiHistoChiSquareNoArg> { 00087 public: 00088 MultiHistoChiSquare() { } 00089 template<typename TT1, typename TT2, typename TT3, typename TT4, typename TT5> 00090 MultiHistoChiSquare(TT1 & t1, TH1 *histo1, 00091 TT2 & t2, TH1 *histo2, 00092 TT3 & t3, TH1 *histo3, 00093 TT4 & t4, TH1 *histo4, 00094 TT5 & t5, TH1 *histo5, 00095 double rangeMin, double rangeMax) : 00096 chi1_(t1, histo1, rangeMin, rangeMax), 00097 chi2_(t2, histo2, rangeMin, rangeMax), 00098 chi3_(t3, histo3, rangeMin, rangeMax), 00099 chi4_(t4, histo4, rangeMin, rangeMax), 00100 chi5_(t5, histo5, rangeMin, rangeMax) { 00101 } 00102 double operator()() const { 00103 double chi2 = chi1_() + chi2_() + chi3_() + chi4_() + chi5_(); 00104 static size_t count = 0; 00105 ++count; 00106 return chi2; 00107 } 00108 void setHistos(TH1 *histo1, TH1 *histo2, TH1 *histo3, TH1 * histo4, TH1 * histo5) { 00109 chi1_.setHistos(histo1); 00110 chi2_.setHistos(histo2); 00111 chi3_.setHistos(histo3); 00112 chi4_.setHistos(histo4); 00113 chi5_.setHistos(histo5); 00114 } 00115 size_t numberOfBins() const { 00116 return 00117 chi1_.numberOfBins() + 00118 chi2_.numberOfBins() + 00119 chi3_.numberOfBins() + 00120 chi4_.numberOfBins() + 00121 chi5_.numberOfBins(); 00122 } 00123 T1 & function1() { return chi1_.function(); } 00124 const T1 & function1() const { return chi1_.function(); } 00125 T2 & function2() { return chi2_.function(); } 00126 const T2 & function2() const { return chi2_.function(); } 00127 T3 & function3() { return chi3_.function(); } 00128 const T3 & function3() const { return chi3_.function(); } 00129 T4 & function4() { return chi4_.function(); } 00130 const T4 & function4() const { return chi4_.function(); } 00131 T5 & function5() { return chi5_.function(); } 00132 const T5 & function5() const { return chi5_.function(); } 00133 private: 00134 T1 chi1_; 00135 T2 chi2_; 00136 T3 chi3_; 00137 T4 chi4_; 00138 T5 chi5_; 00139 }; 00140 00141 template<typename T1, typename T2, typename T3, typename T4> 00142 class MultiHistoChiSquare<T1, T2, T3, T4, 00143 helper::MultiHistoChiSquareNoArg, 00144 helper::MultiHistoChiSquareNoArg> { 00145 public: 00146 MultiHistoChiSquare() { } 00147 template<typename TT1, typename TT2, typename TT3, typename TT4> 00148 MultiHistoChiSquare(TT1 & t1, TH1 *histo1, 00149 TT2 & t2, TH1 *histo2, 00150 TT3 & t3, TH1 *histo3, 00151 TT4 & t4, TH1 *histo4, 00152 double rangeMin, double rangeMax) : 00153 chi1_(t1, histo1, rangeMin, rangeMax), 00154 chi2_(t2, histo2, rangeMin, rangeMax), 00155 chi3_(t3, histo3, rangeMin, rangeMax), 00156 chi4_(t4, histo4, rangeMin, rangeMax) { 00157 } 00158 double operator()() const { 00159 double chi2 = chi1_() + chi2_() + chi3_() + chi4_(); 00160 static size_t count = 0; 00161 ++count; 00162 return chi2; 00163 } 00164 void setHistos(TH1 *histo1, TH1 *histo2, TH1 *histo3, TH1 * histo4) { 00165 chi1_.setHistos(histo1); 00166 chi2_.setHistos(histo2); 00167 chi3_.setHistos(histo3); 00168 chi4_.setHistos(histo4); 00169 } 00170 size_t numberOfBins() const { 00171 return 00172 chi1_.numberOfBins() + 00173 chi2_.numberOfBins() + 00174 chi3_.numberOfBins() + 00175 chi4_.numberOfBins(); 00176 } 00177 T1 & function1() { return chi1_.function(); } 00178 const T1 & function1() const { return chi1_.function(); } 00179 T2 & function2() { return chi2_.function(); } 00180 const T2 & function2() const { return chi2_.function(); } 00181 T3 & function3() { return chi3_.function(); } 00182 const T3 & function3() const { return chi3_.function(); } 00183 T4 & function4() { return chi4_.function(); } 00184 const T4 & function4() const { return chi4_.function(); } 00185 private: 00186 T1 chi1_; 00187 T2 chi2_; 00188 T3 chi3_; 00189 T4 chi4_; 00190 }; 00191 00192 00193 template<typename T1, typename T2,typename T3> 00194 class MultiHistoChiSquare<T1, T2, T3, helper::MultiHistoChiSquareNoArg, 00195 helper::MultiHistoChiSquareNoArg, 00196 helper::MultiHistoChiSquareNoArg> { 00197 public: 00198 MultiHistoChiSquare() { } 00199 template<typename TT1, typename TT2, typename TT3> 00200 MultiHistoChiSquare(TT1 & t1, TH1 *histo1, 00201 TT2 & t2, TH1 *histo2, 00202 TT3 & t3, TH1 *histo3, 00203 double rangeMin, double rangeMax) : 00204 chi1_(t1, histo1, rangeMin, rangeMax), 00205 chi2_(t2, histo2, rangeMin, rangeMax), 00206 chi3_(t3, histo3, rangeMin, rangeMax) { 00207 } 00208 double operator()() const { 00209 return chi1_() + chi2_() + chi3_(); 00210 } 00211 void setHistos(TH1 *histo1, TH1 *histo2, TH1 *histo3) { 00212 chi1_.setHistos(histo1); 00213 chi2_.setHistos(histo2); 00214 chi3_.setHistos(histo3); 00215 } 00216 size_t numberOfBins() const { 00217 return 00218 chi1_.numberOfBins() + 00219 chi2_.numberOfBins() + 00220 chi3_.numberOfBins(); 00221 } 00222 T1 & function1() { return chi1_.function(); } 00223 const T1 & function1() const { return chi1_.function(); } 00224 T2 & function2() { return chi2_.function(); } 00225 const T2 & function2() const { return chi2_.function(); } 00226 T3 & function3() { return chi3_.function(); } 00227 const T3 & function3() const { return chi3_.function(); } 00228 private: 00229 T1 chi1_; 00230 T2 chi2_; 00231 T3 chi3_; 00232 }; 00233 00234 template<typename T1, typename T2> 00235 class MultiHistoChiSquare<T1, T2, 00236 helper::MultiHistoChiSquareNoArg, 00237 helper::MultiHistoChiSquareNoArg, 00238 helper::MultiHistoChiSquareNoArg, 00239 helper::MultiHistoChiSquareNoArg> { 00240 public: 00241 MultiHistoChiSquare() { } 00242 template<typename TT1, typename TT2> 00243 MultiHistoChiSquare(TT1 & t1, TH1 *histo1, 00244 TT2 & t2, TH1 *histo2, 00245 double rangeMin, double rangeMax): 00246 chi1_(t1, histo1, rangeMin, rangeMax), 00247 chi2_(t2, histo2, rangeMin, rangeMax) { 00248 } 00249 double operator()() const { 00250 return chi1_() + chi2_(); 00251 } 00252 void setHistos(TH1 *histo1, TH1 *histo2) { 00253 chi1_.setHistos(histo1); 00254 chi2_.setHistos(histo2); 00255 } 00256 size_t numberOfBins() const { 00257 return 00258 chi1_.numberOfBins() + 00259 chi2_.numberOfBins(); 00260 } 00261 private: 00262 T1 chi1_; 00263 T2 chi2_; 00264 }; 00265 00266 template<typename T1> 00267 class MultiHistoChiSquare<T1, 00268 helper::MultiHistoChiSquareNoArg, 00269 helper::MultiHistoChiSquareNoArg, 00270 helper::MultiHistoChiSquareNoArg, 00271 helper::MultiHistoChiSquareNoArg, 00272 helper::MultiHistoChiSquareNoArg> { 00273 public: 00274 MultiHistoChiSquare() { } 00275 template<typename TT1> 00276 MultiHistoChiSquare(TT1 & t1, TH1 *histo1, double rangeMin, double rangeMax) 00277 : chi1_(t1, histo1, rangeMin, rangeMax) { 00278 } 00279 double operator()() const { 00280 return chi1_(); 00281 } 00282 void setHistos(TH1 *histo1) { 00283 chi1_.setHistos(histo1); 00284 } 00285 size_t numberOfBins() const { 00286 return chi1_.numberOfBins(); 00287 } 00288 private: 00289 T1 chi1_; 00290 }; 00291 00292 template<typename T1, typename T2, typename T3, 00293 typename T4, typename T5, typename T6> 00294 struct RootMinuitResultPrinter<MultiHistoChiSquare<T1, T2, T3, T4, T5, T6> > { 00295 static void print(double amin, unsigned int numberOfFreeParameters, 00296 const MultiHistoChiSquare<T1, T2, T3, T4, T5, T6> & f) { 00297 unsigned int ndof = f.numberOfBins() - numberOfFreeParameters; 00298 std::cout << "chi-squared/n.d.o.f. = " << amin << "/" << ndof << " = " << amin/ndof 00299 << "; prob: " << TMath::Prob(amin, ndof) 00300 << std::endl; 00301 } 00302 }; 00303 } 00304 00305 #endif