extended by cuts on min / max absolute and relative impact parameter
[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 "AliCFGrid.h"
29 #include "AliCFGridSparse.h"
30 #include "AliCFContainer.h"
31 #include "TAxis.h"
32 //____________________________________________________________________
33 ClassImp(AliCFContainer)
34
35 //____________________________________________________________________
36 AliCFContainer::AliCFContainer() : 
37   AliCFFrame(),
38   fNStep(0),
39   fGrid(0x0)
40 {
41   //
42   // default constructor
43   //
44 }
45 //____________________________________________________________________
46 AliCFContainer::AliCFContainer(const Char_t* name, const Char_t* title) : 
47   AliCFFrame(name,title),
48   fNStep(0),
49   fGrid(0x0)
50 {
51   // default constructor
52 }
53
54 //____________________________________________________________________
55 AliCFContainer::AliCFContainer(const Char_t* name, const Char_t* title,const Int_t nSelSteps, const Int_t nVarIn, const Int_t * nBinIn, const Double_t *binLimitsIn, const Bool_t useSparse) :  
56   AliCFFrame(name,title,nVarIn,nBinIn,binLimitsIn),
57   fNStep(0),
58   fGrid(0x0)
59 {
60   //
61   // main constructor
62   //
63
64   // The selection steps
65   fNStep=nSelSteps;
66
67   // The grids 
68   fGrid = new AliCFVGrid*[fNStep]; //the grids at the various selection steps
69   char gname[30];
70   for(Int_t istep=0;istep<fNStep;istep++){
71     sprintf(gname,"%s%s%i",GetName(),"_SelStep", istep);
72     if(!useSparse){
73       fGrid[istep] = new AliCFGrid(gname,title,nVarIn,nBinIn,binLimitsIn); 
74       }
75     else{
76       fGrid[istep] = new AliCFGridSparse(gname,title,nVarIn,nBinIn,binLimitsIn); 
77     }
78     fGrid[istep]->SumW2(); 
79   }
80 }
81 //____________________________________________________________________
82 AliCFContainer::AliCFContainer(const AliCFContainer& c) : 
83   AliCFFrame(),
84   fNStep(c.fNStep),
85   fGrid(c.fGrid)
86 {
87   //
88   // copy constructor
89   //
90   ((AliCFContainer &)c).Copy(*this);
91 }
92 //____________________________________________________________________
93 AliCFContainer::~AliCFContainer()
94 {
95   //
96   // destructor
97   //
98   if(fGrid)delete [] fGrid;
99
100 }
101 //____________________________________________________________________
102 AliCFContainer &AliCFContainer::operator=(const AliCFContainer &c)
103 {
104   //
105   // assigment operator
106   //
107   if (this != &c)
108     ((AliCFContainer &) c).Copy(*this);
109   return *this;
110
111 //____________________________________________________________________
112 void AliCFContainer::SetBinLimits(Int_t varindex, Double_t *array)
113 {
114   //
115   // setting the arrays containing the bin limits 
116   //
117   Int_t nbins=fNVarBins[varindex]+1;
118   for(Int_t i=0;i<nbins;i++){
119     fVarBinLimits[fOffset[varindex]+i] =array[i];
120   } 
121   for(Int_t istep=0;istep<fNStep;istep++){
122     fGrid[istep]->SetBinLimits(varindex,array);
123   }
124
125 //____________________________________________________________________
126 void AliCFContainer::Copy(TObject& c) const
127 {
128   //
129   // copy function
130   //
131   AliCFContainer& target = (AliCFContainer &) c;
132   target.fNStep=fNStep;
133   target.fNVar=fNVar;
134   target.fNDim=fNDim;
135   target.fNVarBinLimits=fNVarBinLimits;
136   if (fNVarBins)
137     target.fNVarBins = fNVarBins;
138   if (fVarBinLimits)
139     target.fVarBinLimits = fVarBinLimits;
140   if (fGrid)
141     target.fGrid = fGrid;
142     for(Int_t istep=0;istep<fNStep;istep++){
143       for(Int_t iel=0;iel<fNDim;iel++){
144         target.fGrid[istep]->SetElement(iel,fGrid[istep]->GetElement(iel));
145       } 
146     }  
147 }
148 //____________________________________________________________________
149 void AliCFContainer::Fill(Double_t *var, Int_t istep, Double_t weight)
150 {
151   //
152   // Fills the grid at selection step istep for a set of values of the 
153   // input variables, with a given weight (by default w=1)
154   //
155   if(istep >= fNStep || istep < 0){
156     AliError("Non-existent selection step, grid was not filled");
157     return;
158   }
159   fGrid[istep]->Fill(var,weight);
160 }
161 //___________________________________________________________________
162 TH1D *AliCFContainer::ShowProjection(Int_t ivar, Int_t istep) const
163 {
164   //
165   // returns 1-D projection along variable ivar at selection step istep
166   //
167   if(istep >= fNStep || istep < 0){
168     AliError("Non-existent selection step, return NULL");
169     return 0x0;
170   }
171   if(ivar >= fNVar || ivar < 0){
172     AliError("Non-existent selection step, return NULL");
173     return 0x0;
174   }
175
176   return fGrid[istep]->Project(ivar);
177 }
178 //___________________________________________________________________
179 TH2D *AliCFContainer::ShowProjection(Int_t ivar1, Int_t ivar2, Int_t istep) const
180 {
181   //
182   // returns 2-D projection along variables ivar1,ivar2 at selection step istep
183   //
184   if(istep >= fNStep || istep < 0){
185     AliError("Non-existent selection step, return NULL");
186     return 0x0;
187   }
188   if(ivar1 >= fNVar || ivar1 < 0 || ivar2 >= fNVar || ivar2 < 0){
189     AliError("Non-existent selection step, return NULL");
190     return 0x0;
191   }
192
193   return fGrid[istep]->Project(ivar1,ivar2);
194 }
195 //___________________________________________________________________
196 TH3D *AliCFContainer::ShowProjection(Int_t ivar1, Int_t ivar2, Int_t ivar3, Int_t istep) const
197 {
198   //
199   // returns 3-D projection along variables ivar1,ivar2,ivar3 
200   // at selection step istep
201   //
202   if(istep >= fNStep || istep < 0){
203     AliError("Non-existent selection step, return NULL");
204     return 0x0;
205   }
206   if(ivar1 >= fNVar || ivar1 < 0 || 
207      ivar2 >= fNVar || ivar2 < 0 ||
208      ivar3 >= fNVar || ivar3 < 0 ) {
209     AliError("Non-existent selection step, return NULL");
210     return 0x0;
211   }
212
213   return fGrid[istep]->Project(ivar1,ivar2,ivar3);
214 }
215 //___________________________________________________________________
216 TH1D *AliCFContainer::ShowSlice(Int_t ivar, Double_t *varMin, Double_t* varMax, Int_t istep) const
217 {
218   //
219   // Make a slice along variable ivar at selection level istep in range [varMin,varMax]
220   //
221   if(istep >= fNStep || istep < 0){
222     AliError("Non-existent selection step, return NULL");
223     return 0x0;
224   }
225   if (ivar >= fNVar || ivar < 0) {
226     AliError("Non-existent variable, return NULL");
227     return 0x0;
228   }
229   return (TH1D*)fGrid[istep]->Slice(ivar,varMin,varMax);
230 }
231 //___________________________________________________________________
232 TH2D *AliCFContainer::ShowSlice(Int_t ivar1, Int_t ivar2, Double_t *varMin, Double_t* varMax, Int_t istep) const
233 {
234   //
235   // Make a slice along variables ivar1 and ivar2 at selection level istep in range [varMin,varMax]
236   //
237   if(istep >= fNStep || istep < 0){
238     AliError("Non-existent selection step, return NULL");
239     return 0x0;
240   }
241   if (ivar1 >= fNVar || ivar1 < 0 || ivar2 >= fNVar || ivar2 < 0) {
242     AliError("Non-existent variable, return NULL");
243     return 0x0;
244   }
245   return (TH2D*)fGrid[istep]->Slice(ivar1,ivar2,varMin,varMax);
246 }
247 //___________________________________________________________________
248 TH3D *AliCFContainer::ShowSlice(Int_t ivar1, Int_t ivar2, Int_t ivar3, Double_t *varMin, Double_t* varMax, Int_t istep) const
249 {
250   //
251   // Make a slice along variables ivar1, ivar2and ivar3 at selection level istep in range [varMin,varMax]
252   //
253   if(istep >= fNStep || istep < 0){
254     AliError("Non-existent selection step, return NULL");
255     return 0x0;
256   }
257   if (ivar1 >= fNVar || ivar1 < 0 || ivar2 >= fNVar || ivar2 < 0 || ivar3 >= fNVar || ivar3 < 0) {
258     AliError("Non-existent variable, return NULL");
259     return 0x0;
260   }
261   return (TH3D*)fGrid[istep]->Slice(ivar1,ivar2,ivar3,varMin,varMax);
262 }
263 //____________________________________________________________________
264 AliCFContainer* AliCFContainer::MakeSlice(Int_t nVars, Int_t* vars, Double_t* varMin, Double_t* varMax) const
265 {
266   //
267   // Makes a slice along the "nVars" variables defined in the array "vars[nVars]" for all the container steps.
268   // The ranges of ALL the container variables must be defined in the array varMin[fNVar] and varMax[fNVar]
269   // The function returns a new container of nVars variables.
270   //
271   Int_t* steps = new Int_t[fNStep];
272   for (Int_t iStep=0;iStep<fNStep;iStep++) steps[iStep]=iStep;
273   return MakeSlice(nVars,vars,varMin,varMax,fNStep,steps);
274 }
275
276 //____________________________________________________________________
277 AliCFContainer* AliCFContainer::MakeSlice(Int_t nVars, Int_t* vars, Double_t* varMin, Double_t* varMax, Int_t nSteps, Int_t* steps) const
278 {
279   //
280   // Makes a slice along the "nVars" variables defined in the array "vars[nVars]" for the given "nSteps" defined in "steps[nSteps]".
281   // The ranges of ALL the container variables must be defined in the array varMin[fNVar] and varMax[fNVar]
282   // The function returns a new container of nVars variables.
283   //
284
285   if (nVars < 1 || nVars > fNVar)   AliError("Bad number of dimensions required for the slice");
286   if (nSteps< 1 || nSteps> fNStep)  AliError("Bad number of steps required for the slice");
287
288   //define new binning for new container
289   Int_t* bins=new Int_t[nVars];
290   for (Int_t iVar=0; iVar<nVars; iVar++) bins[iVar] = fNVarBins[vars[iVar]];
291   AliCFContainer* out = new AliCFContainer(fName,fTitle,nSteps,nVars,bins);
292
293   //set the bin limits
294   for (Int_t iVar=0; iVar<nVars; iVar++) {
295     Double_t *array = new Double_t[fNVarBins[vars[iVar]]+1];
296     GetBinLimits(vars[iVar],array);
297     out->SetBinLimits(iVar,array);
298     delete array;
299   }
300
301   //set grid for the given steps
302   AliInfo(Form("Making a slice in %d dimension(s)",nVars));
303   for (Int_t iStep=0; iStep<nSteps; iStep++) out->SetGrid(iStep,fGrid[steps[iStep]]->Project(nVars,vars,varMin,varMax));
304
305   delete bins;
306   return out;
307 }
308
309 //____________________________________________________________________
310 Long64_t AliCFContainer::Merge(TCollection* list)
311 {
312   // Merge a list of AliCorrection objects with this (needed for
313   // PROOF). 
314   // Returns the number of merged objects (including this).
315
316   if (!list)
317     return 0;
318   
319   if (list->IsEmpty())
320     return 1;
321
322   TIterator* iter = list->MakeIterator();
323   TObject* obj;
324   
325   Int_t count = 0;
326   while ((obj = iter->Next())) {
327     AliCFContainer* entry = dynamic_cast<AliCFContainer*> (obj);
328     if (entry == 0) 
329       continue;
330     this->Add(entry);
331     count++;
332   }
333
334   return count+1;
335 }
336
337 //____________________________________________________________________
338 void AliCFContainer::Add(AliCFContainer* aContainerToAdd, Double_t c)
339 {
340   //
341   //add the content of container aContainerToAdd to the current one
342   //
343   if( (aContainerToAdd->GetNStep()!=fNStep)
344       ||
345       (aContainerToAdd->GetNVar()!=fNVar)
346       ||
347       (aContainerToAdd->GetNDim()!=fNDim)){
348     AliError("Different number of steps/sensitive variables/grid elements: cannot add the containers");
349     return;
350   }
351   for(Int_t istep=0;istep<fNStep;istep++){
352     fGrid[istep]->Add(aContainerToAdd->GetGrid(istep),c);
353   }
354 }
355 //____________________________________________________________________
356 Float_t AliCFContainer::GetOverFlows( Int_t ivar, Int_t istep) const {
357   //
358   // Get overflows in variable var at selection level istep
359   //
360   if(istep >= fNStep || istep < 0){
361     AliError("Non-existent selection step, return -1");
362     return -1.;
363   }
364   return fGrid[istep]->GetOverFlows(ivar);
365
366 //____________________________________________________________________
367 Float_t AliCFContainer::GetUnderFlows( Int_t ivar, Int_t istep) const {
368   //
369   // Get underflows in variable var at selection level istep
370   //
371   if(istep >= fNStep || istep < 0){
372     AliError("Non-existent selection step, return -1");
373     return -1.;
374   }
375   return fGrid[istep]->GetUnderFlows(ivar);
376
377 //____________________________________________________________________
378 Float_t AliCFContainer::GetEntries( Int_t istep) const {
379   //
380   // Get total entries in variable var at selection level istep
381   //
382   if(istep >= fNStep || istep < 0){
383     AliError("Non-existent selection step, return -1");
384     return -1.;
385   }
386   return fGrid[istep]->GetEntries();
387
388 //____________________________________________________________________
389 Int_t AliCFContainer::GetEmptyBins( Int_t istep) const {
390   //
391   // Get empty bins in variable var at selection level istep
392   //
393   if(istep >= fNStep || istep < 0){
394     AliError("Non-existent selection step, return -1");
395     return -1;
396   }
397   return fGrid[istep]->GetEmptyBins();
398
399 //____________________________________________________________________
400 Int_t AliCFContainer::GetEmptyBins( Int_t istep, Double_t *varMin, Double_t* varMax) const {
401   //
402   // Get empty bins in a range in variable var at selection level istep
403   //
404   if(istep >= fNStep || istep < 0){
405     AliError("Non-existent selection step, return -1");
406     return -1;
407   }
408   return fGrid[istep]->GetEmptyBins(varMin,varMax);
409
410 //_____________________________________________________________________
411 Double_t AliCFContainer::GetIntegral( Int_t istep) const 
412 {
413   //
414   // Get Integral over the grid at selection level istep
415   //
416   if(istep >= fNStep || istep < 0){
417     AliError("Non-existent selection step, return -1");
418     return -1.;
419   }
420   return fGrid[istep]->GetIntegral();
421 }
422 //_____________________________________________________________________
423 Double_t AliCFContainer::GetIntegral( Int_t istep, Double_t *varMin, Double_t* varMax ) const 
424 {
425   //
426   // Get Integral over the grid in a range at selection level istep
427   //
428   if(istep >= fNStep || istep < 0){
429     AliError("Non-existent selection step, return -1");
430     return -1.;
431   }
432   return fGrid[istep]->GetIntegral(varMin,varMax);
433 }
434 //_____________________________________________________________________
435 void AliCFContainer::SetRangeUser(Int_t ivar, Double_t varMin, Double_t varMax, Int_t istep) 
436 {
437   //
438   // set axis range at step istep
439   //
440   if ( strcmp(fGrid[istep]->ClassName(),"AliCFGrid") ==0 ) {
441     AliWarning("Could not AliCFGrid::SetRangeUser(), function not implemented");
442     return;
443   }
444   if (istep >= fNStep || istep < 0){
445     AliError("Non-existent selection step");
446     return ;
447   }
448   if (ivar >= fNVar || ivar < 0){
449     AliError("Non-existent selection var");
450     return ;
451   }
452   ((AliCFGridSparse*)fGrid[istep])->SetRangeUser(ivar,varMin,varMax);
453 }
454
455 //_____________________________________________________________________
456 void AliCFContainer::SetRangeUser(Double_t* varMin, Double_t* varMax, Int_t istep) 
457 {
458   //
459   // set all axis ranges at step istep according to varMin and varMax values
460   //
461   if ( strcmp(fGrid[istep]->ClassName(),"AliCFGrid") ==0 ) {
462     AliWarning("Could not AliCFGrid::SetRangeUser(), function not implemented");
463     return;
464   }
465   if (istep >= fNStep || istep < 0){
466     AliError("Non-existent selection step");
467     return ;
468   }
469   ((AliCFGridSparse*)fGrid[istep])->SetRangeUser(varMin,varMax);
470 }