]>
Commit | Line | Data |
---|---|---|
db6722a5 | 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" | |
7036630f | 36 | #include "AliCFUnfolding.h" |
db6722a5 | 37 | |
38 | //____________________________________________________________________ | |
39 | ClassImp(AliCFGridSparse) | |
40 | ||
41 | //____________________________________________________________________ | |
42 | AliCFGridSparse::AliCFGridSparse() : | |
fb494025 | 43 | AliCFFrame(), |
44 | fSumW2(kFALSE), | |
db6722a5 | 45 | fData(0x0) |
46 | { | |
47 | // default constructor | |
48 | } | |
49 | //____________________________________________________________________ | |
50 | AliCFGridSparse::AliCFGridSparse(const Char_t* name, const Char_t* title) : | |
fb494025 | 51 | AliCFFrame(name,title), |
52 | fSumW2(kFALSE), | |
db6722a5 | 53 | fData(0x0) |
54 | { | |
55 | // default constructor | |
56 | } | |
57 | //____________________________________________________________________ | |
fb494025 | 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), | |
db6722a5 | 61 | fData(0x0) |
62 | { | |
63 | // | |
64 | // main constructor | |
65 | // | |
66 | ||
fb494025 | 67 | fData = new THnSparseF(name,title,nVarIn,nBinIn); |
db6722a5 | 68 | } |
fb494025 | 69 | |
db6722a5 | 70 | //____________________________________________________________________ |
fb494025 | 71 | AliCFGridSparse::~AliCFGridSparse() |
db6722a5 | 72 | { |
73 | // | |
fb494025 | 74 | // destructor |
db6722a5 | 75 | // |
fb494025 | 76 | if (fData) delete fData; |
db6722a5 | 77 | } |
78 | ||
79 | //____________________________________________________________________ | |
fb494025 | 80 | AliCFGridSparse::AliCFGridSparse(const AliCFGridSparse& c) : |
81 | AliCFFrame(c), | |
82 | fSumW2(kFALSE), | |
83 | fData(0x0) | |
db6722a5 | 84 | { |
85 | // | |
fb494025 | 86 | // copy constructor |
db6722a5 | 87 | // |
fb494025 | 88 | ((AliCFGridSparse &)c).Copy(*this); |
db6722a5 | 89 | } |
90 | ||
91 | //____________________________________________________________________ | |
fb494025 | 92 | AliCFGridSparse& AliCFGridSparse::operator=(const AliCFGridSparse &c) |
db6722a5 | 93 | { |
94 | // | |
95 | // assigment operator | |
96 | // | |
fb494025 | 97 | if (this != &c) c.Copy(*this); |
db6722a5 | 98 | return *this; |
99 | } | |
100 | ||
aa29aca9 | 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 | ||
db6722a5 | 114 | //____________________________________________________________________ |
fb494025 | 115 | void AliCFGridSparse::SetBinLimits(Int_t ivar, const Double_t *array) |
db6722a5 | 116 | { |
117 | // | |
118 | // setting the arrays containing the bin limits | |
119 | // | |
120 | fData->SetBinEdges(ivar, array); | |
db6722a5 | 121 | } |
122 | ||
123 | //____________________________________________________________________ | |
fb494025 | 124 | void AliCFGridSparse::Fill(const Double_t *var, Double_t weight) |
db6722a5 | 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 | //___________________________________________________________________ | |
d91baff0 | 135 | AliCFGridSparse* AliCFGridSparse::MakeSlice(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax, Bool_t useBins) const |
9105291d | 136 | { |
38b1447f | 137 | // |
138 | // projects the grid on the nVars dimensions defined in vars. | |
139 | // axis ranges can be defined in arrays varMin, varMax | |
98a5f772 | 140 | // If useBins=true, varMin and varMax are taken as bin numbers |
38b1447f | 141 | // |
9105291d | 142 | |
143 | // binning for new grid | |
144 | Int_t* bins = new Int_t[nVars]; | |
145 | for (Int_t iVar=0; iVar<nVars; iVar++) { | |
fb494025 | 146 | bins[iVar] = GetNBins(vars[iVar]); |
9105291d | 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()); | |
38b1447f | 154 | if (varMin && varMax) { |
fb494025 | 155 | for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) { |
d91baff0 | 156 | SetAxisRange(clone->GetAxis(iAxis),varMin[iAxis],varMax[iAxis],useBins); |
38b1447f | 157 | } |
9105291d | 158 | } |
38b1447f | 159 | else AliInfo("Keeping same axis ranges"); |
160 | ||
9105291d | 161 | out->SetGrid(clone->Projection(nVars,vars)); |
4b7819c4 | 162 | delete [] bins; |
d91baff0 | 163 | delete clone; |
9105291d | 164 | return out; |
165 | } | |
166 | ||
fb494025 | 167 | |
db6722a5 | 168 | //____________________________________________________________________ |
fb494025 | 169 | Float_t AliCFGridSparse::GetBinCenter(Int_t ivar, Int_t ibin) const |
db6722a5 | 170 | { |
171 | // | |
fb494025 | 172 | // Returns the center of specified bin for variable axis ivar |
173 | // | |
174 | ||
175 | return (Float_t) fData->GetAxis(ivar)->GetBinCenter(ibin); | |
db6722a5 | 176 | } |
177 | ||
178 | //____________________________________________________________________ | |
fb494025 | 179 | Float_t AliCFGridSparse::GetBinSize(Int_t ivar, Int_t ibin) const |
db6722a5 | 180 | { |
181 | // | |
fb494025 | 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); | |
db6722a5 | 186 | } |
187 | ||
db6722a5 | 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 | //____________________________________________________________________ | |
fb494025 | 199 | Float_t AliCFGridSparse::GetElement(Long_t index) const |
db6722a5 | 200 | { |
201 | // | |
fb494025 | 202 | // Returns content of grid element index |
db6722a5 | 203 | // |
db6722a5 | 204 | |
fb494025 | 205 | return fData->GetBinContent(index); |
db6722a5 | 206 | } |
207 | //____________________________________________________________________ | |
fb494025 | 208 | Float_t AliCFGridSparse::GetElement(const Int_t *bin) const |
db6722a5 | 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 | //____________________________________________________________________ | |
fb494025 | 217 | Float_t AliCFGridSparse::GetElement(const Double_t *var) const |
db6722a5 | 218 | { |
219 | // | |
220 | // Get the content in a bin corresponding to a set of input variables | |
221 | // | |
222 | ||
fb494025 | 223 | Long_t index = fData->GetBin(var,kFALSE); |
224 | if (index<0) return 0.; | |
225 | return fData->GetBinContent(index); | |
db6722a5 | 226 | } |
227 | ||
228 | //____________________________________________________________________ | |
fb494025 | 229 | Float_t AliCFGridSparse::GetElementError(Long_t index) const |
db6722a5 | 230 | { |
231 | // | |
fb494025 | 232 | // Returns the error on the content |
db6722a5 | 233 | // |
234 | ||
144192dd | 235 | return fData->GetBinError(index); |
db6722a5 | 236 | } |
237 | //____________________________________________________________________ | |
fb494025 | 238 | Float_t AliCFGridSparse::GetElementError(const Int_t *bin) const |
db6722a5 | 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 | //____________________________________________________________________ | |
fb494025 | 247 | Float_t AliCFGridSparse::GetElementError(const Double_t *var) const |
db6722a5 | 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) | |
fb494025 | 254 | if (index<0) return 0.; |
255 | return fData->GetBinError(index); | |
db6722a5 | 256 | } |
257 | ||
db6722a5 | 258 | //____________________________________________________________________ |
fb494025 | 259 | void AliCFGridSparse::SetElement(Long_t index, Float_t val) |
db6722a5 | 260 | { |
261 | // | |
fb494025 | 262 | // Sets grid element value |
db6722a5 | 263 | // |
fb494025 | 264 | Int_t* bin = new Int_t[GetNVar()]; |
265 | fData->GetBinContent(index,bin); //affects the bin coordinates | |
266 | SetElement(bin,val); | |
267 | delete [] bin ; | |
db6722a5 | 268 | } |
fb494025 | 269 | |
db6722a5 | 270 | //____________________________________________________________________ |
fb494025 | 271 | void AliCFGridSparse::SetElement(const Int_t *bin, Float_t val) |
db6722a5 | 272 | { |
273 | // | |
274 | // Sets grid element of bin indeces bin to val | |
275 | // | |
276 | fData->SetBinContent(bin,val); | |
277 | } | |
278 | //____________________________________________________________________ | |
fb494025 | 279 | void AliCFGridSparse::SetElement(const Double_t *var, Float_t val) |
db6722a5 | 280 | { |
281 | // | |
282 | // Set the content in a bin to value val corresponding to a set of input variables | |
283 | // | |
fb494025 | 284 | Long_t index=fData->GetBin(var,kTRUE); //THnSparse index: allocate the cell |
285 | Int_t *bin = new Int_t[GetNVar()]; | |
db6722a5 | 286 | fData->GetBinContent(index,bin); //trick to access the array of bins |
fb494025 | 287 | SetElement(bin,val); |
db6722a5 | 288 | delete [] bin; |
db6722a5 | 289 | } |
290 | ||
291 | //____________________________________________________________________ | |
fb494025 | 292 | void AliCFGridSparse::SetElementError(Long_t index, Float_t val) |
db6722a5 | 293 | { |
294 | // | |
295 | // Sets grid element iel error to val (linear indexing) in AliCFFrame | |
296 | // | |
fb494025 | 297 | Int_t *bin = new Int_t[GetNVar()]; |
298 | fData->GetBinContent(index,bin); | |
299 | SetElementError(bin,val); | |
db6722a5 | 300 | delete [] bin; |
301 | } | |
fb494025 | 302 | |
db6722a5 | 303 | //____________________________________________________________________ |
fb494025 | 304 | void AliCFGridSparse::SetElementError(const Int_t *bin, Float_t val) |
db6722a5 | 305 | { |
306 | // | |
307 | // Sets grid element error of bin indeces bin to val | |
308 | // | |
309 | fData->SetBinError(bin,val); | |
310 | } | |
311 | //____________________________________________________________________ | |
fb494025 | 312 | void AliCFGridSparse::SetElementError(const Double_t *var, Float_t val) |
db6722a5 | 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 | |
fb494025 | 318 | Int_t *bin = new Int_t[GetNVar()]; |
db6722a5 | 319 | fData->GetBinContent(index,bin); //trick to access the array of bins |
fb494025 | 320 | SetElementError(bin,val); |
db6722a5 | 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 | } | |
db6722a5 | 333 | fSumW2=kTRUE; |
334 | } | |
335 | ||
336 | //____________________________________________________________________ | |
fb494025 | 337 | void AliCFGridSparse::Add(const AliCFGridSparse* aGrid, Double_t c) |
db6722a5 | 338 | { |
339 | // | |
340 | //add aGrid to the current one | |
341 | // | |
342 | ||
fb494025 | 343 | if (aGrid->GetNVar() != GetNVar()){ |
344 | AliError("Different number of variables, cannot add the grids"); | |
db6722a5 | 345 | return; |
346 | } | |
db6722a5 | 347 | |
fb494025 | 348 | if (!fSumW2 && aGrid->GetSumW2()) SumW2(); |
349 | fData->Add(aGrid->GetGrid(),c); | |
db6722a5 | 350 | } |
351 | ||
352 | //____________________________________________________________________ | |
fb494025 | 353 | void AliCFGridSparse::Add(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2) |
db6722a5 | 354 | { |
355 | // | |
356 | //Add aGrid1 and aGrid2 and deposit the result into the current one | |
357 | // | |
358 | ||
fb494025 | 359 | if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) { |
db6722a5 | 360 | AliInfo("Different number of variables, cannot add the grids"); |
361 | return; | |
362 | } | |
db6722a5 | 363 | |
fb494025 | 364 | if (!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2(); |
db6722a5 | 365 | |
366 | fData->Reset(); | |
fb494025 | 367 | fData->Add(aGrid1->GetGrid(),c1); |
368 | fData->Add(aGrid2->GetGrid(),c2); | |
db6722a5 | 369 | } |
370 | ||
371 | //____________________________________________________________________ | |
fb494025 | 372 | void AliCFGridSparse::Multiply(const AliCFGridSparse* aGrid, Double_t c) |
db6722a5 | 373 | { |
374 | // | |
375 | // Multiply aGrid to the current one | |
376 | // | |
377 | ||
fb494025 | 378 | if (aGrid->GetNVar() != GetNVar()) { |
379 | AliError("Different number of variables, cannot multiply the grids"); | |
db6722a5 | 380 | return; |
381 | } | |
db6722a5 | 382 | |
fb494025 | 383 | if(!fSumW2 && aGrid->GetSumW2()) SumW2(); |
384 | THnSparse *h = aGrid->GetGrid(); | |
db6722a5 | 385 | fData->Multiply(h); |
386 | fData->Scale(c); | |
db6722a5 | 387 | } |
388 | ||
389 | //____________________________________________________________________ | |
fb494025 | 390 | void AliCFGridSparse::Multiply(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2) |
db6722a5 | 391 | { |
392 | // | |
393 | //Multiply aGrid1 and aGrid2 and deposit the result into the current one | |
394 | // | |
395 | ||
fb494025 | 396 | if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) { |
397 | AliError("Different number of variables, cannot multiply the grids"); | |
db6722a5 | 398 | return; |
fb494025 | 399 | } |
db6722a5 | 400 | |
fb494025 | 401 | if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2(); |
db6722a5 | 402 | |
403 | fData->Reset(); | |
fb494025 | 404 | THnSparse *h1 = aGrid1->GetGrid(); |
405 | THnSparse *h2 = aGrid2->GetGrid(); | |
db6722a5 | 406 | h2->Multiply(h1); |
407 | h2->Scale(c1*c2); | |
408 | fData->Add(h2); | |
409 | } | |
410 | ||
db6722a5 | 411 | //____________________________________________________________________ |
fb494025 | 412 | void AliCFGridSparse::Divide(const AliCFGridSparse* aGrid, Double_t c) |
db6722a5 | 413 | { |
414 | // | |
415 | // Divide aGrid to the current one | |
416 | // | |
417 | ||
fb494025 | 418 | if (aGrid->GetNVar() != GetNVar()) { |
419 | AliError("Different number of variables, cannot divide the grids"); | |
db6722a5 | 420 | return; |
421 | } | |
db6722a5 | 422 | |
fb494025 | 423 | if (!fSumW2 && aGrid->GetSumW2()) SumW2(); |
db6722a5 | 424 | |
d7c1cb54 | 425 | THnSparse *h1 = aGrid->GetGrid(); |
426 | THnSparse *h2 = (THnSparse*)fData->Clone(); | |
427 | fData->Divide(h2,h1); | |
db6722a5 | 428 | fData->Scale(c); |
db6722a5 | 429 | } |
430 | ||
431 | //____________________________________________________________________ | |
fb494025 | 432 | void AliCFGridSparse::Divide(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2, Option_t *option) |
db6722a5 | 433 | { |
434 | // | |
435 | //Divide aGrid1 and aGrid2 and deposit the result into the current one | |
fb494025 | 436 | //binomial errors are supported |
db6722a5 | 437 | // |
438 | ||
fb494025 | 439 | if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) { |
440 | AliError("Different number of variables, cannot divide the grids"); | |
db6722a5 | 441 | return; |
442 | } | |
db6722a5 | 443 | |
fb494025 | 444 | if (!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2(); |
db6722a5 | 445 | |
fb494025 | 446 | THnSparse *h1= aGrid1->GetGrid(); |
447 | THnSparse *h2= aGrid2->GetGrid(); | |
db6722a5 | 448 | fData->Divide(h1,h2,c1,c2,option); |
449 | } | |
450 | ||
451 | ||
7411edfd | 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 | ||
fb494025 | 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])); | |
7411edfd | 463 | } |
464 | ||
465 | THnSparse *rebinned =fData->Rebin(group); | |
466 | fData->Reset(); | |
467 | fData = rebinned; | |
fb494025 | 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 | // | |
7411edfd | 475 | |
fb494025 | 476 | if (GetElement(index)==0 || fact[0]==0) return; |
7411edfd | 477 | |
fb494025 | 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; | |
7411edfd | 492 | |
fb494025 | 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; | |
7411edfd | 508 | |
fb494025 | 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); | |
7411edfd | 526 | } |
fb494025 | 527 | } |
528 | //____________________________________________________________________ | |
529 | Long_t AliCFGridSparse::GetEmptyBins() const { | |
530 | // | |
531 | // Get empty bins | |
532 | // | |
7411edfd | 533 | |
fb494025 | 534 | return (GetNBinsTotal() - GetNFilledBins()) ; |
535 | } | |
7411edfd | 536 | |
fb494025 | 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 | } | |
7411edfd | 549 | |
fb494025 | 550 | //_____________________________________________________________________ |
551 | Double_t AliCFGridSparse::GetIntegral() const | |
552 | { | |
553 | // | |
554 | // Get full Integral | |
555 | // | |
556 | return fData->ComputeIntegral(); | |
557 | } | |
7411edfd | 558 | |
fb494025 | 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; | |
7411edfd | 569 | |
fb494025 | 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; | |
7411edfd | 586 | } |
fb494025 | 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 | ||
db6722a5 | 600 | //____________________________________________________________________ |
601 | void AliCFGridSparse::Copy(TObject& c) const | |
602 | { | |
603 | // | |
604 | // copy function | |
605 | // | |
fb494025 | 606 | AliCFFrame::Copy(c); |
db6722a5 | 607 | AliCFGridSparse& target = (AliCFGridSparse &) c; |
fb494025 | 608 | target.fSumW2 = fSumW2 ; |
609 | if (fData) { | |
610 | target.fData = (THnSparse*)fData->Clone(); | |
611 | } | |
db6722a5 | 612 | } |
613 | ||
c8df672e | 614 | //____________________________________________________________________ |
d91baff0 | 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 |
c8df672e | 616 | { |
617 | // | |
d91baff0 | 618 | // return a slice on variables iVar1 (and optionnally iVar2 (and iVar3)) while axis ranges are defined with varMin,varMax |
c8df672e | 619 | // arrays varMin and varMax contain the min and max values of each variable. |
fb494025 | 620 | // therefore varMin and varMax must have their dimensions equal to GetNVar() |
98a5f772 | 621 | // If useBins=true, varMin and varMax are taken as bin numbers |
d91baff0 | 622 | // if varmin or varmax point to null, all the range is taken, including over- and underflows |
623 | ||
c8df672e | 624 | THnSparse* clone = (THnSparse*)fData->Clone(); |
d91baff0 | 625 | if (varMin != 0x0 && varMax != 0x0) { |
626 | for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) SetAxisRange(clone->GetAxis(iAxis),varMin[iAxis],varMax[iAxis],useBins); | |
c8df672e | 627 | } |
b12ab491 | 628 | |
d91baff0 | 629 | TH1* projection = 0x0 ; |
630 | TString name,title; | |
631 | GetProjectionName (name ,iVar1,iVar2,iVar3); | |
632 | GetProjectionTitle(title,iVar1,iVar2,iVar3); | |
b12ab491 | 633 | |
d91baff0 | 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))); | |
2c502cd0 | 642 | for (Int_t iBin=1; iBin<=projection->GetNbinsX(); iBin++) { |
643 | Int_t origBin = GetAxis(iVar1)->GetFirst()+iBin-1; | |
644 | TString binLabel = GetAxis(iVar1)->GetBinLabel(origBin) ; | |
d91baff0 | 645 | if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel); |
646 | } | |
647 | } | |
648 | else { | |
649 | if (iVar1 >= GetNVar() || iVar1 < 0 || | |
650 | iVar2 >= GetNVar() || iVar2 < 0 ) { | |
651 | AliError("Non-existent variable, return NULL"); | |
652 | return 0x0; | |
653 | } | |
654 | projection = (TH2D*)clone->Projection(iVar2,iVar1); | |
2c502cd0 | 655 | for (Int_t iBin=1; iBin<=projection->GetNbinsX(); iBin++) { |
656 | Int_t origBin = GetAxis(iVar1)->GetFirst()+iBin-1; | |
657 | TString binLabel = GetAxis(iVar1)->GetBinLabel(origBin) ; | |
d91baff0 | 658 | if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel); |
659 | } | |
2c502cd0 | 660 | for (Int_t iBin=1; iBin<=projection->GetNbinsY(); iBin++) { |
661 | Int_t origBin = GetAxis(iVar2)->GetFirst()+iBin-1; | |
662 | TString binLabel = GetAxis(iVar2)->GetBinLabel(origBin) ; | |
d91baff0 | 663 | if (binLabel.CompareTo("") != 0) projection->GetYaxis()->SetBinLabel(iBin,binLabel); |
664 | } | |
665 | } | |
b12ab491 | 666 | } |
d91baff0 | 667 | else { |
668 | if (iVar1 >= GetNVar() || iVar1 < 0 || | |
669 | iVar2 >= GetNVar() || iVar2 < 0 || | |
670 | iVar3 >= GetNVar() || iVar3 < 0 ) { | |
671 | AliError("Non-existent variable, return NULL"); | |
672 | return 0x0; | |
673 | } | |
674 | projection = (TH3D*)clone->Projection(iVar1,iVar2,iVar3); | |
2c502cd0 | 675 | for (Int_t iBin=1; iBin<=projection->GetNbinsX(); iBin++) { |
676 | Int_t origBin = GetAxis(iVar1)->GetFirst()+iBin-1; | |
677 | TString binLabel = GetAxis(iVar1)->GetBinLabel(origBin) ; | |
d91baff0 | 678 | if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel); |
679 | } | |
2c502cd0 | 680 | for (Int_t iBin=1; iBin<=projection->GetNbinsY(); iBin++) { |
681 | Int_t origBin = GetAxis(iVar2)->GetFirst()+iBin-1; | |
682 | TString binLabel = GetAxis(iVar2)->GetBinLabel(origBin) ; | |
d91baff0 | 683 | if (binLabel.CompareTo("") != 0) projection->GetYaxis()->SetBinLabel(iBin,binLabel); |
684 | } | |
2c502cd0 | 685 | for (Int_t iBin=1; iBin<=projection->GetNbinsZ(); iBin++) { |
686 | Int_t origBin = GetAxis(iVar3)->GetFirst()+iBin-1; | |
687 | TString binLabel = GetAxis(iVar3)->GetBinLabel(origBin) ; | |
d91baff0 | 688 | if (binLabel.CompareTo("") != 0) projection->GetZaxis()->SetBinLabel(iBin,binLabel); |
689 | } | |
b12ab491 | 690 | } |
c8df672e | 691 | |
d91baff0 | 692 | projection->SetName (name .Data()); |
693 | projection->SetTitle(title.Data()); | |
b12ab491 | 694 | |
b12ab491 | 695 | delete clone; |
53ab59fe | 696 | return projection ; |
c8df672e | 697 | } |
698 | ||
699 | //____________________________________________________________________ | |
d91baff0 | 700 | void AliCFGridSparse::SetAxisRange(TAxis* axis, Double_t min, Double_t max, Bool_t useBins) const { |
c8df672e | 701 | // |
d91baff0 | 702 | // sets axis range, and forces bit TAxis::kAxisRange |
703 | // | |
704 | ||
705 | if (useBins) axis->SetRange ((Int_t)min,(Int_t)max); | |
706 | else axis->SetRangeUser( min, max); | |
707 | //axis->SetBit(TAxis::kAxisRange); // uncomment when ROOT TAxis is fixed | |
c8df672e | 708 | } |
709 | ||
9105291d | 710 | //____________________________________________________________________ |
d91baff0 | 711 | void AliCFGridSparse::SetRangeUser(Int_t iVar, Double_t varMin, Double_t varMax, Bool_t useBins) const { |
9105291d | 712 | // |
713 | // set range of axis iVar. | |
714 | // | |
d91baff0 | 715 | SetAxisRange(fData->GetAxis(iVar),varMin,varMax,useBins); |
2c502cd0 | 716 | //AliInfo(Form("AliCFGridSparse axis %d range has been modified",iVar)); |
717 | TAxis* currAxis = fData->GetAxis(iVar); | |
718 | TString outString = Form("%s new range: %.1f < %s < %.1f", GetName(), currAxis->GetBinLowEdge(currAxis->GetFirst()), currAxis->GetTitle(), currAxis->GetBinUpEdge(currAxis->GetLast())); | |
719 | TString binLabel = currAxis->GetBinLabel(currAxis->GetFirst()); | |
720 | if ( ! binLabel.IsNull() ) { | |
721 | outString += " ( "; | |
722 | for ( Int_t ibin = currAxis->GetFirst(); ibin <= currAxis->GetLast(); ibin++ ) { | |
723 | outString += Form("%s ", currAxis->GetBinLabel(ibin)); | |
724 | } | |
725 | outString += ")"; | |
726 | } | |
727 | AliWarning(outString.Data()); | |
728 | ||
9105291d | 729 | } |
730 | ||
c8df672e | 731 | //____________________________________________________________________ |
d91baff0 | 732 | void AliCFGridSparse::SetRangeUser(const Double_t *varMin, const Double_t *varMax, Bool_t useBins) const { |
c8df672e | 733 | // |
fb494025 | 734 | // set range of every axis. varMin and varMax must be of dimension GetNVar() |
c8df672e | 735 | // |
fb494025 | 736 | for (Int_t iAxis=0; iAxis<GetNVar() ; iAxis++) { // set new range for every axis |
d91baff0 | 737 | SetRangeUser(iAxis,varMin[iAxis],varMax[iAxis], useBins); |
c8df672e | 738 | } |
d91baff0 | 739 | AliInfo("AliCFGridSparse axes ranges have been modified"); |
fb494025 | 740 | } |
741 | ||
742 | //____________________________________________________________________ | |
743 | Float_t AliCFGridSparse::GetOverFlows(Int_t ivar, Bool_t exclusive) const | |
744 | { | |
745 | // | |
746 | // Returns overflows in variable ivar | |
747 | // Set 'exclusive' to true for an exclusive check on variable ivar | |
748 | // | |
749 | Int_t* bin = new Int_t[GetNVar()]; | |
750 | memset(bin, 0, sizeof(Int_t) * GetNVar()); | |
751 | Float_t ovfl=0.; | |
752 | for (Long64_t i = 0; i < fData->GetNbins(); i++) { | |
753 | Double_t v = fData->GetBinContent(i, bin); | |
754 | Bool_t add=kTRUE; | |
755 | if (exclusive) { | |
756 | for(Int_t j=0;j<GetNVar();j++){ | |
757 | if(ivar==j)continue; | |
758 | if((bin[j]==0) || (bin[j]==GetNBins(j)+1))add=kFALSE; | |
759 | } | |
760 | } | |
761 | if(bin[ivar]==GetNBins(ivar)+1 && add) ovfl+=v; | |
762 | } | |
763 | ||
764 | delete[] bin; | |
765 | return ovfl; | |
766 | } | |
767 | ||
768 | //____________________________________________________________________ | |
769 | Float_t AliCFGridSparse::GetUnderFlows(Int_t ivar, Bool_t exclusive) const | |
770 | { | |
771 | // | |
772 | // Returns exclusive overflows in variable ivar | |
773 | // Set 'exclusive' to true for an exclusive check on variable ivar | |
774 | // | |
775 | Int_t* bin = new Int_t[GetNVar()]; | |
776 | memset(bin, 0, sizeof(Int_t) * GetNVar()); | |
777 | Float_t unfl=0.; | |
778 | for (Long64_t i = 0; i < fData->GetNbins(); i++) { | |
779 | Double_t v = fData->GetBinContent(i, bin); | |
780 | Bool_t add=kTRUE; | |
781 | if (exclusive) { | |
782 | for(Int_t j=0;j<GetNVar();j++){ | |
783 | if(ivar==j)continue; | |
784 | if((bin[j]==0) || (bin[j]==GetNBins(j)+1))add=kFALSE; | |
785 | } | |
786 | } | |
787 | if(bin[ivar]==0 && add) unfl+=v; | |
788 | } | |
789 | ||
790 | delete[] bin; | |
791 | return unfl; | |
c8df672e | 792 | } |
fb494025 | 793 | |
7036630f | 794 | |
795 | //____________________________________________________________________ | |
796 | void AliCFGridSparse::Smooth() { | |
797 | // | |
798 | // smoothing function: TO USE WITH CARE | |
799 | // | |
800 | ||
801 | AliInfo("Your GridSparse is going to be smoothed"); | |
802 | AliInfo(Form("N TOTAL BINS : %li",GetNBinsTotal())); | |
803 | AliInfo(Form("N FILLED BINS : %li",GetNFilledBins())); | |
804 | AliCFUnfolding::SmoothUsingNeighbours(fData); | |
805 | } |