StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
strangeFormulas.C
1 //======================================================
2 // owner: Gene Van Buren, UCLA
3 // what it does: creates formulas for use with strangeness micro DST
4 // usage: The parameter is either a pointer to a strangeness
5 // micro DST tree, a pointer to a TFile containing such
6 // a tree (tree name assumed to be either "StrangeMuDst"
7 // or "MuDst" (in the case of a common micro DST)), or
8 // the name of such a file or files (one can use wildcards
9 // to examine the data in multiple files). In the latter
10 // two cases, a pointer to the strangeness TTree is returned.
11 // See documentation for more information.
12 //
13 // After initial execution of the macro, the user may utilize
14 // the global pointers TTree* strangeTree or TChain* strangeChain.
15 // Additonal files can be added to the chain by calling
16 // strangeFormulas(filename) again.
17 //
18 // examples:
19 // .x strangeFormulas.C("myfile.root");
20 // Opens a file named "myfile.root", loads the formulas needed,
21 // and returns a pointer to the TTree.
22 // .x strangeFormulas.C("/path/to/otherfiles*.root");
23 // Opens all the files matching the pattern using a TChain.
24 // The returned pointer is the TChain cast to a TTree pointer.
25 // .x strangeFormulas.C("listfile.lis");
26 // Opens all the files specified in the file listfile.lis,
27 // whose format may simply be one filename per line, or the
28 // output of a call to: get_file_list.pl -keys path,filename ...
29 // The returned pointer is the TChain cast to a TTree pointer.
30 // .x strangeFormulas.C;
31 // Opens a file named "evMuDst.root", loads the formulas needed,
32 // and returns a pointer to the TTree (this is the default file).
33 // .x strangeFormulas.C(myTreePtr);
34 // Returns the number of new formulas loaded into Root.
35 // .x strangeFormulas.C(myFilePtr);
36 // Returns a pointer to the tree named either "StrangeMuDst"
37 // or "MuDst" in the file pointed to by myFilePtr.
38 //======================================================
39 //
40 // Should be careful to optimize formulas for number of calls to
41 // other formulas. TTreeFormula/TFormula is not smart enough to save
42 // values to repeat them, and calculates the full thing twice, but
43 // has a limit of 100 values one can calculate (only 50 values for
44 // Root 2.24/04 and earlier).
45 //
46 // For example, "a()+a()+a()" repeats everything necessary to find
47 // "a()" three times. If "a()" requires 20 values to calculate, then
48 // "a()+a()+a()" will fail for Root 2.24/04, needing 60 values. Much
49 // better to write something like "3*a()".
50 //
51 
52 
53 // Public interface:
54 // TTree* strangeFormulas(const char* fname=0, const char* tname=0);
55 // TTree* strangeFormulas(TFile* fptr);
56 // Int_t strangeFormulas(TTree* tree);
57 // void findFormulas(const char* c0, const char* c1=0, const char* c2=0);
58 // TFormula* findFormula(const char* c0); // Requires exact match
59 // void findDefinition(const char* c0); // Requires exact match
60 
61 
62 // Internal members and functions:
63 // void formulate(const char* name, const char* formula);
64 TTree* strangeTree=0;
65 TChain* strangeChain=0;
66 TCollection* ListofFuncs=0;
67 Int_t max_codes=0;
68 static const char* defaultFile = "evMuDst.root";
69 static const char* defaultTree = "StrangeMuDst";
70 static const char* altTree = "MuDst";
71 
72 //-----------------------------------------------------
73 
74 void prep() {
75  if (!(gROOT->GetClass("TTreePlayer"))) {
76  gSystem->Load("libTreePlayer");
77  gSystem->Load("libProof");
78  }
79  if (!ListofFuncs) ListofFuncs=gROOT->GetListOfFunctions();
80 }
81 
82 //-----------------------------------------------------
83 
84 void findFormulas(const char* c0, const char* c1=0, const char* c2=0) {
85  for (Int_t i=0; i<ListofFuncs->GetSize(); i++) {
86  TString ostr = ListofFuncs->At(i)->GetName();
87  if (ostr.Contains(c0,TString::kIgnoreCase)) {
88  if ((!c1) || (ostr.Contains(c1,TString::kIgnoreCase))) {
89  if ((!c2) || (ostr.Contains(c2,TString::kIgnoreCase))) {
90  cout << ostr.Data() << endl;
91  }
92  }
93  }
94  }
95 }
96 
97 //-----------------------------------------------------
98 
99 TFormula* findFormula(const char* c0) {
100  return (TFormula*) ListofFuncs->FindObject(c0);
101 }
102 
103 //-----------------------------------------------------
104 
105 void findDefinition(const char* c0) {
106  TFormula* f1 = findFormula(c0);
107  if (f1) {
108  cout << "Name : " << f1->GetName() << endl;
109  if (f1->IsA() == TTreeFormula::Class())
110  cout << "# of Codes : " << ((TTreeFormula*) f1)->GetNcodes() << endl;
111  cout << "Definition : " << f1->GetTitle() << endl;
112  }
113 }
114 
115 //-----------------------------------------------------
116 
117 void formulate(const char* name, const char* formula) {
118  TTreeFormula* f1 = (TTreeFormula*) findFormula(name);
119  if (f1) {
120  f1->SetTree(strangeTree);
121  } else {
122  f1 = new TTreeFormula(name,formula,strangeTree);
123  ListofFuncs->Add(f1);
124  if (f1->GetNcodes() > max_codes) {
125  cout << "\nWARNING!!! The following formula uses " << f1->GetNcodes();
126  cout << " values,\n too many for this version of ROOT: \n";
127  cout << f1->GetName() << " = " << f1->GetTitle() << endl;
128  }
129  }
130 }
131 
132 //-----------------------------------------------------
133 
134 TTree* strangeFormulas(const char* fname=0, const char* tname=0) {
135  if (!fname) {
136  fname = defaultFile;
137  } else {
138 
139  // Check for list files...
140  TString fnamestr = fname;
141  if (!(fnamestr.EndsWith(".root"))) {
142  ifstream inlist(fname);
143  if (!inlist) {
144  cout << "\nERROR!!! Cannot find list file: " << fname << endl;
145  return strangeTree;
146  }
147  char iname[256];
148  TString inamestr;
149  inlist >> iname;
150  while (! inlist.eof()) {
151  inamestr = iname;
152  inamestr.ReplaceAll("::","/");
153  inamestr.ReplaceAll("//","/");
154  strangeFormulas(inamestr.Data(),tname);
155  if (!strangeTree) {
156  cout << "\nERROR!!! Trouble with first file: "
157  << inamestr.Data() << endl;
158  return 0;
159  }
160  inlist >> iname;
161  }
162  return strangeTree;
163  }
164  }
165 
166  // If we already have a chain and are just adding files...
167  if (strangeChain) {
168  strangeChain->Add(fname);
169  return strangeTree;
170  }
171 
172  // Start chain with the first filename...
173  prep();
174  if (!tname) {
175  tname = defaultTree;
176  }
177  printf("Looking for tree with name %s\n",tname);
178  strangeChain = new TChain(tname);
179  strangeChain->Add(fname);
180  if (strangeChain->LoadTree(0)) {
181  delete strangeChain;
182  strangeChain = 0;
183  // Try again with altTree
184  if (!(strcmp(tname,defaultTree))) return strangeFormulas(fname,altTree);
185  return 0;
186  }
187  strangeTree = (TTree*) strangeChain;
188  strangeFormulas(strangeTree);
189  return strangeTree;
190 }
191 
192 //-----------------------------------------------------
193 
194 TTree* strangeFormulas(TFile* fptr) {
195  prep();
196  if (!fptr) return 0;
197  strangeTree = (TTree*) fptr->Get(defaultTree);
198  if (!strangeTree) strangeTree = (TTree*) fptr->Get(altTree);
199  strangeFormulas(strangeTree);
200  return strangeTree;
201 }
202 
203 //-----------------------------------------------------
204 
205 Int_t strangeFormulas(TTree* tree) {
206  prep();
207  if (!tree) return 0;
208  if (gROOT->GetVersionInt() < 22405) {
209  max_codes = 50;
210  } else {
211  max_codes = 100;
212  }
213 
214  // These branches seem to require classes. No thanks.
215  if (tree->GetBranch("EmcCollection")) {
216  tree->SetBranchStatus("EmcCollection.*",0);
217  }
218  if (tree->GetBranch("PmdCollection")) {
219  tree->SetBranchStatus("PmdCollection.*",0);
220  }
221 
222  strangeTree = tree;
223  char name[256];
224  char expr[2048];
225  char track[32];
226  char temp[256];
227  char ftpc[256];
228  TString tstr;
229 
230  TFormula *f0=0;
231  Int_t initialFormulas = ListofFuncs->GetSize();
232 
233  // Mass formulas
234  f0 = new TFormula("mLambda", "1.11563");
235  f0 = new TFormula("mAntiLambda", "1.11563");
236  f0 = new TFormula("mK0Short", "0.497671");
237  f0 = new TFormula("mProton", "0.938272");
238  f0 = new TFormula("mAntiProton", "0.938272");
239  f0 = new TFormula("mPiPlus", "0.139568");
240  f0 = new TFormula("mPiMinus", "0.139568");
241  f0 = new TFormula("mKaonMinus", "0.493646");
242 
243 
244  // Event
245  printf("Loading event formulas...\n");
246  formulate("Event.run()", "Event.mRun");
247  formulate("Event.event()", "abs(Event.mEvent)");
248  formulate("Event.globalTracks()", "Event.mGlobalTracks");
249  formulate("Event.primaryTracks()", "Event.mPrimaryTracks");
250  formulate("Event.primaryNegTracks()", "Event.mPrimaryNegTracks");
251  formulate("Event.primaryVertexX()", "Event.mPrimaryVertexX");
252  formulate("Event.primaryVertexY()", "Event.mPrimaryVertexY");
253  formulate("Event.primaryVertexZ()", "Event.mPrimaryVertexZ");
254  formulate("Event.magneticField()", "Event.mMagneticField");
255  formulate("Event.l0TriggerWord()", "Event.mL0TriggerWord");
256  formulate("Event.unbiasedTrigger()", "(Event.mEvent>0)");
257 
258 
259  // McEvent
260  if (tree->GetBranch("McEvent")) {
261  printf("Loading MC event formulas...\n");
262 
263  formulate("McEvent.run()", "McEvent.mRun");
264  formulate("McEvent.event()", "McEvent.mEvent");
265  formulate("McEvent.globalTracks()", "McEvent.mGlobalTracks");
266  formulate("McEvent.primaryTracks()", "McEvent.mPrimaryTracks");
267  formulate("McEvent.primaryNegTracks()", "McEvent.mPrimaryNegTracks");
268  formulate("McEvent.primaryVertexX()", "McEvent.mPrimaryVertexX");
269  formulate("McEvent.primaryVertexY()", "McEvent.mPrimaryVertexY");
270  formulate("McEvent.primaryVertexZ()", "McEvent.mPrimaryVertexZ");
271 
272  } // End of McEvent
273 
274 
275  // V0
276  if (tree->GetBranch("V0")) {
277  printf("Loading V0 formulas...\n");
278 
279  // The following formula uses 6 values:
280  formulate("V0.decayLengthV0()",
281  "sqrt(sq(V0.mDecayVertexV0X-Event.mPrimaryVertexX[0])+sq(V0.mDecayVertexV0Y-Event.mPrimaryVertexY[0])+sq(V0.mDecayVertexV0Z-Event.mPrimaryVertexZ[0]))");
282 
283  // The following formulas use 1 value:
284  formulate("V0.decayVertexV0X()", "V0.mDecayVertexV0X");
285  formulate("V0.decayVertexV0Y()", "V0.mDecayVertexV0Y");
286  formulate("V0.decayVertexV0Z()", "V0.mDecayVertexV0Z");
287  formulate("V0.dcaV0Daughters()", "V0.mDcaV0Daughters");
288  formulate("V0.dcaV0ToPrimVertex()", "V0.mDcaV0ToPrimVertex");
289  formulate("V0.dcaPosToPrimVertex()", "V0.mDcaPosToPrimVertex");
290  formulate("V0.dcaNegToPrimVertex()", "V0.mDcaNegToPrimVertex");
291  formulate("V0.momPosX()", "V0.mMomPosX");
292  formulate("V0.momPosY()", "V0.mMomPosY");
293  formulate("V0.momPosZ()", "V0.mMomPosZ");
294  formulate("V0.momNegX()", "V0.mMomNegX");
295  formulate("V0.momNegY()", "V0.mMomNegY");
296  formulate("V0.momNegZ()", "V0.mMomNegZ");
297 
298  formulate("V0.radt2V0()", "sq(V0.mDecayVertexV0X)+sq(V0.mDecayVertexV0Y)");
299  formulate("V0.radtV0()", "sqrt(V0.radt2V0())");
300  formulate("V0.radV0()", "sqrt(V0.radt2V0()+sq(V0.mDecayVertexV0Z))");
301  formulate("V0.phiV0()",
302  "atan2((V0.mDecayVertexV0Y-Event.mPrimaryVertexY[0]),(V0.mDecayVertexV0X-Event.mPrimaryVertexX[0]))");
303  formulate("V0.phi90V0()",
304  "atan2(-(V0.mDecayVertexV0X-Event.mPrimaryVertexX[0]),(V0.mDecayVertexV0Y-Event.mPrimaryVertexY[0]))");
305 
306  formulate("V0.Ptot2Pos()",
307  "(sq(V0.mMomPosX)+sq(V0.mMomPosY)+sq(V0.mMomPosZ))");
308  formulate("V0.Ptot2Neg()",
309  "(sq(V0.mMomNegX)+sq(V0.mMomNegY)+sq(V0.mMomNegZ))");
310  formulate("V0.momV0X()", "(V0.mMomPosX+V0.mMomNegX)");
311  formulate("V0.momV0Y()", "(V0.mMomPosY+V0.mMomNegY)");
312  formulate("V0.momV0Z()", "(V0.mMomPosZ+V0.mMomNegZ)");
313  formulate("V0.Pt2V0()", "(sq(V0.momV0X())+sq(V0.momV0Y()))");
314  formulate("V0.Ptot2V0()", "(V0.Pt2V0()+sq(V0.momV0Z()))");
315 
316  // The following momentum component formulas use 15 values:
317  formulate("V0.MomPosAlongV0()",
318  "(((V0.mMomPosX*V0.momV0X())+(V0.mMomPosY*V0.momV0Y())+(V0.mMomPosZ*V0.momV0Z()))/sqrt(V0.Ptot2V0()))");
319  formulate("V0.MomNegAlongV0()",
320  "(((V0.mMomNegX*V0.momV0X())+(V0.mMomNegY*V0.momV0Y())+(V0.mMomNegZ*V0.momV0Z()))/sqrt(V0.Ptot2V0()))");
321 
322  formulate("V0.alphaV0()",
323  // "((V0.MomPosAlongV0()-V0.MomNegAlongV0())/(V0.MomPosAlongV0()+V0.MomNegAlongV0()))");
324  // The above is cumbersome, using 50 values. The following uses 30:
325  "1.-(2./(1.+(V0.MomPosAlongV0()/V0.MomNegAlongV0())))");
326  // The following formula uses 18 values:
327  formulate("V0.ptArmV0()", "sqrt(V0.Ptot2Pos()-sq(V0.MomPosAlongV0()))");
328 
329  // The following energy formulas use 6 values:
330  formulate("V0.eLambda()", "sqrt(V0.Ptot2V0()+sq(mLambda))");
331  formulate("V0.eK0Short()", "sqrt(V0.Ptot2V0()+sq(mK0Short))");
332  formulate("V0.ePosProton()", "sqrt(V0.Ptot2Pos()+sq(mProton))");
333  formulate("V0.eNegAntiProton()", "sqrt(V0.Ptot2Neg()+sq(mAntiProton))");
334  formulate("V0.ePosPion()", "sqrt(V0.Ptot2Pos()+sq(mPiPlus))");
335  formulate("V0.eNegPion()", "sqrt(V0.Ptot2Neg()+sq(mPiMinus))");
336 
337  // The following mass formulas use 12 values:
338  formulate("V0.massLambda()",
339  "sqrt(sq(V0.ePosProton()+V0.eNegPion())-V0.Ptot2V0())");
340  formulate("V0.massAntiLambda()",
341  "sqrt(sq(V0.eNegAntiProton()+V0.ePosPion())-V0.Ptot2V0())");
342  formulate("V0.massK0Short()",
343  "sqrt(sq(V0.ePosPion()+V0.eNegPion())-V0.Ptot2V0())");
344 
345  // The following rapidity formulas use 8 values:
346  formulate("V0.rapLambda()",
347  // "0.5*log((V0.eLambda()+V0.momV0Z())/(V0.eLambda()-V0.momV0Z()))");
348  // Can optimize for TTreeFormula:
349  "0.5*log(1.+(2./((V0.eLambda()/V0.momV0Z())-1.)))");
350  formulate("V0.rapK0Short()",
351  // "0.5*log((V0.eK0Short()+V0.momV0Z())/(V0.eK0Short()-V0.momV0Z()))");
352  // Can optimize for TTreeFormula:
353  "0.5*log(1.+(2./((V0.eK0Short()/V0.momV0Z())-1.)))");
354 
355  // The following cTau formulas use 24 values:
356  formulate("V0.cTauLambda()",
357  "V0.massLambda()*V0.decayLengthV0()/sqrt(V0.Ptot2V0())");
358  formulate("V0.cTauK0Short()",
359  "V0.massK0Short()*V0.decayLengthV0()/sqrt(V0.Ptot2V0())");
360 
361  formulate("V0.ptPos()", "sqrt(sq(V0.mMomPosX)+sq(V0.mMomPosY))");
362  formulate("V0.ptotPos()", "sqrt(V0.Ptot2Pos())");
363  formulate("V0.ptNeg()", "sqrt(sq(V0.mMomNegX)+sq(V0.mMomNegY))");
364  formulate("V0.ptotNeg()", "sqrt(V0.Ptot2Neg())");
365  formulate("V0.ptV0()", "sqrt(V0.Pt2V0())");
366  formulate("V0.ptotV0()", "sqrt(V0.Ptot2V0())");
367  formulate("V0.thetaV0()", "acos(V0.momV0Z()/V0.ptotV0())");
368  formulate("V0.pseudoRapV0()", "-log(tan(V0.thetaV0()/2.))");
369  formulate("V0.psiV0()", "atan2(V0.momV0Y(),V0.momV0X())");
370  formulate("V0.psi90V0()", "atan2(-V0.momV0X(),V0.momV0Y())");
371 
372  // Track topology maps, with function names like
373  // "V0.topologyMapNeg.*()" and "V0.topologyMapPos.*()"
374  if (tree->GetBranch("V0.mTopologyMapPos.mMap0")) {
375  for (int k=0; k<2; k++) {
376  if (k) sprintf(track,"Neg\0");
377  else sprintf(track,"Pos\0");
378 
379 
380  // bit(i), i=0,63, uses only 1 value.
381  for (int l=0; l<2; l++) {
382  for (int j=0; j<32; j++) {
383  int m = l*32 + j;
384  sprintf(name,"V0.topologyMap%s.bit(%d)\0",track,m);
385  sprintf(expr,"(V0.mTopologyMap%s.mMap%d/(2^%d))&1\0",track,l,j);
386  formulate(name,expr);
387  }
388 
389  // data(i), i=0,1, uses only 1 value.
390  sprintf(name,"V0.topologyMap%s.data(%d)",track,l);
391  sprintf(expr,"V0.mTopologyMap%s.mMap%d",track,l);
392  formulate(name,expr);
393  }
394 
395  // ftpcFormat()
396  sprintf(ftpc,"V0.topologyMap%s.ftpcFormat()",track);
397  sprintf(expr,"V0.topologyMap%s.bit(63)",track);
398  formulate(ftpc,expr);
399 
400  // primaryVertexUsed()
401  sprintf(name,"V0.topologyMap%s.primaryVertexUsed()",track);
402  sprintf(expr,"V0.topologyMap%s.bit(0)",track);
403  formulate(name,expr);
404 
405  // turnAroundFlag()
406  sprintf(name,"V0.topologyMap%s.turnAroundFlag()",track);
407  sprintf(expr,"V0.topologyMap%s.bit(62)",track);
408  formulate(name,expr);
409 
410  // hasHitInSvtLayer(i), i=1,6
411  for (int j=1; j<7; j++) {
412  sprintf(name,"V0.topologyMap%s.hasHitInSvtLayer(%d)",track,j);
413  sprintf(temp,"V0.topologyMap%s.bit(%d)\0",track,j);
414  sprintf(expr,"(!%s)&&(%s)\0",ftpc,temp);
415  formulate(name,expr);
416 
417  tstr += temp;
418  if (j<6) tstr += "+";
419  }
420 
421  // numOfSvtHits(), uses 6 values
422  sprintf(name,"V0.topologyMap%s.numOfSvtHits()\0",track);
423  sprintf(expr,"(!%s)*(%s)\0",ftpc,tstr.Data());
424  formulate(name,expr);
425  tstr = "";
426 
427  // hasHitInSsd()
428  sprintf(name,"V0.topologyMap%s.hasHitInSsd()",track);
429  sprintf(expr,"V0.topologyMap%s.bit(7)",track);
430  formulate(name,expr);
431 
432  sprintf(temp,"(!%s)*(\0",ftpc);
433  tstr = temp;
434 
435  // hasHitInTpcRow(i), i=0,44
436  for (int j=0; j<45; j++) {
437  sprintf(name,"V0.topologyMap%s.hasHitInTpcRow(%d)",track,j);
438  int m = j+8;
439  sprintf(temp,"V0.topologyMap%s.bit(%d)\0",track,m);
440  sprintf(expr,"(!%s)&&(%s)\0",ftpc,temp);
441  formulate(name,expr);
442 
443  tstr += temp;
444  if (j<44) tstr += "+";
445  }
446 
447  // numOfTpcHits(), uses 45 values.
448  sprintf(name,"V0.topologyMap%s.numOfTpcHits()\0",track);
449  tstr += ")";
450  formulate(name,tstr.Data());
451  tstr = "";
452 
453  // hasHitInMwpc()
454  sprintf(name,"V0.topologyMap%s.hasHitInMwpc()",track);
455  sprintf(expr,"V0.topologyMap%s.bit(53)",track);
456  formulate(name,expr);
457 
458  // hasHitInCtb()
459  sprintf(name,"V0.topologyMap%s.hasHitInCtb()",track);
460  sprintf(expr,"V0.topologyMap%s.bit(54)",track);
461  formulate(name,expr);
462 
463  // hasHitInTofPatch()
464  sprintf(name,"V0.topologyMap%s.hasHitInTofPatch()",track);
465  sprintf(expr,"V0.topologyMap%s.bit(55)",track);
466  formulate(name,expr);
467 
468  // hasHitInRich()
469  sprintf(name,"V0.topologyMap%s.hasHitInRich()",track);
470  sprintf(expr,"V0.topologyMap%s.bit(56)",track);
471  formulate(name,expr);
472 
473  // hasHitInBarrelEmc()
474  sprintf(name,"V0.topologyMap%s.hasHitInBarrelEmc()",track);
475  sprintf(expr,"V0.topologyMap%s.bit(57)",track);
476  formulate(name,expr);
477 
478  // hasHitInEndcapEmc()
479  sprintf(name,"V0.topologyMap%s.hasHitInEndcapEmc()",track);
480  sprintf(expr,"V0.topologyMap%s.bit(58)",track);
481  formulate(name,expr);
482  } } // End topology maps
483 
484  // The following formulas use 1 value:
485  formulate("V0.chi2V0()", "V0.mChi2V0");
486  formulate("V0.clV0()", "V0.mClV0");
487  formulate("V0.chi2Pos()", "V0.mChi2Pos");
488  formulate("V0.clPos()", "V0.mClPos");
489  formulate("V0.dedxPos()", "V0.mDedxPos");
490  formulate("V0.numDedxPos()", "V0.mNumDedxPos");
491  formulate("V0.chi2Neg()", "V0.mChi2Neg");
492  formulate("V0.clNeg()", "V0.mClNeg");
493  formulate("V0.dedxNeg()", "V0.mDedxNeg");
494  formulate("V0.numDedxNeg()", "V0.mNumDedxNeg");
495 
496  } // End of V0
497 
498  // V0Mc
499  if (tree->GetBranch("V0Mc")) {
500  printf("Loading V0Mc formulas...\n");
501 
502  // The following formula uses 6 values:
503  formulate("V0Mc.decayLengthV0()",
504  "sqrt(sq(V0Mc.mPositionX-McEvent.mPrimaryVertexX[0])+sq(V0Mc.mPositionY-McEvent.mPrimaryVertexY[0])+sq(V0Mc.mPositionZ-McEvent.mPrimaryVertexZ[0]))");
505 
506  // The following formulas use 1 value:
507  formulate("V0Mc.decayMode()", "V0Mc.mDecayMode");
508  formulate("V0Mc.positiveCommonTpcHits()", "V0Mc.mPositiveCommonTpcHits");
509  formulate("V0Mc.positiveSimTpcHits()", "V0Mc.mPositiveSimTpcHits");
510  formulate("V0Mc.negativeCommonTpcHits()", "V0Mc.mNegativeCommonTpcHits");
511  formulate("V0Mc.negativeSimTpcHits()", "V0Mc.mNegativeSimTpcHits");
512  formulate("V0Mc.geantIdParent()", "V0Mc.mParentGeantId");
513  formulate("V0Mc.geantIdPositive()", "V0Mc.mPositiveGeantId");
514  formulate("V0Mc.geantIdNegative()", "V0Mc.mNegativeGeantId");
515  formulate("V0Mc.parentMomentumX()", "V0Mc.mParentMomentumX");
516  formulate("V0Mc.parentMomentumY()", "V0Mc.mParentMomentumY");
517  formulate("V0Mc.parentMomentumZ()", "V0Mc.mParentMomentumZ");
518  formulate("V0Mc.positiveMomentumX()", "V0Mc.mPositiveMomentumX");
519  formulate("V0Mc.positiveMomentumY()", "V0Mc.mPositiveMomentumY");
520  formulate("V0Mc.positiveMomentumZ()", "V0Mc.mPositiveMomentumZ");
521  formulate("V0Mc.negativeMomentumX()", "V0Mc.mNegativeMomentumX");
522  formulate("V0Mc.negativeMomentumY()", "V0Mc.mNegativeMomentumY");
523  formulate("V0Mc.negativeMomentumZ()", "V0Mc.mNegativeMomentumZ");
524  formulate("V0Mc.positionX()", "V0Mc.mPositionX");
525  formulate("V0Mc.positionY()", "V0Mc.mPositionY");
526  formulate("V0Mc.positionZ()", "V0Mc.mPositionZ");
527 
528  } // End of V0Mc
529 
530 
531  // Xi
532  if (tree->GetBranch("Xi")) {
533  printf("Loading Xi formulas...\n");
534 
535  f0 = new TFormula("mXiMinus", "1.32133");
536  f0 = new TFormula("mOmegaMinus", "1.67243");
537 
538  // First, the Xi's get all the same functions that the V0's get...
539  // The following formula uses 6 values:
540  formulate("Xi.decayLengthV0()",
541  "sqrt(sq(Xi.mDecayVertexV0X-Xi.mDecayVertexXiX)+sq(Xi.mDecayVertexV0Y-Xi.mDecayVertexXiY)+sq(Xi.mDecayVertexV0Z-Xi.mDecayVertexXiZ))");
542 // "sqrt(sq(Xi.mDecayVertexV0X-Event.mPrimaryVertexX[0])+sq(Xi.mDecayVertexV0Y-Event.mPrimaryVertexY[0])+sq(Xi.mDecayVertexV0Z-Event.mPrimaryVertexZ[0]))");
543 
544  // The following formulas use 1 value:
545  formulate("Xi.decayVertexV0X()", "Xi.mDecayVertexV0X");
546  formulate("Xi.decayVertexV0Y()", "Xi.mDecayVertexV0Y");
547  formulate("Xi.decayVertexV0Z()", "Xi.mDecayVertexV0Z");
548  formulate("Xi.dcaV0Daughters()", "Xi.mDcaV0Daughters");
549  formulate("Xi.dcaV0ToPrimVertex()", "Xi.mDcaV0ToPrimVertex");
550  formulate("Xi.dcaPosToPrimVertex()", "Xi.mDcaPosToPrimVertex");
551  formulate("Xi.dcaNegToPrimVertex()", "Xi.mDcaNegToPrimVertex");
552  formulate("Xi.momPosX()", "Xi.mMomPosX");
553  formulate("Xi.momPosY()", "Xi.mMomPosY");
554  formulate("Xi.momPosZ()", "Xi.mMomPosZ");
555  formulate("Xi.momNegX()", "Xi.mMomNegX");
556  formulate("Xi.momNegY()", "Xi.mMomNegY");
557  formulate("Xi.momNegZ()", "Xi.mMomNegZ");
558 
559  formulate("Xi.radt2V0()", "sq(Xi.mDecayVertexV0X)+sq(Xi.mDecayVertexV0Y)");
560  formulate("Xi.radtV0()", "sqrt(Xi.radt2V0())");
561  formulate("Xi.radV0()", "sqrt(Xi.radt2V0()+sq(Xi.mDecayVertexV0Z))");
562  formulate("Xi.phiV0()",
563  "atan2((Xi.mDecayVertexV0Y-Xi.mDecayVertexXiY),(Xi.mDecayVertexV0X-Xi.mDecayVertexXiX))");
564 // "atan2((Xi.mDecayVertexV0Y-Event.mPrimaryVertexY[0]),(Xi.mDecayVertexV0X-Event.mPrimaryVertexX[0]))");
565 
566  formulate("Xi.Ptot2Pos()",
567  "(sq(Xi.mMomPosX)+sq(Xi.mMomPosY)+sq(Xi.mMomPosZ))");
568  formulate("Xi.Ptot2Neg()",
569  "(sq(Xi.mMomNegX)+sq(Xi.mMomNegY)+sq(Xi.mMomNegZ))");
570  formulate("Xi.momV0X()", "(Xi.mMomPosX+Xi.mMomNegX)");
571  formulate("Xi.momV0Y()", "(Xi.mMomPosY+Xi.mMomNegY)");
572  formulate("Xi.momV0Z()", "(Xi.mMomPosZ+Xi.mMomNegZ)");
573  formulate("Xi.Pt2V0()", "(sq(Xi.momV0X())+sq(Xi.momV0Y()))");
574  formulate("Xi.Ptot2V0()", "(Xi.Pt2V0()+sq(Xi.momV0Z()))");
575 
576  // The following momentum component formulas use 15 values:
577  formulate("Xi.MomPosAlongV0()",
578  "(((Xi.mMomPosX*Xi.momV0X())+(Xi.mMomPosY*Xi.momV0Y())+(Xi.mMomPosZ*Xi.momV0Z()))/sqrt(Xi.Ptot2V0()))");
579  formulate("Xi.MomNegAlongV0()",
580  "(((Xi.mMomNegX*Xi.momV0X())+(Xi.mMomNegY*Xi.momV0Y())+(Xi.mMomNegZ*Xi.momV0Z()))/sqrt(Xi.Ptot2V0()))");
581 
582  formulate("Xi.alphaV0()",
583  // "((Xi.MomPosAlongV0()-Xi.MomNegAlongV0())/(Xi.MomPosAlongV0()+Xi.MomNegAlongV0()))");
584  // The above is cumbersome, using 50 values. The following uses 30:
585  "1.-(2./(1.+(Xi.MomPosAlongV0()/Xi.MomNegAlongV0())))");
586  // The following formula uses 18 values:
587  formulate("Xi.ptArmV0()",
588  "sqrt(Xi.Ptot2Pos()-sq(Xi.MomPosAlongV0()))");
589 
590  // The following energy formulas use 6 values:
591  formulate("Xi.eLambda()", "sqrt(Xi.Ptot2V0()+sq(mLambda))");
592  formulate("Xi.eK0Short()", "sqrt(Xi.Ptot2V0()+sq(mK0Short))");
593  formulate("Xi.ePosProton()", "sqrt(Xi.Ptot2Pos()+sq(mProton))");
594  formulate("Xi.eNegAntiProton()", "sqrt(Xi.Ptot2Neg()+sq(mAntiProton))");
595  formulate("Xi.ePosPion()", "sqrt(Xi.Ptot2Pos()+sq(mPiPlus))");
596  formulate("Xi.eNegPion()", "sqrt(Xi.Ptot2Neg()+sq(mPiMinus))");
597 
598  // The following mass formulas use 12 values:
599  formulate("Xi.massLambda()",
600  "sqrt(sq(Xi.ePosProton()+Xi.eNegPion())-Xi.Ptot2V0())");
601  formulate("Xi.massAntiLambda()",
602  "sqrt(sq(Xi.eNegAntiProton()+Xi.ePosPion())-Xi.Ptot2V0())");
603  formulate("Xi.massK0Short()",
604  "sqrt(sq(Xi.ePosPion()+Xi.eNegPion())-Xi.Ptot2V0())");
605 
606  // The following rapidity formulas use 8 values:
607  formulate("Xi.rapLambda()",
608  // "0.5*log((Xi.eLambda()+Xi.momV0Z())/(Xi.eLambda()-Xi.momV0Z()))");
609  // Can optimize for TTreeFormula:
610  "0.5*log(1.+(2./((Xi.eLambda()/Xi.momV0Z())-1.)))");
611  formulate("Xi.rapK0Short()",
612  // "0.5*log((Xi.eK0Short()+Xi.momV0Z())/(Xi.eK0Short()-Xi.momV0Z()))");
613  // Can optimize for TTreeFormula:
614  "0.5*log(1.+(2./((Xi.eK0Short()/Xi.momV0Z())-1.)))");
615 
616  // The following cTau formulas use 24 values:
617  formulate("Xi.cTauLambda()",
618  "Xi.massLambda()*Xi.decayLengthV0()/sqrt(Xi.Ptot2V0())");
619  formulate("Xi.cTauK0Short()",
620  "Xi.massK0Short()*Xi.decayLengthV0()/sqrt(Xi.Ptot2V0())");
621 
622  formulate("Xi.ptPos()", "sqrt(sq(Xi.mMomPosX)+sq(Xi.mMomPosY))");
623  formulate("Xi.ptotPos()", "sqrt(Xi.Ptot2Pos())");
624  formulate("Xi.ptNeg()", "sqrt(sq(Xi.mMomNegX)+sq(Xi.mMomNegY))");
625  formulate("Xi.ptotNeg()", "sqrt(Xi.Ptot2Neg())");
626  formulate("Xi.ptV0()", "sqrt(Xi.Pt2V0())");
627  formulate("Xi.ptotV0()", "sqrt(Xi.Ptot2V0())");
628  formulate("Xi.thetaV0()", "acos(Xi.momV0Z()/Xi.ptotV0())");
629  formulate("Xi.pseudoRapV0()", "-log(tan(Xi.thetaV0()/2.))");
630  formulate("Xi.psiV0()", "atan2(Xi.momV0Y(),Xi.momV0X())");
631 
632  // The following formulas use 1 value:
633  formulate("Xi.chi2V0()", "Xi.mChi2V0");
634  formulate("Xi.clV0()", "Xi.mClV0");
635  formulate("Xi.chi2Pos()", "Xi.mChi2Pos");
636  formulate("Xi.dedxPos()", "Xi.mDedxPos");
637  formulate("Xi.numDedxPos()", "Xi.mNumDedxPos");
638  formulate("Xi.clPos()", "Xi.mClPos");
639  formulate("Xi.chi2Neg()", "Xi.mChi2Neg");
640  formulate("Xi.clNeg()", "Xi.mClNeg");
641  formulate("Xi.dedxNeg()", "Xi.mDedxNeg");
642  formulate("Xi.numDedxNeg()", "Xi.mNumDedxNeg");
643 
644 
645  // Now, finally get to the unique Xi formulas:
646  // The following formula uses 6 values:
647  // A straight line approximation to the path...
648  formulate("Xi.decayLengthXi()",
649  "sqrt(sq(Xi.mDecayVertexXiX-Event.mPrimaryVertexX[0])+sq(Xi.mDecayVertexXiY-Event.mPrimaryVertexY[0])+sq(Xi.mDecayVertexXiZ-Event.mPrimaryVertexZ[0]))");
650 
651  // The following formulas use 1 value:
652  formulate("Xi.charge()", "Xi.mCharge");
653  formulate("Xi.decayVertexXiX()", "Xi.mDecayVertexXiX");
654  formulate("Xi.decayVertexXiY()", "Xi.mDecayVertexXiY");
655  formulate("Xi.decayVertexXiZ()", "Xi.mDecayVertexXiZ");
656  formulate("Xi.dcaXiDaughters()", "Xi.mDcaXiDaughters");
657  formulate("Xi.dcaXiToPrimVertex()", "Xi.mDcaXiToPrimVertex");
658  formulate("Xi.dcaBachelorToPrimVertex()", "Xi.mDcaBachelorToPrimVertex");
659  formulate("Xi.momBachelorX()", "Xi.mMomBachelorX");
660  formulate("Xi.momBachelorY()", "Xi.mMomBachelorY");
661  formulate("Xi.momBachelorZ()", "Xi.mMomBachelorZ");
662  formulate("Xi.momXiX()", "Xi.mMomBachelorX+Xi.momV0X()");
663  formulate("Xi.momXiY()", "Xi.mMomBachelorY+Xi.momV0Y()");
664  formulate("Xi.momXiZ()", "Xi.mMomBachelorZ+Xi.momV0Z()");
665  formulate("Xi.keyBachelor()", "Xi.mKeyBachelor");
666 
667  formulate("Xi.radt2Xi()", "sq(Xi.mDecayVertexXiX)+sq(Xi.mDecayVertexXiY)");
668  formulate("Xi.radtXi()", "sqrt(Xi.radt2Xi())");
669  formulate("Xi.radXi()", "sqrt(Xi.radt2Xi()+sq(Xi.mDecayVertexXiZ))");
670  formulate("Xi.phiXi()",
671  "atan2((Xi.mDecayVertexXiY-Event.mPrimaryVertexY[0]),(Xi.mDecayVertexXiX-Event.mPrimaryVertexX[0]))");
672 
673  formulate("Xi.Ptot2Bachelor()",
674  "(sq(Xi.mMomBachelorX)+sq(Xi.mMomBachelorY)+sq(Xi.mMomBachelorZ))");
675  formulate("Xi.Pt2Xi()", "(sq(Xi.momXiX())+sq(Xi.momXiY()))");
676  formulate("Xi.Ptot2Xi()", "(Xi.Pt2Xi()+sq(Xi.momXiZ()))");
677 
678  // The following momentum component formulas use 21 and 24 values:
679  formulate("Xi.MomBachelorAlongXi()",
680  "(((Xi.mMomBachelorX*Xi.momXiX())+(Xi.mMomBachelorY*Xi.momXiY())+(Xi.mMomBachelorZ*Xi.momXiZ()))/sqrt(Xi.Ptot2Xi()))");
681  formulate("Xi.MomV0AlongXi()",
682  "(((Xi.momV0X()*Xi.momXiX())+(Xi.momV0Y()*Xi.momXiY())+(Xi.momV0Z()*Xi.momXiZ()))/sqrt(Xi.Ptot2Xi()))");
683 
684  formulate("Xi.alphaXi()",
685  // "(Xi.mCharge*(Xi.MomBachelorAlongXi()-Xi.MomV0AlongXi())/(Xi.MomBachelorAlongXi()+Xi.MomV0AlongXi()))");
686  // The above is cumbersome, using 50 values. The following uses 30:
687  "Xi.mCharge*(1.-(2./(1.+(Xi.MomBachelorAlongXi()/Xi.MomV0AlongXi()))))");
688  // The following formula uses 30 values:
689  formulate("Xi.ptArmXi()",
690  "sqrt(Xi.Ptot2V0()-sq(Xi.MomV0AlongXi()))");
691 
692  // The following energy formulas use 9 values:
693  formulate("Xi.eXi()", "sqrt(Xi.Ptot2Xi()+sq(mXiMinus))");
694  formulate("Xi.eOmega()", "sqrt(Xi.Ptot2Xi()+sq(mOmegaMinus))");
695  formulate("Xi.eBachelorPion()", "sqrt(Xi.Ptot2Bachelor()+sq(mPiMinus))");
696  formulate("Xi.eBachelorKaon()", "sqrt(Xi.Ptot2Bachelor()+sq(mKaonMinus))");
697 
698  // The following mass formulas use 18 values:
699  formulate("Xi.massXi()",
700  "sqrt(sq(Xi.eLambda()+Xi.eBachelorPion())-Xi.Ptot2Xi())");
701  formulate("Xi.massOmega()",
702  "sqrt(sq(Xi.eLambda()+Xi.eBachelorKaon())-Xi.Ptot2Xi())");
703 
704  // The following rapidity formulas use 12 values:
705  formulate("Xi.rapXi()",
706  // "0.5*log((Xi.eXi()+Xi.momXiZ())/(Xi.eXi()-Xi.momXiZ()))");
707  // Can optimize for TTreeFormula:
708  "0.5*log(1.+(2./((Xi.eXi()/Xi.momXiZ())-1.)))");
709  formulate("Xi.rapOmega()",
710  // "0.5*log((Xi.eOmega()+Xi.momXiZ())/(Xi.eOmega()-Xi.momXiZ()))");
711  // Can optimize for TTreeFormula:
712  "0.5*log(1.+(2./((Xi.eOmega()/Xi.momXiZ())-1.)))");
713 
714  // The following cTau formulas use 33 values:
715  formulate("Xi.cTauXi()",
716  "Xi.massXi()*Xi.decayLengthXi()/sqrt(Xi.Ptot2Xi())");
717  formulate("Xi.cTauOmega()",
718  "Xi.massOmega()*Xi.decayLengthXi()/sqrt(Xi.Ptot2Xi())");
719 
720  formulate("Xi.ptBachelor()",
721  "sqrt(sq(Xi.mMomBachelorX)+sq(Xi.mMomBachelorY))");
722  formulate("Xi.ptotBachelor()", "sqrt(Xi.Ptot2Bachelor())");
723  formulate("Xi.ptXi()", "sqrt(Xi.Pt2Xi())");
724  formulate("Xi.ptotXi()", "sqrt(Xi.Ptot2Xi())");
725  formulate("Xi.thetaXi()", "acos(Xi.momXiZ()/Xi.ptotXi())");
726  formulate("Xi.pseudoRapXi()", "-log(tan(Xi.thetaXi()/2.))");
727  formulate("Xi.psiXi()", "atan2(Xi.momXiY(),Xi.momXiX())");
728 
729  // Track topology maps, with function names like
730  // "Xi.topologyMapNeg.*()", Xi.topologyMapPos.*(),
731  // and "Xi.topologyMapBachelor.*()"
732  if (tree->GetBranch("Xi.mTopologyMapBachelor.mMap0")) {
733  for (int k=0; k<3; k++) {
734  if (k==2) sprintf(track,"Bachelor\0");
735  else if (k==1) sprintf(track,"Neg\0");
736  else sprintf(track,"Pos\0");
737 
738 
739  // bit(i), i=0,63, uses only 1 value.
740  for (int l=0; l<2; l++) {
741  for (int j=0; j<32; j++) {
742  int m = l*32 + j;
743  sprintf(name,"Xi.topologyMap%s.bit(%d)\0",track,m);
744  sprintf(expr,"(Xi.mTopologyMap%s.mMap%d/(2^%d))&1\0",track,l,j);
745  formulate(name,expr);
746  }
747 
748  // data(i), i=0,1, uses only 1 value.
749  sprintf(name,"Xi.topologyMap%s.data(%d)",track,l);
750  sprintf(expr,"Xi.mTopologyMap%s.mMap%d",track,l);
751  formulate(name,expr);
752  }
753 
754  // ftpcFormat()
755  sprintf(ftpc,"Xi.topologyMap%s.ftpcFormat()",track);
756  sprintf(expr,"Xi.topologyMap%s.bit(63)",track);
757  formulate(ftpc,expr);
758 
759  // primaryVertexUsed()
760  sprintf(name,"Xi.topologyMap%s.primaryVertexUsed()",track);
761  sprintf(expr,"Xi.topologyMap%s.bit(0)",track);
762  formulate(name,expr);
763 
764  // turnAroundFlag()
765  sprintf(name,"Xi.topologyMap%s.turnAroundFlag()",track);
766  sprintf(expr,"Xi.topologyMap%s.bit(62)",track);
767  formulate(name,expr);
768 
769  // hasHitInSvtLayer(i), i=1,6
770  for (int j=1; j<7; j++) {
771  sprintf(name,"Xi.topologyMap%s.hasHitInSvtLayer(%d)",track,j);
772  sprintf(temp,"Xi.topologyMap%s.bit(%d)\0",track,j);
773  sprintf(expr,"(!%s)&&(%s)\0",ftpc,temp);
774  formulate(name,expr);
775 
776  tstr += temp;
777  if (j<6) tstr += "+";
778  }
779 
780  // numOfSvtHits(), uses 6 values
781  sprintf(name,"Xi.topologyMap%s.numOfSvtHits()\0",track);
782  sprintf(expr,"(!%s)*(%s)\0",ftpc,tstr.Data());
783  formulate(name,expr);
784  tstr = "";
785 
786  // hasHitInSSD()
787  sprintf(name,"Xi.topologyMap%s.hasHitInSSD()",track);
788  sprintf(expr,"Xi.topologyMap%s.bit(7)",track);
789  formulate(name,expr);
790 
791  sprintf(temp,"(!%s)*(\0",ftpc);
792  tstr = temp;
793 
794  // hasHitInTpcRow(i), i=0,44
795  for (int j=0; j<45; j++) {
796  sprintf(name,"Xi.topologyMap%s.hasHitInTpcRow(%d)",track,j);
797  int m = j+8;
798  sprintf(temp,"Xi.topologyMap%s.bit(%d)\0",track,m);
799  sprintf(expr,"(!%s)&&(%s)\0",ftpc,temp);
800  formulate(name,expr);
801 
802  tstr += temp;
803  if (j<44) tstr += "+";
804  }
805 
806  // numOfTpcHits(), uses 45 values.
807  sprintf(name,"Xi.topologyMap%s.numOfTpcHits()\0",track);
808  tstr += ")";
809  formulate(name,tstr.Data());
810  tstr = "";
811 
812  // hasHitInMwpc()
813  sprintf(name,"Xi.topologyMap%s.hasHitInMwpc()",track);
814  sprintf(expr,"Xi.topologyMap%s.bit(53)",track);
815  formulate(name,expr);
816 
817  // hasHitInCtb()
818  sprintf(name,"Xi.topologyMap%s.hasHitInCtb()",track);
819  sprintf(expr,"Xi.topologyMap%s.bit(54)",track);
820  formulate(name,expr);
821 
822  // hasHitInTofPatch()
823  sprintf(name,"Xi.topologyMap%s.hasHitInTofPatch()",track);
824  sprintf(expr,"Xi.topologyMap%s.bit(55)",track);
825  formulate(name,expr);
826 
827  // hasHitInRich()
828  sprintf(name,"Xi.topologyMap%s.hasHitInRich()",track);
829  sprintf(expr,"Xi.topologyMap%s.bit(56)",track);
830  formulate(name,expr);
831 
832  // hasHitInBarrelEmc()
833  sprintf(name,"Xi.topologyMap%s.hasHitInBarrelEmc()",track);
834  sprintf(expr,"Xi.topologyMap%s.bit(57)",track);
835  formulate(name,expr);
836 
837  // hasHitInEndcapEmc()
838  sprintf(name,"Xi.topologyMap%s.hasHitInEndcapEmc()",track);
839  sprintf(expr,"Xi.topologyMap%s.bit(58)",track);
840  formulate(name,expr);
841 
842  } } // End topology maps
843 
844  // The following formulas use 1 value:
845  formulate("Xi.chi2Xi()", "Xi.mChi2Xi");
846  formulate("Xi.clXi()", "Xi.mClXi");
847  formulate("Xi.chi2Bachelor()", "Xi.mChi2Bachelor");
848  formulate("Xi.clBachelor()", "Xi.mClBachelor");
849  formulate("Xi.dedxBachelor()", "Xi.mDedxBachelor");
850  formulate("Xi.numDedxBachelor()", "Xi.mNumDedxBachelor");
851 
852  } // End of Xi
853 
854  // XiMc
855  if (tree->GetBranch("XiMc")) {
856  printf("Loading XiMc formulas...\n");
857 
858  // The following formulas use 6 values:
859  formulate("XiMc.decayLengthXi()",
860  "sqrt(sq(XiMc.mPositionX-McEvent.mPrimaryVertexX[0])+sq(XiMc.mPositionY-McEvent.mPrimaryVertexY[0])+sq(XiMc.mPositionZ-McEvent.mPrimaryVertexZ[0]))");
861 
862  // The following formulas use 1 value:
863  formulate("XiMc.decayMode()", "XiMc.mDecayMode");
864  formulate("XiMc.commonTpcHits()", "XiMc.mCommonTpcHits");
865  formulate("XiMc.simTpcHits()", "XiMc.mSimTpcHits");
866  formulate("XiMc.geantIdParent()", "XiMc.mParentGeantId");
867  formulate("XiMc.geantIdDaughter()", "XiMc.mDaughterGeantId");
868  formulate("XiMc.parentMomentumX()", "XiMc.mParentMomentumX");
869  formulate("XiMc.parentMomentumY()", "XiMc.mParentMomentumY");
870  formulate("XiMc.parentMomentumZ()", "XiMc.mParentMomentumZ");
871  formulate("XiMc.daughterMomentumX()", "XiMc.mDaughterMomentumX");
872  formulate("XiMc.daughterMomentumY()", "XiMc.mDaughterMomentumY");
873  formulate("XiMc.daughterMomentumZ()", "XiMc.mDaughterMomentumZ");
874  formulate("XiMc.positionX()", "XiMc.mPositionX");
875  formulate("XiMc.positionY()", "XiMc.mPositionY");
876  formulate("XiMc.positionZ()", "XiMc.mPositionZ");
877 
878  } // End of XiMc
879 
880 
881  // Kink
882  if (tree->GetBranch("Kink")) {
883  printf("Loading Kink formulas...\n");
884 
885  } // End of Kink
886 
887  // KinkMc
888  if (tree->GetBranch("KinkMc")) {
889  printf("Loading KinkMc formulas...\n");
890 
891  // The following formulas use 1 value:
892  formulate("KinkMc.decayMode()", "KinkMc.mDecayMode");
893  formulate("KinkMc.commonTpcHits()", "KinkMc.mCommonTpcHits");
894  formulate("KinkMc.simTpcHits()", "KinkMc.mSimTpcHits");
895  formulate("KinkMc.geantIdParent()", "KinkMc.mParentGeantId");
896  formulate("KinkMc.geantIdDaughter()", "KinkMc.mDaughterGeantId");
897  formulate("KinkMc.parentMomentumX()", "KinkMc.mParentMomentumX");
898  formulate("KinkMc.parentMomentumY()", "KinkMc.mParentMomentumY");
899  formulate("KinkMc.parentMomentumZ()", "KinkMc.mParentMomentumZ");
900  formulate("KinkMc.daughterMomentumX()", "KinkMc.mDaughterMomentumX");
901  formulate("KinkMc.daughterMomentumY()", "KinkMc.mDaughterMomentumY");
902  formulate("KinkMc.daughterMomentumZ()", "KinkMc.mDaughterMomentumZ");
903  formulate("KinkMc.positionX()", "KinkMc.mPositionX");
904  formulate("KinkMc.positionY()", "KinkMc.mPositionY");
905  formulate("KinkMc.positionZ()", "KinkMc.mPositionZ");
906 
907  } // End of KinkMc
908 
909  Int_t finalFormulas = ListofFuncs->GetSize();
910  return (finalFormulas-initialFormulas);
911 
912 }
913 //______________________________________________________________________
914 // $Id: strangeFormulas.C,v 3.12 2008/03/05 15:47:25 genevb Exp $
915 // $Log: strangeFormulas.C,v $
916 // Revision 3.12 2008/03/05 15:47:25 genevb
917 // updated ROOT class for ListOfFunctions()
918 //
919 // Revision 3.11 2004/10/20 19:22:10 genevb
920 // Compatibility with small ROOT and CINT changes
921 //
922 // Revision 3.10 2004/04/12 19:50:06 genevb
923 // Allow use of list files
924 //
925 // Revision 3.9 2004/04/06 21:27:51 genevb
926 // Avoid PmdCollection branch
927 //
928 // Revision 3.8 2004/01/06 05:21:22 genevb
929 // Restore decay length functionality (was broken)
930 //
931 // Revision 3.7 2003/01/22 05:15:16 genevb
932 // Use TChain for multiple files
933 //
934 // Revision 3.6 2002/05/17 14:07:55 genevb
935 // Added some new event functions
936 //
937 // Revision 3.5 2002/04/30 01:29:18 genevb
938 // Updated macros for common micro DST
939 //
940 // Revision 3.4 2001/05/04 21:17:57 genevb
941 // Catch ROOT definition of TTreeFormula class, add McEvent branch
942 //
943 // Revision 3.3 2000/08/28 16:24:33 genevb
944 // Introduce findFormula(), handle executing on second tree
945 //
946 // Revision 3.2 2000/08/11 17:09:05 genevb
947 // Introduce findFormulas(), findDefinition(), and some new formulas.
948 //
949 // Revision 3.1 2000/08/10 01:21:10 genevb
950 // Added number of dedx points
951 //
952 // Revision 3.0 2000/07/17 22:08:11 genevb
953 // Updated for rev. 3, fixed bug in number of tpc hits
954 //
955 // Revision 2.0 2000/06/09 22:13:45 genevb
956 // Updated for version 2 of Strangeness mico DST package
957 //
958 // Revision 1.7 2000/04/19 15:11:15 genevb
959 // Streamlined adding TTreeFormulas
960 //
961 // Revision 1.6 2000/04/13 19:33:44 genevb
962 // Removed redundant formulas
963 //
964 // Revision 1.5 2000/04/13 18:30:26 genevb
965 // Better handling of backward compatibility
966 //
967 // Revision 1.4 2000/04/12 21:13:27 genevb
968 // Added track topology map functions
969 //
970 // Revision 1.3 2000/04/11 17:55:39 genevb
971 // Removed first parameter
972 //
973 // Revision 1.2 2000/04/07 16:22:48 genevb
974 // Remove ambiguity on supplying just one parameter
975 //
976 // Revision 1.1 2000/04/07 16:14:53 genevb
977 // Introduction of strangeFormulas.C
978 //