FairRoot/PandaRoot
PndParticleQATask.cxx
Go to the documentation of this file.
1 // ************************************************************************
2 //
3 // QA Task for single particles
4 //
5 // K.Goetzen 7/2013
6 // last change: K.Goetzen 3/2016
7 // ************************************************************************
8 
9 
10 // The header file
11 #include "PndParticleQATask.h"
12 
13 // C++ headers
14 
15 // FAIR headers
16 
17 // ROOT headers
18 #include "TString.h"
19 
20 // RHO headers
21 #include "RhoCandidate.h"
22 #include "RhoTuple.h"
23 
24 // Analysis headers
25 #include "PndAnalysis.h"
26 #include "PndRhoTupleQA.h"
27 
28 
29 using std::cout;
30 using std::endl;
31 
32 
33 // ----- Default constructor -------------------------------------------
34 PndParticleQATask::PndParticleQATask(bool fastsim, bool dumpchrg, bool dumpneut, bool dumpmc, int mode) :
35  FairTask("Panda Tutorial Analysis Task") {
36  fFastSim = fastsim;
37  fDumpChrg = dumpchrg;
38  fDumpNeut = dumpneut;
39  fDumpMc = dumpmc;
40  fMode = mode;
41  fPidArrayNames = "";
42 }
43 // -------------------------------------------------------------------------
44 
45 
46 // ----- Destructor ----------------------------------------------------
48 // -------------------------------------------------------------------------
49 
50 
51 // -------------------------------------------------------------------------
52 // ----- Split string according to delimiter delim
54 {
55  toks.clear();
56 
57  TObjArray *tok = s.Tokenize(delim);
58  int N = tok->GetEntries();
59 
60  for (int i=0;i<N;++i)
61  {
62  TString st = ((TObjString*)tok->At(i))->String();
63  st.ReplaceAll("\t","");
64  st = st.Strip(TString::kBoth);
65  if (st != "") toks.push_back(st);
66  }
67 
68  return toks.size();
69 }
70 
71 // -------------------------------------------------------------------------
72 // ----- Method to select true PID candidates
74 {
75  int removed = 0;
76 
77  for (int ii=l.GetLength()-1;ii>=0;--ii)
78  {
79  if ( !(ana->McTruthMatch(l[ii])) )
80  {
81  l.Remove(l[ii]);
82  removed++;
83  }
84  }
85 
86  return removed;
87 }
88 // -------------------------------------------------------------------------
89 
90 
91 // ----- Public method Init --------------------------------------------
93 {
94  // initialize analysis object
95  fAnalysis = new PndAnalysis();
96 
97  // reset the event counter
98  fEvtCount = 0;
99 
100  // if fPidArrayNames not set, set it to defaults
101  // The 'PID-units' are separated by ':', whereas the algo names within a unit are separated with ';'
102  // *** The first algo should be an ideal algo! If there is non, just put the first algo twice ***
103  if ("" == fPidArrayNames)
104  {
105  if (fFastSim)
106  {
107  fPidArrayNames = "IdealPidProbability : ScEmcPidBarrelProbability;ScEmcPidFwCapProbability;ScEmcPidBwCapProbability : DrcBarrelProbability:";
108  fPidArrayNames += "DrcDiscProbability : MvdPidProbability : ScMdtPidBarrelProbability;ScMdtPidForwardProbability : SttPidProbability : RichProbability";
109  }
110  else
111  {
112  fPidArrayNames = "PidAlgoIdealCharged : PidAlgoEmcBayes : PidAlgoDrc : PidAlgoDisc : PidAlgoMvd : PidAlgoMdtHardCuts : PidAlgoStt : PidAlgoRich : PidAlgoSciT : ";
113  //fPidArrayNames += "PidAlgoMdtPdf";
114  }
115  }
116 
117  fPidArrayNames.ReplaceAll(" ","");
118 
119  // Now cut the fPidArrayNames string into units(groups) of algos
120 
121  fPidList.clear();
122  int nalgos = SplitString(fPidArrayNames,":",fPidList);
123 
124  fPidArrayNames.Remove(0,fPidArrayNames.First(":")+1); // remove the first (ideal) algo
125  fPidArrayNames.ReplaceAll(":",";"); // turn string to a correct algo combination
126 
127 
128  for (int i=1;i<nalgos;++i)
129  {
130  TString nonalgo = fPidArrayNames;
131  nonalgo.ReplaceAll(fPidList[i],"");
132  nonalgo.ReplaceAll(";;",";");
133 
134  cout <<"[PndParticleQATask] Algo["<<i<<"] : "<<fPidList[i]<<" Non-Algo : "<<nonalgo<<endl;
135  fPidList.push_back(nonalgo);
136  }
137 
138  // we want also the combination of all algos, except the 0-th (being the ideal element)
139  fPidList.push_back(fPidArrayNames);
140 
141  // create ntuple
142  nmc = ntp = ntpn = 0;
143 
144  if (fDumpMc) nmc = new RhoTuple("nmc", "Particle QA MC truth");
145  if (fDumpChrg) ntp = new RhoTuple("ntp", "Particle QA charged");
146  if (fDumpNeut) ntpn = new RhoTuple("ntpn","Particle QA neutrals");
147 
148  return kSUCCESS;
149 }
150 
151 // -------------------------------------------------------------------------
152 
154 {
155  // Get run and runtime database
156  //FairRun* run = FairRun::Instance();
157  //if ( ! run ) Fatal("SetParContainers", "No analysis run");
158 }
159 
160 // -------------------------------------------------------------------------
161 
162 
163 // ----- Public method Exec --------------------------------------------
164 void PndParticleQATask::Exec(Option_t*)
165 {
166  // *** some variables
167  //int i=0,j=0, k=0, l=0;
168  int i=0,j=0;
169  TLorentzVector dummy;
170 
171  // necessary to read the next event
173 
174  if (!(++fEvtCount%100)) cout << "[PndParticleQATask] evt "<<fEvtCount<<endl;
175 
176  // *** RhoCandLists for the analysis
177  RhoCandList chrpid[50];
178 
179  //RhoCandList chr, chr1emc, chr2drc, chr3dsc, chr4mvd, chr5mdt, chr6stt, chr7rch, chr8chk, chr9idl;
180  //RhoCandList chr1nemc, chr2ndrc, chr3ndsc, chr4nmvd, chr5nmdt, chr6nstt, chr7nrch;
181  //RhoCandList chr16, chr126, chr1256, chr12356, chr1236, chr26, chr123456, chr1234567;
182  RhoCandList neut, mclist;
183 
184  PndRhoTupleQA qa(fAnalysis,15.0);
185 
186  // *** store MC truth info
187  if (fDumpMc)
188  {
189  fAnalysis->FillList(mclist, "McTruth");
190  nmc->Column("ev", (Int_t) fEvtCount);
191  qa.qaMcList("", mclist, nmc, 20);
192  nmc->DumpData();
193  }
194 
195  if (fDumpChrg)
196  {
197 
198  // *** Fill the lists with different pid algos
199  // *** the first element should contain the full combination exept element 0
200 
201  int nalgos = fPidList.size();
202  for (i=0;i<nalgos;++i)
203  fAnalysis->FillList(chrpid[i], "Charged", fPidList[i]);
204 
205 
206  int ntrk = chrpid[0].GetLength();
207 
208  TLorentzVector chrgP4=dummy;
209 
210  // *******************************
211  // *** Loop over CHARGED particles
212  // *******************************
213  for (j=0; j<ntrk; ++j)
214  {
215  RhoCandidate *truth = chrpid[0][j]->GetMcTruth();
216 
217  ntp->Column("mode", (Int_t) fMode, 0 );
218  ntp->Column("ev", (Int_t) fEvtCount, 0 );
219  ntp->Column("trk", (Int_t) j, 0 );
220  ntp->Column("ntrk", (Int_t) ntrk, 0 );
221  ntp->Column("chrg", (Float_t) chrpid[0][j]->Charge(), 0.0f );
222 
223  qa.qaP4( "", chrpid[0][j]->P4(), ntp);
224  qa.qaPull( "" , chrpid[0][j] , ntp);
225 
226  // all the pid stuff now
227  qa.qaPid("idl", chrpid[0][j], ntp);
228  qa.qaPid("", chrpid[nalgos-1][j], ntp);
229 
230  for (i=1; i<nalgos-1; ++i)
231  {
232  int nidx = (nalgos-2)/2;
233  int algidx = (i-1)%nidx;
234  TString algname = fPidList[algidx+1];
235 
236  //cout <<nalgos<<" "<<nidx<<" ";
237 
238  if (algname.Contains(";")) algname.Remove(algname.First(";"),1000);
239  algname.ReplaceAll("Pid","");
240  algname.ReplaceAll("Algo","");
241  algname.ReplaceAll("Probability","");
242  algname.ToLower();
243  algname=algname(0,10);
244 
245  TString smpname = Form("a%d",algidx);
246  if ((i-1)>=nidx)
247  {
248  smpname = "n" + smpname;
249  algname = "n" + algname;
250  }
251 
252  //cout <<i<<" idx:"<<algidx<<" "<<smpname<<" / "<<algname<<endl;
253 
254  qa.qaPid(smpname, chrpid[i][j], ntp);
255  qa.qaPid(algname, chrpid[i][j], ntp);
256  }
257 
258  qa.qaEmc( "", chrpid[0][j], ntp);
259  qa.qaMvd( "", chrpid[0][j], ntp);
260  qa.qaStt( "", chrpid[0][j], ntp);
261  qa.qaDrc( "", chrpid[0][j], ntp);
262  qa.qaDsc( "", chrpid[0][j], ntp);
263  qa.qaTof( "", chrpid[0][j], ntp);
264  qa.qaMuo( "", chrpid[0][j], ntp);
265  qa.qaTrk( "", chrpid[0][j], ntp);
266  qa.qaRich("", chrpid[0][j], ntp);
267 
268  float mct = 0.0;
269  float prim = 0.0;
270 
271  if (truth)
272  {
273  mct = 1.0;
274  RhoCandidate *moth = truth->TheMother();
275  if (!moth || abs(moth->PdgCode()-88850)<100 )
276  {
277  prim = 1.0;
278  chrgP4 = truth->P4();
279  }
280 
281  qa.qaP4( "tr", chrgP4, ntp);
282  ntp->Column("trpdg", (Float_t) truth->PdgCode(), 0.0f );
283  }
284  else
285  {
286  qa.qaP4( "tr", dummy, ntp, true);
287  ntp->Column("trpdg", (Float_t) 0., 0.0f );
288  }
289 
290  ntp->Column("prim", (Float_t) prim, 0.0f );
291  ntp->Column("mct", (Float_t) mct, 0.0f );
292 
293  ntp->DumpData();
294  }
295  }
296 
297  // *******************************
298  // *** Loop over NEUTRAL particles
299  // *******************************
300 
301  if (fDumpNeut)
302  {
303  // *** Select with no PID info ('All'); type and mass are set
304  fAnalysis->FillList( neut, "Neutral" );
305 
306  int ntrk = neut.GetLength();
307  for (j=0; j<ntrk; ++j)
308  {
309  RhoCandidate *truth = neut[j]->GetMcTruth();
310 
311  ntpn->Column("mode", (Int_t) fMode, 0 );
312  ntpn->Column("ev", (Int_t) fEvtCount, 0 );
313  ntpn->Column("trk", (Int_t) j, 0 );
314  ntpn->Column("ntrk", (Int_t) ntrk, 0 );
315  ntpn->Column("chrg", (Float_t) neut[j]->Charge(), 0.0f );
316 
317  qa.qaP4( "", neut[j]->P4(), ntpn);
318  qa.qaEmc( "", neut[j], ntpn);
319  //qa.qaP4( "primlv", chrgP4, ntpn);
320 
321  float mct = 0.0;
322  float prim = 0.0;
323 
324  if (truth)
325  {
326  mct = 1.0;
327  RhoCandidate *moth = truth->TheMother();
328  if (!moth || abs(moth->PdgCode()-88850)<100 ) prim = 1.0;
329  if (moth)
330  {
331  qa.qaP4( "moth", moth->P4(), ntpn);
332  ntpn->Column("mothpdg", (Float_t) moth->PdgCode(), -999.f);
333  }
334  else
335  {
336  qa.qaP4( "moth", dummy, ntpn, true);
337  ntpn->Column("mothpdg", (Float_t) -1., -999.f);
338  }
339 
340  qa.qaP4( "tr", truth->P4(), ntpn);
341  ntpn->Column("trpdg", (Float_t) truth->PdgCode(), 0.0f );
342  }
343  else
344  {
345  qa.qaP4( "moth", dummy, ntpn, true);
346  qa.qaP4( "tr", dummy, ntpn, true);
347  ntpn->Column("trpdg", (Float_t) 0., 0.0f );
348  ntpn->Column("mothpdg", (Float_t) -1, -999.f);
349  }
350 
351  ntpn->Column("prim", (Float_t) prim, 0.0f );
352  ntpn->Column("mct", (Float_t) mct, 0.0f );
353 
354  ntpn->DumpData();
355  }
356  }
357 }
358 
359 
361 {
362  if (fDumpMc) nmc->GetInternalTree()->Write();
363  if (fDumpChrg) ntp->GetInternalTree()->Write();
364  if (fDumpNeut) ntpn->GetInternalTree()->Write();
365 }
366 
368 
369  /*
370  if (fFastSim)
371  {
372  // KG 03/2016: Changed ordering like in FullSim (don't know why it was ordered differently by me beforehand...)
373 
374  fPid[1] = "ScEmcPidBarrelProbability;ScEmcPidFwCapProbability;ScEmcPidBwCapProbability";
375  fPid[2] = "DrcBarrelProbability";
376  fPid[3] = "DrcDiscProbability";
377  fPid[4] = "MvdPidProbability";
378  fPid[5] = "ScMdtPidBarrelProbability;ScMdtPidForwardProbability";
379  fPid[6] = "SttPidProbability";
380  fPid[7] = "RichProbability";
381 
382  fPid[9] = "IdealPidProbability";
383 
384  // total PID
385  fPid[0] = "PidChargedProbability";
386  // control: pid8 should be = pid0
387  fPid[8] = fPid[1];
388  for (int i=2;i<8;++i) fPid[8] += ";"+fPid[i];
389  }
390  else
391  {
392  // individual detectors/ algos
393  fPid[1] = "PidAlgoEmcBayes";
394  fPid[2] = "PidAlgoDrc";
395  fPid[3] = "PidAlgoDisc";
396  fPid[4] = "PidAlgoMvd";
397  fPid[5] = "PidAlgoMdtHardCuts";
398  fPid[6] = "PidAlgoStt";
399  fPid[7] = "PidAlgoIdealCharged"; // only 6 algos available in full sim
400 
401  fPid[9] = "PidAlgoIdealCharged";
402 
403  // total pid
404  fPid[0] = fPid[1];
405  for (int i=2;i<7;++i) fPid[0] += ";"+fPid[i];
406  fPid[8] = fPid[0];
407  }
408  */
409 
410 /*
411  // *** charged lists with different PID algo combinations
412  // *** the individual PID probs
413  if (fDumpChrg) fAnalysis->FillList( chr, "Charged" , fPid[0]); // total pid
414 
415 
416  fAnalysis->FillList( chr1emc, "Charged" , fPid[1]); // emc = algo 1
417  fAnalysis->FillList( chr2drc, "Charged" , fPid[2]); // drc = algo 2
418  fAnalysis->FillList( chr3dsc, "Charged" , fPid[3]); // dsc = algo 3
419  fAnalysis->FillList( chr4mvd, "Charged" , fPid[4]); // mvd = algo 4
420  fAnalysis->FillList( chr5mdt, "Charged" , fPid[5]); // mdt = algo 5
421  fAnalysis->FillList( chr6stt, "Charged" , fPid[6]); // stt = algo 6
422  if (fFastSim) fAnalysis->FillList( chr7rch, "Charged" , fPid[7]); // rich = algo 7
423 
424  fAnalysis->FillList( chr8chk, "Charged" , fPid[8]); // check for total PID (only useful for FastSim)
425  fAnalysis->FillList( chr9idl, "Charged" , fPid[9]); // idl = ideal PID
426 
427 
428 
429  // *** combinations without a certain PID algo
430  if (fFastSim)
431  {
432  fAnalysis->FillList( chr1nemc, "Charged" , fPid[2]+";"+fPid[3]+";"+fPid[4]+";"+fPid[5]+";"+fPid[6]+";"+fPid[7]); // w/o emc = no algo 1
433  fAnalysis->FillList( chr2ndrc, "Charged" , fPid[1]+";"+fPid[3]+";"+fPid[4]+";"+fPid[5]+";"+fPid[6]+";"+fPid[7]); // w/o drc = no algo 2
434  fAnalysis->FillList( chr3ndsc, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[4]+";"+fPid[5]+";"+fPid[6]+";"+fPid[7]); // w/o dsc = no algo 3
435  fAnalysis->FillList( chr4nmvd, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[5]+";"+fPid[6]+";"+fPid[7]); // w/o mvd = no algo 4
436  fAnalysis->FillList( chr5nmdt, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[4]+";"+fPid[6]+";"+fPid[7]); // w/o mdt = no algo 5
437  fAnalysis->FillList( chr6nstt, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[4]+";"+fPid[5]+";"+fPid[7]); // w/o stt = no algo 6
438  fAnalysis->FillList( chr7nrch, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[4]+";"+fPid[5]+";"+fPid[6]); // w/o rich = no algo 7
439  }
440  else
441  {
442  fAnalysis->FillList( chr1nemc, "Charged" , fPid[2]+";"+fPid[3]+";"+fPid[4]+";"+fPid[5]+";"+fPid[6]); // w/o emc = no algo 1
443  fAnalysis->FillList( chr2ndrc, "Charged" , fPid[1]+";"+fPid[3]+";"+fPid[4]+";"+fPid[5]+";"+fPid[6]); // w/o drc = no algo 2
444  fAnalysis->FillList( chr3ndsc, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[4]+";"+fPid[5]+";"+fPid[6]); // w/o dsc = no algo 3
445  fAnalysis->FillList( chr4nmvd, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[5]+";"+fPid[6]); // w/o mvd = no algo 4
446  fAnalysis->FillList( chr5nmdt, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[4]+";"+fPid[6]); // w/o mdt = no algo 5
447  fAnalysis->FillList( chr6nstt, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[4]+";"+fPid[5]); // w/o stt = no algo 6
448  }
449  */
450 
451  // now the combination of numbers define the algo-combination
452  //fAnalysis->FillList( chr16, "Charged" , fPid[1]+";"+fPid[6] );
453  //fAnalysis->FillList( chr126, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[6] );
454  //fAnalysis->FillList( chr1236, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[6] );
455  //fAnalysis->FillList( chr1256, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[5]+";"+fPid[6]);
456  //fAnalysis->FillList( chr12356, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[5]+";"+fPid[6]);
457  //fAnalysis->FillList( chr123456, "Charged" , fPid[1]+";"+fPid[2]+";"+fPid[3]+";"+fPid[4]+";"+fPid[5]+";"+fPid[6]);
458  //fAnalysis->FillList( chr26, "Charged" , fPid[2]+";"+fPid[6]);
459  //fAnalysis->FillList( chrmva, "Charged" ,"TMVABDTMvaProb");
460 
461 
462  /*
463  qa.qaPid( "pid", chr[j], ntp);
464 
465  qa.qaPid( "pid1", chr1emc[j], ntp);
466  qa.qaPid( "pid2", chr2drc[j], ntp);
467  qa.qaPid( "pid3", chr3dsc[j], ntp);
468  qa.qaPid( "pid4", chr4mvd[j], ntp);
469  qa.qaPid( "pid5", chr5mdt[j], ntp);
470  qa.qaPid( "pid6", chr6stt[j], ntp);
471  if (fFastSim)
472  qa.qaPid( "pid7", chr7rch[j], ntp);
473 
474  qa.qaPid( "pidchk", chr8chk[j], ntp);
475  qa.qaPid( "pidid", chr9idl[j], ntp);
476 
477  qa.qaPid( "pidn1", chr1nemc[j], ntp);
478  qa.qaPid( "pidn2", chr2ndrc[j], ntp);
479  qa.qaPid( "pidn3", chr3ndsc[j], ntp);
480  qa.qaPid( "pidn4", chr4nmvd[j], ntp);
481  qa.qaPid( "pidn5", chr5nmdt[j], ntp);
482  qa.qaPid( "pidn6", chr6nstt[j], ntp);
483  if (fFastSim)
484  qa.qaPid( "pidn7", chr7nrch[j], ntp);
485 
486  //qa.qaPid( "algmva", chrmva[j], ntp);
487 
488  //qa.qaPid( "pid16", chr16[j], ntp);
489  //qa.qaPid( "pid126", chr126[j], ntp);
490  //qa.qaPid( "pid1236", chr1236[j], ntp);
491  //qa.qaPid( "pid1256", chr1256[j], ntp);
492  //qa.qaPid( "pid12356", chr12356[j], ntp);
493  //qa.qaPid( "pid123456", chr123456[j], ntp);
494  //qa.qaPid( "pid26", chr26[j], ntp);
495 
496  qa.qaEmc( "", chr[j], ntp);
497  qa.qaMvd( "", chr[j], ntp);
498  qa.qaStt( "", chr[j], ntp);
499  qa.qaDrc( "", chr[j], ntp);
500  qa.qaDsc( "", chr[j], ntp);
501  qa.qaTof( "", chr[j], ntp);
502  qa.qaMuo( "", chr[j], ntp);
503  qa.qaTrk( "", chr[j], ntp);
504  */
CandList mclist
Int_t i
Definition: run_full.C:25
TLorentzVector s
Definition: Pnd2DStar.C:50
int SplitString(TString s, TString delim, StringList &toks)
Int_t GetLength() const
Definition: RhoCandList.h:46
void qaPid(TString pre, RhoCandidate *c, RhoTuple *n)
Bool_t FillList(RhoCandList &l, TString listkey="All", TString pidTcaNames="", int trackHypothesis=-1)
virtual void SetParContainers()
void qaTrk(TString pre, RhoCandidate *c, RhoTuple *n)
void qaStt(TString pre, RhoCandidate *c, RhoTuple *n)
void qaP4(TString pre, TLorentzVector c, RhoTuple *n, bool skip=false)
void qaRich(TString pre, RhoCandidate *c, RhoTuple *n)
void qaMcList(TString pre, RhoCandList &l, RhoTuple *n, int max=10000)
Int_t mode
Definition: autocutx.C:47
void GetEventInTask()
int SelectTruePid(PndAnalysis *ana, RhoCandList &l)
std::vector< TString > StringList
void qaDsc(TString pre, RhoCandidate *c, RhoTuple *n)
TFile * f
Definition: bump_analys.C:12
void qaMvd(TString pre, RhoCandidate *c, RhoTuple *n)
TLorentzVector P4() const
Definition: RhoCandidate.h:195
void Column(const char *label, Bool_t value, Bool_t defval=0, const char *block=0)
Definition: RhoTuple.cxx:56
Int_t Remove(RhoCandidate *)
PndParticleQATask(bool fastsim=false, bool dumpchrg=true, bool dumpneut=true, bool dumpmc=true, int mode=0)
void DumpData()
Definition: RhoTuple.cxx:391
void qaTof(TString pre, RhoCandidate *c, RhoTuple *n)
void qaEmc(TString pre, RhoCandidate *c, RhoTuple *n)
virtual void Exec(Option_t *opt)
ClassImp(PndAnaContFact)
virtual InitStatus Init()
TTree * GetInternalTree()
Definition: RhoTuple.h:207
Bool_t McTruthMatch(RhoCandidate *cand, Int_t level=2, bool verbose=false)
void qaDrc(TString pre, RhoCandidate *c, RhoTuple *n)
void qaPull(TString pre, RhoCandidate *c, RhoTuple *n, bool skip=false)
PndAnalysis * fAnalysis
void qaMuo(TString pre, RhoCandidate *c, RhoTuple *n)
const RhoCandidate * TheMother() const
Definition: RhoCandidate.h:272