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 <AliKFParticle.h>
52 #include <AliEventplane.h>
53 #include <AliVEvent.h>
54 #include <AliVParticle.h>
55 #include <AliVTrack.h>
56 #include "AliDielectronPair.h"
57 #include "AliDielectronHistos.h"
58 #include "AliDielectronCF.h"
59 #include "AliDielectronMC.h"
60 #include "AliDielectronVarManager.h"
61 #include "AliDielectronTrackRotator.h"
62 #include "AliDielectronDebugTree.h"
63 #include "AliDielectronSignalMC.h"
64 #include "AliDielectronMixingHandler.h"
66 #include "AliDielectron.h"
68 ClassImp(AliDielectron)
70 const char* AliDielectron::fgkTrackClassNames[4] = {
77 const char* AliDielectron::fgkPairClassNames[11] = {
91 //________________________________________________________________
92 AliDielectron::AliDielectron() :
93 TNamed("AliDielectron","AliDielectron"),
94 fEventFilter("EventFilter"),
95 fTrackFilter("TrackFilter"),
96 fPairPreFilter("PairPreFilter"),
97 fPairPreFilterLegs("PairPreFilterLegs"),
98 fPairFilter("PairFilter"),
99 fEventPlanePreFilter("EventPlanePreFilter"),
100 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
109 fPairCandidates(new TObjArray(11)),
114 fPreFilterEventPlane(kFALSE),
115 fLikeSignSubEvents(kFALSE),
116 fPreFilterUnlikeOnly(kFALSE),
117 fPreFilterAllSigns(kFALSE),
119 fStoreRotatedPairs(kFALSE),
120 fDontClearArrays(kFALSE),
121 fEstimatorFilename(""),
122 fTRDpidCorrectionFilename(""),
123 fVZEROCalibrationFilename(""),
124 fVZERORecenteringFilename("")
127 // Default constructor
132 //________________________________________________________________
133 AliDielectron::AliDielectron(const char* name, const char* title) :
135 fEventFilter("EventFilter"),
136 fTrackFilter("TrackFilter"),
137 fPairPreFilter("PairPreFilter"),
138 fPairPreFilterLegs("PairPreFilterLegs"),
139 fPairFilter("PairFilter"),
140 fEventPlanePreFilter("EventPlanePreFilter"),
141 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
150 fPairCandidates(new TObjArray(11)),
155 fPreFilterEventPlane(kFALSE),
156 fLikeSignSubEvents(kFALSE),
157 fPreFilterUnlikeOnly(kFALSE),
158 fPreFilterAllSigns(kFALSE),
160 fStoreRotatedPairs(kFALSE),
161 fDontClearArrays(kFALSE),
162 fEstimatorFilename(""),
163 fTRDpidCorrectionFilename(""),
164 fVZEROCalibrationFilename(""),
165 fVZERORecenteringFilename("")
173 //________________________________________________________________
174 AliDielectron::~AliDielectron()
177 // Default destructor
179 if (fHistoArray) delete fHistoArray;
180 if (fHistos) delete fHistos;
181 if (fPairCandidates) delete fPairCandidates;
182 if (fDebugTree) delete fDebugTree;
183 if (fMixing) delete fMixing;
184 if (fSignalsMC) delete fSignalsMC;
185 if (fCfManagerPair) delete fCfManagerPair;
188 //________________________________________________________________
189 void AliDielectron::Init()
192 // Initialise objects
195 if(GetHasMC()) AliDielectronMC::Instance()->SetHasMC(GetHasMC());
197 InitPairCandidateArrays();
199 if (fCfManagerPair) {
200 fCfManagerPair->SetSignalsMC(fSignalsMC);
201 fCfManagerPair->InitialiseContainer(fPairFilter);
204 fTrackRotator->SetTrackArrays(&fTracks[0],&fTracks[1]);
205 fTrackRotator->SetPdgLegs(fPdgLeg1,fPdgLeg2);
207 if (fDebugTree) fDebugTree->SetDielectron(this);
208 if(fEstimatorFilename.Contains(".root")) AliDielectronVarManager::InitEstimatorAvg(fEstimatorFilename.Data());
209 if(fTRDpidCorrectionFilename.Contains(".root")) AliDielectronVarManager::InitTRDpidEffHistograms(fTRDpidCorrectionFilename.Data());
210 if(fVZEROCalibrationFilename.Contains(".root")) AliDielectronVarManager::SetVZEROCalibrationFile(fVZEROCalibrationFilename.Data());
211 if(fVZERORecenteringFilename.Contains(".root")) AliDielectronVarManager::SetVZERORecenteringFile(fVZERORecenteringFilename.Data());
213 if (fMixing) fMixing->Init(this);
215 fHistoArray->SetSignalsMC(fSignalsMC);
220 //________________________________________________________________
221 void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
224 // Process the events
227 //at least first event is needed!
229 AliError("At least first event must be set!");
233 //in case we have MC load the MC event and process the MC particles
234 if (AliDielectronMC::Instance()->ConnectMCEvent()){
238 //if candidate array doesn't exist, create it
239 if (!fPairCandidates->UncheckedAt(0)) {
240 InitPairCandidateArrays();
245 //mask used to require that all cuts are fulfilled
246 UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
249 if ((ev1&&fEventFilter.IsSelected(ev1)!=selectedMask) ||
250 (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
252 //fill track arrays for the first event
254 FillTrackArrays(ev1);
255 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
259 //fill track arrays for the second event
261 FillTrackArrays(ev2,1);
262 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
265 // TPC event plane correction
266 AliEventplane *cevplane = new AliEventplane();
267 if (ev1 && cevplane && fPreFilterEventPlane && ( fEventPlanePreFilter.GetCuts()->GetEntries()>0 || fEventPlanePOIPreFilter.GetCuts()->GetEntries()>0))
268 EventPlanePreFilter(0, 1, fTracks[0], fTracks[1], ev1, cevplane);
271 AliDielectronVarManager::SetEvent(ev1);
273 //set mixing bin to event data
274 Int_t bin=fMixing->FindBin(AliDielectronVarManager::GetData());
275 AliDielectronVarManager::SetValue(AliDielectronVarManager::kMixingBin,bin);
279 // create pairs and fill pair candidate arrays
280 for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
281 for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
282 FillPairArrays(itrackArr1, itrackArr2);
288 fTrackRotator->SetEvent(ev1);
293 //fill debug tree if a manager is attached
294 if (fDebugTree) FillDebugTree();
296 //process event mixing
298 fMixing->Fill(ev1,this);
299 // FillHistograms(0x0,kTRUE);
302 //in case there is a histogram manager, fill the QA histograms
303 if (fHistos && fSignalsMC) FillMCHistograms(ev1);
304 if (fHistos) FillHistograms(ev1);
308 if (!fDontClearArrays) ClearArrays();
309 AliDielectronVarManager::SetTPCEventPlane(0x0);
313 //________________________________________________________________
314 void AliDielectron::ProcessMC(AliVEvent *ev1)
317 // Process the MC data
320 AliDielectronMC *dieMC=AliDielectronMC::Instance();
322 if (fHistos) FillHistogramsMC(dieMC->GetMCEvent(), ev1);
324 if(!fSignalsMC) return;
325 //loop over all MC data and Fill the CF container if it exist
326 if (!fCfManagerPair && !fHistoArray) return;
327 if(fCfManagerPair) fCfManagerPair->SetPdgMother(fPdgMother);
329 Bool_t bFillCF = (fCfManagerPair ? fCfManagerPair->GetStepForMCtruth() : kFALSE);
330 Bool_t bFillHF = (fHistoArray ? fHistoArray->GetStepForMCGenerated() : kFALSE);
331 if(!bFillCF && !bFillHF) return;
333 // signals to be studied
334 Int_t nSignals = fSignalsMC->GetEntries();
336 // initialize 2D arrays of labels for particles from each MC signal
337 Int_t** labels1; // labels for particles satisfying branch 1
338 Int_t** labels2; // labels for particles satisfying branch 2
339 Int_t** labels12; // labels for particles satisfying both branches
340 labels1 = new Int_t*[nSignals];
341 labels2 = new Int_t*[nSignals];
342 labels12 = new Int_t*[nSignals];
343 Int_t* indexes1=new Int_t[nSignals];
344 Int_t* indexes2=new Int_t[nSignals];
345 Int_t* indexes12=new Int_t[nSignals];
346 for(Int_t isig=0;isig<nSignals;++isig) {
347 *(labels1+isig) = new Int_t[dieMC->GetNMCTracks()];
348 *(labels2+isig) = new Int_t[dieMC->GetNMCTracks()];
349 *(labels12+isig) = new Int_t[dieMC->GetNMCTracks()];
350 for(Int_t ip=0; ip<dieMC->GetNMCTracks();++ip) {
351 labels1[isig][ip] = -1;
352 labels2[isig][ip] = -1;
353 labels12[isig][ip] = -1;
360 Bool_t truth1=kFALSE;
361 Bool_t truth2=kFALSE;
362 // loop over the MC tracks
363 for(Int_t ipart=0; ipart<dieMC->GetNMCTracks(); ++ipart) {
364 for(Int_t isig=0; isig<nSignals; ++isig) { // loop over signals
365 // Proceed only if this signal is required in the pure MC step
366 // NOTE: Some signals can be satisfied by many particles and this leads to high
367 // computation times (e.g. secondary electrons from the GEANT transport). Be aware of this!!
368 if(!((AliDielectronSignalMC*)fSignalsMC->At(isig))->GetFillPureMCStep()) continue;
370 truth1 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 1);
371 truth2 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 2);
373 // particles satisfying both branches are treated separately to avoid double counting during pairing
374 if(truth1 && truth2) {
375 labels12[isig][indexes12[isig]] = ipart;
380 labels1[isig][indexes1[isig]] = ipart;
384 labels2[isig][indexes2[isig]] = ipart;
389 } // end loop over MC particles
391 // Do the pairing and fill the CF container with pure MC info
392 for(Int_t isig=0; isig<nSignals; ++isig) {
393 // mix the particles which satisfy only one of the signal branches
394 for(Int_t i1=0;i1<indexes1[isig];++i1) {
395 for(Int_t i2=0;i2<indexes2[isig];++i2) {
396 if(bFillCF) fCfManagerPair->FillMC(labels1[isig][i1], labels2[isig][i2], isig);
397 if(bFillHF) fHistoArray->Fill(labels1[isig][i1], labels2[isig][i2], isig);
400 // mix the particles which satisfy both branches
401 for(Int_t i1=0;i1<indexes12[isig];++i1) {
402 for(Int_t i2=0; i2<i1; ++i2) {
403 if(bFillCF) fCfManagerPair->FillMC(labels12[isig][i1], labels12[isig][i2], isig);
404 if(bFillHF) fHistoArray->Fill(labels12[isig][i1], labels12[isig][i2], isig);
407 } // end loop over signals
409 // release the memory
410 for(Int_t isig=0;isig<nSignals;++isig) {
411 delete [] *(labels1+isig);
412 delete [] *(labels2+isig);
413 delete [] *(labels12+isig);
423 //________________________________________________________________
424 void AliDielectron::FillHistogramsTracks(TObjArray **tracks)
427 // Fill Histogram information for tracks after prefilter
428 // ignore mixed events - for prefilter, only single tracks +/- are relevant
431 TString className,className2;
432 Double_t values[AliDielectronVarManager::kNMaxValues];
434 //Fill track information, separately for the track array candidates
435 for (Int_t i=0; i<2; ++i){
436 className.Form("Pre_%s",fgkTrackClassNames[i]);
437 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
438 Int_t ntracks=tracks[i]->GetEntriesFast();
439 for (Int_t itrack=0; itrack<ntracks; ++itrack){
440 AliDielectronVarManager::Fill(tracks[i]->UncheckedAt(itrack), values);
441 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
447 //________________________________________________________________
448 void AliDielectron::FillHistogramsMC(const AliMCEvent *ev, AliVEvent *ev1)
451 // Fill Histogram information for MCEvents
454 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
455 // Fill event information
456 AliDielectronVarManager::Fill(ev1, values); // ESD/AOD information
457 AliDielectronVarManager::Fill(ev, values); // MC truth info
458 if (fHistos->GetHistogramList()->FindObject("MCEvent"))
459 fHistos->FillClass("MCEvent", AliDielectronVarManager::kNMaxValues, values);
463 //________________________________________________________________
464 void AliDielectron::FillHistograms(const AliVEvent *ev, Bool_t pairInfoOnly)
467 // Fill Histogram information for tracks and pairs
470 TString className,className2;
471 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
473 //Fill event information
475 if (fHistos->GetHistogramList()->FindObject("Event"))
476 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, AliDielectronVarManager::GetData());
479 //Fill track information, separately for the track array candidates
481 for (Int_t i=0; i<4; ++i){
482 className.Form("Track_%s",fgkTrackClassNames[i]);
483 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
484 Int_t ntracks=fTracks[i].GetEntriesFast();
485 for (Int_t itrack=0; itrack<ntracks; ++itrack){
486 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
487 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
492 //Fill Pair information, separately for all pair candidate arrays and the legs
493 TObjArray arrLegs(100);
494 for (Int_t i=0; i<10; ++i){
495 className.Form("Pair_%s",fgkPairClassNames[i]);
496 className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
497 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
498 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
499 if (!pairClass&&!legClass) continue;
500 Int_t ntracks=PairArray(i)->GetEntriesFast();
501 for (Int_t ipair=0; ipair<ntracks; ++ipair){
502 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
504 //fill pair information
506 AliDielectronVarManager::Fill(pair, values);
507 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
510 //fill leg information, don't fill the information twice
512 AliVParticle *d1=pair->GetFirstDaughter();
513 AliVParticle *d2=pair->GetSecondDaughter();
514 if (!arrLegs.FindObject(d1)){
515 AliDielectronVarManager::Fill(d1, values);
516 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
519 if (!arrLegs.FindObject(d2)){
520 AliDielectronVarManager::Fill(d2, values);
521 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
526 if (legClass) arrLegs.Clear();
530 //________________________________________________________________
531 void AliDielectron::FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter/*=kFALSE*/)
534 // Fill Histogram information for pairs and the track in the pair
535 // NOTE: in this funtion the leg information may be filled multiple
536 // times. This funtion is used in the track rotation pairing
537 // and those legs are not saved!
539 TString className,className2;
540 Double_t values[AliDielectronVarManager::kNMaxValues];
542 //Fill Pair information, separately for all pair candidate arrays and the legs
543 TObjArray arrLegs(100);
544 const Int_t type=pair->GetType();
546 className.Form("RejPair_%s",fgkPairClassNames[type]);
547 className2.Form("RejTrack_%s",fgkPairClassNames[type]);
549 className.Form("Pair_%s",fgkPairClassNames[type]);
550 className2.Form("Track_Legs_%s",fgkPairClassNames[type]);
553 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
554 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
556 //fill pair information
558 AliDielectronVarManager::Fill(pair, values);
559 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
563 AliVParticle *d1=pair->GetFirstDaughter();
564 AliDielectronVarManager::Fill(d1, values);
565 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
567 AliVParticle *d2=pair->GetSecondDaughter();
568 AliDielectronVarManager::Fill(d2, values);
569 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
573 //________________________________________________________________
574 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
577 // select tracks and fill track candidate arrays
578 // eventNr = 0: First event, use track arrays 0 and 1
579 // eventNr = 1: Second event, use track arrays 2 and 3
582 Int_t ntracks=ev->GetNumberOfTracks();
584 UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
585 for (Int_t itrack=0; itrack<ntracks; ++itrack){
587 AliVParticle *particle=ev->GetTrack(itrack);
590 if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
592 //fill selected particle into the corresponding track arrays
593 Short_t charge=particle->Charge();
594 if (charge>0) fTracks[eventNr*2].Add(particle);
595 else if (charge<0) fTracks[eventNr*2+1].Add(particle);
599 //________________________________________________________________
600 void AliDielectron::EventPlanePreFilter(Int_t arr1, Int_t arr2, TObjArray arrTracks1, TObjArray arrTracks2, const AliVEvent *ev, AliEventplane *cevplane)
603 // Prefilter tracks and tracks from pairs
604 // Needed for rejection in the Q-Vector of the event plane
605 // remove contribution of all tracks to the Q-vector that are in invariant mass window
608 // TODO: how should we implement the filtering for the nanoADOs
610 AliEventplane *evplane = const_cast<AliVEvent *>(ev)->GetEventplane();
613 // do not change these vectors qref
614 TVector2 * const qref = evplane->GetQVector();
617 TVector2 *qrsub1 = evplane->GetQsub1();
618 TVector2 *qrsub2 = evplane->GetQsub2();
621 TVector2 *qcorr = new TVector2(*qref);
622 TVector2 *qcsub1 = 0x0;
623 TVector2 *qcsub2 = 0x0;
624 // printf("qrsub1 %p %f \n",qrsub1,qrsub1->X());
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")) etagap=kTRUE;
634 // subevent separation
635 if(fLikeSignSubEvents || etagap) {
636 qcsub1 = new TVector2(*qcorr);
637 qcsub2 = new TVector2(*qcorr);
639 Int_t ntracks=ev->GetNumberOfTracks();
642 for (Int_t itrack=0; itrack<ntracks; ++itrack){
643 AliVParticle *particle=ev->GetTrack(itrack);
644 AliVTrack *track= static_cast<AliVTrack*>(particle);
645 if (!track) continue;
647 Double_t cQX = evplane->GetQContributionX(track);
648 Double_t cQY = evplane->GetQContributionY(track);
650 // by charge sub1+ sub2-
651 if(fLikeSignSubEvents) {
652 Short_t charge=track->Charge();
653 if (charge<0) qcsub1->Set(qcsub1->X()-cQX, qcsub1->Y()-cQY);
654 if (charge>0) qcsub2->Set(qcsub2->X()-cQX, qcsub2->Y()-cQY);
656 // by eta sub1+ sub2-
658 Double_t eta=track->Eta();
659 if (eta<0.0) qcsub1->Set(qcsub1->X()-cQX, qcsub1->Y()-cQY);
660 if (eta>0.0) qcsub2->Set(qcsub2->X()-cQX, qcsub2->Y()-cQY);
666 qcsub1 = new TVector2(*qrsub1);
667 qcsub2 = new TVector2(*qrsub2);
670 // apply cuts, e.g. etagap
671 if(fEventPlanePreFilter.GetCuts()->GetEntries()) {
672 UInt_t selectedMask=(1<<fEventPlanePreFilter.GetCuts()->GetEntries())-1;
673 Int_t ntracks=ev->GetNumberOfTracks();
674 for (Int_t itrack=0; itrack<ntracks; ++itrack){
675 AliVParticle *particle=ev->GetTrack(itrack);
676 AliVTrack *track= static_cast<AliVTrack*>(particle);
677 if (!track) continue;
680 UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
682 if (cutMask==selectedMask) continue;
687 cQX = evplane->GetQContributionX(track);
688 cQY = evplane->GetQContributionY(track);
690 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
691 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
692 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
693 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
696 qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
697 qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
698 qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
702 // POI (particle of interest) rejection
703 Int_t pairIndex=GetPairIndex(arr1,arr2);
705 Int_t ntrack1=arrTracks1.GetEntriesFast();
706 Int_t ntrack2=arrTracks2.GetEntriesFast();
707 AliDielectronPair candidate;
708 candidate.SetKFUsage(fUseKF);
710 UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
711 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
713 if (arr1==arr2) end=itrack1;
714 Bool_t accepted=kFALSE;
715 for (Int_t itrack2=0; itrack2<end; ++itrack2){
716 TObject *track1=arrTracks1.UncheckedAt(itrack1);
717 TObject *track2=arrTracks2.UncheckedAt(itrack2);
718 if (!track1 || !track2) continue;
720 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
721 static_cast<AliVTrack*>(track2), fPdgLeg2);
723 candidate.SetType(pairIndex);
724 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
727 UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
729 if (cutMask==selectedMask) continue;
732 //remove the tracks from the Track arrays
733 arrTracks2.AddAt(0x0,itrack2);
735 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
737 //compress the track arrays
738 arrTracks1.Compress();
739 arrTracks2.Compress();
742 //Modify the components: subtract the tracks
743 ntrack1=arrTracks1.GetEntriesFast();
744 ntrack2=arrTracks2.GetEntriesFast();
746 // remove leg1 contribution
747 for (Int_t itrack=0; itrack<ntrack1; ++itrack){
748 AliVTrack *track= static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack));
749 if (!track) continue;
751 Double_t cQX = evplane->GetQContributionX(track);
752 Double_t cQY = evplane->GetQContributionY(track);
753 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
754 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
755 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
756 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
759 qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
760 qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
761 qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
763 // remove leg2 contribution
764 for (Int_t itrack=0; itrack<ntrack2; ++itrack){
765 AliVTrack *track= static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack));
766 if (!track) continue;
768 Double_t cQX = evplane->GetQContributionX(track);
769 Double_t cQY = evplane->GetQContributionY(track);
770 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
771 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
772 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
773 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
776 qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
777 qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
778 qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
781 // printf("qrsub1 %p %f \t qcsub1 %p %f \n",qrsub1,qrsub1->X(),qcsub1,qcsub1->X());
782 // set AliEventplane with corrected values
783 cevplane->SetQVector(qcorr);
784 cevplane->SetQsub(qcsub1, qcsub2);
785 AliDielectronVarManager::SetTPCEventPlane(cevplane);
788 //________________________________________________________________
789 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
792 // Prefilter tracks from pairs
793 // Needed for datlitz rejections
794 // remove all tracks from the Single track arrays that pass the cuts in this filter
797 Int_t ntrack1=arrTracks1.GetEntriesFast();
798 Int_t ntrack2=arrTracks2.GetEntriesFast();
799 AliDielectronPair candidate;
800 candidate.SetKFUsage(fUseKF);
801 // flag arrays for track removal
802 Bool_t *bTracks1 = new Bool_t[ntrack1];
803 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1) bTracks1[itrack1]=kFALSE;
804 Bool_t *bTracks2 = new Bool_t[ntrack2];
805 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2) bTracks2[itrack2]=kFALSE;
807 UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
808 UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
810 Int_t nRejPasses = 1; //for fPreFilterUnlikeOnly and no set flag
811 if (fPreFilterAllSigns) nRejPasses = 3;
813 for (Int_t iRP=0; iRP < nRejPasses; ++iRP) {
814 Int_t arr1RP=arr1, arr2RP=arr2;
815 TObjArray *arrTracks1RP=&arrTracks1;
816 TObjArray *arrTracks2RP=&arrTracks2;
817 Bool_t *bTracks1RP = bTracks1;
818 Bool_t *bTracks2RP = bTracks2;
820 case 1: arr1RP=arr1;arr2RP=arr1;
821 arrTracks1RP=&arrTracks1;
822 arrTracks2RP=&arrTracks1;
823 bTracks1RP = bTracks1;
824 bTracks2RP = bTracks1;
826 case 2: arr1RP=arr2;arr2RP=arr2;
827 arrTracks1RP=&arrTracks2;
828 arrTracks2RP=&arrTracks2;
829 bTracks1RP = bTracks2;
830 bTracks2RP = bTracks2;
832 default: ;//nothing to do
834 Int_t ntrack1RP=(*arrTracks1RP).GetEntriesFast();
835 Int_t ntrack2RP=(*arrTracks2RP).GetEntriesFast();
837 Int_t pairIndex=GetPairIndex(arr1RP,arr2RP);
839 for (Int_t itrack1=0; itrack1<ntrack1RP; ++itrack1){
841 if (arr1RP==arr2RP) end=itrack1;
842 for (Int_t itrack2=0; itrack2<end; ++itrack2){
843 TObject *track1=(*arrTracks1RP).UncheckedAt(itrack1);
844 TObject *track2=(*arrTracks2RP).UncheckedAt(itrack2);
845 if (!track1 || !track2) continue;
847 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
848 static_cast<AliVTrack*>(track2), fPdgLeg2);
850 candidate.SetType(pairIndex);
851 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
852 //relate to the production vertex
853 // if (AliDielectronVarManager::GetKFVertex()) candidate.SetProductionVertex(*AliDielectronVarManager::GetKFVertex());
856 UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
859 if (cutMask!=selectedMask) continue;
860 if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
861 if (fHistos) FillHistogramsPair(&candidate,kTRUE);
862 //set flags for track removal
863 bTracks1RP[itrack1]=kTRUE;
864 bTracks2RP[itrack2]=kTRUE;
869 //remove the tracks from the Track arrays
870 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
871 if(bTracks1[itrack1]) arrTracks1.AddAt(0x0, itrack1);
873 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2){
874 if(bTracks2[itrack2]) arrTracks2.AddAt(0x0, itrack2);
881 //compress the track arrays
882 arrTracks1.Compress();
883 arrTracks2.Compress();
885 //apply leg cuts after the pre filter
886 if ( fPairPreFilterLegs.GetCuts()->GetEntries()>0 ) {
887 selectedMask=(1<<fPairPreFilterLegs.GetCuts()->GetEntries())-1;
888 //loop over tracks from array 1
889 for (Int_t itrack=0; itrack<arrTracks1.GetEntriesFast();++itrack){
891 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
894 if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);;
896 arrTracks1.Compress();
898 //in case of like sign don't loop over second array
900 arrTracks2=arrTracks1;
903 //loop over tracks from array 2
904 for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
906 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
908 if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
910 arrTracks2.Compress();
914 //For unlike-sign monitor track-cuts:
915 if (arr1!=arr2&&fHistos) {
916 TObjArray *unlikesignArray[2] = {&arrTracks1,&arrTracks2};
917 FillHistogramsTracks(unlikesignArray);
921 //________________________________________________________________
922 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2)
925 // select pairs and fill pair candidate arrays
928 TObjArray arrTracks1=fTracks[arr1];
929 TObjArray arrTracks2=fTracks[arr2];
931 //process pre filter if set
932 if ((!fPreFilterAllSigns) && (!fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
934 Int_t pairIndex=GetPairIndex(arr1,arr2);
936 Int_t ntrack1=arrTracks1.GetEntriesFast();
937 Int_t ntrack2=arrTracks2.GetEntriesFast();
939 AliDielectronPair *candidate=new AliDielectronPair;
940 candidate->SetKFUsage(fUseKF);
942 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
944 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
946 if (arr1==arr2) end=itrack1;
947 for (Int_t itrack2=0; itrack2<end; ++itrack2){
949 candidate->SetTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
950 static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
951 candidate->SetType(pairIndex);
952 Int_t label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother);
953 candidate->SetLabel(label);
954 if (label>-1) candidate->SetPdgCode(fPdgMother);
956 // check for gamma kf particle
957 label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,22);
959 candidate->SetGammaTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
960 static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
961 // should we set the pdgmothercode and the label
965 UInt_t cutMask=fPairFilter.IsSelected(candidate);
967 //CF manager for the pair
968 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
969 //histogram array for the pair
970 if (fHistoArray) fHistoArray->Fill(pairIndex,candidate);
973 if (cutMask!=selectedMask) continue;
975 //add the candidate to the candidate array
976 PairArray(pairIndex)->Add(candidate);
977 //get a new candidate
978 candidate=new AliDielectronPair;
979 candidate->SetKFUsage(fUseKF);
982 //delete the surplus candidate
986 //________________________________________________________________
987 void AliDielectron::FillPairArrayTR()
990 // select pairs and fill pair candidate arrays
992 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
994 while ( fTrackRotator->NextCombination() ){
995 AliDielectronPair candidate;
996 candidate.SetKFUsage(fUseKF);
997 candidate.SetTracks(&fTrackRotator->GetKFTrackP(), &fTrackRotator->GetKFTrackN(),
998 fTrackRotator->GetVTrackP(),fTrackRotator->GetVTrackN());
999 candidate.SetType(kEv1PMRot);
1002 UInt_t cutMask=fPairFilter.IsSelected(&candidate);
1004 //CF manager for the pair
1005 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,&candidate);
1006 //histogram array for the pair
1007 if (fHistoArray) fHistoArray->Fill((Int_t)kEv1PMRot,&candidate);
1010 if (cutMask==selectedMask) {
1011 if(fHistos) FillHistogramsPair(&candidate);
1012 if(fStoreRotatedPairs) PairArray(kEv1PMRot)->Add(new AliDielectronPair(candidate));
1017 //________________________________________________________________
1018 void AliDielectron::FillDebugTree()
1021 // Fill Histogram information for tracks and pairs
1025 for (Int_t i=0; i<10; ++i){
1026 Int_t ntracks=PairArray(i)->GetEntriesFast();
1027 for (Int_t ipair=0; ipair<ntracks; ++ipair){
1028 fDebugTree->Fill(static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair)));
1033 //________________________________________________________________
1034 void AliDielectron::SaveDebugTree()
1037 // delete the debug tree, this will also write the tree
1039 if (fDebugTree) fDebugTree->DeleteStreamer();
1043 //__________________________________________________________________
1044 void AliDielectron::AddSignalMC(AliDielectronSignalMC* signal) {
1046 // Add an MC signal to the signals list
1049 fSignalsMC = new TObjArray();
1050 fSignalsMC->SetOwner();
1052 fSignalsMC->Add(signal);
1054 //________________________________________________________________
1055 void AliDielectron::FillMCHistograms(const AliVEvent *ev) {
1057 // fill QA MC histograms for pairs and legs of all added mc signals
1060 if (!fSignalsMC) return;
1061 TString className,className2;
1062 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
1063 AliDielectronVarManager::Fill(ev, values); // get event informations
1064 //loop over all added mc signals
1065 for(Int_t isig=0; isig<fSignalsMC->GetEntries(); isig++) {
1067 className.Form("Pair_%s",fSignalsMC->At(isig)->GetName());
1068 className2.Form("Track_Legs_%s",fSignalsMC->At(isig)->GetName());
1069 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
1070 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
1071 if(!pairClass && !legClass) return;
1073 Int_t ntracks=PairArray(AliDielectron::kEv1PM)->GetEntriesFast(); // only SE +-
1074 for (Int_t ipair=0; ipair<ntracks; ++ipair){
1075 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(AliDielectron::kEv1PM)->UncheckedAt(ipair));
1077 Bool_t isMCtruth = AliDielectronMC::Instance()->IsMCTruth(pair, (AliDielectronSignalMC*)fSignalsMC->At(isig));
1079 //fill pair information
1081 AliDielectronVarManager::Fill(pair, values);
1082 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1084 //fill leg information, both + and - in the same histo
1086 AliDielectronVarManager::Fill(pair->GetFirstDaughter(),values);
1087 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1088 AliDielectronVarManager::Fill(pair->GetSecondDaughter(),values);
1089 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);