00001 #include "cafe/StatSample.hpp"
00002 #include <string>
00003
00004 using namespace std ;
00005
00006 namespace cafe {
00007
00008 StatSample::StatSample(const string& sample) : _name(sample)
00009 {
00010 _events.push_back(new StatWeight("Initial")) ;
00011 _weight = new StatWeight("Efficiency correction") ;
00012 }
00013
00014 StatSample::~StatSample() {
00015 }
00016
00017 void StatSample::AddTags(const vector<string>& tags) {
00018 for (vector<string>::const_iterator it = tags.begin() ;
00019 it != tags.end(); it++) {
00020 string s = *it ;
00021 while (s.size() > 0 && s.substr(0,1) == " ") s.erase(0,1) ;
00022 while (s.size() > 0 && s.substr(s.size()-1,1) == " ") s.erase(s.size()-1,1) ;
00023 if (s.size() ==0 ) continue ;
00024 _tags.push_back(s) ;
00025 }
00026 return ;
00027 }
00028
00029
00030 void StatSample::AddAndTags(const vector<string>& tags) {
00031 for (vector<string>::const_iterator it = tags.begin() ;
00032 it != tags.end(); it++) {
00033 string s = *it ;
00034 while (s.size() > 0 && s.substr(0,1) == " ") s.erase(0,1) ;
00035 while (s.size() > 0 && s.substr(s.size()-1,1) == " ") s.erase(s.size()-1,1) ;
00036 if (s.size() ==0 ) continue ;
00037 _tags_and.push_back(s) ;
00038 }
00039 return ;
00040 }
00041
00042 unsigned long StatSample::add(cafe::Event* event, const std::string& name) {
00043 if (!event) {
00044 cerr << "StatSample ERROR!. Event pointer == 0." << endl ;
00045 return 0;
00046 }
00047
00048 if (!tagged(event)) return 0 ;
00049
00050 vector<StatWeight*>::const_iterator it = _events.begin();
00051 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00052
00053 if (it == _events.end()) {
00054 _events.push_back(new StatWeight(name, true)) ;
00055 it = _events.end()-1 ;
00056 }
00057
00058 (*it) ->applyWeight(_weight->weight(), _weight->weight_pos(), _weight->weight_neg()) ;
00059 return (*it)->nevents() ;
00060 }
00061
00062 double StatSample::applyWeight(cafe::Event* event, const std::string& name,
00063 double weight, double weight_pos, double weight_neg) {
00064 if (!event) {
00065 cerr << "StatSample ERROR!. Event pointer == 0." << endl ;
00066 return 0;
00067 }
00068
00069 if (!tagged(event)) return 0.0 ;
00070
00071 vector<StatWeight*>::const_iterator it = _events.begin();
00072 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00073
00074 if (it == _events.end()) {
00075 _events.push_back(new StatWeight(name)) ;
00076 it = _events.end()-1 ;
00077 }
00078
00079
00080 _weight->applyWeight(weight, weight_pos, weight_neg) ;
00081
00082
00083 return (*it) ->applyWeight(weight, weight_pos, weight_neg) ;
00084 }
00085
00086
00087
00088 unsigned long StatSample::nevents(unsigned int n ) const {
00089 if (n >= _events.size()) {
00090 cerr << "ERROR! StatSample \"" << _name << "\": selection number " << n
00091 << " greater than selection size " << _events.size() << endl ;
00092 exit(1) ;
00093 }
00094 return _events[n]->nevents() ;
00095 }
00096
00097
00098 unsigned long StatSample::nevents(const string& name) const {
00099
00100 vector<StatWeight*>::const_iterator it = _events.begin();
00101 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00102
00103 if (it == _events.end()) {
00104 cout << "cafe::StatSample: \"" << _name << "\": No weight with name \"" << name
00105 << "\" found in the Stat class" << endl ;
00106 return 0 ;
00107 }
00108 return (*it)->nevents() ;
00109 }
00110
00111 void StatSample::Clear() {
00112 for (vector<StatWeight*>::iterator it = _events.begin() ;
00113 it != _events.end(); it++)
00114 (*it)->Clear() ;
00115
00116 _weight->Clear() ;
00117 return ;
00118 }
00119
00120 const StatWeight* StatSample::eventWeight(const std::string& name) const {
00121
00122 if (name == "global") return _weight ;
00123
00124 vector<StatWeight*>::const_iterator it = _events.begin();
00125 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00126
00127 if (it == _events.end()) throw StatWeightNotFoundException(name) ;
00128
00129 return *it ;
00130 }
00131
00132 Collection<EventWeight> StatSample::ListEventWeights() const {
00133 Collection<EventWeight> weightlist;
00134 EventWeight *weight;
00135
00136 weight = new EventWeight("Global weight",_weight->weight(),
00137 _weight->weight_pos(),_weight->weight_neg());
00138 weightlist.push_back(weight);
00139 vector<StatWeight*>::const_iterator it = _events.begin();
00140 for (; it != _events.end(); it++) {
00141
00142 if ((*it)->isWeight() && (*it)->name() != "Efficiency correction"
00143 && (*it)->name() != "Initial") {
00144 weight = new EventWeight((*it)->name(),((StatWeight*)(*it))->weight(),
00145 ((StatWeight*)(*it))->weight_pos(),((StatWeight*)(*it))->weight_neg());
00146 weightlist.push_back(weight);
00147 }
00148 }
00149 return weightlist;
00150 }
00151
00152 const StatWeight* StatSample::eventWeight(unsigned int n) const {
00153 if (n >= _events.size()) {
00154 cerr << "ERROR! StatSample: \"" << _name << "\": weight number " << n
00155 << " greater than selection size " << _events.size() << endl ;
00156 exit(1) ;
00157 }
00158
00159 return _events[n] ;
00160 }
00161
00162 const StatWeight* StatSample::eventSelection(unsigned int n) const {
00163 if (n >= _events.size()) {
00164 cerr << "ERROR! StatSample \"" << _name << "\": Selection number " << n
00165 << " greater than selection size " << _events.size() << endl ;
00166 exit(1) ;
00167 }
00168 return _events[n];
00169 }
00170
00171 const StatWeight* StatSample::eventSelection(const string& name) const {
00172
00173 vector<StatWeight*>::const_iterator it = _events.begin();
00174 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00175
00176 if (it == _events.end()) {
00177 cout << "cafe::StatSample \"" << _name << "\": No selection with name \"" << name
00178 << "\" found in the Stat class" << endl ;
00179 return 0 ;
00180 }
00181
00182 return (*it) ;
00183 }
00184
00185 double StatSample::eff(unsigned int n) const {
00186 if (n >= _events.size()) {
00187 cerr << "ERROR! StatSamplec\"" << _name << "\": Selection number " << n
00188 << " greater than selection size " << _events.size() << endl ;
00189 exit(1) ;
00190 }
00191
00192 if (_events[n]->isWeight()) return _events[n]->weight_average() ;
00193
00194 if ( n > 0)
00195 return ((double)_events[n]->nevents())/_events[n-1]->nevents() ;
00196
00197 return -1.0 ;
00198 }
00199
00200
00201 double StatSample::eff(const std::string& name) const {
00202
00203 vector<StatWeight*>::const_iterator it = _events.begin();
00204 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00205
00206 if (it == _events.end()) {
00207 cout << "cafe::StatSample \"" << _name << "\": No selection with name \"" << name
00208 << "\" found in the Stat class" << endl ;
00209 return 0 ;
00210 }
00211
00212 if (it == _events.begin()) return 0 ;
00213
00214 return ((double) (*it)->nevents())/(*(it-1))->nevents() ;
00215 }
00216
00217
00218 double StatSample::effErr(unsigned int n) const {
00219 if (n >= _events.size()) {
00220 cerr << "ERROR! StatSample \"" << _name << "\": Selection number " << n
00221 << " greater than selection size " << _events.size() << endl ;
00222 exit(1) ;
00223 }
00224
00225 if (_events[n]->isWeight()) return (_events[n])->err() ;
00226
00227 if ( n >0)
00228 return _events[n]->err(*_events[n-1]) ;
00229
00230 return -1.0 ;
00231 }
00232
00233 double StatSample::effErr(const std::string& name) const {
00234
00235 vector<StatWeight*>::const_iterator it = _events.begin();
00236 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00237
00238 if (it == _events.end()) {
00239 cout << "cafe::StatSample \"" << _name << "\": No selection with name \"" << name
00240 << "\" found in the Stat class" << endl ;
00241 return 0 ;
00242 }
00243
00244 if (it == _events.begin()) return 0 ;
00245
00246 return (*it)->err(**(it-1)) ;
00247 }
00248
00249
00250 double StatSample::effGlob(unsigned int n) const {
00251 if (n >= _events.size()) {
00252 cerr << "ERROR! StatSample \"" << _name << "\": Selection number " << n
00253 << " greater than selection size " << _events.size() << endl ;
00254 exit(1) ;
00255 }
00256
00257 if ( _events.front()->nevents() == 0 ) return -1.0 ;
00258
00259 if (n == 0)
00260 return ((double)_events.back()->nevents())/_events.front()->nevents() ;
00261
00262 return ((double)_events[n]->nevents())/_events.front()->nevents() ;
00263 }
00264
00265
00266 double StatSample::effGlob(const std::string& name) const {
00267
00268 if ( _events.front()->nevents() == 0 ) return -1.0 ;
00269
00270 vector<StatWeight*>::const_iterator it = _events.begin();
00271 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00272
00273 if (it == _events.end()) {
00274 cout << "cafe::StatSample \"" << _name << "\": No selection with name \"" << name
00275 << "\" found in the Stat class" << endl ;
00276 return -1.0 ;
00277 }
00278
00279 if (it == _events.begin()) return -1.0 ;
00280
00281 return ((double) (*it)->nevents())/_events.front()->nevents() ;
00282 }
00283
00284
00285 double StatSample::effErrGlob(unsigned int n) const {
00286 if (n >= _events.size()) {
00287 cerr << "ERROR! StatSample \"" << _name << "\": Selection number " << n
00288 << " greater than selection size " << _events.size() << endl ;
00289 exit(1) ;
00290 }
00291
00292 if ( _events.front()->nevents() == 0) return -1.0 ;
00293
00294 if ( n == 0)
00295 return _events.back()->err(*_events.front());
00296
00297 return _events[n]->err(*_events.front());
00298 }
00299
00300 double StatSample::effErrGlob(const std::string& name) const {
00301
00302 if ( _events.front()->nevents() == 0 ) return -1.0 ;
00303
00304 vector<StatWeight*>::const_iterator it = _events.begin();
00305 for (; it != _events.end(); it++) if ((*it)->name() == name ) break ;
00306
00307 if (it == _events.end()) {
00308 cout << "cafe::StatSample \"" << _name << "\": No selection with name \"" << name
00309 << "\" found in the Stat class" << endl ;
00310 return -1.0 ;
00311 }
00312
00313 if (it == _events.begin()) return -1.0 ;
00314
00315 return (*it)->err(*_events.front());
00316 }
00317
00318 double StatSample::correctedEfficiency(unsigned int n) const {
00319 return effGlob(n) * eventWeight(n)->weight_average() ;
00320 }
00321
00322 double StatSample::correctedEffErr(unsigned int n) const {
00323 const StatWeight* w = eventWeight(n) ;
00324 return sqrt(pow(w->weight_average()*effErrGlob(n),2)
00325 + pow(effGlob(n)*w->err(),2)) ;
00326 }
00327
00328 double StatSample::correctedEfficiency(const std::string& name) const {
00329 return effGlob(name) * eventWeight(name)->weight_average() ;
00330 }
00331
00332 double StatSample::correctedEffErr(const std::string& name) const {
00333 const StatWeight* w = eventWeight(name) ;
00334 return sqrt(pow(w->weight_average()*effErrGlob(name),2)
00335 + pow(effGlob(name)*w->err(),2)) ;
00336 }
00337
00338 bool StatSample::compareNames(const StatSample& sample) const {
00339
00340 if (_events.size() != sample._events.size()) return false ;
00341
00342 for (unsigned int n = 0 ; n < _events.size() ; n++)
00343 if (_events[n]->name() != sample._events[n]->name() ) return false ;
00344
00345 return true ;
00346 }
00347
00348 bool StatSample::tagged(const cafe::Event* event) const {
00349
00350 if (_tags.size() == 0 && _tags_and.size() == 0 ) return true ;
00351
00352 for (vector<string>::const_iterator it = _tags_and.begin() ;
00353 it != _tags_and.end(); it++) {
00354 if (!event->hasTag(*it)) return false ;
00355 }
00356
00357 return _tags.size() == 0 || event->hasTag(_tags) ;
00358 }
00359
00360
00361 ostream& StatSample::HtmlTable(ostream& os) const {
00362
00363 bool weightMode = _weight->nevents() > 0 ? true : false ;
00364
00365 os << "<TABLE BORDERCOLORDARK=\"996633\" BORDERCOLOR=\"CC9966\" BORDERCOLORLIGHT=\"FFCC99\" border=3 cellPadding=5 width=\"99%\">" << endl ;
00366 os << "<TBODY align=right>" << endl ;
00367
00368 os << "<TR>" << endl ;
00369 os << "<TH align=left>" << endl ;
00370 os << "SELECTION" ;
00371 os << " </TH>" << endl ;
00372 if (weightMode)
00373 os << "<TH align=center colspan=4>" << endl ;
00374 else
00375 os << "<TH align=center colspan=3>" << endl ;
00376 os << name() << endl ;
00377 os << "</TH>" << endl ;
00378 os << "</TR>" << endl ;
00379
00380 bool color = false ;
00381
00382 for (unsigned int n = 0; n < size() ; n++) {
00383
00384 if (color) {
00385 os << "<TR BGCOLOR=#bfefff>" << endl ;
00386 color = !color ;
00387 } else {
00388 os << "<TR>" << endl ;
00389 color = !color ;
00390 }
00391
00392 os << "<TD align=left>" << endl ;
00393 os << eventSelection(n)->name() << endl ;
00394 os << "</TD>" << endl ;
00395
00396 os << "<TD TITLE=\"Number of events\">" << endl ;
00397 os << nevents(n) << endl ;
00398 if (n==0) {
00399 os << "<TD> </TD> <TD> </TD>" ;
00400 if (weightMode) os << "<TD> </TD> " ;
00401 os << endl ;
00402 continue ;
00403 }
00404
00405 if (eventSelection(n)->isWeight()) {
00406 if (eventSelection(n)->name() == eventWeight()->name())
00407 os << "</TD> <TD TITLE=\"Global event weight\">" << endl ;
00408 else
00409 os << "</TD> <TD TITLE=\"Average weight\">" << endl ;
00410 os << eff(n) << "±" << effErr(n)<< endl ;
00411 os << "</TD> <TD>  </TD>";
00412 if (weightMode) os << "<TD>  </TD>";
00413 os << endl ;
00414 continue ;
00415 }
00416
00417 os << "</TD><TD TITLE=\"Selection efficiency\">"<< endl ;
00418 os << 100.0*eff(n) << "±" << 100.0*effErr(n) << "%" << endl ;
00419 os << "</TD><TD TITLE=\"Global efficiency\">"<< endl ;
00420 os << 100.0*effGlob(n) << "±" << 100.0*effErrGlob(n) << "%"
00421 << endl ;
00422 os << "</TD>" << endl ;
00423 if (weightMode) {
00424 os << "</TD><TD TITLE=\"Global efficiency corrected by the event weight\">"<< endl ;
00425 os << 100.0*correctedEfficiency(n) << "±" << 100.0*correctedEffErr(n) << "%"
00426 << endl ;
00427 os << "</TD>" << endl ;
00428 }
00429 os << "</TR>" << endl ;
00430 }
00431
00432 os << "</TBODY></TABLE>" << endl ;
00433
00434 return os ;
00435 }
00436
00437
00439 ostream& StatSample::print_tex (ostream& os, const string title) const {
00440
00441 bool weightMode = _weight->nevents() > 0 ? true : false ;
00442
00443 os << "" << endl;
00444 os << "% Efficiency table %" << endl;
00445 os << "" << endl;
00446 os << "\\begin{table}[p]" << endl;
00447 os << "\\begin{center}" << endl;
00448 os << "\\begin{tabular}{lrrr" ;
00449 if (weightMode) os << "r" ;
00450 os << "}" << endl;
00451 os << " \\hline \\hline" << endl;
00452 os << " Selection & Events & Relative & Total " ;
00453 if (weightMode) os << "& Total Corrected by Event Weights " ;
00454 os << "\\\\ \\hline" << endl;
00455
00456 os << tex(eventSelection(0)->name()) << " & " ;
00457 os << nevents(0) << " & & " ;
00458 if (weightMode) os << " & " ;
00459 os << "\\\\ " << endl ;
00460
00461 for (unsigned int n = 1; n < size() ; n++) {
00462
00463 os << tex(eventSelection(n)->name()) << " & " ;
00464 os << nevents(n) << " & ";
00465
00466 if (eventSelection(n)->isWeight()) {
00467 os << " $\\mathit{ " << eff(n) << " \\pm "
00468 << effErr(n) << " }$ & & " ;
00469 if (weightMode) os << " & " ;
00470 } else {
00471 os << " $ " << 100.0*eff(n) << " \\pm "
00472 << 100.0*effErr(n) << " ~\\% $ & " ;
00473 os << " $ " << 100.0*effGlob(n) << " \\pm "
00474 << 100.0*effErrGlob(n) << "~\\% $ " ;
00475 if (weightMode)
00476 os << " $ " << 100.0*correctedEfficiency(n) << " \\pm "
00477 << 100.0*correctedEffErr(n) << "~\\% $ " ;
00478 }
00479
00480 os << " \\\\ " << endl ;
00481 }
00482
00483 os << " \\hline " << endl;
00484 os << " \\hline" << endl;
00485 os << " \\end{tabular}" << endl;
00486 os << " \\caption{" << title << " Sample " << name() << " }" << endl;
00487 os << " \\label{Table:" << title.c_str() << ":" << name() << "}" << endl;
00488 os << "\\end{center}" << endl;
00489 os << "\\end{table}" << endl;
00490 os << endl;
00491
00492 return os ;
00493 }
00494
00495
00496 std::string StatSample::tex(const std::string& init) {
00497 string name ;
00498 for (unsigned int i=0; i<init.size(); i++) {
00499 string ch ;
00500 if (init.substr(i,1) == "_") ch = "\\_" ;
00501 else if (init.substr(i,2) == ">=") {
00502 ch = "$\\geq$" ;
00503 i++ ;
00504 }
00505 else if (init.substr(i,2) == "<=") {
00506 ch = "$\\leq$" ;
00507 i++ ;
00508 }
00509 else if (init.substr(i,1) == "<") ch = "$<$" ;
00510 else if (init.substr(i,1) == ">") ch = "$>$" ;
00511 else ch = init.substr(i,1) ;
00512 name = name + ch ;
00513 }
00514 return name ;
00515 }
00516
00517 }
00518
00519 ClassImp(cafe::StatSample);