HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
hparticlecutrange.cc
Go to the documentation of this file.
1 #include "hparticlecutrange.h"
2 #include <iostream>
3 #include <iomanip>
4 
5 #include "TDirectory.h"
6 #include "TROOT.h"
7 
8 using namespace std;
9 
11 
12 //_HADES_CLASS_DESCRIPTION
13 ////////////////////////////////////////////////////////////////////////////////
14 //
15 //
16 // HParticleCutRange
17 //
18 // Helper class for cuts.
19 // A cut has a name (should be unique), a cut number (better unique)
20 // and a condition as argument of creation. The cut object owns counters
21 // for the number of calls and the number of failed evaluations. The
22 // The counters cand be used to monitor the efficiency of the cut
23 // If the TCutG object belonging to the cut is set evalG(var,var,version)
24 // will evaluate the graph. cut. As option TF1 objects cann be used to
25 // cut (see the exapmple macro below)
26 // The cuts can be inversed by setInverse(Bool_t). In fact
27 // cuts will than select outside the band low-up range and
28 // for the graph cut isInside(var,var)==kFALSE will be used for selection.
29 //
30 //#########################################################
31 // USAGE:
32 // // outside eventloop:
33 // HParticleCutRange cut1("BetaCut",1,0.9,1.1);
34 // // will create a cut object selecting beta range and
35 // ....
36 // // inside eventloop:
37 // if(cut1->eval(beta,0)) { // true if condition is fullfilled, stat counted for version 0
38 //
39 // }
40 // if(cut1->eval(beta,1)) { // true if condition is fullfilled, stat counted for version 1
41 //
42 // }
43 //
44 // ....
45 // // after eventloop
46 // cut1.print(); // show cut name,number,cut statistics and range
47 //
48 //void testCutRange()
49 //{
50 // // example macro for HParticleCutRange demonstrating the
51 // // different features. The cut will be applied on the
52 // // mass of an particle in this example.
53 // //
54 // // Cuts can be applied in 3 ways:
55 // //
56 // // CUTMODE:
57 // // 1. 1-dim cuts (upper+lower limit)
58 // // 2. 2-dim cut using TCutG
59 // // 3. 2-dim cut using TF1
60 // //
61 // // In TCutG or TF1 mode the example cuts in mass depends on the momentum.
62 // // The TCutG is owned by the cut and the user just has to set the
63 // // points. TF1 have to be contructed outside the clas due to the
64 // // available contructors of TF1. The user ahs to set the pointers
65 // // to the TF1. Remark: if the TF1 is contructed from a user function
66 // // the cut will not work when read back from root file.
67 // //
68 // // TF1MODE:
69 // // There are 4 options :
70 // // 1. low+up (1 seperate TF1 for lower and upper cut)
71 // // 2. low (1 TF1 for lower cut)
72 // // 3. up (1 TF1 for upper cut)
73 // // 3. mean+width (1 TF1 for mean of the cut, 1 TF1 for the width of the cut)
74 //
75 //
76 // Bool_t invert = kFALSE; // invert cut : default: kFALSE
77 // Int_t cutmode = 2; //0=range,1=cutG,2=TF1
78 // TString tf1mode = "low+up"; // TF1 mode: low+up, low,up,mean+width
79 //
80 // Double_t slope = .10;
81 //
82 // Double_t mass_pion = HPhysicsConstants::mass(8);
83 // Double_t mass_proton = HPhysicsConstants::mass(14);
84 //
85 //
86 // HParticleCutRange cut1("massCut",1,mass_proton-50,mass_proton+50);
87 // cut1.setInverse(invert);
88 //
89 //
90 // //--------------------------------------------------
91 // // TF1 mode
92 // // Cuts in mass depend on mommentum
93 // // low+up , low , up mode
94 // TF1* flow = new TF1("flow","pol1",0,1000);
95 // flow->SetParameter(0,mass_pion);
96 // flow->SetParameter(1,-slope);
97 //
98 // TF1* fup = new TF1("fup","pol1" ,0,1000);
99 // fup->SetParameter(0,mass_pion);
100 // fup->SetParameter(1,slope);
101 // fup->SetLineColor(4);
102 //
103 // // mean+width mode
104 // TF1* fmean = new TF1("fmean","pol1",0,1000);
105 // fmean->SetParameter(0,mass_pion);
106 // fmean->SetParameter(1,0);
107 //
108 // TF1* fwidth = new TF1("fwidth","pol1",0,1000);
109 // fwidth->SetParameter(0,0);
110 // fwidth->SetParameter(1,slope);
111 // fwidth->SetLineColor(4);
112 //
113 // if(tf1mode=="low+up") cut1.setTF1(flow,fup,tf1mode);
114 // if(tf1mode=="low") cut1.setTF1(flow, 0,tf1mode);
115 // if(tf1mode=="up") cut1.setTF1( 0,fup,tf1mode);
116 // if(tf1mode=="mean+width")cut1.setTF1(flow,fup,tf1mode);
117 // //--------------------------------------------------
118 //
119 //
120 // //--------------------------------------------------
121 // // TCutG mode
122 // cut1.getTCutG()->SetPoint(0, 0,mass_proton);
123 // cut1.getTCutG()->SetPoint(1,1000,mass_proton - slope*1000);
124 // cut1.getTCutG()->SetPoint(2,1000,mass_proton + slope*1000);
125 // cut1.getTCutG()->SetPoint(3, 0,mass_proton);
126 // //--------------------------------------------------
127 //
128 //
129 //
130 // TH2F* hmomvsmass = new TH2F("hmassvsmom","mom vs mass",200,0,2000,200,0,1200);
131 // hmomvsmass->SetXTitle("mom [MeV/c]");
132 // hmomvsmass->SetYTitle("mass [MeV/c^{2}]");
133 //
134 // //--------------------------------------------------
135 // // create some dummy spectrum
136 // Double_t masses [] = {mass_pion,mass_proton};
137 //
138 // for(Int_t i = 0 ; i <10000; i ++){
139 // Double_t mom = gRandom->Rndm()*2000;
140 // Double_t massres = mom*0.1;
141 // Int_t index = (Int_t) (gRandom->Rndm()*2);
142 // Double_t mass = gRandom->Gaus(masses[index],massres);
143 //
144 // if(cutmode == 0 && cut1.eval(mass)) {
145 // hmomvsmass->Fill(mom,mass);
146 // }
147 //
148 // if(cutmode == 1 && cut1.evalG(mom,mass)) {
149 // hmomvsmass->Fill(mom,mass);
150 // }
151 //
152 // if(cutmode == 2 && cut1.evalF(mass,mom)) {
153 // hmomvsmass->Fill(mom,mass);
154 // }
155 // }
156 // //--------------------------------------------------
157 //
158 //
159 // cut1.print();
160 //
161 // TCanvas* result = new TCanvas("result","result",1000,800);
162 //
163 // hmomvsmass->Draw("colz");
164 //
165 //
166 // if(cutmode == 1){
167 // cut1.getTCutG()->Draw("same");
168 // }
169 //
170 // if(cutmode == 2){
171 // if(cut1.getTF1Low())cut1.getTF1Low()->DrawCopy("same");
172 // if(cut1.getTF1Up() )cut1.getTF1Up() ->DrawCopy("same");
173 // }
174 //
175 // TFile* cutsfile = new TFile("myCuts.root","RECREATE");
176 // cut1.Write();
177 // cutsfile->Save();
178 // cutsfile->Close();
179 //
180 //
181 //}
182 ////////////////////////////////////////////////////////////////////////////////
183 
185  Int_t num,Double_t l,Double_t u)
186 {
187  SetName(name);
188  TDirectory* saveDir = gDirectory;
189  gROOT->cd();
190  fCut = new TCutG();
191  fCut->SetName(name);
192  fLowF1 = NULL;
193  fUpF1 = NULL;
194  fF1Mode = -1;
195  flow = l;
196  fup = u;
197  fCutNumber = num;
198  fmaxVersion = 0;
199  fbInverseCut= kFALSE;
200  setMaxCut(4);
201  saveDir->cd();
202 }
203 
205 {
206  ;
207 }
208 
209 
210 void HParticleCutRange::setTF1(TF1* flowF, TF1* fupF,TString mode)
211 {
212  // Set the TF1 objects for low and up cut. The TF1
213  // will be used by evalF(var,var2) for cutting where
214  // the cuts in var will be a function of var2.
215  // There are the following modes implemented:
216  //
217  // mode = "low+up" : lower and upper cur are defined
218  // by independent TF1 (band pass)
219  // = "low" : low TF1 is used to defined a cut
220  // for var < lowcut(var2) ( high pass)
221  // = "up" : up TF1 is used to defined a cut
222  // for var > upcut(var2) ( low pass)
223  // = "mean+width" : is used to define a cut
224  // by mean(var2)(low TF1) + width(var2)(up TF1)
225  // for var > mean + width && var < mean - width ( band pass)
226  // the cuts can be inverted as the other cuts
227 
228 
229  fF1Mode= -1;
230  fLowF1 = NULL;
231  fUpF1 = NULL;
232 
233  if(mode.CompareTo("low+up") == 0){
234  if(flowF == 0 || fupF == 0){
235  Error("setTF1()","Both TF1 needs to be !=0 in mode \"low+up\"");
236  return;
237  } else {
238  fF1Mode = 0;
239  fLowF1 = flowF;
240  fUpF1 = fupF;
241  }
242  } else if(mode.CompareTo("low") == 0){
243  if(flowF == 0 || fupF != 0){
244  Error("setTF1()","Lower TF1 needs to be set and upper TF1 == 0 in mode \"low\"");
245  return;
246 
247  } else {
248  fF1Mode=1;
249  fLowF1 = flowF;
250  }
251  } else if(mode.CompareTo("up") == 0){
252  if(flowF != 0 || fupF == 0){
253  Error("setTF1()","Upper TF1 needs to be set and lower TF1 == 0 in mode \"up\"");
254  return;
255 
256  } else {
257  fF1Mode=2;
258  fUpF1 = fupF;
259  }
260  } else if(mode.CompareTo("mean+width") == 0){
261  if(flowF == 0 || fupF == 0){
262  Error("setTF1()","Both TF1 needs to be !=0 in mode \"mean+width\"");
263  return;
264  } else {
265  fF1Mode=3;
266  fLowF1 = flowF;
267  fUpF1 = fupF;
268  }
269  } else {
270  Error("setTF1()","Unknown mode =%s",mode.Data());
271  }
272 }
273 
275 {
276  // set the max number of versions of stst counters
277  fmaxCut = max;
278  if(fmaxCut == 0) fmaxCut = 1;
279  resetCounter();
280 }
281 
282 Bool_t HParticleCutRange::eval(Double_t var,UInt_t version){
283 
284  // returns kTRUE if the object fullfills the condition.
285  // counters for calls and failed conditions are filled.
286  // version is used to fill the stat for a given version
287  // (0 up to 9 incl )
288  if(version<fmaxCut){
289  fctCall[version]++;
290  if(version>fmaxVersion) fmaxVersion = version;
291  }
292  if( (!fbInverseCut && (var > fup || var < flow)) ||
293  ( fbInverseCut && !(var > fup || var < flow))
294  )
295  {
296  if(version<fmaxCut)fctFail[version]++;
297  return kFALSE;
298  } else return kTRUE;
299 }
300 
301 Bool_t HParticleCutRange::evalG(Double_t var,Double_t var2,UInt_t version){
302 
303  // returns kTRUE if the object fullfills the condition.
304  // counters for calls and failed conditions are filled.
305  // version is used to fill the stat for a given version
306 
307  if(fCut->GetN() == 0) {
308  Warning("evalG(var,var)","Cut %s has no set TCutG !",GetName());
309  return kFALSE;
310  }
311  if(version<fmaxCut){
312  fctCall[version]++;
313  if(version>fmaxVersion) fmaxVersion = version;
314  }
315  if( (!fbInverseCut && !fCut->IsInside(var,var2)) ||
316  ( fbInverseCut && fCut->IsInside(var,var2))
317  )
318  {
319  if(version<fmaxCut)fctFail[version]++;
320  return kFALSE;
321  } else return kTRUE;
322 }
323 
324 Bool_t HParticleCutRange::evalF(Double_t var,Double_t var2,UInt_t version){
325 
326  // returns kTRUE if the object fullfills the condition.
327  // counters for calls and failed conditions are filled.
328  // version is used to fill the stat for a given version
329 
330  if(fF1Mode == -1) {
331  Warning("evalF(var,var)","TF1 Cut %s has no set !",GetName());
332  return kFALSE;
333  }
334 
335  if(version<fmaxCut){
336  fctCall[version]++;
337  if(version>fmaxVersion) fmaxVersion = version;
338  }
339 
340  Double_t lowCut = -1e30;
341  Double_t upCut = 1e30;
342 
343  if(fF1Mode == 0) { // low+up
344  lowCut = fLowF1->Eval(var2);
345  upCut = fUpF1 ->Eval(var2);
346  } else if (fF1Mode == 1 ) { // low
347  lowCut = fLowF1->Eval(var2);
348  } else if (fF1Mode == 2) { // up
349  upCut = fUpF1->Eval(var2);
350  } else { // mean+width
351  Double_t width = fUpF1->Eval(var2);
352  Double_t mean = fLowF1->Eval(var2);
353  lowCut = mean - width;
354  upCut = mean + width;
355  }
356 
357 
358  if( (!fbInverseCut && !( var<upCut && var>lowCut) ) ||
359  ( fbInverseCut && ( var<upCut && var>lowCut))
360  )
361  {
362  if(version<fmaxCut)fctFail[version]++;
363  return kFALSE;
364  } else return kTRUE;
365 }
366 
368 {
369  Int_t p = cout.precision();
370  std::ios_base::fmtflags fl =cout.flags();
371  cout<<"CutNumber : "<<setw(3)<<fCutNumber
372  <<" name : "<<setw(20)<<GetName()
373  <<", lowCut : "<<setw(10)<<flow
374  <<", UpCut : "<<setw(10)<<fup<<", cut [%] : "<<flush;
375  for(UInt_t i = 0; i < fmaxCut ; i++){ cout<<setw(5)<<fixed<<right<<setprecision(1)<<getCutRate(i)<<" "<<flush;}
376  cout<<setprecision(p)<<endl;
377  cout.flags(fl);
378 }
379 
381 {
382  fctFail.clear();
383  fctCall.clear();
384  fctFail.assign(fmaxCut,0);
385  fctCall.assign(fmaxCut,0);
386 }
387 
388 Float_t HParticleCutRange::getCutRate(UInt_t version)
389 {
390  return (version <fmaxCut && fctCall[version] > 0) ? (fctFail[version]/(Float_t)fctCall[version])*100.:0;
391 }
392 
393 UInt_t HParticleCutRange::getNCall(UInt_t version)
394 {
395  return (version <fmaxCut ) ? fctCall[version]:0;
396 }
397 
398 UInt_t HParticleCutRange::getNFail(UInt_t version)
399 {
400  return (version <fmaxCut ) ? fctFail[version]:0;
401 }
402 
void setMaxCut(UInt_t max=4)
UInt_t getNFail(UInt_t version=0)
ClassImp(HParticleCutRange) HParticleCutRange
Bool_t evalG(Double_t var, Double_t var2, UInt_t version=0)
Float_t getCutRate(UInt_t version=0)
Bool_t evalF(Double_t var, Double_t var2, UInt_t version=0)
void setTF1(TF1 *flow, TF1 *fup=0, TString mode="low+up")
UInt_t getNCall(UInt_t version=0)
Bool_t eval(Double_t var, UInt_t version=0)
Int_t mode