]> git.uio.no Git - u/mrichter/AliRoot.git/blame - CORRFW/AliCFGridSparse.cxx
macros developed by Luca Barioglio for patterns analysis
[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"
7036630f 36#include "AliCFUnfolding.h"
db6722a5 37
38//____________________________________________________________________
39ClassImp(AliCFGridSparse)
40
41//____________________________________________________________________
42AliCFGridSparse::AliCFGridSparse() :
fb494025 43 AliCFFrame(),
44 fSumW2(kFALSE),
db6722a5 45 fData(0x0)
46{
47 // default constructor
48}
49//____________________________________________________________________
50AliCFGridSparse::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 58AliCFGridSparse::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 71AliCFGridSparse::~AliCFGridSparse()
db6722a5 72{
73 //
fb494025 74 // destructor
db6722a5 75 //
fb494025 76 if (fData) delete fData;
db6722a5 77}
78
79//____________________________________________________________________
fb494025 80AliCFGridSparse::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 92AliCFGridSparse& 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//____________________________________________________________________
102void 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 115void 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 124void 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 135AliCFGridSparse* 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 169Float_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 179Float_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//____________________________________________________________________
189Float_t AliCFGridSparse::GetEntries() const
190{
191 //
192 // total entries (including overflows and underflows)
193 //
194
195 return fData->GetEntries();
196}
197
198//____________________________________________________________________
fb494025 199Float_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 208Float_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 217Float_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 229Float_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 238Float_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 247Float_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 259void 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 271void 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 279void 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 292void 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 304void 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 312void 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//____________________________________________________________________
325void 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 337void 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 353void 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 372void 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 390void 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 412void 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 432void 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//____________________________________________________________________
453void 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//____________________________________________________________________
470void 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//____________________________________________________________________
486void 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//____________________________________________________________________
502void 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//____________________________________________________________________
518void 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//____________________________________________________________________
529Long_t AliCFGridSparse::GetEmptyBins() const {
530 //
531 // Get empty bins
532 //
7411edfd 533
fb494025 534 return (GetNBinsTotal() - GetNFilledBins()) ;
535}
7411edfd 536
fb494025 537//____________________________________________________________________
538Int_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//_____________________________________________________________________
551Double_t AliCFGridSparse::GetIntegral() const
552{
553 //
554 // Get full Integral
555 //
556 return fData->ComputeIntegral();
557}
7411edfd 558
fb494025 559//____________________________________________________________________
560Long64_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//____________________________________________________________________
589void 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//____________________________________________________________________
601void 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 615TH1* 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 700void 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 711void 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 732void 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//____________________________________________________________________
743Float_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//____________________________________________________________________
769Float_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//____________________________________________________________________
796void 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}