1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
17 // Dielectron Analysis Main class //
20 Framework to perform event selectoin, single track selection and track pair
23 Convention for the signs of the pair in fPairCandidates:
24 The names are available via the function PairClassName(Int_t i)
26 0: ev1+ ev1+ (same event like sign +)
27 1: ev1+ ev1- (same event unlike sign)
28 2: ev1- ev1- (same event like sign -)
30 3: ev1+ ev2+ (mixed event like sign +)
31 4: ev1- ev2+ (mixed event unlike sign -+)
32 6: ev1+ ev2- (mixed event unlike sign +-)
33 7: ev1- ev2- (mixed event like sign -)
35 5: ev2+ ev2+ (same event like sign +)
36 8: ev2+ ev2- (same event unlike sign)
37 9: ev2- ev2- (same event like sign -)
39 10: ev1+ ev1- (same event track rotation)
43 ///////////////////////////////////////////////////////////////////////////
50 #include <AliKFParticle.h>
52 #include <AliEventplane.h>
53 #include <AliVEvent.h>
54 #include <AliVParticle.h>
55 #include <AliVTrack.h>
56 #include "AliDielectronPair.h"
57 #include "AliDielectronHistos.h"
58 #include "AliDielectronCF.h"
59 #include "AliDielectronMC.h"
60 #include "AliDielectronVarManager.h"
61 #include "AliDielectronTrackRotator.h"
62 #include "AliDielectronDebugTree.h"
63 #include "AliDielectronSignalMC.h"
64 #include "AliDielectronMixingHandler.h"
66 #include "AliDielectron.h"
68 ClassImp(AliDielectron)
70 const char* AliDielectron::fgkTrackClassNames[4] = {
77 const char* AliDielectron::fgkPairClassNames[11] = {
91 //________________________________________________________________
92 AliDielectron::AliDielectron() :
93 TNamed("AliDielectron","AliDielectron"),
94 fEventFilter("EventFilter"),
95 fTrackFilter("TrackFilter"),
96 fPairPreFilter("PairPreFilter"),
97 fPairPreFilterLegs("PairPreFilterLegs"),
98 fPairFilter("PairFilter"),
99 fEventPlanePreFilter("EventPlanePreFilter"),
100 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
109 fPairCandidates(new TObjArray(11)),
114 fPreFilterEventPlane(kFALSE),
115 fLikeSignSubEvents(kFALSE),
116 fPreFilterUnlikeOnly(kFALSE),
117 fPreFilterAllSigns(kFALSE),
119 fStoreRotatedPairs(kFALSE),
120 fDontClearArrays(kFALSE),
121 fEstimatorFilename(""),
122 fTRDpidCorrectionFilename(""),
123 fVZEROCalibrationFilename(""),
124 fVZERORecenteringFilename("")
127 // Default constructor
132 //________________________________________________________________
133 AliDielectron::AliDielectron(const char* name, const char* title) :
135 fEventFilter("EventFilter"),
136 fTrackFilter("TrackFilter"),
137 fPairPreFilter("PairPreFilter"),
138 fPairPreFilterLegs("PairPreFilterLegs"),
139 fPairFilter("PairFilter"),
140 fEventPlanePreFilter("EventPlanePreFilter"),
141 fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
150 fPairCandidates(new TObjArray(11)),
155 fPreFilterEventPlane(kFALSE),
156 fLikeSignSubEvents(kFALSE),
157 fPreFilterUnlikeOnly(kFALSE),
158 fPreFilterAllSigns(kFALSE),
160 fStoreRotatedPairs(kFALSE),
161 fDontClearArrays(kFALSE),
162 fEstimatorFilename(""),
163 fTRDpidCorrectionFilename(""),
164 fVZEROCalibrationFilename(""),
165 fVZERORecenteringFilename("")
173 //________________________________________________________________
174 AliDielectron::~AliDielectron()
177 // Default destructor
179 if (fHistoArray) delete fHistoArray;
180 if (fHistos) delete fHistos;
181 if (fPairCandidates) delete fPairCandidates;
182 if (fDebugTree) delete fDebugTree;
183 if (fMixing) delete fMixing;
184 if (fSignalsMC) delete fSignalsMC;
185 if (fCfManagerPair) delete fCfManagerPair;
188 //________________________________________________________________
189 void AliDielectron::Init()
192 // Initialise objects
195 if(GetHasMC()) AliDielectronMC::Instance()->SetHasMC(GetHasMC());
197 InitPairCandidateArrays();
199 if (fCfManagerPair) {
200 fCfManagerPair->SetSignalsMC(fSignalsMC);
201 fCfManagerPair->InitialiseContainer(fPairFilter);
204 fTrackRotator->SetTrackArrays(&fTracks[0],&fTracks[1]);
205 fTrackRotator->SetPdgLegs(fPdgLeg1,fPdgLeg2);
207 if (fDebugTree) fDebugTree->SetDielectron(this);
208 if(fEstimatorFilename.Contains(".root")) AliDielectronVarManager::InitEstimatorAvg(fEstimatorFilename.Data());
209 if(fTRDpidCorrectionFilename.Contains(".root")) AliDielectronVarManager::InitTRDpidEffHistograms(fTRDpidCorrectionFilename.Data());
210 if(fVZEROCalibrationFilename.Contains(".root")) AliDielectronVarManager::SetVZEROCalibrationFile(fVZEROCalibrationFilename.Data());
211 if(fVZERORecenteringFilename.Contains(".root")) AliDielectronVarManager::SetVZERORecenteringFile(fVZERORecenteringFilename.Data());
213 if (fMixing) fMixing->Init(this);
215 fHistoArray->SetSignalsMC(fSignalsMC);
220 //________________________________________________________________
221 void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
224 // Process the events
227 //at least first event is needed!
229 AliError("At least first event must be set!");
232 AliDielectronVarManager::SetEvent(ev1);
234 //set mixing bin to event data
235 Int_t bin=fMixing->FindBin(AliDielectronVarManager::GetData());
236 AliDielectronVarManager::SetValue(AliDielectronVarManager::kMixingBin,bin);
239 //in case we have MC load the MC event and process the MC particles
240 if (AliDielectronMC::Instance()->ConnectMCEvent()){
244 //if candidate array doesn't exist, create it
245 if (!fPairCandidates->UncheckedAt(0)) {
246 InitPairCandidateArrays();
251 //mask used to require that all cuts are fulfilled
252 UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
255 if ((ev1&&fEventFilter.IsSelected(ev1)!=selectedMask) ||
256 (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
258 // AliDielectronVarManager::SetEvent(ev1); // why a second time???
260 //fill track arrays for the first event
262 FillTrackArrays(ev1);
263 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
267 //fill track arrays for the second event
269 FillTrackArrays(ev2,1);
270 if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
273 // TPC event plane correction
274 AliEventplane *cevplane = new AliEventplane();
275 if (ev1 && cevplane && fPreFilterEventPlane && ( fEventPlanePreFilter.GetCuts()->GetEntries()>0 || fEventPlanePOIPreFilter.GetCuts()->GetEntries()>0))
276 EventPlanePreFilter(0, 1, fTracks[0], fTracks[1], ev1, cevplane);
279 // create pairs and fill pair candidate arrays
280 for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
281 for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
282 FillPairArrays(itrackArr1, itrackArr2);
288 fTrackRotator->SetEvent(ev1);
293 //fill debug tree if a manager is attached
294 if (fDebugTree) FillDebugTree();
296 //process event mixing
298 fMixing->Fill(ev1,this);
299 // FillHistograms(0x0,kTRUE);
302 //in case there is a histogram manager, fill the QA histograms
303 if (fHistos && fSignalsMC) FillMCHistograms(ev1);
304 if (fHistos) FillHistograms(ev1);
308 if (!fDontClearArrays) ClearArrays();
309 AliDielectronVarManager::SetTPCEventPlane(0x0);
313 //________________________________________________________________
314 void AliDielectron::ProcessMC(AliVEvent *ev1)
317 // Process the MC data
320 AliDielectronMC *dieMC=AliDielectronMC::Instance();
322 if (fHistos) FillHistogramsMC(dieMC->GetMCEvent(), ev1);
324 if(!fSignalsMC) return;
325 //loop over all MC data and Fill the CF container if it exist
326 if (!fCfManagerPair && !fHistoArray) return;
327 if(fCfManagerPair) fCfManagerPair->SetPdgMother(fPdgMother);
329 Bool_t bFillCF = (fCfManagerPair ? fCfManagerPair->GetStepForMCtruth() : kFALSE);
330 Bool_t bFillHF = (fHistoArray ? fHistoArray->GetStepForMCGenerated() : kFALSE);
331 if(!bFillCF && !bFillHF) return;
333 // signals to be studied
334 Int_t nSignals = fSignalsMC->GetEntries();
336 // initialize 2D arrays of labels for particles from each MC signal
337 Int_t** labels1; // labels for particles satisfying branch 1
338 Int_t** labels2; // labels for particles satisfying branch 2
339 Int_t** labels12; // labels for particles satisfying both branches
340 labels1 = new Int_t*[nSignals];
341 labels2 = new Int_t*[nSignals];
342 labels12 = new Int_t*[nSignals];
343 Int_t* indexes1=new Int_t[nSignals];
344 Int_t* indexes2=new Int_t[nSignals];
345 Int_t* indexes12=new Int_t[nSignals];
346 for(Int_t isig=0;isig<nSignals;++isig) {
347 *(labels1+isig) = new Int_t[dieMC->GetNMCTracks()];
348 *(labels2+isig) = new Int_t[dieMC->GetNMCTracks()];
349 *(labels12+isig) = new Int_t[dieMC->GetNMCTracks()];
350 for(Int_t ip=0; ip<dieMC->GetNMCTracks();++ip) {
351 labels1[isig][ip] = -1;
352 labels2[isig][ip] = -1;
353 labels12[isig][ip] = -1;
360 Bool_t truth1=kFALSE;
361 Bool_t truth2=kFALSE;
362 // loop over the MC tracks
363 for(Int_t ipart=0; ipart<dieMC->GetNMCTracks(); ++ipart) {
364 for(Int_t isig=0; isig<nSignals; ++isig) { // loop over signals
365 // Proceed only if this signal is required in the pure MC step
366 // NOTE: Some signals can be satisfied by many particles and this leads to high
367 // computation times (e.g. secondary electrons from the GEANT transport). Be aware of this!!
368 if(!((AliDielectronSignalMC*)fSignalsMC->At(isig))->GetFillPureMCStep()) continue;
370 truth1 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 1);
371 truth2 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 2);
373 // particles satisfying both branches are treated separately to avoid double counting during pairing
374 if(truth1 && truth2) {
375 labels12[isig][indexes12[isig]] = ipart;
380 labels1[isig][indexes1[isig]] = ipart;
384 labels2[isig][indexes2[isig]] = ipart;
389 } // end loop over MC particles
391 // Do the pairing and fill the CF container with pure MC info
392 for(Int_t isig=0; isig<nSignals; ++isig) {
393 // mix the particles which satisfy only one of the signal branches
394 for(Int_t i1=0;i1<indexes1[isig];++i1) {
395 for(Int_t i2=0;i2<indexes2[isig];++i2) {
396 if(bFillCF) fCfManagerPair->FillMC(labels1[isig][i1], labels2[isig][i2], isig);
397 if(bFillHF) fHistoArray->Fill(labels1[isig][i1], labels2[isig][i2], isig);
400 // mix the particles which satisfy both branches
401 for(Int_t i1=0;i1<indexes12[isig];++i1) {
402 for(Int_t i2=0; i2<i1; ++i2) {
403 if(bFillCF) fCfManagerPair->FillMC(labels12[isig][i1], labels12[isig][i2], isig);
404 if(bFillHF) fHistoArray->Fill(labels12[isig][i1], labels12[isig][i2], isig);
407 } // end loop over signals
409 // release the memory
410 for(Int_t isig=0;isig<nSignals;++isig) {
411 delete [] *(labels1+isig);
412 delete [] *(labels2+isig);
413 delete [] *(labels12+isig);
423 //________________________________________________________________
424 void AliDielectron::FillHistogramsTracks(TObjArray **tracks)
427 // Fill Histogram information for tracks after prefilter
428 // ignore mixed events - for prefilter, only single tracks +/- are relevant
431 TString className,className2;
432 Double_t values[AliDielectronVarManager::kNMaxValues];
434 //Fill track information, separately for the track array candidates
435 for (Int_t i=0; i<2; ++i){
436 className.Form("Pre_%s",fgkTrackClassNames[i]);
437 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
438 Int_t ntracks=tracks[i]->GetEntriesFast();
439 for (Int_t itrack=0; itrack<ntracks; ++itrack){
440 AliDielectronVarManager::Fill(tracks[i]->UncheckedAt(itrack), values);
441 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
447 //________________________________________________________________
448 void AliDielectron::FillHistogramsMC(const AliMCEvent *ev, AliVEvent *ev1)
451 // Fill Histogram information for MCEvents
454 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
455 // Fill event information
456 AliDielectronVarManager::Fill(ev1, values); // ESD/AOD information
457 AliDielectronVarManager::Fill(ev, values); // MC truth info
458 if (fHistos->GetHistogramList()->FindObject("MCEvent"))
459 fHistos->FillClass("MCEvent", AliDielectronVarManager::kNMaxValues, values);
463 //________________________________________________________________
464 void AliDielectron::FillHistograms(const AliVEvent *ev, Bool_t pairInfoOnly)
467 // Fill Histogram information for tracks and pairs
470 TString className,className2;
471 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
472 //Fill event information
473 if (ev){ //TODO: Why not use GetData() ??? See below event plane stuff!!!
474 AliDielectronVarManager::Fill(ev, values); //data should already be stored in AliDielectronVarManager from SetEvent, does EV plane correction rely on this???
476 //set mixing bin to event data
477 Int_t bin=fMixing->FindBin(values);
478 values[AliDielectronVarManager::kMixingBin]=bin;
481 if (fHistos->GetHistogramList()->FindObject("Event"))
482 // fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, AliDielectronVarManager::GetData());
483 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, values); //check event plane stuff and replace with above...
486 //Fill track information, separately for the track array candidates
488 for (Int_t i=0; i<4; ++i){
489 className.Form("Track_%s",fgkTrackClassNames[i]);
490 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
491 Int_t ntracks=fTracks[i].GetEntriesFast();
492 for (Int_t itrack=0; itrack<ntracks; ++itrack){
493 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
494 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
499 //Fill Pair information, separately for all pair candidate arrays and the legs
500 TObjArray arrLegs(100);
501 for (Int_t i=0; i<10; ++i){
502 className.Form("Pair_%s",fgkPairClassNames[i]);
503 className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
504 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
505 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
506 if (!pairClass&&!legClass) continue;
507 Int_t ntracks=PairArray(i)->GetEntriesFast();
508 for (Int_t ipair=0; ipair<ntracks; ++ipair){
509 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
511 //fill pair information
513 AliDielectronVarManager::Fill(pair, values);
514 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
517 //fill leg information, don't fill the information twice
519 AliVParticle *d1=pair->GetFirstDaughter();
520 AliVParticle *d2=pair->GetSecondDaughter();
521 if (!arrLegs.FindObject(d1)){
522 AliDielectronVarManager::Fill(d1, values);
523 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
526 if (!arrLegs.FindObject(d2)){
527 AliDielectronVarManager::Fill(d2, values);
528 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
533 if (legClass) arrLegs.Clear();
537 //________________________________________________________________
538 void AliDielectron::FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter/*=kFALSE*/)
541 // Fill Histogram information for pairs and the track in the pair
542 // NOTE: in this funtion the leg information may be filled multiple
543 // times. This funtion is used in the track rotation pairing
544 // and those legs are not saved!
546 TString className,className2;
547 Double_t values[AliDielectronVarManager::kNMaxValues];
549 //Fill Pair information, separately for all pair candidate arrays and the legs
550 TObjArray arrLegs(100);
551 const Int_t type=pair->GetType();
553 className.Form("RejPair_%s",fgkPairClassNames[type]);
554 className2.Form("RejTrack_%s",fgkPairClassNames[type]);
556 className.Form("Pair_%s",fgkPairClassNames[type]);
557 className2.Form("Track_Legs_%s",fgkPairClassNames[type]);
560 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
561 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
563 //fill pair information
565 AliDielectronVarManager::Fill(pair, values);
566 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
570 AliVParticle *d1=pair->GetFirstDaughter();
571 AliDielectronVarManager::Fill(d1, values);
572 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
574 AliVParticle *d2=pair->GetSecondDaughter();
575 AliDielectronVarManager::Fill(d2, values);
576 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
580 //________________________________________________________________
581 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
584 // select tracks and fill track candidate arrays
585 // eventNr = 0: First event, use track arrays 0 and 1
586 // eventNr = 1: Second event, use track arrays 2 and 3
589 Int_t ntracks=ev->GetNumberOfTracks();
593 UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
594 for (Int_t itrack=0; itrack<ntracks; ++itrack){
596 AliVParticle *particle=ev->GetTrack(itrack);
599 if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
601 //fill selected particle into the corresponding track arrays
602 Short_t charge=particle->Charge();
603 if (charge>0) fTracks[eventNr*2].Add(particle);
604 else if (charge<0) fTracks[eventNr*2+1].Add(particle);
608 //________________________________________________________________
609 void AliDielectron::EventPlanePreFilter(Int_t arr1, Int_t arr2, TObjArray arrTracks1, TObjArray arrTracks2, const AliVEvent *ev, AliEventplane *cevplane)
612 // Prefilter tracks and tracks from pairs
613 // Needed for rejection in the Q-Vector of the event plane
614 // remove contribution of all tracks to the Q-vector that are in invariant mass window
616 AliEventplane *evplane = const_cast<AliVEvent *>(ev)->GetEventplane();
617 // AliEventplane *evplane = ev->GetEventplane();
620 // do not change these vectors qref
621 TVector2 * const qref = evplane->GetQVector();
624 TVector2 *qrsub1 = evplane->GetQsub1();
625 TVector2 *qrsub2 = evplane->GetQsub2();
628 TVector2 *qcorr = new TVector2(*qref);
629 TVector2 *qcsub1 = 0x0;
630 TVector2 *qcsub2 = 0x0;
631 // printf("qrsub1 %p %f \n",qrsub1,qrsub1->X());
635 Bool_t etagap = kFALSE;
636 for (Int_t iCut=0; iCut<fEventPlanePreFilter.GetCuts()->GetEntries();++iCut) {
637 TString cutName=fEventPlanePreFilter.GetCuts()->At(iCut)->GetName();
638 if(cutName.Contains("eta") || cutName.Contains("Eta")) etagap=kTRUE;
641 // subevent separation
642 if(fLikeSignSubEvents || etagap) {
643 qcsub1 = new TVector2(*qcorr);
644 qcsub2 = new TVector2(*qcorr);
646 Int_t ntracks=ev->GetNumberOfTracks();
649 for (Int_t itrack=0; itrack<ntracks; ++itrack){
650 AliVParticle *particle=ev->GetTrack(itrack);
651 AliVTrack *track= static_cast<AliVTrack*>(particle);
652 if (!track) continue;
654 Double_t cQX = evplane->GetQContributionX(track);
655 Double_t cQY = evplane->GetQContributionY(track);
657 // by charge sub1+ sub2-
658 if(fLikeSignSubEvents) {
659 Short_t charge=track->Charge();
660 if (charge<0) qcsub1->Set(qcsub1->X()-cQX, qcsub1->Y()-cQY);
661 if (charge>0) qcsub2->Set(qcsub2->X()-cQX, qcsub2->Y()-cQY);
663 // by eta sub1+ sub2-
665 Double_t eta=track->Eta();
666 if (eta<0.0) qcsub1->Set(qcsub1->X()-cQX, qcsub1->Y()-cQY);
667 if (eta>0.0) qcsub2->Set(qcsub2->X()-cQX, qcsub2->Y()-cQY);
673 qcsub1 = new TVector2(*qrsub1);
674 qcsub2 = new TVector2(*qrsub2);
677 // apply cuts, e.g. etagap
678 if(fEventPlanePreFilter.GetCuts()->GetEntries()) {
679 UInt_t selectedMask=(1<<fEventPlanePreFilter.GetCuts()->GetEntries())-1;
680 Int_t ntracks=ev->GetNumberOfTracks();
681 for (Int_t itrack=0; itrack<ntracks; ++itrack){
682 AliVParticle *particle=ev->GetTrack(itrack);
683 AliVTrack *track= static_cast<AliVTrack*>(particle);
684 if (!track) continue;
687 UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
689 if (cutMask==selectedMask) continue;
694 cQX = evplane->GetQContributionX(track);
695 cQY = evplane->GetQContributionY(track);
697 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
698 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
699 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
700 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
703 qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
704 qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
705 qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
709 // POI (particle of interest) rejection
710 Int_t pairIndex=GetPairIndex(arr1,arr2);
712 Int_t ntrack1=arrTracks1.GetEntriesFast();
713 Int_t ntrack2=arrTracks2.GetEntriesFast();
714 AliDielectronPair candidate;
715 candidate.SetKFUsage(fUseKF);
717 UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
718 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
720 if (arr1==arr2) end=itrack1;
721 Bool_t accepted=kFALSE;
722 for (Int_t itrack2=0; itrack2<end; ++itrack2){
723 TObject *track1=arrTracks1.UncheckedAt(itrack1);
724 TObject *track2=arrTracks2.UncheckedAt(itrack2);
725 if (!track1 || !track2) continue;
727 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
728 static_cast<AliVTrack*>(track2), fPdgLeg2);
730 candidate.SetType(pairIndex);
731 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
734 UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
736 if (cutMask==selectedMask) continue;
739 //remove the tracks from the Track arrays
740 arrTracks2.AddAt(0x0,itrack2);
742 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
744 //compress the track arrays
745 arrTracks1.Compress();
746 arrTracks2.Compress();
749 //Modify the components: subtract the tracks
750 ntrack1=arrTracks1.GetEntriesFast();
751 ntrack2=arrTracks2.GetEntriesFast();
753 // remove leg1 contribution
754 for (Int_t itrack=0; itrack<ntrack1; ++itrack){
755 AliVTrack *track= static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack));
756 if (!track) continue;
758 Double_t cQX = evplane->GetQContributionX(track);
759 Double_t cQY = evplane->GetQContributionY(track);
760 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
761 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
762 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
763 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
766 qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
767 qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
768 qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
770 // remove leg2 contribution
771 for (Int_t itrack=0; itrack<ntrack2; ++itrack){
772 AliVTrack *track= static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack));
773 if (!track) continue;
775 Double_t cQX = evplane->GetQContributionX(track);
776 Double_t cQY = evplane->GetQContributionY(track);
777 Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
778 Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
779 Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
780 Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
783 qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
784 qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
785 qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
788 // printf("qrsub1 %p %f \t qcsub1 %p %f \n",qrsub1,qrsub1->X(),qcsub1,qcsub1->X());
789 // set AliEventplane with corrected values
790 cevplane->SetQVector(qcorr);
791 cevplane->SetQsub(qcsub1, qcsub2);
792 AliDielectronVarManager::SetTPCEventPlane(cevplane);
795 //________________________________________________________________
796 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
799 // Prefilter tracks from pairs
800 // Needed for datlitz rejections
801 // remove all tracks from the Single track arrays that pass the cuts in this filter
804 Int_t ntrack1=arrTracks1.GetEntriesFast();
805 Int_t ntrack2=arrTracks2.GetEntriesFast();
806 AliDielectronPair candidate;
807 candidate.SetKFUsage(fUseKF);
808 // flag arrays for track removal
809 Bool_t *bTracks1 = new Bool_t[ntrack1];
810 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1) bTracks1[itrack1]=kFALSE;
811 Bool_t *bTracks2 = new Bool_t[ntrack2];
812 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2) bTracks2[itrack2]=kFALSE;
814 UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
815 UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
817 Int_t nRejPasses = 1; //for fPreFilterUnlikeOnly and no set flag
818 if (fPreFilterAllSigns) nRejPasses = 3;
820 for (Int_t iRP=0; iRP < nRejPasses; ++iRP) {
821 Int_t arr1RP=arr1, arr2RP=arr2;
822 TObjArray *arrTracks1RP=&arrTracks1;
823 TObjArray *arrTracks2RP=&arrTracks2;
824 Bool_t *bTracks1RP = bTracks1;
825 Bool_t *bTracks2RP = bTracks2;
827 case 1: arr1RP=arr1;arr2RP=arr1;
828 arrTracks1RP=&arrTracks1;
829 arrTracks2RP=&arrTracks1;
830 bTracks1RP = bTracks1;
831 bTracks2RP = bTracks1;
833 case 2: arr1RP=arr2;arr2RP=arr2;
834 arrTracks1RP=&arrTracks2;
835 arrTracks2RP=&arrTracks2;
836 bTracks1RP = bTracks2;
837 bTracks2RP = bTracks2;
839 default: ;//nothing to do
841 Int_t ntrack1RP=(*arrTracks1RP).GetEntriesFast();
842 Int_t ntrack2RP=(*arrTracks2RP).GetEntriesFast();
844 Int_t pairIndex=GetPairIndex(arr1RP,arr2RP);
846 for (Int_t itrack1=0; itrack1<ntrack1RP; ++itrack1){
848 if (arr1RP==arr2RP) end=itrack1;
849 for (Int_t itrack2=0; itrack2<end; ++itrack2){
850 TObject *track1=(*arrTracks1RP).UncheckedAt(itrack1);
851 TObject *track2=(*arrTracks2RP).UncheckedAt(itrack2);
852 if (!track1 || !track2) continue;
854 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
855 static_cast<AliVTrack*>(track2), fPdgLeg2);
857 candidate.SetType(pairIndex);
858 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
859 //relate to the production vertex
860 // if (AliDielectronVarManager::GetKFVertex()) candidate.SetProductionVertex(*AliDielectronVarManager::GetKFVertex());
863 UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
866 if (cutMask!=selectedMask) continue;
867 if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
868 if (fHistos) FillHistogramsPair(&candidate,kTRUE);
869 //set flags for track removal
870 bTracks1RP[itrack1]=kTRUE;
871 bTracks2RP[itrack2]=kTRUE;
876 //remove the tracks from the Track arrays
877 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
878 if(bTracks1[itrack1]) arrTracks1.AddAt(0x0, itrack1);
880 for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2){
881 if(bTracks2[itrack2]) arrTracks2.AddAt(0x0, itrack2);
888 //compress the track arrays
889 arrTracks1.Compress();
890 arrTracks2.Compress();
892 //apply leg cuts after the pre filter
893 if ( fPairPreFilterLegs.GetCuts()->GetEntries()>0 ) {
894 selectedMask=(1<<fPairPreFilterLegs.GetCuts()->GetEntries())-1;
895 //loop over tracks from array 1
896 for (Int_t itrack=0; itrack<arrTracks1.GetEntriesFast();++itrack){
898 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
901 if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);;
903 arrTracks1.Compress();
905 //in case of like sign don't loop over second array
907 arrTracks2=arrTracks1;
910 //loop over tracks from array 2
911 for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
913 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
915 if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
917 arrTracks2.Compress();
921 //For unlike-sign monitor track-cuts:
922 if (arr1!=arr2&&fHistos) {
923 TObjArray *unlikesignArray[2] = {&arrTracks1,&arrTracks2};
924 FillHistogramsTracks(unlikesignArray);
928 //________________________________________________________________
929 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2)
932 // select pairs and fill pair candidate arrays
935 TObjArray arrTracks1=fTracks[arr1];
936 TObjArray arrTracks2=fTracks[arr2];
938 //process pre filter if set
939 if ((!fPreFilterAllSigns) && (!fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
941 Int_t pairIndex=GetPairIndex(arr1,arr2);
943 Int_t ntrack1=arrTracks1.GetEntriesFast();
944 Int_t ntrack2=arrTracks2.GetEntriesFast();
946 AliDielectronPair *candidate=new AliDielectronPair;
947 candidate->SetKFUsage(fUseKF);
949 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
951 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
953 if (arr1==arr2) end=itrack1;
954 for (Int_t itrack2=0; itrack2<end; ++itrack2){
956 candidate->SetTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
957 static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
958 candidate->SetType(pairIndex);
959 Int_t label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother);
960 candidate->SetLabel(label);
961 if (label>-1) candidate->SetPdgCode(fPdgMother);
963 // check for gamma kf particle
964 label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,22);
966 candidate->SetGammaTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
967 static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
968 // should we set the pdgmothercode and the label
972 UInt_t cutMask=fPairFilter.IsSelected(candidate);
974 //CF manager for the pair
975 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
976 //histogram array for the pair
977 if (fHistoArray) fHistoArray->Fill(pairIndex,candidate);
980 if (cutMask!=selectedMask) continue;
982 //add the candidate to the candidate array
983 PairArray(pairIndex)->Add(candidate);
984 //get a new candidate
985 candidate=new AliDielectronPair;
986 candidate->SetKFUsage(fUseKF);
989 //delete the surplus candidate
993 //________________________________________________________________
994 void AliDielectron::FillPairArrayTR()
997 // select pairs and fill pair candidate arrays
999 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1001 while ( fTrackRotator->NextCombination() ){
1002 AliDielectronPair candidate;
1003 candidate.SetKFUsage(fUseKF);
1004 candidate.SetTracks(&fTrackRotator->GetKFTrackP(), &fTrackRotator->GetKFTrackN(),
1005 fTrackRotator->GetVTrackP(),fTrackRotator->GetVTrackN());
1006 candidate.SetType(kEv1PMRot);
1009 UInt_t cutMask=fPairFilter.IsSelected(&candidate);
1011 //CF manager for the pair
1012 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,&candidate);
1013 //histogram array for the pair
1014 if (fHistoArray) fHistoArray->Fill((Int_t)kEv1PMRot,&candidate);
1017 if (cutMask==selectedMask) {
1018 if(fHistos) FillHistogramsPair(&candidate);
1019 if(fStoreRotatedPairs) PairArray(kEv1PMRot)->Add(new AliDielectronPair(candidate));
1024 //________________________________________________________________
1025 void AliDielectron::FillDebugTree()
1028 // Fill Histogram information for tracks and pairs
1032 for (Int_t i=0; i<10; ++i){
1033 Int_t ntracks=PairArray(i)->GetEntriesFast();
1034 for (Int_t ipair=0; ipair<ntracks; ++ipair){
1035 fDebugTree->Fill(static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair)));
1040 //________________________________________________________________
1041 void AliDielectron::SaveDebugTree()
1044 // delete the debug tree, this will also write the tree
1046 if (fDebugTree) fDebugTree->DeleteStreamer();
1050 //__________________________________________________________________
1051 void AliDielectron::AddSignalMC(AliDielectronSignalMC* signal) {
1053 // Add an MC signal to the signals list
1056 fSignalsMC = new TObjArray();
1057 fSignalsMC->SetOwner();
1059 fSignalsMC->Add(signal);
1061 //________________________________________________________________
1062 void AliDielectron::FillMCHistograms(const AliVEvent *ev) {
1064 // fill QA MC histograms for pairs and legs of all added mc signals
1067 if (!fSignalsMC) return;
1068 TString className,className2;
1069 Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
1070 AliDielectronVarManager::Fill(ev, values); // get event informations
1071 //loop over all added mc signals
1072 for(Int_t isig=0; isig<fSignalsMC->GetEntries(); isig++) {
1074 className.Form("Pair_%s",fSignalsMC->At(isig)->GetName());
1075 className2.Form("Track_Legs_%s",fSignalsMC->At(isig)->GetName());
1076 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
1077 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
1078 if(!pairClass && !legClass) return;
1080 Int_t ntracks=PairArray(AliDielectron::kEv1PM)->GetEntriesFast(); // only SE +-
1081 for (Int_t ipair=0; ipair<ntracks; ++ipair){
1082 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(AliDielectron::kEv1PM)->UncheckedAt(ipair));
1084 Bool_t isMCtruth = AliDielectronMC::Instance()->IsMCTruth(pair, (AliDielectronSignalMC*)fSignalsMC->At(isig));
1086 //fill pair information
1088 AliDielectronVarManager::Fill(pair, values);
1089 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1091 //fill leg information, both + and - in the same histo
1093 AliDielectronVarManager::Fill(pair->GetFirstDaughter(),values);
1094 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
1095 AliDielectronVarManager::Fill(pair->GetSecondDaughter(),values);
1096 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);