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