CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/PhysicsTools/FWLite/interface/Scanner.h

Go to the documentation of this file.
00001 // these includes are FWLite-safe
00002 #include "DataFormats/FWLite/interface/Handle.h"
00003 #include "DataFormats/FWLite/interface/Event.h"
00004 // these are from ROOT, so they're safe too
00005 #include <TString.h>
00006 #include <TRegexp.h>
00007 #include <TObjString.h>
00008 #include <TObjArray.h>
00009 #include <TDirectory.h>
00010 #include <TEnv.h>
00011 #include <TClass.h>
00012 
00013 #if !defined(__CINT__) && !defined(__MAKECINT__)
00014 #include <RooFit.h>
00015 #include <RooArgList.h>
00016 #include <RooDataSet.h>
00017 #include <RooRealVar.h>
00018 #include <RooCategory.h>
00019 
00020 #include "PhysicsTools/FWLite/interface/ScannerHelpers.h"
00021 #endif
00022 
00023 #include "PhysicsTools/FWLite/interface/EventSelectors.h"
00024 
00025 namespace fwlite {
00026 
00043     template<typename Collection>
00044     class Scanner {
00045         public:
00047             typedef fwlite::Handle<Collection> HandleT;
00048 
00050             Scanner(fwlite::EventBase *ev, const char *label, const char *instance = "", const char *process="")  :
00051                 event_(ev), label_(label), instance_(instance), 
00052                 printFullEventId_(ev->isRealData()),
00053                 ignoreExceptions_(false),
00054                 exprSep_(":"),
00055                 maxEvents_(-1),
00056                 maxLinesToPrint_(50)
00057             {
00058                 objType = helper::Parser::elementType(edm::TypeWithDict(HandleT::TempWrapT::typeInfo()));
00059             }
00060 
00061    //------------------------------------------------------------------------------------------------------------------------------------
00077             void scan(const char *exprs, const char *cut="", int nmax=-1) {
00078                 helper::ScannerBase scanner(objType); 
00079                 scanner.setIgnoreExceptions(ignoreExceptions_);
00080 
00081                 TObjArray  *exprArray = TString(exprs).Tokenize(exprSep_);
00082                 int rowline = 0;
00083                 if (printFullEventId_) {
00084                     printf(" : %9s : %4s : %9s : %3s", "RUN", "LUMI", "EVENT", "#IT");
00085                     rowline += 3*4+9+4+9+3-1; // -1 as first char remain blank
00086                 } else {
00087                     printf(" : %5s : %3s", "EVENT", "#IT");
00088                     rowline += 3+6+3+3-1;  // -1 as first char remain blank
00089                 }
00090                 for (int i = 0; i < exprArray->GetEntries(); ++i) {
00091                     TString str = ((TObjString *)(*exprArray)[i])->GetString();
00092                     std::string lb = str.Data();
00093                     std::string ex = str.Data();
00094                     if ((ex[0] == '@') && (ex.find('=') != std::string::npos)) {
00095                         lb = lb.substr(1,ex.find('=')-1); 
00096                         ex = ex.substr(ex.find('=')+1);    
00097                     }
00098                     scanner.addExpression(ex.c_str());
00099                     printf(" : %8s", (lb.size()>8 ? lb.substr(lb.size()-8) : lb).c_str()); // the rightmost part is usually the more interesting one
00100                     rowline += 3+8;
00101                 }
00102                 std::cout << " :" << std::endl;
00103                 rowline += 2;
00104                 delete exprArray;
00105 
00106                 TString rule('-', rowline);
00107                 std::cout << " " << rule << " " << std::endl;
00108 
00109                 if (strlen(cut)) scanner.setCut(cut);
00110 
00111                 int iev = 0, line = 0;
00112                 for (event_->toBegin(); (iev != nmax) && !event_->atEnd(); ++iev, ++(*event_)) {
00113                     if (!selectEvent(*event_)) continue;
00114                     handle_.getByLabel(*event_, label_.c_str(), instance_.c_str(), process_.c_str());
00115                     if (handle_.failedToGet()) {
00116                         if (ignoreExceptions_) continue;
00117                     } 
00118                     const Collection & vals = *handle_;
00119                     for (size_t j = 0, n = vals.size(); j < n; ++j) {
00120                         if (!scanner.test(&vals[j])) continue;
00121                         if (printFullEventId_) {
00122                             const edm::EventAuxiliary &id = event_->eventAuxiliary();
00123                             printf(" : %9d : %4d : %9d : %3lu", id.run(), id.luminosityBlock(), id.event(), (unsigned long)j);
00124                         } else {
00125                             printf(" : %5d : %3lu", iev, (unsigned long)j);
00126                         }
00127                         scanner.print(&vals[j]);
00128                         std::cout << " :" << std::endl;
00129                         if (++line == maxLinesToPrint_) {
00130                             line = 0;
00131                             if (!wantMore()) { 
00132                                 iev = nmax-1; // this is to exit the outer loop
00133                                 break;        // and this to exit the inner one
00134                              }
00135                         }
00136                     }
00137                 }
00138                 std::cout << std::endl;
00139             }
00140   
00141    //------------------------------------------------------------------------------------------------------------------------------------
00145             size_t count(const char *cut) {
00146                 helper::ScannerBase scanner(objType); 
00147                 scanner.setIgnoreExceptions(ignoreExceptions_);
00148 
00149                 scanner.setCut(cut);
00150 
00151                 size_t npass = 0;
00152                 int iev = 0;
00153                 for (event_->toBegin(); !event_->atEnd(); ++(*event_), ++iev) {
00154                     if (maxEvents_ > -1 && iev > maxEvents_) break;
00155                     if (!selectEvent(*event_)) continue;
00156                     handle_.getByLabel(*event_, label_.c_str(), instance_.c_str(), process_.c_str());
00157                     const Collection & vals = *handle_;
00158                     for (size_t j = 0, n = vals.size(); j < n; ++j) {
00159                         if (scanner.test(&vals[j])) npass++;
00160                     }
00161                 }
00162                 return npass;
00163             }
00164 
00166             size_t countEvents() {
00167                 size_t npass = 0;
00168                 int iev = 0;
00169                 for (event_->toBegin(); !event_->atEnd(); ++(*event_), ++iev) {
00170                     if (maxEvents_ > -1 && iev > maxEvents_) break;
00171                     if (selectEvent(*event_)) npass++;
00172                 }
00173                 return npass;
00174             }
00175 
00176    //------------------------------------------------------------------------------------------------------------------------------------
00185             TH1 * draw(const char *expr, const char *cut, TString drawopt, TH1 *hist) {
00186                 // prep the machinery
00187                 helper::ScannerBase scanner(objType);
00188                 scanner.setIgnoreExceptions(ignoreExceptions_);
00189                 if (!scanner.addExpression(expr)) return 0;
00190                 if (strlen(cut)) scanner.setCut(cut);
00191 
00192                 // check histo
00193                 if (hist == 0) {
00194                     std::cerr << "Method draw(expr, cut, drawopt, hist) cannot be called with null 'hist'. Use the other draw methods instead." << std::endl;
00195                     return 0;
00196                 }
00197 
00198                 // fill histogram
00199                 int iev = 0;
00200                 for (event_->toBegin(); !event_->atEnd(); ++(*event_), ++iev) {
00201                     if (maxEvents_ > -1 && iev > maxEvents_) break;
00202                     if (!selectEvent(*event_)) continue;
00203                     handle_.getByLabel(*event_, label_.c_str(), instance_.c_str(), process_.c_str());
00204                     const Collection & vals = *handle_;
00205                     for (size_t j = 0, n = vals.size(); j < n; ++j) {
00206                         scanner.fill1D(&vals[j], hist);
00207                     }
00208                 }
00209 
00210                 if (drawopt.Contains("NORM",TString::kIgnoreCase) && (hist->Integral() != 0)) {
00211                     hist->Sumw2();
00212                     hist->Scale(1.0/hist->Integral());
00213                     // remove the "NORM" because THistPainter doesn't understand it
00214                     drawopt(TRegexp("[Nn][Oo][Rr][Mm]")) = "";
00215                 }
00216 
00217                 if (!drawopt.Contains("GOFF",TString::kIgnoreCase)) hist->Draw(drawopt);
00218                 return hist;
00219             }
00220 
00227             TH1 * draw(const char *expr, const char *cut = "", TString drawopt = "", const char *hname = "htemp", const TH1 *htemplate = 0) {
00228                 TH1 *hist = 0;
00229                 if (htemplate != 0) {
00230                     if ((strcmp(hname, "htemp") == 0) && (strcmp(hname,htemplate->GetName()) != 0)) htempDelete();
00231                     hist = (TH1*) hist->Clone(hname);
00232                 } else if (drawopt.Contains("SAME",TString::kIgnoreCase)) { 
00233                     hist = getSameH1(hname);
00234                 }
00235 
00236                 // if in the end we found no way to make "hist"
00237                 if (hist == 0) {
00238                     if (strcmp(hname, "htemp") == 0) htempDelete();
00239                     hist = new TH1F(hname, "", gEnv->GetValue("Hist.Binning.1D.x",100), 0, 0);
00240                     hist->SetBit(TH1::kCanRebin);
00241                 }
00242                 hist->SetTitle((strlen(cut) ? TString(expr)+"{"+cut+"}" : TString(expr)));
00243                 hist->GetXaxis()->SetTitle(expr);
00244                 return draw(expr, cut, drawopt, hist);
00245             }
00246 
00247 
00250             TH1 * draw(const char *expr, int nbins, double xlow, double xhigh, const char *cut = "", const char *drawopt = "", const char *hname = "htemp") {
00251                 if (TString(drawopt).Contains("SAME",TString::kIgnoreCase)) { 
00252                     std::cerr << "Binning is ignored when 'SAME' is specified." << std::endl; 
00253                     TH1 *hsame = getSameH1(hname);
00254                     return draw(expr, cut, drawopt, hsame);
00255                 }
00256                 if (strcmp(hname, "htemp") == 0) htempDelete();
00257                 TH1 * htemp = new TH1F(hname, expr, nbins, xlow, xhigh);
00258                 if (strlen(cut)) htemp->SetTitle(TString(expr)+"{"+cut+"}");
00259                 htemp->GetXaxis()->SetTitle(expr);
00260                 return draw(expr,cut,drawopt,htemp);
00261             }
00264             TH1 * draw(const char *expr, int nbins, double *xbins, const char *cut = "", const char *drawopt = "", const char *hname = "htemp") {
00265                 if (TString(drawopt).Contains("SAME",TString::kIgnoreCase)) { 
00266                     std::cerr << "Binning is ignored when 'SAME' is specified." << std::endl; 
00267                     TH1 *hsame = getSameH1(hname);
00268                     return draw(expr, cut, drawopt, hsame);
00269                 }
00270                 if (strcmp(hname, "htemp") == 0) htempDelete();
00271                 TH1 * htemp = new TH1F(hname, expr, nbins, xbins);
00272                 if (strlen(cut)) htemp->SetTitle(TString(expr)+"{"+cut+"}");
00273                 htemp->GetXaxis()->SetTitle(expr);
00274                 return draw(expr,cut,drawopt,htemp);
00275             }
00276 
00277    //------------------------------------------------------------------------------------------------------------------------------------
00279             TProfile * drawProf(TString xexpr, TString yexpr, const char *cut, TString drawopt, TProfile *hist) {
00280                 // prep the machinery
00281                 helper::ScannerBase scanner(objType);
00282                 scanner.setIgnoreExceptions(ignoreExceptions_);
00283                 if (!scanner.addExpression(xexpr.Data())) return 0;
00284                 if (!scanner.addExpression(yexpr.Data())) return 0;
00285                 if (strlen(cut)) scanner.setCut(cut);
00286 
00287                 // check histo
00288                 if (hist == 0) {
00289                     std::cerr << "Method drawProf(xexpr, yexpr, cut, drawopt, hist) cannot be called with null 'hist'. Use the other draw methods instead." << std::endl;
00290                     return 0;
00291                 }
00292 
00293                 // fill histogram
00294                 int iev = 0;
00295                 for (event_->toBegin(); !event_->atEnd(); ++(*event_), ++iev) {
00296                     if (maxEvents_ > -1 && iev > maxEvents_) break;
00297                     if (!selectEvent(*event_)) continue;
00298                     handle_.getByLabel(*event_, label_.c_str(), instance_.c_str(), process_.c_str());
00299                     const Collection & vals = *handle_;
00300                     for (size_t j = 0, n = vals.size(); j < n; ++j) {
00301                         scanner.fillProf(&vals[j], hist);
00302                     }
00303                 }
00304 
00305                 if (!strlen(hist->GetTitle())) hist->SetTitle((strlen(cut) ? yexpr+":"+xexpr+"{"+cut+"}" : yexpr+":"+xexpr));
00306                 if (!strlen(hist->GetXaxis()->GetTitle())) hist->GetXaxis()->SetTitle(xexpr);
00307                 if (!strlen(hist->GetYaxis()->GetTitle())) hist->GetYaxis()->SetTitle(yexpr);
00308                 if (!TString(drawopt).Contains("GOFF",TString::kIgnoreCase)) hist->Draw(drawopt);
00309                 return hist;
00310             }
00312             TProfile * drawProf(TString xexpr, TString yexpr, const char *cut = "", TString drawopt = "", const char *hname = "htemp", TProfile *htemplate = 0) {
00313                 TProfile *hist = 0;
00314                 if (htemplate != 0) {
00315                     if ((strcmp(hname, "htemp") == 0) && (strcmp(hname,htemplate->GetName() )!= 0)) htempDelete();
00316                     hist = (TProfile*) hist->Clone(hname);
00317                 } else if (drawopt.Contains("SAME",TString::kIgnoreCase)) { 
00318                     hist = getSameProf(hname);
00319                 }
00320 
00321                 // if in the end we found no way to make "hist"
00322                 if (hist == 0) {
00323                     if (strcmp(hname, "htemp") == 0) htempDelete();
00324                     hist = new TProfile(hname, "", gEnv->GetValue("Hist.Binning.1D.x",100), 0., 0.);
00325                     hist->SetBit(TProfile::kCanRebin);
00326                 }
00327                 return drawProf(xexpr, yexpr, cut, drawopt, hist);
00328             }
00329 
00331             TProfile * drawProf(TString xexpr, int bins, double xlow, double xhigh, TString yexpr, const char *cut = "", const char *drawopt = "", const char *hname = "htemp") {
00332                 if (TString(drawopt).Contains("SAME",TString::kIgnoreCase)) { 
00333                     std::cerr << "Binning is ignored when 'SAME' is specified." << std::endl; 
00334                     TProfile *hsame = getSameProf(hname);
00335                     return drawProf(xexpr, yexpr, cut, drawopt, hsame);
00336                 }
00337                 if (strcmp(hname, "htemp") == 0) htempDelete();
00338                 TProfile * htemp = new TProfile(hname, "", bins, xlow, xhigh);
00339                 return drawProf(xexpr,yexpr,cut,drawopt,htemp);
00340             }
00341 
00342    //------------------------------------------------------------------------------------------------------------------------------------
00344             TH2 * draw2D(TString xexpr, TString yexpr, const char *cut, TString drawopt, TH2 *hist) {
00345                 // prep the machinery
00346                 helper::ScannerBase scanner(objType);
00347                 scanner.setIgnoreExceptions(ignoreExceptions_);
00348                 if (!scanner.addExpression((const char *)xexpr)) return 0;
00349                 if (!scanner.addExpression((const char *)yexpr)) return 0;
00350                 if (strlen(cut)) scanner.setCut(cut);
00351 
00352                 // check histo
00353                 if (hist == 0) {
00354                     std::cerr << "Method draw2D(xexpr, yexpr, cut, drawopt, hist) cannot be called with null 'hist'. Use the other draw methods instead." << std::endl;
00355                     return 0;
00356                 }
00357 
00358                 // fill histogram
00359                 int iev = 0;
00360                 for (event_->toBegin(), iev = 0; !event_->atEnd(); ++(*event_), ++iev) {
00361                     if (maxEvents_ > -1 && iev > maxEvents_) break;
00362                     if (!selectEvent(*event_)) continue;
00363                     handle_.getByLabel(*event_, label_.c_str(), instance_.c_str(), process_.c_str());
00364                     const Collection & vals = *handle_;
00365                     for (size_t j = 0, n = vals.size(); j < n; ++j) {
00366                         scanner.fill2D(&vals[j], hist);
00367                     }
00368                 }
00369 
00370                 if (!strlen(hist->GetTitle())) hist->SetTitle((strlen(cut) ? yexpr+":"+xexpr+"{"+cut+"}" : yexpr+":"+xexpr));
00371                 if (!strlen(hist->GetXaxis()->GetTitle())) hist->GetXaxis()->SetTitle(xexpr);
00372                 if (!strlen(hist->GetYaxis()->GetTitle())) hist->GetYaxis()->SetTitle(yexpr);
00373                 if (!TString(drawopt).Contains("GOFF",TString::kIgnoreCase)) hist->Draw(drawopt);
00374                 return hist;
00375             }
00378             TH2 * draw2D(TString xexpr, TString yexpr, const char *cut = "", TString drawopt = "", const char *hname = "htemp", TH2 *htemplate = 0) {
00379                 TH2 *hist = 0;
00380                 if (htemplate != 0) {
00381                     if ((strcmp(hname, "htemp") == 0) && (strcmp(hname,htemplate->GetName()) != 0)) htempDelete();
00382                     hist = (TH2*) hist->Clone(hname);
00383                 } else if (drawopt.Contains("SAME",TString::kIgnoreCase)) { 
00384                     hist = getSameH2(hname);
00385                 }
00386 
00387                 // if in the end we found no way to make "hist"
00388                 if (hist == 0) {
00389                     // prep the machinery
00390                     helper::ScannerBase scanner(objType);
00391                     scanner.setIgnoreExceptions(ignoreExceptions_);
00392                     if (!scanner.addExpression((const char *)xexpr)) return 0;
00393                     if (!scanner.addExpression((const char *)yexpr)) return 0;
00394                     if (strlen(cut)) scanner.setCut(cut);
00395 
00396                     if (strcmp(hname, "htemp") == 0) htempDelete();
00397                     // ok this is much more a hack than for the 1D case
00398                     double xmin = 0, xmax = -1, ymin = 0, ymax = -1; int iev;
00399                     for (event_->toBegin(), iev = 0; !event_->atEnd(); ++(*event_), ++iev) {
00400                         if (maxEvents_ > -1 && iev > maxEvents_) break;
00401                         if (!selectEvent(*event_)) continue;
00402                         handle_.getByLabel(*event_, label_.c_str(), instance_.c_str(), process_.c_str());
00403                         const Collection & vals = *handle_;
00404                         for (size_t j = 0, n = vals.size(); j < n; ++j) {
00405                             if (!scanner.test(&vals[j])) continue;
00406                             double x = scanner.eval(&vals[j],0);
00407                             double y = scanner.eval(&vals[j],1);
00408                             if ((xmax == -1) || (x >= xmax)) xmax = x;
00409                             if ((xmin ==  0) || (x <= xmin)) xmin = x;
00410                             if ((ymax == -1) || (y >= ymax)) ymax = y;
00411                             if ((ymin ==  0) || (y <= ymin)) ymin = y;
00412                         }
00413                     }
00414                     hist = new TH2F(hname, "",
00415                             gEnv->GetValue("Hist.Binning.2D.x",20), xmin, xmax,
00416                             gEnv->GetValue("Hist.Binning.2D.y",20), ymin, ymax);
00417                 }
00418                 return draw2D(xexpr, yexpr, cut, drawopt, hist);
00419             }
00420 
00422             TH2 * draw2D(TString xexpr, int xbins, double xlow, double xhigh, 
00423                          TString yexpr, int ybins, double ylow, double yhigh,
00424                          const char *cut = "", const char *drawopt = "", const char *hname="htemp") {
00425                 if (TString(drawopt).Contains("SAME",TString::kIgnoreCase)) { 
00426                     std::cerr << "Binning is ignored when 'SAME' is specified." << std::endl; 
00427                     TH2 *hsame = getSameH2(hname);
00428                     return draw2D(xexpr, yexpr, cut, drawopt, hsame);
00429                 }
00430                 if (strcmp(hname, "htemp") == 0) htempDelete();
00431                 TH2 * htemp = new TH2F("htemp", "", xbins, xlow, xhigh, ybins,ylow,yhigh);
00432                 return draw2D(xexpr,yexpr,cut,drawopt,htemp);
00433             }
00434 
00436             TGraph * drawGraph(TString xexpr, TString yexpr, const char *cut, TString drawopt, TGraph *graph) {
00437                 // prep the machinery
00438                 helper::ScannerBase scanner(objType);
00439                 scanner.setIgnoreExceptions(ignoreExceptions_);
00440                 if (!scanner.addExpression((const char *)xexpr)) return 0;
00441                 if (!scanner.addExpression((const char *)yexpr)) return 0;
00442                 if (strlen(cut)) scanner.setCut(cut);
00443 
00444                 // make graph, if needed
00445                 if (graph == 0) {
00446                     graph = new TGraph();
00447                     graph->SetNameTitle("htemp", (strlen(cut) ? yexpr+":"+xexpr+"{"+cut+"}" : yexpr+":"+xexpr)); 
00448                 }
00449 
00450                 // fill graph
00451                 int iev = 0;
00452                 for (event_->toBegin(); !event_->atEnd(); ++(*event_), ++iev) {
00453                     if (maxEvents_ > -1 && iev > maxEvents_) break;
00454                     if (!selectEvent(*event_)) continue;
00455                     handle_.getByLabel(*event_, label_.c_str(), instance_.c_str(), process_.c_str());
00456                     const Collection & vals = *handle_;
00457                     for (size_t j = 0, n = vals.size(); j < n; ++j) {
00458                         scanner.fillGraph(&vals[j], graph);
00459                     }
00460                 }
00461 
00462                 if (!strlen(graph->GetTitle())) graph->SetTitle((strlen(cut) ? yexpr+":"+xexpr+"{"+cut+"}" : yexpr+":"+xexpr));
00463                 if (!strlen(graph->GetXaxis()->GetTitle())) graph->GetXaxis()->SetTitle(xexpr);
00464                 if (!strlen(graph->GetYaxis()->GetTitle())) graph->GetYaxis()->SetTitle(yexpr);
00465                 if (!TString(drawopt).Contains("GOFF",TString::kIgnoreCase)) graph->Draw(drawopt);
00466                 return graph;
00467             }
00468 
00470             TGraph * drawGraph(TString xexpr, TString yexpr, const char *cut = "", TString drawopt = "AP", const char *gname = "htemp") {
00471                 if (strcmp(gname, "htemp") == 0) htempDelete();
00472                 TGraph *graph =  new TGraph();
00473                 graph->SetNameTitle(gname, (strlen(cut) ? yexpr+":"+xexpr+"{"+cut+"}" : yexpr+":"+xexpr)); 
00474                 return drawGraph(xexpr,yexpr,cut,drawopt,graph);
00475             }
00476 
00477 
00478    //------------------------------------------------------------------------------------------------------------------------------------
00485             RooDataSet *fillDataSet(const char *realvars, const char *boolvars, const char *cut="", const char *name="data") {
00486                 helper::ScannerBase scanner(objType); 
00487                 scanner.setIgnoreExceptions(ignoreExceptions_);
00488 
00489                 RooArgList vars;
00490                 TObjArray  *exprArray = TString(realvars).Tokenize(exprSep_);
00491                 TObjArray  *catArray  = TString(boolvars).Tokenize(exprSep_);
00492                 int nreals = exprArray->GetEntries();
00493                 int nbools  = catArray->GetEntries();
00494                 for (int i = 0; i < nreals; ++i) {
00495                     TString str = ((TObjString *)(*exprArray)[i])->GetString();
00496                     std::string lb = str.Data();
00497                     std::string ex = str.Data();
00498                     if ((ex[0] == '@') && (ex.find('=') != std::string::npos)) {
00499                         lb = lb.substr(1,ex.find('=')-1); 
00500                         ex = ex.substr(ex.find('=')+1);    
00501                     }
00502                     if (!scanner.addExpression(ex.c_str())) {
00503                         std::cerr << "Filed to define real variable '" << lb << "', expr = '" << ex << "'" << std::endl;
00504                         return 0;
00505                     }
00506                     // FIXME: I have to leave it dangling on the HEAP otherwise ROOT segfaults...
00507                     RooRealVar *var = new RooRealVar(lb.c_str(),lb.c_str(), 0.0);
00508                     vars.add(*var);
00509                 }
00510                 for (int i = 0; i < nbools; ++i) {
00511                     TString str = ((TObjString *)(*catArray)[i])->GetString();
00512                     std::string lb = str.Data();
00513                     std::string ex = str.Data();
00514                     if ((ex[0] == '@') && (ex.find('=') != std::string::npos)) {
00515                         lb = lb.substr(1,ex.find('=')-1); 
00516                         ex = ex.substr(ex.find('=')+1);    
00517                     }
00518                     if (!scanner.addExtraCut(ex.c_str())) {
00519                         std::cerr << "Filed to define bool variable '" << lb << "', cut = '" << ex << "'" << std::endl;
00520                         return 0;
00521                     }
00522                     RooCategory *cat = new RooCategory(lb.c_str(), lb.c_str());
00523                     cat->defineType("fail",0);
00524                     cat->defineType("pass",1);
00525                     vars.add(*cat);
00526                 }
00527 
00528                 RooDataSet *ds = new RooDataSet(name, name, vars);
00529 
00530                 if (strlen(cut)) scanner.setCut(cut);
00531                 int iev = 0;
00532                 for (event_->toBegin(); !event_->atEnd(); ++iev, ++(*event_)) {
00533                     if (maxEvents_ > -1 && iev > maxEvents_) break;
00534                     if (!selectEvent(*event_)) continue;
00535                     handle_.getByLabel(*event_, label_.c_str(), instance_.c_str(), process_.c_str());
00536                     if (handle_.failedToGet()) {
00537                         if (ignoreExceptions_) continue;
00538                     } 
00539                     const Collection & vals = *handle_;
00540                     for (size_t j = 0, n = vals.size(); j < n; ++j) {
00541                         if (!scanner.test(&vals[j])) continue;
00542                         for (int i = 0; i < nreals; ++i) {
00543                             RooRealVar *var = (RooRealVar *)vars.at(i);
00544                             var->setVal(scanner.eval(&vals[j], i));
00545                         }
00546                         for (int i = 0; i < nbools; ++i) {
00547                             RooCategory *cat = (RooCategory*) vars.at(i+nreals);
00548                             cat->setIndex(int(scanner.test(&vals[j], i+1))); // 0 is the event selection cut
00549                         }
00550                         ds->add(vars);
00551                     }
00552                 }
00553     
00554                 delete exprArray;
00555                 delete catArray;
00556 
00557                 return ds;
00558             }
00559   
00560 
00561 
00562             void setPrintFullEventId(bool printIt=true) { printFullEventId_ = printIt; }
00563             void setExpressionSeparator(TString separator) { exprSep_ = separator; }
00564             void setIgnoreExceptions(bool ignoreThem) { ignoreExceptions_ = ignoreThem; }
00565             void setMaxLinesToPrint(int lines) { maxLinesToPrint_ = (lines > 0 ? lines : 2147483647); }
00566     
00567             void addEventSelector(fwlite::EventSelector *selector) { eventSelectors_.Add(selector); }
00568             void clearEventSelector() { eventSelectors_.Clear(); }
00569             TObjArray & eventSelectors() { return eventSelectors_; }
00570             bool selectEvent(const fwlite::EventBase &ev) const {
00571                 for (int i = 0, n = eventSelectors_.GetEntries(); i < n; ++i) {
00572                     if (!((fwlite::EventSelector *)(eventSelectors_[i]))->accept(ev)) return false;
00573                 }
00574                 return true;
00575             }
00576 
00577             void setMaxEvents(int max) { maxEvents_ = max; }
00578         private:
00579             fwlite::EventBase *event_;
00580             std::string    label_, instance_, process_;
00581             bool printFullEventId_;
00582             bool ignoreExceptions_;
00583             TString exprSep_;
00584             HandleT        handle_;
00585             edm::TypeWithDict   objType;
00586 
00587             TObjArray eventSelectors_;
00588 
00589             int maxEvents_;
00590 
00591             int maxLinesToPrint_;
00592             bool wantMore() const {
00593                 // ask if user wants more
00594                 fprintf(stderr,"Type <CR> to continue or q to quit ==> ");
00595                 // read first char
00596                 int readch = getchar(), answer = readch;
00597                 // poll out remaining chars from buffer
00598                 while (readch != '\n' && readch != EOF) readch = getchar();
00599                 // check first char
00600                 return !(answer == 'q' || answer == 'Q');
00601             }
00602 
00603             void htempDelete() {
00604                 if (gDirectory) {
00605                     TObject *obj = gDirectory->Get("htemp");
00606                     if (obj) obj->Delete();
00607                 }
00608             }
00609 
00612             TH1 *getSameH1(const char *hname) {
00613                 if (gDirectory && gDirectory->Get("htemp") != 0 && 
00614                         gDirectory->Get("htemp")->IsA()->InheritsFrom(TH1::Class())) {
00615                     TH1 *hist = (TH1*) ((TH1*) gDirectory->Get("htemp"))->Clone(hname);
00616                     hist->Reset();
00617                     hist->SetLineColor(kBlack);
00618                     hist->SetMarkerColor(kBlack);
00619                     return hist;
00620                 } else {
00621                     std::cerr << "There is no 'htemp' histogram from which to 'SAME'." << std::endl;
00622                     return 0;
00623                 }
00624             }
00625 
00628             TH2 *getSameH2(const char *hname) {
00629                 if (gDirectory && gDirectory->Get("htemp") != 0 && 
00630                         gDirectory->Get("htemp")->IsA()->InheritsFrom(TH2::Class())) {
00631                     TH2 *hist = (TH2*) ((TH2*) gDirectory->Get("htemp"))->Clone(hname);
00632                     hist->Reset();
00633                     hist->SetLineColor(kBlack);
00634                     hist->SetMarkerColor(kBlack);
00635                     return hist;
00636                 } else {
00637                     std::cerr << "There is no 'htemp' histogram from which to 'SAME'." << std::endl;
00638                     return 0;
00639                 }
00640             }
00641 
00644             TProfile *getSameProf(const char *hname) {
00645                 if (gDirectory && gDirectory->Get("htemp") != 0 && 
00646                         gDirectory->Get("htemp")->IsA()->InheritsFrom(TProfile::Class())) {
00647                     TProfile *hist = (TProfile*) ((TProfile*) gDirectory->Get("htemp"))->Clone(hname);
00648                     hist->Reset();
00649                     hist->SetLineColor(kBlack);
00650                     hist->SetMarkerColor(kBlack);
00651                     return hist;
00652                 } else {
00653                     std::cerr << "There is no 'htemp' histogram from which to 'SAME'." << std::endl;
00654                     return 0;
00655                 }
00656             }
00657 
00658 
00659     };
00660 }