Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaCut.cxx
Go to the documentation of this file.
1//*-- Author : Ole Hansen 03-May-2000
2
4//
5// THaCut -- Class for a cut (a.k.a. test)
6//
7// This is a slightly expanded version of a THaFormula that supports
8// statistics counters and caches the result of the last evaluation.
9//
11
12#include "THaCut.h"
13#include "THaPrintOption.h"
14#include "TMath.h"
15
16#include <iostream>
17#include <iomanip>
18#include <algorithm>
19#include <cstring>
20#include <vector>
21
22using namespace std;
23
24//_____________________________________________________________________________
26 : THaFormula(), fLastResult(false), fNCalled(0), fNPassed(0), fMode(kAND)
27{
28 // Default constructor
29}
30
31//_____________________________________________________________________________
32THaCut::THaCut( const char* name, const char* expression, const char* block,
33 const THaVarList* vlst, const THaCutList* clst )
34 : THaFormula(), fLastResult(false), fBlockname(block), fNCalled(0),
35 fNPassed(0), fMode(kAND)
36{
37 // Create a cut 'name' according to 'expression'.
38 // The cut may use global variables from the list 'vlst' and other,
39 // previously defined cuts from 'clst'.
40 //
41 // Unlike the behavior of THaFormula, THaCuts do NOT store themselves in
42 // ROOT's list of functions. Otherwise existing cuts used in new cut
43 // expressions would get reparsed instead of queried. This wouldn't
44 // work properly with a non-default array evaluation mode (OR/XOR).
45
46 SetList(vlst);
47 SetCutList(clst);
48
49 // Call common THaFormula::Init
50 if( Init(name, expression) != 0 ||
52 return;
53 }
54
55 // Do not register cuts in ROOT's list of functions
57
58 // This calls THaFormula::Compile(), which calls TFormula::Analyze(),
59 // which then calls our own DefinedVariable()
60 Compile();
61}
62
63//_____________________________________________________________________________
65{
66 // Check if 'name' is in the list of existing cuts.
67 // If so, store pointer to the cut for use by DefinedValue().
68 // Otherwise, assume 'name' is a global variable and pass it on
69 // to THaFormula::DefinedVariable().
70
71 // Return codes:
72 // >=0 serial number of variable or cut found
73 // -1 variable not found
74 // -2 error parsing variable name
75 // -3 error parsing variable name, error already printed
76
77 action = kDefinedVariable;
78 Int_t k = DefinedCut( name );
79 if( k>=0 ) return k;
80 return THaFormula::DefinedVariable( name, action );
81}
82
83//_____________________________________________________________________________
85{
86 return (TMath::Nint( THaFormula::EvalInstanceUnchecked(instance) ) != 0);
87}
88
89//_____________________________________________________________________________
91{
92 // Evaluate the cut and increment counters. The Double_t return value
93 // is awkward, but results are usually retrieved via GetResult anyway.
94 // Problems like this will go away if Eval() is templatized.
95
97 fNCalled++;
98 if( IsError() ) {
99 fLastResult = false;
100 }
101 else {
102 Int_t ndata = 1;
104 ndata = GetNdataUnchecked();
105 if( ndata == 0 )
107 else {
109 if( TestBit(kArrayFormula) && !IsInvalid() && ndata > 1 ) {
110 switch( fMode ) {
111 case kAND:
112 // All elements satisfy the test (==N)
113 for( Int_t i=1; fLastResult && i<ndata; ++i )
115 break;
116 case kOR:
117 // At least one element satisfies the test (>=1)
118 for( Int_t i=1; !fLastResult && i<ndata; ++i )
120 break;
121 case kXOR:
122 {
123 // Exactly one element satisfies the test (==1)
124 Int_t ntrue = fLastResult ? 1 : 0;
125 for( Int_t i=1; ntrue != 2 && i<ndata; ++i ) {
126 if( EvalElement(i) )
127 ++ntrue;
128 }
129 fLastResult = (ntrue == 1);
130 }
131 break;
132 default:
133 fLastResult = false;
134 break;
135 }
136 }
137 }
138 if( IsInvalid() ) {
139 fLastResult = false;
140 }
141 else if( fLastResult ) {
142 fNPassed++;
143 }
144 }
145 return fLastResult;
146}
147
148//_____________________________________________________________________________
150{
151 // Parse the given expression for a mode prefix (e.g. "OR:")
152 // and return its value. If the expression does not have a mode prefix,
153 // return the default kAND (=0).
154 // The expression is expected to have all whitespace removed.
155 // If the prefix was found, it is stripped from the expression.
156 // If a mode prefix seems to be present, but is not found in
157 // the defined modes, return kModeErr.
158
159 const EvalMode kDefaultMode = kOR;
160 const char* const here = "THaCut";
161
162 class ModeDef_t {
163 public:
164 const char* prefix;
166 };
167 const vector<ModeDef_t> mode_defs = {
168 { "OR", kOR }, { "ANY", kOR }, { "AND", kAND },
169 { "ALL", kAND }, { "XOR", kXOR }, { "ONE", kXOR },
170 { "ONEOF", kXOR },
171 };
172
173 Ssiz_t colon = expr.Index(":");
174 if( colon == kNPOS )
175 return kDefaultMode;
176
178 for( const auto& def : mode_defs ) {
179 if( expr.BeginsWith(def.prefix) &&
180 static_cast<Ssiz_t>(strlen(def.prefix)) == colon ) {
181 expr.Remove(0, colon + 1);
182 mode = def.mode;
183 break;
184 }
185 }
186
187 if( mode == kModeErr ) {
188 TString prefix = expr(0, colon);
189 Error(here, "Unknown prefix %s", prefix.Data() );
190 } else if( expr.Length() == 0 ) {
191 Error(here, "expression may not be empty");
192 mode = kModeErr;
193 }
194 if( mode == kModeErr )
195 SetBit(kError);
196 return mode;
197}
198
199//_____________________________________________________________________________
200void THaCut::Print( Option_t* option ) const
201{
202 // Print this cut.
203 // Options:
204 // "BRIEF" -- short (default)
205 // "FULL" -- extended
206 // "LINE" -- one-line (for listings)
207 // "STATS" -- one-line (listing of statistics only)
208
210 Int_t nn = max( s.GetValue(1), (Int_t)strlen(GetName()) );
211 Int_t nt = max( s.GetValue(2), (Int_t)strlen(GetTitle()) );
212 Int_t nb = max( s.GetValue(3), fBlockname.Length() );
213 Int_t np = max( s.GetValue(4), (Int_t)strlen(s.GetOption(4)) );
214
215 // Print data according to the requested format
216
217 ios_base::fmtflags fmt = cout.flags();
218 streamsize prec = cout.precision();
219 if ( s.IsLine() ) {
220
221 cout.flags( ios::left );
222 cout << setw(nn) << GetName() << " "
223 << setw(nt) << GetTitle() << " ";
224 if( !strcmp( s.GetOption(), kPRINTLINE )) {
225 cout << setw(1) << (bool)fLastResult << " "
226 << setw(nb) << fBlockname << " ";
227 }
228 cout << setw(9) << fNCalled << " "
229 << setw(np) << fNPassed << " ";
230 cout << setprecision(3);
231 if( fNCalled > 0 )
232 cout << "(" << 100.0*((float)fNPassed)/((float)fNCalled) << "%)";
233 else
234 cout << "(0.0%)";
235
236 cout << endl;
237
238 } else {
239
240 cout.flags( ios::right );
242 cout << "Curval: " << setw(9) << (bool)fLastResult << " "
243 << "Block: " << fBlockname << endl;
244 cout << "Called: " << setw(9) << fNCalled << " "
245 << "Passed: " << setw(9) << fNPassed;
246 if( fNCalled > 0 ) {
247 cout << setprecision(3)
248 <<" (" << 100.0*((float)fNPassed)/((float)fNCalled) << "%)";
249 } else
250 cout << " (0.00%)";
251 cout << endl;
252 }
253 cout.flags(fmt);
254 cout.precision(prec);
255}
256
257//_____________________________________________________________________________
258void THaCut::SetBlockname( const Text_t* name )
259{
260 // Set name of block (=group of cuts) for this cut.
261 // The block name is used only for informational purposes within the
262 // THaCut class.
263
265}
266
267//_____________________________________________________________________________
268void THaCut::SetName( const Text_t* name )
269{
270 // Set name of the cut
271 // This method overrides the one provided by TNamed
272 // so that the name can only be set if it is empty.
273 // This avoids problems with hash values since THaCuts are
274 // elements of a THashList.
275 // Alternatively, we could rehash the associated table(s), but that
276 // would be much more involved.
277
278 if( fName.Length() == 0 )
280}
281
282//_____________________________________________________________________________
283void THaCut::SetNameTitle( const Text_t* name, const Text_t* formula )
284{
285 // Set name and formula of the object, only if not yet initialized
286
287 if( fName.Length() == 0 )
288 TNamed::SetNameTitle( name, formula );
289}
290
291//_____________________________________________________________________________
293{
294 // Reset cut result and statistics counters
295
296 ClearResult();
297 fNCalled = fNPassed = 0;
298}
299
300//_____________________________________________________________________________
int Int_t
bool Bool_t
const Ssiz_t kNPOS
char Text_t
int Ssiz_t
double Double_t
const char Option_t
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char mode
char name[80]
Option_t *const kPRINTLINE
static const char *const here
Definition THaVar.cxx:64
virtual Double_t Eval()
Definition THaCut.cxx:90
UInt_t fNPassed
Definition THaCut.h:49
virtual void SetBlockname(const Text_t *name)
Definition THaCut.cxx:258
EvalMode
Definition THaCut.h:24
@ kOR
Definition THaCut.h:24
@ kAND
Definition THaCut.h:24
@ kXOR
Definition THaCut.h:24
@ kModeErr
Definition THaCut.h:24
virtual void SetNameTitle(const Text_t *name, const Text_t *title)
Definition THaCut.cxx:283
EvalMode ParsePrefix(TString &expr)
Definition THaCut.cxx:149
Bool_t fLastResult
Definition THaCut.h:46
virtual void Print(Option_t *opt="") const
Definition THaCut.cxx:200
virtual void SetName(const Text_t *name)
Definition THaCut.cxx:268
EvalMode fMode
Definition THaCut.h:50
void ClearResult()
Definition THaCut.h:26
Bool_t EvalElement(Int_t instance)
Definition THaCut.cxx:84
TString fBlockname
Definition THaCut.h:47
virtual void Reset()
Definition THaCut.cxx:292
THaCut()
Definition THaCut.cxx:25
virtual Int_t DefinedVariable(TString &variable, Int_t &action)
Definition THaCut.cxx:64
UInt_t fNCalled
Definition THaCut.h:48
virtual void Print(Option_t *option="") const
Int_t Init(const char *name, const char *expression)
Int_t GetNdataUnchecked() const
virtual Int_t DefinedVariable(TString &variable, Int_t &action)
virtual Int_t Compile(const char *expression="")
Bool_t IsInvalid() const
Definition THaFormula.h:54
virtual Int_t DefinedCut(TString &variable)
Bool_t IsError() const
Definition THaFormula.h:53
Double_t EvalInstanceUnchecked(Int_t instance)
Definition THaFormula.h:102
@ kFuncOfVarArray
Definition THaFormula.h:66
void SetList(const THaVarList *lst)
Definition THaFormula.h:56
void SetCutList(const THaCutList *lst)
Definition THaFormula.h:57
const char * GetOption(Int_t i=0) const
Bool_t IsLine() const
Int_t GetValue(Int_t i=0) const
const char * GetName() const override
const char * GetTitle() const override
TString fTitle
TString fName
virtual void SetName(const char *name)
virtual void SetNameTitle(const char *name, const char *title)
void SetBit(UInt_t f)
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual void Error(const char *method, const char *msgfmt,...) const
void ResetBit(UInt_t f)
Ssiz_t Length() const
const char * Data() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
TString & Remove(EStripType s, char c)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
double max(double x, double y)
Int_t Nint(T x)
STL namespace.
ClassImp(TPyArg)