Improved functionality of AliRsnDaughterDef::MatchesDaughter()
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnExpression.cxx
CommitLineData
4fbb2459 1//
9477aa42 2// AliRsnExpresion class is used to
3// handle operators &|!
4// in AliRsnCut
4fbb2459 5//
6// authors: Martin Vala (martin.vala@cern.ch)
7// Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
8//
9
baca856a 10#include <TString.h>
11#include <TObjString.h>
12#include <TObjArray.h>
13
14#include "AliLog.h"
15
4fbb2459 16#include "AliRsnVariableExpression.h"
baca856a 17#include "AliRsnExpression.h"
18
aec0ec32 19ClassImp(AliRsnExpression)
baca856a 20
4fbb2459 21AliRsnCutSet *AliRsnExpression::fgCutSet = 0;
baca856a 22
23//______________________________________________________________________________
aec0ec32 24AliRsnExpression::AliRsnExpression(TString exp) :
2a1c7696 25 TObject(),
26 fVname(""),
27 fArg1(0x0),
28 fArg2(0x0),
29 fOperator(0)
baca856a 30{
2a1c7696 31 // Default constructor
32 TObjArray* tokens = Tokenize(exp);
33
34 Int_t i = -1;
35 AliRsnExpression* e = Expression(*tokens, i);
36 // Copy !!!
37 fArg1 = e->fArg1; e->fArg1 = 0;
38 fArg2 = e->fArg2; e->fArg2 = 0;
39 fOperator = e->fOperator;
40 fVname = e->fVname;
41 delete e;
42 delete tokens;
baca856a 43}
44
45//______________________________________________________________________________
46AliRsnExpression::~AliRsnExpression()
47{
2a1c7696 48 if (fArg1) delete fArg1;
49 if (fArg2) delete fArg2;
baca856a 50}
51
aec0ec32 52AliRsnExpression::AliRsnExpression(const AliRsnExpression & exp) : TObject(exp),
2a1c7696 53 fVname(exp.fVname),
54 fArg1(exp.fArg1),
55 fArg2(exp.fArg2),
56 fOperator(exp.fOperator)
baca856a 57{}
58
59//______________________________________________________________________________
aec0ec32 60AliRsnExpression& AliRsnExpression::operator= (const AliRsnExpression& e)
baca856a 61{
2a1c7696 62 // AliRsnExpression assignment operator.
63
64 if (this != &e) {
65 TObject::operator= (e);
66 fArg1 = e.fArg1;
67 fArg2 = e.fArg2;
68 fOperator = e.fOperator;
69 fVname = e.fVname;
70 }
71 return *this;
baca856a 72}
73
74//______________________________________________________________________________
aec0ec32 75AliRsnExpression::AliRsnExpression(int op, AliRsnExpression* a, AliRsnExpression* b) :
2a1c7696 76 TObject(),
77 fVname(""),
78 fArg1(a),
79 fArg2(b),
80 fOperator(op)
baca856a 81{
2a1c7696 82 // Create a new expression
baca856a 83}
84
85//______________________________________________________________________________
aec0ec32 86AliRsnExpression::AliRsnExpression(int op, AliRsnExpression* a) :
2a1c7696 87 TObject(),
88 fVname(""),
89 fArg1(0),
90 fArg2(a),
91 fOperator(op)
baca856a 92{
2a1c7696 93 // Create a unary expression.
baca856a 94}
95
96//______________________________________________________________________________
aec0ec32 97Bool_t AliRsnExpression::Value(TObjArray &vars)
baca856a 98{
2a1c7696 99 // Evaluate the expression
100 if (fArg2 == 0 && fVname.IsNull()) {
101 AliError("Expression undefined.");
102 return kFALSE;
103 }
baca856a 104
105// AliDebug(AliLog::kDebug,Form("fOperator %d",fOperator));
8ecf98c4 106
2a1c7696 107 switch (fOperator) {
baca856a 108
2a1c7696 109 case kOpOR :
110 return fArg1->Value(vars) || fArg2->Value(vars);
baca856a 111
2a1c7696 112 case kOpAND :
113 return fArg1->Value(vars) && fArg2->Value(vars);
baca856a 114
2a1c7696 115 case kOpNOT :
116 return !(fArg2->Value(vars));
baca856a 117
2a1c7696 118 case 0 : {
4fbb2459 119// Int_t indexx = fgCutSet->GetIndexByCutName ( fVname.Data() );
2a1c7696 120 AliDebug(AliLog::kDebug, Form("Vname %s", fVname.Data()));
4fbb2459 121// return fgCutSet->GetBoolValue ( indexx );
2a1c7696 122 return fgCutSet->GetBoolValue(fVname.Atoi());
123 }
baca856a 124
2a1c7696 125 default:
126 AliError("Illegal operator in expression!");
baca856a 127
2a1c7696 128 }
129 return kFALSE;
baca856a 130}
131
132
133//______________________________________________________________________________
134TString AliRsnExpression::Unparse() const
135{
2a1c7696 136 // Unparse the expression
baca856a 137
2a1c7696 138 TString opVals[4] = { "", "&", "|", "!" };
139 if (fArg2 == 0 && fVname.IsNull()) {
140 AliError("Expression undefined.");
141 return "Error";
142 }
baca856a 143
2a1c7696 144 if (fArg2 == 0 && !fVname.IsNull()) return fVname;
baca856a 145
2a1c7696 146 if (fArg1 == 0 && fArg2) {
147 return opVals[fOperator] + fArg2->Unparse();
148 }
149 return "(" + fArg1->Unparse() + " " + opVals[fOperator] + " " + fArg2->Unparse() + ")";
baca856a 150}
151
152//______________________________________________________________________________
aec0ec32 153TObjArray* AliRsnExpression::Tokenize(TString str) const
baca856a 154{
2a1c7696 155 // tokenize the expression
156
157 // Remove spaces
158 TString str1;
159 for (Int_t i = 0; i < str.Length(); i++) {
160 if (str[i] == ' ') continue;
161 str1.Append(str[i]);
162 }
163 // get variable tokens
164 TObjArray* valtok = str1.Tokenize("!&|()");
165 // put all variables together
166 Int_t nvt = valtok->GetEntriesFast();
167 TString sumval;
168 for (Int_t i = 0; i < nvt; i++) {
169 TObjString* val = (TObjString*) valtok->At(i);
170 sumval.Append(val->String());
171 }
172 // get the operator tokens
173 TObjArray* optok = str1.Tokenize(sumval.Data());
174 // put all operator in one string
175 TString operators;
176 Int_t nopt = optok->GetEntriesFast();
177 for (Int_t i = 0; i < nopt; i++) {
178 TObjString* val1 = (TObjString*) optok->At(i);
179 operators.Append(val1->String());
180 }
181 // add more room to be safe
182 TObjString* blank = new TObjString(" ");
183 operators.Append(" ");
184 valtok->AddLast(blank);
185 // Now put var. and oper. together
186 TObjArray* tokens = new TObjArray(valtok->GetEntriesFast() + operators.Length());
187 int io = 0, iv = 0;
188 int index = 0;
189 while (1) {
190 TString so = operators[io];
191 int indexO = str1.Index(so, index);
192 TString val2 = ((TObjString*) valtok->At(iv))->String();
193 int indexV = str1.Index(val2, index);
194 if ((indexO < indexV || indexV < 0) && indexO >= 0) {
195 tokens->AddLast(new TObjString(so));
196 index += so.Length();
197 io++;
198 }
199 if ((indexV < indexO || indexO < 0) && indexV >= 0) {
200 tokens->AddLast(new TObjString(val2));
201 index += val2.Length();
202 iv++;
203 }
204 if (index >= str1.Length()) break;
205 }
baca856a 206
207// // Debug -> Print the tokens
208// Int_t nt = tokens->GetEntriesFast();
209// for ( Int_t i=0; i<nt; i++ )
210// {
211// TObjString* val3 = ( TObjString* ) tokens->At ( i );
212// AliInfo ( Form ( "%d %s",i,val3->String().Data() ) );
213// }
8ecf98c4 214//
215//
2a1c7696 216 delete valtok;
217 delete optok;
baca856a 218
2a1c7696 219 return tokens;
baca856a 220}
221
222
223//______________________________________________________________________________
aec0ec32 224AliRsnExpression* AliRsnExpression::Element(TObjArray &st, Int_t &i)
baca856a 225{
2a1c7696 226 // create an element
227
228 AliRsnExpression* result = 0;
229
230 Int_t nt = st.GetEntriesFast();
231 TString token = "@";
232 TObjString* valt;
233 // next token
234 if (i < nt - 1) {
4fbb2459 235 i++;
236 valt = (TObjString*) st.At(i);
237 token = valt->String();
2a1c7696 238 }
239 // token type
240 char ttok = (token[0] != '|' && token[0] != '&' &&
241 token[0] != '!' && token[0] != '(' && token[0] != ')') ? 'w' : token[0];
242 switch (ttok) {
243 case 'w' : {
244 result = new AliRsnVariableExpression(token);
245 break;
246 }
247 case '(' :
248 result = Expression(st, i);
249 // next token
250 if (i < nt - 1) {
251 i++;
252 valt = (TObjString*) st.At(i);
253 token = valt->String();
254 }
255 if (token[0] != ')') {
256 // i--; // push back
257 AliErrorGeneral("AliRsnExpression::Element", "Mismatched parenthesis.");
258 delete result;
259 result = new AliRsnExpression;
260 }
261 break;
262 default:
263 i--; // push back
264 AliErrorGeneral("AliRsnExpression::Element", Form("Unexpected symbol on input. %s", token.Data()));
265 //if (result) delete result;
266 result = new AliRsnExpression;
267 }
268 return result;
baca856a 269}
270
271//______________________________________________________________________________
aec0ec32 272AliRsnExpression* AliRsnExpression::Primary(TObjArray &st, Int_t &i)
baca856a 273{
2a1c7696 274 // create a primary
275
276 Int_t nt = st.GetEntriesFast();
277 TString token = "@";
278 TObjString* valt;
279 // next token
280 if (i < nt - 1) {
281 i++;
282 valt = (TObjString*) st.At(i);
283 token = valt->String();
284 }
285
286 switch (token[0]) {
287 case '!' :
288 return new AliRsnExpression(kOpNOT, Primary(st, i));
289 default:
290 i--; // push back
291 return Element(st, i);
292 }
baca856a 293}
294
295//______________________________________________________________________________
2a1c7696 296AliRsnExpression* AliRsnExpression::Expression(TObjArray &st, Int_t &i)
baca856a 297{
2a1c7696 298 // create an expression
baca856a 299
2a1c7696 300 AliRsnExpression* result = 0;
301 Bool_t done = kFALSE;
302 TString token;
303 TObjString* valt;
baca856a 304
2a1c7696 305 static int stack = 0;
306 stack++;
307 Int_t nt = st.GetEntriesFast();
baca856a 308
2a1c7696 309 result = Primary(st, i);
baca856a 310// cout <<"i "<<i<< "Primary " << result->Unparse() << endl;
2a1c7696 311 while (! done) {
312 // next token
313 if (i < nt - 1) i++;
314 else break;
315 valt = (TObjString*) st.At(i);
316 token = valt->String();
317 switch (token[0]) {
318 case '&' :
319 result = new AliRsnExpression(kOpAND, result, Primary(st, i));
baca856a 320// cout <<"i "<<i<< " Expression AND " << result->Unparse() << endl;
2a1c7696 321 break;
322 case '|' :
323 result = new AliRsnExpression(kOpOR, result, Primary(st, i));
baca856a 324// cout <<"i "<<i<< " Expression OR " << result->Unparse() << endl;
2a1c7696 325 break;
326 default:
327 done = kTRUE;
328 i--; // push back
329 break;
330 }
331 }
332 stack--;
333 if (stack == 0 && !token.IsNull() && token[0] == ')') {
334 AliErrorGeneral("AliRsnExpression::Expression", "To many closing parenthesis.");
335 delete result;
336 result = new AliRsnExpression;
337 } else if (stack == 0 && i < nt - 1) {
aec0ec32 338 AliErrorGeneral("AliRsnExpression::Expression", Form("Unexpected symbol on input. %s", token.Data()));
baca856a 339 delete result;
340 result = new AliRsnExpression;
2a1c7696 341 }
342 return result;
baca856a 343}