FairRoot/PandaRoot
autocutx.C
Go to the documentation of this file.
1 #include <algorithm>
2 #include "TFile.h"
3 #include "TTree.h"
4 #include "TLeaf.h"
5 #include "TString.h"
6 #include "TH1F.h"
7 #include "TCanvas.h"
8 #include "TROOT.h"
9 #include "TEventList.h"
10 #include "TDirectory.h"
11 #include <iostream>
12 #include "TLine.h"
13 #include "TLatex.h"
14 #include "TStyle.h"
15 #include "TObjArray.h"
16 #include "TPRegexp.h"
17 #include "TRegexp.h"
18 #include <map>
19 #include <utility>
20 #include <algorithm>
21 
22 #define MAX 1000
23 #define BINS 500
24 #define NCAN 3
25 #define MAXVARS 8 //maximum allowed number of variables for one selection
26 #define MAXCUTS 12 //maximum allowed number of cuts for one selection
27 
28 typedef std::vector<pair<double, int> > ValueMap;
29 typedef std::map<int, int> CountMap;
30 
32 std::map<TString, TString> mctvar;
33 
36 double cut[MAX];
37 double qual[MAX];
38 int idx[MAX];
39 
40 double N0_sig, N0_bg;
41 double Nsigev, Nbgev;
42 bool dstarmode;
43 
44 Float_t fbranch[MAX];
45 Int_t ibranch[MAX];
47 Int_t ev, run, mode, rec, nbranch;
48 
49 // ---------------------------------------------------------------
50 
51 int gettype(TTree *t, TString varname)
52 {
53  TString leaftype = t->GetLeaf(varname)->GetTypeName();
54 
55  if (leaftype=="Float_t") return 0;
56  else if (leaftype=="Int_t") return 1;
57  else if (leaftype=="Bool_t") return 2;
58 
59  return -1;
60 }
61 
62 // ---------------------------------------------------------------
63 
64 bool mycompare(int i, int j)
65 {
66  return qual[i]>qual[j];
67 }
68 
69 // ---------------------------------------------------------------
70 
71 int init(TTree *t)
72 {
73  t->SetBranchAddress("ev",&ev);
74  t->SetBranchAddress("run",&run);
75  t->SetBranchAddress("mode",&mode);
76  t->SetBranchAddress("recmode",&rec);
77 
78  TObjArray* branches = t->GetListOfBranches();
79 
80  nbranch = 0;
81 
82  for(int i=0; i<=branches->GetLast(); ++i)
83  {
84  TBranch* branch = (TBranch*)branches->UncheckedAt(i);
85  TString v=branch->GetName();
86 
87  if ( v=="ev" || v=="mode" || v=="run" || v=="nsig" ) continue;
88  if ( v.Contains("pdg") || v.Contains("beam") || v.Contains("mct") ) continue;
89  if ( v.BeginsWith("t") && v!="thr") continue;
90  if ( v.EndsWith("vx") || v.EndsWith("vy") || v.EndsWith("vz") || v.EndsWith("pocmag")) continue;
91 
92  bool ok=false;
93 
94  if ( v.BeginsWith("es") || v=="mmiss" || v.EndsWith("d0m") ) ok=true;
95  if ( v.EndsWith("p") || v.EndsWith("tht") || v.EndsWith("pcm") || v.EndsWith("thtcm") || v.EndsWith("pt") ) ok=true;
96  if ( ok || v.EndsWith("ang") || v.Contains("poc") ) ok=true;
97  if ( ok || v.Contains("pid") || v.Contains("min") || v.Contains("max") || v.Contains("sum") || v.Contains("fw") ) ok=true;
98  if ( ok || v.EndsWith("sph") || v.EndsWith("apl") || v.EndsWith("pla") || v.EndsWith("thr") || v.EndsWith("cir") ) ok=true;
99 
100  if ( v=="xmdif" && dstarmode ) ok = true;
101  if ( v=="xd0m" && dstarmode ) ok = false;
102 
103  if (!ok) continue;
104 
105  Int_t dtype=gettype(t, v);
106  switch (dtype)
107  {
108  case 0: t->SetBranchAddress(v, &(fbranch[nbranch])); break;
109  case 1: t->SetBranchAddress(v, &(ibranch[nbranch])); break;
110  case 2: t->SetBranchAddress(v, &(bbranch[nbranch])); break;
111  }
112 
113  vars[nbranch] = v;
114  nbranch++;
115  }
116 
117  return nbranch;
118 }
119 
120 // ---------------------------------------------------------------
121 
122 int uid(int lev, int lrun, int lmode)
123 {
124  return lev+10000*lrun+(((lmode/100)%10)*20+lmode%10)*100000;
125 }
126 
127 // ---------------------------------------------------------------
128 
129 int countEvents(TTree *t, TEventList &el)
130 {
131  t->SetEventList(0);
132  t->SetBranchStatus("*",0);
133  t->SetBranchStatus("ev",1);
134  t->SetBranchStatus("run",1);
135  t->SetBranchStatus("mode",1);
136  t->SetBranchStatus("recmode",1);
137 
138  evcnt.clear();
139  for (int j=0;j<10;++j) evcntrec[j].clear();
140 
141  for (int i=0;i<el.GetN();++i)
142  {
143  t->GetEntry(el.GetEntry(i));
144  evcnt[uid(ev,run,mode)]+=1;
145  if (rec<10) evcntrec[rec][uid(ev,run,mode)]+=1;
146  }
147  t->SetBranchStatus("*",1);
148 
149  return evcnt.size();
150 }
151 // ---------------------------------------------------------------
152 
153 void makeMaps(TTree *t, TString varname, TEventList &els, TEventList &elb, ValueMap &sig, ValueMap &bg, int id)
154 {
155  int i;
156  t->SetBranchStatus("*",0);
157  t->SetBranchStatus("ev",1);
158  t->SetBranchStatus("mode",1);
159  t->SetBranchStatus("run",1);
160  t->SetBranchStatus(varname,1);
161 
162  Float_t var;
163  Int_t dtype=gettype(t, varname);
164 
165  sig.clear();
166  bg.clear();
167 
168  // prepare the pairs of variable value, eventnumber for signal and count signals
169  for (i=0;i<els.GetN();++i)
170  {
171  t->GetEntry(els.GetEntry(i));
172  switch (dtype) {case 2: var = (Float_t)bbranch[id]; break; case 1: var = (Float_t) ibranch[id]; break; default: var=fbranch[id]; }
173 
174  sig.push_back(std::make_pair(var, uid(ev,run,mode) ));
175  }
176 
177  // prepare the pairs of variable value, eventnumber for background and count background
178  for (i=0;i<elb.GetN();++i)
179  {
180  t->GetEntry(elb.GetEntry(i));
181  switch (dtype) {case 2: var = (Float_t)bbranch[id]; break; case 1: var = (Float_t) ibranch[id]; break; default: var=fbranch[id]; }
182 
183  bg.push_back(std::make_pair(var, uid(ev,run,mode) ));
184  }
185 }
186 
187 // ---------------------------------------------------------------
188 
189 double bestEffEvt(TTree *t, TString varname, TEventList &els, TEventList &elb, double &bestcut, double supr, int id)
190 {
191  CountMap bgcnt, sigcnt, sigcnt2;
192  ValueMap sigvals, bgvals;
193 
194  int Nbgval = elb.GetN();
195  int dtype = gettype(t,varname);
196 
197  makeMaps(t, varname, els, elb, sigvals, bgvals, id);
198 
199 
200  // sort signals by first element = variable value
201  sort(bgvals.begin(), bgvals.end());
202 
203  int i=0;
204  bgcnt.clear();
205  // find cut for current efficiency requirement left cut
206  while ( (bgcnt.size()/(double)Nbgev)<(1-supr) && i<Nbgval ) bgcnt[bgvals[i++].second]+=1;
207  double leftcut = bgvals[i].first;
208 
209  bgcnt.clear();
210  i=bgvals.size()-1;
211  // find cut for current efficiency requirement right cut
212  while ( (bgcnt.size()/(double)Nbgev)<(1-supr) && i>=0) bgcnt[bgvals[i--].second]+=1;
213  double rightcut = bgvals[i].first;
214 
215  sigcnt.clear();
216  sigcnt2.clear();
217 
218  for (i=0;i<(int)sigvals.size();++i)
219  {
220  if (sigvals[i].first<=leftcut) sigcnt[sigvals[i].second]+=1;
221  if (sigvals[i].first>=rightcut) sigcnt2[sigvals[i].second]+=1;
222  }
223 
224  t->SetBranchStatus("*",1);
225 
226  double lefteff = sigcnt.size()/Nsigev;
227  double righteff = sigcnt2.size()/Nsigev;
228 
229  //cout <<varname<<" "<<flush;
230 
231  TString prec="%.4f";
232 
233  bestcut = rightcut;
234  if (lefteff>righteff)
235  {
236  bestcut = leftcut;
237 
238  if (bestcut<1e-3 || fabs(1.-bestcut)<1e-3) prec="%.6f";
239  if (dtype==0) cuts[id] = TString::Format(TString("%s<="+prec).Data(),varname.Data(),leftcut);
240  else cuts[id] = TString::Format("%s<=%.1f",varname.Data(),leftcut);
241 
242  qual[id] = lefteff;
243 
244  return lefteff;
245  }
246 
247  if (bestcut<1e-3 || fabs(1.-bestcut)<1e-3) prec="%.6f";
248 
249  if (dtype==0) cuts[id] = TString::Format(TString("%s>="+prec).Data(),varname.Data(),rightcut);
250  else cuts[id] = TString::Format("%s>=%.1f",varname.Data(),rightcut);
251 
252  qual[id] = righteff;
253 
254  return righteff;
255 }
256 
257 // ---------------------------------------------------------------
258 
259 double bestSuppressionEvt(TTree *t, TString varname, TEventList &els, TEventList &elb, double &bestcut, double eff, int id)
260 {
261  CountMap bgcnt, bgcnt2, sigcnt;
262  ValueMap sigvals, bgvals;
263 
264  int Nsigval = els.GetN();
265  int dtype = gettype(t,varname);
266 
267  makeMaps(t, varname, els, elb, sigvals, bgvals, id);
268 
269  // sort signals by first element = variable value
270  sort(sigvals.begin(), sigvals.end());
271 
272  int i=0;
273  sigcnt.clear();
274  // find cut for current efficiency requirement left cut
275  while ( (sigcnt.size()/(double)Nsigev)<eff && i<Nsigval ) sigcnt[sigvals[i++].second]+=1;
276  double leftcut = sigvals[i].first;
277 
278  sigcnt.clear();
279  i=sigvals.size()-1;
280  // find cut for current efficiency requirement right cut
281  while ( (sigcnt.size()/(double)Nsigev)<eff && i>=0) sigcnt[sigvals[i--].second]+=1;
282  double rightcut = sigvals[i].first;
283 
284  bgcnt.clear();
285  bgcnt2.clear();
286 
287  for (i=0;i<(int)bgvals.size();++i)
288  {
289  if (bgvals[i].first<=leftcut) bgcnt[bgvals[i].second];
290  if (bgvals[i].first>=rightcut) bgcnt2[bgvals[i].second];
291  }
292 
293  t->SetBranchStatus("*",1);
294 
295 
296  double leftsupr = (Nbgev-bgcnt.size())/Nbgev;
297  double rightsupr = (Nbgev-bgcnt2.size())/Nbgev;
298 
299  //cout <<varname<<" "<<flush;
300 
301  if (leftcut!=leftcut || rightcut!=rightcut) return 0;
302 
303  TString prec="%.4f";
304 
305  bestcut = rightcut;
306  if (leftsupr>rightsupr)
307  {
308  bestcut = leftcut;
309 
310  if (bestcut<1e-3 || fabs(1.-bestcut)<1e-3) prec="%.6f";
311  if (dtype==0) cuts[id] = TString::Format(TString("%s<="+prec).Data(),varname.Data(),leftcut);
312  else cuts[id] = TString::Format("%s<=%.1f",varname.Data(),leftcut);
313 
314  qual[id] = leftsupr;
315 
316  return leftsupr;
317  }
318 
319  if (bestcut<1e-3 || fabs(1.-bestcut)<1e-3) prec="%.6f";
320 
321  if (dtype==0) cuts[id] = TString::Format(TString("%s>="+prec).Data(),varname.Data(),rightcut);
322  else cuts[id] = TString::Format("%s>=%.1f",varname.Data(),rightcut);
323 
324  qual[id] = rightsupr;
325 
326  return rightsupr;
327 }
328 
329 // ---------------------------------------------------------------
330 
331 int findcut(TTree *t, TEventList &els, TEventList &elb, double supr, double &bestqa)
332 {
333  int i;
334 
335  bestqa = -999.;
336 
337  TString bestcut="";
338 
339  int bestid = -1;
340 
341  //cout <<"000/000"<<flush;
342 
343  for(i=0; i<nbranch; ++i)
344  {
345  idx[i] = i;
346 
347  if (i%(nbranch/10)==0){ cout <<"#"<<flush;}
348 // printf("\b\b\b\b\b\b\b%03d/%03d",i+1,nbranch);
349 // fflush(stdout);
350 
351  double qa=0;
352 
353  if (supr<0) qa = bestEffEvt(t, vars[i], els, elb, cut[i], -supr, i);
354  else qa = bestSuppressionEvt(t, vars[i], els, elb, cut[i], supr, i);
355 
356  if (qa>bestqa && fabs(cut[i])>1e-5 && fabs(cut[i]-1.0)>1e-5)
357  {
358  bestqa = qa;
359  bestcut = cuts[i];
360  bestid = i;
361  }
362  }
363 
364  return bestid;
365 }
366 
367 // ---------------------------------------------------------------
369 {
370  int cnt = 0;
371  TString svar="";
372  TRegexp rvar("-[a-zA-Z_][a-zA-Z0-9_]+-");
373 
374  TObjArray *tok = s.Tokenize("&&");
375  int N = tok->GetEntries();
376  for (int i=0;i<N;++i)
377  {
378  if (i<100)
379  {
380  TString toks = ((TObjString*)tok->At(i))->String();
381  toks.ReplaceAll("\t","");
382  toks = toks.Strip(TString::kBoth);
383  if (toks.Index("<")>0) toks = toks(0,toks.Index("<"));
384  if (toks.Index(">")>0) toks = toks(0,toks.Index(">"));
385  svar += "-"+toks+"-";
386  }
387  }
388  while (svar(rvar)!="") {svar.ReplaceAll(svar(rvar),""); cnt++;}
389  return cnt;
390 }
391 
392 // ---------------------------------------------------------------
394 {
395  TObjArray *tok = s.Tokenize("&&");
396  return tok->GetEntries();
397 }
398 
399 // ---------------------------------------------------------------
400 
401 int autocutx(TString fname, TString precut="", double supr=0.95, double target=0.0001, double mineff = 0.1, double minreleff = 0.0, int evmult=10000, double norm=1.0, int n0s=-1)
402 {
403 // gStyle->SetTitleX(0.2);
404 // gStyle->SetTitleY(0.993);
405 // gStyle->SetTitleH(0.07);
406 // gStyle->SetPadTopMargin(0.08);
407 // gStyle->SetTitleBorderSize(0);
408  gStyle->SetOptStat(0);
409 
410  TCanvas *c1=new TCanvas("c1","c1",10,10,1800,550);
411  c1->Divide(7,2);
412 
413  TString tagcut = "tag";
414 
415  TRegexp ren("M[0-9][0-9][0-9]");
416  TRegexp regntp("n[0-9]+");
417  TRegexp regS("[0-9]+S");
418  TRegexp regB("[0-9]+B");
419 
420  TString en = fname(ren); en = en(1,5);
421  TString s = fname(regS); s = s(0,s.Length()-1);
422  TString b = fname(regB); b = b(0,b.Length()-1);
423 
424  TString ntp = fname(regntp);
425  TString smode = ntp(1,ntp.Length());
426  int dmode = smode.Atoi()/10;
427  dstarmode = (dmode==11 || dmode==13 || dmode==15);
428 
429  if (dmode>=10 && dmode<20) norm = 0.5;
430 
431  if (dmode/10 == 6) norm = 0.2;
432 
433  if (n0s<0) n0s = s.Atoi();
434  int n0b = b.Atoi();
435 
436  N0_sig = n0s*evmult;
437  N0_bg = n0b*evmult;
438 
439  cout <<"tree '"<<ntp.Data()<<"' with N_sig = "<<N0_sig<<", N_bg = "<<N0_bg<<endl;
440 
441  TFile *f=new TFile(fname,"READ");
442  TTree *t=(TTree*)f->Get(ntp);
443 
444  init(t);
445 
446  TEventList elsall("elsall"), elball("elball");
447  TEventList els("els"), elb("elb");
448 
449  if (precut=="") precut = tagcut;
450  else precut = tagcut+"&&"+precut;
451 
452  TString sigcut = "xmct";
453  TString bgcut = "!xmct";
454 
455  t->Draw(">>elsall",tagcut+"&&"+sigcut);
456  t->Draw(">>elball",tagcut+"&&"+bgcut);
457  float nsig = countEvents(t,elsall);
458  float nbg = countEvents(t,elball);
459 
460  double beff=1., seff=1., rseff=1.;
461 
462  TRegexp rnum("[\\-]*[0-9]+\\.[0-9]+$");
463  int cnt=0;
464 
465  while (cnt<150 && beff>target && seff>=mineff && rseff>=minreleff)
466  {
467  c1->cd(cnt%7+1);
468  t->SetLineColor(1); t->Draw("xm",precut);
469  t->SetLineColor(2); t->Draw("xm",precut+"&&"+sigcut,"same");
470  t->SetLineColor(4); t->Draw("xm",precut+"&&"+bgcut,"same");
471 
472  c1->Update();
473 
474  t->Draw(">>els",sigcut+"&&"+precut);
475  t->Draw(">>elb",bgcut+"&&"+precut);
476 
477  Nbgev = countEvents(t, elb);
478  Nsigev = countEvents(t, els);
479 
480  beff = Nbgev/N0_bg;
481  seff = Nsigev/N0_sig;
482  rseff = Nsigev/nsig;
483 
484  printf("S=%6d B=%6d (%.2f): ",(int)Nsigev, (int)Nbgev, supr);
485 
486  // stop if target reached or signal efficiency too small
487  if (beff<=target || seff<mineff || rseff<minreleff) continue;
488 
489  double qa=0.;
490 
491  int bestid = findcut(t, els, elb, supr, qa);
492 
493  TString bestcut = cuts[bestid];
494 
495  std::vector<int> myidx (idx, idx+nbranch);
496  std::sort(myidx.begin(), myidx.end(), mycompare);
497 
498  if (precut.Length()>3 && precut.Index(vars[bestid]+">")<0 && precut.Index(vars[bestid]+"<")<0)
499  {
500  int i = 0, ncuts = countCuts(precut);
501 
502  while (i<nbranch && precut.Index(vars[idx[i]]+">")<0 && precut.Index(vars[idx[i]]+"<")<0) ++i;
503 
504  if (qual[idx[i]]/qa>0.8 ) bestcut = cuts[idx[i]];
505  }
506 
507  TString thenum = bestcut(rnum);
508  double cutval = thenum.Atof();
509  TString thevar = bestcut(0,bestcut.Index(thenum));
510  TString thebarevar = thevar;
511  thebarevar.ReplaceAll(">","");
512  thebarevar.ReplaceAll("<","");
513  thebarevar.ReplaceAll("=","");
514 
515  TRegexp rcut(thevar+"[\\-]*[0-9]+\\.[0-9]+");
516  TString theoldcut = precut(rcut);
517 
518  c1->cd(cnt%7+8);
519 
520  t->SetLineColor(1); t->Draw(thebarevar,precut);
521  t->SetLineColor(2); t->Draw(thebarevar,precut+"&&"+sigcut,"same");
522  t->SetLineColor(4); t->Draw(thebarevar,precut+"&&"+bgcut,"same");
523  c1->Update();
524  TLine l; l.SetLineColor(6); l.SetLineWidth(2);
525  l.DrawLine(cutval,0,cutval,gPad->GetUymax()*0.9);
526 
527  c1->Update();
528 
529  if (theoldcut!="")
530  precut.ReplaceAll(theoldcut,bestcut);
531  else
532  precut += "&&"+bestcut;
533 
534  cout <<" : "<<precut<<endl;
535  cnt++;
536  }
537 
538  cout <<"\nCUT : "<<en<<smode<<" : "<<precut.Data()<<endl;
539  cout <<"SIG EVT: "<<Nsigev<<" ev BG: "<<Nbgev<<" ev"<<endl;
540 
541  printf("SIG EFF : %6.1f%% BG EFF : %7.3f%%\n",Nsigev/N0_sig*100.,Nbgev/N0_bg*100.);
542  printf("SIG REL : %6.1f%% BG REL : %7.3f%%\n\n",Nsigev/nsig*100.,Nbgev/nbg*100.);
543 
544  cout<<"Recoil : "; for (int k=0;k<10;++k) printf(" %02d ",k);cout <<endl;
545  cout<<"Eff : "; for (int k=0;k<10;++k) printf("%6.1f%%",(double) evcntrec[k].size()/evmult*norm*100.);cout <<endl<<endl;
546 
547  t->SetEventList(0);
548  return 0;
549 }
#define MAX
Definition: autocutx.C:22
printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime)
TEventList * els
Definition: findcuts.C:52
void makeMaps(TTree *t, TString varname, TEventList &els, TEventList &elb, ValueMap &sig, ValueMap &bg, int id)
Definition: autocutx.C:153
Int_t run
Definition: autocutx.C:47
Int_t i
Definition: run_full.C:25
TTree * b
int findcut(TTree *t, TEventList &els, TEventList &elb, double supr, double &bestqa)
Definition: autocutx.C:331
TLorentzVector s
Definition: Pnd2DStar.C:50
int ev
bool dstarmode
Definition: autocutx.C:42
TString cuts[MAX]
Definition: autocutx.C:35
double N0_sig
Definition: autocutx.C:40
double Nsigev
Definition: autocutx.C:41
CountMap evcntrec[10]
Definition: autocutx.C:31
__m128 v
Definition: P4_F32vec4.h:4
bool mycompare(int i, int j)
Definition: autocutx.C:64
static int init
Definition: ranlxd.cxx:374
int autocutx(TString fname, TString precut="", double supr=0.95, double target=0.0001, double mineff=0.1, double minreleff=0.0, int evmult=10000, double norm=1.0, int n0s=-1)
Definition: autocutx.C:401
double bestSuppressionEvt(TTree *t, TString varname, TEventList &els, TEventList &elb, double &bestcut, double eff, int id)
Definition: autocutx.C:259
double cut[MAX]
Definition: autocutx.C:36
Int_t mode
Definition: autocutx.C:47
int idx[MAX]
Definition: autocutx.C:38
int uid(int lev, int lrun, int lmode)
Definition: autocutx.C:122
std::vector< pair< double, int > > ValueMap
Definition: autocutx.C:28
Float_t fbranch[MAX]
Definition: autocutx.C:44
double N0_bg
Definition: autocutx.C:40
int gettype(TTree *t, TString varname)
Definition: autocutx.C:51
float_m ok
TString vars[MAX]
Definition: autocutx.C:34
TFile * f
Definition: bump_analys.C:12
Bool_t bbranch[MAX]
Definition: autocutx.C:46
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
c1
Definition: plot_dirc.C:35
std::map< TString, TString > mctvar
Definition: autocutx.C:32
Int_t nbranch
Definition: autocutx.C:47
int nsig
Definition: toy_core.C:46
std::map< int, int > CountMap
Definition: autocutx.C:29
TEventList * elb
Definition: findcuts.C:52
int countVars(TString s)
Definition: autocutx.C:368
Int_t cnt
Definition: hist-t7.C:106
int countEvents(TTree *t, TEventList &el)
Definition: autocutx.C:129
TTree * t
Definition: bump_analys.C:13
double Nbgev
Definition: autocutx.C:41
Int_t ibranch[MAX]
Definition: autocutx.C:45
double qual[MAX]
Definition: autocutx.C:37
Int_t rec
Definition: autocutx.C:47
CountMap evcnt
Definition: autocutx.C:31
double bestEffEvt(TTree *t, TString varname, TEventList &els, TEventList &elb, double &bestcut, double supr, int id)
Definition: autocutx.C:189
int countCuts(TString s)
Definition: autocutx.C:393