]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliAnalysisTaskESDfilter.cxx
default setting for n sigma cut changed from TRUE to FALSE
[u/mrichter/AliRoot.git] / ANALYSIS / AliAnalysisTaskESDfilter.cxx
CommitLineData
96b85d73 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/* $Id: AliAnalysisTaskESDfilter.cxx 24535 2008-03-16 22:43:30Z fca $ */
17
18#include <TChain.h>
7b4cee8d 19#include <TTree.h>
ec6465fe 20#include <TList.h>
e6500713 21#include <TArrayI.h>
d7bdc804 22#include <TRandom.h>
da97a08a 23#include <TParticle.h>
96b85d73 24
25#include "AliAnalysisTaskESDfilter.h"
26#include "AliAnalysisManager.h"
27#include "AliESDEvent.h"
da97a08a 28#include "AliStack.h"
96b85d73 29#include "AliAODEvent.h"
da97a08a 30#include "AliMCEvent.h"
31#include "AliMCEventHandler.h"
96b85d73 32#include "AliESDInputHandler.h"
33#include "AliAODHandler.h"
da97a08a 34#include "AliAODMCParticle.h"
96b85d73 35#include "AliAnalysisFilter.h"
96b85d73 36#include "AliESDMuonTrack.h"
37#include "AliESDVertex.h"
38#include "AliESDv0.h"
39#include "AliESDkink.h"
40#include "AliESDcascade.h"
41#include "AliESDPmdTrack.h"
42#include "AliESDCaloCluster.h"
43#include "AliESDCaloCells.h"
44#include "AliMultiplicity.h"
45#include "AliLog.h"
46
47ClassImp(AliAnalysisTaskESDfilter)
48
49////////////////////////////////////////////////////////////////////////
50
51AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter():
52 AliAnalysisTaskSE(),
53 fTrackFilter(0x0),
54 fKinkFilter(0x0),
d7bdc804 55 fV0Filter(0x0),
56 fHighPthreshold(0),
980e4563 57 fPtshape(0x0)
96b85d73 58{
59 // Default constructor
60}
61
980e4563 62AliAnalysisTaskESDfilter::AliAnalysisTaskESDfilter(const char* name):
96b85d73 63 AliAnalysisTaskSE(name),
64 fTrackFilter(0x0),
65 fKinkFilter(0x0),
d7bdc804 66 fV0Filter(0x0),
67 fHighPthreshold(0),
980e4563 68 fPtshape(0x0)
96b85d73 69{
70 // Constructor
71}
72
73void AliAnalysisTaskESDfilter::UserCreateOutputObjects()
74{
75// Create the output container
76 OutputTree()->GetUserInfo()->Add(fTrackFilter);
77}
78
79void AliAnalysisTaskESDfilter::Init()
80{
81 // Initialization
82 if (fDebug > 1) AliInfo("Init() \n");
83 // Call configuration file
84}
85
86
87void AliAnalysisTaskESDfilter::UserExec(Option_t */*option*/)
88{
89// Execute analysis for current event
90//
91
92 Long64_t ientry = Entry();
2827d046 93 if (fDebug > 0) printf("Filter: Analysing event # %5d\n", (Int_t) ientry);
d7bdc804 94 if (fHighPthreshold == 0) AliInfo("detector PID signals are stored in each track");
95 if (!fPtshape) AliInfo("detector PID signals are not stored below the pt threshold");
da97a08a 96
96b85d73 97 ConvertESDtoAOD();
98}
99
100void AliAnalysisTaskESDfilter::ConvertESDtoAOD() {
101 // ESD Filter analysis task executed for each event
da97a08a 102
96b85d73 103 AliESDEvent* esd = dynamic_cast<AliESDEvent*>(InputEvent());
104 AliESD* old = esd->GetAliESDOld();
da97a08a 105
106 // Fetch Stack for debuggging if available
107 AliStack *pStack = 0;
108 AliMCEventHandler *mcH = 0;
109 if(MCEvent()){
110 pStack = MCEvent()->Stack();
111 mcH = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
112 }
96b85d73 113 // set arrays and pointers
114 Float_t posF[3];
115 Double_t pos[3];
116 Double_t p[3];
117 Double_t p_pos[3];
118 Double_t p_neg[3];
8d69965b 119 Double_t p_pos_atv0[3];
120 Double_t p_neg_atv0[3];
96b85d73 121 Double_t covVtx[6];
122 Double_t covTr[21];
123 Double_t pid[10];
124
125 for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
126 for (Int_t i = 0; i < 21; i++) covTr [i] = 0.;
127
128
da97a08a 129 // loop over events and fill them
130
131 // Multiplicity information needed by the header (to be revised!)
96b85d73 132 Int_t nTracks = esd->GetNumberOfTracks();
8d69965b 133 // if (fDebug > 0) printf("-------------------Bo: Number of ESD tracks %d \n",nTracks);
134
96b85d73 135 Int_t nPosTracks = 0;
3e492e99 136// for (Int_t iTrack = 0; iTrack < nTracks; ++iTrack)
137// if (esd->GetTrack(iTrack)->GetSign()> 0) nPosTracks++;
96b85d73 138
139 // Update the header
140
141 AliAODHeader* header = AODEvent()->GetHeader();
142 header->SetRunNumber(esd->GetRunNumber());
143 if (old) {
144 header->SetBunchCrossNumber(0);
145 header->SetOrbitNumber(0);
146 header->SetPeriodNumber(0);
147 header->SetEventType(0);
148 header->SetMuonMagFieldScale(-999.); // FIXME
149 header->SetCentrality(-999.); // FIXME
150 } else {
151 header->SetBunchCrossNumber(esd->GetBunchCrossNumber());
152 header->SetOrbitNumber(esd->GetOrbitNumber());
153 header->SetPeriodNumber(esd->GetPeriodNumber());
154 header->SetEventType(esd->GetEventType());
155 header->SetMuonMagFieldScale(-999.); // FIXME
156 header->SetCentrality(-999.); // FIXME
157 }
158
159 header->SetTriggerMask(esd->GetTriggerMask());
160 header->SetTriggerCluster(esd->GetTriggerCluster());
161 header->SetMagneticField(esd->GetMagneticField());
162 header->SetZDCN1Energy(esd->GetZDCN1Energy());
163 header->SetZDCP1Energy(esd->GetZDCP1Energy());
164 header->SetZDCN2Energy(esd->GetZDCN2Energy());
165 header->SetZDCP2Energy(esd->GetZDCP2Energy());
166 header->SetZDCEMEnergy(esd->GetZDCEMEnergy(0),esd->GetZDCEMEnergy(1));
613fc341 167 Float_t diamxy[2]={esd->GetDiamondX(),esd->GetDiamondY()};
168 Float_t diamcov[3]; esd->GetDiamondCovXY(diamcov);
169 header->SetDiamond(diamxy,diamcov);
96b85d73 170//
171//
172 Int_t nV0s = esd->GetNumberOfV0s();
173 Int_t nCascades = esd->GetNumberOfCascades();
174 Int_t nKinks = esd->GetNumberOfKinks();
175 Int_t nVertices = nV0s + 2*nCascades /*could lead to two vertices, one V0 and the Xi */+ nKinks + 1 /* = prim. vtx*/;
176 Int_t nJets = 0;
177 Int_t nCaloClus = esd->GetNumberOfCaloClusters();
178 Int_t nFmdClus = 0;
179 Int_t nPmdClus = esd->GetNumberOfPmdTracks();
180
2827d046 181 if (fDebug > 0)
182 printf(" NV0=%d NCASCADES=%d NKINKS=%d\n", nV0s, nCascades, nKinks);
96b85d73 183
184 AODEvent()->ResetStd(nTracks, nVertices, nV0s+nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
185
186 AliAODTrack *aodTrack = 0x0;
d7bdc804 187 AliAODPid *detpid = 0x0;
188 Double_t timezero = 0; //TO BE FIXED
7dd90a3c 189 AliAODv0 *aodV0 = 0x0;
190
d3fc6709 191 // RefArray to store the mapping between esd track number and newly created AOD-Track
192 TRefArray *aodRefs = NULL;
193 if (nTracks > 0) aodRefs = new TRefArray(nTracks);
8d69965b 194
96b85d73 195 // Array to take into account the tracks already added to the AOD
196 Bool_t * usedTrack = NULL;
197 if (nTracks>0) {
198 usedTrack = new Bool_t[nTracks];
199 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
200 }
201 // Array to take into account the V0s already added to the AOD
202 Bool_t * usedV0 = NULL;
203 if (nV0s>0) {
204 usedV0 = new Bool_t[nV0s];
205 for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
206 }
207 // Array to take into account the kinks already added to the AOD
208 Bool_t * usedKink = NULL;
209 if (nKinks>0) {
210 usedKink = new Bool_t[nKinks];
211 for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
212 }
213
214 // Access to the AOD container of vertices
215 TClonesArray &vertices = *(AODEvent()->GetVertices());
216 Int_t jVertices=0;
217
218 // Access to the AOD container of tracks
219 TClonesArray &tracks = *(AODEvent()->GetTracks());
220 Int_t jTracks=0;
221
222 // Access to the AOD container of V0s
223 TClonesArray &V0s = *(AODEvent()->GetV0s());
224 Int_t jV0s=0;
225
226 // Add primary vertex. The primary tracks will be defined
227 // after the loops on the composite objects (V0, cascades, kinks)
228 const AliESDVertex *vtx = esd->GetPrimaryVertex();
229
230 vtx->GetXYZ(pos); // position
231 vtx->GetCovMatrix(covVtx); //covariance matrix
232
233 AliAODVertex * primary = new(vertices[jVertices++])
c06d243f 234 AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
f7361742 235 primary->SetName(vtx->GetName());
236 primary->SetTitle(vtx->GetTitle());
237
2827d046 238 if (fDebug > 0) primary->Print();
96b85d73 239
240 // Create vertices starting from the most complex objects
241 Double_t chi2 = 0.;
242
243 // Cascades
244 for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
245 AliESDcascade *cascade = esd->GetCascade(nCascade);
246
247 cascade->GetXYZ(pos[0], pos[1], pos[2]);
248
249 if (!old) {
250 chi2 = cascade->GetChi2Xi(); // = chi2/NDF since NDF = 2*2-3
251 cascade->GetPosCovXi(covVtx);
252 } else {
253 chi2 = -999.;
254 for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
255 }
256 // Add the cascade vertex
257 AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
258 covVtx,
259 chi2,
260 primary,
261 nCascade,
262 AliAODVertex::kCascade);
263
264 primary->AddDaughter(vcascade);
265
266 // Add the V0 from the cascade. The ESD class have to be optimized...
267 // Now we have to search for the corresponding Vo in the list of V0s
268 // using the indeces of the positive and negative tracks
269
270 Int_t posFromV0 = cascade->GetPindex();
271 Int_t negFromV0 = cascade->GetNindex();
272
273
274 AliESDv0 * v0 = 0x0;
275 Int_t indV0 = -1;
276
277 for (Int_t iV0=0; iV0<nV0s; ++iV0) {
278
279 v0 = esd->GetV0(iV0);
280 Int_t posV0 = v0->GetPindex();
281 Int_t negV0 = v0->GetNindex();
282
283 if (posV0==posFromV0 && negV0==negFromV0) {
284 indV0 = iV0;
285 break;
286 }
287 }
288
289 AliAODVertex * vV0FromCascade = 0x0;
290
291 if (indV0>-1 && !usedV0[indV0] ) {
292
293 // the V0 exists in the array of V0s and is not used
294
295 usedV0[indV0] = kTRUE;
296
297 v0->GetXYZ(pos[0], pos[1], pos[2]);
298 if (!old) {
299 chi2 = v0->GetChi2V0(); // = chi2/NDF since NDF = 2*2-3
300 v0->GetPosCov(covVtx);
301 } else {
302 chi2 = -999.;
303 for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
304 }
305
306 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
307 covVtx,
308 chi2,
309 vcascade,
310 indV0,
311 AliAODVertex::kV0);
312 } else {
313
314 // the V0 doesn't exist in the array of V0s or was used
315// cerr << "Error: event " << esd->GetEventNumberInFile() << " cascade " << nCascade
316// << " The V0 " << indV0
317// << " doesn't exist in the array of V0s or was used!" << endl;
318
319 cascade->GetXYZ(pos[0], pos[1], pos[2]);
320
321 if (!old) {
322 chi2 = v0->GetChi2V0();
323 cascade->GetPosCov(covVtx);
324 } else {
325 chi2 = -999.;
326 for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
327 }
328
329 vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
330 covVtx,
331 chi2, // = chi2/NDF since NDF = 2*2-3 (AM)
332 vcascade,
333 indV0,
334 AliAODVertex::kV0);
335 vcascade->AddDaughter(vV0FromCascade);
336 }
337
338 // Add the positive tracks from the V0
339
340 if (posFromV0>-1 && !usedTrack[posFromV0]) {
341
342 usedTrack[posFromV0] = kTRUE;
343
344 AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
345 esdTrack->GetPxPyPz(p_pos);
346 esdTrack->GetXYZ(pos);
347 esdTrack->GetCovarianceXYZPxPyPz(covTr);
348 esdTrack->GetESDpid(pid);
fae68d32 349 UInt_t selectInfo = 0;
350 if (fTrackFilter) {
351 selectInfo = fTrackFilter->IsSelected(esdTrack);
352 }
96b85d73 353
da97a08a 354 if(mcH)mcH->SelectParticle(esdTrack->GetLabel());
96b85d73 355 vV0FromCascade->AddDaughter(aodTrack =
356 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
357 esdTrack->GetLabel(),
358 p_pos,
359 kTRUE,
360 pos,
361 kFALSE,
362 covTr,
363 (Short_t)esdTrack->GetSign(),
364 esdTrack->GetITSClusterMap(),
365 pid,
366 vV0FromCascade,
367 kTRUE, // check if this is right
f7361742 368 vtx->UsesTrack(esdTrack->GetID()),
3de26c63 369 AliAODTrack::kSecondary,
370 selectInfo)
371 );
d3fc6709 372 aodRefs->AddAt(aodTrack, posFromV0);
373
3e492e99 374 if (esdTrack->GetSign() > 0) nPosTracks++;
96b85d73 375 aodTrack->ConvertAliPIDtoAODPID();
4fcd837c 376 aodTrack->SetFlags(esdTrack->GetStatus());
d7bdc804 377 SetAODPID(esdTrack,aodTrack,detpid,timezero);
96b85d73 378 }
379 else {
380// cerr << "Error: event " << esd->GetEventNumberInFile() << " cascade " << nCascade
381// << " track " << posFromV0 << " has already been used!" << endl;
382 }
383
384 // Add the negative tracks from the V0
385
386 if (negFromV0>-1 && !usedTrack[negFromV0]) {
387
388 usedTrack[negFromV0] = kTRUE;
389
390 AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
391 esdTrack->GetPxPyPz(p_neg);
392 esdTrack->GetXYZ(pos);
393 esdTrack->GetCovarianceXYZPxPyPz(covTr);
394 esdTrack->GetESDpid(pid);
fae68d32 395 UInt_t selectInfo = 0;
396 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdTrack);
da97a08a 397 if(mcH)mcH->SelectParticle(esdTrack->GetLabel());
96b85d73 398 vV0FromCascade->AddDaughter(aodTrack =
399 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
400 esdTrack->GetLabel(),
401 p_neg,
402 kTRUE,
403 pos,
404 kFALSE,
405 covTr,
406 (Short_t)esdTrack->GetSign(),
407 esdTrack->GetITSClusterMap(),
408 pid,
409 vV0FromCascade,
410 kTRUE, // check if this is right
f7361742 411 vtx->UsesTrack(esdTrack->GetID()),
3de26c63 412 AliAODTrack::kSecondary,
413 selectInfo)
414 );
d3fc6709 415 aodRefs->AddAt(aodTrack, negFromV0);
3de26c63 416
3e492e99 417 if (esdTrack->GetSign() > 0) nPosTracks++;
96b85d73 418 aodTrack->ConvertAliPIDtoAODPID();
4fcd837c 419 aodTrack->SetFlags(esdTrack->GetStatus());
d7bdc804 420 SetAODPID(esdTrack,aodTrack,detpid,timezero);
96b85d73 421 }
422 else {
423// cerr << "Error: event " << esd->GetEventNumberInFile() << " cascade " << nCascade
424// << " track " << negFromV0 << " has already been used!" << endl;
425 }
426
427 // add it to the V0 array as well
428 Double_t d0[2] = { -999., -99.};
429 // counting is probably wrong
430 new(V0s[jV0s++]) AliAODv0(vV0FromCascade, -999., -99., p_pos, p_neg, d0); // to be refined
431
432 // Add the bachelor track from the cascade
433
434 Int_t bachelor = cascade->GetBindex();
435
436 if(bachelor>-1 && !usedTrack[bachelor]) {
437
438 usedTrack[bachelor] = kTRUE;
439
440 AliESDtrack *esdTrack = esd->GetTrack(bachelor);
441 esdTrack->GetPxPyPz(p);
442 esdTrack->GetXYZ(pos);
443 esdTrack->GetCovarianceXYZPxPyPz(covTr);
444 esdTrack->GetESDpid(pid);
fae68d32 445 UInt_t selectInfo = 0;
446 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdTrack);
da97a08a 447
448 if(mcH)mcH->SelectParticle(esdTrack->GetLabel());
96b85d73 449 vcascade->AddDaughter(aodTrack =
450 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
451 esdTrack->GetLabel(),
452 p,
453 kTRUE,
454 pos,
455 kFALSE,
456 covTr,
457 (Short_t)esdTrack->GetSign(),
458 esdTrack->GetITSClusterMap(),
459 pid,
460 vcascade,
461 kTRUE, // check if this is right
f7361742 462 vtx->UsesTrack(esdTrack->GetID()),
3de26c63 463 AliAODTrack::kSecondary,
464 selectInfo)
465 );
d3fc6709 466 aodRefs->AddAt(aodTrack, bachelor);
3e492e99 467 if (esdTrack->GetSign() > 0) nPosTracks++;
96b85d73 468 aodTrack->ConvertAliPIDtoAODPID();
4fcd837c 469 aodTrack->SetFlags(esdTrack->GetStatus());
d7bdc804 470 SetAODPID(esdTrack,aodTrack,detpid,timezero);
96b85d73 471 }
472 else {
473// cerr << "Error: event " << esd->GetEventNumberInFile() << " cascade " << nCascade
474// << " track " << bachelor << " has already been used!" << endl;
475 }
476
477 // Add the primary track of the cascade (if any)
478
479 } // end of the loop on cascades
ec6465fe 480
481 //
96b85d73 482 // V0s
ec6465fe 483 //
96b85d73 484
485 for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
486
7dd90a3c 487 if (usedV0[nV0]) continue; // skip if already added to the AOD
96b85d73 488
489 AliESDv0 *v0 = esd->GetV0(nV0);
ec6465fe 490 Int_t posFromV0 = v0->GetPindex();
491 Int_t negFromV0 = v0->GetNindex();
492 if (posFromV0 < 0 || negFromV0 < 0) continue;
493
494 // V0 selection
495 //
c12f1b16 496 AliESDVertex *esdVtx = new AliESDVertex(*(esd->GetPrimaryVertex()));
ec6465fe 497 AliESDtrack *esdV0Pos = esd->GetTrack(posFromV0);
498 AliESDtrack *esdV0Neg = esd->GetTrack(negFromV0);
c12f1b16 499 TList v0objects;
ec6465fe 500 v0objects.AddAt(v0, 0);
501 v0objects.AddAt(esdV0Pos, 1);
502 v0objects.AddAt(esdV0Neg, 2);
503 v0objects.AddAt(esdVtx, 3);
504 UInt_t selectV0 = 0;
505 if (fV0Filter) {
396d2b33 506 selectV0 = fV0Filter->IsSelected(&v0objects);
c12f1b16 507 // this is a little awkward but otherwise the
70186db5 508 // list wants to access the pointer (delete it)
509 // again when going out of scope
510 delete v0objects.RemoveAt(3); // esdVtx created via copy construct
511 esdVtx = 0;
396d2b33 512 if (!selectV0)
513 continue;
514 }
515 else{
70186db5 516 delete v0objects.RemoveAt(3); // esdVtx created via copy construct
517 esdVtx = 0;
ec6465fe 518 }
ec6465fe 519
96b85d73 520 v0->GetXYZ(pos[0], pos[1], pos[2]);
521
522 if (!old) {
523 chi2 = v0->GetChi2V0(); // = chi2/NDF since NDF = 2*2-3
524 v0->GetPosCov(covVtx);
525 } else {
526 chi2 = -999.;
527 for (Int_t i = 0; i < 6; i++) covVtx[i] = 0.;
528 }
529
530
531 AliAODVertex * vV0 =
532 new(vertices[jVertices++]) AliAODVertex(pos,
533 covVtx,
534 chi2,
535 primary,
536 nV0,
537 AliAODVertex::kV0);
538 primary->AddDaughter(vV0);
539
7dd90a3c 540
541 Float_t dcaPosToPrimVertexXYZ[2] = { 999., 999.}; // ..[0] = in XY plane and ..[1] = in Z
542 Float_t dcaNegToPrimVertexXYZ[2] = { 999., 999.}; // ..[0] = in XY plane and ..[1] = in Z
543 Double_t dcaDaughterToPrimVertex[2] = { 999., 999.}; // ..[0] = Pos and ..[1] = Neg
96b85d73 544
7dd90a3c 545 Double_t dcaV0Daughters = v0->GetDcaV0Daughters();
70186db5 546 Double_t dcaV0ToPrimVertex = v0->GetD(esd->GetPrimaryVertex()->GetX(),esd->GetPrimaryVertex()->GetY(),esd->GetPrimaryVertex()->GetZ());
8d69965b 547 v0->GetPPxPyPz(p_pos_atv0[0],p_pos_atv0[1],p_pos_atv0[2]);
548 v0->GetNPxPyPz(p_neg_atv0[0],p_neg_atv0[1],p_neg_atv0[2]);
7dd90a3c 549
96b85d73 550 // Add the positive tracks from the V0
551
ec6465fe 552
553 esdV0Pos->GetPxPyPz(p_pos);
554 esdV0Pos->GetXYZ(pos);
555 esdV0Pos->GetCovarianceXYZPxPyPz(covTr);
556 esdV0Pos->GetESDpid(pid);
557 esdV0Pos->GetImpactParameters(dcaPosToPrimVertexXYZ[0],dcaPosToPrimVertexXYZ[1]);
558 if (!usedTrack[posFromV0]) {
96b85d73 559 usedTrack[posFromV0] = kTRUE;
fae68d32 560 UInt_t selectInfo = 0;
ec6465fe 561 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdV0Pos);
da97a08a 562 if(mcH)mcH->SelectParticle(esdV0Pos->GetLabel());
ec6465fe 563 aodTrack = new(tracks[jTracks++]) AliAODTrack(esdV0Pos->GetID(),
564 esdV0Pos->GetLabel(),
8d69965b 565 p_pos,
566 kTRUE,
567 pos,
568 kFALSE,
569 covTr,
ec6465fe 570 (Short_t)esdV0Pos->GetSign(),
571 esdV0Pos->GetITSClusterMap(),
8d69965b 572 pid,
573 vV0,
574 kTRUE, // check if this is right
f7361742 575 vtx->UsesTrack(esdV0Pos->GetID()),
3de26c63 576 AliAODTrack::kSecondary,
577 selectInfo);
d3fc6709 578 aodRefs->AddAt(aodTrack,posFromV0);
8d69965b 579 // if (fDebug > 0) printf("-------------------Bo: pos track from original pt %.3f \n",aodTrack->Pt());
ec6465fe 580 if (esdV0Pos->GetSign() > 0) nPosTracks++;
96b85d73 581 aodTrack->ConvertAliPIDtoAODPID();
ec6465fe 582 aodTrack->SetFlags(esdV0Pos->GetStatus());
583 SetAODPID(esdV0Pos,aodTrack,detpid,timezero);
584 }
585 else {
d3fc6709 586 aodTrack = dynamic_cast<AliAODTrack*>(aodRefs->At(posFromV0));
8d69965b 587 // if (fDebug > 0) printf("-------------------Bo pos track from refArray pt %.3f \n",aodTrack->Pt());
96b85d73 588 }
ec6465fe 589 vV0->AddDaughter(aodTrack);
590
96b85d73 591 // Add the negative tracks from the V0
592
ec6465fe 593 esdV0Neg->GetPxPyPz(p_neg);
594 esdV0Neg->GetXYZ(pos);
595 esdV0Neg->GetCovarianceXYZPxPyPz(covTr);
596 esdV0Neg->GetESDpid(pid);
597 esdV0Neg->GetImpactParameters(dcaNegToPrimVertexXYZ[0],dcaNegToPrimVertexXYZ[1]);
598
599 if (!usedTrack[negFromV0]) {
96b85d73 600 usedTrack[negFromV0] = kTRUE;
fae68d32 601 UInt_t selectInfo = 0;
ec6465fe 602 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdV0Neg);
da97a08a 603 if(mcH)mcH->SelectParticle(esdV0Neg->GetLabel());
ec6465fe 604 aodTrack = new(tracks[jTracks++]) AliAODTrack(esdV0Neg->GetID(),
605 esdV0Neg->GetLabel(),
8d69965b 606 p_neg,
607 kTRUE,
608 pos,
609 kFALSE,
610 covTr,
ec6465fe 611 (Short_t)esdV0Neg->GetSign(),
612 esdV0Neg->GetITSClusterMap(),
8d69965b 613 pid,
614 vV0,
615 kTRUE, // check if this is right
f7361742 616 vtx->UsesTrack(esdV0Neg->GetID()),
3de26c63 617 AliAODTrack::kSecondary,
618 selectInfo);
ec6465fe 619
d3fc6709 620 aodRefs->AddAt(aodTrack,negFromV0);
8d69965b 621 // if (fDebug > 0) printf("-------------------Bo: neg track from original pt %.3f \n",aodTrack->Pt());
ec6465fe 622 if (esdV0Neg->GetSign() > 0) nPosTracks++;
96b85d73 623 aodTrack->ConvertAliPIDtoAODPID();
ec6465fe 624 aodTrack->SetFlags(esdV0Neg->GetStatus());
625 SetAODPID(esdV0Neg,aodTrack,detpid,timezero);
626 }
627 else {
d3fc6709 628 aodTrack = dynamic_cast<AliAODTrack*>(aodRefs->At(negFromV0));
8d69965b 629 // if (fDebug > 0) printf("-------------------Bo neg track from refArray pt %.3f \n",aodTrack->Pt());
96b85d73 630 }
ec6465fe 631 vV0->AddDaughter(aodTrack);
632 dcaDaughterToPrimVertex[0] =
633 TMath::Sqrt(dcaPosToPrimVertexXYZ[0]*dcaPosToPrimVertexXYZ[0]
634 +dcaPosToPrimVertexXYZ[1]*dcaPosToPrimVertexXYZ[1]);
7dd90a3c 635 dcaDaughterToPrimVertex[1] =
ec6465fe 636 TMath::Sqrt(dcaNegToPrimVertexXYZ[0]*dcaNegToPrimVertexXYZ[0]
637 +dcaNegToPrimVertexXYZ[1]*dcaNegToPrimVertexXYZ[1]);
96b85d73 638 // add it to the V0 array as well
7dd90a3c 639 aodV0 = new(V0s[jV0s++])
ec6465fe 640 AliAODv0(vV0, dcaV0Daughters, dcaV0ToPrimVertex, p_pos_atv0, p_neg_atv0, dcaDaughterToPrimVertex); // to be refined
7dd90a3c 641 // set the aod v0 on-the-fly status
642 aodV0->SetOnFlyStatus(v0->GetOnFlyStatus());
96b85d73 643 }
644 V0s.Expand(jV0s);
645 // end of the loop on V0s
646
647 // Kinks: it is a big mess the access to the information in the kinks
648 // The loop is on the tracks in order to find the mother and daugther of each kink
649
650
651 for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
652
653 AliESDtrack * esdTrack = esd->GetTrack(iTrack);
654
655 Int_t ikink = esdTrack->GetKinkIndex(0);
656
657 if (ikink && nKinks) {
658 // Negative kink index: mother, positive: daughter
659
660 // Search for the second track of the kink
661
662 for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
663
664 AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
665
666 Int_t jkink = esdTrack1->GetKinkIndex(0);
667
668 if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
669
670 // The two tracks are from the same kink
671
672 if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
673
674 Int_t imother = -1;
675 Int_t idaughter = -1;
676
677 if (ikink<0 && jkink>0) {
678
679 imother = iTrack;
680 idaughter = jTrack;
681 }
682 else if (ikink>0 && jkink<0) {
683
684 imother = jTrack;
685 idaughter = iTrack;
686 }
687 else {
688// cerr << "Error: Wrong combination of kink indexes: "
689// << ikink << " " << jkink << endl;
690 continue;
691 }
692
5dddb02b 693 // Add the mother track if it passed primary track selection cuts
96b85d73 694
695 AliAODTrack * mother = NULL;
696
fae68d32 697 UInt_t selectInfo = 0;
698 if (fTrackFilter) {
699 selectInfo = fTrackFilter->IsSelected(esd->GetTrack(imother));
700 if (!selectInfo) continue;
701 }
5dddb02b 702
96b85d73 703 if (!usedTrack[imother]) {
704
705 usedTrack[imother] = kTRUE;
706
03a5cc9f 707 AliESDtrack *esdTrackM = esd->GetTrack(imother);
708 esdTrackM->GetPxPyPz(p);
709 esdTrackM->GetXYZ(pos);
710 esdTrackM->GetCovarianceXYZPxPyPz(covTr);
711 esdTrackM->GetESDpid(pid);
da97a08a 712 if(mcH)mcH->SelectParticle(esdTrackM->GetLabel());
96b85d73 713 mother =
03a5cc9f 714 new(tracks[jTracks++]) AliAODTrack(esdTrackM->GetID(),
715 esdTrackM->GetLabel(),
96b85d73 716 p,
717 kTRUE,
718 pos,
719 kFALSE,
720 covTr,
03a5cc9f 721 (Short_t)esdTrackM->GetSign(),
722 esdTrackM->GetITSClusterMap(),
96b85d73 723 pid,
724 primary,
725 kTRUE, // check if this is right
f7361742 726 vtx->UsesTrack(esdTrack->GetID()),
3de26c63 727 AliAODTrack::kPrimary,
728 selectInfo);
d3fc6709 729 aodRefs->AddAt(mother, imother);
730
03a5cc9f 731 if (esdTrackM->GetSign() > 0) nPosTracks++;
732 mother->SetFlags(esdTrackM->GetStatus());
635ef56c 733 mother->ConvertAliPIDtoAODPID();
96b85d73 734 primary->AddDaughter(mother);
735 mother->ConvertAliPIDtoAODPID();
d7bdc804 736 SetAODPID(esdTrackM,mother,detpid,timezero);
96b85d73 737 }
738 else {
739// cerr << "Error: event " << esd->GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
740// << " track " << imother << " has already been used!" << endl;
741 }
742
743 // Add the kink vertex
744 AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
745
746 AliAODVertex * vkink =
747 new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
748 NULL,
749 0.,
750 mother,
751 esdTrack->GetID(), // This is the track ID of the mother's track!
752 AliAODVertex::kKink);
753 // Add the daughter track
754
755 AliAODTrack * daughter = NULL;
756
757 if (!usedTrack[idaughter]) {
758
759 usedTrack[idaughter] = kTRUE;
760
03a5cc9f 761 AliESDtrack *esdTrackD = esd->GetTrack(idaughter);
762 esdTrackD->GetPxPyPz(p);
763 esdTrackD->GetXYZ(pos);
764 esdTrackD->GetCovarianceXYZPxPyPz(covTr);
765 esdTrackD->GetESDpid(pid);
c12f1b16 766 selectInfo = 0;
fae68d32 767 if (fTrackFilter) selectInfo = fTrackFilter->IsSelected(esdTrackD);
da97a08a 768 if(mcH)mcH->SelectParticle(esdTrackD->GetLabel());
96b85d73 769 daughter =
03a5cc9f 770 new(tracks[jTracks++]) AliAODTrack(esdTrackD->GetID(),
771 esdTrackD->GetLabel(),
96b85d73 772 p,
773 kTRUE,
774 pos,
775 kFALSE,
776 covTr,
03a5cc9f 777 (Short_t)esdTrackD->GetSign(),
778 esdTrackD->GetITSClusterMap(),
96b85d73 779 pid,
780 vkink,
781 kTRUE, // check if this is right
f7361742 782 vtx->UsesTrack(esdTrack->GetID()),
3de26c63 783 AliAODTrack::kSecondary,
784 selectInfo);
d3fc6709 785
786 aodRefs->AddAt(daughter, idaughter);
787
03a5cc9f 788 if (esdTrackD->GetSign() > 0) nPosTracks++;
789 daughter->SetFlags(esdTrackD->GetStatus());
635ef56c 790 daughter->ConvertAliPIDtoAODPID();
96b85d73 791 vkink->AddDaughter(daughter);
792 daughter->ConvertAliPIDtoAODPID();
d7bdc804 793 SetAODPID(esdTrackD,daughter,detpid,timezero);
96b85d73 794 }
795 else {
796// cerr << "Error: event " << esd->GetEventNumberInFile() << " kink " << TMath::Abs(ikink)-1
797// << " track " << idaughter << " has already been used!" << endl;
798 }
799 }
800 }
801 }
802 }
803
804
805 // Tracks (primary and orphan)
806
3e492e99 807 if (fDebug > 0) printf("NUMBER OF ESD TRACKS %5d\n", nTracks);
96b85d73 808
809 for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
810
811
812 if (usedTrack[nTrack]) continue;
813
814 AliESDtrack *esdTrack = esd->GetTrack(nTrack);
815 UInt_t selectInfo = 0;
816 //
817 // Track selection
818 if (fTrackFilter) {
819 selectInfo = fTrackFilter->IsSelected(esdTrack);
f7361742 820 if (!selectInfo && !vtx->UsesTrack(esdTrack->GetID())) continue;
96b85d73 821 }
822
823 //
824 esdTrack->GetPxPyPz(p);
825 esdTrack->GetXYZ(pos);
826 esdTrack->GetCovarianceXYZPxPyPz(covTr);
827 esdTrack->GetESDpid(pid);
da97a08a 828 if(mcH)mcH->SelectParticle(esdTrack->GetLabel());
fae68d32 829 primary->AddDaughter(aodTrack =
830 new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
831 esdTrack->GetLabel(),
832 p,
833 kTRUE,
834 pos,
835 kFALSE,
836 covTr,
837 (Short_t)esdTrack->GetSign(),
838 esdTrack->GetITSClusterMap(),
839 pid,
840 primary,
841 kTRUE, // check if this is right
f7361742 842 vtx->UsesTrack(esdTrack->GetID()),
fae68d32 843 AliAODTrack::kPrimary,
844 selectInfo)
da97a08a 845 );
d3fc6709 846 aodRefs->AddAt(aodTrack, nTrack);
847
fae68d32 848 if (esdTrack->GetSign() > 0) nPosTracks++;
849 aodTrack->SetFlags(esdTrack->GetStatus());
850 aodTrack->ConvertAliPIDtoAODPID();
851 SetAODPID(esdTrack,aodTrack,detpid,timezero);
96b85d73 852 } // end of loop on tracks
853
3e492e99 854 // Update number of AOD tracks in header at the end of track loop (M.G.)
855 header->SetRefMultiplicity(jTracks);
856 header->SetRefMultiplicityPos(nPosTracks);
857 header->SetRefMultiplicityNeg(jTracks - nPosTracks);
858 if (fDebug > 0)
859 printf(" NAODTRACKS=%d NPOS=%d NNEG=%d\n", jTracks, nPosTracks, jTracks - nPosTracks);
860 // Do not shrink the array of tracks - other filters may add to it (M.G)
861// tracks.Expand(jTracks); // remove 'empty slots' due to unwritten tracks
96b85d73 862
863 // Access to the AOD container of PMD clusters
864 TClonesArray &pmdClusters = *(AODEvent()->GetPmdClusters());
865 Int_t jPmdClusters=0;
866
867 for (Int_t iPmd = 0; iPmd < nPmdClus; ++iPmd) {
868 // file pmd clusters, to be revised!
869 AliESDPmdTrack *pmdTrack = esd->GetPmdTrack(iPmd);
870 Int_t nLabel = 0;
871 Int_t *label = 0x0;
03a5cc9f 872 Double_t posPmd[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ()};
873 Double_t pidPmd[9] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // to be revised!
96b85d73 874 // type not set!
875 // assoc cluster not set
03a5cc9f 876 new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), posPmd, pidPmd);
96b85d73 877 }
878
879 // Access to the AOD container of clusters
880 TClonesArray &caloClusters = *(AODEvent()->GetCaloClusters());
881 Int_t jClusters=0;
882
883 for (Int_t iClust=0; iClust<nCaloClus; ++iClust) {
884
885 AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
886
e6500713 887 Int_t id = cluster->GetID();
888 Int_t nLabel = cluster->GetNLabels();
889 TArrayI* labels = cluster->GetLabels();
890 Int_t *label = 0;
da97a08a 891 if (labels){
892 label = (cluster->GetLabels())->GetArray();
893 for(int i = 0;i < labels->GetSize();++i){
894 if(mcH)mcH->SelectParticle(label[i]);
895 }
896 }
e6500713 897
96b85d73 898 Float_t energy = cluster->E();
899 cluster->GetPosition(posF);
e6500713 900 Char_t ttype = AliAODCluster::kUndef;
96b85d73 901
902 if (cluster->GetClusterType() == AliESDCaloCluster::kPHOSCluster) {
903 ttype=AliAODCluster::kPHOSNeutral;
904 }
905 else if (cluster->GetClusterType() == AliESDCaloCluster::kEMCALClusterv1) {
906 ttype = AliAODCluster::kEMCALClusterv1;
907 }
908
909
910 AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
911 nLabel,
912 label,
913 energy,
636555d2 914 posF,
96b85d73 915 NULL,
916 ttype);
917
e6500713 918 caloCluster->SetCaloCluster(cluster->GetDistanceToBadChannel(),
919 cluster->GetClusterDisp(),
78902954 920 cluster->GetM20(), cluster->GetM02(),
921 cluster->GetEmcCpvDistance(),
922 cluster->GetNExMax(),cluster->GetTOF()) ;
e6500713 923
3cbe9a4d 924 caloCluster->SetPIDFromESD(cluster->GetPid());
e6500713 925 caloCluster->SetNCells(cluster->GetNCells());
926 caloCluster->SetCellsAbsId(cluster->GetCellsAbsId());
927 caloCluster->SetCellsAmplitudeFraction(cluster->GetCellsAmplitudeFraction());
78902954 928
929 TArrayI* matchedT = cluster->GetTracksMatched();
cb234979 930 if (matchedT && cluster->GetTrackMatched() >= 0) {
78902954 931 for (Int_t im = 0; im < matchedT->GetSize(); im++) {
d3fc6709 932 Int_t iESDtrack = matchedT->At(im);;
933 if (aodRefs->At(iESDtrack) != 0) {
934 caloCluster->AddTrackMatched((AliAODTrack*)aodRefs->At(iESDtrack));
935 }
78902954 936 }
937 }
d3fc6709 938
96b85d73 939 }
940 caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters
941 // end of loop on calo clusters
942
943 // fill EMCAL cell info
944 if (esd->GetEMCALCells()) { // protection against missing ESD information
945 AliESDCaloCells &esdEMcells = *(esd->GetEMCALCells());
946 Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
947
948 AliAODCaloCells &aodEMcells = *(AODEvent()->GetEMCALCells());
949 aodEMcells.CreateContainer(nEMcell);
950 aodEMcells.SetType(AliAODCaloCells::kEMCAL);
951 for (Int_t iCell = 0; iCell < nEMcell; iCell++) {
952 aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell));
953 }
954 aodEMcells.Sort();
955 }
956
957 // fill PHOS cell info
958 if (esd->GetPHOSCells()) { // protection against missing ESD information
959 AliESDCaloCells &esdPHcells = *(esd->GetPHOSCells());
960 Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
961
962 AliAODCaloCells &aodPHcells = *(AODEvent()->GetPHOSCells());
963 aodPHcells.CreateContainer(nPHcell);
964 aodPHcells.SetType(AliAODCaloCells::kPHOS);
965 for (Int_t iCell = 0; iCell < nPHcell; iCell++) {
966 aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell));
967 }
968 aodPHcells.Sort();
969 }
970
971 // tracklets
972 AliAODTracklets &SPDTracklets = *(AODEvent()->GetTracklets());
973 const AliMultiplicity *mult = esd->GetMultiplicity();
974 if (mult) {
975 if (mult->GetNumberOfTracklets()>0) {
976 SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
977
978 for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
da97a08a 979 if(mcH){
980 mcH->SelectParticle(mult->GetLabel(n, 0));
981 mcH->SelectParticle(mult->GetLabel(n, 1));
982 }
983 SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n, 0),mult->GetLabel(n, 1));
96b85d73 984 }
985 }
986 } else {
987 //Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
988 }
989
990 delete [] usedTrack;
991 delete [] usedV0;
992 delete [] usedKink;
d3fc6709 993 delete aodRefs;
96b85d73 994
995 return;
996}
997
7b4cee8d 998
d7bdc804 999void AliAnalysisTaskESDfilter::SetAODPID(AliESDtrack *esdtrack, AliAODTrack *aodtrack, AliAODPid *detpid, Double_t timezero)
1000{
1001 //
1002 // Setter for the raw PID detector signals
1003 //
1004
1005 if(esdtrack->Pt()>fHighPthreshold) {
1006 detpid = new AliAODPid();
373fc041 1007 SetDetectorRawSignals(detpid,esdtrack,timezero);
d7bdc804 1008 aodtrack->SetDetPID(detpid);
1009 } else {
1010 if(fPtshape){
1011 if(esdtrack->Pt()> fPtshape->GetXmin()){
1012 Double_t y = fPtshape->Eval(esdtrack->Pt())/fPtshape->Eval(fHighPthreshold);
1013 if(gRandom->Rndm(0)<1./y){
1014 detpid = new AliAODPid();
373fc041 1015 SetDetectorRawSignals(detpid,esdtrack,timezero);
d7bdc804 1016 aodtrack->SetDetPID(detpid);
1017 }//end rndm
1018 }//end if p < pmin
1019 }//end if p function
1020 }// end else
1021}
1022
373fc041 1023void AliAnalysisTaskESDfilter::SetDetectorRawSignals(AliAODPid *aodpid, AliESDtrack *track, Double_t timezero)
1024{
1025//
1026//assignment of the detector signals (AliXXXesdPID inspired)
1027//
1028 if(!track){
1029 AliInfo("no ESD track found. .....exiting");
1030 return;
1031 }
1032
1033 aodpid->SetITSsignal(track->GetITSsignal());
1034 aodpid->SetTPCsignal(track->GetTPCsignal());
1035 //n TRD planes = 6
1036
1037 Int_t nslices = track->GetNumberOfTRDslices()*6;
1038 Double_t *trdslices = new Double_t[nslices];
1039 for(Int_t iSl =0; iSl < track->GetNumberOfTRDslices(); iSl++) {
1040 for(Int_t iPl =0; iPl<6; iPl++) trdslices[iPl*track->GetNumberOfTRDslices()+iSl] = track->GetTRDslice(iPl,iSl);
1041 }
d7bdc804 1042
373fc041 1043
1044 aodpid->SetTRDsignal(track->GetNumberOfTRDslices()*6,trdslices);
1045 Double_t times[AliAODPid::kSPECIES]; track->GetIntegratedTimes(times);
1046 aodpid->SetIntegratedTimes(times);
1047
1048 aodpid->SetTOFsignal(track->GetTOFsignal()-timezero); // to be fixed
1049 aodpid->SetHMPIDsignal(track->GetHMPIDsignal());
1050
1051}
7b4cee8d 1052
96b85d73 1053void AliAnalysisTaskESDfilter::Terminate(Option_t */*option*/)
1054{
1055// Terminate analysis
1056//
1057 if (fDebug > 1) printf("AnalysisESDfilter: Terminate() \n");
1058}
1059
da97a08a 1060void AliAnalysisTaskESDfilter::PrintMCInfo(AliStack *pStack,Int_t label){
1061 if(!pStack)return;
1062 label = TMath::Abs(label);
1063 TParticle *part = pStack->Particle(label);
1064 Printf("########################");
1065 Printf("%s:%d %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,label,part->GetUniqueID(),part->GetPdgCode(),part->P());
1066 part->Print();
1067 TParticle* mother = part;
1068 Int_t imo = part->GetFirstMother();
1069 Int_t nprim = pStack->GetNprimary();
1070 // while((imo >= nprim) && (mother->GetUniqueID() == 4)) {
1071 while((imo >= nprim)) {
1072 mother = pStack->Particle(imo);
1073 Printf("Mother %s:%d Label %d UniqueID %d PDG %d P %3.3f",(char*)__FILE__,__LINE__,imo,mother->GetUniqueID(),mother->GetPdgCode(),mother->P());
1074 mother->Print();
1075 imo = mother->GetFirstMother();
1076 }
1077 Printf("########################");
1078}