Fixes for bug #62149 AliITSTrackleterSPDEff returns an error in case of 'empty' events
[u/mrichter/AliRoot.git] / CORRFW / AliCFContainer.cxx
1 /* $Id$ */
2 /**************************************************************************
3  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4  *                                                                        *
5  * Author: The ALICE Off-line Project.                                    *
6  * Contributors are mentioned in the code where appropriate.              *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          *
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16 //--------------------------------------------------------------------//
17 //                                                                    //
18 // AliCFContainer Class                                               //
19 // Class to accumulate data on an N-dimensional grids, at different   //
20 // selection stages. To be used as an input to get corrections for    //
21 // Reconstruction & Trigger efficiency                                // 
22 //                                                                    //
23 // -- Author : S.Arcelli                                              //
24 //--------------------------------------------------------------------//
25 //
26 //
27 #include <AliLog.h>
28 #include "AliCFGridSparse.h"
29 #include "AliCFContainer.h"
30 #include "TAxis.h"
31 //____________________________________________________________________
32 ClassImp(AliCFContainer)
33
34 //____________________________________________________________________
35 AliCFContainer::AliCFContainer() : 
36   AliCFFrame(),
37   fNStep(0),
38   fGrid(0x0)
39 {
40   //
41   // default constructor
42   //
43 }
44 //____________________________________________________________________
45 AliCFContainer::AliCFContainer(const Char_t* name, const Char_t* title) : 
46   AliCFFrame(name,title),
47   fNStep(0),
48   fGrid(0x0)
49 {
50   // default constructor
51 }
52
53 //____________________________________________________________________
54 AliCFContainer::AliCFContainer(const Char_t* name, const Char_t* title, const Int_t nSelSteps, const Int_t nVarIn, const Int_t* nBinIn) :  
55   AliCFFrame(name,title),
56   fNStep(nSelSteps),
57   fGrid(0x0)
58 {
59   //
60   // main constructor
61   //
62
63   // The grids 
64   fGrid = new AliCFGridSparse*[fNStep]; //the grids at the various selection steps
65   char gname[100];
66   for (Int_t istep=0; istep<fNStep; istep++) {
67     sprintf(gname,"%s%s%i",GetName(),"_SelStep", istep);
68     fGrid[istep] = new AliCFGridSparse(gname,title,nVarIn,nBinIn);
69     fGrid[istep]->SumW2();
70   }
71   AliInfo(Form("Grids created for %d steps required  \n =>  Don't forget to set the bin limits !!",fNStep));
72 }
73 //____________________________________________________________________
74 AliCFContainer::AliCFContainer(const AliCFContainer& c) :
75   AliCFFrame(c.fName,c.fTitle),
76   fNStep(0),
77   fGrid(0x0)
78 {
79   //
80   // copy constructor
81   //
82   c.Copy(*this);
83 }
84 //____________________________________________________________________
85 AliCFContainer::~AliCFContainer()
86 {
87   //
88   // destructor
89   //
90   if (fGrid) delete [] fGrid;
91 }
92 //____________________________________________________________________
93 AliCFContainer &AliCFContainer::operator=(const AliCFContainer &c)
94 {
95   //
96   // assigment operator
97   //
98   if (this != &c) c.Copy(*this);
99   return *this;
100
101
102 //____________________________________________________________________
103 void AliCFContainer::Copy(TObject& c) const
104 {
105   //
106   // copy function
107   //
108   AliCFFrame::Copy(c);
109   AliCFContainer& target = (AliCFContainer &) c;
110   target.fNStep = fNStep;
111   target.fGrid  = new AliCFGridSparse*[fNStep];
112   for (Int_t iStep=0; iStep<fNStep; iStep++) {
113     if (fGrid[iStep])  target.fGrid[iStep] = new AliCFGridSparse(*(fGrid[iStep]));
114   }
115 }
116
117 //____________________________________________________________________
118 void AliCFContainer::Fill(const Double_t *var, Int_t istep, Double_t weight)
119 {
120   //
121   // Fills the grid at selection step istep for a set of values of the 
122   // input variables, with a given weight (by default w=1)
123   //
124   if(istep >= fNStep || istep < 0){
125     AliError("Non-existent selection step, grid was not filled");
126     return;
127   }
128   fGrid[istep]->Fill(var,weight);
129 }
130 //___________________________________________________________________
131 TH1D *AliCFContainer::Project(Int_t ivar, Int_t istep) const
132 {
133   //
134   // returns 1-D projection along variable ivar at selection step istep
135   //
136   if(istep >= fNStep || istep < 0){
137     AliError("Non-existent selection step, return NULL");
138     return 0x0;
139   }
140   if(ivar >= GetNVar() || ivar < 0){
141     AliError("Non-existent variable, return NULL");
142     return 0x0;
143   }
144
145   return fGrid[istep]->Project(ivar);
146 }
147 //___________________________________________________________________
148 TH2D *AliCFContainer::Project(Int_t ivar1, Int_t ivar2, Int_t istep) const
149 {
150   //
151   // returns 2-D projection along variables ivar1,ivar2 at selection step istep
152   //
153   if(istep >= fNStep || istep < 0){
154     AliError("Non-existent selection step, return NULL");
155     return 0x0;
156   }
157   if(ivar1 >= GetNVar() || ivar1 < 0 || ivar2 >= GetNVar() || ivar2 < 0){
158     AliError("Non-existent variable, return NULL");
159     return 0x0;
160   }
161
162   return fGrid[istep]->Project(ivar1,ivar2);
163 }
164 //___________________________________________________________________
165 TH3D *AliCFContainer::Project(Int_t ivar1, Int_t ivar2, Int_t ivar3, Int_t istep) const
166 {
167   //
168   // returns 3-D projection along variables ivar1,ivar2,ivar3 
169   // at selection step istep
170   //
171   if(istep >= fNStep || istep < 0){
172     AliError("Non-existent selection step, return NULL");
173     return 0x0;
174   }
175   if(ivar1 >= GetNVar() || ivar1 < 0 || 
176      ivar2 >= GetNVar() || ivar2 < 0 ||
177      ivar3 >= GetNVar() || ivar3 < 0 ) {
178     AliError("Non-existent variable, return NULL");
179     return 0x0;
180   }
181
182   return fGrid[istep]->Project(ivar1,ivar2,ivar3);
183 }
184 //___________________________________________________________________
185 TH1D *AliCFContainer::ShowSlice(Int_t ivar, const Double_t *varMin, const Double_t* varMax, Int_t istep, Bool_t useBins) const
186 {
187   //
188   // Make a slice along variable ivar at selection level istep in range [varMin,varMax]
189   // If useBins=true, varMin and varMax are taken as bin numbers
190   //
191   if(istep >= fNStep || istep < 0){
192     AliError("Non-existent selection step, return NULL");
193     return 0x0;
194   }
195   if (ivar >= GetNVar() || ivar < 0) {
196     AliError("Non-existent variable, return NULL");
197     return 0x0;
198   }
199   return (TH1D*)fGrid[istep]->Slice(ivar,varMin,varMax,useBins);
200 }
201 //___________________________________________________________________
202 TH2D *AliCFContainer::ShowSlice(Int_t ivar1, Int_t ivar2, const Double_t *varMin, const Double_t* varMax, Int_t istep, Bool_t useBins) const
203 {
204   //
205   // Make a slice along variables ivar1 and ivar2 at selection level istep in range [varMin,varMax]
206   // If useBins=true, varMin and varMax are taken as bin numbers
207   //
208   if(istep >= fNStep || istep < 0){
209     AliError("Non-existent selection step, return NULL");
210     return 0x0;
211   }
212   if (ivar1 >= GetNVar() || ivar1 < 0 || ivar2 >= GetNVar() || ivar2 < 0) {
213     AliError("Non-existent variable, return NULL");
214     return 0x0;
215   }
216   return (TH2D*)fGrid[istep]->Slice(ivar1,ivar2,varMin,varMax,useBins);
217 }
218 //___________________________________________________________________
219 TH3D *AliCFContainer::ShowSlice(Int_t ivar1, Int_t ivar2, Int_t ivar3, const Double_t *varMin, const Double_t* varMax, Int_t istep, Bool_t useBins) const
220 {
221   //
222   // Make a slice along variables ivar1, ivar2and ivar3 at selection level istep in range [varMin,varMax]
223   // If useBins=true, varMin and varMax are taken as bin numbers
224   //
225   if(istep >= fNStep || istep < 0){
226     AliError("Non-existent selection step, return NULL");
227     return 0x0;
228   }
229   if (ivar1 >= GetNVar() || ivar1 < 0 || ivar2 >= GetNVar() || ivar2 < 0 || ivar3 >= GetNVar() || ivar3 < 0) {
230     AliError("Non-existent variable, return NULL");
231     return 0x0;
232   }
233   return (TH3D*)fGrid[istep]->Slice(ivar1,ivar2,ivar3,varMin,varMax,useBins);
234 }
235 //____________________________________________________________________
236 AliCFContainer* AliCFContainer::MakeSlice(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax, Bool_t useBins) const
237 {
238   //
239   // Makes a slice along the "nVars" variables defined in the array "vars[nVars]" for all the container steps.
240   // The ranges of ALL the container variables must be defined in the array varMin[GetNVar()] and varMax[GetNVar()]
241   // The function returns a new container of nVars variables.
242   // If useBins=true, varMin and varMax are taken as bin numbers
243   //
244   Int_t* steps = new Int_t[fNStep];
245   for (Int_t iStep=0;iStep<fNStep;iStep++) steps[iStep]=iStep;
246   AliCFContainer* out = MakeSlice(nVars,vars,varMin,varMax,fNStep,steps,useBins);
247   delete [] steps ;
248   return out;
249 }
250
251 //____________________________________________________________________
252 AliCFContainer* AliCFContainer::MakeSlice(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax, Int_t nSteps, const Int_t* steps, Bool_t useBins) const
253 {
254   //
255   // Makes a slice along the "nVars" variables defined in the array "vars[nVars]" for the given "nSteps" defined in "steps[nSteps]".
256   // The ranges of ALL the container variables must be defined in the array varMin[GetNVar()] and varMax[GetNVar()]
257   // The function returns a new container of nVars variables.
258   // If useBins=true, varMin and varMax are taken as bin numbers
259   //
260
261   if (nVars < 1 || nVars > GetNVar())   AliError("Bad number of dimensions required for the slice");
262   if (nSteps< 1 || nSteps> fNStep)  AliError("Bad number of steps required for the slice");
263
264   AliInfo(Form("Making a slice in %d dimension(s)",nVars));
265
266   // create the output grids
267   AliCFGridSparse** grids = new AliCFGridSparse*[nSteps] ;
268   for (Int_t iStep=0; iStep<nSteps; iStep++) grids[iStep] = fGrid[steps[iStep]]->Project(nVars,vars,varMin,varMax,useBins);
269   
270   TAxis ** axis = new TAxis*[nVars];
271   for (Int_t iVar=0; iVar<nVars; iVar++) axis[iVar] = ((AliCFGridSparse*)grids[0])->GetGrid()->GetAxis(iVar); //same axis for every grid
272
273   //define new binning for new container
274   Int_t* bins=new Int_t[nVars];
275   for (Int_t iVar=0; iVar<nVars; iVar++) bins[iVar] = axis[iVar]->GetNbins();
276
277   AliCFContainer* out = new AliCFContainer(fName,fTitle,nSteps,nVars,bins);
278
279   //set the bin limits
280   for (Int_t iVar=0; iVar<nVars; iVar++) {
281     Int_t nBins = bins[iVar];
282     Double_t *array = new Double_t[nBins+1];
283     for (Int_t iBin=1; iBin<=nBins; iBin++) {
284       array[iBin-1] = axis[iVar]->GetBinLowEdge(iBin);
285     }
286     array[nBins] = axis[iVar]->GetBinUpEdge(nBins);
287     out->SetBinLimits(iVar,array);
288     delete [] array;
289   }
290
291   //set grid for the given steps
292   for (Int_t iStep=0; iStep<nSteps; iStep++) out->SetGrid(iStep,grids[iStep]);
293
294   delete [] bins;
295   delete [] axis ;
296   return out;
297 }
298
299 //____________________________________________________________________
300 Long64_t AliCFContainer::Merge(TCollection* list)
301 {
302   // Merge a list of AliCorrection objects with this (needed for
303   // PROOF). 
304   // Returns the number of merged objects (including this).
305
306   if (!list)
307     return 0;
308   
309   if (list->IsEmpty())
310     return 1;
311
312   TIterator* iter = list->MakeIterator();
313   TObject* obj;
314   
315   Int_t count = 0;
316   while ((obj = iter->Next())) {
317     AliCFContainer* entry = dynamic_cast<AliCFContainer*> (obj);
318     if (entry == 0) 
319       continue;
320     this->Add(entry);
321     count++;
322   }
323
324   return count+1;
325 }
326
327 //____________________________________________________________________
328 void AliCFContainer::Add(const AliCFContainer* aContainerToAdd, Double_t c)
329 {
330   //
331   //add the content of container aContainerToAdd to the current one
332   //
333   if ((aContainerToAdd->GetNStep()      != fNStep)          ||
334       (aContainerToAdd->GetNVar()       != GetNVar())       ||
335       (aContainerToAdd->GetNBinsTotal() != GetNBinsTotal()))
336     {
337       AliError("Different number of steps/sensitive variables/grid elements: cannot add the containers");
338       return;
339     }
340   for (Int_t istep=0; istep<fNStep; istep++) {
341     fGrid[istep]->Add(aContainerToAdd->GetGrid(istep),c);
342   }
343 }
344 //____________________________________________________________________
345 Float_t AliCFContainer::GetOverFlows( Int_t ivar, Int_t istep, Bool_t exclusive) const {
346   //
347   // Get overflows in variable var at selection level istep
348   // Set 'exclusive' to true for an exclusive check on variable ivar
349   //
350   if(istep >= fNStep || istep < 0){
351     AliError("Non-existent selection step, return -1");
352     return -1.;
353   }
354   return fGrid[istep]->GetOverFlows(ivar,exclusive);
355
356 //____________________________________________________________________
357 Float_t AliCFContainer::GetUnderFlows( Int_t ivar, Int_t istep, Bool_t exclusive) const {
358   //
359   // Get underflows in variable var at selection level istep
360   // Set 'exclusive' to true for an exclusive check on variable ivar
361   //
362   if(istep >= fNStep || istep < 0){
363     AliError("Non-existent selection step, return -1");
364     return -1.;
365   }
366   return fGrid[istep]->GetUnderFlows(ivar,exclusive);
367
368 //____________________________________________________________________
369 Float_t AliCFContainer::GetEntries(Int_t istep) const {
370   //
371   // Get total entries in variable var at selection level istep
372   //
373   if(istep >= fNStep || istep < 0){
374     AliError("Non-existent selection step, return -1");
375     return -1.;
376   }
377   return fGrid[istep]->GetEntries();
378
379 // //____________________________________________________________________
380 // Int_t AliCFContainer::GetEmptyBins(Int_t istep) const {
381 //   //
382 //   // Get empty bins in variable var at selection level istep
383 //   //
384 //   if(istep >= fNStep || istep < 0){
385 //     AliError("Non-existent selection step, return -1");
386 //     return -1;
387 //   }
388 //   return fGrid[istep]->GetEmptyBins();
389 // } 
390 // //____________________________________________________________________
391 // Int_t AliCFContainer::GetEmptyBins( Int_t istep, Double_t *varMin, Double_t* varMax) const {
392 //   //
393 //   // Get empty bins in a range in variable var at selection level istep
394 //   //
395 //   if(istep >= fNStep || istep < 0){
396 //     AliError("Non-existent selection step, return -1");
397 //     return -1;
398 //   }
399 //   return fGrid[istep]->GetEmptyBins(varMin,varMax);
400 // } 
401 //_____________________________________________________________________
402 Double_t AliCFContainer::GetIntegral( Int_t istep) const 
403 {
404   //
405   // Get Integral over the grid at selection level istep
406   //
407   if(istep >= fNStep || istep < 0){
408     AliError("Non-existent selection step, return -1");
409     return -1.;
410   }
411   return fGrid[istep]->GetIntegral();
412 }
413 //_____________________________________________________________________
414 // Double_t AliCFContainer::GetIntegral( Int_t istep, Double_t *varMin, Double_t* varMax ) const 
415 // {
416 //   //
417 //   // Get Integral over the grid in a range at selection level istep
418 //   //
419 //   if(istep >= fNStep || istep < 0){
420 //     AliError("Non-existent selection step, return -1");
421 //     return -1.;
422 //   }
423 //   return fGrid[istep]->GetIntegral(varMin,varMax);
424 // }
425 //_____________________________________________________________________
426 void AliCFContainer::SetRangeUser(Int_t ivar, Double_t varMin, Double_t varMax, Int_t istep) 
427 {
428   //
429   // set axis range at step istep
430   //
431   if (istep >= fNStep || istep < 0){
432     AliError("Non-existent selection step");
433     return ;
434   }
435   if (ivar >= GetNVar() || ivar < 0){
436     AliError("Non-existent selection var");
437     return ;
438   }
439   fGrid[istep]->SetRangeUser(ivar,varMin,varMax);
440 }
441
442 //_____________________________________________________________________
443 void AliCFContainer::SetRangeUser(Double_t* varMin, Double_t* varMax, Int_t istep) 
444 {
445   //
446   // set all axis ranges at step istep according to varMin and varMax values
447   //
448   if (istep >= fNStep || istep < 0){
449     AliError("Non-existent selection step");
450     return ;
451   }
452   ((AliCFGridSparse*)fGrid[istep])->SetRangeUser(varMin,varMax);
453 }
454
455 //_____________________________________________________________________
456 void AliCFContainer::Print(const Option_t*) const {
457   AliInfo("====================================================================================");
458   AliInfo(Form("AliCFContainer : name = %s   title = %s",GetName(),GetTitle()));
459   AliInfo(Form("number of steps \t %d",GetNStep()));
460   for (Int_t iStep=0;iStep<GetNStep();iStep++) AliInfo(Form("step %d \t -> %s",iStep,GetStepTitle(iStep)));
461   AliInfo(Form("number of variables \t %d",GetNVar()));
462   for (Int_t iVar=0;iVar<GetNVar();iVar++) {
463     Double_t *binLimits = new Double_t[GetNBins(iVar)+1];
464     GetBinLimits(iVar,binLimits);
465     AliInfo(Form("variable %d \t -> %s : %d bins in [%f,%f]",iVar,GetVarTitle(iVar),GetNBins(iVar),binLimits[0],binLimits[GetNBins(iVar)]));
466     delete binLimits;
467   }
468   AliInfo("====================================================================================");
469 }