]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/EMCAL/AliAnalysisTaskEmcal.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWG / EMCAL / AliAnalysisTaskEmcal.cxx
1 // $Id$
2 //
3 // Emcal base analysis task.
4 //
5 // Author: S.Aiola, M. Verweij
6 #include "AliAnalysisTaskEmcal.h"
7
8 #include <TClonesArray.h>
9 #include <TList.h>
10 #include <TObject.h>
11 #include <TH1F.h>
12 #include <TProfile.h>
13 #include <TSystem.h>
14 #include <TFile.h>
15 #include <TChain.h>
16 #include <TKey.h>
17
18 #include "AliAODEvent.h"
19 #include "AliAnalysisManager.h"
20 #include "AliCentrality.h"
21 #include "AliEMCALGeometry.h"
22 #include "AliESDEvent.h"
23 #include "AliEmcalParticle.h"
24 #include "AliEventplane.h"
25 #include "AliInputEventHandler.h"
26 #include "AliLog.h"
27 #include "AliMCParticle.h"
28 #include "AliVCluster.h"
29 #include "AliVEventHandler.h"
30 #include "AliVParticle.h"
31 #include "AliVCaloTrigger.h"
32 #include "AliGenPythiaEventHeader.h"
33 #include "AliAODMCHeader.h"
34 #include "AliMCEvent.h"
35 #include "AliAnalysisUtils.h"
36 #include "AliEmcalTriggerPatchInfo.h"
37
38 #include "AliParticleContainer.h"
39 #include "AliClusterContainer.h"
40
41 ClassImp(AliAnalysisTaskEmcal)
42
43 //________________________________________________________________________
44 AliAnalysisTaskEmcal::AliAnalysisTaskEmcal() : 
45   AliAnalysisTaskSE("AliAnalysisTaskEmcal"),
46   fForceBeamType(kNA),
47   fGeneralHistograms(kFALSE),
48   fInitialized(kFALSE),
49   fCreateHisto(kTRUE),
50   fCaloCellsName(),
51   fCaloTriggersName(),
52   fCaloTriggerPatchInfoName(),
53   fMinCent(-999),
54   fMaxCent(-999),
55   fMinVz(-999),
56   fMaxVz(-999),
57   fTrackPtCut(0),
58   fMinNTrack(0),
59   fUseAliAnaUtils(kFALSE),
60   fAliAnalysisUtils(0x0),
61   fOffTrigger(AliVEvent::kAny),
62   fTrigClass(),
63   fTriggerTypeSel(kND),
64   fNbins(500),
65   fMinBinPt(0),
66   fMaxBinPt(250),
67   fMinPtTrackInEmcal(0),
68   fEventPlaneVsEmcal(-1),
69   fMinEventPlane(-1e6),
70   fMaxEventPlane(1e6),
71   fCentEst("V0M"),
72   fIsEmbedded(kFALSE),
73   fIsPythia(kFALSE),
74   fSelectPtHardBin(-999),
75   fMinMCLabel(0),
76   fMCLabelShift(0),
77   fNcentBins(4),
78   fNeedEmcalGeom(kTRUE),
79   fIsEsd(kFALSE),
80   fGeom(0),
81   fTracks(0),
82   fCaloClusters(0),
83   fCaloCells(0),
84   fCaloTriggers(0),
85   fTriggerPatchInfo(0),
86   fCent(0),
87   fCentBin(-1),
88   fEPV0(-1.0),
89   fEPV0A(-1.0),
90   fEPV0C(-1.0),
91   fNVertCont(0),
92   fBeamType(kNA),
93   fPythiaHeader(0),
94   fPtHard(0),
95   fPtHardBin(0),
96   fNTrials(0),
97   fXsection(0),
98   fParticleCollArray(),
99   fClusterCollArray(),
100   fMainTriggerPatch(0x0),
101   fTriggers(0),
102   fOutput(0),
103   fHistTrialsAfterSel(0),
104   fHistEventsAfterSel(0),
105   fHistXsectionAfterSel(0),
106   fHistTrials(0),
107   fHistEvents(0),
108   fHistXsection(0),
109   fHistPtHard(0),
110   fHistCentrality(0),
111   fHistZVertex(0),
112   fHistEventPlane(0),
113   fHistEventRejection(0)
114 {
115   // Default constructor.
116
117   fVertex[0] = 0;
118   fVertex[1] = 0;
119   fVertex[2] = 0;
120
121   fParticleCollArray.SetOwner(kTRUE);
122   fClusterCollArray.SetOwner(kTRUE);
123 }
124
125 //________________________________________________________________________
126 AliAnalysisTaskEmcal::AliAnalysisTaskEmcal(const char *name, Bool_t histo) : 
127   AliAnalysisTaskSE(name),
128   fForceBeamType(kNA),
129   fGeneralHistograms(kFALSE),
130   fInitialized(kFALSE),
131   fCreateHisto(histo),
132   fCaloCellsName(),
133   fCaloTriggersName(),
134   fCaloTriggerPatchInfoName(),
135   fMinCent(-999),
136   fMaxCent(-999),
137   fMinVz(-999),
138   fMaxVz(-999),
139   fTrackPtCut(0),
140   fMinNTrack(0),
141   fUseAliAnaUtils(kFALSE),
142   fAliAnalysisUtils(0x0),
143   fOffTrigger(AliVEvent::kAny),
144   fTrigClass(),
145   fTriggerTypeSel(kND),
146   fNbins(500),
147   fMinBinPt(0),
148   fMaxBinPt(250),
149   fMinPtTrackInEmcal(0),
150   fEventPlaneVsEmcal(-1),
151   fMinEventPlane(-1e6),
152   fMaxEventPlane(1e6),
153   fCentEst("V0M"),
154   fIsEmbedded(kFALSE),
155   fIsPythia(kFALSE),
156   fSelectPtHardBin(-999),
157   fMinMCLabel(0),
158   fMCLabelShift(0),
159   fNcentBins(4),
160   fNeedEmcalGeom(kTRUE),
161   fIsEsd(kFALSE),
162   fGeom(0),
163   fTracks(0),
164   fCaloClusters(0),
165   fCaloCells(0),
166   fCaloTriggers(0),
167   fTriggerPatchInfo(0),
168   fCent(0),
169   fCentBin(-1),
170   fEPV0(-1.0),
171   fEPV0A(-1.0),
172   fEPV0C(-1.0),
173   fNVertCont(0),
174   fBeamType(kNA),
175   fPythiaHeader(0),
176   fPtHard(0),
177   fPtHardBin(0),
178   fNTrials(0),
179   fXsection(0),
180   fParticleCollArray(),
181   fClusterCollArray(),
182   fMainTriggerPatch(0x0),
183   fTriggers(0),
184   fOutput(0),
185   fHistTrialsAfterSel(0),
186   fHistEventsAfterSel(0),
187   fHistXsectionAfterSel(0),
188   fHistTrials(0),
189   fHistEvents(0),
190   fHistXsection(0),
191   fHistPtHard(0),
192   fHistCentrality(0),
193   fHistZVertex(0),
194   fHistEventPlane(0),
195   fHistEventRejection(0)
196 {
197   // Standard constructor.
198
199   fVertex[0] = 0;
200   fVertex[1] = 0;
201   fVertex[2] = 0;
202
203   fParticleCollArray.SetOwner(kTRUE);
204   fClusterCollArray.SetOwner(kTRUE);
205
206   if (fCreateHisto) {
207     DefineOutput(1, TList::Class()); 
208   }
209 }
210
211 //________________________________________________________________________
212 AliAnalysisTaskEmcal::~AliAnalysisTaskEmcal()
213 {
214   // Destructor
215 }
216
217 //________________________________________________________________________
218 void AliAnalysisTaskEmcal::SetClusPtCut(Double_t cut, Int_t c)
219 {
220   AliClusterContainer *cont = GetClusterContainer(c);
221   if (cont) cont->SetClusPtCut(cut);
222   else AliError(Form("%s in SetClusPtCut(...): container %d not found",GetName(),c));
223 }
224
225 //________________________________________________________________________
226 void AliAnalysisTaskEmcal::SetClusTimeCut(Double_t min, Double_t max, Int_t c)
227 {
228   AliClusterContainer *cont = GetClusterContainer(c);
229   if (cont) cont->SetClusTimeCut(min,max);
230   else AliError(Form("%s in SetClusTimeCut(...): container %d not found",GetName(),c));
231 }
232
233 //________________________________________________________________________
234 void AliAnalysisTaskEmcal::SetTrackPtCut(Double_t cut, Int_t c)
235 {
236   AliParticleContainer *cont = GetParticleContainer(c);
237   if (cont) cont->SetParticlePtCut(cut);
238   else AliError(Form("%s in SetTrackPtCut(...): container %d not found",GetName(),c));
239
240   fTrackPtCut = cut;
241 }
242
243 //________________________________________________________________________
244 void AliAnalysisTaskEmcal::SetTrackEtaLimits(Double_t min, Double_t max, Int_t c)
245 {
246   AliParticleContainer *cont = GetParticleContainer(c);
247   if (cont) cont->SetParticleEtaLimits(min,max);
248   else AliError(Form("%s in SetTrackPtCut(...): container %d not found",GetName(),c));
249 }
250
251 //________________________________________________________________________
252 void AliAnalysisTaskEmcal::SetTrackPhiLimits(Double_t min, Double_t max, Int_t c)
253 {
254   AliParticleContainer *cont = GetParticleContainer(c);
255   if (cont) cont->SetParticlePhiLimits(min,max);
256   else AliError(Form("%s in SetTrackPhiLimits(...): container %d not found",GetName(),c));
257 }
258
259 //________________________________________________________________________
260 void AliAnalysisTaskEmcal::UserCreateOutputObjects()
261 {
262   // Create user output.
263
264   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
265   if (mgr) {
266     AliVEventHandler *evhand = mgr->GetInputEventHandler();
267     if (evhand) {
268       if (evhand->InheritsFrom("AliESDInputHandler")) {
269         fIsEsd = kTRUE;
270       }
271       else {
272         fIsEsd = kFALSE;        
273       }
274     }
275     else {
276       AliError("Event handler not found!");
277     }
278   }
279   else {
280     AliError("Analysis manager not found!");
281   }  
282
283   if (!fCreateHisto)
284     return;
285
286   OpenFile(1);
287   fOutput = new TList();
288   fOutput->SetOwner();
289
290   if (fForceBeamType == kpp)
291     fNcentBins = 1;
292
293   if (!fGeneralHistograms)
294     return;
295
296   if (fIsPythia) {
297     fHistTrialsAfterSel = new TH1F("fHistTrialsAfterSel", "fHistTrialsAfterSel", 11, 0, 11);
298     fHistTrialsAfterSel->GetXaxis()->SetTitle("p_{T} hard bin");
299     fHistTrialsAfterSel->GetYaxis()->SetTitle("trials");
300     fOutput->Add(fHistTrialsAfterSel);
301     
302     fHistEventsAfterSel = new TH1F("fHistEventsAfterSel", "fHistEventsAfterSel", 11, 0, 11);
303     fHistEventsAfterSel->GetXaxis()->SetTitle("p_{T} hard bin");
304     fHistEventsAfterSel->GetYaxis()->SetTitle("total events");
305     fOutput->Add(fHistEventsAfterSel);
306
307     fHistXsectionAfterSel = new TProfile("fHistXsectionAfterSel", "fHistXsectionAfterSel", 11, 0, 11);
308     fHistXsectionAfterSel->GetXaxis()->SetTitle("p_{T} hard bin");
309     fHistXsectionAfterSel->GetYaxis()->SetTitle("xsection");
310     fOutput->Add(fHistXsectionAfterSel);
311     
312     fHistTrials = new TH1F("fHistTrials", "fHistTrials", 11, 0, 11);
313     fHistTrials->GetXaxis()->SetTitle("p_{T} hard bin");
314     fHistTrials->GetYaxis()->SetTitle("trials");
315     fOutput->Add(fHistTrials);
316
317     fHistEvents = new TH1F("fHistEvents", "fHistEvents", 11, 0, 11);
318     fHistEvents->GetXaxis()->SetTitle("p_{T} hard bin");
319     fHistEvents->GetYaxis()->SetTitle("total events");
320     fOutput->Add(fHistEvents);
321
322     fHistXsection = new TProfile("fHistXsection", "fHistXsection", 11, 0, 11);
323     fHistXsection->GetXaxis()->SetTitle("p_{T} hard bin");
324     fHistXsection->GetYaxis()->SetTitle("xsection");
325     fOutput->Add(fHistXsection);
326
327     const Int_t ptHardLo[11] = { 0, 5,11,21,36,57, 84,117,152,191,234};
328     const Int_t ptHardHi[11] = { 5,11,21,36,57,84,117,152,191,234,1000000};
329     
330     for (Int_t i = 1; i < 12; i++) {
331       fHistTrialsAfterSel->GetXaxis()->SetBinLabel(i, Form("%d-%d",ptHardLo[i-1],ptHardHi[i-1]));
332       fHistEventsAfterSel->GetXaxis()->SetBinLabel(i, Form("%d-%d",ptHardLo[i-1],ptHardHi[i-1]));
333       
334       fHistTrials->GetXaxis()->SetBinLabel(i, Form("%d-%d",ptHardLo[i-1],ptHardHi[i-1]));
335       fHistXsection->GetXaxis()->SetBinLabel(i, Form("%d-%d",ptHardLo[i-1],ptHardHi[i-1]));
336       fHistEvents->GetXaxis()->SetBinLabel(i, Form("%d-%d",ptHardLo[i-1],ptHardHi[i-1]));
337     }
338
339     fHistPtHard = new TH1F("fHistPtHard", "fHistPtHard", fNbins*2, fMinBinPt, fMaxBinPt*4);
340     fHistPtHard->GetXaxis()->SetTitle("p_{T,hard} (GeV/c)");
341     fHistPtHard->GetYaxis()->SetTitle("counts");
342     fOutput->Add(fHistPtHard);
343   }
344
345   fHistCentrality = new TH1F("fHistCentrality","Event centrality distribution", 200, 0, 100);
346   fHistCentrality->GetXaxis()->SetTitle("Centrality (%)");
347   fHistCentrality->GetYaxis()->SetTitle("counts");
348   fOutput->Add(fHistCentrality);
349
350   fHistZVertex = new TH1F("fHistZVertex","Z vertex position", 60, -30, 30);
351   fHistZVertex->GetXaxis()->SetTitle("z");
352   fHistZVertex->GetYaxis()->SetTitle("counts");
353   fOutput->Add(fHistZVertex);
354
355   fHistEventPlane = new TH1F("fHistEventPlane","Event plane", 120, -TMath::Pi(), TMath::Pi());
356   fHistEventPlane->GetXaxis()->SetTitle("event plane");
357   fHistEventPlane->GetYaxis()->SetTitle("counts");
358   fOutput->Add(fHistEventPlane);
359
360   fHistEventRejection = new TH1I("fHistEventRejection","Reasons to reject event",20,0,20);
361   fHistEventRejection->Fill("PhysSel",0);
362   fHistEventRejection->Fill("trigger",0);
363   fHistEventRejection->Fill("trigTypeSel",0);
364   fHistEventRejection->Fill("Cent",0);
365   fHistEventRejection->Fill("vertex contr.",0);
366   fHistEventRejection->Fill("Vz",0);
367   fHistEventRejection->Fill("trackInEmcal",0);
368   fHistEventRejection->Fill("minNTrack",0);
369   fHistEventRejection->Fill("VtxSel2013pA",0);
370   fHistEventRejection->Fill("PileUp",0);
371   fHistEventRejection->Fill("EvtPlane",0);
372   fHistEventRejection->Fill("SelPtHardBin",0);
373   fHistEventRejection->GetYaxis()->SetTitle("counts");
374   fOutput->Add(fHistEventRejection);
375
376   PostData(1, fOutput);
377 }
378
379 //________________________________________________________________________
380 Bool_t AliAnalysisTaskEmcal::FillGeneralHistograms()
381 {
382   if (fIsPythia) {
383     fHistEventsAfterSel->Fill(fPtHardBin, 1);
384     fHistTrialsAfterSel->Fill(fPtHardBin, fNTrials);
385     fHistXsectionAfterSel->Fill(fPtHardBin, fXsection);
386     fHistPtHard->Fill(fPtHard);
387   }
388
389   fHistCentrality->Fill(fCent);
390   fHistZVertex->Fill(fVertex[2]);
391   fHistEventPlane->Fill(fEPV0);
392
393   return kTRUE;
394 }
395
396 //________________________________________________________________________
397 void AliAnalysisTaskEmcal::UserExec(Option_t *) 
398 {
399   // Main loop, called for each event.
400
401   fMainTriggerPatch = NULL;
402
403   if (!fInitialized)
404     ExecOnce();
405
406   if (!fInitialized)
407     return;
408
409   if (!RetrieveEventObjects())
410     return;
411
412   if (!IsEventSelected()) 
413     return;
414
415   if (fGeneralHistograms && fCreateHisto) {
416     if (!FillGeneralHistograms())
417       return;
418   }
419
420   if (!Run())
421     return;
422
423   if (fCreateHisto) {
424     if (!FillHistograms())
425       return;
426   }
427     
428   if (fCreateHisto && fOutput) {
429     // information for this iteration of the UserExec in the container
430     PostData(1, fOutput);
431   }
432 }
433
434 //________________________________________________________________________
435 Bool_t AliAnalysisTaskEmcal::AcceptCluster(AliVCluster *clus, Int_t c) const
436 {
437   // Return true if cluster is accepted.
438
439   if (!clus)
440     return kFALSE;
441
442   AliClusterContainer *cont = GetClusterContainer(c);
443   if (!cont) {
444     AliError(Form("%s:Container %d not found",GetName(),c));
445     return 0;
446   }
447
448   return cont->AcceptCluster(clus);
449 }
450
451 //________________________________________________________________________
452 Bool_t AliAnalysisTaskEmcal::AcceptTrack(AliVParticle *track, Int_t c) const
453 {
454   // Return true if track is accepted.
455
456   if (!track)
457     return kFALSE;
458
459   AliParticleContainer *cont = GetParticleContainer(c);
460   if (!cont) {
461     AliError(Form("%s:Container %d not found",GetName(),c));
462     return 0;
463   }
464
465   return cont->AcceptParticle(track);
466 }
467
468 //________________________________________________________________________
469 Bool_t AliAnalysisTaskEmcal::PythiaInfoFromFile(const char* currFile, Float_t &fXsec, Float_t &fTrials, Int_t &pthard)
470 {
471   //
472   // Get the cross section and the trails either from pyxsec.root or from pysec_hists.root
473   // Get the pt hard bin from the file path
474   // This is to called in Notify and should provide the path to the AOD/ESD file
475   // (Partially copied from AliAnalysisHelperJetTasks)
476
477   TString file(currFile);  
478   fXsec = 0;
479   fTrials = 1;
480
481   if (file.Contains(".zip#")) {
482     Ssiz_t pos1 = file.Index("root_archive",12,0,TString::kExact);
483     Ssiz_t pos = file.Index("#",1,pos1,TString::kExact);
484     Ssiz_t pos2 = file.Index(".root",5,TString::kExact);
485     file.Replace(pos+1,pos2-pos1,"");
486   } else {
487     // not an archive take the basename....
488     file.ReplaceAll(gSystem->BaseName(file.Data()),"");
489   }
490   AliDebug(1,Form("File name: %s",file.Data()));
491
492   // Get the pt hard bin
493   TString strPthard(file);
494
495   strPthard.Remove(strPthard.Last('/'));
496   strPthard.Remove(strPthard.Last('/'));
497   if (strPthard.Contains("AOD")) strPthard.Remove(strPthard.Last('/'));    
498   strPthard.Remove(0,strPthard.Last('/')+1);
499   if (strPthard.IsDec()) 
500     pthard = strPthard.Atoi();
501   else 
502     AliWarning(Form("Could not extract file number from path %s", strPthard.Data()));
503
504   // problem that we cannot really test the existance of a file in a archive so we have to live with open error message from root
505   TFile *fxsec = TFile::Open(Form("%s%s",file.Data(),"pyxsec.root")); 
506   
507   if (!fxsec) {
508     // next trial fetch the histgram file
509     fxsec = TFile::Open(Form("%s%s",file.Data(),"pyxsec_hists.root"));
510     if (!fxsec) {
511         // not a severe condition but inciate that we have no information
512       return kFALSE;
513     } else {
514       // find the tlist we want to be independtent of the name so use the Tkey
515       TKey* key = (TKey*)fxsec->GetListOfKeys()->At(0); 
516       if (!key) {
517         fxsec->Close();
518         return kFALSE;
519       }
520       TList *list = dynamic_cast<TList*>(key->ReadObj());
521       if (!list) {
522         fxsec->Close();
523         return kFALSE;
524       }
525       fXsec = ((TProfile*)list->FindObject("h1Xsec"))->GetBinContent(1);
526       fTrials  = ((TH1F*)list->FindObject("h1Trials"))->GetBinContent(1);
527       fxsec->Close();
528     }
529   } else { // no tree pyxsec.root
530     TTree *xtree = (TTree*)fxsec->Get("Xsection");
531     if (!xtree) {
532       fxsec->Close();
533       return kFALSE;
534     }
535     UInt_t   ntrials  = 0;
536     Double_t  xsection  = 0;
537     xtree->SetBranchAddress("xsection",&xsection);
538     xtree->SetBranchAddress("ntrials",&ntrials);
539     xtree->GetEntry(0);
540     fTrials = ntrials;
541     fXsec = xsection;
542     fxsec->Close();
543   }
544   return kTRUE;
545 }
546
547 //________________________________________________________________________
548 Bool_t AliAnalysisTaskEmcal::UserNotify()
549 {
550   // Called when file changes.
551
552   if (!fIsPythia || !fGeneralHistograms || !fCreateHisto)
553     return kTRUE;
554
555   TTree *tree = AliAnalysisManager::GetAnalysisManager()->GetTree();
556   if (!tree) {
557     AliError(Form("%s - UserNotify: No current tree!",GetName()));
558     return kFALSE;
559   }
560
561   Float_t xsection    = 0;
562   Float_t trials      = 0;
563   Int_t   pthardbin   = 0;
564
565   TFile *curfile = tree->GetCurrentFile();
566   if (!curfile) {
567     AliError(Form("%s - UserNotify: No current file!",GetName()));
568     return kFALSE;
569   }
570
571   TChain *chain = dynamic_cast<TChain*>(tree);
572   if (chain) tree = chain->GetTree();
573
574   Int_t nevents = tree->GetEntriesFast();
575
576   PythiaInfoFromFile(curfile->GetName(), xsection, trials, pthardbin);
577
578   // TODO: Workaround
579   if ((pthardbin < 0) || (pthardbin > 10)) pthardbin = 0;
580
581   fHistTrials->Fill(pthardbin, trials);
582   fHistXsection->Fill(pthardbin, xsection);
583   fHistEvents->Fill(pthardbin, nevents);
584
585   return kTRUE;
586 }
587
588 //________________________________________________________________________
589 void AliAnalysisTaskEmcal::ExecOnce()
590 {
591   // Init the analysis.
592
593   if (!InputEvent()) {
594     AliError(Form("%s: Could not retrieve event! Returning!", GetName()));
595     return;
596   }
597
598   if (fNeedEmcalGeom) {
599     fGeom = AliEMCALGeometry::GetInstance();
600     if (!fGeom) {
601       AliError(Form("%s: Can not create geometry", GetName()));
602       return;
603     }
604   }
605
606   
607   if (fEventPlaneVsEmcal >= 0) {
608     if (fGeom) {
609       Double_t ep = (fGeom->GetArm1PhiMax() + fGeom->GetArm1PhiMin()) / 2 * TMath::DegToRad() + fEventPlaneVsEmcal - TMath::Pi();
610       fMinEventPlane = ep - TMath::Pi() / 4;
611       fMaxEventPlane = ep + TMath::Pi() / 4;
612     }
613     else {
614       AliWarning("Could not set event plane limits because EMCal geometry was not loaded!");
615     }
616   }
617
618   //Load all requested track branches - each container knows name already
619   for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
620     AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
621     cont->SetArray(InputEvent());
622   }
623
624   if (fParticleCollArray.GetEntriesFast()>0) {
625     fTracks = GetParticleArray(0);
626     if (!fTracks) {
627       AliError(Form("%s: Could not retrieve first track branch!", GetName()));
628       return;
629     }
630   }
631
632   //Load all requested cluster branches - each container knows name already
633   for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
634     AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
635     cont->SetArray(InputEvent());
636   }
637
638   if (fClusterCollArray.GetEntriesFast()>0) {
639     fCaloClusters = GetClusterArray(0);
640     if (!fCaloClusters) {
641       AliError(Form("%s: Could not retrieve first cluster branch!", GetName()));
642       return;
643     }
644   }
645
646   if (!fCaloCellsName.IsNull() && !fCaloCells) {
647     fCaloCells =  dynamic_cast<AliVCaloCells*>(InputEvent()->FindListObject(fCaloCellsName));
648     if (!fCaloCells) {
649       AliError(Form("%s: Could not retrieve cells %s!", GetName(), fCaloCellsName.Data())); 
650       return;
651     }
652   }
653
654   if (!fCaloTriggersName.IsNull() && !fCaloTriggers) {
655     fCaloTriggers =  dynamic_cast<AliVCaloTrigger*>(InputEvent()->FindListObject(fCaloTriggersName));
656     if (!fCaloTriggers) {
657       AliError(Form("%s: Could not retrieve calo triggers %s!", GetName(), fCaloTriggersName.Data())); 
658       return;
659     }
660   }
661
662   if (!fCaloTriggerPatchInfoName.IsNull() && !fTriggerPatchInfo) {
663     fTriggerPatchInfo = GetArrayFromEvent(fCaloTriggerPatchInfoName.Data(),"AliEmcalTriggerPatchInfo");
664     if (!fTriggerPatchInfo) {
665       AliError(Form("%s: Could not retrieve calo trigger patch info %s!", GetName(), fCaloTriggerPatchInfoName.Data())); 
666       return;
667     }
668
669   }
670
671   fInitialized = kTRUE;
672 }
673
674 //_____________________________________________________
675 AliAnalysisTaskEmcal::BeamType AliAnalysisTaskEmcal::GetBeamType()
676 {
677   // Get beam type : pp-AA-pA
678   // ESDs have it directly, AODs get it from hardcoded run number ranges
679
680   if (fForceBeamType != kNA)
681     return fForceBeamType;
682
683   AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
684   if (esd) {
685     const AliESDRun *run = esd->GetESDRun();
686     TString beamType = run->GetBeamType();
687     if (beamType == "p-p")
688       return kpp;
689     else if (beamType == "A-A")
690       return kAA;
691     else if (beamType == "p-A")
692       return kpA;
693     else
694       return kNA;
695   } else {
696     Int_t runNumber = InputEvent()->GetRunNumber();
697     if ((runNumber >= 136851 && runNumber <= 139517) ||  // LHC10h
698         (runNumber >= 166529 && runNumber <= 170593)) {  // LHC11h
699       return kAA;
700     } else if ((runNumber>=188365 && runNumber <= 188366) ||   // LHC12g
701                (runNumber >= 195344 && runNumber <= 196608)) { // LHC13b-f
702       return kpA;
703     } else {
704       return kpp;
705     }
706   }  
707 }
708
709 //________________________________________________________________________
710 ULong_t AliAnalysisTaskEmcal::GetTriggerList(){
711           if (!fTriggerPatchInfo)
712             return 0;
713
714           //number of patches in event
715           Int_t nPatch = fTriggerPatchInfo->GetEntries();
716
717           //loop over patches to define trigger type of event
718           Int_t nG1 = 0;
719           Int_t nG2 = 0;
720           Int_t nJ1 = 0;
721           Int_t nJ2 = 0;
722           AliEmcalTriggerPatchInfo *patch;
723           for (Int_t iPatch = 0; iPatch < nPatch; iPatch++) {
724             patch = (AliEmcalTriggerPatchInfo*)fTriggerPatchInfo->At( iPatch );
725             if (patch->IsGammaHigh()) nG1++;
726             if (patch->IsGammaLow())  nG2++;
727             if (patch->IsJetHigh()) nJ1++;
728             if (patch->IsJetLow())  nJ2++;
729           }
730
731           AliDebug(2, "Patch summary: ");
732           AliDebug(2, Form("Number of patches: %d", nPatch));
733           AliDebug(2, Form("Jet:   low[%d], high[%d]" ,nJ2, nJ1));
734           AliDebug(2, Form("Gamma: low[%d], high[%d]" ,nG2, nG1));
735
736           ULong_t triggers(0);
737           if (nG1>0)
738                 SETBIT(triggers, kG1);
739           if (nG2>0)
740                 SETBIT(triggers, kG2);
741           if (nJ1>0)
742                 SETBIT(triggers, kJ1);
743           if (nJ2>0)
744                 SETBIT(triggers, kJ2);
745           return triggers;
746 }
747
748 //________________________________________________________________________
749 Bool_t AliAnalysisTaskEmcal::HasTriggerType(TriggerType t){
750         // Check if event has a given trigger type
751         if(t == kND){
752                 return fTriggers == 0;
753         }
754         return TESTBIT(fTriggers, int(t));
755 }
756
757 //________________________________________________________________________
758 Bool_t AliAnalysisTaskEmcal::IsEventSelected()
759 {
760   // Check if event is selected
761
762   if (fOffTrigger != AliVEvent::kAny) {
763     UInt_t res = 0;
764     const AliESDEvent *eev = dynamic_cast<const AliESDEvent*>(InputEvent());
765     if (eev) {
766       res = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();
767     } else {
768       const AliAODEvent *aev = dynamic_cast<const AliAODEvent*>(InputEvent());
769       if (aev) {
770         res = aev->GetHeader()->GetOfflineTrigger();
771       }
772     }
773     if ((res & fOffTrigger) == 0) {
774       if (fGeneralHistograms) 
775         fHistEventRejection->Fill("PhysSel",1);
776       return kFALSE;
777     }
778   }
779
780   if (!fTrigClass.IsNull()) {
781     TString fired;
782     const AliESDEvent *eev = dynamic_cast<const AliESDEvent*>(InputEvent());
783     if (eev) {
784       fired = eev->GetFiredTriggerClasses();
785     } else {
786       const AliAODEvent *aev = dynamic_cast<const AliAODEvent*>(InputEvent());
787       if (aev) {
788         fired = aev->GetFiredTriggerClasses();
789       }
790     }
791     if (!fired.Contains("-B-")) {
792       if (fGeneralHistograms) 
793         fHistEventRejection->Fill("trigger",1);
794       return kFALSE;
795     }
796     TObjArray *arr = fTrigClass.Tokenize("|");
797     if (!arr) {
798       if (fGeneralHistograms) 
799         fHistEventRejection->Fill("trigger",1);
800       return kFALSE;
801     }
802     Bool_t match = 0;
803     for (Int_t i=0;i<arr->GetEntriesFast();++i) {
804       TObject *obj = arr->At(i);
805       if (!obj)
806         continue;
807       if (fired.Contains(obj->GetName())) {
808         match = 1;
809         break;
810       }
811     }
812     delete arr;
813     if (!match) {
814       if (fGeneralHistograms) 
815         fHistEventRejection->Fill("trigger",1);
816       return kFALSE;
817     }
818   }
819
820   if (fTriggerTypeSel != kND) {
821     if (!HasTriggerType(fTriggerTypeSel)) {
822       if (fGeneralHistograms) 
823         fHistEventRejection->Fill("trigTypeSel",1);
824       return kFALSE;
825     }
826   }
827
828   if ((fMinCent != -999) && (fMaxCent != -999)) {
829     if (fCent<fMinCent || fCent>fMaxCent) {
830       if (fGeneralHistograms) 
831         fHistEventRejection->Fill("Cent",1);
832       return kFALSE;
833     }
834   }
835
836   if (fUseAliAnaUtils) {
837     if (!fAliAnalysisUtils)
838       fAliAnalysisUtils = new AliAnalysisUtils();
839     fAliAnalysisUtils->SetMinVtxContr(2);
840     fAliAnalysisUtils->SetMaxVtxZ(999);
841     if(fMinVz<-10.) fMinVz = -10.; 
842     if(fMinVz>10.)  fMaxVz = 10.;
843
844     if (!fAliAnalysisUtils->IsVertexSelected2013pA(InputEvent())) {
845       if (fGeneralHistograms) 
846         fHistEventRejection->Fill("VtxSel2013pA",1);
847       return kFALSE;
848     }
849
850     if (fAliAnalysisUtils->IsPileUpEvent(InputEvent())) {
851       fHistEventRejection->Fill("PileUp",1);
852       return kFALSE;
853     }
854   }
855
856   if ((fMinVz != -999) && (fMaxVz != -999)) {
857     if (fNVertCont == 0 ) {
858       if (fGeneralHistograms) 
859         fHistEventRejection->Fill("vertex contr.",1);
860       return kFALSE;
861     }
862     Double_t vz = fVertex[2];
863     if (vz<fMinVz || vz>fMaxVz) {
864       if (fGeneralHistograms) 
865         fHistEventRejection->Fill("Vz",1);
866       return kFALSE;
867     }
868   }
869
870   if (fMinPtTrackInEmcal > 0 && fGeom) {
871     Bool_t trackInEmcalOk = kFALSE;
872     Int_t ntracks = GetNParticles(0);
873     for (Int_t i = 0; i < ntracks; i++) {
874       AliVParticle *track = GetAcceptParticleFromArray(i,0);
875       if (!track)
876         continue;
877
878       Double_t phiMin = fGeom->GetArm1PhiMin() * TMath::DegToRad();
879       Double_t phiMax = fGeom->GetArm1PhiMax() * TMath::DegToRad();
880       Int_t runNumber = InputEvent()->GetRunNumber();
881       if (runNumber>=177295 && runNumber<=197470) { //small SM masked in 2012 and 2013
882         phiMin = 1.4;   
883         phiMax = TMath::Pi();
884       }
885
886       if (track->Eta() < fGeom->GetArm1EtaMin() || track->Eta() > fGeom->GetArm1EtaMax() || track->Phi() < phiMin || track->Phi() > phiMax)
887         continue;
888       if (track->Pt() > fMinPtTrackInEmcal) {
889         trackInEmcalOk = kTRUE;
890         break;
891       }
892     }
893     if (!trackInEmcalOk) {
894       if (fGeneralHistograms) 
895         fHistEventRejection->Fill("trackInEmcal",1);
896       return kFALSE;
897     }
898   }
899
900   if (fMinNTrack > 0) {
901     Int_t nTracksAcc = 0;
902     Int_t ntracks = GetNParticles(0);
903     for (Int_t i = 0; i < ntracks; i++) {
904       AliVParticle *track = GetAcceptParticleFromArray(i,0);
905       if (!track)
906         continue;
907       if (track->Pt() > fTrackPtCut) {
908         nTracksAcc++;
909         if (nTracksAcc>=fMinNTrack)
910           break;
911       }
912     }
913     if (nTracksAcc<fMinNTrack) {
914       if (fGeneralHistograms) 
915         fHistEventRejection->Fill("minNTrack",1);
916       return kFALSE;
917     }
918   }
919
920   if (!(fEPV0 > fMinEventPlane && fEPV0 <= fMaxEventPlane) &&
921       !(fEPV0 + TMath::Pi() > fMinEventPlane && fEPV0 + TMath::Pi() <= fMaxEventPlane) &&
922       !(fEPV0 - TMath::Pi() > fMinEventPlane && fEPV0 - TMath::Pi() <= fMaxEventPlane)) 
923     {
924       if (fGeneralHistograms) 
925         fHistEventRejection->Fill("EvtPlane",1);
926       return kFALSE;
927     }
928
929   if (fSelectPtHardBin != -999 && fSelectPtHardBin != fPtHardBin)  {
930       if (fGeneralHistograms) 
931         fHistEventRejection->Fill("SelPtHardBin",1);
932       return kFALSE;
933     }
934
935   return kTRUE;
936 }
937
938 //________________________________________________________________________
939 TClonesArray *AliAnalysisTaskEmcal::GetArrayFromEvent(const char *name, const char *clname)
940 {
941   // Get array from event.
942
943   TClonesArray *arr = 0;
944   TString sname(name);
945   if (!sname.IsNull()) {
946     arr = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(sname));
947     if (!arr) {
948       AliWarning(Form("%s: Could not retrieve array with name %s!", GetName(), name)); 
949       return 0;
950     }
951   } else {
952     return 0;
953   }
954
955   if (!clname)
956     return arr;
957
958   TString objname(arr->GetClass()->GetName());
959   TClass cls(objname);
960   if (!cls.InheritsFrom(clname)) {
961     AliWarning(Form("%s: Objects of type %s in %s are not inherited from %s!", 
962                     GetName(), cls.GetName(), name, clname)); 
963     return 0;
964   }
965   return arr;
966 }
967
968 //________________________________________________________________________
969 Bool_t AliAnalysisTaskEmcal::RetrieveEventObjects()
970 {
971   // Retrieve objects from event.
972
973   fVertex[0] = 0;
974   fVertex[1] = 0;
975   fVertex[2] = 0;
976   fNVertCont = 0;
977
978   const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
979   if (vert) {
980     vert->GetXYZ(fVertex);
981     fNVertCont = vert->GetNContributors();
982   }
983
984   fBeamType = GetBeamType();
985
986   if (fBeamType == kAA || fBeamType == kpA ) {
987     AliCentrality *aliCent = InputEvent()->GetCentrality();
988     if (aliCent) {
989       fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
990       if (fNcentBins==4) {
991         if      (fCent >=  0 && fCent <   10) fCentBin = 0;
992         else if (fCent >= 10 && fCent <   30) fCentBin = 1;
993         else if (fCent >= 30 && fCent <   50) fCentBin = 2;
994         else if (fCent >= 50 && fCent <= 100) fCentBin = 3; 
995         else {
996           AliWarning(Form("%s: Negative centrality: %f. Assuming 99", GetName(), fCent));
997           fCentBin = fNcentBins-1;
998         }
999       } else {
1000         Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1001         if(centWidth>0.)
1002           fCentBin = TMath::FloorNint(fCent/centWidth);
1003         else 
1004           fCentBin = 0;
1005         if (fCentBin>=fNcentBins) {
1006           AliWarning(Form("%s: fCentBin too large: cent = %f fCentBin = %d. Assuming 99", GetName(),fCent,fCentBin));
1007           fCentBin = fNcentBins-1;
1008         }
1009       }
1010     } else {
1011       AliWarning(Form("%s: Could not retrieve centrality information! Assuming 99", GetName()));
1012       fCentBin = fNcentBins-1;
1013     }
1014     AliEventplane *aliEP = InputEvent()->GetEventplane();
1015     if (aliEP) {
1016       fEPV0  = aliEP->GetEventplane("V0" ,InputEvent());
1017       fEPV0A = aliEP->GetEventplane("V0A",InputEvent());
1018       fEPV0C = aliEP->GetEventplane("V0C",InputEvent());
1019     } else {
1020       AliWarning(Form("%s: Could not retrieve event plane information!", GetName()));
1021     }
1022   } else {
1023     fCent = 99;
1024     fCentBin = 0;
1025   }
1026
1027   if (fIsPythia) {
1028
1029     if (MCEvent()) {
1030       fPythiaHeader = dynamic_cast<AliGenPythiaEventHeader*>(MCEvent()->GenEventHeader());
1031       if (!fPythiaHeader) {
1032         // Check if AOD
1033         AliAODMCHeader* aodMCH = dynamic_cast<AliAODMCHeader*>(InputEvent()->FindListObject(AliAODMCHeader::StdBranchName()));
1034
1035         if (aodMCH) {
1036           for (UInt_t i = 0;i<aodMCH->GetNCocktailHeaders();i++) {
1037             fPythiaHeader = dynamic_cast<AliGenPythiaEventHeader*>(aodMCH->GetCocktailHeader(i));
1038             if (fPythiaHeader) break;
1039           }
1040         }
1041       }
1042     }
1043
1044     if (fPythiaHeader) {
1045       fPtHard = fPythiaHeader->GetPtHard();
1046
1047       const Int_t ptHardLo[11] = { 0, 5,11,21,36,57, 84,117,152,191,234};
1048       const Int_t ptHardHi[11] = { 5,11,21,36,57,84,117,152,191,234,1000000};
1049       for (fPtHardBin = 0; fPtHardBin < 11; fPtHardBin++) {
1050         if (fPtHard >= ptHardLo[fPtHardBin] && fPtHard < ptHardHi[fPtHardBin])
1051           break;
1052       }
1053
1054       fXsection = fPythiaHeader->GetXsection();
1055       fNTrials = fPythiaHeader->Trials();
1056     }
1057   }
1058
1059   fTriggers = GetTriggerList();
1060
1061   return kTRUE;
1062 }
1063
1064 //________________________________________________________________________
1065 AliParticleContainer* AliAnalysisTaskEmcal::AddParticleContainer(const char *n) 
1066 {
1067   // Add particle container
1068   // will be called in AddTask macro
1069
1070   TString tmp = TString(n);
1071   if (tmp.IsNull()) return 0;
1072
1073   AliParticleContainer *cont = 0x0;
1074   cont = new AliParticleContainer();
1075   cont->SetArrayName(n);
1076   TString contName = cont->GetArrayName();
1077  
1078   fParticleCollArray.Add(cont);
1079
1080   return cont;
1081 }
1082
1083 //________________________________________________________________________
1084 AliClusterContainer* AliAnalysisTaskEmcal::AddClusterContainer(const char *n) 
1085 {
1086   // Add cluster container
1087   // will be called in AddTask macro
1088
1089   TString tmp = TString(n);
1090   if (tmp.IsNull()) return 0;
1091
1092   AliClusterContainer *cont = 0x0;
1093   cont = new AliClusterContainer();
1094   cont->SetArrayName(n);
1095
1096   fClusterCollArray.Add(cont);
1097
1098   return cont;
1099 }
1100
1101 //________________________________________________________________________
1102 AliParticleContainer* AliAnalysisTaskEmcal::GetParticleContainer(Int_t i) const 
1103 {
1104   // Get i^th particle container
1105
1106   if (i<0 || i>fParticleCollArray.GetEntriesFast()) return 0;
1107   AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1108   return cont;
1109 }
1110
1111 //________________________________________________________________________
1112 AliClusterContainer* AliAnalysisTaskEmcal::GetClusterContainer(Int_t i) const 
1113 {
1114   // Get i^th cluster container
1115
1116   if (i<0 || i>fClusterCollArray.GetEntriesFast()) return 0;
1117   AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1118   return cont;
1119 }
1120
1121 //________________________________________________________________________
1122 AliParticleContainer* AliAnalysisTaskEmcal::GetParticleContainer(const char *name) const 
1123 {
1124   // Get particle container with name
1125
1126   AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.FindObject(name));
1127   return cont;
1128 }
1129
1130 //________________________________________________________________________
1131 AliClusterContainer* AliAnalysisTaskEmcal::GetClusterContainer(const char *name) const 
1132 {
1133   // Get cluster container with name
1134
1135   AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.FindObject(name));
1136   return cont;
1137 }
1138
1139 //________________________________________________________________________
1140 TClonesArray* AliAnalysisTaskEmcal::GetParticleArray(Int_t i) const 
1141 {
1142   // Get i^th TClonesArray with AliVParticle
1143
1144   AliParticleContainer *cont = GetParticleContainer(i);
1145   if (!cont) {
1146     AliError(Form("%s: Particle container %d not found",GetName(),i));
1147     return 0;
1148   }
1149   TString contName = cont->GetArrayName();
1150   return cont->GetArray();
1151 }
1152
1153 //________________________________________________________________________
1154 TClonesArray* AliAnalysisTaskEmcal::GetClusterArray(Int_t i) const 
1155 {
1156   // Get i^th TClonesArray with AliVCluster
1157
1158   AliClusterContainer *cont = GetClusterContainer(i);
1159   if (!cont) {
1160     AliError(Form("%s:Cluster container %d not found",GetName(),i));
1161     return 0;
1162   }
1163   return cont->GetArray();
1164 }
1165
1166 //________________________________________________________________________
1167 AliVParticle* AliAnalysisTaskEmcal::GetAcceptParticleFromArray(Int_t p, Int_t c) const 
1168 {
1169   // Get particle p if accepted from  container c
1170   // If particle not accepted return 0
1171
1172   AliParticleContainer *cont = GetParticleContainer(c);
1173   if (!cont) {
1174     AliError(Form("%s: Particle container %d not found",GetName(),c));
1175     return 0;
1176   }
1177   AliVParticle *vp = cont->GetAcceptParticle(p);
1178
1179   return vp;
1180 }
1181
1182 //________________________________________________________________________
1183 AliVCluster* AliAnalysisTaskEmcal::GetAcceptClusterFromArray(Int_t cl, Int_t c) const 
1184 {
1185   // Get particle p if accepted from  container c
1186   // If particle not accepted return 0
1187
1188   AliClusterContainer *cont = GetClusterContainer(c);
1189   if (!cont) {
1190     AliError(Form("%s: Cluster container %d not found",GetName(),c));
1191     return 0;
1192   }
1193   AliVCluster *vc = cont->GetAcceptCluster(cl);
1194
1195   return vc;
1196 }
1197
1198 //________________________________________________________________________
1199 Int_t AliAnalysisTaskEmcal::GetNParticles(Int_t i) const 
1200 {
1201   // Get number of entries in particle array i
1202
1203   AliParticleContainer *cont = GetParticleContainer(i);
1204   if (!cont) {
1205     AliError(Form("%s: Particle container %d not found",GetName(),i));
1206     return 0;
1207   }
1208   return cont->GetNEntries();
1209 }
1210
1211 //________________________________________________________________________
1212 Int_t AliAnalysisTaskEmcal::GetNClusters(Int_t i) const 
1213 {
1214   // Get number of entries in cluster array i
1215
1216   AliClusterContainer *cont = GetClusterContainer(i);
1217   if (!cont) {
1218     AliError(Form("%s: Cluster container %d not found",GetName(),i));
1219     return 0;
1220   }
1221   return cont->GetNEntries();
1222 }
1223
1224 //________________________________________________________________________
1225 AliEmcalTriggerPatchInfo* AliAnalysisTaskEmcal::GetMainTriggerPatch() 
1226 {
1227   //get main trigger match; if not known yet, look for it and cache
1228
1229   if (fMainTriggerPatch) 
1230     return fMainTriggerPatch;
1231
1232   if (!fTriggerPatchInfo) {
1233     AliError(Form("%s: fTriggerPatchInfo not available",GetName()));
1234     return 0;
1235   }
1236
1237   //number of patches in event
1238   Int_t nPatch = fTriggerPatchInfo->GetEntries();
1239
1240   //extract main trigger patch
1241   AliEmcalTriggerPatchInfo *patch;
1242   for (Int_t iPatch = 0; iPatch < nPatch; iPatch++) {
1243     
1244     patch = (AliEmcalTriggerPatchInfo*)fTriggerPatchInfo->At( iPatch );
1245     if (patch->IsMainTrigger()) {
1246       fMainTriggerPatch = patch;
1247       break;
1248     }
1249   }
1250
1251   return fMainTriggerPatch;
1252 }
1253
1254 //________________________________________________________________________
1255 void AliAnalysisTaskEmcal::AddObjectToEvent(TObject *obj)
1256 {
1257   // Add object to event
1258
1259   if (!(InputEvent()->FindListObject(obj->GetName()))) {
1260     InputEvent()->AddObject(obj);
1261   } else {
1262     AliFatal(Form("%s: Container with name %s already present. Aborting", GetName(), obj->GetName()));
1263   }
1264 }
1265
1266 //________________________________________________________________________
1267 void AliAnalysisTaskEmcal::GenerateFixedBinArray(Int_t n, Double_t min, Double_t max, Double_t* array) const
1268 {
1269   Double_t binWidth = (max-min)/n;
1270   array[0] = min;
1271   for (Int_t i = 1; i <= n; i++) {
1272     array[i] = array[i-1]+binWidth;
1273   }
1274 }
1275
1276 //________________________________________________________________________
1277 Double_t* AliAnalysisTaskEmcal::GenerateFixedBinArray(Int_t n, Double_t min, Double_t max) const
1278 {
1279   Double_t *array = new Double_t[n+1];
1280
1281   GenerateFixedBinArray(n, min, max, array);
1282
1283   return array;
1284 }