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"
72 #include "AliDielectronHistos.h"
74 #include "AliDielectron.h"
76 ClassImp(AliDielectron)
78 const char* AliDielectron::fgkTrackClassNames[4] = {
85 const char* AliDielectron::fgkPairClassNames[11] = {
99 //________________________________________________________________
100 AliDielectron::AliDielectron() :
101 TNamed("AliDielectron","AliDielectron"),
104 fPostPIDCntrdCorr(0x0),
105 fPostPIDWdthCorr(0x0),
108 fEventFilter("EventFilter"),
109 fTrackFilter("TrackFilter"),
110 fPairPreFilter("PairPreFilter"),
111 fPairPreFilterLegs("PairPreFilterLegs"),
112 fPairFilter("PairFilter"),
113 fEventPlanePreFilter("EventPlanePreFilter"),
114 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
124 fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
125 fPairCandidates(new TObjArray(11)),
130 fPreFilterEventPlane(kFALSE),
131 fLikeSignSubEvents(kFALSE),
132 fPreFilterUnlikeOnly(kFALSE),
133 fPreFilterAllSigns(kFALSE),
135 fStoreRotatedPairs(kFALSE),
136 fDontClearArrays(kFALSE),
137 fEventProcess(kTRUE),
138 fEstimatorFilename(""),
139 fTRDpidCorrectionFilename(""),
140 fVZEROCalibrationFilename(""),
141 fVZERORecenteringFilename(""),
142 fZDCRecenteringFilename("")
146 // Default constructor
151 //________________________________________________________________
152 AliDielectron::AliDielectron(const char* name, const char* title) :
156 fPostPIDCntrdCorr(0x0),
157 fPostPIDWdthCorr(0x0),
160 fEventFilter("EventFilter"),
161 fTrackFilter("TrackFilter"),
162 fPairPreFilter("PairPreFilter"),
163 fPairPreFilterLegs("PairPreFilterLegs"),
164 fPairFilter("PairFilter"),
165 fEventPlanePreFilter("EventPlanePreFilter"),
166 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
176 fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
177 fPairCandidates(new TObjArray(11)),
182 fPreFilterEventPlane(kFALSE),
183 fLikeSignSubEvents(kFALSE),
184 fPreFilterUnlikeOnly(kFALSE),
185 fPreFilterAllSigns(kFALSE),
187 fStoreRotatedPairs(kFALSE),
188 fDontClearArrays(kFALSE),
189 fEventProcess(kTRUE),
190 fEstimatorFilename(""),
191 fTRDpidCorrectionFilename(""),
192 fVZEROCalibrationFilename(""),
193 fVZERORecenteringFilename(""),
194 fZDCRecenteringFilename("")
202 //________________________________________________________________
203 AliDielectron::~AliDielectron()
206 // Default destructor
208 if (fQAmonitor) delete fQAmonitor;
209 if (fPostPIDCntrdCorr) delete fPostPIDCntrdCorr;
210 if (fPostPIDWdthCorr) delete fPostPIDWdthCorr;
211 if (fLegEffMap) delete fLegEffMap;
212 if (fPairEffMap) delete fPairEffMap;
213 if (fHistos) delete fHistos;
214 if (fUsedVars) delete fUsedVars;
215 if (fPairCandidates && fEventProcess) delete fPairCandidates;
216 if (fDebugTree) delete fDebugTree;
217 if (fMixing) delete fMixing;
218 if (fSignalsMC) delete fSignalsMC;
219 if (fCfManagerPair) delete fCfManagerPair;
220 if (fHistoArray) delete fHistoArray;
223 //________________________________________________________________
224 void AliDielectron::Init()
227 // Initialise objects
230 if(GetHasMC()) AliDielectronMC::Instance()->SetHasMC(GetHasMC());
232 if(fEventProcess) InitPairCandidateArrays();
234 if (fCfManagerPair) {
235 fCfManagerPair->SetSignalsMC(fSignalsMC);
236 fCfManagerPair->InitialiseContainer(fPairFilter);
239 fTrackRotator->SetTrackArrays(&fTracks[0],&fTracks[1]);
240 fTrackRotator->SetPdgLegs(fPdgLeg1,fPdgLeg2);
242 if (fDebugTree) fDebugTree->SetDielectron(this);
244 if(fEstimatorFilename.Contains(".root")) AliDielectronVarManager::InitEstimatorAvg(fEstimatorFilename.Data());
245 if(fTRDpidCorrectionFilename.Contains(".root")) AliDielectronVarManager::InitTRDpidEffHistograms(fTRDpidCorrectionFilename.Data());
246 if(fVZEROCalibrationFilename.Contains(".root")) AliDielectronVarManager::SetVZEROCalibrationFile(fVZEROCalibrationFilename.Data());
247 if(fVZERORecenteringFilename.Contains(".root")) AliDielectronVarManager::SetVZERORecenteringFile(fVZERORecenteringFilename.Data());
248 if(fZDCRecenteringFilename.Contains(".root")) AliDielectronVarManager::SetZDCRecenteringFile(fZDCRecenteringFilename.Data());
250 if (fMixing) fMixing->Init(this);
252 fHistoArray->SetSignalsMC(fSignalsMC);
256 if(fPostPIDCntrdCorr) AliDielectronPID::SetCentroidCorrFunction(fPostPIDCntrdCorr);
257 if(fPostPIDWdthCorr) AliDielectronPID::SetWidthCorrFunction(fPostPIDWdthCorr);
260 AliDielectronPairLegCuts *trk2leg = new AliDielectronPairLegCuts("trk2leg","trk2leg");
261 // move all track cuts (if any) into pair leg cuts
262 TIter listIterator(fTrackFilter.GetCuts());
263 while (AliAnalysisCuts *thisCut = (AliAnalysisCuts*) listIterator()) {
264 trk2leg->GetLeg1Filter().AddCuts((AliAnalysisCuts*)thisCut->Clone());
265 trk2leg->GetLeg2Filter().AddCuts((AliAnalysisCuts*)thisCut->Clone());
267 // add pair leg cuts to pair filter
268 fPairFilter.AddCuts(trk2leg);
272 fQAmonitor = new AliDielectronCutQA(Form("QAcuts_%s",GetName()),"QAcuts");
273 fQAmonitor->AddTrackFilter(&fTrackFilter);
274 if(!fNoPairing) fQAmonitor->AddPairFilter(&fPairFilter);
275 fQAmonitor->AddEventFilter(&fEventFilter);
280 (*fUsedVars)|= (*fHistos->GetUsedVars());
285 //________________________________________________________________
287 void AliDielectron::Process(TObjArray *arr)
290 // Process the pair array
294 fPairCandidates = arr;
296 //fill debug tree if a manager is attached
297 // if (fDebugTree) FillDebugTree();
298 //in case there is a histogram manager, fill the QA histograms
299 // if (fHistos && fSignalsMC) FillMCHistograms(ev1);
301 // apply cuts and fill output
302 if (fHistos) FillHistogramsFromPairArray();
304 // never clear arrays !!!!
309 //________________________________________________________________
310 Bool_t AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
313 // Process the events
316 //at least first event is needed!
318 AliError("At least first event must be set!");
322 // modify event numbers in MC so that we can identify new events
323 // in AliDielectronV0Cuts (not neeeded for collision data)
325 ev1->SetBunchCrossNumber(1);
326 ev1->SetOrbitNumber(1);
327 ev1->SetPeriodNumber(1);
331 AliDielectronVarManager::SetFillMap(fUsedVars);
332 AliDielectronVarManager::SetEvent(ev1);
334 //set mixing bin to event data
335 Int_t bin=fMixing->FindBin(AliDielectronVarManager::GetData());
336 AliDielectronVarManager::SetValue(AliDielectronVarManager::kMixingBin,bin);
339 // set efficiency maps
340 AliDielectronVarManager::SetLegEffMap(fLegEffMap);
341 AliDielectronVarManager::SetPairEffMap(fPairEffMap);
343 //in case we have MC load the MC event and process the MC particles
344 // why do not apply the event cuts first ????
345 if (AliDielectronMC::Instance()->ConnectMCEvent()){
349 //if candidate array doesn't exist, create it
350 if (!fPairCandidates->UncheckedAt(0)) {
351 InitPairCandidateArrays();
356 //mask used to require that all cuts are fulfilled
357 UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
360 UInt_t cutmask = fEventFilter.IsSelected(ev1);
361 if(fCutQA) fQAmonitor->FillAll(ev1);
362 if(fCutQA) fQAmonitor->Fill(cutmask,ev1);
363 if ((ev1&&cutmask!=selectedMask) ||
364 (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return 0;
366 //fill track arrays for the first event
368 FillTrackArrays(ev1);
369 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
373 //fill track arrays for the second event
375 FillTrackArrays(ev2,1);
376 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
379 // TPC event plane correction
380 if (ev1 && fPreFilterEventPlane && ( fEventPlanePreFilter.GetCuts()->GetEntries()>0 || fEventPlanePOIPreFilter.GetCuts()->GetEntries()>0))
381 EventPlanePreFilter(0, 1, fTracks[0], fTracks[1], ev1);
384 // create pairs and fill pair candidate arrays
385 for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
386 for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
387 if(!fProcessLS && GetPairIndex(itrackArr1,itrackArr2)!=kEv1PM) continue;
388 FillPairArrays(itrackArr1, itrackArr2);
394 fTrackRotator->SetEvent(ev1);
399 //fill debug tree if a manager is attached
400 if (fDebugTree) FillDebugTree();
402 //process event mixing
404 fMixing->Fill(ev1,this);
405 // FillHistograms(0x0,kTRUE);
408 // fill candidate variables
409 Double_t ntracks = fTracks[0].GetEntriesFast() + fTracks[1].GetEntriesFast();
410 Double_t npairs = PairArray(AliDielectron::kEv1PM)->GetEntriesFast();
411 AliDielectronVarManager::SetValue(AliDielectronVarManager::kTracks, ntracks);
412 AliDielectronVarManager::SetValue(AliDielectronVarManager::kPairs, npairs);
414 //in case there is a histogram manager, fill the QA histograms
415 if (fHistos && fSignalsMC) FillMCHistograms(ev1);
416 if (fHistos) FillHistograms(ev1);
417 // fill histo array with event information only
418 if (fHistoArray && fHistoArray->IsEventArray())
419 fHistoArray->Fill(0,const_cast<Double_t *>(AliDielectronVarManager::GetData()),0x0,0x0);
422 if (!fDontClearArrays) ClearArrays();
424 // reset TPC EP and unique identifiers for v0 cut class
425 AliDielectronVarManager::SetTPCEventPlane(0x0);
426 if(GetHasMC()) { // only for MC needed
427 for (Int_t iCut=0; iCut<fTrackFilter.GetCuts()->GetEntries();++iCut) {
428 if ( fTrackFilter.GetCuts()->At(iCut)->IsA() == AliDielectronV0Cuts::Class() )
429 ((AliDielectronV0Cuts*)fTrackFilter.GetCuts()->At(iCut))->ResetUniqueEventNumbers();
437 //________________________________________________________________
438 void AliDielectron::ProcessMC(AliVEvent *ev1)
441 // Process the MC data
444 AliDielectronMC *dieMC=AliDielectronMC::Instance();
446 if (fHistos) FillHistogramsMC(dieMC->GetMCEvent(), ev1);
449 if(!dieMC->GetNMCTracks()) return;
451 // signals to be studied
452 if(!fSignalsMC) return;
453 Int_t nSignals = fSignalsMC->GetEntries();
454 if(!nSignals) return;
456 //loop over all MC data and Fill the HF, CF containers and histograms if they exist
457 if(fCfManagerPair) fCfManagerPair->SetPdgMother(fPdgMother);
459 Bool_t bFillCF = (fCfManagerPair ? fCfManagerPair->GetStepForMCtruth() : kFALSE);
460 Bool_t bFillHF = (fHistoArray ? fHistoArray->GetStepForMCGenerated() : kFALSE);
461 Bool_t bFillHist = kFALSE;
463 const THashList *histlist = fHistos->GetHistogramList();
464 for(Int_t isig=0;isig<nSignals;isig++) {
465 TString sigName = fSignalsMC->At(isig)->GetName();
466 bFillHist |= histlist->FindObject(Form("Pair_%s_MCtruth",sigName.Data()))!=0x0;
467 bFillHist |= histlist->FindObject(Form("Track_Leg_%s_MCtruth",sigName.Data()))!=0x0;
468 bFillHist |= histlist->FindObject(Form("Track_%s_%s_MCtruth",fgkPairClassNames[1],sigName.Data()))!=0x0;
472 // check if there is anything to fill
473 if(!bFillCF && !bFillHF && !bFillHist) return;
476 // initialize 2D arrays of labels for particles from each MC signal
477 Int_t** labels1; // labels for particles satisfying branch 1
478 Int_t** labels2; // labels for particles satisfying branch 2
479 Int_t** labels12; // labels for particles satisfying both branches
480 labels1 = new Int_t*[nSignals];
481 labels2 = new Int_t*[nSignals];
482 labels12 = new Int_t*[nSignals];
483 Int_t* indexes1=new Int_t[nSignals];
484 Int_t* indexes2=new Int_t[nSignals];
485 Int_t* indexes12=new Int_t[nSignals];
486 for(Int_t isig=0;isig<nSignals;++isig) {
487 *(labels1+isig) = new Int_t[dieMC->GetNMCTracks()];
488 *(labels2+isig) = new Int_t[dieMC->GetNMCTracks()];
489 *(labels12+isig) = new Int_t[dieMC->GetNMCTracks()];
490 for(Int_t ip=0; ip<dieMC->GetNMCTracks();++ip) {
491 labels1[isig][ip] = -1;
492 labels2[isig][ip] = -1;
493 labels12[isig][ip] = -1;
500 Bool_t truth1=kFALSE;
501 Bool_t truth2=kFALSE;
502 // loop over the MC tracks
503 for(Int_t ipart=0; ipart<dieMC->GetNMCTracks(); ++ipart) {
504 for(Int_t isig=0; isig<nSignals; ++isig) { // loop over signals
505 // Proceed only if this signal is required in the pure MC step
506 // NOTE: Some signals can be satisfied by many particles and this leads to high
507 // computation times (e.g. secondary electrons from the GEANT transport). Be aware of this!!
508 if(!((AliDielectronSignalMC*)fSignalsMC->At(isig))->GetFillPureMCStep()) continue;
510 truth1 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 1);
511 truth2 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 2);
513 // particles satisfying both branches are treated separately to avoid double counting during pairing
514 if(truth1 && truth2) {
515 labels12[isig][indexes12[isig]] = ipart;
520 labels1[isig][indexes1[isig]] = ipart;
524 labels2[isig][indexes2[isig]] = ipart;
529 } // end loop over MC particles
531 // Do the pairing and fill the CF container with pure MC info
532 for(Int_t isig=0; isig<nSignals; ++isig) {
533 // printf("INDEXES: %d-%d both%d\n",indexes1[isig],indexes2[isig],indexes12[isig]);
534 // mix the particles which satisfy only one of the signal branches
535 for(Int_t i1=0;i1<indexes1[isig];++i1) {
536 if(!indexes2[isig]) FillMCHistograms(labels1[isig][i1], -1, isig); // (e.g. single electrons only, no pairs)
537 for(Int_t i2=0;i2<indexes2[isig];++i2) {
538 // add pair cuts on mc truth level
539 if(bFillCF) fCfManagerPair->FillMC(labels1[isig][i1], labels2[isig][i2], isig);
540 if(bFillHF) fHistoArray->Fill(labels1[isig][i1], labels2[isig][i2], isig);
541 FillMCHistograms(labels1[isig][i1], labels2[isig][i2], isig);
544 // mix the particles which satisfy both branches
545 for(Int_t i1=0;i1<indexes12[isig];++i1) {
546 for(Int_t i2=0; i2<i1; ++i2) {
547 // add pair cuts on mc truth level
548 if(bFillCF) fCfManagerPair->FillMC(labels12[isig][i1], labels12[isig][i2], isig);
549 if(bFillHF) fHistoArray->Fill(labels12[isig][i1], labels12[isig][i2], isig);
550 FillMCHistograms(labels12[isig][i1], labels12[isig][i2], isig);
553 } // end loop over signals
555 // release the memory
556 for(Int_t isig=0;isig<nSignals;++isig) {
557 delete [] *(labels1+isig);
558 delete [] *(labels2+isig);
559 delete [] *(labels12+isig);
569 //________________________________________________________________
570 void AliDielectron::FillHistogramsTracks(TObjArray **tracks)
573 // Fill Histogram information for tracks after prefilter
574 // ignore mixed events - for prefilter, only single tracks +/- are relevant
577 TString className,className2;
578 Double_t values[AliDielectronVarManager::kNMaxValues];
579 AliDielectronVarManager::SetFillMap(fUsedVars);
581 //Fill track information, separately for the track array candidates
582 for (Int_t i=0; i<2; ++i){
583 className.Form("Pre_%s",fgkTrackClassNames[i]);
584 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
585 Int_t ntracks=tracks[i]->GetEntriesFast();
586 for (Int_t itrack=0; itrack<ntracks; ++itrack){
587 AliDielectronVarManager::Fill(tracks[i]->UncheckedAt(itrack), values);
588 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
594 //________________________________________________________________
595 void AliDielectron::FillHistogramsMC(const AliMCEvent *ev, AliVEvent *ev1)
598 // Fill Histogram information for MCEvents
601 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
602 AliDielectronVarManager::SetFillMap(fUsedVars);
604 // Fill event information
605 AliDielectronVarManager::Fill(ev1, values); // ESD/AOD information
606 AliDielectronVarManager::Fill(ev, values); // MC truth info
607 if (fHistos->GetHistogramList()->FindObject("MCEvent"))
608 fHistos->FillClass("MCEvent", AliDielectronVarManager::kNMaxValues, values);
612 //________________________________________________________________
613 void AliDielectron::FillHistograms(const AliVEvent *ev, Bool_t pairInfoOnly)
616 // Fill Histogram information for tracks and pairs
619 TString className,className2;
620 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
621 AliDielectronVarManager::SetFillMap(fUsedVars);
623 //Fill event information
625 if (fHistos->GetHistogramList()->FindObject("Event")) {
626 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, AliDielectronVarManager::GetData());
630 //Fill track information, separately for the track array candidates
632 className2.Form("Track_%s",fgkPairClassNames[1]); // unlike sign, SE only
633 for (Int_t i=0; i<4; ++i){
634 className.Form("Track_%s",fgkTrackClassNames[i]);
635 Bool_t mergedtrkClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
636 Bool_t trkClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
637 if (!trkClass && !mergedtrkClass) continue;
638 Int_t ntracks=fTracks[i].GetEntriesFast();
639 for (Int_t itrack=0; itrack<ntracks; ++itrack){
640 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
642 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
643 if(mergedtrkClass && i<2)
644 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values); //only ev1
649 //Fill Pair information, separately for all pair candidate arrays and the legs
650 TObjArray arrLegs(100);
651 for (Int_t i=0; i<10; ++i){
652 className.Form("Pair_%s",fgkPairClassNames[i]);
653 className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
654 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
655 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
656 if (!pairClass&&!legClass) continue;
657 Int_t ntracks=PairArray(i)->GetEntriesFast();
658 for (Int_t ipair=0; ipair<ntracks; ++ipair){
659 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
661 //fill pair information
663 AliDielectronVarManager::Fill(pair, values);
664 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
667 //fill leg information, don't fill the information twice
669 AliVParticle *d1=pair->GetFirstDaughterP();
670 AliVParticle *d2=pair->GetSecondDaughterP();
671 if (!arrLegs.FindObject(d1)){
672 AliDielectronVarManager::Fill(d1, values);
673 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
676 if (!arrLegs.FindObject(d2)){
677 AliDielectronVarManager::Fill(d2, values);
678 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
683 if (legClass) arrLegs.Clear();
687 //________________________________________________________________
688 void AliDielectron::FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter/*=kFALSE*/)
691 // Fill Histogram information for pairs and the track in the pair
692 // NOTE: in this funtion the leg information may be filled multiple
693 // times. This funtion is used in the track rotation pairing
694 // and those legs are not saved!
696 TString className,className2;
697 Double_t values[AliDielectronVarManager::kNMaxValues];
698 AliDielectronVarManager::SetFillMap(fUsedVars);
700 //Fill Pair information, separately for all pair candidate arrays and the legs
701 TObjArray arrLegs(100);
702 const Int_t type=pair->GetType();
704 className.Form("RejPair_%s",fgkPairClassNames[type]);
705 className2.Form("RejTrack_%s",fgkPairClassNames[type]);
707 className.Form("Pair_%s",fgkPairClassNames[type]);
708 className2.Form("Track_Legs_%s",fgkPairClassNames[type]);
711 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
712 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
714 //fill pair information
716 AliDielectronVarManager::Fill(pair, values);
717 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
721 AliVParticle *d1=pair->GetFirstDaughterP();
722 AliDielectronVarManager::Fill(d1, values);
723 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
725 AliVParticle *d2=pair->GetSecondDaughterP();
726 AliDielectronVarManager::Fill(d2, values);
727 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
731 //________________________________________________________________
732 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
735 // select tracks and fill track candidate arrays
736 // eventNr = 0: First event, use track arrays 0 and 1
737 // eventNr = 1: Second event, use track arrays 2 and 3
740 Int_t ntracks=ev->GetNumberOfTracks();
742 UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
743 for (Int_t itrack=0; itrack<ntracks; ++itrack){
745 AliVParticle *particle=ev->GetTrack(itrack);
748 UInt_t cutmask=fTrackFilter.IsSelected(particle);
750 if(fCutQA) fQAmonitor->FillAll(particle);
751 if(fCutQA) fQAmonitor->Fill(cutmask,particle);
753 if (cutmask!=selectedMask) continue;
755 //fill selected particle into the corresponding track arrays
756 Short_t charge=particle->Charge();
757 if (charge>0) fTracks[eventNr*2].Add(particle);
758 else if (charge<0) fTracks[eventNr*2+1].Add(particle);
764 //________________________________________________________________
765 void AliDielectron::EventPlanePreFilter(Int_t arr1, Int_t arr2, TObjArray arrTracks1, TObjArray arrTracks2, const AliVEvent *ev)
768 // Prefilter tracks and tracks from pairs
769 // Needed for rejection in the Q-Vector of the event plane
770 // remove contribution of all tracks to the Q-vector that are in invariant mass window
773 AliEventplane *evplane = const_cast<AliVEvent *>(ev)->GetEventplane();
774 if(!evplane) { // nanoAODs , here we do NOT have sub event reaction planes
776 // get the EPselectionTask for recalculation of weighting factors
777 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
778 AliEPSelectionTask *eptask = dynamic_cast<AliEPSelectionTask *>(man->GetTask("EventplaneSelection"));
781 // get recentering values for Qx and Qy (only rms is needed for correction)
782 // Double_t mean[2]={0.,0.}
783 // eptask->Recenter(0, mean);
784 Double_t rms[2] ={1.,1.};
785 eptask->Recenter(1, rms);
789 TMap mapRemovedTracks;
792 Double_t cQX=0., cQY=0.;
793 // apply cuts to the tracks, e.g. etagap
794 if(fEventPlanePreFilter.GetCuts()->GetEntries()) {
795 UInt_t selectedMask=(1<<fEventPlanePreFilter.GetCuts()->GetEntries())-1;
796 Int_t ntracks=ev->GetNumberOfTracks();
797 for (Int_t itrack=0; itrack<ntracks; ++itrack){
798 AliVParticle *particle=ev->GetTrack(itrack);
799 AliVTrack *track= static_cast<AliVTrack*>(particle);
800 if (!track) continue;
802 UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
804 if (cutMask==selectedMask) continue;
806 mapRemovedTracks.Add(track,track);
807 cQX += (eptask->GetWeight(track) * TMath::Cos(2*track->Phi()) / rms[0]);
808 cQY += (eptask->GetWeight(track) * TMath::Sin(2*track->Phi()) / rms[1]);
812 // POI (particle of interest) rejection
813 Int_t pairIndex=GetPairIndex(arr1,arr2);
815 Int_t ntrack1=arrTracks1.GetEntriesFast();
816 Int_t ntrack2=arrTracks2.GetEntriesFast();
817 AliDielectronPair candidate;
818 candidate.SetKFUsage(fUseKF);
820 UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
821 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
823 if (arr1==arr2) end=itrack1;
824 Bool_t accepted=kFALSE;
825 for (Int_t itrack2=0; itrack2<end; ++itrack2){
826 TObject *track1=arrTracks1.UncheckedAt(itrack1);
827 TObject *track2=arrTracks2.UncheckedAt(itrack2);
828 if (!track1 || !track2) continue;
830 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
831 static_cast<AliVTrack*>(track2), fPdgLeg2);
832 candidate.SetType(pairIndex);
833 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
835 //event plane pair cuts
836 UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
838 if (cutMask==selectedMask) continue;
841 //remove the tracks from the Track arrays
842 arrTracks2.AddAt(0x0,itrack2);
844 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
846 //compress the track arrays
847 arrTracks1.Compress();
848 arrTracks2.Compress();
850 //Modify the components: subtract the tracks
851 ntrack1=arrTracks1.GetEntriesFast();
852 ntrack2=arrTracks2.GetEntriesFast();
853 // remove leg1 contribution
854 for (Int_t itrack=0; itrack<ntrack1; ++itrack){
855 AliVTrack *track= static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack));
856 if (!track) continue;
857 // track contribution was already removed
858 if (mapRemovedTracks.FindObject(track)) continue;
859 else mapRemovedTracks.Add(track,track);
861 cQX += (eptask->GetWeight(track) * TMath::Cos(2*track->Phi()) / rms[0]);
862 cQY += (eptask->GetWeight(track) * TMath::Sin(2*track->Phi()) / rms[1]);
864 // remove leg2 contribution
865 for (Int_t itrack=0; itrack<ntrack2; ++itrack){
866 AliVTrack *track= static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack));
867 if (!track) continue;
868 // track contribution was already removed
869 if (mapRemovedTracks.FindObject(track)) continue;
870 else mapRemovedTracks.Add(track,track);
872 cQX += (eptask->GetWeight(track) * TMath::Cos(2*track->Phi()) / rms[0]);
873 cQY += (eptask->GetWeight(track) * TMath::Sin(2*track->Phi()) / rms[1]);
876 // build a corrected alieventplane using the values from the var manager
877 // these uncorrected values are filled using the stored magnitude and angle in the header
879 qcorr.Set(AliDielectronVarManager::GetValue(AliDielectronVarManager::kTPCxH2uc)-cQX,
880 AliDielectronVarManager::GetValue(AliDielectronVarManager::kTPCyH2uc)-cQY);
881 // fill alieventplane
882 AliEventplane cevplane;
883 cevplane.SetQVector(&qcorr);
884 AliDielectronVarManager::SetTPCEventPlane(&cevplane);
885 cevplane.SetQVector(0);
890 // this is done in case of ESDs or AODs
891 Bool_t isESD=(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliESDInputHandler::Class());
892 // copy event plane object
893 AliEventplane cevplane(*evplane);
894 // Int_t nMaxID=cevplane->GetQContributionXArray()->GetSize();
896 TVector2 *qcorr = cevplane.GetQVector();
898 TVector2 *qcsub1 = 0x0;
899 TVector2 *qcsub2 = 0x0;
902 Bool_t etagap = kFALSE;
903 for (Int_t iCut=0; iCut<fEventPlanePreFilter.GetCuts()->GetEntries();++iCut) {
904 TString cutName=fEventPlanePreFilter.GetCuts()->At(iCut)->GetName();
905 if(cutName.Contains("eta") || cutName.Contains("Eta")) etagap=kTRUE;
908 // subevent configuration for eta gap or LS (default is rndm)
909 if(fLikeSignSubEvents && etagap) {
910 // start with the full Qvector/event in both sub events
911 qcsub1 = new TVector2(*qcorr);
912 qcsub2 = new TVector2(*qcorr);
913 cevplane.SetQsub(qcsub1,qcsub2);
915 Int_t ntracks=ev->GetNumberOfTracks();
917 for (Int_t itrack=0; itrack<ntracks; ++itrack){
918 AliVParticle *particle=ev->GetTrack(itrack);
919 AliVTrack *track= static_cast<AliVTrack*>(particle);
920 if (!track) continue;
921 if (track->GetID()>=0 && !isESD) continue;
922 Int_t tmpID = isESD ? track->GetID() : track->GetID()*-1 - 1;
924 // set contributions to zero
925 // charge sub1+ sub2-
926 if(fLikeSignSubEvents) {
927 Short_t charge=track->Charge();
929 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
930 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
933 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
934 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
939 Double_t eta=track->Eta();
941 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
942 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
945 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
946 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
949 } // end: loop over tracks
950 } // end: sub event configuration
952 // apply cuts, e.g. etagap
953 if(fEventPlanePreFilter.GetCuts()->GetEntries()) {
954 UInt_t selectedMask=(1<<fEventPlanePreFilter.GetCuts()->GetEntries())-1;
955 Int_t ntracks=ev->GetNumberOfTracks();
956 for (Int_t itrack=0; itrack<ntracks; ++itrack){
957 AliVParticle *particle=ev->GetTrack(itrack);
958 AliVTrack *track= static_cast<AliVTrack*>(particle);
959 if (!track) continue;
960 if (track->GetID()>=0 && !isESD) continue;
961 Int_t tmpID = isESD ? track->GetID() : track->GetID()*-1 - 1;
964 UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
966 if (cutMask==selectedMask) continue;
968 // set contributions to zero
969 cevplane.GetQContributionXArray()->SetAt(0.0, tmpID);
970 cevplane.GetQContributionYArray()->SetAt(0.0, tmpID);
971 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
972 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
973 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
974 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
978 // POI (particle of interest) rejection
979 Int_t pairIndex=GetPairIndex(arr1,arr2);
980 Int_t ntrack1=arrTracks1.GetEntriesFast();
981 Int_t ntrack2=arrTracks2.GetEntriesFast();
982 AliDielectronPair candidate;
983 candidate.SetKFUsage(fUseKF);
985 UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
986 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
988 if (arr1==arr2) end=itrack1;
989 Bool_t accepted=kFALSE;
990 for (Int_t itrack2=0; itrack2<end; ++itrack2){
991 TObject *track1=arrTracks1.UncheckedAt(itrack1);
992 TObject *track2=arrTracks2.UncheckedAt(itrack2);
993 if (!track1 || !track2) continue;
995 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
996 static_cast<AliVTrack*>(track2), fPdgLeg2);
998 candidate.SetType(pairIndex);
999 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
1002 UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
1004 if (cutMask==selectedMask) continue;
1007 //remove the tracks from the Track arrays
1008 arrTracks2.AddAt(0x0,itrack2);
1010 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
1012 //compress the track arrays
1013 arrTracks1.Compress();
1014 arrTracks2.Compress();
1016 //Modify the components: subtract the tracks
1017 ntrack1=arrTracks1.GetEntriesFast();
1018 ntrack2=arrTracks2.GetEntriesFast();
1019 // remove leg1 contribution
1020 for (Int_t itrack=0; itrack<ntrack1; ++itrack){
1021 AliVTrack *track= static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack));
1022 if (!track) continue;
1023 if (track->GetID()>=0 && !isESD) continue;
1024 Int_t tmpID = isESD ? track->GetID() : track->GetID()*-1 - 1;
1025 // set contributions to zero
1026 cevplane.GetQContributionXArray()->SetAt(0.0, tmpID);
1027 cevplane.GetQContributionYArray()->SetAt(0.0, tmpID);
1028 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
1029 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
1030 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
1031 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
1033 // remove leg2 contribution
1034 for (Int_t itrack=0; itrack<ntrack2; ++itrack){
1035 AliVTrack *track= static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack));
1036 if (!track) continue;
1037 if (track->GetID()>=0 && !isESD) continue;
1038 Int_t tmpID = isESD ? track->GetID() : track->GetID()*-1 - 1;
1039 // set contributions to zero
1040 cevplane.GetQContributionXArray()->SetAt(0.0, tmpID);
1041 cevplane.GetQContributionYArray()->SetAt(0.0, tmpID);
1042 cevplane.GetQContributionXArraysub1()->SetAt(0.0, tmpID);
1043 cevplane.GetQContributionYArraysub1()->SetAt(0.0, tmpID);
1044 cevplane.GetQContributionXArraysub2()->SetAt(0.0, tmpID);
1045 cevplane.GetQContributionYArraysub2()->SetAt(0.0, tmpID);
1048 // set corrected AliEventplane and fill variables with corrected values
1049 AliDielectronVarManager::SetTPCEventPlane(&cevplane);
1052 } // end: ESD or AOD case
1055 //________________________________________________________________
1056 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
1059 // Prefilter tracks from pairs
1060 // Needed for datlitz rejections
1061 // remove all tracks from the Single track arrays that pass the cuts in this filter
1064 Int_t ntrack1=arrTracks1.GetEntriesFast();
1065 Int_t ntrack2=arrTracks2.GetEntriesFast();
1066 AliDielectronPair candidate;
1067 candidate.SetKFUsage(fUseKF);
1068 // flag arrays for track removal
1069 Bool_t *bTracks1 = new Bool_t[ntrack1];
1070 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1) bTracks1[itrack1]=kFALSE;
1071 Bool_t *bTracks2 = new Bool_t[ntrack2];
1072 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2) bTracks2[itrack2]=kFALSE;
1074 UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
1075 UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1077 Int_t nRejPasses = 1; //for fPreFilterUnlikeOnly and no set flag
1078 if (fPreFilterAllSigns) nRejPasses = 3;
1080 for (Int_t iRP=0; iRP < nRejPasses; ++iRP) {
1081 Int_t arr1RP=arr1, arr2RP=arr2;
1082 TObjArray *arrTracks1RP=&arrTracks1;
1083 TObjArray *arrTracks2RP=&arrTracks2;
1084 Bool_t *bTracks1RP = bTracks1;
1085 Bool_t *bTracks2RP = bTracks2;
1087 case 1: arr1RP=arr1;arr2RP=arr1;
1088 arrTracks1RP=&arrTracks1;
1089 arrTracks2RP=&arrTracks1;
1090 bTracks1RP = bTracks1;
1091 bTracks2RP = bTracks1;
1093 case 2: arr1RP=arr2;arr2RP=arr2;
1094 arrTracks1RP=&arrTracks2;
1095 arrTracks2RP=&arrTracks2;
1096 bTracks1RP = bTracks2;
1097 bTracks2RP = bTracks2;
1099 default: ;//nothing to do
1101 Int_t ntrack1RP=(*arrTracks1RP).GetEntriesFast();
1102 Int_t ntrack2RP=(*arrTracks2RP).GetEntriesFast();
1104 Int_t pairIndex=GetPairIndex(arr1RP,arr2RP);
1106 for (Int_t itrack1=0; itrack1<ntrack1RP; ++itrack1){
1107 Int_t end=ntrack2RP;
1108 if (arr1RP==arr2RP) end=itrack1;
1109 for (Int_t itrack2=0; itrack2<end; ++itrack2){
1110 TObject *track1=(*arrTracks1RP).UncheckedAt(itrack1);
1111 TObject *track2=(*arrTracks2RP).UncheckedAt(itrack2);
1112 if (!track1 || !track2) continue;
1114 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
1115 static_cast<AliVTrack*>(track2), fPdgLeg2);
1117 candidate.SetType(pairIndex);
1118 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
1119 //relate to the production vertex
1120 // if (AliDielectronVarManager::GetKFVertex()) candidate.SetProductionVertex(*AliDielectronVarManager::GetKFVertex());
1123 UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
1126 if (cutMask!=selectedMask) continue;
1127 if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
1128 if (fHistos) FillHistogramsPair(&candidate,kTRUE);
1129 //set flags for track removal
1130 bTracks1RP[itrack1]=kTRUE;
1131 bTracks2RP[itrack2]=kTRUE;
1136 //remove the tracks from the Track arrays
1137 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
1138 if(bTracks1[itrack1]) arrTracks1.AddAt(0x0, itrack1);
1140 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2){
1141 if(bTracks2[itrack2]) arrTracks2.AddAt(0x0, itrack2);
1148 //compress the track arrays
1149 arrTracks1.Compress();
1150 arrTracks2.Compress();
1152 //apply leg cuts after the pre filter
1153 if ( fPairPreFilterLegs.GetCuts()->GetEntries()>0 ) {
1154 selectedMask=(1<<fPairPreFilterLegs.GetCuts()->GetEntries())-1;
1155 //loop over tracks from array 1
1156 for (Int_t itrack=0; itrack<arrTracks1.GetEntriesFast();++itrack){
1158 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
1161 if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);
1163 arrTracks1.Compress();
1165 //in case of like sign don't loop over second array
1167 arrTracks2=arrTracks1;
1170 //loop over tracks from array 2
1171 for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
1173 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
1175 if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
1177 arrTracks2.Compress();
1181 //For unlike-sign monitor track-cuts:
1182 if (arr1!=arr2&&fHistos) {
1183 TObjArray *unlikesignArray[2] = {&arrTracks1,&arrTracks2};
1184 FillHistogramsTracks(unlikesignArray);
1188 //________________________________________________________________
1189 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2)
1192 // select pairs and fill pair candidate arrays
1195 TObjArray arrTracks1=fTracks[arr1];
1196 TObjArray arrTracks2=fTracks[arr2];
1198 //process pre filter if set
1199 if ((!fPreFilterAllSigns) && (!fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
1201 Int_t pairIndex=GetPairIndex(arr1,arr2);
1203 Int_t ntrack1=arrTracks1.GetEntriesFast();
1204 Int_t ntrack2=arrTracks2.GetEntriesFast();
1206 AliDielectronPair *candidate=new AliDielectronPair;
1207 candidate->SetKFUsage(fUseKF);
1209 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1211 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
1213 if (arr1==arr2) end=itrack1;
1214 for (Int_t itrack2=0; itrack2<end; ++itrack2){
1215 //create the pair (direct pointer to the memory by this daughter reference are kept also for ME)
1216 candidate->SetTracks(&(*static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1))), fPdgLeg1,
1217 &(*static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2))), fPdgLeg2);
1218 candidate->SetType(pairIndex);
1220 Int_t label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother);
1221 candidate->SetLabel(label);
1222 if (label>-1) candidate->SetPdgCode(fPdgMother);
1223 else candidate->SetPdgCode(0);
1225 // check for gamma kf particle
1226 label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,22);
1228 candidate->SetGammaTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
1229 static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
1230 // should we set the pdgmothercode and the label
1234 UInt_t cutMask=fPairFilter.IsSelected(candidate);
1236 //CF manager for the pair
1237 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
1240 if(pairIndex==kEv1PM && fCutQA) {
1241 fQAmonitor->FillAll(candidate);
1242 fQAmonitor->Fill(cutMask,candidate);
1246 if (cutMask!=selectedMask) continue;
1248 //histogram array for the pair
1249 if (fHistoArray) fHistoArray->Fill(pairIndex,candidate);
1251 //add the candidate to the candidate array
1252 PairArray(pairIndex)->Add(candidate);
1253 //get a new candidate
1254 candidate=new AliDielectronPair;
1255 candidate->SetKFUsage(fUseKF);
1258 //delete the surplus candidate
1262 //________________________________________________________________
1263 void AliDielectron::FillPairArrayTR()
1266 // select pairs and fill pair candidate arrays
1268 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1270 while ( fTrackRotator->NextCombination() ){
1271 AliDielectronPair candidate;
1272 candidate.SetKFUsage(fUseKF);
1273 candidate.SetTracks(&fTrackRotator->GetKFTrackP(), &fTrackRotator->GetKFTrackN(),
1274 fTrackRotator->GetVTrackP(),fTrackRotator->GetVTrackN());
1275 candidate.SetType(kEv1PMRot);
1278 UInt_t cutMask=fPairFilter.IsSelected(&candidate);
1280 //CF manager for the pair
1281 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,&candidate);
1284 if (cutMask==selectedMask) {
1286 //histogram array for the pair
1287 if (fHistoArray) fHistoArray->Fill((Int_t)kEv1PMRot,&candidate);
1289 if(fHistos) FillHistogramsPair(&candidate);
1290 if(fStoreRotatedPairs) PairArray(kEv1PMRot)->Add(new AliDielectronPair(candidate));
1295 //________________________________________________________________
1296 void AliDielectron::FillDebugTree()
1299 // Fill Histogram information for tracks and pairs
1303 for (Int_t i=0; i<10; ++i){
1304 Int_t ntracks=PairArray(i)->GetEntriesFast();
1305 for (Int_t ipair=0; ipair<ntracks; ++ipair){
1306 fDebugTree->Fill(static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair)));
1311 //________________________________________________________________
1312 void AliDielectron::SaveDebugTree()
1315 // delete the debug tree, this will also write the tree
1317 if (fDebugTree) fDebugTree->DeleteStreamer();
1321 //__________________________________________________________________
1322 void AliDielectron::AddSignalMC(AliDielectronSignalMC* signal) {
1324 // Add an MC signal to the signals list
1327 fSignalsMC = new TObjArray();
1328 fSignalsMC->SetOwner();
1330 fSignalsMC->Add(signal);
1333 //________________________________________________________________
1334 void AliDielectron::FillMCHistograms(Int_t label1, Int_t label2, Int_t nSignal) {
1336 // fill QA MC TRUTH histograms for pairs and legs of all added mc signals
1339 TString className,className2,className3;
1340 className.Form("Pair_%s_MCtruth",fSignalsMC->At(nSignal)->GetName());
1341 className2.Form("Track_Legs_%s_MCtruth",fSignalsMC->At(nSignal)->GetName());
1342 className3.Form("Track_%s_%s_MCtruth",fgkPairClassNames[1],fSignalsMC->At(nSignal)->GetName());
1343 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
1344 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
1345 Bool_t trkClass=fHistos->GetHistogramList()->FindObject(className3.Data())!=0x0;
1346 // printf("fill signal %d: pair %d legs %d trk %d \n",nSignal,pairClass,legClass,trkClass);
1347 if(!pairClass && !legClass && !trkClass) return;
1349 // printf("leg labels: %d-%d \n",label1,label2);
1350 AliVParticle* part1 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label1);
1351 AliVParticle* part2 = AliDielectronMC::Instance()->GetMCTrackFromMCEvent(label2);
1352 if(!part1 && !part2) return;
1354 // fill only unlike sign (and only SE)
1355 if(part1->Charge()*part2->Charge()>=0) return;
1359 AliDielectronMC* dieMC = AliDielectronMC::Instance();
1361 Int_t mLabel1 = dieMC->GetMothersLabel(label1); // should work for both ESD and AOD
1362 Int_t mLabel2 = dieMC->GetMothersLabel(label2);
1364 // check the same mother option
1365 AliDielectronSignalMC* sigMC = (AliDielectronSignalMC*)fSignalsMC->At(nSignal);
1366 if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kSame && mLabel1!=mLabel2) return;
1367 if(sigMC->GetMothersRelation()==AliDielectronSignalMC::kDifferent && mLabel1==mLabel2) return;
1369 // fill event values
1370 Double_t values[AliDielectronVarManager::kNMaxValues];
1371 AliDielectronVarManager::SetFillMap(fUsedVars);
1372 AliDielectronVarManager::Fill(dieMC->GetMCEvent(), values); // get event informations
1374 // fill the leg variables
1375 // printf("leg:%d trk:%d part1:%p part2:%p \n",legClass,trkClass,part1,part2);
1376 if (legClass || trkClass) {
1377 if(part1) AliDielectronVarManager::Fill(part1,values);
1378 if(part1 && trkClass) fHistos->FillClass(className3, AliDielectronVarManager::kNMaxValues, values);
1379 if(part1 && part2 && legClass) fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1380 if(part2) AliDielectronVarManager::Fill(part2,values);
1381 if(part2 && trkClass) fHistos->FillClass(className3, AliDielectronVarManager::kNMaxValues, values);
1382 if(part1 && part2 && legClass) fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1385 //fill pair information
1386 if (pairClass && part1 && part2) {
1387 AliDielectronVarManager::FillVarMCParticle2(part1,part2,values);
1388 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1393 //________________________________________________________________
1394 void AliDielectron::FillMCHistograms(const AliVEvent *ev) {
1396 // fill QA MC histograms for pairs and legs of all added mc signals
1399 if (!fSignalsMC) return;
1400 TString className,className2,className3;
1401 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
1402 AliDielectronVarManager::SetFillMap(fUsedVars);
1403 AliDielectronVarManager::Fill(ev, values); // get event informations
1404 //loop over all added mc signals
1405 for(Int_t isig=0; isig<fSignalsMC->GetEntries(); isig++) {
1407 //check if and what to fill
1408 className.Form("Pair_%s",fSignalsMC->At(isig)->GetName());
1409 className2.Form("Track_Legs_%s",fSignalsMC->At(isig)->GetName());
1410 className3.Form("Track_%s_%s",fgkPairClassNames[1],fSignalsMC->At(isig)->GetName()); // unlike sign, SE only
1411 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
1412 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
1413 Bool_t mergedtrkClass=fHistos->GetHistogramList()->FindObject(className3.Data())!=0x0;
1414 if(!pairClass && !legClass && !mergedtrkClass) continue;
1416 // fill pair and/or their leg variables
1417 if(pairClass || legClass) {
1418 Int_t npairs=PairArray(AliDielectron::kEv1PM)->GetEntriesFast(); // only SE +-
1419 for (Int_t ipair=0; ipair<npairs; ++ipair){
1420 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(AliDielectron::kEv1PM)->UncheckedAt(ipair));
1422 Bool_t isMCtruth = AliDielectronMC::Instance()->IsMCTruth(pair, (AliDielectronSignalMC*)fSignalsMC->At(isig));
1424 //fill pair information
1426 AliDielectronVarManager::Fill(pair, values);
1427 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1429 //fill leg information, both + and - in the same histo
1431 AliDielectronVarManager::Fill(pair->GetFirstDaughterP(),values);
1432 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1433 AliDielectronVarManager::Fill(pair->GetSecondDaughterP(),values);
1434 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1440 // fill single tracks of signals
1441 if(!mergedtrkClass) continue;
1442 // loop over SE track arrays
1443 for (Int_t i=0; i<2; ++i){
1444 Int_t ntracks=fTracks[i].GetEntriesFast();
1445 for (Int_t itrack=0; itrack<ntracks; ++itrack){
1446 Int_t label=((AliVParticle*)fTracks[i].UncheckedAt(itrack))->GetLabel();
1447 Bool_t isMCtruth1 = AliDielectronMC::Instance()->IsMCTruth(label, (AliDielectronSignalMC*)fSignalsMC->At(isig), 1);
1448 Bool_t isMCtruth2 = AliDielectronMC::Instance()->IsMCTruth(label, (AliDielectronSignalMC*)fSignalsMC->At(isig), 2);
1449 // skip if track does not correspond to the signal
1450 if(!isMCtruth1 && !isMCtruth2) continue;
1451 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
1452 fHistos->FillClass(className3, AliDielectronVarManager::kNMaxValues, values);
1460 //______________________________________________
1461 void AliDielectron::SetCentroidCorrFunction(TF1 *fun, UInt_t varx, UInt_t vary, UInt_t varz)
1463 UInt_t valType[20] = {0};
1464 valType[0]=varx; valType[1]=vary; valType[2]=varz;
1465 AliDielectronHistos::StoreVariables(fun->GetHistogram(), valType);
1466 // clone temporare histogram, otherwise it will not be streamed to file!
1467 TString key = Form("cntrd%d%d%d",varx,vary,varz);
1468 fPostPIDCntrdCorr = (TH1*)fun->GetHistogram()->Clone(key.Data());
1469 if(fPostPIDCntrdCorr) {
1470 fPostPIDCntrdCorr->GetListOfFunctions()->AddAt(fun,0);
1471 // check for corrections and add their variables to the fill map
1472 printf("POST TPC PID CORRECTION added for centroids: ");
1473 switch(fPostPIDCntrdCorr->GetDimension()) {
1474 case 3: printf(" %s, ",fPostPIDCntrdCorr->GetZaxis()->GetName());
1475 case 2: printf(" %s, ",fPostPIDCntrdCorr->GetYaxis()->GetName());
1476 case 1: printf(" %s ",fPostPIDCntrdCorr->GetXaxis()->GetName());
1479 fUsedVars->SetBitNumber(varx, kTRUE);
1480 fUsedVars->SetBitNumber(vary, kTRUE);
1481 fUsedVars->SetBitNumber(varz, kTRUE);
1485 //______________________________________________
1486 void AliDielectron::SetCentroidCorrFunction(TH1 *fun, UInt_t varx, UInt_t vary, UInt_t varz)
1488 UInt_t valType[20] = {0};
1489 valType[0]=varx; valType[1]=vary; valType[2]=varz;
1490 AliDielectronHistos::StoreVariables(fun, valType);
1491 // clone temporare histogram, otherwise it will not be streamed to file!
1492 TString key = Form("cntrd%d%d%d",varx,vary,varz);
1493 fPostPIDCntrdCorr = (TH1*)fun->Clone(key.Data());
1494 // check for corrections and add their variables to the fill map
1495 if(fPostPIDCntrdCorr) {
1496 printf("POST TPC PID CORRECTION added for centroids: ");
1497 switch(fPostPIDCntrdCorr->GetDimension()) {
1498 case 3: printf(" %s, ",fPostPIDCntrdCorr->GetZaxis()->GetName());
1499 case 2: printf(" %s, ",fPostPIDCntrdCorr->GetYaxis()->GetName());
1500 case 1: printf(" %s ",fPostPIDCntrdCorr->GetXaxis()->GetName());
1503 fUsedVars->SetBitNumber(varx, kTRUE);
1504 fUsedVars->SetBitNumber(vary, kTRUE);
1505 fUsedVars->SetBitNumber(varz, kTRUE);
1509 //______________________________________________
1510 void AliDielectron::SetWidthCorrFunction(TF1 *fun, UInt_t varx, UInt_t vary, UInt_t varz)
1512 UInt_t valType[20] = {0};
1513 valType[0]=varx; valType[1]=vary; valType[2]=varz;
1514 AliDielectronHistos::StoreVariables(fun->GetHistogram(), valType);
1515 // clone temporare histogram, otherwise it will not be streamed to file!
1516 TString key = Form("wdth%d%d%d",varx,vary,varz);
1517 fPostPIDWdthCorr = (TH1*)fun->GetHistogram()->Clone(key.Data());
1518 if(fPostPIDWdthCorr) {
1519 fPostPIDWdthCorr->GetListOfFunctions()->AddAt(fun,0);
1520 // check for corrections and add their variables to the fill map
1521 printf("POST TPC PID CORRECTION added for widths: ");
1522 switch(fPostPIDWdthCorr->GetDimension()) {
1523 case 3: printf(" %s, ",fPostPIDWdthCorr->GetZaxis()->GetName());
1524 case 2: printf(" %s, ",fPostPIDWdthCorr->GetYaxis()->GetName());
1525 case 1: printf(" %s ",fPostPIDWdthCorr->GetXaxis()->GetName());
1528 fUsedVars->SetBitNumber(varx, kTRUE);
1529 fUsedVars->SetBitNumber(vary, kTRUE);
1530 fUsedVars->SetBitNumber(varz, kTRUE);
1533 //______________________________________________
1534 void AliDielectron::SetWidthCorrFunction(TH1 *fun, UInt_t varx, UInt_t vary, UInt_t varz)
1536 UInt_t valType[20] = {0};
1537 valType[0]=varx; valType[1]=vary; valType[2]=varz;
1538 AliDielectronHistos::StoreVariables(fun, valType);
1539 // clone temporare histogram, otherwise it will not be streamed to file!
1540 TString key = Form("cntrd%d%d%d",varx,vary,varz);
1541 fPostPIDWdthCorr = (TH1*)fun->Clone(key.Data());
1542 // check for corrections and add their variables to the fill map
1543 if(fPostPIDWdthCorr) {
1544 printf("POST TPC PID CORRECTION added for widths: ");
1545 switch(fPostPIDWdthCorr->GetDimension()) {
1546 case 3: printf(" %s, ",fPostPIDWdthCorr->GetZaxis()->GetName());
1547 case 2: printf(" %s, ",fPostPIDWdthCorr->GetYaxis()->GetName());
1548 case 1: printf(" %s ",fPostPIDWdthCorr->GetXaxis()->GetName());
1551 fUsedVars->SetBitNumber(varx, kTRUE);
1552 fUsedVars->SetBitNumber(vary, kTRUE);
1553 fUsedVars->SetBitNumber(varz, kTRUE);
1558 //______________________________________________
1559 TObject* AliDielectron::InitEffMap(TString filename)
1561 // init an efficiency object for on-the-fly correction calculations
1562 if(filename.Contains("alien://") && !gGrid) TGrid::Connect("alien://",0,0,"t");
1564 TFile* file=TFile::Open(filename.Data());
1565 if(!file) return 0x0;
1566 else printf("[I] AliDielectron::InitEffMap efficiency maps %s loaded! \n",filename.Data());
1568 // NOTE: the spline must have the 'variable name' stored in its fHistogram
1569 TSpline3 *hEff = (TSpline3*) file->Get("hEfficiency");
1570 //if(hEff) printf("we use a TSpline!!!!!!!!!!! \n");
1571 if(hEff) return (hEff->Clone("effMap"));
1574 THnBase *hGen = (THnBase*) file->Get("hGenerated");
1575 THnBase *hFnd = (THnBase*) file->Get("hFound");
1576 if(!hFnd || !hGen) return 0x0;
1579 return (hFnd->Clone("effMap"));
1582 //________________________________________________________________
1583 void AliDielectron::FillHistogramsFromPairArray(Bool_t pairInfoOnly/*=kFALSE*/)
1586 // Fill Histogram information for tracks and pairs
1589 TString className,className2;
1590 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
1591 AliDielectronVarManager::SetFillMap(fUsedVars);
1592 AliDielectronVarManager::SetLegEffMap(fLegEffMap);
1593 AliDielectronVarManager::SetPairEffMap(fPairEffMap);
1595 //Fill event information
1597 if(fHistos->GetHistogramList()->FindObject("Event")) {
1598 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, AliDielectronVarManager::GetData());
1602 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1604 //Fill Pair information, separately for all pair candidate arrays and the legs
1605 TObjArray arrLegs(100);
1606 for (Int_t i=0; i<10; ++i){ // ROT pairs??
1607 Int_t npairs=PairArray(i)->GetEntriesFast();
1608 if(npairs<1) continue;
1610 className.Form("Pair_%s",fgkPairClassNames[i]);
1611 className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
1612 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
1613 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
1615 // if (!pairClass&&!legClass) continue;
1616 for (Int_t ipair=0; ipair<npairs; ++ipair){
1617 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
1620 UInt_t cutMask=fPairFilter.IsSelected(pair);
1623 if(i==kEv1PM && fCutQA) {
1624 fQAmonitor->FillAll(pair);
1625 fQAmonitor->Fill(cutMask,pair);
1628 //CF manager for the pair (TODO: check steps and if they are properly filled)
1629 // if (fCfManagerPair) fCfManagerPair->Fill(cutMask,pair);
1632 if (cutMask!=selectedMask) continue;
1634 //histogram array for the pair
1635 if (fHistoArray) fHistoArray->Fill(i,pair);
1638 AliDielectronVarManager::SetFillMap(fUsedVars);
1640 //fill pair information
1642 AliDielectronVarManager::Fill(pair, values);
1643 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1646 //fill leg information, don't fill the information twice
1648 AliVParticle *d1=pair->GetFirstDaughterP();
1649 AliVParticle *d2=pair->GetSecondDaughterP();
1650 if (!arrLegs.FindObject(d1)){
1651 AliDielectronVarManager::Fill(d1, values);
1652 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1655 if (!arrLegs.FindObject(d2)){
1656 AliDielectronVarManager::Fill(d2, values);
1657 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1662 if (legClass) arrLegs.Clear();