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 ///////////////////////////////////////////////////////////////////////////
51 #include <AliKFParticle.h>
53 #include <AliESDInputHandler.h>
54 #include <AliAnalysisManager.h>
55 #include <AliEPSelectionTask.h>
56 #include <AliEventplane.h>
57 #include <AliVEvent.h>
58 #include <AliVParticle.h>
59 #include <AliVTrack.h>
60 #include "AliDielectronPair.h"
61 #include "AliDielectronHistos.h"
62 #include "AliDielectronCF.h"
63 #include "AliDielectronMC.h"
64 #include "AliDielectronVarManager.h"
65 #include "AliDielectronTrackRotator.h"
66 #include "AliDielectronDebugTree.h"
67 #include "AliDielectronSignalMC.h"
68 #include "AliDielectronMixingHandler.h"
69 #include "AliDielectronPairLegCuts.h"
70 #include "AliDielectronV0Cuts.h"
71 #include "AliDielectronPID.h"
73 #include "AliDielectron.h"
75 ClassImp(AliDielectron)
77 const char* AliDielectron::fgkTrackClassNames[4] = {
84 const char* AliDielectron::fgkPairClassNames[11] = {
98 //________________________________________________________________
99 AliDielectron::AliDielectron() :
100 TNamed("AliDielectron","AliDielectron"),
103 fPostPIDCntrdCorr(0x0),
104 fPostPIDWdthCorr(0x0),
107 fEventFilter("EventFilter"),
108 fTrackFilter("TrackFilter"),
109 fPairPreFilter("PairPreFilter"),
110 fPairPreFilterLegs("PairPreFilterLegs"),
111 fPairFilter("PairFilter"),
112 fEventPlanePreFilter("EventPlanePreFilter"),
113 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
123 fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
124 fPairCandidates(new TObjArray(11)),
129 fPreFilterEventPlane(kFALSE),
130 fLikeSignSubEvents(kFALSE),
131 fPreFilterUnlikeOnly(kFALSE),
132 fPreFilterAllSigns(kFALSE),
134 fStoreRotatedPairs(kFALSE),
135 fDontClearArrays(kFALSE),
136 fEventProcess(kTRUE),
137 fEstimatorFilename(""),
138 fTRDpidCorrectionFilename(""),
139 fVZEROCalibrationFilename(""),
140 fVZERORecenteringFilename(""),
141 fZDCRecenteringFilename("")
145 // Default constructor
150 //________________________________________________________________
151 AliDielectron::AliDielectron(const char* name, const char* title) :
155 fPostPIDCntrdCorr(0x0),
156 fPostPIDWdthCorr(0x0),
159 fEventFilter("EventFilter"),
160 fTrackFilter("TrackFilter"),
161 fPairPreFilter("PairPreFilter"),
162 fPairPreFilterLegs("PairPreFilterLegs"),
163 fPairFilter("PairFilter"),
164 fEventPlanePreFilter("EventPlanePreFilter"),
165 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
175 fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
176 fPairCandidates(new TObjArray(11)),
181 fPreFilterEventPlane(kFALSE),
182 fLikeSignSubEvents(kFALSE),
183 fPreFilterUnlikeOnly(kFALSE),
184 fPreFilterAllSigns(kFALSE),
186 fStoreRotatedPairs(kFALSE),
187 fDontClearArrays(kFALSE),
188 fEventProcess(kTRUE),
189 fEstimatorFilename(""),
190 fTRDpidCorrectionFilename(""),
191 fVZEROCalibrationFilename(""),
192 fVZERORecenteringFilename(""),
193 fZDCRecenteringFilename("")
201 //________________________________________________________________
202 AliDielectron::~AliDielectron()
205 // Default destructor
207 if (fQAmonitor) delete fQAmonitor;
208 if (fPostPIDCntrdCorr) delete fPostPIDCntrdCorr;
209 if (fPostPIDWdthCorr) delete fPostPIDWdthCorr;
210 if (fLegEffMap) delete fLegEffMap;
211 if (fPairEffMap) delete fPairEffMap;
212 if (fHistos) delete fHistos;
213 if (fUsedVars) delete fUsedVars;
214 if (fPairCandidates && fEventProcess) delete fPairCandidates;
215 if (fDebugTree) delete fDebugTree;
216 if (fMixing) delete fMixing;
217 if (fSignalsMC) delete fSignalsMC;
218 if (fCfManagerPair) delete fCfManagerPair;
219 if (fHistoArray) delete fHistoArray;
222 //________________________________________________________________
223 void AliDielectron::Init()
226 // Initialise objects
229 if(GetHasMC()) AliDielectronMC::Instance()->SetHasMC(GetHasMC());
231 if(fEventProcess) InitPairCandidateArrays();
233 if (fCfManagerPair) {
234 fCfManagerPair->SetSignalsMC(fSignalsMC);
235 fCfManagerPair->InitialiseContainer(fPairFilter);
238 fTrackRotator->SetTrackArrays(&fTracks[0],&fTracks[1]);
239 fTrackRotator->SetPdgLegs(fPdgLeg1,fPdgLeg2);
241 if (fDebugTree) fDebugTree->SetDielectron(this);
243 if(fEstimatorFilename.Contains(".root")) AliDielectronVarManager::InitEstimatorAvg(fEstimatorFilename.Data());
244 if(fTRDpidCorrectionFilename.Contains(".root")) AliDielectronVarManager::InitTRDpidEffHistograms(fTRDpidCorrectionFilename.Data());
245 if(fVZEROCalibrationFilename.Contains(".root")) AliDielectronVarManager::SetVZEROCalibrationFile(fVZEROCalibrationFilename.Data());
246 if(fVZERORecenteringFilename.Contains(".root")) AliDielectronVarManager::SetVZERORecenteringFile(fVZERORecenteringFilename.Data());
247 if(fZDCRecenteringFilename.Contains(".root")) AliDielectronVarManager::SetZDCRecenteringFile(fZDCRecenteringFilename.Data());
249 if (fMixing) fMixing->Init(this);
251 fHistoArray->SetSignalsMC(fSignalsMC);
255 if(fPostPIDCntrdCorr) AliDielectronPID::SetCentroidCorrFunction(fPostPIDCntrdCorr);
256 if(fPostPIDWdthCorr) AliDielectronPID::SetWidthCorrFunction(fPostPIDWdthCorr);
259 AliDielectronPairLegCuts *trk2leg = new AliDielectronPairLegCuts("trk2leg","trk2leg");
260 // move all track cuts (if any) into pair leg cuts
261 TIter listIterator(fTrackFilter.GetCuts());
262 while (AliAnalysisCuts *thisCut = (AliAnalysisCuts*) listIterator()) {
263 trk2leg->GetLeg1Filter().AddCuts((AliAnalysisCuts*)thisCut->Clone());
264 trk2leg->GetLeg2Filter().AddCuts((AliAnalysisCuts*)thisCut->Clone());
266 // add pair leg cuts to pair filter
267 fPairFilter.AddCuts(trk2leg);
271 fQAmonitor = new AliDielectronCutQA(Form("QAcuts_%s",GetName()),"QAcuts");
272 fQAmonitor->AddTrackFilter(&fTrackFilter);
273 fQAmonitor->AddPairFilter(&fPairFilter);
274 fQAmonitor->AddEventFilter(&fEventFilter);
279 (*fUsedVars)|= (*fHistos->GetUsedVars());
284 //________________________________________________________________
286 void AliDielectron::Process(TObjArray *arr)
289 // Process the pair array
293 fPairCandidates = arr;
295 //fill debug tree if a manager is attached
296 // if (fDebugTree) FillDebugTree();
297 //in case there is a histogram manager, fill the QA histograms
298 // if (fHistos && fSignalsMC) FillMCHistograms(ev1);
300 // apply cuts and fill output
301 if (fHistos) FillHistogramsFromPairArray();
303 // never clear arrays !!!!
308 //________________________________________________________________
309 Bool_t AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
312 // Process the events
315 //at least first event is needed!
317 AliError("At least first event must be set!");
321 // modify event numbers in MC so that we can identify new events
322 // in AliDielectronV0Cuts (not neeeded for collision data)
324 ev1->SetBunchCrossNumber(1);
325 ev1->SetOrbitNumber(1);
326 ev1->SetPeriodNumber(1);
330 AliDielectronVarManager::SetEvent(ev1);
332 //set mixing bin to event data
333 Int_t bin=fMixing->FindBin(AliDielectronVarManager::GetData());
334 AliDielectronVarManager::SetValue(AliDielectronVarManager::kMixingBin,bin);
337 // set efficiency maps
338 AliDielectronVarManager::SetLegEffMap(fLegEffMap);
339 AliDielectronVarManager::SetPairEffMap(fPairEffMap);
341 //in case we have MC load the MC event and process the MC particles
342 // why do not apply the event cuts first ????
343 if (AliDielectronMC::Instance()->ConnectMCEvent()){
347 //if candidate array doesn't exist, create it
348 if (!fPairCandidates->UncheckedAt(0)) {
349 InitPairCandidateArrays();
354 //mask used to require that all cuts are fulfilled
355 UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
358 UInt_t cutmask = fEventFilter.IsSelected(ev1);
359 if(fCutQA) fQAmonitor->FillAll(ev1);
360 if(fCutQA) fQAmonitor->Fill(cutmask,ev1);
361 if ((ev1&&cutmask!=selectedMask) ||
362 (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return 0;
364 //fill track arrays for the first event
366 FillTrackArrays(ev1);
367 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
371 //fill track arrays for the second event
373 FillTrackArrays(ev2,1);
374 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
377 // TPC event plane correction
378 if (ev1 && fPreFilterEventPlane && ( fEventPlanePreFilter.GetCuts()->GetEntries()>0 || fEventPlanePOIPreFilter.GetCuts()->GetEntries()>0))
379 EventPlanePreFilter(0, 1, fTracks[0], fTracks[1], ev1);
382 // create pairs and fill pair candidate arrays
383 for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
384 for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
385 if(!fProcessLS && GetPairIndex(itrackArr1,itrackArr2)!=kEv1PM) continue;
386 FillPairArrays(itrackArr1, itrackArr2);
392 fTrackRotator->SetEvent(ev1);
397 //fill debug tree if a manager is attached
398 if (fDebugTree) FillDebugTree();
400 //process event mixing
402 fMixing->Fill(ev1,this);
403 // FillHistograms(0x0,kTRUE);
406 // fill candidate variables
407 Double_t ntracks = fTracks[0].GetEntriesFast() + fTracks[1].GetEntriesFast();
408 Double_t npairs = PairArray(AliDielectron::kEv1PM)->GetEntriesFast();
409 AliDielectronVarManager::SetValue(AliDielectronVarManager::kTracks, ntracks);
410 AliDielectronVarManager::SetValue(AliDielectronVarManager::kPairs, npairs);
412 //in case there is a histogram manager, fill the QA histograms
413 if (fHistos && fSignalsMC) FillMCHistograms(ev1);
414 if (fHistos) FillHistograms(ev1);
418 if (!fDontClearArrays) ClearArrays();
420 // reset TPC EP and unique identifiers for v0 cut class
421 AliDielectronVarManager::SetTPCEventPlane(0x0);
422 if(GetHasMC()) { // only for MC needed
423 for (Int_t iCut=0; iCut<fTrackFilter.GetCuts()->GetEntries();++iCut) {
424 if ( fTrackFilter.GetCuts()->At(iCut)->IsA() == AliDielectronV0Cuts::Class() )
425 ((AliDielectronV0Cuts*)fTrackFilter.GetCuts()->At(iCut))->ResetUniqueEventNumbers();
433 //________________________________________________________________
434 void AliDielectron::ProcessMC(AliVEvent *ev1)
437 // Process the MC data
440 AliDielectronMC *dieMC=AliDielectronMC::Instance();
442 if (fHistos) FillHistogramsMC(dieMC->GetMCEvent(), ev1);
445 if(!dieMC->GetNMCTracks()) return;
447 // signals to be studied
448 if(!fSignalsMC) return;
449 Int_t nSignals = fSignalsMC->GetEntries();
450 if(!nSignals) return;
452 //loop over all MC data and Fill the HF, CF containers and histograms if they exist
453 if(fCfManagerPair) fCfManagerPair->SetPdgMother(fPdgMother);
455 Bool_t bFillCF = (fCfManagerPair ? fCfManagerPair->GetStepForMCtruth() : kFALSE);
456 Bool_t bFillHF = (fHistoArray ? fHistoArray->GetStepForMCGenerated() : kFALSE);
457 Bool_t bFillHist = kFALSE;
459 const THashList *histlist = fHistos->GetHistogramList();
460 for(Int_t isig=0;isig<nSignals;isig++) {
461 TString sigName = fSignalsMC->At(isig)->GetName();
462 bFillHist |= histlist->FindObject(Form("Pair_%s_MCtruth",sigName.Data()))!=0x0;
463 bFillHist |= histlist->FindObject(Form("Track_Leg_%s_MCtruth",sigName.Data()))!=0x0;
464 bFillHist |= histlist->FindObject(Form("Track_%s_%s_MCtruth",fgkPairClassNames[1],sigName.Data()))!=0x0;
468 // check if there is anything to fill
469 if(!bFillCF && !bFillHF && !bFillHist) return;
472 // initialize 2D arrays of labels for particles from each MC signal
473 Int_t** labels1; // labels for particles satisfying branch 1
474 Int_t** labels2; // labels for particles satisfying branch 2
475 Int_t** labels12; // labels for particles satisfying both branches
476 labels1 = new Int_t*[nSignals];
477 labels2 = new Int_t*[nSignals];
478 labels12 = new Int_t*[nSignals];
479 Int_t* indexes1=new Int_t[nSignals];
480 Int_t* indexes2=new Int_t[nSignals];
481 Int_t* indexes12=new Int_t[nSignals];
482 for(Int_t isig=0;isig<nSignals;++isig) {
483 *(labels1+isig) = new Int_t[dieMC->GetNMCTracks()];
484 *(labels2+isig) = new Int_t[dieMC->GetNMCTracks()];
485 *(labels12+isig) = new Int_t[dieMC->GetNMCTracks()];
486 for(Int_t ip=0; ip<dieMC->GetNMCTracks();++ip) {
487 labels1[isig][ip] = -1;
488 labels2[isig][ip] = -1;
489 labels12[isig][ip] = -1;
496 Bool_t truth1=kFALSE;
497 Bool_t truth2=kFALSE;
498 // loop over the MC tracks
499 for(Int_t ipart=0; ipart<dieMC->GetNMCTracks(); ++ipart) {
500 for(Int_t isig=0; isig<nSignals; ++isig) { // loop over signals
501 // Proceed only if this signal is required in the pure MC step
502 // NOTE: Some signals can be satisfied by many particles and this leads to high
503 // computation times (e.g. secondary electrons from the GEANT transport). Be aware of this!!
504 if(!((AliDielectronSignalMC*)fSignalsMC->At(isig))->GetFillPureMCStep()) continue;
506 truth1 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 1);
507 truth2 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 2);
509 // particles satisfying both branches are treated separately to avoid double counting during pairing
510 if(truth1 && truth2) {
511 labels12[isig][indexes12[isig]] = ipart;
516 labels1[isig][indexes1[isig]] = ipart;
520 labels2[isig][indexes2[isig]] = ipart;
525 } // end loop over MC particles
527 // Do the pairing and fill the CF container with pure MC info
528 for(Int_t isig=0; isig<nSignals; ++isig) {
529 // printf("INDEXES: %d-%d both%d\n",indexes1[isig],indexes2[isig],indexes12[isig]);
530 // mix the particles which satisfy only one of the signal branches
531 for(Int_t i1=0;i1<indexes1[isig];++i1) {
532 if(!indexes2[isig]) FillMCHistograms(labels1[isig][i1], -1, isig); // (e.g. single electrons only, no pairs)
533 for(Int_t i2=0;i2<indexes2[isig];++i2) {
534 if(bFillCF) fCfManagerPair->FillMC(labels1[isig][i1], labels2[isig][i2], isig);
535 if(bFillHF) fHistoArray->Fill(labels1[isig][i1], labels2[isig][i2], isig);
536 FillMCHistograms(labels1[isig][i1], labels2[isig][i2], isig);
539 // mix the particles which satisfy both branches
540 for(Int_t i1=0;i1<indexes12[isig];++i1) {
541 for(Int_t i2=0; i2<i1; ++i2) {
542 if(bFillCF) fCfManagerPair->FillMC(labels12[isig][i1], labels12[isig][i2], isig);
543 if(bFillHF) fHistoArray->Fill(labels12[isig][i1], labels12[isig][i2], isig);
544 FillMCHistograms(labels12[isig][i1], labels12[isig][i2], isig);
547 } // end loop over signals
549 // release the memory
550 for(Int_t isig=0;isig<nSignals;++isig) {
551 delete [] *(labels1+isig);
552 delete [] *(labels2+isig);
553 delete [] *(labels12+isig);
563 //________________________________________________________________
564 void AliDielectron::FillHistogramsTracks(TObjArray **tracks)
567 // Fill Histogram information for tracks after prefilter
568 // ignore mixed events - for prefilter, only single tracks +/- are relevant
571 TString className,className2;
572 Double_t values[AliDielectronVarManager::kNMaxValues];
573 AliDielectronVarManager::SetFillMap(fUsedVars);
575 //Fill track information, separately for the track array candidates
576 for (Int_t i=0; i<2; ++i){
577 className.Form("Pre_%s",fgkTrackClassNames[i]);
578 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
579 Int_t ntracks=tracks[i]->GetEntriesFast();
580 for (Int_t itrack=0; itrack<ntracks; ++itrack){
581 AliDielectronVarManager::Fill(tracks[i]->UncheckedAt(itrack), values);
582 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
588 //________________________________________________________________
589 void AliDielectron::FillHistogramsMC(const AliMCEvent *ev, AliVEvent *ev1)
592 // Fill Histogram information for MCEvents
595 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
596 AliDielectronVarManager::SetFillMap(fUsedVars);
598 // Fill event information
599 AliDielectronVarManager::Fill(ev1, values); // ESD/AOD information
600 AliDielectronVarManager::Fill(ev, values); // MC truth info
601 if (fHistos->GetHistogramList()->FindObject("MCEvent"))
602 fHistos->FillClass("MCEvent", AliDielectronVarManager::kNMaxValues, values);
606 //________________________________________________________________
607 void AliDielectron::FillHistograms(const AliVEvent *ev, Bool_t pairInfoOnly)
610 // Fill Histogram information for tracks and pairs
613 TString className,className2;
614 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
615 AliDielectronVarManager::SetFillMap(fUsedVars);
617 //Fill event information
619 if (fHistos->GetHistogramList()->FindObject("Event")) {
620 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, AliDielectronVarManager::GetData());
624 //Fill track information, separately for the track array candidates
626 className2.Form("Track_%s",fgkPairClassNames[1]); // unlike sign, SE only
627 for (Int_t i=0; i<4; ++i){
628 className.Form("Track_%s",fgkTrackClassNames[i]);
629 Bool_t mergedtrkClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
630 Bool_t trkClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
631 if (!trkClass && !mergedtrkClass) continue;
632 Int_t ntracks=fTracks[i].GetEntriesFast();
633 for (Int_t itrack=0; itrack<ntracks; ++itrack){
634 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
636 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
637 if(mergedtrkClass && i<2)
638 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values); //only ev1
643 //Fill Pair information, separately for all pair candidate arrays and the legs
644 TObjArray arrLegs(100);
645 for (Int_t i=0; i<10; ++i){
646 className.Form("Pair_%s",fgkPairClassNames[i]);
647 className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
648 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
649 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
650 if (!pairClass&&!legClass) continue;
651 Int_t ntracks=PairArray(i)->GetEntriesFast();
652 for (Int_t ipair=0; ipair<ntracks; ++ipair){
653 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
655 //fill pair information
657 AliDielectronVarManager::Fill(pair, values);
658 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
661 //fill leg information, don't fill the information twice
663 AliVParticle *d1=pair->GetFirstDaughter();
664 AliVParticle *d2=pair->GetSecondDaughter();
665 if (!arrLegs.FindObject(d1)){
666 AliDielectronVarManager::Fill(d1, values);
667 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
670 if (!arrLegs.FindObject(d2)){
671 AliDielectronVarManager::Fill(d2, values);
672 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
677 if (legClass) arrLegs.Clear();
681 //________________________________________________________________
682 void AliDielectron::FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter/*=kFALSE*/)
685 // Fill Histogram information for pairs and the track in the pair
686 // NOTE: in this funtion the leg information may be filled multiple
687 // times. This funtion is used in the track rotation pairing
688 // and those legs are not saved!
690 TString className,className2;
691 Double_t values[AliDielectronVarManager::kNMaxValues];
692 AliDielectronVarManager::SetFillMap(fUsedVars);
694 //Fill Pair information, separately for all pair candidate arrays and the legs
695 TObjArray arrLegs(100);
696 const Int_t type=pair->GetType();
698 className.Form("RejPair_%s",fgkPairClassNames[type]);
699 className2.Form("RejTrack_%s",fgkPairClassNames[type]);
701 className.Form("Pair_%s",fgkPairClassNames[type]);
702 className2.Form("Track_Legs_%s",fgkPairClassNames[type]);
705 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
706 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
708 //fill pair information
710 AliDielectronVarManager::Fill(pair, values);
711 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
715 AliVParticle *d1=pair->GetFirstDaughter();
716 AliDielectronVarManager::Fill(d1, values);
717 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
719 AliVParticle *d2=pair->GetSecondDaughter();
720 AliDielectronVarManager::Fill(d2, values);
721 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
725 //________________________________________________________________
726 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
729 // select tracks and fill track candidate arrays
730 // eventNr = 0: First event, use track arrays 0 and 1
731 // eventNr = 1: Second event, use track arrays 2 and 3
734 Int_t ntracks=ev->GetNumberOfTracks();
736 UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
737 for (Int_t itrack=0; itrack<ntracks; ++itrack){
739 AliVParticle *particle=ev->GetTrack(itrack);
742 UInt_t cutmask=fTrackFilter.IsSelected(particle);
744 if(fCutQA) fQAmonitor->FillAll(particle);
745 if(fCutQA) fQAmonitor->Fill(cutmask,particle);
747 if (cutmask!=selectedMask) continue;
749 //fill selected particle into the corresponding track arrays
750 Short_t charge=particle->Charge();
751 if (charge>0) fTracks[eventNr*2].Add(particle);
752 else if (charge<0) fTracks[eventNr*2+1].Add(particle);
758 //________________________________________________________________
759 void AliDielectron::EventPlanePreFilter(Int_t arr1, Int_t arr2, TObjArray arrTracks1, TObjArray arrTracks2, const AliVEvent *ev)
762 // Prefilter tracks and tracks from pairs
763 // Needed for rejection in the Q-Vector of the event plane
764 // remove contribution of all tracks to the Q-vector that are in invariant mass window
767 AliEventplane *evplane = const_cast<AliVEvent *>(ev)->GetEventplane();
768 if(!evplane) { // nanoAODs , here we do NOT have sub event reaction planes
770 // get the EPselectionTask for recalculation of weighting factors
771 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
772 AliEPSelectionTask *eptask = dynamic_cast<AliEPSelectionTask *>(man->GetTask("EventplaneSelection"));
776 TMap mapRemovedTracks;
779 Double_t cQX=0., cQY=0.;
780 // apply cuts to the tracks, e.g. etagap
781 if(fEventPlanePreFilter.GetCuts()->GetEntries()) {
782 UInt_t selectedMask=(1<<fEventPlanePreFilter.GetCuts()->GetEntries())-1;
783 Int_t ntracks=ev->GetNumberOfTracks();
784 for (Int_t itrack=0; itrack<ntracks; ++itrack){
785 AliVParticle *particle=ev->GetTrack(itrack);
786 AliVTrack *track= static_cast<AliVTrack*>(particle);
787 if (!track) continue;
789 UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
791 if (cutMask==selectedMask) continue;
793 mapRemovedTracks.Add(track,track);
794 cQX += (eptask->GetWeight(track) * TMath::Cos(2*track->Phi()));
795 cQY += (eptask->GetWeight(track) * TMath::Sin(2*track->Phi()));
799 // POI (particle of interest) rejection
800 Int_t pairIndex=GetPairIndex(arr1,arr2);
802 Int_t ntrack1=arrTracks1.GetEntriesFast();
803 Int_t ntrack2=arrTracks2.GetEntriesFast();
804 AliDielectronPair candidate;
805 candidate.SetKFUsage(fUseKF);
807 UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
808 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
810 if (arr1==arr2) end=itrack1;
811 Bool_t accepted=kFALSE;
812 for (Int_t itrack2=0; itrack2<end; ++itrack2){
813 TObject *track1=arrTracks1.UncheckedAt(itrack1);
814 TObject *track2=arrTracks2.UncheckedAt(itrack2);
815 if (!track1 || !track2) continue;
817 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
818 static_cast<AliVTrack*>(track2), fPdgLeg2);
819 candidate.SetType(pairIndex);
820 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
822 //event plane pair cuts
823 UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
825 if (cutMask==selectedMask) continue;
828 //remove the tracks from the Track arrays
829 arrTracks2.AddAt(0x0,itrack2);
831 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
833 //compress the track arrays
834 arrTracks1.Compress();
835 arrTracks2.Compress();
837 //Modify the components: subtract the tracks
838 ntrack1=arrTracks1.GetEntriesFast();
839 ntrack2=arrTracks2.GetEntriesFast();
840 // remove leg1 contribution
841 for (Int_t itrack=0; itrack<ntrack1; ++itrack){
842 AliVTrack *track= static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack));
843 if (!track) continue;
844 // track contribution was already removed
845 if (mapRemovedTracks.FindObject(track)) continue;
846 else mapRemovedTracks.Add(track,track);
848 cQX += (eptask->GetWeight(track) * TMath::Cos(2*track->Phi()));
849 cQY += (eptask->GetWeight(track) * TMath::Sin(2*track->Phi()));
851 // remove leg2 contribution
852 for (Int_t itrack=0; itrack<ntrack2; ++itrack){
853 AliVTrack *track= static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack));
854 if (!track) continue;
855 // track contribution was already removed
856 if (mapRemovedTracks.FindObject(track)) continue;
857 else mapRemovedTracks.Add(track,track);
859 cQX += (eptask->GetWeight(track) * TMath::Cos(2*track->Phi()));
860 cQY += (eptask->GetWeight(track) * TMath::Sin(2*track->Phi()));
863 // build a corrected alieventplane using the values from the var manager
864 // these uncorrected values are filled using the stored magnitude and angle in the header
866 qcorr.Set(AliDielectronVarManager::GetValue(AliDielectronVarManager::kTPCxH2uc)-cQX,
867 AliDielectronVarManager::GetValue(AliDielectronVarManager::kTPCyH2uc)-cQY);
868 // fill alieventplane
869 AliEventplane cevplane;
870 cevplane.SetQVector(&qcorr);
871 AliDielectronVarManager::SetTPCEventPlane(&cevplane);
872 cevplane.SetQVector(0);
877 // this is done in case of ESDs or AODs
878 Bool_t isESD=(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliESDInputHandler::Class());
879 // copy event plane object
880 AliEventplane cevplane(*evplane);
881 // Int_t nMaxID=cevplane->GetQContributionXArray()->GetSize();
883 TVector2 *qcorr = cevplane.GetQVector();
885 TVector2 *qcsub1 = 0x0;
886 TVector2 *qcsub2 = 0x0;
889 Bool_t etagap = kFALSE;
890 for (Int_t iCut=0; iCut<fEventPlanePreFilter.GetCuts()->GetEntries();++iCut) {
891 TString cutName=fEventPlanePreFilter.GetCuts()->At(iCut)->GetName();
892 if(cutName.Contains("eta") || cutName.Contains("Eta")) etagap=kTRUE;
895 // subevent configuration for eta gap or LS (default is rndm)
896 if(fLikeSignSubEvents && etagap) {
897 // start with the full Qvector/event in both sub events
898 qcsub1 = new TVector2(*qcorr);
899 qcsub2 = new TVector2(*qcorr);
900 cevplane.SetQsub(qcsub1,qcsub2);
902 Int_t ntracks=ev->GetNumberOfTracks();
904 for (Int_t itrack=0; itrack<ntracks; ++itrack){
905 AliVParticle *particle=ev->GetTrack(itrack);
906 AliVTrack *track= static_cast<AliVTrack*>(particle);
907 if (!track) continue;
908 if (track->GetID()>=0 && !isESD) continue;
909 Int_t tmpID = isESD ? track->GetID() : track->GetID()*-1 - 1;
911 // set contributions to zero
912 // charge sub1+ sub2-
913 if(fLikeSignSubEvents) {
914 Short_t charge=track->Charge();
916 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
917 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
920 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
921 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
926 Double_t eta=track->Eta();
928 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
929 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
932 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
933 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
936 } // end: loop over tracks
937 } // end: sub event configuration
939 // apply cuts, e.g. etagap
940 if(fEventPlanePreFilter.GetCuts()->GetEntries()) {
941 UInt_t selectedMask=(1<<fEventPlanePreFilter.GetCuts()->GetEntries())-1;
942 Int_t ntracks=ev->GetNumberOfTracks();
943 for (Int_t itrack=0; itrack<ntracks; ++itrack){
944 AliVParticle *particle=ev->GetTrack(itrack);
945 AliVTrack *track= static_cast<AliVTrack*>(particle);
946 if (!track) continue;
947 if (track->GetID()>=0 && !isESD) continue;
948 Int_t tmpID = isESD ? track->GetID() : track->GetID()*-1 - 1;
951 UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
953 if (cutMask==selectedMask) continue;
955 // set contributions to zero
956 cevplane.GetQContributionXArray()->SetAt(0.0, tmpID);
957 cevplane.GetQContributionYArray()->SetAt(0.0, tmpID);
958 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
959 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
960 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
961 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
965 // POI (particle of interest) rejection
966 Int_t pairIndex=GetPairIndex(arr1,arr2);
967 Int_t ntrack1=arrTracks1.GetEntriesFast();
968 Int_t ntrack2=arrTracks2.GetEntriesFast();
969 AliDielectronPair candidate;
970 candidate.SetKFUsage(fUseKF);
972 UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
973 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
975 if (arr1==arr2) end=itrack1;
976 Bool_t accepted=kFALSE;
977 for (Int_t itrack2=0; itrack2<end; ++itrack2){
978 TObject *track1=arrTracks1.UncheckedAt(itrack1);
979 TObject *track2=arrTracks2.UncheckedAt(itrack2);
980 if (!track1 || !track2) continue;
982 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
983 static_cast<AliVTrack*>(track2), fPdgLeg2);
985 candidate.SetType(pairIndex);
986 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
989 UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
991 if (cutMask==selectedMask) continue;
994 //remove the tracks from the Track arrays
995 arrTracks2.AddAt(0x0,itrack2);
997 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
999 //compress the track arrays
1000 arrTracks1.Compress();
1001 arrTracks2.Compress();
1003 //Modify the components: subtract the tracks
1004 ntrack1=arrTracks1.GetEntriesFast();
1005 ntrack2=arrTracks2.GetEntriesFast();
1006 // remove leg1 contribution
1007 for (Int_t itrack=0; itrack<ntrack1; ++itrack){
1008 AliVTrack *track= static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack));
1009 if (!track) continue;
1010 if (track->GetID()>=0 && !isESD) continue;
1011 Int_t tmpID = isESD ? track->GetID() : track->GetID()*-1 - 1;
1012 // set contributions to zero
1013 cevplane.GetQContributionXArray()->SetAt(0.0, tmpID);
1014 cevplane.GetQContributionYArray()->SetAt(0.0, tmpID);
1015 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
1016 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
1017 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
1018 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
1020 // remove leg2 contribution
1021 for (Int_t itrack=0; itrack<ntrack2; ++itrack){
1022 AliVTrack *track= static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack));
1023 if (!track) continue;
1024 if (track->GetID()>=0 && !isESD) continue;
1025 Int_t tmpID = isESD ? track->GetID() : track->GetID()*-1 - 1;
1026 // set contributions to zero
1027 cevplane.GetQContributionXArray()->SetAt(0.0, tmpID);
1028 cevplane.GetQContributionYArray()->SetAt(0.0, tmpID);
1029 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
1030 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
1031 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
1032 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
1035 // set corrected AliEventplane and fill variables with corrected values
1036 AliDielectronVarManager::SetTPCEventPlane(&cevplane);
1039 } // end: ESD or AOD case
1042 //________________________________________________________________
1043 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
1046 // Prefilter tracks from pairs
1047 // Needed for datlitz rejections
1048 // remove all tracks from the Single track arrays that pass the cuts in this filter
1051 Int_t ntrack1=arrTracks1.GetEntriesFast();
1052 Int_t ntrack2=arrTracks2.GetEntriesFast();
1053 AliDielectronPair candidate;
1054 candidate.SetKFUsage(fUseKF);
1055 // flag arrays for track removal
1056 Bool_t *bTracks1 = new Bool_t[ntrack1];
1057 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1) bTracks1[itrack1]=kFALSE;
1058 Bool_t *bTracks2 = new Bool_t[ntrack2];
1059 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2) bTracks2[itrack2]=kFALSE;
1061 UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
1062 UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1064 Int_t nRejPasses = 1; //for fPreFilterUnlikeOnly and no set flag
1065 if (fPreFilterAllSigns) nRejPasses = 3;
1067 for (Int_t iRP=0; iRP < nRejPasses; ++iRP) {
1068 Int_t arr1RP=arr1, arr2RP=arr2;
1069 TObjArray *arrTracks1RP=&arrTracks1;
1070 TObjArray *arrTracks2RP=&arrTracks2;
1071 Bool_t *bTracks1RP = bTracks1;
1072 Bool_t *bTracks2RP = bTracks2;
1074 case 1: arr1RP=arr1;arr2RP=arr1;
1075 arrTracks1RP=&arrTracks1;
1076 arrTracks2RP=&arrTracks1;
1077 bTracks1RP = bTracks1;
1078 bTracks2RP = bTracks1;
1080 case 2: arr1RP=arr2;arr2RP=arr2;
1081 arrTracks1RP=&arrTracks2;
1082 arrTracks2RP=&arrTracks2;
1083 bTracks1RP = bTracks2;
1084 bTracks2RP = bTracks2;
1086 default: ;//nothing to do
1088 Int_t ntrack1RP=(*arrTracks1RP).GetEntriesFast();
1089 Int_t ntrack2RP=(*arrTracks2RP).GetEntriesFast();
1091 Int_t pairIndex=GetPairIndex(arr1RP,arr2RP);
1093 for (Int_t itrack1=0; itrack1<ntrack1RP; ++itrack1){
1094 Int_t end=ntrack2RP;
1095 if (arr1RP==arr2RP) end=itrack1;
1096 for (Int_t itrack2=0; itrack2<end; ++itrack2){
1097 TObject *track1=(*arrTracks1RP).UncheckedAt(itrack1);
1098 TObject *track2=(*arrTracks2RP).UncheckedAt(itrack2);
1099 if (!track1 || !track2) continue;
1101 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
1102 static_cast<AliVTrack*>(track2), fPdgLeg2);
1104 candidate.SetType(pairIndex);
1105 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
1106 //relate to the production vertex
1107 // if (AliDielectronVarManager::GetKFVertex()) candidate.SetProductionVertex(*AliDielectronVarManager::GetKFVertex());
1110 UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
1113 if (cutMask!=selectedMask) continue;
1114 if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
1115 if (fHistos) FillHistogramsPair(&candidate,kTRUE);
1116 //set flags for track removal
1117 bTracks1RP[itrack1]=kTRUE;
1118 bTracks2RP[itrack2]=kTRUE;
1123 //remove the tracks from the Track arrays
1124 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
1125 if(bTracks1[itrack1]) arrTracks1.AddAt(0x0, itrack1);
1127 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2){
1128 if(bTracks2[itrack2]) arrTracks2.AddAt(0x0, itrack2);
1135 //compress the track arrays
1136 arrTracks1.Compress();
1137 arrTracks2.Compress();
1139 //apply leg cuts after the pre filter
1140 if ( fPairPreFilterLegs.GetCuts()->GetEntries()>0 ) {
1141 selectedMask=(1<<fPairPreFilterLegs.GetCuts()->GetEntries())-1;
1142 //loop over tracks from array 1
1143 for (Int_t itrack=0; itrack<arrTracks1.GetEntriesFast();++itrack){
1145 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
1148 if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);
1150 arrTracks1.Compress();
1152 //in case of like sign don't loop over second array
1154 arrTracks2=arrTracks1;
1157 //loop over tracks from array 2
1158 for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
1160 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
1162 if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
1164 arrTracks2.Compress();
1168 //For unlike-sign monitor track-cuts:
1169 if (arr1!=arr2&&fHistos) {
1170 TObjArray *unlikesignArray[2] = {&arrTracks1,&arrTracks2};
1171 FillHistogramsTracks(unlikesignArray);
1175 //________________________________________________________________
1176 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2)
1179 // select pairs and fill pair candidate arrays
1182 TObjArray arrTracks1=fTracks[arr1];
1183 TObjArray arrTracks2=fTracks[arr2];
1185 //process pre filter if set
1186 if ((!fPreFilterAllSigns) && (!fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
1188 Int_t pairIndex=GetPairIndex(arr1,arr2);
1190 Int_t ntrack1=arrTracks1.GetEntriesFast();
1191 Int_t ntrack2=arrTracks2.GetEntriesFast();
1193 AliDielectronPair *candidate=new AliDielectronPair;
1194 candidate->SetKFUsage(fUseKF);
1196 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1198 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
1200 if (arr1==arr2) end=itrack1;
1201 for (Int_t itrack2=0; itrack2<end; ++itrack2){
1202 //create the pair (direct pointer to the memory by this daughter reference are kept also for ME)
1203 candidate->SetTracks(&(*static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1))), fPdgLeg1,
1204 &(*static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2))), fPdgLeg2);
1205 candidate->SetType(pairIndex);
1207 Int_t label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother);
1208 candidate->SetLabel(label);
1209 if (label>-1) candidate->SetPdgCode(fPdgMother);
1210 else candidate->SetPdgCode(0);
1212 // check for gamma kf particle
1213 label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,22);
1215 candidate->SetGammaTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
1216 static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
1217 // should we set the pdgmothercode and the label
1221 UInt_t cutMask=fPairFilter.IsSelected(candidate);
1223 //CF manager for the pair
1224 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
1227 if(pairIndex==kEv1PM && fCutQA) {
1228 fQAmonitor->FillAll(candidate);
1229 fQAmonitor->Fill(cutMask,candidate);
1233 if (cutMask!=selectedMask) continue;
1235 //histogram array for the pair
1236 if (fHistoArray) fHistoArray->Fill(pairIndex,candidate);
1238 //add the candidate to the candidate array
1239 PairArray(pairIndex)->Add(candidate);
1240 //get a new candidate
1241 candidate=new AliDielectronPair;
1242 candidate->SetKFUsage(fUseKF);
1245 //delete the surplus candidate
1249 //________________________________________________________________
1250 void AliDielectron::FillPairArrayTR()
1253 // select pairs and fill pair candidate arrays
1255 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1257 while ( fTrackRotator->NextCombination() ){
1258 AliDielectronPair candidate;
1259 candidate.SetKFUsage(fUseKF);
1260 candidate.SetTracks(&fTrackRotator->GetKFTrackP(), &fTrackRotator->GetKFTrackN(),
1261 fTrackRotator->GetVTrackP(),fTrackRotator->GetVTrackN());
1262 candidate.SetType(kEv1PMRot);
1265 UInt_t cutMask=fPairFilter.IsSelected(&candidate);
1267 //CF manager for the pair
1268 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,&candidate);
1271 if (cutMask==selectedMask) {
1273 //histogram array for the pair
1274 if (fHistoArray) fHistoArray->Fill((Int_t)kEv1PMRot,&candidate);
1276 if(fHistos) FillHistogramsPair(&candidate);
1277 if(fStoreRotatedPairs) PairArray(kEv1PMRot)->Add(new AliDielectronPair(candidate));
1282 //________________________________________________________________
1283 void AliDielectron::FillDebugTree()
1286 // Fill Histogram information for tracks and pairs
1290 for (Int_t i=0; i<10; ++i){
1291 Int_t ntracks=PairArray(i)->GetEntriesFast();
1292 for (Int_t ipair=0; ipair<ntracks; ++ipair){
1293 fDebugTree->Fill(static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair)));
1298 //________________________________________________________________
1299 void AliDielectron::SaveDebugTree()
1302 // delete the debug tree, this will also write the tree
1304 if (fDebugTree) fDebugTree->DeleteStreamer();
1308 //__________________________________________________________________
1309 void AliDielectron::AddSignalMC(AliDielectronSignalMC* signal) {
1311 // Add an MC signal to the signals list
1314 fSignalsMC = new TObjArray();
1315 fSignalsMC->SetOwner();
1317 fSignalsMC->Add(signal);
1320 //________________________________________________________________
1321 void AliDielectron::FillMCHistograms(Int_t label1, Int_t label2, Int_t nSignal) {
1323 // fill QA MC TRUTH histograms for pairs and legs of all added mc signals
1326 TString className,className2,className3;
1327 className.Form("Pair_%s_MCtruth",fSignalsMC->At(nSignal)->GetName());
1328 className2.Form("Track_Legs_%s_MCtruth",fSignalsMC->At(nSignal)->GetName());
1329 className3.Form("Track_%s_%s_MCtruth",fgkPairClassNames[1],fSignalsMC->At(nSignal)->GetName());
1330 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
1331 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
1332 Bool_t trkClass=fHistos->GetHistogramList()->FindObject(className3.Data())!=0x0;
1333 // printf("fill signal %d: pair %d legs %d trk %d \n",nSignal,pairClass,legClass,trkClass);
1334 if(!pairClass && !legClass && !trkClass) return;
1336 // printf("leg labels: %d-%d \n",label1,label2);
1337 AliVParticle* part1 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label1);
1338 AliVParticle* part2 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label2);
1339 if(!part1 && !part2) return;
1341 // fill only unlike sign (and only SE)
1342 if(part1->Charge()*part2->Charge()>=0) return;
1346 AliDielectronMC* dieMC = AliDielectronMC::Instance();
1348 Int_t mLabel1 = dieMC->GetMothersLabel(label1); // should work for both ESD and AOD
1349 Int_t mLabel2 = dieMC->GetMothersLabel(label2);
1351 // check the same mother option
1352 AliDielectronSignalMC* sigMC = (AliDielectronSignalMC*)fSignalsMC->At(nSignal);
1353 if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kSame && mLabel1!=mLabel2) return;
1354 if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kDifferent && mLabel1==mLabel2) return;
1356 // fill event values
1357 Double_t values[AliDielectronVarManager::kNMaxValues];
1358 AliDielectronVarManager::SetFillMap(fUsedVars);
1359 AliDielectronVarManager::Fill(dieMC->GetMCEvent(), values); // get event informations
1361 // fill the leg variables
1362 // printf("leg:%d trk:%d part1:%p part2:%p \n",legClass,trkClass,part1,part2);
1363 if (legClass || trkClass) {
1364 if(part1) AliDielectronVarManager::Fill(part1,values);
1365 if(part1 && trkClass) fHistos->FillClass(className3, AliDielectronVarManager::kNMaxValues, values);
1366 if(part1 && part2 && legClass) fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1367 if(part2) AliDielectronVarManager::Fill(part2,values);
1368 if(part2 && trkClass) fHistos->FillClass(className3, AliDielectronVarManager::kNMaxValues, values);
1369 if(part1 && part2 && legClass) fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1372 //fill pair information
1373 if (pairClass && part1 && part2) {
1374 AliDielectronVarManager::FillVarMCParticle2(part1,part2,values);
1375 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1380 //________________________________________________________________
1381 void AliDielectron::FillMCHistograms(const AliVEvent *ev) {
1383 // fill QA MC histograms for pairs and legs of all added mc signals
1386 if (!fSignalsMC) return;
1387 TString className,className2,className3;
1388 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
1389 AliDielectronVarManager::SetFillMap(fUsedVars);
1390 AliDielectronVarManager::Fill(ev, values); // get event informations
1391 //loop over all added mc signals
1392 for(Int_t isig=0; isig<fSignalsMC->GetEntries(); isig++) {
1394 //check if and what to fill
1395 className.Form("Pair_%s",fSignalsMC->At(isig)->GetName());
1396 className2.Form("Track_Legs_%s",fSignalsMC->At(isig)->GetName());
1397 className3.Form("Track_%s_%s",fgkPairClassNames[1],fSignalsMC->At(isig)->GetName()); // unlike sign, SE only
1398 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
1399 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
1400 Bool_t mergedtrkClass=fHistos->GetHistogramList()->FindObject(className3.Data())!=0x0;
1401 if(!pairClass && !legClass && !mergedtrkClass) continue;
1403 // fill pair and/or their leg variables
1404 if(pairClass || legClass) {
1405 Int_t npairs=PairArray(AliDielectron::kEv1PM)->GetEntriesFast(); // only SE +-
1406 for (Int_t ipair=0; ipair<npairs; ++ipair){
1407 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(AliDielectron::kEv1PM)->UncheckedAt(ipair));
1409 Bool_t isMCtruth = AliDielectronMC::Instance()->IsMCTruth(pair, (AliDielectronSignalMC*)fSignalsMC->At(isig));
1411 //fill pair information
1413 AliDielectronVarManager::Fill(pair, values);
1414 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1416 //fill leg information, both + and - in the same histo
1418 AliDielectronVarManager::Fill(pair->GetFirstDaughter(),values);
1419 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1420 AliDielectronVarManager::Fill(pair->GetSecondDaughter(),values);
1421 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1427 // fill single tracks of signals
1428 if(!mergedtrkClass) continue;
1429 // loop over SE track arrays
1430 for (Int_t i=0; i<2; ++i){
1431 Int_t ntracks=fTracks[i].GetEntriesFast();
1432 for (Int_t itrack=0; itrack<ntracks; ++itrack){
1433 Int_t label=((AliVParticle*)fTracks[i].UncheckedAt(itrack))->GetLabel();
1434 Bool_t isMCtruth1 = AliDielectronMC::Instance()->IsMCTruth(label, (AliDielectronSignalMC*)fSignalsMC->At(isig), 1);
1435 Bool_t isMCtruth2 = AliDielectronMC::Instance()->IsMCTruth(label, (AliDielectronSignalMC*)fSignalsMC->At(isig), 2);
1436 // skip if track does not correspond to the signal
1437 if(!isMCtruth1 && !isMCtruth2) continue;
1438 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
1439 fHistos->FillClass(className3, AliDielectronVarManager::kNMaxValues, values);
1447 //______________________________________________
1448 void AliDielectron::SetCentroidCorrFunction(TF1 *fun, UInt_t varx, UInt_t vary, UInt_t varz)
1450 fun->GetHistogram()->GetXaxis()->SetUniqueID(varx);
1451 fun->GetHistogram()->GetYaxis()->SetUniqueID(vary);
1452 fun->GetHistogram()->GetZaxis()->SetUniqueID(varz);
1453 // clone temporare histogram since otherwise it will not be streamed to file!
1454 TString key = Form("cntrd%d%d%d",varx,vary,varz);
1455 fPostPIDCntrdCorr = (TH1*)fun->GetHistogram()->Clone(key.Data());
1456 fPostPIDCntrdCorr->GetListOfFunctions()->AddAt(fun,0);
1458 //______________________________________________
1459 void AliDielectron::SetWidthCorrFunction(TF1 *fun, UInt_t varx, UInt_t vary, UInt_t varz)
1461 fun->GetHistogram()->GetXaxis()->SetUniqueID(varx);
1462 fun->GetHistogram()->GetYaxis()->SetUniqueID(vary);
1463 fun->GetHistogram()->GetZaxis()->SetUniqueID(varz);
1464 // clone temporare histogram since otherwise it will not be streamed to file!
1465 TString key = Form("wdth%d%d%d",varx,vary,varz);
1466 fPostPIDWdthCorr = (TH1*)fun->GetHistogram()->Clone(key.Data());
1467 fPostPIDWdthCorr->GetListOfFunctions()->AddAt(fun,0);
1470 //______________________________________________
1471 THnBase* AliDielectron::InitEffMap(TString filename)
1473 // init an efficiency object for on-the-fly correction calculations
1474 if(filename.Contains("alien://") && !gGrid) TGrid::Connect("alien://",0,0,"t");
1476 TFile* file=TFile::Open(filename.Data());
1477 if(!file) return 0x0;
1478 THnBase *hGen = (THnBase*) file->Get("hGenerated");
1479 THnBase *hFnd = (THnBase*) file->Get("hFound");
1480 if(!hFnd || !hGen) return 0x0;
1483 printf("[I] AliDielectron::InitEffMap efficiency maps %s with %d dimensions loaded! \n",filename.Data(),hFnd->GetNdimensions());
1484 return ((THnBase*) hFnd->Clone("effMap"));
1487 //________________________________________________________________
1488 void AliDielectron::FillHistogramsFromPairArray(Bool_t pairInfoOnly/*=kFALSE*/)
1491 // Fill Histogram information for tracks and pairs
1494 TString className,className2;
1495 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
1496 AliDielectronVarManager::SetFillMap(fUsedVars);
1497 AliDielectronVarManager::SetLegEffMap(fLegEffMap);
1498 AliDielectronVarManager::SetPairEffMap(fPairEffMap);
1500 //Fill event information
1502 if(fHistos->GetHistogramList()->FindObject("Event")) {
1503 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, AliDielectronVarManager::GetData());
1507 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1509 //Fill Pair information, separately for all pair candidate arrays and the legs
1510 TObjArray arrLegs(100);
1511 for (Int_t i=0; i<10; ++i){ // ROT pairs??
1512 Int_t npairs=PairArray(i)->GetEntriesFast();
1513 if(npairs<1) continue;
1515 className.Form("Pair_%s",fgkPairClassNames[i]);
1516 className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
1517 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
1518 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
1520 // if (!pairClass&&!legClass) continue;
1521 for (Int_t ipair=0; ipair<npairs; ++ipair){
1522 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
1525 UInt_t cutMask=fPairFilter.IsSelected(pair);
1528 if(i==kEv1PM && fCutQA) {
1529 fQAmonitor->FillAll(pair);
1530 fQAmonitor->Fill(cutMask,pair);
1533 //CF manager for the pair (TODO: check steps and if they are properly filled)
1534 // if (fCfManagerPair) fCfManagerPair->Fill(cutMask,pair);
1537 if (cutMask!=selectedMask) continue;
1539 //histogram array for the pair
1540 if (fHistoArray) fHistoArray->Fill(i,pair);
1542 //fill pair information
1544 AliDielectronVarManager::Fill(pair, values);
1545 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1548 //fill leg information, don't fill the information twice
1550 AliVParticle *d1=pair->GetFirstDaughter();
1551 AliVParticle *d2=pair->GetSecondDaughter();
1552 if (!arrLegs.FindObject(d1)){
1553 AliDielectronVarManager::Fill(d1, values);
1554 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1557 if (!arrLegs.FindObject(d2)){
1558 AliDielectronVarManager::Fill(d2, values);
1559 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1564 if (legClass) arrLegs.Clear();