]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliDielectron.cxx
9b7ac74a100fc442d674919cdb4e76e064751483
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectron.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
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 **************************************************************************/
15
16 ///////////////////////////////////////////////////////////////////////////
17 //                Dielectron Analysis Main class                         //
18 //                                                                       //
19 /*
20 Framework to perform event selectoin, single track selection and track pair
21 selection.
22
23 Convention for the signs of the pair in fPairCandidates:
24 The names are available via the function PairClassName(Int_t i)
25
26 0: ev1+ ev1+  (same event like sign +)
27 1: ev1+ ev1-  (same event unlike sign)
28 2: ev1- ev1-  (same event like sign -)
29
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 -)
34
35 5: ev2+ ev2+  (same event like sign +)
36 8: ev2+ ev2-  (same event unlike sign)
37 9: ev2- ev2-  (same event like sign -)
38
39 10: ev1+ ev1- (same event track rotation)
40
41 */
42 //                                                                       //
43 ///////////////////////////////////////////////////////////////////////////
44
45 #include <TString.h>
46 #include <TList.h>
47 #include <TMath.h>
48 #include <TObject.h>
49
50 #include <AliKFParticle.h>
51
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"
65
66 #include "AliDielectron.h"
67
68 ClassImp(AliDielectron)
69
70 const char* AliDielectron::fgkTrackClassNames[4] = {
71   "ev1+",
72   "ev1-",
73   "ev2+",
74   "ev2-"
75 };
76
77 const char* AliDielectron::fgkPairClassNames[11] = {
78   "ev1+_ev1+",
79   "ev1+_ev1-",
80   "ev1-_ev1-",
81   "ev1+_ev2+",
82   "ev1-_ev2+",
83   "ev2+_ev2+",
84   "ev1+_ev2-",
85   "ev1-_ev2-",
86   "ev2+_ev2-",
87   "ev2-_ev2-",
88   "ev1+_ev1-_TR"
89 };
90
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"),
101   fPdgMother(443),
102   fPdgLeg1(11),
103   fPdgLeg2(11),
104   fSignalsMC(0x0),
105   fNoPairing(kFALSE),
106   fUseKF(kTRUE),
107   fHistoArray(0x0),
108   fHistos(0x0),
109   fPairCandidates(new TObjArray(11)),
110   fCfManagerPair(0x0),
111   fTrackRotator(0x0),
112   fDebugTree(0x0),
113   fMixing(0x0),
114   fPreFilterEventPlane(kFALSE),
115   fLikeSignSubEvents(kFALSE),
116   fPreFilterUnlikeOnly(kFALSE),
117   fPreFilterAllSigns(kFALSE),
118   fHasMC(kFALSE),
119   fStoreRotatedPairs(kFALSE),
120   fDontClearArrays(kFALSE),
121   fEstimatorFilename(""),
122   fTRDpidCorrectionFilename(""),
123   fVZEROCalibrationFilename(""),
124   fVZERORecenteringFilename("")
125 {
126   //
127   // Default constructor
128   //
129
130 }
131
132 //________________________________________________________________
133 AliDielectron::AliDielectron(const char* name, const char* title) :
134   TNamed(name,title),
135   fEventFilter("EventFilter"),
136   fTrackFilter("TrackFilter"),
137   fPairPreFilter("PairPreFilter"),
138   fPairPreFilterLegs("PairPreFilterLegs"),
139   fPairFilter("PairFilter"),
140   fEventPlanePreFilter("EventPlanePreFilter"),
141   fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
142   fPdgMother(443),
143   fPdgLeg1(11),
144   fPdgLeg2(11),
145   fSignalsMC(0x0),
146   fNoPairing(kFALSE),
147   fUseKF(kTRUE),
148   fHistoArray(0x0),
149   fHistos(0x0),
150   fPairCandidates(new TObjArray(11)),
151   fCfManagerPair(0x0),
152   fTrackRotator(0x0),
153   fDebugTree(0x0),
154   fMixing(0x0),
155   fPreFilterEventPlane(kFALSE),
156   fLikeSignSubEvents(kFALSE),
157   fPreFilterUnlikeOnly(kFALSE),
158   fPreFilterAllSigns(kFALSE),
159   fHasMC(kFALSE),
160   fStoreRotatedPairs(kFALSE),
161   fDontClearArrays(kFALSE),
162   fEstimatorFilename(""),
163   fTRDpidCorrectionFilename(""),
164   fVZEROCalibrationFilename(""),
165   fVZERORecenteringFilename("")
166 {
167   //
168   // Named constructor
169   //
170   
171 }
172
173 //________________________________________________________________
174 AliDielectron::~AliDielectron()
175 {
176   //
177   // Default destructor
178   //
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;
186 }
187
188 //________________________________________________________________
189 void AliDielectron::Init()
190 {
191   //
192   // Initialise objects
193   //
194
195   if(GetHasMC()) AliDielectronMC::Instance()->SetHasMC(GetHasMC());
196    
197   InitPairCandidateArrays();
198    
199   if (fCfManagerPair) {
200     fCfManagerPair->SetSignalsMC(fSignalsMC);
201     fCfManagerPair->InitialiseContainer(fPairFilter);
202   }
203   if (fTrackRotator)  {
204     fTrackRotator->SetTrackArrays(&fTracks[0],&fTracks[1]);
205     fTrackRotator->SetPdgLegs(fPdgLeg1,fPdgLeg2);
206   }
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());
212   
213   if (fMixing) fMixing->Init(this);
214   if (fHistoArray) {
215     fHistoArray->SetSignalsMC(fSignalsMC);
216     fHistoArray->Init();
217   }
218
219
220 //________________________________________________________________
221 void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
222 {
223   //
224   // Process the events
225   //
226
227   //at least first event is needed!
228   if (!ev1){
229     AliError("At least first event must be set!");
230     return;
231   }
232   AliDielectronVarManager::SetEvent(ev1);
233   if (fMixing){
234     //set mixing bin to event data
235     Int_t bin=fMixing->FindBin(AliDielectronVarManager::GetData());
236     AliDielectronVarManager::SetValue(AliDielectronVarManager::kMixingBin,bin);
237   }
238
239   //in case we have MC load the MC event and process the MC particles
240   if (AliDielectronMC::Instance()->ConnectMCEvent()){
241     ProcessMC(ev1);
242   }
243   
244   //if candidate array doesn't exist, create it
245   if (!fPairCandidates->UncheckedAt(0)) {
246     InitPairCandidateArrays();
247   } else {
248     ClearArrays();
249   }
250
251   //mask used to require that all cuts are fulfilled
252   UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
253
254   //apply event cuts
255     if ((ev1&&fEventFilter.IsSelected(ev1)!=selectedMask) ||
256         (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
257   
258 //   AliDielectronVarManager::SetEvent(ev1); // why a second time???
259
260   //fill track arrays for the first event
261   if (ev1){
262     FillTrackArrays(ev1);
263     if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
264   }
265
266
267   //fill track arrays for the second event
268   if (ev2) {
269     FillTrackArrays(ev2,1);
270     if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
271   }
272
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);
277
278   if (!fNoPairing){
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);
283       }
284     }
285
286     //track rotation
287     if (fTrackRotator) {
288       fTrackRotator->SetEvent(ev1);
289       FillPairArrayTR();
290     }
291   }
292
293   //fill debug tree if a manager is attached
294   if (fDebugTree) FillDebugTree();
295
296   //process event mixing
297   if (fMixing) {
298     fMixing->Fill(ev1,this);
299 //     FillHistograms(0x0,kTRUE);
300   }
301
302   //in case there is a histogram manager, fill the QA histograms
303   if (fHistos && fSignalsMC) FillMCHistograms(ev1);
304   if (fHistos) FillHistograms(ev1);
305
306
307   // clear arrays
308   if (!fDontClearArrays) ClearArrays();
309   AliDielectronVarManager::SetTPCEventPlane(0x0);
310   delete cevplane;
311 }
312
313 //________________________________________________________________
314 void AliDielectron::ProcessMC(AliVEvent *ev1)
315 {
316   //
317   // Process the MC data
318   //
319
320   AliDielectronMC *dieMC=AliDielectronMC::Instance();
321
322   if (fHistos) FillHistogramsMC(dieMC->GetMCEvent(), ev1);
323
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);
328
329   Bool_t bFillCF = (fCfManagerPair ? fCfManagerPair->GetStepForMCtruth()  : kFALSE);
330   Bool_t bFillHF = (fHistoArray    ? fHistoArray->GetStepForMCGenerated() : kFALSE);
331   if(!bFillCF && !bFillHF) return;
332
333   // signals to be studied
334   Int_t nSignals = fSignalsMC->GetEntries();
335
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;
354     }
355     indexes1[isig]=0;
356     indexes2[isig]=0;
357     indexes12[isig]=0;
358   }
359
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;
369
370       truth1 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 1);
371       truth2 = dieMC->IsMCTruth(ipart, (AliDielectronSignalMC*)fSignalsMC->At(isig), 2);
372
373       // particles satisfying both branches are treated separately to avoid double counting during pairing
374       if(truth1 && truth2) {
375         labels12[isig][indexes12[isig]] = ipart;
376         ++indexes12[isig];
377       }
378       else {
379         if(truth1) {
380           labels1[isig][indexes1[isig]] = ipart;
381           ++indexes1[isig];
382         }
383         if(truth2) {
384           labels2[isig][indexes2[isig]] = ipart;
385           ++indexes2[isig];
386         }
387       }
388     }
389   }  // end loop over MC particles
390
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);
398       }
399     }
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);
405       }
406     }
407   }    // end loop over signals
408
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);
414   }
415   delete [] labels1;
416   delete [] labels2;
417   delete [] labels12;
418   delete [] indexes1;
419   delete [] indexes2;
420   delete [] indexes12;
421 }
422
423 //________________________________________________________________
424 void AliDielectron::FillHistogramsTracks(TObjArray **tracks)
425 {
426   //
427   // Fill Histogram information for tracks after prefilter
428   // ignore mixed events - for prefilter, only single tracks +/- are relevant 
429   //
430   
431   TString  className,className2;
432   Double_t values[AliDielectronVarManager::kNMaxValues];
433   
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);
442     }
443   }
444 }
445
446
447 //________________________________________________________________
448 void AliDielectron::FillHistogramsMC(const AliMCEvent *ev, AliVEvent *ev1)
449 {
450   //
451   // Fill Histogram information for MCEvents
452   //
453
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);
460 }
461
462
463 //________________________________________________________________
464 void AliDielectron::FillHistograms(const AliVEvent *ev, Bool_t pairInfoOnly)
465 {
466   //
467   // Fill Histogram information for tracks and pairs
468   //
469   
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???
475       if (fMixing){
476     //set mixing bin to event data
477     Int_t bin=fMixing->FindBin(values);
478     values[AliDielectronVarManager::kMixingBin]=bin;
479   }
480
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...
484   }
485   
486   //Fill track information, separately for the track array candidates
487   if (!pairInfoOnly){
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);
495       }
496     }
497   }
498
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));
510       
511       //fill pair information
512       if (pairClass){
513         AliDielectronVarManager::Fill(pair, values);
514         fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
515       }
516
517       //fill leg information, don't fill the information twice
518       if (legClass){
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);
524           arrLegs.Add(d1);
525         }
526         if (!arrLegs.FindObject(d2)){
527           AliDielectronVarManager::Fill(d2, values);
528           fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
529           arrLegs.Add(d2);
530         }
531       }
532     }
533     if (legClass) arrLegs.Clear();
534   }
535   
536 }
537 //________________________________________________________________
538 void AliDielectron::FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter/*=kFALSE*/)
539 {
540   //
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!
545   //
546   TString  className,className2;
547   Double_t values[AliDielectronVarManager::kNMaxValues];
548   
549   //Fill Pair information, separately for all pair candidate arrays and the legs
550   TObjArray arrLegs(100);
551   const Int_t type=pair->GetType();
552   if (fromPreFilter) {
553     className.Form("RejPair_%s",fgkPairClassNames[type]);
554     className2.Form("RejTrack_%s",fgkPairClassNames[type]);
555   } else {
556     className.Form("Pair_%s",fgkPairClassNames[type]);
557     className2.Form("Track_Legs_%s",fgkPairClassNames[type]);
558   }
559   
560   Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
561   Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
562   
563   //fill pair information
564   if (pairClass){
565     AliDielectronVarManager::Fill(pair, values);
566     fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
567   }
568
569   if (legClass){
570     AliVParticle *d1=pair->GetFirstDaughter();
571     AliDielectronVarManager::Fill(d1, values);
572     fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
573     
574     AliVParticle *d2=pair->GetSecondDaughter();
575     AliDielectronVarManager::Fill(d2, values);
576     fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
577   }
578 }
579
580 //________________________________________________________________
581 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
582 {
583   //
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
587   //
588   
589   Int_t ntracks=ev->GetNumberOfTracks();
590
591
592   fTrackFilter.Init();
593   UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
594   for (Int_t itrack=0; itrack<ntracks; ++itrack){
595     //get particle
596     AliVParticle *particle=ev->GetTrack(itrack);
597
598     //apply track cuts
599     if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
600
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);
605   }
606 }
607
608 //________________________________________________________________
609 void AliDielectron::EventPlanePreFilter(Int_t arr1, Int_t arr2, TObjArray arrTracks1, TObjArray arrTracks2, const AliVEvent *ev, AliEventplane *cevplane)
610 {
611   //
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 
615   //
616   AliEventplane *evplane = const_cast<AliVEvent *>(ev)->GetEventplane();
617 //   AliEventplane *evplane = ev->GetEventplane();
618   if(!evplane) return;
619   
620   // do not change these vectors qref
621   TVector2 * const qref  = evplane->GetQVector();
622   if(!qref) return;
623   // random subevents
624   TVector2 *qrsub1 = evplane->GetQsub1();
625   TVector2 *qrsub2 = evplane->GetQsub2();
626
627   // copy references
628   TVector2 *qcorr  = new TVector2(*qref);
629   TVector2 *qcsub1 = 0x0;
630   TVector2 *qcsub2 = 0x0;
631   //  printf("qrsub1 %p %f \n",qrsub1,qrsub1->X());
632
633
634   // eta gap ?
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;
639   }
640
641   // subevent separation
642   if(fLikeSignSubEvents || etagap) {
643     qcsub1 = new TVector2(*qcorr);
644     qcsub2 = new TVector2(*qcorr);
645
646     Int_t ntracks=ev->GetNumberOfTracks();
647     
648     // track removals
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;
653
654       Double_t cQX     = evplane->GetQContributionX(track);
655       Double_t cQY     = evplane->GetQContributionY(track);
656       
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);
662       }
663       // by eta sub1+ sub2-
664       if(etagap) {
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);
668       }
669     }
670   }
671   else {
672     // by a random
673     qcsub1 = new TVector2(*qrsub1);
674     qcsub2 = new TVector2(*qrsub2);
675   }
676   
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;
685       
686       //event plane cuts
687       UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
688       //apply cut
689       if (cutMask==selectedMask) continue;
690
691       Double_t cQX     = 0.0;
692       Double_t cQY     = 0.0;
693       if(!etagap) {
694         cQX = evplane->GetQContributionX(track);
695         cQY = evplane->GetQContributionY(track);
696       }
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);      
701
702       // update Q vectors
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);
706     }
707   }
708
709   // POI (particle of interest) rejection
710   Int_t pairIndex=GetPairIndex(arr1,arr2);
711   
712   Int_t ntrack1=arrTracks1.GetEntriesFast();
713   Int_t ntrack2=arrTracks2.GetEntriesFast();
714   AliDielectronPair candidate;
715   candidate.SetKFUsage(fUseKF);
716   
717   UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
718   for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
719     Int_t end=ntrack2;
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;
726       //create the pair
727       candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
728                           static_cast<AliVTrack*>(track2), fPdgLeg2);
729       
730       candidate.SetType(pairIndex);
731       candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
732       
733       //event plane cuts
734       UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
735       //apply cut
736       if (cutMask==selectedMask) continue;
737
738       accepted=kTRUE;
739       //remove the tracks from the Track arrays
740       arrTracks2.AddAt(0x0,itrack2);
741     }
742       if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
743   }
744   //compress the track arrays
745   arrTracks1.Compress();
746   arrTracks2.Compress();
747   
748   
749   //Modify the components: subtract the tracks
750   ntrack1=arrTracks1.GetEntriesFast();
751   ntrack2=arrTracks2.GetEntriesFast();
752   
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;
757     
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);
764     
765     // update Q vectors
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);
769   }
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;
774     
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);
781     
782     // update Q vectors
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);
786   }
787
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);
793 }
794
795 //________________________________________________________________
796 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
797 {
798   //
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
802   //
803
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;
813
814   UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
815   UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
816
817   Int_t nRejPasses = 1; //for fPreFilterUnlikeOnly and no set flag 
818   if (fPreFilterAllSigns) nRejPasses = 3;
819
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;
826         switch (iRP) {
827                 case 1: arr1RP=arr1;arr2RP=arr1;
828                                 arrTracks1RP=&arrTracks1;
829                                 arrTracks2RP=&arrTracks1;
830                                 bTracks1RP = bTracks1;
831                                 bTracks2RP = bTracks1;
832                                 break;
833                 case 2: arr1RP=arr2;arr2RP=arr2;
834                                 arrTracks1RP=&arrTracks2;
835                                 arrTracks2RP=&arrTracks2;
836                                 bTracks1RP = bTracks2;
837                                 bTracks2RP = bTracks2;
838                                 break;
839                 default: ;//nothing to do
840         }
841         Int_t ntrack1RP=(*arrTracks1RP).GetEntriesFast();
842         Int_t ntrack2RP=(*arrTracks2RP).GetEntriesFast();
843
844         Int_t pairIndex=GetPairIndex(arr1RP,arr2RP);
845
846         for (Int_t itrack1=0; itrack1<ntrack1RP; ++itrack1){
847           Int_t end=ntrack2RP;
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;
853                 //create the pair
854                 candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
855                         static_cast<AliVTrack*>(track2), fPdgLeg2);
856
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());
861
862                 //pair cuts
863                 UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
864
865                 //apply cut
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;
872           }
873         }
874   }
875
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);
879   }
880   for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2){
881     if(bTracks2[itrack2]) arrTracks2.AddAt(0x0, itrack2);
882   }
883
884   // clean up
885   delete [] bTracks1;
886   delete [] bTracks2;
887
888   //compress the track arrays
889   arrTracks1.Compress();
890   arrTracks2.Compress();
891   
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){
897       //test cuts
898       UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
899       
900       //apply cut
901       if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);;
902     }
903     arrTracks1.Compress();
904     
905     //in case of like sign don't loop over second array
906     if (arr1==arr2) {
907       arrTracks2=arrTracks1;
908     } else {
909       
910       //loop over tracks from array 2
911       for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
912       //test cuts
913         UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
914       //apply cut
915         if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
916       }
917       arrTracks2.Compress();
918       
919     }
920   }
921   //For unlike-sign monitor track-cuts:
922   if (arr1!=arr2&&fHistos) {
923     TObjArray *unlikesignArray[2] = {&arrTracks1,&arrTracks2};
924     FillHistogramsTracks(unlikesignArray);
925   }
926 }
927
928 //________________________________________________________________
929 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2)
930 {
931   //
932   // select pairs and fill pair candidate arrays
933   //
934
935   TObjArray arrTracks1=fTracks[arr1];
936   TObjArray arrTracks2=fTracks[arr2];
937
938   //process pre filter if set
939   if ((!fPreFilterAllSigns) && (!fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 ))  PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
940   
941   Int_t pairIndex=GetPairIndex(arr1,arr2);
942
943   Int_t ntrack1=arrTracks1.GetEntriesFast();
944   Int_t ntrack2=arrTracks2.GetEntriesFast();
945
946   AliDielectronPair *candidate=new AliDielectronPair;
947   candidate->SetKFUsage(fUseKF);
948
949   UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
950   
951   for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
952     Int_t end=ntrack2;
953     if (arr1==arr2) end=itrack1;
954     for (Int_t itrack2=0; itrack2<end; ++itrack2){
955       //create the pair
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);
962
963       // check for gamma kf particle
964       label=AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,22);
965       if (label>-1) {
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
969       }
970
971       //pair cuts
972       UInt_t cutMask=fPairFilter.IsSelected(candidate);
973       
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);
978
979       //apply cut
980       if (cutMask!=selectedMask) continue;
981
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);
987     }
988   }
989   //delete the surplus candidate
990   delete candidate;
991 }
992
993 //________________________________________________________________
994 void AliDielectron::FillPairArrayTR()
995 {
996   //
997   // select pairs and fill pair candidate arrays
998   //
999   UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
1000   
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);
1007     
1008     //pair cuts
1009     UInt_t cutMask=fPairFilter.IsSelected(&candidate);
1010     
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);
1015     
1016     //apply cut
1017     if (cutMask==selectedMask) {
1018      if(fHistos) FillHistogramsPair(&candidate);
1019      if(fStoreRotatedPairs) PairArray(kEv1PMRot)->Add(new AliDielectronPair(candidate));
1020     } 
1021   }
1022 }
1023
1024 //________________________________________________________________
1025 void AliDielectron::FillDebugTree()
1026 {
1027   //
1028   // Fill Histogram information for tracks and pairs
1029   //
1030   
1031   //Fill Debug tree
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)));
1036     }
1037   }
1038 }
1039
1040 //________________________________________________________________
1041 void AliDielectron::SaveDebugTree()
1042 {
1043   //
1044   // delete the debug tree, this will also write the tree
1045   //
1046   if (fDebugTree) fDebugTree->DeleteStreamer();
1047 }
1048
1049
1050 //__________________________________________________________________
1051 void AliDielectron::AddSignalMC(AliDielectronSignalMC* signal) {
1052   //
1053   //  Add an MC signal to the signals list
1054   //
1055   if(!fSignalsMC) {
1056     fSignalsMC = new TObjArray();
1057     fSignalsMC->SetOwner();
1058   }
1059   fSignalsMC->Add(signal);
1060 }
1061 //________________________________________________________________
1062 void AliDielectron::FillMCHistograms(const AliVEvent *ev) {
1063   //
1064   // fill QA MC histograms for pairs and legs of all added mc signals
1065   //
1066
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++) {
1073
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;
1079
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));
1083
1084       Bool_t isMCtruth = AliDielectronMC::Instance()->IsMCTruth(pair, (AliDielectronSignalMC*)fSignalsMC->At(isig));
1085       if(isMCtruth) {
1086         //fill pair information
1087         if (pairClass){
1088           AliDielectronVarManager::Fill(pair, values);
1089           fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
1090         }
1091         //fill leg information, both + and - in the same histo
1092         if (legClass){
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);
1097         }
1098       } //is signal
1099     } //loop: pairs
1100   } //loop: MCsignals
1101
1102 }