1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Authors: Svein Lindal, Daniel Lohner *
8 * based on: on older version (see aliroot up to v5-04-42-AN) *
10 * Authors: Kathrin Koch, Kenneth Aamodt, Ana Marin *
12 * Permission to use, copy, modify and distribute this software and its *
13 * documentation strictly for non-commercial purposes is hereby granted *
14 * without fee, provided that the above copyright notice appears in all *
15 * copies and that both the copyright notice and this permission notice *
16 * appear in the supporting documentation. The authors make no claims *
17 * about the suitability of this software for any purpose. It is *
18 * provided "as is" without express or implied warranty. *
19 **************************************************************************/
21 ////////////////////////////////////////////////
22 //---------------------------------------------
23 // Class reconstructing conversion photons from V0s
24 //---------------------------------------------
25 ////////////////////////////////////////////////
27 // The AliAODConversionPhotons will return the Position (== ESDTrack->GetID())of the positive (negative) ESDTrack
28 // in the Array of ESDTracks stored in the ESDEvent via GetTrackLabelPositive() (GetTrackLabelNagative()).
29 // Since it is the Position in the Array it is always positive.
30 // After the conversion ESD --> AOD each AOD track will give you the former Position in the ESDArray via the
31 // Function AODTrack->GetID(). AODTracks are stored for different TrackParameter (e.g. HybridTracks, TPC only ...). No Standard
32 // AODTracks (not copies of AliExternalTrackParam) will be stored with negative values of AODTrack->GetID() (Formula: (ESDTrack->GetID()+1)*-1)
33 // This leads to the possibility of more than one AOD track with the same negative ID. For that reason all AOD tracks are additionally flaged.
34 // In this analysis we should therefore only use AODTracks with positive values of AODTrack->GetID().
36 // If you want to find the AODTrack corresponding to the daugher track of a AliAODConversionPhoton you have to find the AODTrack with
37 // AODTrack->GetID() == GetTrackLabelPositive() (GetTrackLabelNagative()).
39 #include <TGeoGlobalMagField.h>
41 #include "AliV0ReaderV1.h"
42 #include "AliKFParticle.h"
45 #include "AliAODEvent.h"
46 #include "AliESDEvent.h"
48 #include "AliMCEvent.h"
50 #include "AliMCEventHandler.h"
51 #include "AliESDpid.h"
52 #include "AliESDtrackCuts.h"
54 #include "AliGenCocktailEventHeader.h"
56 #include "AliKFConversionPhoton.h"
57 #include "AliAODConversionPhoton.h"
58 #include "AliConversionPhotonBase.h"
60 #include "AliKFVertex.h"
61 #include "AliAODTrack.h"
62 #include "AliESDtrack.h"
63 #include "AliAnalysisManager.h"
64 #include "AliInputEventHandler.h"
65 #include "AliAODHandler.h"
66 #include "AliPIDResponse.h"
70 #include "TObjArray.h"
77 ClassImp(AliV0ReaderV1)
79 //________________________________________________________________________
80 AliV0ReaderV1::AliV0ReaderV1(const char *name) : AliAnalysisTaskSE(name),
81 fConversionCuts(NULL),
83 fConversionGammas(NULL),
84 fUseImprovedVertex(kTRUE),
85 fUseOwnXYZCalculation(kTRUE),
86 fUseConstructGamma(kFALSE),
87 kUseAODConversionPhoton(kTRUE),
89 fDeltaAODBranchName("GammaConv"),
90 fDeltaAODFilename("AliAODGammaConversion.root"),
92 fEventIsSelected(kFALSE),
93 fNumberOfPrimaryTracks(0),
96 // Default constructor
98 DefineInput(0, TChain::Class());
101 //________________________________________________________________________
102 AliV0ReaderV1::~AliV0ReaderV1()
104 // default deconstructor
106 if(fConversionGammas){
107 fConversionGammas->Delete();// Clear Objects
108 delete fConversionGammas;
109 fConversionGammas=0x0;
114 //________________________________________________________________________
115 AliV0ReaderV1::AliV0ReaderV1(AliV0ReaderV1 &original) : AliAnalysisTaskSE(original),
116 fConversionCuts(NULL),
117 fConversionGammas(NULL),
118 fUseImprovedVertex(original.fUseImprovedVertex),
119 fUseOwnXYZCalculation(original.fUseOwnXYZCalculation),
120 fUseConstructGamma(original.fUseConstructGamma),
121 kUseAODConversionPhoton(original.kUseAODConversionPhoton),
122 fCreateAOD(original.fCreateAOD),
123 fDeltaAODBranchName(original.fDeltaAODBranchName),
124 fDeltaAODFilename(original.fDeltaAODFilename),
125 fEventIsSelected(original.fEventIsSelected)
127 // Default constructor
129 DefineInput(0, TChain::Class());
132 //____________________________________________________________
133 AliV0ReaderV1 &AliV0ReaderV1::operator=(const AliV0ReaderV1 &ref){
135 // Assignment operator
136 // Only copies pointers, object is not the owner of the references
139 AliAnalysisTaskSE::operator=(ref);
140 fUseImprovedVertex=ref.fUseImprovedVertex;
141 fUseOwnXYZCalculation=ref.fUseOwnXYZCalculation;
142 fUseConstructGamma=ref.fUseConstructGamma;
143 kUseAODConversionPhoton=ref.kUseAODConversionPhoton;
144 fCreateAOD=ref.fCreateAOD;
145 fDeltaAODBranchName=ref.fDeltaAODBranchName;
146 fDeltaAODFilename=ref.fDeltaAODFilename;
147 fEventIsSelected=ref.fEventIsSelected;
153 //________________________________________________________________________
154 void AliV0ReaderV1::Init()
156 // Initialize function to be called once before analysis
157 if(fConversionCuts==NULL){
158 if(fConversionCuts==NULL)AliError("No Conversion Cut Selection initialized");
160 if(fEventCuts==NULL){
161 if(fEventCuts==NULL)AliError("No Event Cut Selection initialized");
164 if(fCreateAOD){kUseAODConversionPhoton=kTRUE;}
166 if(fConversionGammas != NULL){
167 delete fConversionGammas;
168 fConversionGammas=NULL;
171 if(fConversionGammas == NULL){
172 if(kUseAODConversionPhoton){
173 fConversionGammas = new TClonesArray("AliAODConversionPhoton",100);}
175 fConversionGammas = new TClonesArray("AliKFConversionPhoton",100);}
177 fConversionGammas->Delete();//Reset the TClonesArray
180 //________________________________________________________________________
181 void AliV0ReaderV1::UserCreateOutputObjects()
187 fDeltaAODBranchName.Append("_");
188 fDeltaAODBranchName.Append(fEventCuts->GetCutNumber());
191 fDeltaAODBranchName.Append("_");
192 fDeltaAODBranchName.Append(fConversionCuts->GetCutNumber());
193 fDeltaAODBranchName.Append("_gamma");
195 fConversionGammas->SetName(fDeltaAODBranchName.Data());
197 AddAODBranch("TClonesArray", &fConversionGammas, fDeltaAODFilename.Data());
198 AliAnalysisManager::GetAnalysisManager()->RegisterExtraFile(fDeltaAODFilename.Data());
202 //________________________________________________________________________
203 Bool_t AliV0ReaderV1::Notify()
205 if (fPeriodName.CompareTo("") == 0){
206 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
208 AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
210 TTree* tree = (TTree*) inputHandler->GetTree();
211 TFile* file = (TFile*) tree->GetCurrentFile();
212 TString fileName(file->GetName());
213 TObjArray *arr = fileName.Tokenize("/");
214 for (Int_t i = 0; i < arr->GetEntriesFast();i++ ){
215 TObjString* testObjString = (TObjString*)arr->At(i);
216 if (testObjString->GetString().Contains("LHC")){
217 fPeriodName = testObjString->GetString();
218 i = arr->GetEntriesFast();
223 if(!fEventCuts->GetDoEtaShift()) return kTRUE; // No Eta Shift requested, continue
224 if(fEventCuts->GetEtaShift() == 0.0){ // Eta Shift requested but not set, get shift automatically
225 fEventCuts->GetCorrectEtaShiftFromPeriod(fPeriodName);
226 fEventCuts->DoEtaShift(kFALSE); // Eta Shift Set, make sure that it is called only once
229 printf(" Gamma Conversion Reader %s_%s :: Eta Shift Manually Set to %f \n\n",
230 (fEventCuts->GetCutNumber()).Data(),(fConversionCuts->GetCutNumber()).Data(),fEventCuts->GetEtaShift());
231 fEventCuts->DoEtaShift(kFALSE); // Eta Shift Set, make sure that it is called only once
236 //________________________________________________________________________
237 void AliV0ReaderV1::UserExec(Option_t *option){
239 AliESDEvent * esdEvent = dynamic_cast<AliESDEvent*>(fInputEvent);
241 if (!TGeoGlobalMagField::Instance()->GetField()) esdEvent->InitMagneticField();
244 // Check if correctly initialized
245 if(!fConversionGammas)Init();
248 fEventIsSelected=ProcessEvent(fInputEvent,fMCEvent);
255 //________________________________________________________________________
256 Bool_t AliV0ReaderV1::ProcessEvent(AliVEvent *inputEvent,AliMCEvent *mcEvent)
259 //Reset the TClonesArray
260 fConversionGammas->Delete();
262 fInputEvent=inputEvent;
266 AliError("No Input event");
269 if(!fEventCuts){AliError("No EventCuts");return kFALSE;}
270 if(!fConversionCuts){AliError("No ConversionCuts");return kFALSE;}
272 // Count Primary Tracks Event
276 if(!fEventCuts->EventIsSelected(fInputEvent,fMCEvent))return kFALSE;
278 // Set Magnetic Field
279 AliKFParticle::SetField(fInputEvent->GetMagneticField());
281 if(fInputEvent->IsA()==AliESDEvent::Class()){
284 if(fInputEvent->IsA()==AliAODEvent::Class()){
285 GetAODConversionGammas();
290 ///________________________________________________________________________
291 void AliV0ReaderV1::FillAODOutput()
293 // Fill AOD Output with reconstructed Photons
295 if(fInputEvent->IsA()==AliESDEvent::Class()){
296 ///Make sure delta aod is filled if standard aod is filled (for synchronization when reading aod with standard aod)
298 AliAODHandler * aodhandler = dynamic_cast<AliAODHandler*>(AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler());
299 if (aodhandler && aodhandler->GetFillAOD()) {
300 AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillExtension(kTRUE);
301 //PostData(0, fConversionGammas);
308 ///________________________________________________________________________
309 const AliExternalTrackParam *AliV0ReaderV1::GetExternalTrackParam(AliESDv0 *fCurrentV0,Int_t &tracklabel,Int_t charge){
311 // Get External Track Parameter with given charge
313 if(!(charge==1||charge==-1)){AliError("Charge not defined");return 0x0;}
315 // Check for sign flip
317 if(!fCurrentV0->GetParamN()||!fCurrentV0->GetParamP())return 0x0;
318 if(!fConversionCuts->GetTrack(fInputEvent,fCurrentV0->GetNindex())||!fConversionCuts->GetTrack(fInputEvent,fCurrentV0->GetPindex()))return 0x0;
319 if((fConversionCuts->GetTrack(fInputEvent,fCurrentV0->GetPindex()))->Charge()==charge){
320 tracklabel=fCurrentV0->GetPindex();
321 return fCurrentV0->GetParamP();}
322 if((fConversionCuts->GetTrack(fInputEvent,fCurrentV0->GetNindex()))->Charge()==charge){
323 tracklabel=fCurrentV0->GetNindex();
324 return fCurrentV0->GetParamN();}
329 ///________________________________________________________________________
330 Bool_t AliV0ReaderV1::ProcessESDV0s()
332 // Process ESD V0s for conversion photon reconstruction
333 AliESDEvent *fESDEvent=dynamic_cast<AliESDEvent*>(fInputEvent);
335 AliKFConversionPhoton *fCurrentMotherKFCandidate=NULL;
339 for(Int_t currentV0Index=0;currentV0Index<fESDEvent->GetNumberOfV0s();currentV0Index++){
340 AliESDv0 *fCurrentV0=(AliESDv0*)(fESDEvent->GetV0(currentV0Index));
342 printf("Requested V0 does not exist");
346 fCurrentMotherKFCandidate=ReconstructV0(fCurrentV0,currentV0Index);
348 if(fCurrentMotherKFCandidate){
349 // Add Gamma to the TClonesArray
351 if(kUseAODConversionPhoton){
352 new((*fConversionGammas)[fConversionGammas->GetEntriesFast()]) AliAODConversionPhoton(fCurrentMotherKFCandidate);
353 AliAODConversionPhoton * currentConversionPhoton = (AliAODConversionPhoton*)(fConversionGammas->At(fConversionGammas->GetEntriesFast()-1));
354 currentConversionPhoton->SetMass(fCurrentMotherKFCandidate->M());
355 currentConversionPhoton->SetMassToZero();
359 new((*fConversionGammas)[fConversionGammas->GetEntriesFast()]) AliKFConversionPhoton(*fCurrentMotherKFCandidate);
362 delete fCurrentMotherKFCandidate;
363 fCurrentMotherKFCandidate=NULL;
370 ///________________________________________________________________________
371 AliKFConversionPhoton *AliV0ReaderV1::ReconstructV0(AliESDv0 *fCurrentV0,Int_t currentV0Index)
373 // cout << currentV0Index << endl;
374 // Reconstruct conversion photon from ESD v0
375 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kPhotonIn);
377 //checks if on the fly mode is set
378 if(!fConversionCuts->SelectV0Finder(fCurrentV0->GetOnFlyStatus())){
379 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kOnFly);
384 Int_t currentTrackLabels[2]={-1,-1};
386 // Get Daughter KF Particles
388 const AliExternalTrackParam *fCurrentExternalTrackParamPositive=GetExternalTrackParamP(fCurrentV0,currentTrackLabels[0]);
389 // cout << fCurrentExternalTrackParamPositive << "\t" << currentTrackLabels[0] << endl;
390 const AliExternalTrackParam *fCurrentExternalTrackParamNegative=GetExternalTrackParamN(fCurrentV0,currentTrackLabels[1]);
391 // cout << fCurrentExternalTrackParamNegative << "\t" << currentTrackLabels[1] << endl;
392 if(!fCurrentExternalTrackParamPositive||!fCurrentExternalTrackParamNegative)return 0x0;
394 // Apply some Cuts before Reconstruction
396 AliVTrack * posTrack = fConversionCuts->GetTrack(fInputEvent,currentTrackLabels[0]);
397 AliVTrack * negTrack = fConversionCuts->GetTrack(fInputEvent,currentTrackLabels[1]);
398 if(!negTrack || !posTrack) {
399 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kNoTracks);
403 if(!fConversionCuts->TracksAreSelected(negTrack, posTrack)){
404 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kTrackCuts);
408 fConversionCuts->FillV0EtaBeforedEdxCuts(fCurrentV0->Eta());
409 if (!fConversionCuts->dEdxCuts(posTrack)) {
410 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kdEdxCuts);
414 if(!fConversionCuts->dEdxCuts(negTrack)) {
415 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kdEdxCuts);
418 fConversionCuts->FillV0EtaAfterdEdxCuts(fCurrentV0->Eta());
419 // Reconstruct Photon
420 AliKFConversionPhoton *fCurrentMotherKF=NULL;
421 // fUseConstructGamma = kFALSE;
422 // cout << "construct gamma " << endl;
423 AliKFParticle fCurrentNegativeKFParticle(*(fCurrentExternalTrackParamNegative),11);
424 // cout << fCurrentExternalTrackParamNegative << "\t" << endl;
425 AliKFParticle fCurrentPositiveKFParticle(*(fCurrentExternalTrackParamPositive),-11);
426 // cout << fCurrentExternalTrackParamPositive << "\t" << endl;
427 // cout << currentTrackLabels[0] << "\t" << currentTrackLabels[1] << endl;
428 // cout << "construct gamma " <<fUseConstructGamma << endl;
431 if(fUseConstructGamma){
432 fCurrentMotherKF = new AliKFConversionPhoton();
433 fCurrentMotherKF->ConstructGamma(fCurrentNegativeKFParticle,fCurrentPositiveKFParticle);
435 fCurrentMotherKF = new AliKFConversionPhoton(fCurrentNegativeKFParticle,fCurrentPositiveKFParticle);
436 fCurrentMotherKF->SetMassConstraint(0,0.0001);
441 fCurrentMotherKF->SetTrackLabels(currentTrackLabels[0],currentTrackLabels[1]);
445 fCurrentMotherKF->SetV0Index(currentV0Index);
450 AliStack *fMCStack= fMCEvent->Stack();
452 Int_t labelp=TMath::Abs(fConversionCuts->GetTrack(fInputEvent,fCurrentMotherKF->GetTrackLabelPositive())->GetLabel());
453 Int_t labeln=TMath::Abs(fConversionCuts->GetTrack(fInputEvent,fCurrentMotherKF->GetTrackLabelNegative())->GetLabel());
455 TParticle *fNegativeMCParticle = fMCStack->Particle(labeln);
456 TParticle *fPositiveMCParticle = fMCStack->Particle(labelp);
458 if(fPositiveMCParticle&&fNegativeMCParticle){
459 fCurrentMotherKF->SetMCLabelPositive(labelp);
460 fCurrentMotherKF->SetMCLabelNegative(labeln);
464 // Update Vertex (moved for same eta compared to old)
465 // cout << currentV0Index <<" \t before: \t" << fCurrentMotherKF->GetPx() << "\t" << fCurrentMotherKF->GetPy() << "\t" << fCurrentMotherKF->GetPz() << endl;
466 if(fUseImprovedVertex == kTRUE){
467 AliKFVertex primaryVertexImproved(*fInputEvent->GetPrimaryVertex());
468 // cout << "Prim Vtx: " << primaryVertexImproved.GetX() << "\t" << primaryVertexImproved.GetY() << "\t" << primaryVertexImproved.GetZ() << endl;
469 primaryVertexImproved+=*fCurrentMotherKF;
470 fCurrentMotherKF->SetProductionVertex(primaryVertexImproved);
474 Double_t PsiPair=GetPsiPair(fCurrentV0,fCurrentExternalTrackParamPositive,fCurrentExternalTrackParamNegative);
475 fCurrentMotherKF->SetPsiPair(PsiPair);
477 // Recalculate ConversionPoint
478 Double_t dca[2]={0,0};
479 if(fUseOwnXYZCalculation){
480 Double_t convpos[3]={0,0,0};
481 if(!GetConversionPoint(fCurrentExternalTrackParamPositive,fCurrentExternalTrackParamNegative,convpos,dca)){
482 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kConvPointFail);
483 delete fCurrentMotherKF;
484 fCurrentMotherKF=NULL;
488 fCurrentMotherKF->SetConversionPoint(convpos);
491 if(fCurrentMotherKF->GetNDF() > 0.)
492 fCurrentMotherKF->SetChi2perNDF(fCurrentMotherKF->GetChi2()/fCurrentMotherKF->GetNDF()); //->Photon is created before all chi2 relevant changes are performed, set it "by hand"
495 // Set Dilepton Mass (moved down for same eta compared to old)
496 fCurrentMotherKF->SetMass(fCurrentMotherKF->M());
500 if(!fConversionCuts->PhotonCuts(fCurrentMotherKF,fInputEvent)){
501 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kPhotonCuts);
502 delete fCurrentMotherKF;
503 fCurrentMotherKF=NULL;
507 // cout << currentV0Index <<" \t after: \t" <<fCurrentMotherKF->GetPx() << "\t" << fCurrentMotherKF->GetPy() << "\t" << fCurrentMotherKF->GetPz() << endl;
509 fConversionCuts->FillPhotonCutIndex(AliConversionPhotonCuts::kPhotonOut);
510 return fCurrentMotherKF;
513 ///________________________________________________________________________
514 Double_t AliV0ReaderV1::GetPsiPair(const AliESDv0* v0, const AliExternalTrackParam *positiveparam,const AliExternalTrackParam *negativeparam) const {
516 // Angle between daughter momentum plane and plane
519 AliExternalTrackParam nt(*negativeparam);
520 AliExternalTrackParam pt(*positiveparam);
522 Float_t magField = fInputEvent->GetMagneticField();
524 Double_t xyz[3] = {0.,0.,0.};
525 v0->GetXYZ(xyz[0],xyz[1],xyz[2]);
527 // Double_t pPlus[3] = {pt.Px(),pt.Py(),pt.Pz()};
528 // Double_t pMinus[3] = {nt.Px(),nt.Py(),nt.Pz()};
530 // Double_t u[3] = {pPlus[0]+pMinus[0],pPlus[1]+pMinus[1],pPlus[2]+pMinus[2]};
531 // Double_t normu = sqrt( (u[0]*u[0]) + (u[1]*u[1]) + (u[2]*u[2]) );
533 // u[0] = u[0] / normu;
534 // u[1] = u[1] / normu;
535 // u[2] = u[2] / normu;
537 // Double_t normpPlus = sqrt( (pPlus[0]*pPlus[0]) + (pPlus[1]*pPlus[1]) + (pPlus[2]*pPlus[2]) );
538 // Double_t normpMinus = sqrt( (pMinus[0]*pMinus[0]) + (pMinus[1]*pMinus[1]) + (pMinus[2]*pMinus[2]) );
540 // pPlus[0] = pPlus[0] / normpPlus;
541 // pPlus[1] = pPlus[1] / normpPlus;
542 // pPlus[2] = pPlus[2] / normpPlus;
544 // pMinus[0] = pMinus[0] / normpMinus;
545 // pMinus[1] = pMinus[1] / normpMinus;
546 // pMinus[2] = pMinus[2] / normpMinus;
548 // Double_t v[3] = {0,0,0}; // pPlus X pMinus
549 // v[0] = (pPlus[1]*pMinus[2]) - (pPlus[2]*pMinus[1]);
550 // v[1] = (pPlus[2]*pMinus[0]) - (pPlus[0]*pMinus[2]);
551 // v[2] = (pPlus[0]*pMinus[1]) - (pPlus[1]*pMinus[0]);
553 // Double_t w[3] = {0,0,0}; // u X v
554 // w[0] = (u[1]*v[2]) - (u[2]*v[1]);
555 // w[1] = (u[2]*v[0]) - (u[0]*v[2]);
556 // w[2] = (u[0]*v[1]) - (u[1]*v[0]);
558 // Double_t z[3] = {0,0,1};
559 // Double_t wc[3] = {0,0,0}; // u X v
560 // wc[0] = (u[1]*z[2]) - (u[2]*z[1]);
561 // wc[1] = (u[2]*z[0]) - (u[0]*z[2]);
562 // wc[2] = (u[0]*z[1]) - (u[1]*z[0]);
564 // Double_t PhiV = TMath::ACos((w[0]*wc[0]) + (w[1]*wc[1]) + (w[2]*wc[2]));
568 // TVector3 pPlus(pt.Px(),pt.Py(),pt.Pz());
569 // TVector3 pMinus(nt.Px(),nt.Py(),nt.Pz());
571 // TVector3 u = pMinus + pPlus;
572 // u = u*(1/u.Mag());
574 // TVector3 pHPlus = pPlus*(1/pPlus.Mag());
575 // TVector3 pHMinus = pMinus*(1/pMinus.Mag());
577 // TVector3 v = pHPlus.Cross(pHMinus);
578 // TVector3 w = u.Cross(v);
579 // TVector3 z(0,0,1);
580 // TVector3 wc = u.Cross(z);
582 // Double_t PhiV = w * wc;
584 Double_t mn[3] = {0,0,0};
585 Double_t mp[3] = {0,0,0};
587 v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
588 v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
590 Double_t deltat = 1.;
591 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
592 Double_t radiussum = TMath::Sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]) + 50;//radius to which tracks shall be propagated
594 Double_t momPosProp[3] = {0,0,0};
595 Double_t momNegProp[3] = {0,0,0};
597 Double_t psiPair = 4.;
598 if(nt.PropagateTo(radiussum,magField) == 0) return psiPair; //propagate tracks to the outside -> Better Purity and Efficiency
599 if(pt.PropagateTo(radiussum,magField) == 0) return psiPair; //propagate tracks to the outside -> Better Purity and Efficiency
601 pt.GetPxPyPz(momPosProp);//Get momentum vectors of tracks after propagation
602 nt.GetPxPyPz(momNegProp);
605 TMath::Sqrt(momNegProp[0]*momNegProp[0]+momNegProp[1]*momNegProp[1]+momNegProp[2]*momNegProp[2]);//absolute momentum value of negative daughter
608 TMath::Sqrt(momPosProp[0]*momPosProp[0]+momPosProp[1]*momPosProp[1]+momPosProp[2]*momPosProp[2]);//absolute momentum value of positive daughter
610 Double_t scalarproduct =
611 momPosProp[0]*momNegProp[0]+momPosProp[1]*momNegProp[1]+momPosProp[2]*momNegProp[2];//scalar product of propagated positive and negative daughters' momenta
613 Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));//Angle between propagated daughter tracks
615 // psiPair = TMath::Abs(TMath::ASin(deltat/chipair));
616 psiPair = TMath::ASin(deltat/chipair);
620 ///________________________________________________________________________
621 Bool_t AliV0ReaderV1::GetHelixCenter(const AliExternalTrackParam *track,Double_t center[2]){
623 // Get Center of the helix track parametrization
625 Int_t charge=track->Charge();
626 Double_t b=fInputEvent->GetMagneticField();
629 track->GetHelixParameters(helix,b);
631 Double_t xpos = helix[5];
632 Double_t ypos = helix[0];
633 Double_t radius = TMath::Abs(1./helix[4]);
634 Double_t phi = helix[2];
637 phi = phi + 2*TMath::Pi();
640 phi -= TMath::Pi()/2.;
641 Double_t xpoint = radius * TMath::Cos(phi);
642 Double_t ypoint = radius * TMath::Sin(phi);
656 center[0] = xpos + xpoint;
657 center[1] = ypos + ypoint;
661 ///________________________________________________________________________
662 Bool_t AliV0ReaderV1::GetConversionPoint(const AliExternalTrackParam *pparam,const AliExternalTrackParam *nparam,Double_t convpos[3],Double_t dca[2]){
664 // Recalculate Conversion Point
666 if(!pparam||!nparam)return kFALSE;
668 Double_t helixcenterpos[2];
669 GetHelixCenter(pparam,helixcenterpos);
671 Double_t helixcenterneg[2];
672 GetHelixCenter(nparam,helixcenterneg);
674 Double_t helixpos[6];
675 pparam->GetHelixParameters(helixpos,fInputEvent->GetMagneticField());
676 Double_t posradius = TMath::Abs(1./helixpos[4]);
678 Double_t helixneg[6];
679 nparam->GetHelixParameters(helixneg,fInputEvent->GetMagneticField());
680 Double_t negradius = TMath::Abs(1./helixneg[4]);
682 // Calculate xy-position
684 Double_t xpos = helixcenterpos[0];
685 Double_t ypos = helixcenterpos[1];
686 Double_t xneg = helixcenterneg[0];
687 Double_t yneg = helixcenterneg[1];
689 convpos[0] = (xpos*negradius + xneg*posradius)/(negradius+posradius);
690 convpos[1] = (ypos*negradius+ yneg*posradius)/(negradius+posradius);
693 // Calculate Track XY vertex position
695 Double_t deltaXPos = convpos[0] - xpos;
696 Double_t deltaYPos = convpos[1] - ypos;
698 Double_t deltaXNeg = convpos[0] - xneg;
699 Double_t deltaYNeg = convpos[1] - yneg;
701 Double_t alphaPos = TMath::Pi() + TMath::ATan2(-deltaYPos,-deltaXPos);
702 Double_t alphaNeg = TMath::Pi() + TMath::ATan2(-deltaYNeg,-deltaXNeg);
704 Double_t vertexXNeg = xneg + TMath::Abs(negradius)*TMath::Cos(alphaNeg);
705 Double_t vertexYNeg = yneg + TMath::Abs(negradius)*TMath::Sin(alphaNeg);
707 Double_t vertexXPos = xpos + TMath::Abs(posradius)*TMath::Cos(alphaPos);
708 Double_t vertexYPos = ypos + TMath::Abs(posradius)*TMath::Sin(alphaPos);
710 AliExternalTrackParam p(*pparam);
711 AliExternalTrackParam n(*nparam);
713 TVector2 vertexPos(vertexXPos,vertexYPos);
714 TVector2 vertexNeg(vertexXNeg,vertexYNeg);
716 // Convert to local coordinate system
717 TVector2 vertexPosRot=vertexPos.Rotate(-p.GetAlpha());
718 TVector2 vertexNegRot=vertexNeg.Rotate(-n.GetAlpha());
720 // Propagate Track Params to Vertex
722 if(!p.PropagateTo(vertexPosRot.X(),fInputEvent->GetMagneticField()))return kFALSE;
723 if(!n.PropagateTo(vertexNegRot.X(),fInputEvent->GetMagneticField()))return kFALSE;
725 // Check whether propagation was sucessful
727 if(TMath::Abs(vertexPos.Mod()-TMath::Sqrt(p.GetX()*p.GetX()+p.GetY()*p.GetY()))>0.01)return kFALSE;
728 if(TMath::Abs(vertexNeg.Mod()-TMath::Sqrt(n.GetX()*n.GetX()+n.GetY()*n.GetY()))>0.01)return kFALSE;
730 // Calculate z position
732 convpos[2] = (p.GetZ()*negradius+n.GetZ()*posradius)/(negradius+posradius);
735 TVector2 vdca=vertexPos-vertexNeg;
737 dca[1]=TMath::Abs(n.GetZ()-p.GetZ());
741 //________________________________________________________________________
742 Bool_t AliV0ReaderV1::GetAODConversionGammas(){
744 // Get reconstructed conversion photons from satellite AOD file
746 AliAODEvent *fAODEvent=dynamic_cast<AliAODEvent*>(fInputEvent);
750 if(fConversionGammas == NULL){
751 fConversionGammas = new TClonesArray("AliAODConversionPhoton",100);
753 fConversionGammas->Delete();//Reset the TClonesArray
755 //Get Gammas from satellite AOD gamma branch
757 AliAODConversionPhoton *gamma=0x0;
759 TClonesArray *fInputGammas=dynamic_cast<TClonesArray*>(fAODEvent->FindListObject(fDeltaAODBranchName.Data()));
762 FindDeltaAODBranchName();
763 fInputGammas=dynamic_cast<TClonesArray*>(fAODEvent->FindListObject(fDeltaAODBranchName.Data()));}
764 if(!fInputGammas){AliError("No Gamma Satellites found");return kFALSE;}
765 // Apply Selection Cuts to Gammas and create local working copy
767 for(Int_t i=0;i<fInputGammas->GetEntriesFast();i++){
768 gamma=dynamic_cast<AliAODConversionPhoton*>(fInputGammas->At(i));
770 if(fRelabelAODs)RelabelAODPhotonCandidates(gamma);
771 if(fConversionCuts->PhotonIsSelected(gamma,fInputEvent)){
772 new((*fConversionGammas)[fConversionGammas->GetEntriesFast()]) AliAODConversionPhoton(*gamma);}
778 if(fConversionGammas->GetEntries()){return kTRUE;}
783 //________________________________________________________________________
784 void AliV0ReaderV1::FindDeltaAODBranchName(){
786 // Find delta AOD branchname containing reconstructed photons
788 TList *list=fInputEvent->GetList();
789 for(Int_t ii=0;ii<list->GetEntries();ii++){
790 TString name((list->At(ii))->GetName());
791 if(name.BeginsWith(fDeltaAODBranchName)&&name.EndsWith("gamma")){
792 fDeltaAODBranchName=name;
793 AliInfo(Form("Set DeltaAOD BranchName to: %s",fDeltaAODBranchName.Data()));
798 //________________________________________________________________________
799 void AliV0ReaderV1::RelabelAODPhotonCandidates(AliAODConversionPhoton *PhotonCandidate){
801 // Relabeling For AOD Event
803 // MCLabel -> AODMCLabel
804 Bool_t AODLabelPos = kFALSE;
805 Bool_t AODLabelNeg = kFALSE;
807 for(Int_t i = 0; i<fInputEvent->GetNumberOfTracks();i++){
808 AliAODTrack *tempDaughter = static_cast<AliAODTrack*>(fInputEvent->GetTrack(i));
810 if( tempDaughter->GetID() == PhotonCandidate->GetTrackLabelPositive() ){
811 PhotonCandidate->SetMCLabelPositive(abs(tempDaughter->GetLabel()));
812 PhotonCandidate->SetLabelPositive(i);
817 if( tempDaughter->GetID() == PhotonCandidate->GetTrackLabelNegative()){
818 PhotonCandidate->SetMCLabelNegative(abs(tempDaughter->GetLabel()));
819 PhotonCandidate->SetLabelNegative(i);
823 if(AODLabelNeg && AODLabelPos){
827 if(!AODLabelPos || !AODLabelNeg){
828 AliError(Form("NO AOD Daughters Found Pos: %i %i Neg: %i %i",AODLabelPos,PhotonCandidate->GetTrackLabelPositive(),AODLabelNeg,PhotonCandidate->GetTrackLabelNegative()));
833 //________________________________________________________________________
834 void AliV0ReaderV1::CountTracks(){
836 // In Case of MC count only MB tracks
837 // if(fMCEvent && fInputEvent->IsA()==AliESDEvent::Class()){
838 // fEventCuts->GetNotRejectedParticles(1,NULL,fMCEvent);
840 // if(fMCEvent && fInputEvent->IsA()==AliAODEvent::Class()){
841 // fEventCuts->GetNotRejectedParticles(1,NULL,fInputEvent);
844 if(fInputEvent->IsA()==AliESDEvent::Class()){
845 // Using standard function for setting Cuts
846 Bool_t selectPrimaries=kTRUE;
847 AliESDtrackCuts *EsdTrackCuts = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(selectPrimaries);
848 EsdTrackCuts->SetMaxDCAToVertexZ(2);
849 EsdTrackCuts->SetEtaRange(-0.8, 0.8);
850 EsdTrackCuts->SetPtRange(0.15);
851 fNumberOfPrimaryTracks = 0;
852 for(Int_t iTracks = 0; iTracks < fInputEvent->GetNumberOfTracks(); iTracks++){
853 AliESDtrack* curTrack = (AliESDtrack*) fInputEvent->GetTrack(iTracks);
854 if(!curTrack) continue;
855 if(!EsdTrackCuts->AcceptTrack(curTrack)) continue;
856 //if(fMCEvent && !(fEventCuts->IsParticleFromBGEvent(abs(curTrack->GetLabel()),fMCEvent->Stack(),fInputEvent))) continue;
857 fNumberOfPrimaryTracks++;
862 else if(fInputEvent->IsA()==AliAODEvent::Class()){
863 fNumberOfPrimaryTracks = 0;
864 for(Int_t iTracks = 0; iTracks<fInputEvent->GetNumberOfTracks(); iTracks++){
865 AliAODTrack* curTrack = (AliAODTrack*) fInputEvent->GetTrack(iTracks);
866 if(curTrack->GetID()<0) continue; // Avoid double counting of tracks
867 if(!curTrack->IsHybridGlobalConstrainedGlobal()) continue;
868 if(abs(curTrack->Eta())>0.8) continue;
869 if(curTrack->Pt()<0.15) continue;
870 //if(fMCEvent && !(fEventCuts->IsParticleFromBGEvent(abs(curTrack->GetLabel()),NULL,fInputEvent))) continue;
871 //if(abs(curTrack->ZAtDCA())>2) continue; // Only Set For TPCOnly tracks
872 fNumberOfPrimaryTracks++;
879 //________________________________________________________________________
880 void AliV0ReaderV1::Terminate(Option_t *)