1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
17 // Dielectron Analysis Main class //
20 Framework to perform event selectoin, single track selection and track pair
23 Convention for the signs of the pair in fPairCandidates:
24 The names are available via the function PairClassName(Int_t i)
26 0: ev1+ ev1+ (same event like sign +)
27 1: ev1+ ev1- (same event unlike sign)
28 2: ev1- ev1- (same event like sign -)
30 3: ev1+ ev2+ (mixed event like sign +)
31 4: ev1- ev2+ (mixed event unlike sign -+)
32 6: ev1+ ev2- (mixed event unlike sign +-)
33 7: ev1- ev2- (mixed event like sign -)
35 5: ev2+ ev2+ (same event like sign +)
36 8: ev2+ ev2- (same event unlike sign)
37 9: ev2- ev2- (same event like sign -)
39 10: ev1+ ev1- (same event track rotation)
43 ///////////////////////////////////////////////////////////////////////////
50 #include <AliESDEvent.h>
51 #include <AliESDtrack.h>
52 #include <AliKFParticle.h>
54 #include <AliEventplane.h>
55 #include <AliVEvent.h>
56 #include <AliVParticle.h>
57 #include <AliVTrack.h>
58 #include "AliDielectronPair.h"
59 #include "AliDielectronHistos.h"
60 #include "AliDielectronCF.h"
61 #include "AliDielectronMC.h"
62 #include "AliDielectronVarManager.h"
63 #include "AliDielectronTrackRotator.h"
64 #include "AliDielectronDebugTree.h"
65 #include "AliDielectronSignalMC.h"
66 #include "AliDielectronMixingHandler.h"
68 #include "AliDielectron.h"
70 ClassImp(AliDielectron)
72 const char* AliDielectron::fgkTrackClassNames[4] = {
79 const char* AliDielectron::fgkPairClassNames[11] = {
93 //________________________________________________________________
94 AliDielectron::AliDielectron() :
95 TNamed("AliDielectron","AliDielectron"),
96 fEventFilter("EventFilter"),
97 fTrackFilter("TrackFilter"),
98 fPairPreFilter("PairPreFilter"),
99 fPairPreFilterLegs("PairPreFilterLegs"),
100 fPairFilter("PairFilter"),
101 fEventPlanePreFilter("EventPlanePreFilter"),
102 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
109 fPairCandidates(new TObjArray(11)),
114 fPreFilterEventPlane(kFALSE),
115 fLikeSignSubEvents(kFALSE),
116 fPreFilterUnlikeOnly(kFALSE),
117 fPreFilterAllSigns(kFALSE),
119 fStoreRotatedPairs(kFALSE),
120 fEstimatorFilename(""),
121 fTRDpidCorrectionFilename("")
124 // Default constructor
129 //________________________________________________________________
130 AliDielectron::AliDielectron(const char* name, const char* title) :
132 fEventFilter("EventFilter"),
133 fTrackFilter("TrackFilter"),
134 fPairPreFilter("PairPreFilter"),
135 fPairPreFilterLegs("PairPreFilterLegs"),
136 fPairFilter("PairFilter"),
137 fEventPlanePreFilter("EventPlanePreFilter"),
138 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
145 fPairCandidates(new TObjArray(11)),
150 fPreFilterEventPlane(kFALSE),
151 fLikeSignSubEvents(kFALSE),
152 fPreFilterUnlikeOnly(kFALSE),
153 fPreFilterAllSigns(kFALSE),
155 fStoreRotatedPairs(kFALSE),
156 fEstimatorFilename(""),
157 fTRDpidCorrectionFilename("")
165 //________________________________________________________________
166 AliDielectron::~AliDielectron()
169 // Default destructor
171 if (fHistos) delete fHistos;
172 if (fPairCandidates) delete fPairCandidates;
173 if (fDebugTree) delete fDebugTree;
174 if (fMixing) delete fMixing;
175 if (fSignalsMC) delete fSignalsMC;
176 if (fCfManagerPair) delete fCfManagerPair;
179 //________________________________________________________________
180 void AliDielectron::Init()
183 // Initialise objects
186 if(GetHasMC()) AliDielectronMC::Instance()->SetHasMC(GetHasMC());
188 InitPairCandidateArrays();
190 if (fCfManagerPair) {
191 fCfManagerPair->SetSignalsMC(fSignalsMC);
192 fCfManagerPair->InitialiseContainer(fPairFilter);
195 fTrackRotator->SetTrackArrays(&fTracks[0],&fTracks[1]);
196 fTrackRotator->SetPdgLegs(fPdgLeg1,fPdgLeg2);
198 if (fDebugTree) fDebugTree->SetDielectron(this);
199 if(fEstimatorFilename.Contains(".root")) AliDielectronVarManager::InitEstimatorAvg(fEstimatorFilename.Data());
200 if(fTRDpidCorrectionFilename.Contains(".root")) AliDielectronVarManager::InitTRDpidEffHistograms(fTRDpidCorrectionFilename.Data());
202 if (fMixing) fMixing->Init(this);
205 //________________________________________________________________
206 void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
209 // Process the events
212 //at least first event is needed!
214 AliError("At least first event must be set!");
217 AliDielectronVarManager::SetEvent(ev1);
219 //in case we have MC load the MC event and process the MC particles
220 if (AliDielectronMC::Instance()->HasMC()) {
221 if (!AliDielectronMC::Instance()->ConnectMCEvent()){
222 AliError("Could not properly connect the MC event, skipping this event!");
228 //if candidate array doesn't exist, create it
229 if (!fPairCandidates->UncheckedAt(0)) {
230 InitPairCandidateArrays();
235 //mask used to require that all cuts are fulfilled
236 UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
239 if ((ev1&&fEventFilter.IsSelected(ev1)!=selectedMask) ||
240 (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
242 AliDielectronVarManager::SetEvent(ev1);
244 //fill track arrays for the first event
246 FillTrackArrays(ev1);
247 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
251 //fill track arrays for the second event
253 FillTrackArrays(ev2,1);
254 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
257 // TPC event plane correction
258 AliEventplane *cevplane = new AliEventplane();
259 if (ev1 && fPreFilterEventPlane && ( fEventPlanePreFilter.GetCuts()->GetEntries()>0 || fEventPlanePOIPreFilter.GetCuts()->GetEntries()>0))
260 EventPlanePreFilter(0, 1, fTracks[0], fTracks[1], ev1, cevplane);
263 // create pairs and fill pair candidate arrays
264 for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
265 for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
266 FillPairArrays(itrackArr1, itrackArr2);
272 fTrackRotator->SetEvent(ev1);
277 //fill debug tree if a manager is attached
278 if (fDebugTree) FillDebugTree();
280 //process event mixing
282 fMixing->Fill(ev1,this);
283 // FillHistograms(0x0,kTRUE);
286 //in case there is a histogram manager, fill the QA histograms
287 if (fHistos) FillHistograms(ev1);
291 AliDielectronVarManager::SetTPCEventPlane(0x0);
295 //________________________________________________________________
296 void AliDielectron::ProcessMC(AliVEvent *ev1)
299 // Process the MC data
302 AliDielectronMC *dieMC=AliDielectronMC::Instance();
304 if (fHistos) FillHistogramsMC(dieMC->GetMCEvent(), ev1);
306 if(!fSignalsMC) return;
307 //loop over all MC data and Fill the CF container if it exist
308 if (!fCfManagerPair) return;
309 fCfManagerPair->SetPdgMother(fPdgMother);
310 if(!fCfManagerPair->GetStepForMCtruth()) return;
312 // signals to be studied
313 Int_t nSignals = fSignalsMC->GetEntries();
315 // initialize 2D arrays of labels for particles from each MC signal
316 Int_t** labels1; // labels for particles satisfying branch 1
317 Int_t** labels2; // labels for particles satisfying branch 2
318 Int_t** labels12; // labels for particles satisfying both branches
319 labels1 = new Int_t*[nSignals];
320 labels2 = new Int_t*[nSignals];
321 labels12 = new Int_t*[nSignals];
322 Int_t* indexes1=new Int_t[nSignals];
323 Int_t* indexes2=new Int_t[nSignals];
324 Int_t* indexes12=new Int_t[nSignals];
325 for(Int_t isig=0;isig<nSignals;++isig) {
326 *(labels1+isig) = new Int_t[dieMC->GetNMCTracks()];
327 *(labels2+isig) = new Int_t[dieMC->GetNMCTracks()];
328 *(labels12+isig) = new Int_t[dieMC->GetNMCTracks()];
329 for(Int_t ip=0; ip<dieMC->GetNMCTracks();++ip) {
330 labels1[isig][ip] = -1;
331 labels2[isig][ip] = -1;
332 labels12[isig][ip] = -1;
339 Bool_t truth1=kFALSE;
340 Bool_t truth2=kFALSE;
341 // loop over the MC tracks
342 for(Int_t ipart=0; ipart<dieMC->GetNMCTracks(); ++ipart) {
343 for(Int_t isig=0; isig<nSignals; ++isig) { // loop over signals
344 // Proceed only if this signal is required in the pure MC step
345 // NOTE: Some signals can be satisfied by many particles and this leads to high
346 // computation times (e.g. secondary electrons from the GEANT transport). Be aware of this!!
347 if(!((AliDielectronSignalMC*)fSignalsMC->At(isig))->GetFillPureMCStep()) continue;
349 truth1 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 1);
350 truth2 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 2);
352 // particles satisfying both branches are treated separately to avoid double counting during pairing
353 if(truth1 && truth2) {
354 labels12[isig][indexes12[isig]] = ipart;
359 labels1[isig][indexes1[isig]] = ipart;
363 labels2[isig][indexes2[isig]] = ipart;
368 } // end loop over MC particles
370 // Do the pairing and fill the CF container with pure MC info
371 for(Int_t isig=0; isig<nSignals; ++isig) {
372 // mix the particles which satisfy only one of the signal branches
373 for(Int_t i1=0;i1<indexes1[isig];++i1) {
374 for(Int_t i2=0;i2<indexes2[isig];++i2) {
375 fCfManagerPair->FillMC(labels1[isig][i1], labels2[isig][i2], isig);
378 // mix the particles which satisfy both branches
379 for(Int_t i1=0;i1<indexes12[isig];++i1) {
380 for(Int_t i2=0; i2<i1; ++i2) {
381 fCfManagerPair->FillMC(labels12[isig][i1], labels12[isig][i2], isig);
384 } // end loop over signals
386 // release the memory
387 for(Int_t isig=0;isig<nSignals;++isig) {
388 delete [] *(labels1+isig);
389 delete [] *(labels2+isig);
390 delete [] *(labels12+isig);
400 //________________________________________________________________
401 void AliDielectron::FillHistogramsTracks(TObjArray **tracks)
404 // Fill Histogram information for tracks after prefilter
405 // ignore mixed events - for prefilter, only single tracks +/- are relevant
408 TString className,className2;
409 Double_t values[AliDielectronVarManager::kNMaxValues];
411 //Fill track information, separately for the track array candidates
412 for (Int_t i=0; i<2; ++i){
413 className.Form("Pre_%s",fgkTrackClassNames[i]);
414 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
415 Int_t ntracks=tracks[i]->GetEntriesFast();
416 for (Int_t itrack=0; itrack<ntracks; ++itrack){
417 AliDielectronVarManager::Fill(tracks[i]->UncheckedAt(itrack), values);
418 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
424 //________________________________________________________________
425 void AliDielectron::FillHistogramsMC(const AliMCEvent *ev, AliVEvent *ev1)
428 // Fill Histogram information for MCEvents
431 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
432 // Fill event information
433 AliDielectronVarManager::Fill(ev1, values); // ESD/AOD information
434 AliDielectronVarManager::Fill(ev, values); // MC truth info
435 if (fHistos->GetHistogramList()->FindObject("MCEvent"))
436 fHistos->FillClass("MCEvent", AliDielectronVarManager::kNMaxValues, values);
440 //________________________________________________________________
441 void AliDielectron::FillHistograms(const AliVEvent *ev, Bool_t pairInfoOnly)
444 // Fill Histogram information for tracks and pairs
447 TString className,className2;
448 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
449 //Fill event information
451 AliDielectronVarManager::Fill(ev, values);
452 if (fHistos->GetHistogramList()->FindObject("Event"))
453 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, values);
456 //Fill track information, separately for the track array candidates
458 for (Int_t i=0; i<4; ++i){
459 className.Form("Track_%s",fgkTrackClassNames[i]);
460 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
461 Int_t ntracks=fTracks[i].GetEntriesFast();
462 for (Int_t itrack=0; itrack<ntracks; ++itrack){
463 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
464 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
469 //Fill Pair information, separately for all pair candidate arrays and the legs
470 TObjArray arrLegs(100);
471 for (Int_t i=0; i<10; ++i){
472 className.Form("Pair_%s",fgkPairClassNames[i]);
473 className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
474 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
475 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
476 if (!pairClass&&!legClass) continue;
477 Int_t ntracks=PairArray(i)->GetEntriesFast();
478 for (Int_t ipair=0; ipair<ntracks; ++ipair){
479 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
481 //fill pair information
483 AliDielectronVarManager::Fill(pair, values);
484 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
487 //fill leg information, don't fill the information twice
489 AliVParticle *d1=pair->GetFirstDaughter();
490 AliVParticle *d2=pair->GetSecondDaughter();
491 if (!arrLegs.FindObject(d1)){
492 AliDielectronVarManager::Fill(d1, values);
493 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
496 if (!arrLegs.FindObject(d2)){
497 AliDielectronVarManager::Fill(d2, values);
498 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
503 if (legClass) arrLegs.Clear();
507 //________________________________________________________________
508 void AliDielectron::FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter/*=kFALSE*/)
511 // Fill Histogram information for pairs and the track in the pair
512 // NOTE: in this funtion the leg information may be filled multiple
513 // times. This funtion is used in the track rotation pairing
514 // and those legs are not saved!
516 TString className,className2;
517 Double_t values[AliDielectronVarManager::kNMaxValues];
519 //Fill Pair information, separately for all pair candidate arrays and the legs
520 TObjArray arrLegs(100);
521 const Int_t type=pair->GetType();
523 className.Form("RejPair_%s",fgkPairClassNames[type]);
524 className2.Form("RejTrack_%s",fgkPairClassNames[type]);
526 className.Form("Pair_%s",fgkPairClassNames[type]);
527 className2.Form("Track_Legs_%s",fgkPairClassNames[type]);
530 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
531 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
533 //fill pair information
535 AliDielectronVarManager::Fill(pair, values);
536 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
540 AliVParticle *d1=pair->GetFirstDaughter();
541 AliDielectronVarManager::Fill(d1, values);
542 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
544 AliVParticle *d2=pair->GetSecondDaughter();
545 AliDielectronVarManager::Fill(d2, values);
546 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
550 //________________________________________________________________
551 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
554 // select tracks and fill track candidate arrays
555 // eventNr = 0: First event, use track arrays 0 and 1
556 // eventNr = 1: Second event, use track arrays 2 and 3
559 Int_t ntracks=ev->GetNumberOfTracks();
560 UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
561 for (Int_t itrack=0; itrack<ntracks; ++itrack){
563 AliVParticle *particle=ev->GetTrack(itrack);
564 //TODO: temporary solution, perhaps think about a better implementation
565 // This is needed to use AliESDpidCuts, which relies on the ESD event
566 // is set as a AliESDtrack attribute... somehow ugly!
567 if (ev->IsA()==AliESDEvent::Class()){
568 AliESDtrack *track=static_cast<AliESDtrack*>(particle);
569 track->SetESDEvent(static_cast<AliESDEvent*>(ev)); //only in trunk...
573 if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
575 //fill selected particle into the corresponding track arrays
576 Short_t charge=particle->Charge();
577 if (charge>0) fTracks[eventNr*2].Add(particle);
578 else if (charge<0) fTracks[eventNr*2+1].Add(particle);
582 //________________________________________________________________
583 void AliDielectron::EventPlanePreFilter(Int_t arr1, Int_t arr2, TObjArray arrTracks1, TObjArray arrTracks2, const AliVEvent *ev, AliEventplane *cevplane)
586 // Prefilter tracks and tracks from pairs
587 // Needed for rejection in the Q-Vector of the event plane
588 // remove contribution of all tracks to the Q-vector that are in invariant mass window
590 AliEventplane *evplane = const_cast<AliVEvent *>(ev)->GetEventplane();
593 // do not change these vectors qref
594 TVector2 *qref = evplane->GetQVector();
597 TVector2 *qrsub1 = evplane->GetQsub1();
598 TVector2 *qrsub2 = evplane->GetQsub2();
601 TVector2 *qstd = dynamic_cast<TVector2 *>(qref->Clone());
602 TVector2 *qssub1 = dynamic_cast<TVector2 *>(qrsub1->Clone());
603 TVector2 *qssub2 = dynamic_cast<TVector2 *>(qrsub2->Clone());
605 // subevents by charge separation sub1+ sub2-
606 if(fLikeSignSubEvents) {
607 qssub1 = dynamic_cast<TVector2 *>(qstd->Clone());
608 qssub2 = dynamic_cast<TVector2 *>(qstd->Clone());
610 Int_t ntracks=ev->GetNumberOfTracks();
613 for (Int_t itrack=0; itrack<ntracks; ++itrack){
614 AliVParticle *particle=ev->GetTrack(itrack);
615 AliVTrack *track= static_cast<AliVTrack*>(particle);
616 if (!track) continue;
618 Double_t cQX = evplane->GetQContributionX(track);
619 Double_t cQY = evplane->GetQContributionY(track);
621 Short_t charge=track->Charge();
622 if (charge<0) qssub1->Set(qssub1->X()-cQX, qssub1->Y()-cQY);
623 if (charge>0) qssub2->Set(qssub2->X()-cQX, qssub2->Y()-cQY);
627 // subevents eta division sub1+ sub2-
628 Bool_t etagap = kFALSE;
629 for (Int_t iCut=0; iCut<fEventPlanePreFilter.GetCuts()->GetEntries();++iCut) {
630 TString cutName=fEventPlanePreFilter.GetCuts()->At(iCut)->GetName();
631 if(cutName.Contains("eta") || cutName.Contains("Eta")) {
634 qssub1 = dynamic_cast<TVector2 *>(qstd->Clone());
635 qssub2 = dynamic_cast<TVector2 *>(qstd->Clone());
637 Int_t ntracks=ev->GetNumberOfTracks();
640 for (Int_t itrack=0; itrack<ntracks; ++itrack){
641 AliVParticle *particle=ev->GetTrack(itrack);
642 AliVTrack *track= static_cast<AliVTrack*>(particle);
643 if (!track) continue;
645 Double_t cQX = evplane->GetQContributionX(track);
646 Double_t cQY = evplane->GetQContributionY(track);
648 Double_t eta=track->Eta();
649 if (eta<0.0) qssub1->Set(qssub1->X()-cQX, qssub1->Y()-cQY);
650 if (eta>0.0) qssub2->Set(qssub2->X()-cQX, qssub2->Y()-cQY);
655 // apply cuts, e.g. etagap
656 if(fEventPlanePreFilter.GetCuts()->GetEntries()) {
657 UInt_t selectedMask=(1<<fEventPlanePreFilter.GetCuts()->GetEntries())-1;
658 Int_t ntracks=ev->GetNumberOfTracks();
659 for (Int_t itrack=0; itrack<ntracks; ++itrack){
660 AliVParticle *particle=ev->GetTrack(itrack);
661 AliVTrack *track= static_cast<AliVTrack*>(particle);
662 if (!track) continue;
665 UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
667 if (cutMask==selectedMask) continue;
672 cQX = evplane->GetQContributionX(track);
673 cQY = evplane->GetQContributionY(track);
675 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
676 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
677 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
678 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
681 qstd->Set(qstd->X()-cQX, qstd->Y()-cQY);
682 qssub1->Set(qssub1->X()-cQXsub1, qssub1->Y()-cQYsub1);
683 qssub2->Set(qssub2->X()-cQXsub2, qssub2->Y()-cQYsub2);
687 if(!qstd || !qssub1 || !qssub2) return;
689 TVector2 *qcorr = dynamic_cast<TVector2 *>(qstd->Clone());
690 TVector2 *qcsub1 = dynamic_cast<TVector2 *>(qssub1->Clone());
691 TVector2 *qcsub2 = dynamic_cast<TVector2 *>(qssub2->Clone());
694 // POI (particle of interest) rejection
695 Int_t pairIndex=GetPairIndex(arr1,arr2);
697 Int_t ntrack1=arrTracks1.GetEntriesFast();
698 Int_t ntrack2=arrTracks2.GetEntriesFast();
699 AliDielectronPair candidate;
701 UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
702 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
704 if (arr1==arr2) end=itrack1;
705 Bool_t accepted=kFALSE;
706 for (Int_t itrack2=0; itrack2<end; ++itrack2){
707 TObject *track1=arrTracks1.UncheckedAt(itrack1);
708 TObject *track2=arrTracks2.UncheckedAt(itrack2);
709 if (!track1 || !track2) continue;
711 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
712 static_cast<AliVTrack*>(track2), fPdgLeg2);
714 candidate.SetType(pairIndex);
715 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
718 UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
720 if (cutMask==selectedMask) continue;
723 //remove the tracks from the Track arrays
724 arrTracks2.AddAt(0x0,itrack2);
726 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
728 //compress the track arrays
729 arrTracks1.Compress();
730 arrTracks2.Compress();
733 //Modify the components: subtract the tracks
734 ntrack1=arrTracks1.GetEntriesFast();
735 ntrack2=arrTracks2.GetEntriesFast();
737 // remove leg1 contribution
738 for (Int_t itrack=0; itrack<ntrack1; ++itrack){
739 AliVTrack *track= static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack));
740 if (!track) continue;
742 Double_t cQX = evplane->GetQContributionX(track);
743 Double_t cQY = evplane->GetQContributionY(track);
744 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
745 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
746 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
747 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
750 qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
751 qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
752 qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
754 // remove leg2 contribution
755 for (Int_t itrack=0; itrack<ntrack2; ++itrack){
756 AliVTrack *track= static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack));
757 if (!track) continue;
759 Double_t cQX = evplane->GetQContributionX(track);
760 Double_t cQY = evplane->GetQContributionY(track);
761 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
762 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
763 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
764 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
767 qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
768 qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
769 qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
772 // set AliEventplane with corrected values
773 cevplane->SetQVector(qcorr);
774 cevplane->SetQsub(qcsub1, qcsub2);
775 AliDielectronVarManager::SetTPCEventPlane(cevplane);
778 //________________________________________________________________
779 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
782 // Prefilter tracks from pairs
783 // Needed for datlitz rejections
784 // remove all tracks from the Single track arrays that pass the cuts in this filter
787 Int_t ntrack1=arrTracks1.GetEntriesFast();
788 Int_t ntrack2=arrTracks2.GetEntriesFast();
789 AliDielectronPair candidate;
791 // flag arrays for track removal
792 Bool_t *bTracks1 = new Bool_t[ntrack1];
793 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1) bTracks1[itrack1]=kFALSE;
794 Bool_t *bTracks2 = new Bool_t[ntrack2];
795 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2) bTracks2[itrack2]=kFALSE;
797 UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
798 UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
800 Int_t nRejPasses = 1; //for fPreFilterUnlikeOnly and no set flag
801 if (fPreFilterAllSigns) nRejPasses = 3;
803 for (Int_t iRP=0; iRP < nRejPasses; ++iRP) {
804 Int_t arr1RP=arr1, arr2RP=arr2;
805 TObjArray *arrTracks1RP=&arrTracks1;
806 TObjArray *arrTracks2RP=&arrTracks2;
807 Bool_t *bTracks1RP = bTracks1;
808 Bool_t *bTracks2RP = bTracks2;
810 case 1: arr1RP=arr1;arr2RP=arr1;
811 arrTracks1RP=&arrTracks1;
812 arrTracks2RP=&arrTracks1;
813 bTracks1RP = bTracks1;
814 bTracks2RP = bTracks1;
816 case 2: arr1RP=arr2;arr2RP=arr2;
817 arrTracks1RP=&arrTracks2;
818 arrTracks2RP=&arrTracks2;
819 bTracks1RP = bTracks2;
820 bTracks2RP = bTracks2;
822 default: ;//nothing to do
824 Int_t ntrack1RP=(*arrTracks1RP).GetEntriesFast();
825 Int_t ntrack2RP=(*arrTracks2RP).GetEntriesFast();
827 Int_t pairIndex=GetPairIndex(arr1RP,arr2RP);
829 for (Int_t itrack1=0; itrack1<ntrack1RP; ++itrack1){
831 if (arr1RP==arr2RP) end=itrack1;
832 for (Int_t itrack2=0; itrack2<end; ++itrack2){
833 TObject *track1=(*arrTracks1RP).UncheckedAt(itrack1);
834 TObject *track2=(*arrTracks2RP).UncheckedAt(itrack2);
835 if (!track1 || !track2) continue;
837 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
838 static_cast<AliVTrack*>(track2), fPdgLeg2);
840 candidate.SetType(pairIndex);
841 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
842 //relate to the production vertex
843 // if (AliDielectronVarManager::GetKFVertex()) candidate.SetProductionVertex(*AliDielectronVarManager::GetKFVertex());
846 UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
849 if (cutMask!=selectedMask) continue;
850 if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
851 if (fHistos) FillHistogramsPair(&candidate,kTRUE);
852 //set flags for track removal
853 bTracks1RP[itrack1]=kTRUE;
854 bTracks2RP[itrack2]=kTRUE;
859 //remove the tracks from the Track arrays
860 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
861 if(bTracks1[itrack1]) arrTracks1.AddAt(0x0, itrack1);
863 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2){
864 if(bTracks2[itrack2]) arrTracks2.AddAt(0x0, itrack2);
871 //compress the track arrays
872 arrTracks1.Compress();
873 arrTracks2.Compress();
875 //apply leg cuts after the pre filter
876 if ( fPairPreFilterLegs.GetCuts()->GetEntries()>0 ) {
877 selectedMask=(1<<fPairPreFilterLegs.GetCuts()->GetEntries())-1;
878 //loop over tracks from array 1
879 for (Int_t itrack=0; itrack<arrTracks1.GetEntriesFast();++itrack){
881 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
884 if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);;
886 arrTracks1.Compress();
888 //in case of like sign don't loop over second array
890 arrTracks2=arrTracks1;
893 //loop over tracks from array 2
894 for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
896 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
898 if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
900 arrTracks2.Compress();
904 //For unlike-sign monitor track-cuts:
905 if (arr1!=arr2&&fHistos) {
906 TObjArray *unlikesignArray[2] = {&arrTracks1,&arrTracks2};
907 FillHistogramsTracks(unlikesignArray);
911 //________________________________________________________________
912 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2)
915 // select pairs and fill pair candidate arrays
918 TObjArray arrTracks1=fTracks[arr1];
919 TObjArray arrTracks2=fTracks[arr2];
921 //process pre filter if set
922 if ((!fPreFilterAllSigns) && (!fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
924 Int_t pairIndex=GetPairIndex(arr1,arr2);
926 Int_t ntrack1=arrTracks1.GetEntriesFast();
927 Int_t ntrack2=arrTracks2.GetEntriesFast();
929 AliDielectronPair *candidate=new AliDielectronPair;
931 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
933 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
935 if (arr1==arr2) end=itrack1;
936 for (Int_t itrack2=0; itrack2<end; ++itrack2){
938 candidate->SetTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
939 static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
940 candidate->SetType(pairIndex);
941 candidate->SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother));
944 UInt_t cutMask=fPairFilter.IsSelected(candidate);
946 //CF manager for the pair
947 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
950 if (cutMask!=selectedMask) continue;
952 //add the candidate to the candidate array
953 PairArray(pairIndex)->Add(candidate);
954 //get a new candidate
955 candidate=new AliDielectronPair;
958 //delete the surplus candidate
962 //________________________________________________________________
963 void AliDielectron::FillPairArrayTR()
966 // select pairs and fill pair candidate arrays
968 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
970 while ( fTrackRotator->NextCombination() ){
971 AliDielectronPair candidate;
972 candidate.SetTracks(&fTrackRotator->GetKFTrackP(), &fTrackRotator->GetKFTrackN(),
973 fTrackRotator->GetVTrackP(),fTrackRotator->GetVTrackN());
974 candidate.SetType(kEv1PMRot);
977 UInt_t cutMask=fPairFilter.IsSelected(&candidate);
979 //CF manager for the pair
980 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,&candidate);
983 if (cutMask==selectedMask) {
984 if(fHistos) FillHistogramsPair(&candidate);
985 if(fStoreRotatedPairs) PairArray(10)->Add(new AliDielectronPair(candidate));
990 //________________________________________________________________
991 void AliDielectron::FillDebugTree()
994 // Fill Histogram information for tracks and pairs
998 for (Int_t i=0; i<10; ++i){
999 Int_t ntracks=PairArray(i)->GetEntriesFast();
1000 for (Int_t ipair=0; ipair<ntracks; ++ipair){
1001 fDebugTree->Fill(static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair)));
1006 //________________________________________________________________
1007 void AliDielectron::SaveDebugTree()
1010 // delete the debug tree, this will also write the tree
1012 if (fDebugTree) fDebugTree->DeleteStreamer();
1016 //__________________________________________________________________
1017 void AliDielectron::AddSignalMC(AliDielectronSignalMC* signal) {
1019 // Add an MC signal to the signals list
1022 fSignalsMC = new TObjArray();
1023 fSignalsMC->SetOwner();
1025 fSignalsMC->Add(signal);