CbmRoot
Loading...
Searching...
No Matches
PairAnalysisObjectCuts.cxx
Go to the documentation of this file.
1/* Copyright (C) 2015-2020 Justus-Liebig-Universitaet Giessen, Giessen
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Julian Book [committer] */
4
5/*
6
7 Advanced cut class.
8
9 Add cuts that depend on some variable or formula of them. The minimum and
10 maximum cut value can be expressed by a TForumla, TGraph or a THnBase.
11
12
13*/
14// //
16
17
19
20#include <TAxis.h>
21#include <TFormula.h>
22#include <TGraph.h>
23#include <THnBase.h>
24#include <TSpline.h>
25
26#include "PairAnalysisHelper.h"
27
29
30
32 : PairAnalysisObjectCuts("objcuts", "objcuts")
33{
34 //
35 // Default costructor
36 //
37}
38
39//________________________________________________________________________
40PairAnalysisObjectCuts::PairAnalysisObjectCuts(const char* name, const char* title)
41 : AnalysisCuts(name, title)
42 , fUsedVars(new TBits(PairAnalysisVarManager::kNMaxValuesMC))
43{
44 //
45 // Named contructor
46 //
47 for (Int_t i = 0; i < fMaxCuts; ++i) {
48 fActiveCuts[i] = 0;
49 fCutExclude[i] = kFALSE;
50 fCutMin[i] = 0x0;
51 fCutMax[i] = 0x0;
52 fVarFormula[i] = 0x0;
53 }
55}
56
57//________________________________________________________________________
59{
60 //
61 // Destructor
62 //
63 if (fUsedVars) delete fUsedVars;
64 for (Int_t i = 0; i < fMaxCuts; ++i) {
65 fActiveCuts[i] = 0;
66 if (fCutMin[i]) delete fCutMin[i];
67 if (fCutMax[i]) delete fCutMax[i];
68 if (fVarFormula[i]) delete fVarFormula[i];
69 }
70}
71
72//________________________________________________________________________
73Bool_t PairAnalysisObjectCuts::IsSelected(Double_t* const values)
74{
75 //
76 // Make cut decision
77 //
78
79 //reset
81 SetSelected(kFALSE);
82
83 for (Int_t iCut = 0; iCut < fNActiveCuts; ++iCut) {
84 Int_t cut = fActiveCuts[iCut];
86
87 // variable you want to cut on
88 Double_t compValue = 0.;
89 if (fVarFormula[iCut]) compValue = PairAnalysisHelper::EvalFormula(fVarFormula[iCut], values);
90 else
91 compValue = values[cut];
92
93 // cut limits
94 Double_t cutMin = -9.e30;
95 Double_t cutMax = +9.e30;
96
97
99 if ((fCutMin[iCut] && fCutMin[iCut]->IsA() == THnBase::Class())
100 || (fCutMax[iCut] && fCutMax[iCut]->IsA() == THnBase::Class())) {
101
102 THnBase* hn = static_cast<THnBase*>(fCutMin[iCut]);
103 if (fCutMin[iCut]) {
104 Double_t* vals = new Double_t[hn->GetNdimensions()]; //={-1};
105 // get array of values for the corresponding dimensions using axis names
106 for (Int_t idim = 0; idim < hn->GetNdimensions(); idim++) {
107 vals[idim] = values[PairAnalysisVarManager::GetValueType(
108 hn->GetAxis(idim)->GetName())];
109 }
110 // find bin for values (w/o creating it in case it is not filled)
111 Long_t bin = hn->GetBin(vals, kFALSE);
112 if (bin > 0) cutMin = hn->GetBinContent(bin);
113 delete[] vals;
114 }
115
116 THnBase* hx = static_cast<THnBase*>(fCutMax[iCut]);
117 if (fCutMax[iCut]) {
118 Double_t* vals = new Double_t[hx->GetNdimensions()]; //={-1};
119 // get array of values for the corresponding dimensions using axis names
120 for (Int_t idim = 0; idim < hx->GetNdimensions(); idim++) {
121 vals[idim] = values[PairAnalysisVarManager::GetValueType(
122 hx->GetAxis(idim)->GetName())];
123 }
124 // find bin for values (w/o creating it in case it is not filled)
125 Long_t bin = hx->GetBin(vals, kFALSE);
126 if (bin > 0) cutMax = hx->GetBinContent(bin);
127 delete[] vals;
128 }
129 }
130 else if ((fCutMin[iCut] && fCutMin[iCut]->IsA() == TFormula::Class())
131 || (fCutMax[iCut] && fCutMax[iCut]->IsA() == TFormula::Class())) {
133 TFormula* formN = static_cast<TFormula*>(fCutMin[iCut]);
134 if (formN) cutMin = PairAnalysisHelper::EvalFormula(formN, values);
135
136 TFormula* formM = static_cast<TFormula*>(fCutMax[iCut]);
137 if (formM) cutMax = PairAnalysisHelper::EvalFormula(formM, values);
138 }
139 else if ((fCutMin[iCut] && fCutMin[iCut]->IsA() == TGraph::Class())
140 || (fCutMax[iCut] && fCutMax[iCut]->IsA() == TGraph::Class())) {
144 TGraph* graphN = static_cast<TGraph*>(fCutMin[iCut]);
145 TGraph* graphM = static_cast<TGraph*>(fCutMax[iCut]);
146
147 // get x-value from formula
148 TFormula* formX = 0;
149 Double_t xval = 0.;
150 if (graphN) {
151 formX = static_cast<TFormula*>(graphN->GetListOfFunctions()->At(0));
152 if (formX) xval = PairAnalysisHelper::EvalFormula(formX, values);
153 }
154 if (!formX && graphM) {
155 formX = static_cast<TFormula*>(graphM->GetListOfFunctions()->At(0));
156 if (formX) xval = PairAnalysisHelper::EvalFormula(formX, values);
157 }
158
160 // if(graphN) cutMin = graphN->Eval(xval);
161 // if(graphM) cutMax = graphM->Eval(xval);
162
164 Int_t idx = TMath::BinarySearch(graphN->GetN(), graphN->GetX(), xval);
165 cutMin = graphN->GetY()[idx];
166 idx = TMath::BinarySearch(graphM->GetN(), graphM->GetX(), xval);
167 cutMax = graphM->GetY()[idx];
168 }
169 else if ((fCutMin[iCut] && fCutMin[iCut]->IsA() == TSpline3::Class())
170 || (fCutMax[iCut] && fCutMax[iCut]->IsA() == TSpline3::Class())) {
173 // TSpline3 *splineN = static_cast<TSpline3*>(fCutMin[iCut]);
174 // if(splineN) cutMin = splineN->Eval(xval);
175 // TSpline3 *splineM = static_cast<TSpline3*>(fCutMax[iCut]);
176 // if(splineM) cutMax = splineM->Eval(xval);
177 }
178 else {
179 Error("IsSelected:", "Cut object not supported (this message should never appear)");
180 return kTRUE;
181 }
182
183 // protection against NaN (e.g. outside formula ranges, exclude them)
184 if (TMath::IsNaN(cutMin)) cutMin = compValue + 1.;
185 if (TMath::IsNaN(cutMax)) cutMax = compValue - 1.;
186
187 // apply cut
188 if (((compValue < cutMin) || (compValue > cutMax)) ^ fCutExclude[iCut]) CLRBIT(fSelectedCutsMask, iCut);
189
190 // cut type and decision
192 return kFALSE; // option to (minor) speed improvement
193 }
194
195 Bool_t isSelected = (fSelectedCutsMask == fActiveCutsMask);
196 if (fCutType == ECutType::kAny) isSelected = (fSelectedCutsMask > 0);
197 SetSelected(isSelected);
198 return isSelected;
199}
200
201//________________________________________________________________________
203{
204 //
205 // Make cut decision
206 //
207
208 //reset
210 SetSelected(kFALSE);
211 if (!track) return kFALSE;
212
213 //Fill values
214 Double_t* values = PairAnalysisVarManager::GetData();
216 PairAnalysisVarManager::Fill(track, values);
217
218 return (IsSelected(values));
219}
220
221//________________________________________________________________________
223 const char* formulaMax, Bool_t excludeRange)
224{
225 //
226 // Set cut range and activate it
227 //
228 fCutMin[fNActiveCuts] = PairAnalysisHelper::GetFormula(formulaMin, formulaMin);
229 fCutMax[fNActiveCuts] = PairAnalysisHelper::GetFormula(formulaMax, formulaMax);
230 fCutExclude[fNActiveCuts] = excludeRange;
232 fActiveCuts[fNActiveCuts] = (UShort_t) type;
233 fUsedVars->SetBitNumber(type, kTRUE);
234 ++fNActiveCuts;
235}
236
237//________________________________________________________________________
238void PairAnalysisObjectCuts::AddCut(const char* formula, const char* formulaMin, const char* formulaMax,
239 Bool_t excludeRange)
240{
241 //
242 // Set cut range and activate it
243 //
244 fCutMin[fNActiveCuts] = PairAnalysisHelper::GetFormula(formulaMin, formulaMin);
245 fCutMax[fNActiveCuts] = PairAnalysisHelper::GetFormula(formulaMax, formulaMax);
246 fCutExclude[fNActiveCuts] = excludeRange;
250 ++fNActiveCuts;
251}
252
253//________________________________________________________________________
255 TGraph* const graphMax, Bool_t excludeRange)
256{
257 //
258 // Set cut range and activate it
259 //
260 // if(graphMin) {
261 // TSpline3 *splineMin = new TSpline3("splineMin",graphMin); //spline w/o begin and end point conditions
262 // fCutMin[fNActiveCuts]=splineMin;
263 // }
264 // if(graphMax) {
265 // TSpline3 *splineMax = new TSpline3("splineMax",graphMax); //spline w/o begin and end point conditions
266 // fCutMax[fNActiveCuts]=splineMax;
267 // }
268 fCutMin[fNActiveCuts] = graphMin;
269 fCutMax[fNActiveCuts] = graphMax;
270 fCutExclude[fNActiveCuts] = excludeRange;
272 fActiveCuts[fNActiveCuts] = (UShort_t) type;
273 fUsedVars->SetBitNumber(type, kTRUE);
274 ++fNActiveCuts;
275}
276
277//________________________________________________________________________
278void PairAnalysisObjectCuts::AddCut(const char* formula, TGraph* const graphMin, TGraph* const graphMax,
279 Bool_t excludeRange)
280{
281 //
282 // Set cut range and activate it
283 //
284 // if(graphMin) {
285 // TSpline3 *splineMin = new TSpline3("splineMin",graphMin); //spline w/o begin and end point conditions
286 // fCutMin[fNActiveCuts]=splineMin;
287 // }
288 // if(graphMax) {
289 // TSpline3 *splineMax = new TSpline3("splineMax",graphMax); //spline w/o begin and end point conditions
290 // fCutMax[fNActiveCuts]=splineMax;
291 // }
292 fCutMin[fNActiveCuts] = graphMin;
293 fCutMax[fNActiveCuts] = graphMax;
294 fCutExclude[fNActiveCuts] = excludeRange;
298 ++fNActiveCuts;
299}
300
301//________________________________________________________________________
303 THnBase* const histMax, Bool_t excludeRange)
304{
305 //
306 // Set cut range and activate it
307 //
308 fCutMin[fNActiveCuts] = histMin;
309 fCutMax[fNActiveCuts] = histMax;
310 fCutExclude[fNActiveCuts] = excludeRange;
312 fActiveCuts[fNActiveCuts] = (UShort_t) type;
313 fUsedVars->SetBitNumber(type, kTRUE);
314 ++fNActiveCuts;
315}
316
317//________________________________________________________________________
318void PairAnalysisObjectCuts::AddCut(const char* formula, THnBase* const histMin, THnBase* const histMax,
319 Bool_t excludeRange)
320{
321 //
322 // Set cut range and activate it
323 //
324 fCutMin[fNActiveCuts] = histMin;
325 fCutMax[fNActiveCuts] = histMax;
326 fCutExclude[fNActiveCuts] = excludeRange;
330 ++fNActiveCuts;
331}
332
333//________________________________________________________________________
334void PairAnalysisObjectCuts::Print(const Option_t* /*option*/) const
335{
336 //
337 // Print cuts and the range
338 //
339 printf("cut ranges for '%s'\n", GetTitle());
340 if (fCutType == ECutType::kAll) { printf("All Cuts have to be fulfilled\n"); }
341 else {
342 printf("Any Cut has to be fulfilled\n");
343 }
344
346 for (Int_t iCut = 0; iCut < fNActiveCuts; ++iCut) {
347
348 // variable
349 Int_t cut = (Int_t) fActiveCuts[iCut];
350 TString tit = PairAnalysisVarManager::GetValueName((Int_t) cut);
351
352 Bool_t fvar = fVarFormula[iCut];
353 if (fvar) {
354 TFormula* form = static_cast<TFormula*>(fVarFormula[iCut]);
355 tit = form->GetExpFormula();
356 // replace parameter variables with names labels
357 for (Int_t j = 0; j < form->GetNpar(); j++)
358 tit.ReplaceAll(Form("[%d]", j), form->GetParName(j));
359 }
360
361 // cut logic
362 Bool_t inverse = fCutExclude[iCut];
363
364 // cut limits
365 Bool_t bCutGraph = (fCutMin[iCut] && fCutMin[iCut]->IsA() == TGraph::Class());
366 Bool_t bCutForm = (fCutMin[iCut] && fCutMin[iCut]->IsA() == TFormula::Class());
367 Bool_t bCutHn = (fCutMin[iCut] && fCutMin[iCut]->IsA() == THnBase::Class());
368 // Bool_t bCutSpline = (fCutMin[iCut] && fCutMin[iCut]->IsA() == TSpline::Class());
369
370 TString dep = "";
371 // HnBase
372 if (bCutHn) {
373 THnBase* obj = static_cast<THnBase*>(fCutMin[iCut]);
374 for (Int_t idim = 0; idim < obj->GetNdimensions(); idim++)
375 dep += Form("%s%s", (idim ? "," : ""), obj->GetAxis(idim)->GetName());
376 dep.Prepend("histogram(");
377 dep.Append(")");
378 }
379 // Graph
380 if (bCutGraph) {
381 TGraph* obj = static_cast<TGraph*>(fCutMin[iCut]);
382 TFormula* form = static_cast<TFormula*>(obj->GetListOfFunctions()->At(0));
383 dep = form->GetExpFormula();
384 // replace parameter variables with names labels
385 for (Int_t j = 0; j < form->GetNpar(); j++)
386 dep.ReplaceAll(Form("[%d]", j), form->GetParName(j));
387 dep.Prepend("graph(");
388 dep.Append(")");
389 }
390 // formula
391 if (bCutForm) {
392 TFormula* obj = static_cast<TFormula*>(fCutMin[iCut]);
393 dep = obj->GetExpFormula();
394 // replace parameter variables with names labels
395 for (Int_t j = 0; j < obj->GetNpar(); j++)
396 dep.ReplaceAll(Form("[%d]", j), obj->GetParName(j));
397 dep.Prepend("formula(");
398 dep.Append(")");
399 }
400
401 // stdout
402 if (!inverse) printf("Cut %02d: %s < %s < %s\n", iCut, dep.Data(), tit.Data(), dep.Data());
403 else
404 printf("Cut %02d: !(%s < %s < %s)\n", iCut, dep.Data(), tit.Data(), dep.Data());
405
406 } //loop over cuts
407}
ClassImp(PairAnalysisObjectCuts) PairAnalysisObjectCuts
#define SETBIT(n, i)
Definition RTypes.h:15
#define TESTBIT(n, i)
Definition RTypes.h:17
#define CLRBIT(n, i)
Definition RTypes.h:16
virtual void SetSelected(Bool_t dec)
virtual Bool_t IsSelected(Double_t *const values)
virtual void Print(const Option_t *option="") const
TFormula * fVarFormula[fMaxCuts]
void AddCut(PairAnalysisVarManager::ValueTypes type, const char *formulaMin, const char *formulaMax, Bool_t excludeRange=kFALSE)
static void SetFillMap(TBits *map)
static const char * GetValueName(Int_t i)
static UInt_t GetValueType(const char *valname)
static void Fill(const TObject *particle, Double_t *const values)
TFormula * GetFormula(const char *name, const char *formula)
Double_t EvalFormula(TFormula *form, const Double_t *values)