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