update in default cuts (Andrea Dainese)
[u/mrichter/AliRoot.git] / CORRFW / AliCFGridSparse.cxx
CommitLineData
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"
36
37//____________________________________________________________________
38ClassImp(AliCFGridSparse)
39
40//____________________________________________________________________
41AliCFGridSparse::AliCFGridSparse() :
fb494025 42 AliCFFrame(),
43 fSumW2(kFALSE),
db6722a5 44 fData(0x0)
45{
46 // default constructor
47}
48//____________________________________________________________________
49AliCFGridSparse::AliCFGridSparse(const Char_t* name, const Char_t* title) :
fb494025 50 AliCFFrame(name,title),
51 fSumW2(kFALSE),
db6722a5 52 fData(0x0)
53{
54 // default constructor
55}
56//____________________________________________________________________
fb494025 57AliCFGridSparse::AliCFGridSparse(const Char_t* name, const Char_t* title, Int_t nVarIn, const Int_t * nBinIn) :
58 AliCFFrame(name,title),
59 fSumW2(kFALSE),
db6722a5 60 fData(0x0)
61{
62 //
63 // main constructor
64 //
65
fb494025 66 fData = new THnSparseF(name,title,nVarIn,nBinIn);
db6722a5 67}
fb494025 68
db6722a5 69//____________________________________________________________________
fb494025 70AliCFGridSparse::~AliCFGridSparse()
db6722a5 71{
72 //
fb494025 73 // destructor
db6722a5 74 //
fb494025 75 if (fData) delete fData;
db6722a5 76}
77
78//____________________________________________________________________
fb494025 79AliCFGridSparse::AliCFGridSparse(const AliCFGridSparse& c) :
80 AliCFFrame(c),
81 fSumW2(kFALSE),
82 fData(0x0)
db6722a5 83{
84 //
fb494025 85 // copy constructor
db6722a5 86 //
fb494025 87 ((AliCFGridSparse &)c).Copy(*this);
db6722a5 88}
89
90//____________________________________________________________________
fb494025 91AliCFGridSparse& AliCFGridSparse::operator=(const AliCFGridSparse &c)
db6722a5 92{
93 //
94 // assigment operator
95 //
fb494025 96 if (this != &c) c.Copy(*this);
db6722a5 97 return *this;
98}
99
100//____________________________________________________________________
aa29aca9 101void AliCFGridSparse::SetBinLimits(Int_t ivar, Double_t min, Double_t max)
102{
103 //
104 // set a uniform binning for variable ivar
105 //
106 Int_t nBins = GetNBins(ivar);
107 Double_t * array = new Double_t[nBins+1];
108 for (Int_t iEdge=0; iEdge<=nBins; iEdge++) array[iEdge] = min + iEdge * (max-min)/nBins ;
109 fData->SetBinEdges(ivar, array);
110 delete [] array ;
111}
112
113//____________________________________________________________________
fb494025 114void AliCFGridSparse::SetBinLimits(Int_t ivar, const Double_t *array)
db6722a5 115{
116 //
117 // setting the arrays containing the bin limits
118 //
119 fData->SetBinEdges(ivar, array);
db6722a5 120}
121
122//____________________________________________________________________
fb494025 123void AliCFGridSparse::Fill(const Double_t *var, Double_t weight)
db6722a5 124{
125 //
126 // Fill the grid,
127 // given a set of values of the input variable,
128 // with weight (by default w=1)
129 //
130 fData->Fill(var,weight);
131}
132
133//___________________________________________________________________
134TH1D *AliCFGridSparse::Project(Int_t ivar) const
135{
136 //
137 // Make a 1D projection along variable ivar
138 //
139
db6722a5 140 TH1D *hist=fData->Projection(ivar);
fb494025 141 hist->SetXTitle(GetVarTitle(ivar));
91e32eeb 142 hist->SetName(Form("%s_proj-%s",GetName(),GetVarTitle(ivar)));
fb494025 143 hist->SetTitle(Form("%s: projection on %s",GetTitle(),GetVarTitle(ivar)));
db6722a5 144 return hist;
db6722a5 145}
146//___________________________________________________________________
147TH2D *AliCFGridSparse::Project(Int_t ivar1, Int_t ivar2) const
148{
149 //
150 // Make a 2D projection along variables ivar1 & ivar2
151 //
152
318f64b1 153 TH2D *hist=fData->Projection(ivar2,ivar1); //notice inverted axis (THnSparse uses TH3 2d-projection convention...)
fb494025 154 hist->SetXTitle(GetVarTitle(ivar1));
155 hist->SetYTitle(GetVarTitle(ivar2));
91e32eeb 156 hist->SetName(Form("%s_proj-%s,%s",GetName(),GetVarTitle(ivar1),GetVarTitle(ivar2)));
fb494025 157 hist->SetTitle(Form("%s: projection on %s-%s",GetTitle(),GetVarTitle(ivar1),GetVarTitle(ivar2)));
db6722a5 158 return hist;
db6722a5 159}
160//___________________________________________________________________
161TH3D *AliCFGridSparse::Project(Int_t ivar1, Int_t ivar2, Int_t ivar3) const
162{
163 //
164 // Make a 3D projection along variables ivar1 & ivar2 & ivar3
165 //
db6722a5 166
167 TH3D *hist=fData->Projection(ivar1,ivar2,ivar3);
fb494025 168 hist->SetXTitle(GetVarTitle(ivar1));
169 hist->SetYTitle(GetVarTitle(ivar2));
170 hist->SetZTitle(GetVarTitle(ivar3));
91e32eeb 171 hist->SetName(Form("%s_proj-%s,%s,%s",GetName(),GetVarTitle(ivar1),GetVarTitle(ivar2),GetVarTitle(ivar3)));
fb494025 172 hist->SetTitle(Form("%s: projection on %s-%s-%s",GetTitle(),GetVarTitle(ivar1),GetVarTitle(ivar2),GetVarTitle(ivar3)));
db6722a5 173 return hist;
db6722a5 174}
175
9105291d 176//___________________________________________________________________
98a5f772 177AliCFGridSparse* AliCFGridSparse::Project(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax, Bool_t useBins) const
9105291d 178{
38b1447f 179 //
180 // projects the grid on the nVars dimensions defined in vars.
181 // axis ranges can be defined in arrays varMin, varMax
98a5f772 182 // If useBins=true, varMin and varMax are taken as bin numbers
38b1447f 183 //
9105291d 184
185 // binning for new grid
186 Int_t* bins = new Int_t[nVars];
187 for (Int_t iVar=0; iVar<nVars; iVar++) {
fb494025 188 bins[iVar] = GetNBins(vars[iVar]);
9105291d 189 }
190
191 // create new grid sparse
192 AliCFGridSparse* out = new AliCFGridSparse(fName,fTitle,nVars,bins);
193
194 //set the range in the THnSparse to project
195 THnSparse* clone = ((THnSparse*)fData->Clone());
38b1447f 196 if (varMin && varMax) {
fb494025 197 for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) {
98a5f772 198 if (useBins) clone->GetAxis(iAxis)->SetRange((Int_t)varMin[iAxis],(Int_t)varMax[iAxis]);
199 else clone->GetAxis(iAxis)->SetRangeUser(varMin[iAxis],varMax[iAxis]);
38b1447f 200 }
9105291d 201 }
38b1447f 202 else AliInfo("Keeping same axis ranges");
203
9105291d 204 out->SetGrid(clone->Projection(nVars,vars));
4b7819c4 205 delete [] bins;
9105291d 206 return out;
207}
208
fb494025 209
db6722a5 210//____________________________________________________________________
fb494025 211Float_t AliCFGridSparse::GetBinCenter(Int_t ivar, Int_t ibin) const
db6722a5 212{
213 //
fb494025 214 // Returns the center of specified bin for variable axis ivar
215 //
216
217 return (Float_t) fData->GetAxis(ivar)->GetBinCenter(ibin);
db6722a5 218}
219
220//____________________________________________________________________
fb494025 221Float_t AliCFGridSparse::GetBinSize(Int_t ivar, Int_t ibin) const
db6722a5 222{
223 //
fb494025 224 // Returns the size of specified bin for variable axis ivar
225 //
226
227 return (Float_t) fData->GetAxis(ivar)->GetBinUpEdge(ibin) - fData->GetAxis(ivar)->GetBinLowEdge(ibin);
db6722a5 228}
229
db6722a5 230//____________________________________________________________________
231Float_t AliCFGridSparse::GetEntries() const
232{
233 //
234 // total entries (including overflows and underflows)
235 //
236
237 return fData->GetEntries();
238}
239
240//____________________________________________________________________
fb494025 241Float_t AliCFGridSparse::GetElement(Long_t index) const
db6722a5 242{
243 //
fb494025 244 // Returns content of grid element index
db6722a5 245 //
db6722a5 246
fb494025 247 return fData->GetBinContent(index);
db6722a5 248}
249//____________________________________________________________________
fb494025 250Float_t AliCFGridSparse::GetElement(const Int_t *bin) const
db6722a5 251{
252 //
253 // Get the content in a bin corresponding to a set of bin indexes
254 //
255 return fData->GetBinContent(bin);
256
257}
258//____________________________________________________________________
fb494025 259Float_t AliCFGridSparse::GetElement(const Double_t *var) const
db6722a5 260{
261 //
262 // Get the content in a bin corresponding to a set of input variables
263 //
264
fb494025 265 Long_t index = fData->GetBin(var,kFALSE);
266 if (index<0) return 0.;
267 return fData->GetBinContent(index);
db6722a5 268}
269
270//____________________________________________________________________
fb494025 271Float_t AliCFGridSparse::GetElementError(Long_t index) const
db6722a5 272{
273 //
fb494025 274 // Returns the error on the content
db6722a5 275 //
276
fb494025 277 return fData->GetBinContent(index);
db6722a5 278}
279//____________________________________________________________________
fb494025 280Float_t AliCFGridSparse::GetElementError(const Int_t *bin) const
db6722a5 281{
282 //
283 // Get the error in a bin corresponding to a set of bin indexes
284 //
285 return fData->GetBinError(bin);
286
287}
288//____________________________________________________________________
fb494025 289Float_t AliCFGridSparse::GetElementError(const Double_t *var) const
db6722a5 290{
291 //
292 // Get the error in a bin corresponding to a set of input variables
293 //
294
295 Long_t index=fData->GetBin(var,kFALSE); //this is the THnSparse index (do not allocate new cells if content is empy)
fb494025 296 if (index<0) return 0.;
297 return fData->GetBinError(index);
db6722a5 298}
299
db6722a5 300//____________________________________________________________________
fb494025 301void AliCFGridSparse::SetElement(Long_t index, Float_t val)
db6722a5 302{
303 //
fb494025 304 // Sets grid element value
db6722a5 305 //
fb494025 306 Int_t* bin = new Int_t[GetNVar()];
307 fData->GetBinContent(index,bin); //affects the bin coordinates
308 SetElement(bin,val);
309 delete [] bin ;
db6722a5 310}
fb494025 311
db6722a5 312//____________________________________________________________________
fb494025 313void AliCFGridSparse::SetElement(const Int_t *bin, Float_t val)
db6722a5 314{
315 //
316 // Sets grid element of bin indeces bin to val
317 //
318 fData->SetBinContent(bin,val);
319}
320//____________________________________________________________________
fb494025 321void AliCFGridSparse::SetElement(const Double_t *var, Float_t val)
db6722a5 322{
323 //
324 // Set the content in a bin to value val corresponding to a set of input variables
325 //
fb494025 326 Long_t index=fData->GetBin(var,kTRUE); //THnSparse index: allocate the cell
327 Int_t *bin = new Int_t[GetNVar()];
db6722a5 328 fData->GetBinContent(index,bin); //trick to access the array of bins
fb494025 329 SetElement(bin,val);
db6722a5 330 delete [] bin;
db6722a5 331}
332
333//____________________________________________________________________
fb494025 334void AliCFGridSparse::SetElementError(Long_t index, Float_t val)
db6722a5 335{
336 //
337 // Sets grid element iel error to val (linear indexing) in AliCFFrame
338 //
fb494025 339 Int_t *bin = new Int_t[GetNVar()];
340 fData->GetBinContent(index,bin);
341 SetElementError(bin,val);
db6722a5 342 delete [] bin;
343}
fb494025 344
db6722a5 345//____________________________________________________________________
fb494025 346void AliCFGridSparse::SetElementError(const Int_t *bin, Float_t val)
db6722a5 347{
348 //
349 // Sets grid element error of bin indeces bin to val
350 //
351 fData->SetBinError(bin,val);
352}
353//____________________________________________________________________
fb494025 354void AliCFGridSparse::SetElementError(const Double_t *var, Float_t val)
db6722a5 355{
356 //
357 // Set the error in a bin to value val corresponding to a set of input variables
358 //
359 Long_t index=fData->GetBin(var); //THnSparse index
fb494025 360 Int_t *bin = new Int_t[GetNVar()];
db6722a5 361 fData->GetBinContent(index,bin); //trick to access the array of bins
fb494025 362 SetElementError(bin,val);
db6722a5 363 delete [] bin;
364}
365
366//____________________________________________________________________
367void AliCFGridSparse::SumW2()
368{
369 //
370 //set calculation of the squared sum of the weighted entries
371 //
372 if(!fSumW2){
373 fData->CalculateErrors(kTRUE);
374 }
db6722a5 375 fSumW2=kTRUE;
376}
377
378//____________________________________________________________________
fb494025 379void AliCFGridSparse::Add(const AliCFGridSparse* aGrid, Double_t c)
db6722a5 380{
381 //
382 //add aGrid to the current one
383 //
384
fb494025 385 if (aGrid->GetNVar() != GetNVar()){
386 AliError("Different number of variables, cannot add the grids");
db6722a5 387 return;
388 }
db6722a5 389
fb494025 390 if (!fSumW2 && aGrid->GetSumW2()) SumW2();
391 fData->Add(aGrid->GetGrid(),c);
db6722a5 392}
393
394//____________________________________________________________________
fb494025 395void AliCFGridSparse::Add(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2)
db6722a5 396{
397 //
398 //Add aGrid1 and aGrid2 and deposit the result into the current one
399 //
400
fb494025 401 if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) {
db6722a5 402 AliInfo("Different number of variables, cannot add the grids");
403 return;
404 }
db6722a5 405
fb494025 406 if (!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2();
db6722a5 407
408 fData->Reset();
fb494025 409 fData->Add(aGrid1->GetGrid(),c1);
410 fData->Add(aGrid2->GetGrid(),c2);
db6722a5 411}
412
413//____________________________________________________________________
fb494025 414void AliCFGridSparse::Multiply(const AliCFGridSparse* aGrid, Double_t c)
db6722a5 415{
416 //
417 // Multiply aGrid to the current one
418 //
419
fb494025 420 if (aGrid->GetNVar() != GetNVar()) {
421 AliError("Different number of variables, cannot multiply the grids");
db6722a5 422 return;
423 }
db6722a5 424
fb494025 425 if(!fSumW2 && aGrid->GetSumW2()) SumW2();
426 THnSparse *h = aGrid->GetGrid();
db6722a5 427 fData->Multiply(h);
428 fData->Scale(c);
db6722a5 429}
430
431//____________________________________________________________________
fb494025 432void AliCFGridSparse::Multiply(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2)
db6722a5 433{
434 //
435 //Multiply aGrid1 and aGrid2 and deposit the result into the current one
436 //
437
fb494025 438 if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) {
439 AliError("Different number of variables, cannot multiply the grids");
db6722a5 440 return;
fb494025 441 }
db6722a5 442
fb494025 443 if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2();
db6722a5 444
445 fData->Reset();
fb494025 446 THnSparse *h1 = aGrid1->GetGrid();
447 THnSparse *h2 = aGrid2->GetGrid();
db6722a5 448 h2->Multiply(h1);
449 h2->Scale(c1*c2);
450 fData->Add(h2);
451}
452
db6722a5 453//____________________________________________________________________
fb494025 454void AliCFGridSparse::Divide(const AliCFGridSparse* aGrid, Double_t c)
db6722a5 455{
456 //
457 // Divide aGrid to the current one
458 //
459
fb494025 460 if (aGrid->GetNVar() != GetNVar()) {
461 AliError("Different number of variables, cannot divide the grids");
db6722a5 462 return;
463 }
db6722a5 464
fb494025 465 if (!fSumW2 && aGrid->GetSumW2()) SumW2();
db6722a5 466
d7c1cb54 467 THnSparse *h1 = aGrid->GetGrid();
468 THnSparse *h2 = (THnSparse*)fData->Clone();
469 fData->Divide(h2,h1);
db6722a5 470 fData->Scale(c);
db6722a5 471}
472
473//____________________________________________________________________
fb494025 474void AliCFGridSparse::Divide(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2, Option_t *option)
db6722a5 475{
476 //
477 //Divide aGrid1 and aGrid2 and deposit the result into the current one
fb494025 478 //binomial errors are supported
db6722a5 479 //
480
fb494025 481 if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) {
482 AliError("Different number of variables, cannot divide the grids");
db6722a5 483 return;
484 }
db6722a5 485
fb494025 486 if (!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2();
db6722a5 487
fb494025 488 THnSparse *h1= aGrid1->GetGrid();
489 THnSparse *h2= aGrid2->GetGrid();
db6722a5 490 fData->Divide(h1,h2,c1,c2,option);
491}
492
493
494//____________________________________________________________________
7411edfd 495void AliCFGridSparse::Rebin(const Int_t* group)
496{
497 //
498 // rebin the grid according to Rebin() as in THnSparse
499 // Please notice that the original number of bins on
500 // a given axis has to be divisible by the rebin group.
501 //
502
fb494025 503 for(Int_t i=0;i<GetNVar();i++){
504 if (group[i]!=1) AliInfo(Form(" merging bins along dimension %i in groups of %i bins", i,group[i]));
7411edfd 505 }
506
507 THnSparse *rebinned =fData->Rebin(group);
508 fData->Reset();
509 fData = rebinned;
fb494025 510}
511//____________________________________________________________________
512void AliCFGridSparse::Scale(Long_t index, const Double_t *fact)
513{
514 //
515 //scale content of a certain cell by (positive) fact (with error)
516 //
7411edfd 517
fb494025 518 if (GetElement(index)==0 || fact[0]==0) return;
7411edfd 519
fb494025 520 Double_t in[2], out[2];
521 in[0]=GetElement(index);
522 in[1]=GetElementError(index);
523 GetScaledValues(fact,in,out);
524 SetElement(index,out[0]);
525 if (fSumW2) SetElementError(index,out[1]);
526}
527//____________________________________________________________________
528void AliCFGridSparse::Scale(const Int_t *bin, const Double_t *fact)
529{
530 //
531 //scale content of a certain cell by (positive) fact (with error)
532 //
533 if(GetElement(bin)==0 || fact[0]==0)return;
7411edfd 534
fb494025 535 Double_t in[2], out[2];
536 in[0]=GetElement(bin);
537 in[1]=GetElementError(bin);
538 GetScaledValues(fact,in,out);
539 SetElement(bin,out[0]);
540 if(fSumW2)SetElementError(bin,out[1]);
541
542}
543//____________________________________________________________________
544void AliCFGridSparse::Scale(const Double_t *var, const Double_t *fact)
545{
546 //
547 //scale content of a certain cell by (positive) fact (with error)
548 //
549 if(GetElement(var)==0 || fact[0]==0)return;
7411edfd 550
fb494025 551 Double_t in[2], out[2];
552 in[0]=GetElement(var);
553 in[1]=GetElementError(var);
554 GetScaledValues(fact,in,out);
555 SetElement(var,out[0]);
556 if(fSumW2)SetElementError(var,out[1]);
557
558}
559//____________________________________________________________________
560void AliCFGridSparse::Scale(const Double_t* fact)
561{
562 //
563 //scale contents of the whole grid by fact
564 //
565
566 for (Long_t iel=0; iel<GetNFilledBins(); iel++) {
567 Scale(iel,fact);
7411edfd 568 }
fb494025 569}
570//____________________________________________________________________
571Long_t AliCFGridSparse::GetEmptyBins() const {
572 //
573 // Get empty bins
574 //
7411edfd 575
fb494025 576 return (GetNBinsTotal() - GetNFilledBins()) ;
577}
7411edfd 578
fb494025 579//_____________________________________________________________________
580// Int_t AliCFGridSparse::GetEmptyBins( Double_t *varMin, Double_t* varMax ) const
581// {
582// //
583// // Get empty bins in a range specified by varMin and varMax
584// //
585
586// Int_t *indexMin = new Int_t[GetNVar()];
587// Int_t *indexMax = new Int_t[GetNVar()];
588
589// //Find out the min and max bins
590
591// for (Int_t i=0;i<GetNVar();i++) {
592// Double_t xmin=varMin[i]; // the min values
593// Double_t xmax=varMax[i]; // the min values
594// Int_t nbins = fData->GetAxis(i)->GetNbins()+1;
595// Double_t *bins=new Double_t[nbins];
596// for(Int_t ibin =0;ibin<nbins;ibin++){
597// bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
598// }
599// indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
600// indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
601// delete [] bins;
602// }
603
604// Int_t val=0;
605// for(Int_t i=0;i<fNDim;i++){
606// for (Int_t j=0;j<GetNVar();j++)fIndex[j]=GetBinIndex(j,i);
607// Bool_t isIn=kTRUE;
608// for (Int_t j=0;j<GetNVar();j++){
609// if(!(fIndex[j]>=indexMin[j] && fIndex[j]<=indexMax[j]))isIn=kFALSE;
610// }
611// if(isIn && GetElement(i)<=0)val++;
612// }
613// AliInfo(Form(" the empty bins = %i ",val));
614
615// delete [] indexMin;
616// delete [] indexMax;
617// return val;
618// }
619
620//____________________________________________________________________
621Int_t AliCFGridSparse::CheckStats(Double_t thr) const
622{
623 //
624 // Count the cells below a certain threshold
625 //
626 Int_t ncellsLow=0;
627 for (Int_t i=0; i<GetNBinsTotal(); i++) {
628 if (GetElement(i)<thr) ncellsLow++;
629 }
630 return ncellsLow;
631}
7411edfd 632
fb494025 633//_____________________________________________________________________
634Double_t AliCFGridSparse::GetIntegral() const
635{
636 //
637 // Get full Integral
638 //
639 return fData->ComputeIntegral();
640}
7411edfd 641
fb494025 642//_____________________________________________________________________
643// Double_t AliCFGridSparse::GetIntegral(Int_t *binMin, Int_t* binMax ) const
644// {
645// //
646// // Get Integral in a range of bin indeces (extremes included)
647// //
648
649// Double_t val=0;
650
651// for(Int_t i=0;i<GetNVar();i++){
652// if(binMin[i]<1)binMin[i]=1;
653// if(binMax[i]>fNVarBins[i])binMax[i]=fNVarBins[i];
654// if((binMin[i]>binMax[i])){
655// AliInfo(Form(" Bin indices in variable %i in reverse order, please check!", i));
656// return val;
657// }
658// }
659// val=GetSum(0,binMin,binMax);
660
661// return val;
662// }
663
664//_____________________________________________________________________
665// Double_t AliCFGridSparse::GetIntegral(Double_t *varMin, Double_t* varMax ) const
666// {
667// //
668// // Get Integral in a range (extremes included)
669// //
670
671// Int_t *indexMin=new Int_t[GetNVar()];
672// Int_t *indexMax=new Int_t[GetNVar()];
673
674// //Find out the min and max bins
675
676// for(Int_t i=0;i<GetNVar();i++){
677// Double_t xmin=varMin[i]; // the min values
678// Double_t xmax=varMax[i]; // the min values
679// Int_t nbins=fNVarBins[i]+1;
680// Double_t *bins=new Double_t[nbins];
681// for(Int_t ibin =0;ibin<nbins;ibin++){
682// bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
683// }
684// indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
685// indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
686// delete [] bins;
687// }
688
689// //move to the TH/THnSparse convention in N-dim bin numbering
690// for(Int_t i=0;i<GetNVar();i++){
691// indexMin[i]+=1;
692// indexMax[i]+=1;
693// }
694
695// Double_t val=GetIntegral(indexMin,indexMax);
696
697// delete [] indexMin;
698// delete [] indexMax;
699
700// return val;
701// }
702
703// //_____________________________________________________________________
704// Double_t AliCFGridSparse::GetSum(Int_t ivar, Int_t *binMin, Int_t* binMax) const
705// {
706// //
707// // recursively add over nested loops....
708// //
709
710// static Double_t val;
711// if (ivar==0) val=0.;
712// for(Int_t ibin=binMin[ivar]-1 ; ibin<=binMax[ivar]-1 ; ibin++){
713// //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
714// fIndex[ivar]=ibin;
715// if(ivar<GetNVar()-1) {
716// val=GetSum(ivar+1,binMin,binMax);
717// }
718// else {
719// Int_t iel=GetBinIndex(fIndex);
720// val+=GetElement(iel);
721// }
722// }
723
724// return val;
725// }
726
727//____________________________________________________________________
728Long64_t AliCFGridSparse::Merge(TCollection* list)
729{
730 //
731 // Merge a list of AliCFGridSparse with this (needed for PROOF).
732 // Returns the number of merged objects (including this).
733 //
734
735 if (!list)
736 return 0;
7411edfd 737
fb494025 738 if (list->IsEmpty())
739 return 1;
740
741 TIterator* iter = list->MakeIterator();
742 TObject* obj;
743
744 Int_t count = 0;
745 while ((obj = iter->Next())) {
746 AliCFGridSparse* entry = dynamic_cast<AliCFGridSparse*> (obj);
747 if (entry == 0)
748 continue;
749 this->Add(entry);
750 count++;
751 }
752
753 return count+1;
7411edfd 754}
fb494025 755
756//____________________________________________________________________
757void AliCFGridSparse::GetScaledValues(const Double_t *fact, const Double_t *in, Double_t *out) const{
758 //
759 // scale input *in and its error by (positive) fact (with error)
760 // and erite it to *out
761 //
762 out[0]=in[0]*fact[0];
763 out[1]=TMath::Sqrt(in[1]*in[1]/in[0]/in[0]
764 +fact[1]*fact[1]/fact[0]/fact[0])*out[0];
765
766}
767
7411edfd 768//____________________________________________________________________
db6722a5 769void AliCFGridSparse::Copy(TObject& c) const
770{
771 //
772 // copy function
773 //
fb494025 774 AliCFFrame::Copy(c);
db6722a5 775 AliCFGridSparse& target = (AliCFGridSparse &) c;
fb494025 776 target.fSumW2 = fSumW2 ;
777 if (fData) {
778 target.fData = (THnSparse*)fData->Clone();
779 }
db6722a5 780}
781
c8df672e 782//____________________________________________________________________
98a5f772 783TH1D* AliCFGridSparse::Slice(Int_t iVar, const Double_t *varMin, const Double_t *varMax, Bool_t useBins) const
c8df672e 784{
785 //
786 // return a slice (1D-projection) on variable iVar while axis ranges are defined with varMin,varMax
787 // arrays varMin and varMax contain the min and max values of each variable.
fb494025 788 // therefore varMin and varMax must have their dimensions equal to GetNVar()
98a5f772 789 // If useBins=true, varMin and varMax are taken as bin numbers
c8df672e 790
791 THnSparse* clone = (THnSparse*)fData->Clone();
fb494025 792 for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) {
98a5f772 793 if (useBins) clone->GetAxis(iAxis)->SetRange((Int_t)varMin[iAxis],(Int_t)varMax[iAxis]);
794 else clone->GetAxis(iAxis)->SetRangeUser(varMin[iAxis],varMax[iAxis]);
c8df672e 795 }
796 return clone->Projection(iVar);
797}
798
799//____________________________________________________________________
98a5f772 800TH2D* AliCFGridSparse::Slice(Int_t iVar1, Int_t iVar2, const Double_t *varMin, const Double_t *varMax, Bool_t useBins) const
c8df672e 801{
802 //
803 // return a slice (2D-projection) on variables iVar1 and iVar2 while axis ranges are defined with varMin,varMax
804 // arrays varMin and varMax contain the min and max values of each variable.
fb494025 805 // therefore varMin and varMax must have their dimensions equal to GetNVar()
98a5f772 806 // If useBins=true, varMin and varMax are taken as bin numbers
c8df672e 807
808 THnSparse* clone = (THnSparse*)fData->Clone();
fb494025 809 for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) {
98a5f772 810 if (useBins) clone->GetAxis(iAxis)->SetRange((Int_t)varMin[iAxis],(Int_t)varMax[iAxis]);
811 else clone->GetAxis(iAxis)->SetRangeUser(varMin[iAxis],varMax[iAxis]);
c8df672e 812 }
813 return clone->Projection(iVar1,iVar2);
814}
815
816//____________________________________________________________________
98a5f772 817TH3D* AliCFGridSparse::Slice(Int_t iVar1, Int_t iVar2, Int_t iVar3, const Double_t *varMin, const Double_t *varMax, Bool_t useBins) const
c8df672e 818{
819 //
820 // return a slice (3D-projection) on variables iVar1, iVar2 and iVar3 while axis ranges are defined with varMin,varMax
821 // arrays varMin and varMax contain the min and max values of each variable.
fb494025 822 // therefore varMin and varMax must have their dimensions equal to GetNVar()
98a5f772 823 // If useBins=true, varMin and varMax are taken as bin numbers
c8df672e 824
825 THnSparse* clone = (THnSparse*)fData->Clone();
fb494025 826 for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) {
98a5f772 827 if (useBins) clone->GetAxis(iAxis)->SetRange((Int_t)varMin[iAxis],(Int_t)varMax[iAxis]);
828 else clone->GetAxis(iAxis)->SetRangeUser(varMin[iAxis],varMax[iAxis]);
c8df672e 829 }
830 return clone->Projection(iVar1,iVar2,iVar3);
831}
832
833//____________________________________________________________________
9105291d 834void AliCFGridSparse::SetRangeUser(Int_t iVar, Double_t varMin, Double_t varMax) {
835 //
836 // set range of axis iVar.
837 //
838 fData->GetAxis(iVar)->SetRangeUser(varMin,varMax);
839 AliWarning(Form("THnSparse axis %d range has been modified",iVar));
840}
841
842//____________________________________________________________________
fb494025 843void AliCFGridSparse::SetRangeUser(const Double_t *varMin, const Double_t *varMax) {
c8df672e 844 //
fb494025 845 // set range of every axis. varMin and varMax must be of dimension GetNVar()
c8df672e 846 //
fb494025 847 for (Int_t iAxis=0; iAxis<GetNVar() ; iAxis++) { // set new range for every axis
9105291d 848 SetRangeUser(iAxis,varMin[iAxis],varMax[iAxis]);
c8df672e 849 }
9105291d 850 AliWarning("THnSparse axes ranges have been modified");
851}
852
853//____________________________________________________________________
854void AliCFGridSparse::UseAxisRange(Bool_t b) const {
fb494025 855 for (Int_t iAxis=0; iAxis<GetNVar(); iAxis++) fData->GetAxis(iAxis)->SetBit(TAxis::kAxisRange,b);
856}
857
858//____________________________________________________________________
859Float_t AliCFGridSparse::GetOverFlows(Int_t ivar, Bool_t exclusive) const
860{
861 //
862 // Returns overflows in variable ivar
863 // Set 'exclusive' to true for an exclusive check on variable ivar
864 //
865 Int_t* bin = new Int_t[GetNVar()];
866 memset(bin, 0, sizeof(Int_t) * GetNVar());
867 Float_t ovfl=0.;
868 for (Long64_t i = 0; i < fData->GetNbins(); i++) {
869 Double_t v = fData->GetBinContent(i, bin);
870 Bool_t add=kTRUE;
871 if (exclusive) {
872 for(Int_t j=0;j<GetNVar();j++){
873 if(ivar==j)continue;
874 if((bin[j]==0) || (bin[j]==GetNBins(j)+1))add=kFALSE;
875 }
876 }
877 if(bin[ivar]==GetNBins(ivar)+1 && add) ovfl+=v;
878 }
879
880 delete[] bin;
881 return ovfl;
882}
883
884//____________________________________________________________________
885Float_t AliCFGridSparse::GetUnderFlows(Int_t ivar, Bool_t exclusive) const
886{
887 //
888 // Returns exclusive overflows in variable ivar
889 // Set 'exclusive' to true for an exclusive check on variable ivar
890 //
891 Int_t* bin = new Int_t[GetNVar()];
892 memset(bin, 0, sizeof(Int_t) * GetNVar());
893 Float_t unfl=0.;
894 for (Long64_t i = 0; i < fData->GetNbins(); i++) {
895 Double_t v = fData->GetBinContent(i, bin);
896 Bool_t add=kTRUE;
897 if (exclusive) {
898 for(Int_t j=0;j<GetNVar();j++){
899 if(ivar==j)continue;
900 if((bin[j]==0) || (bin[j]==GetNBins(j)+1))add=kFALSE;
901 }
902 }
903 if(bin[ivar]==0 && add) unfl+=v;
904 }
905
906 delete[] bin;
907 return unfl;
c8df672e 908}
fb494025 909