dd984b914d88e03c9bd3c482b8f6b11c22182324
[u/mrichter/AliRoot.git] / CORRFW / AliCFVGrid.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 // AliCFVGrid Class                                                   //
18 // Just an interface to handle both AliCFGrid and AliCFGridSparse     //
19 // implementations                                                    //
20 //                                                                    //
21 // -- Author : S.Arcelli                                              //
22 //--------------------------------------------------------------------//
23 //
24 //
25 #include "AliCFVGrid.h"
26 #include "TMath.h"
27 #include <AliLog.h>
28
29 //____________________________________________________________________
30 ClassImp(AliCFVGrid)
31
32 //____________________________________________________________________
33 AliCFVGrid::AliCFVGrid() : 
34   AliCFFrame(),
35   fSumW2(kFALSE)
36 {
37   // default constructor
38 }
39 //____________________________________________________________________
40 AliCFVGrid::AliCFVGrid(const Char_t* name, const Char_t* title) : 
41   AliCFFrame(name,title),
42   fSumW2(kFALSE)
43 {
44   // default constructor
45 }
46
47 //____________________________________________________________________
48 AliCFVGrid::AliCFVGrid(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t * nBinIn, const Double_t *binLimitsIn) :  
49   AliCFFrame(name,title,nVarIn,nBinIn,binLimitsIn),
50   fSumW2(kFALSE)
51 {
52   //
53   // main constructor
54   //
55
56 }
57
58 //____________________________________________________________________
59 AliCFVGrid::AliCFVGrid(const AliCFVGrid& c) : 
60   AliCFFrame(c),
61   fSumW2(c.fSumW2)
62 {
63   //
64   // copy constructor
65   //
66  ((AliCFVGrid &)c).Copy(*this);
67
68 }
69 //____________________________________________________________________
70 AliCFVGrid::~AliCFVGrid()
71 {
72   //
73   // destructor
74   //
75 }
76
77 //____________________________________________________________________
78 AliCFVGrid &AliCFVGrid::operator=(const AliCFVGrid &c)
79 {
80   //
81   // assigment operator
82   //
83   if (this != &c)
84     AliCFFrame::operator=(c);
85   return *this;
86
87
88 //____________________________________________________________________
89 void AliCFVGrid::Copy(TObject& c) const
90 {
91   //
92   // copy function
93   //
94   AliCFVGrid& target = (AliCFVGrid &) c;
95
96   target.fSumW2=fSumW2;
97 }
98
99 //____________________________________________________________________
100 void AliCFVGrid::Scale(Int_t index, Double_t *fact)
101 {
102   //
103   //scale content of a certain cell by (positive) fact (with error)
104   //
105   if(GetElement(index)==0 || fact[0]==0)return;
106
107   Double_t in[2], out[2];
108   in[0]=GetElement(index);
109   in[1]=GetElementError(index);
110   GetScaledValues(fact,in,out);
111   SetElement(index,out[0]);
112   if(fSumW2)SetElementError(index,out[1]);
113 }
114 //____________________________________________________________________
115 void AliCFVGrid::Scale(Int_t *bin, Double_t *fact)
116 {
117   //
118   //scale content of a certain cell by (positive) fact (with error)
119   //
120   if(GetElement(bin)==0 || fact[0]==0)return;
121
122   Double_t in[2], out[2];
123   in[0]=GetElement(bin);
124   in[1]=GetElementError(bin);
125   GetScaledValues(fact,in,out);
126   SetElement(bin,out[0]);
127   if(fSumW2)SetElementError(bin,out[1]);
128   
129 }
130 //____________________________________________________________________
131 void AliCFVGrid::Scale(Double_t *var, Double_t *fact) 
132 {
133   //
134   //scale content of a certain cell by (positive) fact (with error)
135   //
136   if(GetElement(var)==0 || fact[0]==0)return;
137
138   Double_t in[2], out[2];
139   in[0]=GetElement(var);
140   in[1]=GetElementError(var);
141   GetScaledValues(fact,in,out);
142   SetElement(var,out[0]);
143   if(fSumW2)SetElementError(var,out[1]);
144   
145 }
146 //____________________________________________________________________
147 void AliCFVGrid::Scale( Double_t *fact) 
148 {
149   //
150   //scale contents of the whole grid by fact
151   //
152
153   for(Int_t iel=0;iel<fNDim;iel++){
154     Scale(iel,fact);
155   }
156 }
157
158 //____________________________________________________________________
159 Int_t AliCFVGrid::GetEmptyBins() const {
160   //
161   // Get empty bins 
162   //
163   Int_t val=0;
164   for(Int_t i=0;i<fNDim;i++){
165     if(GetElement(i)<=0)val++;     
166   }
167   return val;
168
169 //_____________________________________________________________________
170 Int_t AliCFVGrid::GetEmptyBins( Double_t *varMin, Double_t* varMax ) const 
171 {
172   //
173   // Get empty bins in a range
174   //
175
176   Int_t *indexMin=new Int_t[fNVar];
177   Int_t *indexMax=new Int_t[fNVar];
178
179   //Find out the min and max bins
180
181   for(Int_t i=0;i<fNVar;i++){
182     Double_t xmin=varMin[i]; // the min values  
183     Double_t xmax=varMax[i]; // the min values  
184     Int_t nbins=fNVarBins[i]+1;
185     Double_t *bins=new Double_t[nbins];
186     for(Int_t ibin =0;ibin<nbins;ibin++){
187      bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
188     }
189     indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
190     indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
191     delete [] bins;
192   }
193
194   Int_t val=0;
195   for(Int_t i=0;i<fNDim;i++){
196     for (Int_t j=0;j<fNVar;j++)fIndex[j]=GetBinIndex(j,i);
197     Bool_t isIn=kTRUE;
198     for (Int_t j=0;j<fNVar;j++){
199       if(!(fIndex[j]>=indexMin[j] && fIndex[j]<=indexMax[j]))isIn=kFALSE;   
200     }
201     if(isIn && GetElement(i)<=0)val++;     
202   }
203   AliInfo(Form(" the empty bins = %i ",val)); 
204
205   delete [] indexMin;
206   delete [] indexMax;
207   return val;
208
209 //____________________________________________________________________
210 Int_t AliCFVGrid::CheckStats(Double_t thr) const
211 {
212   //
213   // Count the cells below a certain threshold
214   //
215   Int_t ncellsLow=0;
216   for(Int_t i=0;i<fNDim;i++){
217     if(GetElement(i)<thr)ncellsLow++;
218   }
219   return ncellsLow;
220 }
221 //_____________________________________________________________________
222 Double_t AliCFVGrid::GetIntegral() const 
223 {
224   //
225   // Get full Integral
226   //
227   Double_t val=0;
228   for(Int_t i=0;i<fNDim;i++){
229     val+=GetElement(i);     
230   }
231   return val;  
232
233 //_____________________________________________________________________
234 Double_t AliCFVGrid::GetIntegral(Int_t *binMin, Int_t* binMax ) const 
235 {
236   //
237   // Get Integral in a range of bin indeces (extremes included)
238   //
239
240   Double_t val=0;
241
242   for(Int_t i=0;i<fNVar;i++){
243     if(binMin[i]<1)binMin[i]=1;
244     if(binMax[i]>fNVarBins[i])binMax[i]=fNVarBins[i];
245     if((binMin[i]>binMax[i])){
246       AliInfo(Form(" Bin indeces in variable %i in reverse order, please check!", i));
247       return val;
248     }
249   }
250   val=GetSum(0,binMin,binMax);
251
252   return val;
253
254
255 //_____________________________________________________________________
256 Double_t AliCFVGrid::GetIntegral(Double_t *varMin, Double_t* varMax ) const 
257 {
258   //
259   // Get Integral in a range (extremes included)
260   //
261
262   Int_t *indexMin=new Int_t[fNVar];
263   Int_t *indexMax=new Int_t[fNVar];
264
265   //Find out the min and max bins
266
267   for(Int_t i=0;i<fNVar;i++){
268     Double_t xmin=varMin[i]; // the min values  
269     Double_t xmax=varMax[i]; // the min values  
270     Int_t nbins=fNVarBins[i]+1;
271     Double_t *bins=new Double_t[nbins];
272     for(Int_t ibin =0;ibin<nbins;ibin++){
273      bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
274     }
275     indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
276     indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
277     delete [] bins;
278   }
279
280   //move to the TH/THnSparse convention in N-dim bin numbering 
281   for(Int_t i=0;i<fNVar;i++){
282     indexMin[i]+=1;
283     indexMax[i]+=1;
284   }
285
286   Double_t val=GetIntegral(indexMin,indexMax);
287
288   delete [] indexMin;
289   delete [] indexMax;
290
291   return val;
292
293
294 //_____________________________________________________________________
295 Double_t AliCFVGrid::GetSum(Int_t ivar, Int_t *binMin, Int_t* binMax) const 
296 {
297   //
298   // recursively add over nested loops.... 
299   //
300   static Double_t val;
301   if(ivar==0)val=0.;
302   for(Int_t ibin=binMin[ivar]-1;ibin<=binMax[ivar]-1;ibin++){
303   //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
304     fIndex[ivar]=ibin;
305     if(ivar<fNVar-1) {
306       val=GetSum(ivar+1,binMin,binMax);
307     }
308     else {
309       Int_t iel=GetBinIndex(fIndex);
310       val+=GetElement(iel);
311     }
312   }
313
314   return val;
315 }
316
317 //____________________________________________________________________
318 Long64_t AliCFVGrid::Merge(TCollection* list)
319 {
320   // Merge a list of AliCF grids with this (needed for
321   // PROOF). 
322   // Returns the number of merged objects (including this).
323
324   if (!list)
325     return 0;
326   
327   if (list->IsEmpty())
328     return 1;
329
330   TIterator* iter = list->MakeIterator();
331   TObject* obj;
332   
333   Int_t count = 0;
334   while ((obj = iter->Next())) {
335     AliCFVGrid* entry = dynamic_cast<AliCFVGrid*> (obj);
336     if (entry == 0) 
337       continue;
338     this->Add(entry);
339     count++;
340   }
341
342   return count+1;
343 }
344
345 //____________________________________________________________________
346 void AliCFVGrid::GetScaledValues(Double_t *fact, Double_t *in, Double_t *out) const{
347   //
348   // scale input *in and it error by (positive) fact (with error)
349   // and erite it to *out
350   //
351     out[0]=in[0]*fact[0];
352     out[1]=TMath::Sqrt(in[1]*in[1]/in[0]/in[0]
353                        +fact[1]*fact[1]/fact[0]/fact[0])*out[0];
354     
355 }