]> git.uio.no Git - u/mrichter/AliRoot.git/blob - CORRFW/AliCFGridSparse.cxx
added settings for magnetic field
[u/mrichter/AliRoot.git] / CORRFW / AliCFGridSparse.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15 //--------------------------------------------------------------------//
16 //                                                                    //
17 // AliCFGridSparse Class                                              //
18 // Class to accumulate data on an N-dimensional grid, to be used      //
19 // as input to get corrections for Reconstruction & Trigger efficiency// 
20 // Based on root THnSparse                                            //
21 // -- Author : S.Arcelli                                              //
22 // Still to be done:                                                  //
23 // --Interpolate among bins in a range                                // 
24 //--------------------------------------------------------------------//
25 //
26 //
27 #include "AliCFGridSparse.h"
28 #include "THnSparse.h"
29 #include "AliLog.h"
30 #include "TMath.h"
31 #include "TROOT.h"
32 #include "TH1D.h"
33 #include "TH2D.h"
34 #include "TH3D.h"
35 #include "TAxis.h"
36 #include "AliCFUnfolding.h"
37
38 //____________________________________________________________________
39 ClassImp(AliCFGridSparse)
40
41 //____________________________________________________________________
42 AliCFGridSparse::AliCFGridSparse() : 
43   AliCFFrame(),
44   fSumW2(kFALSE),
45   fData(0x0)
46 {
47   // default constructor
48 }
49 //____________________________________________________________________
50 AliCFGridSparse::AliCFGridSparse(const Char_t* name, const Char_t* title) : 
51   AliCFFrame(name,title),
52   fSumW2(kFALSE),
53   fData(0x0)
54 {
55   // default constructor
56 }
57 //____________________________________________________________________
58 AliCFGridSparse::AliCFGridSparse(const Char_t* name, const Char_t* title, Int_t nVarIn, const Int_t * nBinIn) :  
59   AliCFFrame(name,title),
60   fSumW2(kFALSE),
61   fData(0x0)
62 {
63   //
64   // main constructor
65   //
66
67   fData = new THnSparseF(name,title,nVarIn,nBinIn);
68 }
69
70 //____________________________________________________________________
71 AliCFGridSparse::~AliCFGridSparse()
72 {
73   //
74   // destructor
75   //
76   if (fData) delete fData;
77 }
78
79 //____________________________________________________________________
80 AliCFGridSparse::AliCFGridSparse(const AliCFGridSparse& c) :
81   AliCFFrame(c),
82   fSumW2(kFALSE),
83   fData(0x0)
84 {
85   //
86   // copy constructor
87   //
88   ((AliCFGridSparse &)c).Copy(*this);
89 }
90
91 //____________________________________________________________________
92 AliCFGridSparse& AliCFGridSparse::operator=(const AliCFGridSparse &c)
93 {
94   //
95   // assigment operator
96   //
97   if (this != &c) c.Copy(*this);
98   return *this;
99
100
101 //____________________________________________________________________
102 void AliCFGridSparse::SetBinLimits(Int_t ivar, Double_t min, Double_t max)
103 {
104   //
105   // set a uniform binning for variable ivar
106   //
107   Int_t nBins = GetNBins(ivar);
108   Double_t * array = new Double_t[nBins+1];
109   for (Int_t iEdge=0; iEdge<=nBins; iEdge++) array[iEdge] = min + iEdge * (max-min)/nBins ;
110   fData->SetBinEdges(ivar, array);
111   delete [] array ;
112
113
114 //____________________________________________________________________
115 void AliCFGridSparse::SetBinLimits(Int_t ivar, const Double_t *array)
116 {
117   //
118   // setting the arrays containing the bin limits 
119   //
120   fData->SetBinEdges(ivar, array);
121
122
123 //____________________________________________________________________
124 void AliCFGridSparse::Fill(const Double_t *var, Double_t weight)
125 {
126   //
127   // Fill the grid,
128   // given a set of values of the input variable, 
129   // with weight (by default w=1)
130   //
131   fData->Fill(var,weight);
132 }
133
134 //___________________________________________________________________
135 AliCFGridSparse* AliCFGridSparse::MakeSlice(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax, Bool_t useBins) const
136 {
137   //
138   // projects the grid on the nVars dimensions defined in vars.
139   // axis ranges can be defined in arrays varMin, varMax
140   // If useBins=true, varMin and varMax are taken as bin numbers
141   //
142
143   // binning for new grid
144   Int_t* bins = new Int_t[nVars];
145   for (Int_t iVar=0; iVar<nVars; iVar++) {
146     bins[iVar] = GetNBins(vars[iVar]);
147   }
148   
149   // create new grid sparse
150   AliCFGridSparse* out = new AliCFGridSparse(fName,fTitle,nVars,bins);
151
152   //set the range in the THnSparse to project
153   THnSparse* clone = ((THnSparse*)fData->Clone());
154   if (varMin && varMax) {
155     for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) {
156       SetAxisRange(clone->GetAxis(iAxis),varMin[iAxis],varMax[iAxis],useBins);
157     }
158   }
159   else AliInfo("Keeping same axis ranges");
160
161   out->SetGrid(clone->Projection(nVars,vars));
162   delete [] bins;
163   delete clone;
164   return out;
165 }
166
167
168 //____________________________________________________________________
169 Float_t AliCFGridSparse::GetBinCenter(Int_t ivar, Int_t ibin) const
170 {
171   //
172   // Returns the center of specified bin for variable axis ivar
173   // 
174   
175   return (Float_t) fData->GetAxis(ivar)->GetBinCenter(ibin);
176 }
177
178 //____________________________________________________________________
179 Float_t AliCFGridSparse::GetBinSize(Int_t ivar, Int_t ibin) const
180 {
181   //
182   // Returns the size of specified bin for variable axis ivar
183   // 
184   
185   return (Float_t) fData->GetAxis(ivar)->GetBinUpEdge(ibin) - fData->GetAxis(ivar)->GetBinLowEdge(ibin);
186 }
187
188 //____________________________________________________________________
189 Float_t AliCFGridSparse::GetEntries() const
190 {
191   //
192   // total entries (including overflows and underflows)
193   //
194
195   return fData->GetEntries();
196 }
197
198 //____________________________________________________________________
199 Float_t AliCFGridSparse::GetElement(Long_t index) const
200 {
201   //
202   // Returns content of grid element index 
203   //
204   
205   return fData->GetBinContent(index);
206 }
207 //____________________________________________________________________
208 Float_t AliCFGridSparse::GetElement(const Int_t *bin) const
209 {
210   //
211   // Get the content in a bin corresponding to a set of bin indexes
212   //
213   return fData->GetBinContent(bin);
214
215 }  
216 //____________________________________________________________________
217 Float_t AliCFGridSparse::GetElement(const Double_t *var) const
218 {
219   //
220   // Get the content in a bin corresponding to a set of input variables
221   //
222
223   Long_t index = fData->GetBin(var,kFALSE);
224   if (index<0) return 0.;
225   return fData->GetBinContent(index);
226
227
228 //____________________________________________________________________
229 Float_t AliCFGridSparse::GetElementError(Long_t index) const
230 {
231   //
232   // Returns the error on the content 
233   //
234
235   return fData->GetBinContent(index);
236 }
237 //____________________________________________________________________
238 Float_t AliCFGridSparse::GetElementError(const Int_t *bin) const
239 {
240  //
241   // Get the error in a bin corresponding to a set of bin indexes
242   //
243   return fData->GetBinError(bin);
244
245 }  
246 //____________________________________________________________________
247 Float_t AliCFGridSparse::GetElementError(const Double_t *var) const
248 {
249   //
250   // Get the error in a bin corresponding to a set of input variables
251   //
252
253   Long_t index=fData->GetBin(var,kFALSE); //this is the THnSparse index (do not allocate new cells if content is empy)
254   if (index<0) return 0.;
255   return fData->GetBinError(index);
256
257
258 //____________________________________________________________________
259 void AliCFGridSparse::SetElement(Long_t index, Float_t val)
260 {
261   //
262   // Sets grid element value
263   //
264   Int_t* bin = new Int_t[GetNVar()];
265   fData->GetBinContent(index,bin); //affects the bin coordinates
266   SetElement(bin,val);
267   delete [] bin ;
268 }
269
270 //____________________________________________________________________
271 void AliCFGridSparse::SetElement(const Int_t *bin, Float_t val)
272 {
273   //
274   // Sets grid element of bin indeces bin to val
275   //
276   fData->SetBinContent(bin,val);
277 }
278 //____________________________________________________________________
279 void AliCFGridSparse::SetElement(const Double_t *var, Float_t val) 
280 {
281   //
282   // Set the content in a bin to value val corresponding to a set of input variables
283   //
284   Long_t index=fData->GetBin(var,kTRUE); //THnSparse index: allocate the cell
285   Int_t *bin = new Int_t[GetNVar()];
286   fData->GetBinContent(index,bin); //trick to access the array of bins
287   SetElement(bin,val);
288   delete [] bin;
289 }
290
291 //____________________________________________________________________
292 void AliCFGridSparse::SetElementError(Long_t index, Float_t val)
293 {
294   //
295   // Sets grid element iel error to val (linear indexing) in AliCFFrame
296   //
297   Int_t *bin = new Int_t[GetNVar()];
298   fData->GetBinContent(index,bin);
299   SetElementError(bin,val);
300   delete [] bin;
301 }
302
303 //____________________________________________________________________
304 void AliCFGridSparse::SetElementError(const Int_t *bin, Float_t val)
305 {
306   //
307   // Sets grid element error of bin indeces bin to val
308   //
309   fData->SetBinError(bin,val);
310 }
311 //____________________________________________________________________
312 void AliCFGridSparse::SetElementError(const Double_t *var, Float_t val) 
313 {
314   //
315   // Set the error in a bin to value val corresponding to a set of input variables
316   //
317   Long_t index=fData->GetBin(var); //THnSparse index
318   Int_t *bin = new Int_t[GetNVar()];
319   fData->GetBinContent(index,bin); //trick to access the array of bins
320   SetElementError(bin,val);
321   delete [] bin;
322 }
323
324 //____________________________________________________________________
325 void AliCFGridSparse::SumW2()
326 {
327   //
328   //set calculation of the squared sum of the weighted entries
329   //
330   if(!fSumW2){
331     fData->CalculateErrors(kTRUE); 
332   }
333   fSumW2=kTRUE;
334 }
335
336 //____________________________________________________________________
337 void AliCFGridSparse::Add(const AliCFGridSparse* aGrid, Double_t c)
338 {
339   //
340   //add aGrid to the current one
341   //
342
343   if (aGrid->GetNVar() != GetNVar()){
344     AliError("Different number of variables, cannot add the grids");
345     return;
346   } 
347   
348   if (!fSumW2  && aGrid->GetSumW2()) SumW2();
349   fData->Add(aGrid->GetGrid(),c);
350 }
351
352 //____________________________________________________________________
353 void AliCFGridSparse::Add(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2)
354 {
355   //
356   //Add aGrid1 and aGrid2 and deposit the result into the current one
357   //
358
359   if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) {
360     AliInfo("Different number of variables, cannot add the grids");
361     return;
362   } 
363   
364   if (!fSumW2  && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2();
365
366   fData->Reset();
367   fData->Add(aGrid1->GetGrid(),c1);
368   fData->Add(aGrid2->GetGrid(),c2);
369 }
370
371 //____________________________________________________________________
372 void AliCFGridSparse::Multiply(const AliCFGridSparse* aGrid, Double_t c)
373 {
374   //
375   // Multiply aGrid to the current one
376   //
377
378   if (aGrid->GetNVar() != GetNVar()) {
379     AliError("Different number of variables, cannot multiply the grids");
380     return;
381   } 
382   
383   if(!fSumW2  && aGrid->GetSumW2()) SumW2();
384   THnSparse *h = aGrid->GetGrid();
385   fData->Multiply(h);
386   fData->Scale(c);
387 }
388
389 //____________________________________________________________________
390 void AliCFGridSparse::Multiply(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2)
391 {
392   //
393   //Multiply aGrid1 and aGrid2 and deposit the result into the current one
394   //
395
396   if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) {
397     AliError("Different number of variables, cannot multiply the grids");
398     return;
399   }
400   
401   if(!fSumW2  && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2();
402
403   fData->Reset();
404   THnSparse *h1 = aGrid1->GetGrid();
405   THnSparse *h2 = aGrid2->GetGrid();
406   h2->Multiply(h1);
407   h2->Scale(c1*c2);
408   fData->Add(h2);
409 }
410
411 //____________________________________________________________________
412 void AliCFGridSparse::Divide(const AliCFGridSparse* aGrid, Double_t c)
413 {
414   //
415   // Divide aGrid to the current one
416   //
417
418   if (aGrid->GetNVar() != GetNVar()) {
419     AliError("Different number of variables, cannot divide the grids");
420     return;
421   } 
422   
423   if (!fSumW2  && aGrid->GetSumW2()) SumW2();
424
425   THnSparse *h1 = aGrid->GetGrid();
426   THnSparse *h2 = (THnSparse*)fData->Clone();
427   fData->Divide(h2,h1);
428   fData->Scale(c);
429 }
430
431 //____________________________________________________________________
432 void AliCFGridSparse::Divide(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2, Option_t *option)
433 {
434   //
435   //Divide aGrid1 and aGrid2 and deposit the result into the current one
436   //binomial errors are supported
437   //
438
439   if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) {
440     AliError("Different number of variables, cannot divide the grids");
441     return;
442   } 
443   
444   if (!fSumW2  && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2();
445
446   THnSparse *h1= aGrid1->GetGrid();
447   THnSparse *h2= aGrid2->GetGrid();
448   fData->Divide(h1,h2,c1,c2,option);
449 }
450
451
452 //____________________________________________________________________
453 void AliCFGridSparse::Rebin(const Int_t* group)
454 {
455   //
456   // rebin the grid according to Rebin() as in THnSparse
457   // Please notice that the original number of bins on
458   // a given axis has to be divisible by the rebin group.
459   //
460
461   for(Int_t i=0;i<GetNVar();i++){
462     if (group[i]!=1) AliInfo(Form(" merging bins along dimension %i in groups of %i bins", i,group[i]));
463   }
464
465   THnSparse *rebinned =fData->Rebin(group);
466   fData->Reset();
467   fData = rebinned;
468 }
469 //____________________________________________________________________
470 void AliCFGridSparse::Scale(Long_t index, const Double_t *fact)
471 {
472   //
473   //scale content of a certain cell by (positive) fact (with error)
474   //
475
476   if (GetElement(index)==0 || fact[0]==0) return;
477
478   Double_t in[2], out[2];
479   in[0]=GetElement(index);
480   in[1]=GetElementError(index);
481   GetScaledValues(fact,in,out);
482   SetElement(index,out[0]);
483   if (fSumW2) SetElementError(index,out[1]);
484 }
485 //____________________________________________________________________
486 void AliCFGridSparse::Scale(const Int_t *bin, const Double_t *fact)
487 {
488   //
489   //scale content of a certain cell by (positive) fact (with error)
490   //
491   if(GetElement(bin)==0 || fact[0]==0)return;
492
493   Double_t in[2], out[2];
494   in[0]=GetElement(bin);
495   in[1]=GetElementError(bin);
496   GetScaledValues(fact,in,out);
497   SetElement(bin,out[0]);
498   if(fSumW2)SetElementError(bin,out[1]);
499   
500 }
501 //____________________________________________________________________
502 void AliCFGridSparse::Scale(const Double_t *var, const Double_t *fact) 
503 {
504   //
505   //scale content of a certain cell by (positive) fact (with error)
506   //
507   if(GetElement(var)==0 || fact[0]==0)return;
508
509   Double_t in[2], out[2];
510   in[0]=GetElement(var);
511   in[1]=GetElementError(var);
512   GetScaledValues(fact,in,out);
513   SetElement(var,out[0]);
514   if(fSumW2)SetElementError(var,out[1]);
515   
516 }
517 //____________________________________________________________________
518 void AliCFGridSparse::Scale(const Double_t* fact)
519 {
520   //
521   //scale contents of the whole grid by fact
522   //
523
524   for (Long_t iel=0; iel<GetNFilledBins(); iel++) {
525     Scale(iel,fact);
526   }
527 }
528 //____________________________________________________________________
529 Long_t AliCFGridSparse::GetEmptyBins() const {
530   //
531   // Get empty bins 
532   //
533
534   return (GetNBinsTotal() - GetNFilledBins()) ;
535
536
537 //____________________________________________________________________
538 Int_t AliCFGridSparse::CheckStats(Double_t thr) const
539 {
540   //
541   // Count the cells below a certain threshold
542   //
543   Int_t ncellsLow=0;
544   for (Int_t i=0; i<GetNBinsTotal(); i++) {
545     if (GetElement(i)<thr) ncellsLow++;
546   }
547   return ncellsLow;
548 }
549
550 //_____________________________________________________________________
551 Double_t AliCFGridSparse::GetIntegral() const 
552 {
553   //
554   // Get full Integral
555   //
556   return fData->ComputeIntegral();  
557
558
559 //____________________________________________________________________
560 Long64_t AliCFGridSparse::Merge(TCollection* list)
561 {
562   //
563   // Merge a list of AliCFGridSparse with this (needed for PROOF). 
564   // Returns the number of merged objects (including this).
565   //
566
567   if (!list)
568     return 0;
569   
570   if (list->IsEmpty())
571     return 1;
572
573   TIterator* iter = list->MakeIterator();
574   TObject* obj;
575   
576   Int_t count = 0;
577   while ((obj = iter->Next())) {
578     AliCFGridSparse* entry = dynamic_cast<AliCFGridSparse*> (obj);
579     if (entry == 0) 
580       continue;
581     this->Add(entry);
582     count++;
583   }
584
585   return count+1;
586 }
587
588 //____________________________________________________________________
589 void AliCFGridSparse::GetScaledValues(const Double_t *fact, const Double_t *in, Double_t *out) const{
590   //
591   // scale input *in and its error by (positive) fact (with error)
592   // and erite it to *out
593   //
594   out[0]=in[0]*fact[0];
595   out[1]=TMath::Sqrt(in[1]*in[1]/in[0]/in[0]
596                      +fact[1]*fact[1]/fact[0]/fact[0])*out[0];
597     
598 }
599
600 //____________________________________________________________________
601 void AliCFGridSparse::Copy(TObject& c) const
602 {
603   //
604   // copy function
605   //
606   AliCFFrame::Copy(c);
607   AliCFGridSparse& target = (AliCFGridSparse &) c;
608   target.fSumW2 = fSumW2 ;
609   if (fData) {
610     target.fData = (THnSparse*)fData->Clone();
611   }
612 }
613
614 //____________________________________________________________________
615 TH1* AliCFGridSparse::Slice(Int_t iVar1, Int_t iVar2, Int_t iVar3, const Double_t *varMin, const Double_t *varMax, Bool_t useBins) const
616 {
617   //
618   // return a slice on variables iVar1 (and optionnally iVar2 (and iVar3)) while axis ranges are defined with varMin,varMax
619   // arrays varMin and varMax contain the min and max values of each variable.
620   // therefore varMin and varMax must have their dimensions equal to GetNVar()
621   // If useBins=true, varMin and varMax are taken as bin numbers
622   // if varmin or varmax point to null, all the range is taken, including over- and underflows
623
624   THnSparse* clone = (THnSparse*)fData->Clone();
625   if (varMin != 0x0 && varMax != 0x0) {
626     for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) SetAxisRange(clone->GetAxis(iAxis),varMin[iAxis],varMax[iAxis],useBins);
627   }
628
629   TH1* projection = 0x0 ;
630   TString name,title;
631   GetProjectionName (name ,iVar1,iVar2,iVar3);
632   GetProjectionTitle(title,iVar1,iVar2,iVar3);
633
634   if (iVar3<0) {
635     if (iVar2<0) {
636       if (iVar1 >= GetNVar() || iVar1 < 0 ) {
637         AliError("Non-existent variable, return NULL");
638         return 0x0;
639       }
640       projection = (TH1D*)clone->Projection(iVar1); 
641       projection->SetTitle(Form("%s_proj-%s",GetTitle(),GetVarTitle(iVar1)));
642       for (Int_t iBin=1; iBin<=GetNBins(iVar1); iBin++) {
643         TString binLabel = GetAxis(iVar1)->GetBinLabel(iBin) ;
644         if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel);
645       }
646     }
647     else {
648       if (iVar1 >= GetNVar() || iVar1 < 0 ||
649           iVar2 >= GetNVar() || iVar2 < 0 ) {
650         AliError("Non-existent variable, return NULL");
651         return 0x0;
652       }
653       projection = (TH2D*)clone->Projection(iVar2,iVar1); 
654       for (Int_t iBin=1; iBin<=GetNBins(iVar1); iBin++) {
655         TString binLabel = GetAxis(iVar1)->GetBinLabel(iBin) ;
656         if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel);
657       }
658       for (Int_t iBin=1; iBin<=GetNBins(iVar2); iBin++) {
659         TString binLabel = GetAxis(iVar2)->GetBinLabel(iBin) ;
660         if (binLabel.CompareTo("") != 0) projection->GetYaxis()->SetBinLabel(iBin,binLabel);
661       }
662     }
663   }
664   else {
665     if (iVar1 >= GetNVar() || iVar1 < 0 ||
666         iVar2 >= GetNVar() || iVar2 < 0 ||
667         iVar3 >= GetNVar() || iVar3 < 0 ) {
668       AliError("Non-existent variable, return NULL");
669       return 0x0;
670     }
671     projection = (TH3D*)clone->Projection(iVar1,iVar2,iVar3); 
672     for (Int_t iBin=1; iBin<=GetNBins(iVar1); iBin++) {
673       TString binLabel = GetAxis(iVar1)->GetBinLabel(iBin) ;
674       if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel);
675     }
676     for (Int_t iBin=1; iBin<=GetNBins(iVar2); iBin++) {
677       TString binLabel = GetAxis(iVar2)->GetBinLabel(iBin) ;
678       if (binLabel.CompareTo("") != 0) projection->GetYaxis()->SetBinLabel(iBin,binLabel);
679     }
680     for (Int_t iBin=1; iBin<=GetNBins(iVar3); iBin++) {
681       TString binLabel = GetAxis(iVar3)->GetBinLabel(iBin) ;
682       if (binLabel.CompareTo("") != 0) projection->GetZaxis()->SetBinLabel(iBin,binLabel);
683     }
684   }
685   
686   projection->SetName (name .Data());
687   projection->SetTitle(title.Data());
688
689   delete clone;
690   return projection ;
691 }
692
693 //____________________________________________________________________
694 void AliCFGridSparse::SetAxisRange(TAxis* axis, Double_t min, Double_t max, Bool_t useBins) const {
695   //
696   // sets axis range, and forces bit TAxis::kAxisRange
697   //
698   
699   if (useBins) axis->SetRange    ((Int_t)min,(Int_t)max);
700   else         axis->SetRangeUser(       min,       max);
701   //axis->SetBit(TAxis::kAxisRange); // uncomment when ROOT TAxis is fixed
702 }
703
704 //____________________________________________________________________
705 void AliCFGridSparse::SetRangeUser(Int_t iVar, Double_t varMin, Double_t varMax, Bool_t useBins) const {
706   //
707   // set range of axis iVar. 
708   //
709   SetAxisRange(fData->GetAxis(iVar),varMin,varMax,useBins);
710   AliInfo(Form("AliCFGridSparse axis %d range has been modified",iVar));
711 }
712
713 //____________________________________________________________________
714 void AliCFGridSparse::SetRangeUser(const Double_t *varMin, const Double_t *varMax, Bool_t useBins) const {
715   //
716   // set range of every axis. varMin and varMax must be of dimension GetNVar()
717   //
718   for (Int_t iAxis=0; iAxis<GetNVar() ; iAxis++) { // set new range for every axis
719     SetRangeUser(iAxis,varMin[iAxis],varMax[iAxis], useBins);
720   }
721   AliInfo("AliCFGridSparse axes ranges have been modified");
722 }
723
724 //____________________________________________________________________
725 Float_t AliCFGridSparse::GetOverFlows(Int_t ivar, Bool_t exclusive) const
726 {
727   //
728   // Returns overflows in variable ivar
729   // Set 'exclusive' to true for an exclusive check on variable ivar
730   //
731   Int_t* bin = new Int_t[GetNVar()];
732   memset(bin, 0, sizeof(Int_t) * GetNVar());
733   Float_t ovfl=0.;
734   for (Long64_t i = 0; i < fData->GetNbins(); i++) {
735     Double_t v = fData->GetBinContent(i, bin);
736     Bool_t add=kTRUE;
737     if (exclusive) {
738       for(Int_t j=0;j<GetNVar();j++){
739         if(ivar==j)continue;
740         if((bin[j]==0) || (bin[j]==GetNBins(j)+1))add=kFALSE;
741       }
742     }
743     if(bin[ivar]==GetNBins(ivar)+1 && add) ovfl+=v;
744   }
745
746   delete[] bin;
747   return ovfl;
748 }
749
750 //____________________________________________________________________
751 Float_t AliCFGridSparse::GetUnderFlows(Int_t ivar, Bool_t exclusive) const
752 {
753   //
754   // Returns exclusive overflows in variable ivar
755   // Set 'exclusive' to true for an exclusive check on variable ivar
756   //
757   Int_t* bin = new Int_t[GetNVar()];
758   memset(bin, 0, sizeof(Int_t) * GetNVar());
759   Float_t unfl=0.;
760   for (Long64_t i = 0; i < fData->GetNbins(); i++) {
761     Double_t v = fData->GetBinContent(i, bin);
762     Bool_t add=kTRUE;
763     if (exclusive) {
764       for(Int_t j=0;j<GetNVar();j++){
765         if(ivar==j)continue;
766         if((bin[j]==0) || (bin[j]==GetNBins(j)+1))add=kFALSE;
767       }
768     }
769     if(bin[ivar]==0 && add) unfl+=v;
770   }
771
772   delete[] bin;
773   return unfl;
774 }
775
776
777 //____________________________________________________________________
778 void AliCFGridSparse::Smooth() {
779   //
780   // smoothing function: TO USE WITH CARE
781   //
782
783   AliInfo("Your GridSparse is going to be smoothed");
784   AliInfo(Form("N TOTAL  BINS : %li",GetNBinsTotal()));
785   AliInfo(Form("N FILLED BINS : %li",GetNFilledBins()));
786   AliCFUnfolding::SmoothUsingNeighbours(fData);
787 }