Coding rules
[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[30];
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, Double_t *varMin, Double_t* varMax, Int_t istep) const
186 {
187   //
188   // Make a slice along variable ivar at selection level istep in range [varMin,varMax]
189   //
190   if(istep >= fNStep || istep < 0){
191     AliError("Non-existent selection step, return NULL");
192     return 0x0;
193   }
194   if (ivar >= GetNVar() || ivar < 0) {
195     AliError("Non-existent variable, return NULL");
196     return 0x0;
197   }
198   return (TH1D*)fGrid[istep]->Slice(ivar,varMin,varMax);
199 }
200 //___________________________________________________________________
201 TH2D *AliCFContainer::ShowSlice(Int_t ivar1, Int_t ivar2, Double_t *varMin, Double_t* varMax, Int_t istep) const
202 {
203   //
204   // Make a slice along variables ivar1 and ivar2 at selection level istep in range [varMin,varMax]
205   //
206   if(istep >= fNStep || istep < 0){
207     AliError("Non-existent selection step, return NULL");
208     return 0x0;
209   }
210   if (ivar1 >= GetNVar() || ivar1 < 0 || ivar2 >= GetNVar() || ivar2 < 0) {
211     AliError("Non-existent variable, return NULL");
212     return 0x0;
213   }
214   return (TH2D*)fGrid[istep]->Slice(ivar1,ivar2,varMin,varMax);
215 }
216 //___________________________________________________________________
217 TH3D *AliCFContainer::ShowSlice(Int_t ivar1, Int_t ivar2, Int_t ivar3, Double_t *varMin, Double_t* varMax, Int_t istep) const
218 {
219   //
220   // Make a slice along variables ivar1, ivar2and ivar3 at selection level istep in range [varMin,varMax]
221   //
222   if(istep >= fNStep || istep < 0){
223     AliError("Non-existent selection step, return NULL");
224     return 0x0;
225   }
226   if (ivar1 >= GetNVar() || ivar1 < 0 || ivar2 >= GetNVar() || ivar2 < 0 || ivar3 >= GetNVar() || ivar3 < 0) {
227     AliError("Non-existent variable, return NULL");
228     return 0x0;
229   }
230   return (TH3D*)fGrid[istep]->Slice(ivar1,ivar2,ivar3,varMin,varMax);
231 }
232 //____________________________________________________________________
233 AliCFContainer* AliCFContainer::MakeSlice(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax) const
234 {
235   //
236   // Makes a slice along the "nVars" variables defined in the array "vars[nVars]" for all the container steps.
237   // The ranges of ALL the container variables must be defined in the array varMin[GetNVar()] and varMax[GetNVar()]
238   // The function returns a new container of nVars variables.
239   //
240   Int_t* steps = new Int_t[fNStep];
241   for (Int_t iStep=0;iStep<fNStep;iStep++) steps[iStep]=iStep;
242   AliCFContainer* out = MakeSlice(nVars,vars,varMin,varMax,fNStep,steps);
243   delete [] steps ;
244   return out;
245 }
246
247 //____________________________________________________________________
248 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) const
249 {
250   //
251   // Makes a slice along the "nVars" variables defined in the array "vars[nVars]" for the given "nSteps" defined in "steps[nSteps]".
252   // The ranges of ALL the container variables must be defined in the array varMin[GetNVar()] and varMax[GetNVar()]
253   // The function returns a new container of nVars variables.
254   //
255
256   if (nVars < 1 || nVars > GetNVar())   AliError("Bad number of dimensions required for the slice");
257   if (nSteps< 1 || nSteps> fNStep)  AliError("Bad number of steps required for the slice");
258
259   AliInfo(Form("Making a slice in %d dimension(s)",nVars));
260
261   // create the output grids
262   AliCFGridSparse** grids = new AliCFGridSparse*[nSteps] ;
263   for (Int_t iStep=0; iStep<nSteps; iStep++) grids[iStep] = fGrid[steps[iStep]]->Project(nVars,vars,varMin,varMax);
264   
265   TAxis ** axis = new TAxis*[nVars];
266   for (Int_t iVar=0; iVar<nVars; iVar++) axis[iVar] = ((AliCFGridSparse*)grids[0])->GetGrid()->GetAxis(iVar); //same axis for every grid
267
268   //define new binning for new container
269   Int_t* bins=new Int_t[nVars];
270   for (Int_t iVar=0; iVar<nVars; iVar++) bins[iVar] = axis[iVar]->GetNbins();
271
272   AliCFContainer* out = new AliCFContainer(fName,fTitle,nSteps,nVars,bins);
273
274   //set the bin limits
275   for (Int_t iVar=0; iVar<nVars; iVar++) {
276     Int_t nBins = bins[iVar];
277     Double_t *array = new Double_t[nBins+1];
278     for (Int_t iBin=1; iBin<=nBins; iBin++) {
279       array[iBin-1] = axis[iVar]->GetBinLowEdge(iBin);
280     }
281     array[nBins] = axis[iVar]->GetBinUpEdge(nBins);
282     out->SetBinLimits(iVar,array);
283     delete [] array;
284   }
285
286   //set grid for the given steps
287   for (Int_t iStep=0; iStep<nSteps; iStep++) out->SetGrid(iStep,grids[iStep]);
288
289   delete bins;
290   delete [] axis ;
291   return out;
292 }
293
294 //____________________________________________________________________
295 Long64_t AliCFContainer::Merge(TCollection* list)
296 {
297   // Merge a list of AliCorrection objects with this (needed for
298   // PROOF). 
299   // Returns the number of merged objects (including this).
300
301   if (!list)
302     return 0;
303   
304   if (list->IsEmpty())
305     return 1;
306
307   TIterator* iter = list->MakeIterator();
308   TObject* obj;
309   
310   Int_t count = 0;
311   while ((obj = iter->Next())) {
312     AliCFContainer* entry = dynamic_cast<AliCFContainer*> (obj);
313     if (entry == 0) 
314       continue;
315     this->Add(entry);
316     count++;
317   }
318
319   return count+1;
320 }
321
322 //____________________________________________________________________
323 void AliCFContainer::Add(const AliCFContainer* aContainerToAdd, Double_t c)
324 {
325   //
326   //add the content of container aContainerToAdd to the current one
327   //
328   if ((aContainerToAdd->GetNStep()      != fNStep)          ||
329       (aContainerToAdd->GetNVar()       != GetNVar())       ||
330       (aContainerToAdd->GetNBinsTotal() != GetNBinsTotal()))
331     {
332       AliError("Different number of steps/sensitive variables/grid elements: cannot add the containers");
333       return;
334     }
335   for (Int_t istep=0; istep<fNStep; istep++) {
336     fGrid[istep]->Add(aContainerToAdd->GetGrid(istep),c);
337   }
338 }
339 //____________________________________________________________________
340 Float_t AliCFContainer::GetOverFlows( Int_t ivar, Int_t istep, Bool_t exclusive) const {
341   //
342   // Get overflows in variable var at selection level istep
343   // Set 'exclusive' to true for an exclusive check on variable ivar
344   //
345   if(istep >= fNStep || istep < 0){
346     AliError("Non-existent selection step, return -1");
347     return -1.;
348   }
349   return fGrid[istep]->GetOverFlows(ivar,exclusive);
350
351 //____________________________________________________________________
352 Float_t AliCFContainer::GetUnderFlows( Int_t ivar, Int_t istep, Bool_t exclusive) const {
353   //
354   // Get underflows in variable var at selection level istep
355   // Set 'exclusive' to true for an exclusive check on variable ivar
356   //
357   if(istep >= fNStep || istep < 0){
358     AliError("Non-existent selection step, return -1");
359     return -1.;
360   }
361   return fGrid[istep]->GetUnderFlows(ivar,exclusive);
362
363 //____________________________________________________________________
364 Float_t AliCFContainer::GetEntries(Int_t istep) const {
365   //
366   // Get total entries in variable var at selection level istep
367   //
368   if(istep >= fNStep || istep < 0){
369     AliError("Non-existent selection step, return -1");
370     return -1.;
371   }
372   return fGrid[istep]->GetEntries();
373
374 // //____________________________________________________________________
375 // Int_t AliCFContainer::GetEmptyBins(Int_t istep) const {
376 //   //
377 //   // Get empty bins in variable var at selection level istep
378 //   //
379 //   if(istep >= fNStep || istep < 0){
380 //     AliError("Non-existent selection step, return -1");
381 //     return -1;
382 //   }
383 //   return fGrid[istep]->GetEmptyBins();
384 // } 
385 // //____________________________________________________________________
386 // Int_t AliCFContainer::GetEmptyBins( Int_t istep, Double_t *varMin, Double_t* varMax) const {
387 //   //
388 //   // Get empty bins in a range in variable var at selection level istep
389 //   //
390 //   if(istep >= fNStep || istep < 0){
391 //     AliError("Non-existent selection step, return -1");
392 //     return -1;
393 //   }
394 //   return fGrid[istep]->GetEmptyBins(varMin,varMax);
395 // } 
396 //_____________________________________________________________________
397 Double_t AliCFContainer::GetIntegral( Int_t istep) const 
398 {
399   //
400   // Get Integral over the grid at selection level istep
401   //
402   if(istep >= fNStep || istep < 0){
403     AliError("Non-existent selection step, return -1");
404     return -1.;
405   }
406   return fGrid[istep]->GetIntegral();
407 }
408 //_____________________________________________________________________
409 // Double_t AliCFContainer::GetIntegral( Int_t istep, Double_t *varMin, Double_t* varMax ) const 
410 // {
411 //   //
412 //   // Get Integral over the grid in a range at selection level istep
413 //   //
414 //   if(istep >= fNStep || istep < 0){
415 //     AliError("Non-existent selection step, return -1");
416 //     return -1.;
417 //   }
418 //   return fGrid[istep]->GetIntegral(varMin,varMax);
419 // }
420 //_____________________________________________________________________
421 void AliCFContainer::SetRangeUser(Int_t ivar, Double_t varMin, Double_t varMax, Int_t istep) 
422 {
423   //
424   // set axis range at step istep
425   //
426   if (istep >= fNStep || istep < 0){
427     AliError("Non-existent selection step");
428     return ;
429   }
430   if (ivar >= GetNVar() || ivar < 0){
431     AliError("Non-existent selection var");
432     return ;
433   }
434   fGrid[istep]->SetRangeUser(ivar,varMin,varMax);
435 }
436
437 //_____________________________________________________________________
438 void AliCFContainer::SetRangeUser(Double_t* varMin, Double_t* varMax, Int_t istep) 
439 {
440   //
441   // set all axis ranges at step istep according to varMin and varMax values
442   //
443   if (istep >= fNStep || istep < 0){
444     AliError("Non-existent selection step");
445     return ;
446   }
447   ((AliCFGridSparse*)fGrid[istep])->SetRangeUser(varMin,varMax);
448 }