e52affa60f8ca23f9e0058ca0f7c66ce3db67202
[u/mrichter/AliRoot.git] / PWGGA / GammaConv / AliV0ReaderV1.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Authors: Svein Lindal, Daniel Lohner                                   *
5  * Version 1.0                                                            *
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 ////////////////////////////////////////////////
17 //---------------------------------------------
18 // Class reconstructing conversion photons from V0s
19 //---------------------------------------------
20 ////////////////////////////////////////////////
21
22 #include "AliV0ReaderV1.h"
23 #include "AliKFParticle.h"
24 #include "AliAODv0.h"
25 #include "AliESDv0.h"
26 #include "AliAODEvent.h"
27 #include "AliESDEvent.h"
28 #include "AliKFParticle.h"
29 #include "AliKFConversionPhoton.h"
30 #include "AliAODConversionPhoton.h"
31 #include "AliConversionPhotonBase.h"
32 #include "TVector.h"
33 #include "AliKFVertex.h"
34 #include "AliAODTrack.h"
35 #include "AliESDtrack.h"
36 #include "AliAnalysisManager.h"
37 #include "AliInputEventHandler.h"
38 #include "AliAODHandler.h"
39 #include "AliPIDResponse.h"
40 #include "TChain.h"
41 #include "AliStack.h"
42
43 class iostream;
44
45
46 using namespace std;
47
48 ClassImp(AliV0ReaderV1)
49
50 //________________________________________________________________________
51 AliV0ReaderV1::AliV0ReaderV1(const char *name) : AliAnalysisTaskSE(name),
52     fConversionCuts(NULL),
53     fConversionGammas(NULL),
54     fUseImprovedVertex(kTRUE),
55     fUseOwnXYZCalculation(kTRUE),
56     fUseConstructGamma(kFALSE),
57     kUseAODConversionPhoton(kTRUE),
58     fCreateAOD(kFALSE),
59     fDeltaAODBranchName("GammaConv"),
60     fDeltaAODFilename("AliAODGammaConversion.root"),
61     fEventIsSelected(kFALSE)
62 {
63     // Default constructor
64
65     DefineInput(0, TChain::Class());
66 }
67
68 //________________________________________________________________________
69 AliV0ReaderV1::~AliV0ReaderV1()
70 {
71     // default deconstructor
72
73     if(fConversionGammas){
74         fConversionGammas->Delete();// Clear Objects
75         delete fConversionGammas;
76         fConversionGammas=0x0;
77     }
78 }
79 /*
80 //________________________________________________________________________
81 AliV0ReaderV1::AliV0ReaderV1(AliV0ReaderV1 &original) : AliAnalysisTaskSE(original),
82     fConversionCuts(NULL),
83     fConversionGammas(NULL),
84     fUseImprovedVertex(original.fUseImprovedVertex),
85     fUseOwnXYZCalculation(original.fUseOwnXYZCalculation),
86     fUseConstructGamma(original.fUseConstructGamma),
87     kUseAODConversionPhoton(original.kUseAODConversionPhoton),
88     fCreateAOD(original.fCreateAOD),
89     fDeltaAODBranchName(original.fDeltaAODBranchName),
90     fDeltaAODFilename(original.fDeltaAODFilename),
91     fEventIsSelected(original.fEventIsSelected)
92 {
93     // Default constructor
94
95     DefineInput(0, TChain::Class());
96 }
97
98 //____________________________________________________________
99 AliV0ReaderV1 &AliV0ReaderV1::operator=(const AliV0ReaderV1 &ref){
100         //
101         // Assignment operator
102         // Only copies pointers, object is not the owner of the references
103         //
104     if(this != &ref){
105         AliAnalysisTaskSE::operator=(ref);
106         fUseImprovedVertex=ref.fUseImprovedVertex;
107         fUseOwnXYZCalculation=ref.fUseOwnXYZCalculation;
108         fUseConstructGamma=ref.fUseConstructGamma;
109         kUseAODConversionPhoton=ref.kUseAODConversionPhoton;
110         fCreateAOD=ref.fCreateAOD;
111         fDeltaAODBranchName=ref.fDeltaAODBranchName;
112         fDeltaAODFilename=ref.fDeltaAODFilename;
113         fEventIsSelected=ref.fEventIsSelected;
114     }
115     return *this;
116 }
117 */
118 //________________________________________________________________________
119 void AliV0ReaderV1::Init()
120 {
121     // Initialize function to be called once before analysis
122
123     if(fConversionCuts==NULL){
124         if(fConversionCuts==NULL)AliError("No Cut Selection initialized");
125     }
126
127     if(fCreateAOD){kUseAODConversionPhoton=kTRUE;}
128
129     if(fConversionGammas != NULL){
130         delete fConversionGammas;
131         fConversionGammas=NULL;
132     }
133
134     if(fConversionGammas == NULL){
135         if(kUseAODConversionPhoton){
136             fConversionGammas = new TClonesArray("AliAODConversionPhoton",100);}
137         else{
138             fConversionGammas = new TClonesArray("AliKFConversionPhoton",100);}
139     }
140     fConversionGammas->Delete();//Reset the TClonesArray
141
142 }
143
144 //________________________________________________________________________
145 void AliV0ReaderV1::UserCreateOutputObjects()
146 {
147     // Create AODs
148
149     if(fCreateAOD){
150         if(fConversionCuts){
151             fDeltaAODBranchName.Append("_");
152             fDeltaAODBranchName.Append(fConversionCuts->GetCutNumber());
153             fDeltaAODBranchName.Append("_gamma");
154         }
155         fConversionGammas->SetName(fDeltaAODBranchName.Data());
156
157         AddAODBranch("TClonesArray", &fConversionGammas, fDeltaAODFilename.Data());
158         AliAnalysisManager::GetAnalysisManager()->RegisterExtraFile(fDeltaAODFilename.Data());
159     }
160
161 }
162
163 //________________________________________________________________________
164 void AliV0ReaderV1::UserExec(Option_t *){
165
166     // Check if correctly initialized
167     if(!fConversionGammas)Init();
168
169     // User Exec
170     fEventIsSelected=ProcessEvent(fInputEvent,fMCEvent);
171 }
172
173 //________________________________________________________________________
174 Bool_t AliV0ReaderV1::ProcessEvent(AliVEvent *inputEvent,AliMCEvent *mcEvent)
175 {
176     //Reset the TClonesArray
177     fConversionGammas->Delete();
178
179     fInputEvent=inputEvent;
180     fMCEvent=mcEvent;
181
182     if(!fInputEvent){
183         AliError("No Input event");
184         return kFALSE;
185     }
186
187     if(!fConversionCuts){AliError("No ConversionCuts");return kFALSE;}
188
189     // Event Cuts
190     if(!fConversionCuts->EventIsSelected(fInputEvent,fMCEvent))return kFALSE;
191
192     // Set Magnetic Field
193     AliKFParticle::SetField(fInputEvent->GetMagneticField());
194
195     if(fInputEvent->IsA()==AliESDEvent::Class()){
196         ProcessESDV0s();
197     }
198     if(fInputEvent->IsA()==AliAODEvent::Class()){
199         GetAODConversionGammas();
200     }
201
202     // AOD Output
203     FillAODOutput();
204
205     return kTRUE;
206 }
207 ///________________________________________________________________________
208 void AliV0ReaderV1::FillAODOutput()
209 {
210     // Fill AOD Output with reconstructed Photons
211
212     if(fInputEvent->IsA()==AliESDEvent::Class()){
213         ///Make sure delta aod is filled if standard aod is filled (for synchronization when reading aod with standard aod)
214         if(fCreateAOD) {
215             AliAODHandler * aodhandler = dynamic_cast<AliAODHandler*>(AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler());
216             if (aodhandler && aodhandler->GetFillAOD()) {
217                AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillExtension(kTRUE);
218               //PostData(0, fConversionGammas);
219
220             }
221         }
222     }
223 }
224
225 ///________________________________________________________________________
226 const AliExternalTrackParam *AliV0ReaderV1::GetExternalTrackParam(AliESDv0 *fCurrentV0,Int_t &tracklabel,Int_t charge){
227
228     // Get External Track Parameter with given charge
229
230     if(!(charge==1||charge==-1)){AliError("Charge not defined");return 0x0;}
231
232     // Check for sign flip
233     if(fCurrentV0){
234         if(!fCurrentV0->GetParamN()||!fCurrentV0->GetParamP())return 0x0;
235         if(!fConversionCuts->GetTrack(fInputEvent,fCurrentV0->GetNindex())||!fConversionCuts->GetTrack(fInputEvent,fCurrentV0->GetPindex()))return 0x0;
236         if((fConversionCuts->GetTrack(fInputEvent,fCurrentV0->GetPindex()))->Charge()==charge){
237             tracklabel=fCurrentV0->GetPindex();
238             return fCurrentV0->GetParamP();}
239         if((fConversionCuts->GetTrack(fInputEvent,fCurrentV0->GetNindex()))->Charge()==charge){
240             tracklabel=fCurrentV0->GetNindex();
241             return fCurrentV0->GetParamN();}
242     }
243     return 0x0;
244 }
245
246 ///________________________________________________________________________
247 Bool_t AliV0ReaderV1::ProcessESDV0s()
248 {
249     // Process ESD V0s for conversion photon reconstruction
250
251     AliESDEvent *fESDEvent=dynamic_cast<AliESDEvent*>(fInputEvent);
252
253     AliKFConversionPhoton *fCurrentMotherKFCandidate=NULL;
254
255     if(fESDEvent){
256
257         for(Int_t currentV0Index=0;currentV0Index<fESDEvent->GetNumberOfV0s();currentV0Index++){
258             AliESDv0 *fCurrentV0=(AliESDv0*)(fESDEvent->GetV0(currentV0Index));
259             if(!fCurrentV0){
260                 printf("Requested V0 does not exist");
261                 continue;}
262
263             fCurrentMotherKFCandidate=ReconstructV0(fCurrentV0,currentV0Index);
264
265             if(fCurrentMotherKFCandidate){
266
267                 // Add Gamma to the TClonesArray
268
269                 if(kUseAODConversionPhoton){
270                     new((*fConversionGammas)[fConversionGammas->GetEntriesFast()]) AliAODConversionPhoton(fCurrentMotherKFCandidate);
271                 }
272                 else{
273                     new((*fConversionGammas)[fConversionGammas->GetEntriesFast()]) AliKFConversionPhoton(*fCurrentMotherKFCandidate);
274                 }
275
276                 delete fCurrentMotherKFCandidate;
277                 fCurrentMotherKFCandidate=NULL;
278             }
279         }
280     }
281     return kTRUE;
282 }
283
284 ///________________________________________________________________________
285 AliKFConversionPhoton *AliV0ReaderV1::ReconstructV0(AliESDv0 *fCurrentV0,Int_t currentV0Index)
286 {
287         // Reconstruct conversion photon from ESD v0
288     fConversionCuts->FillPhotonCutIndex(AliConversionCuts::kPhotonIn);
289
290     //checks if on the fly mode is set
291     if(!fConversionCuts->SelectV0Finder(fCurrentV0->GetOnFlyStatus())){
292        fConversionCuts->FillPhotonCutIndex(AliConversionCuts::kOnFly);
293        return 0x0;
294     }
295
296     // TrackLabels
297     Int_t currentTrackLabels[2]={-1,-1};
298
299     // Get Daughter KF Particles
300
301     const AliExternalTrackParam *fCurrentExternalTrackParamPositive=GetExternalTrackParamP(fCurrentV0,currentTrackLabels[0]);
302     const AliExternalTrackParam *fCurrentExternalTrackParamNegative=GetExternalTrackParamN(fCurrentV0,currentTrackLabels[1]);
303
304     if(!fCurrentExternalTrackParamPositive||!fCurrentExternalTrackParamNegative)return 0x0;
305
306     // Apply some Cuts before Reconstruction
307
308     AliVTrack * posTrack = fConversionCuts->GetTrack(fInputEvent,currentTrackLabels[0]);
309     AliVTrack * negTrack = fConversionCuts->GetTrack(fInputEvent,currentTrackLabels[1]);
310
311     if(!negTrack || !posTrack) {
312        fConversionCuts->FillPhotonCutIndex(AliConversionCuts::kNoTracks);
313        return 0x0;
314     }
315
316     // Track Cuts
317     if(!fConversionCuts->TracksAreSelected(negTrack, posTrack)){
318        fConversionCuts->FillPhotonCutIndex(AliConversionCuts::kTrackCuts);
319        return 0x0;
320     }
321
322     // PID Cuts
323     if(!fConversionCuts->dEdxCuts(negTrack) || !fConversionCuts->dEdxCuts(posTrack)) {
324        fConversionCuts->FillPhotonCutIndex(AliConversionCuts::kdEdxCuts);
325        return 0x0;
326     }
327
328     // Reconstruct Photon
329
330     AliKFConversionPhoton *fCurrentMotherKF=NULL;
331
332     AliKFParticle fCurrentNegativeKFParticle(*(fCurrentExternalTrackParamNegative),11);
333     AliKFParticle fCurrentPositiveKFParticle(*(fCurrentExternalTrackParamPositive),-11);
334
335     // Reconstruct Gamma
336
337     if(fUseConstructGamma){
338         fCurrentMotherKF = new AliKFConversionPhoton();
339         fCurrentMotherKF->ConstructGamma(fCurrentNegativeKFParticle,fCurrentPositiveKFParticle);
340     }else{
341         fCurrentMotherKF = new AliKFConversionPhoton(fCurrentNegativeKFParticle,fCurrentPositiveKFParticle);
342         fCurrentMotherKF->SetMassConstraint(0,0);
343     }
344
345     // Set Track Labels
346
347     fCurrentMotherKF->SetTrackLabels(currentTrackLabels[0],currentTrackLabels[1]);
348
349     // Set V0 index
350
351     fCurrentMotherKF->SetV0Index(currentV0Index);
352
353     //Set MC Label
354
355     if(fMCEvent){
356
357         AliStack *fMCStack= fMCEvent->Stack();
358
359         Int_t labelp=TMath::Abs(fConversionCuts->GetTrack(fInputEvent,fCurrentMotherKF->GetTrackLabelPositive())->GetLabel());
360         Int_t labeln=TMath::Abs(fConversionCuts->GetTrack(fInputEvent,fCurrentMotherKF->GetTrackLabelNegative())->GetLabel());
361
362         TParticle *fNegativeMCParticle = fMCStack->Particle(labeln);
363         TParticle *fPositiveMCParticle = fMCStack->Particle(labelp);
364
365         if(fPositiveMCParticle&&fNegativeMCParticle){
366             fCurrentMotherKF->SetMCLabelPositive(labelp);
367             fCurrentMotherKF->SetMCLabelNegative(labeln);
368         }
369     }
370
371     // Update Vertex (moved for same eta compared to old)
372     if(fUseImprovedVertex == kTRUE){
373        AliKFVertex primaryVertexImproved(*fInputEvent->GetPrimaryVertex());
374        primaryVertexImproved+=*fCurrentMotherKF;
375        fCurrentMotherKF->SetProductionVertex(primaryVertexImproved);
376     }
377
378     // SetPsiPair
379
380     Double_t PsiPair=GetPsiPair(fCurrentV0,fCurrentExternalTrackParamPositive,fCurrentExternalTrackParamNegative);
381     fCurrentMotherKF->SetPsiPair(PsiPair);
382
383
384     // Recalculate ConversionPoint
385     Double_t dca[2]={0,0};
386     if(fUseOwnXYZCalculation){
387         Double_t convpos[3]={0,0,0};
388         if(!GetConversionPoint(fCurrentExternalTrackParamPositive,fCurrentExternalTrackParamNegative,convpos,dca)){
389            fConversionCuts->FillPhotonCutIndex(AliConversionCuts::kConvPointFail);
390            delete fCurrentMotherKF;
391            fCurrentMotherKF=NULL;
392            return 0x0;
393         }
394
395         fCurrentMotherKF->SetConversionPoint(convpos);
396     }
397
398     if(fCurrentMotherKF->GetNDF() > 0.)
399         fCurrentMotherKF->SetChi2perNDF(fCurrentMotherKF->GetChi2()/fCurrentMotherKF->GetNDF());   //->Photon is created before all chi2 relevant changes are performed, set it "by hand"
400
401
402     // Set Dilepton Mass (moved down for same eta compared to old)
403     fCurrentMotherKF->SetMass(fCurrentMotherKF->M());
404
405     // Apply Photon Cuts
406
407     if(!fConversionCuts->PhotonCuts(fCurrentMotherKF,fInputEvent)){
408         fConversionCuts->FillPhotonCutIndex(AliConversionCuts::kPhotonCuts);
409         delete fCurrentMotherKF;
410         fCurrentMotherKF=NULL;
411         return 0x0;
412     }
413
414     fConversionCuts->FillPhotonCutIndex(AliConversionCuts::kPhotonOut);
415     return fCurrentMotherKF;
416 }
417
418 ///________________________________________________________________________
419 Double_t AliV0ReaderV1::GetPsiPair(const AliESDv0* v0, const AliExternalTrackParam *positiveparam,const AliExternalTrackParam *negativeparam) const {
420     //
421     // Angle between daughter momentum plane and plane
422     //
423
424     AliExternalTrackParam nt(*negativeparam);
425     AliExternalTrackParam pt(*positiveparam);
426
427    Float_t magField = fInputEvent->GetMagneticField();
428
429    Double_t xyz[3] = {0.,0.,0.};
430    v0->GetXYZ(xyz[0],xyz[1],xyz[2]);
431
432    Double_t mn[3] = {0,0,0};
433    Double_t mp[3] = {0,0,0};
434
435    v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
436    v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
437
438    Double_t deltat = 1.;
439    deltat = TMath::ATan(mp[2]/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1])+1.e-13)) -  TMath::ATan(mn[2]/(TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1])+1.e-13));//difference of angles of the two daughter tracks with z-axis
440    Double_t radiussum = TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]) + 50;//radius to which tracks shall be propagated
441
442    Double_t momPosProp[3] = {0,0,0};
443    Double_t momNegProp[3] = {0,0,0};
444
445    Double_t psiPair = 4.;
446    if(nt.PropagateTo(radiussum,magField) == 0) return psiPair; //propagate tracks to the outside -> Better Purity and Efficiency
447
448    if(pt.PropagateTo(radiussum,magField) == 0) return psiPair; //propagate tracks to the outside -> Better Purity and Efficiency
449
450    pt.GetPxPyPz(momPosProp);//Get momentum vectors of tracks after propagation
451    nt.GetPxPyPz(momNegProp);
452
453    Double_t pEle =
454        TMath::Sqrt(momNegProp[0]*momNegProp[0]+momNegProp[1]*momNegProp[1]+momNegProp[2]*momNegProp[2]);//absolute momentum value of negative daughter
455
456    Double_t pPos =
457        TMath::Sqrt(momPosProp[0]*momPosProp[0]+momPosProp[1]*momPosProp[1]+momPosProp[2]*momPosProp[2]);//absolute momentum value of positive daughter
458
459    Double_t scalarproduct =
460        momPosProp[0]*momNegProp[0]+momPosProp[1]*momNegProp[1]+momPosProp[2]*momNegProp[2];//scalar product of propagated positive and negative daughters' momenta
461
462    Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));//Angle between propagated daughter tracks
463
464    psiPair =  TMath::Abs(TMath::ASin(deltat/chipair));
465
466    return psiPair;
467 }
468
469 ///________________________________________________________________________
470 Bool_t AliV0ReaderV1::GetHelixCenter(const AliExternalTrackParam *track,Double_t center[2]){
471
472     // Get Center of the helix track parametrization
473
474     Int_t charge=track->Charge();
475     Double_t b=fInputEvent->GetMagneticField();
476
477     Double_t    helix[6];
478     track->GetHelixParameters(helix,b);
479
480     Double_t xpos =     helix[5];
481     Double_t ypos =     helix[0];
482     Double_t radius = TMath::Abs(1./helix[4]);
483     Double_t phi = helix[2];
484
485     if(phi < 0){
486         phi = phi + 2*TMath::Pi();
487     }
488
489     phi -= TMath::Pi()/2.;
490     Double_t xpoint =   radius * TMath::Cos(phi);
491     Double_t ypoint =   radius * TMath::Sin(phi);
492
493     if(b<0){
494         if(charge > 0){
495             xpoint = - xpoint;
496             ypoint = - ypoint;
497         }
498
499         if(charge < 0){
500             xpoint =    xpoint;
501             ypoint =    ypoint;
502         }
503     }
504     if(b>0){
505         if(charge > 0){
506             xpoint =    xpoint;
507             ypoint =    ypoint;
508         }
509
510         if(charge < 0){
511             xpoint = - xpoint;
512             ypoint = - ypoint;
513         }
514     }
515     center[0] = xpos + xpoint;
516     center[1] = ypos + ypoint;
517
518     return 1;
519 }
520 ///________________________________________________________________________
521 Bool_t AliV0ReaderV1::GetConversionPoint(const AliExternalTrackParam *pparam,const AliExternalTrackParam *nparam,Double_t convpos[3],Double_t dca[2]){
522
523     // Recalculate Conversion Point
524
525     if(!pparam||!nparam)return kFALSE;
526
527     Double_t helixcenterpos[2];
528     GetHelixCenter(pparam,helixcenterpos);
529
530     Double_t helixcenterneg[2];
531     GetHelixCenter(nparam,helixcenterneg);
532
533         Double_t helixpos[6];
534         pparam->GetHelixParameters(helixpos,fInputEvent->GetMagneticField());
535         Double_t posradius = TMath::Abs(1./helixpos[4]);
536
537         Double_t helixneg[6];
538         nparam->GetHelixParameters(helixneg,fInputEvent->GetMagneticField());
539         Double_t negradius = TMath::Abs(1./helixneg[4]);
540
541         // Calculate xy-position
542
543         Double_t xpos = helixcenterpos[0];
544         Double_t ypos = helixcenterpos[1];
545         Double_t xneg = helixcenterneg[0];
546         Double_t yneg = helixcenterneg[1];
547
548         convpos[0] = (xpos*negradius + xneg*posradius)/(negradius+posradius);
549         convpos[1] = (ypos*negradius+ yneg*posradius)/(negradius+posradius);
550
551
552         // Calculate Track XY vertex position
553
554         Double_t deltaXPos = convpos[0] -       xpos;
555         Double_t deltaYPos = convpos[1] -       ypos;
556
557         Double_t deltaXNeg = convpos[0] -       xneg;
558         Double_t deltaYNeg = convpos[1] -       yneg;
559
560         Double_t alphaPos =     TMath::Pi() + TMath::ATan2(-deltaYPos,-deltaXPos);
561         Double_t alphaNeg =     TMath::Pi() + TMath::ATan2(-deltaYNeg,-deltaXNeg);
562
563         Double_t vertexXNeg =   xneg +  TMath::Abs(negradius)*TMath::Cos(alphaNeg);
564         Double_t vertexYNeg =   yneg +  TMath::Abs(negradius)*TMath::Sin(alphaNeg);
565
566         Double_t vertexXPos =   xpos +  TMath::Abs(posradius)*TMath::Cos(alphaPos);
567         Double_t vertexYPos =   ypos +  TMath::Abs(posradius)*TMath::Sin(alphaPos);
568
569         AliExternalTrackParam p(*pparam);
570         AliExternalTrackParam n(*nparam);
571
572         TVector2 vertexPos(vertexXPos,vertexYPos);
573         TVector2 vertexNeg(vertexXNeg,vertexYNeg);
574
575         // Convert to local coordinate system
576         TVector2 vertexPosRot=vertexPos.Rotate(-p.GetAlpha());
577         TVector2 vertexNegRot=vertexNeg.Rotate(-n.GetAlpha());
578
579         // Propagate Track Params to Vertex
580
581         if(!p.PropagateTo(vertexPosRot.X(),fInputEvent->GetMagneticField()))return kFALSE;
582         if(!n.PropagateTo(vertexNegRot.X(),fInputEvent->GetMagneticField()))return kFALSE;
583
584         // Check whether propagation was sucessful
585
586         if(TMath::Abs(vertexPos.Mod()-TMath::Sqrt(p.GetX()*p.GetX()+p.GetY()*p.GetY()))>0.01)return kFALSE;
587         if(TMath::Abs(vertexNeg.Mod()-TMath::Sqrt(n.GetX()*n.GetX()+n.GetY()*n.GetY()))>0.01)return kFALSE;
588
589         // Calculate z position
590
591         convpos[2] = (p.GetZ()*negradius+n.GetZ()*posradius)/(negradius+posradius);
592
593         // Calculate DCA
594         TVector2 vdca=vertexPos-vertexNeg;
595         dca[0]=vdca.Mod();
596         dca[1]=TMath::Abs(n.GetZ()-p.GetZ());
597
598         return kTRUE;
599 }
600 //________________________________________________________________________
601 Bool_t AliV0ReaderV1::GetAODConversionGammas(){
602
603     // Get reconstructed conversion photons from satellite AOD file
604
605     AliAODEvent *fAODEvent=dynamic_cast<AliAODEvent*>(fInputEvent);
606
607     if(fAODEvent){
608
609        if(fConversionGammas == NULL){
610           fConversionGammas = new TClonesArray("AliAODConversionPhoton",100);
611        }
612         fConversionGammas->Delete();//Reset the TClonesArray
613
614         //Get Gammas from satellite AOD gamma branch
615
616         AliAODConversionPhoton *gamma=0x0;
617
618         TClonesArray *fInputGammas=dynamic_cast<TClonesArray*>(fAODEvent->FindListObject(fDeltaAODBranchName.Data()));
619         if(!fInputGammas){
620            FindDeltaAODBranchName();
621            fInputGammas=dynamic_cast<TClonesArray*>(fAODEvent->FindListObject(fDeltaAODBranchName.Data()));}
622         if(!fInputGammas){AliError("No Gamma Satellites found");return kFALSE;}
623         // Apply Selection Cuts to Gammas and create local working copy
624         if(fInputGammas){
625            for(Int_t i=0;i<fInputGammas->GetEntriesFast();i++){
626               gamma=dynamic_cast<AliAODConversionPhoton*>(fInputGammas->At(i));
627               if(gamma){
628                  if(fConversionCuts->PhotonIsSelected(gamma,fInputEvent)){
629                     new((*fConversionGammas)[fConversionGammas->GetEntriesFast()]) AliAODConversionPhoton(*gamma);}
630               }
631            }
632         }
633     }
634
635     if(fConversionGammas->GetEntries()){return kTRUE;}
636
637     return kFALSE;
638 }
639
640 //________________________________________________________________________
641 void AliV0ReaderV1::FindDeltaAODBranchName(){
642
643     // Find delta AOD branchname containing reconstructed photons
644
645     TList *list=fInputEvent->GetList();
646     for(Int_t ii=0;ii<list->GetEntries();ii++){
647         TString name((list->At(ii))->GetName());
648         if(name.BeginsWith(fDeltaAODBranchName)&&name.EndsWith("gamma")){
649             fDeltaAODBranchName=name;
650             AliInfo(Form("Set DeltaAOD BranchName to: %s",fDeltaAODBranchName.Data()));
651             return;
652         }
653     }
654 }
655
656
657 //________________________________________________________________________
658 void AliV0ReaderV1::Terminate(Option_t *)
659 {
660
661 }