2 /**************************************************************************
3 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16 //---------------------------------------------------------------------//
19 // Class to accumulate data on an N-dimensional grid, to be used //
20 // as input to get corrections for Reconstruction & Trigger efficiency //
21 // The class uses a one-dimensional array of floats to store the grid //
22 // --Author : S.Arcelli //
23 // Still to be done: //
24 // --Implement methods to merge cells //
25 // --Interpolate among bins in a range //
26 // This implementation will be aventually replaced byAliCFGridSparse //
27 //---------------------------------------------------------------------//
31 #include "AliCFGrid.h"
38 //____________________________________________________________________
41 //____________________________________________________________________
42 AliCFGrid::AliCFGrid() :
50 // default constructor
52 //____________________________________________________________________
53 AliCFGrid::AliCFGrid(const Char_t* name, const Char_t* title) :
54 AliCFVGrid(name,title),
61 // default constructor
64 //____________________________________________________________________
65 AliCFGrid::AliCFGrid(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t * nBinIn, const Double_t *binLimitsIn) :
66 AliCFVGrid(name,title,nVarIn,nBinIn,binLimitsIn),
78 fNunfl=new Float_t[fNVar];
79 fNovfl= new Float_t[fNVar];
84 for(Int_t j=0;j<fNVar;j++){
92 fData = new Float_t[fNDim];
95 for(Int_t j=0;j<fNDim;j++){
101 //____________________________________________________________________
102 AliCFGrid::AliCFGrid(const AliCFGrid& c) :
113 ((AliCFGrid &)c).Copy(*this);
116 //____________________________________________________________________
117 AliCFGrid::~AliCFGrid()
122 if(fNunfl)delete fNunfl;
123 if(fNovfl)delete fNovfl;
124 if(fData)delete fData;
125 if(fSumW2)delete fErr2;
128 //____________________________________________________________________
129 AliCFGrid &AliCFGrid::operator=(const AliCFGrid &c)
132 // assigment operator
135 ((AliCFGrid &) c).Copy(*this);
138 //____________________________________________________________________
139 Float_t AliCFGrid::GetElement(Int_t bin) const
142 // Returns grid element bin
145 AliInfo(Form(" element index outside the grid, return -1"));
150 //____________________________________________________________________
151 Float_t AliCFGrid::GetElement(Int_t *bin) const
154 // Get the content in a bin corresponding to a set of bin indexes
156 //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
157 for(Int_t i=0;i<fNVar; i++)fIndex[i]=bin[i]-1;
158 Int_t ind =GetBinIndex(fIndex);
159 return GetElement(ind);
161 //____________________________________________________________________
162 Float_t AliCFGrid::GetElement(Double_t *var) const
165 // Get the content in a bin corresponding to a set of input variables
169 for(Int_t i=0;i<fNVar;i++){
170 Int_t nbins=fNVarBins[i]+1;
171 Float_t *bins=new Float_t[nbins];
172 for(Int_t ibin =0;ibin<nbins;ibin++){
173 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
176 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
180 if(var[i] < bins[0]){
186 if(var[i] > bins[nbins-1]){
193 //move to the TH/THnSparse convention in N-dim bin numbering
194 for(Int_t i=0;i<fNVar; i++)fIndex[i]+=1;
196 if(!(ovfl==1 || unfl==1)){
197 return GetElement(fIndex);
200 AliInfo(Form(" input variables outside the grid, return -1"));
204 //____________________________________________________________________
205 Float_t AliCFGrid::GetElementError(Int_t iel) const
208 // Return the error on grid element iel
211 AliInfo(Form(" element index outside the grid, return -1"));
214 if(fSumW2)return TMath::Sqrt(fErr2[iel]);
215 return TMath::Sqrt(fData[iel]);
217 //____________________________________________________________________
218 Float_t AliCFGrid::GetElementError(Int_t *bin) const
221 // Get the error in a bin corresponding to a set of bin indeces
223 //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
224 for(Int_t i=0;i<fNVar; i++)fIndex[i]=bin[i]-1;
225 Int_t ind =GetBinIndex(fIndex);
226 return GetElementError(ind);
229 //____________________________________________________________________
230 Float_t AliCFGrid::GetElementError(Double_t *var) const
233 // Get the error in a bin corresponding to a set of input variables
237 for(Int_t i=0;i<fNVar;i++){
238 Int_t nbins=fNVarBins[i]+1;
239 Float_t *bins=new Float_t[nbins];
240 for(Int_t ibin =0;ibin<nbins;ibin++){
241 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
244 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
247 if(var[i] < bins[0]){
253 if(var[i] > bins[nbins-1]){
259 //move to the TH/THnSparse convention in N-dim bin numbering
260 for(Int_t i=0;i<fNVar; i++)fIndex[i]+=1;
261 if(!(ovfl==1 || unfl==1)){
262 return GetElementError(fIndex);
265 AliInfo(Form(" input variables outside the grid, return -1"));
269 //____________________________________________________________________
270 void AliCFGrid::SetElement(Int_t iel, Float_t val)
273 // Sets grid element iel to val
276 AliInfo(Form(" element index outside the grid, no value set"));
281 //____________________________________________________________________
282 void AliCFGrid::SetElement(Int_t *bin, Float_t val)
285 // Sets grid element of bin indeces bin to val
287 //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
288 for(Int_t i=0;i<fNVar; i++)fIndex[i]=bin[i]-1;
289 Int_t ind =GetBinIndex(fIndex);
292 //____________________________________________________________________
293 void AliCFGrid::SetElement(Double_t *var, Float_t val)
296 // Set the content in a bin to value val corresponding to a set of input variables
300 for(Int_t i=0;i<fNVar;i++){
301 Int_t nbins=fNVarBins[i]+1;
302 Float_t *bins=new Float_t[nbins];
303 for(Int_t ibin =0;ibin<nbins;ibin++){
304 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
307 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
310 if(var[i] < bins[0]){
316 if(var[i] > bins[nbins-1]){
322 //move to the TH/THnSparse convention in N-dim bin numbering
323 for(Int_t i=0;i<fNVar; i++)fIndex[i]+=1;
324 if(!(ovfl==1 || unfl==1)){
325 SetElement(fIndex,val);
328 AliInfo(Form(" input variables outside the grid, no value set"));
331 //____________________________________________________________________
332 void AliCFGrid::SetElementError(Int_t iel, Float_t val)
335 // Set squared error on grid element iel to val*val
338 AliInfo(Form(" element index outside the grid, no value set"));
344 //____________________________________________________________________
345 void AliCFGrid::SetElementError(Int_t *bin, Float_t val)
348 // Set squared error to val on grid element of bin indeces bin
350 //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
351 for(Int_t i=0;i<fNVar; i++)fIndex[i]=bin[i]-1;
352 Int_t ind =GetBinIndex(fIndex);
353 SetElementError(ind,val);
355 //____________________________________________________________________
356 void AliCFGrid::SetElementError(Double_t *var, Float_t val)
359 // Set squared error to val in a bin corresponding to a set of input variables
363 for(Int_t i=0;i<fNVar;i++){
364 Int_t nbins=fNVarBins[i]+1;
365 Float_t *bins=new Float_t[nbins];
366 for(Int_t ibin =0;ibin<nbins;ibin++){
367 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
370 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
373 if(var[i] < bins[0]){
379 if(var[i] > bins[nbins-1]){
385 //move to the TH/THnSparse convention in N-dim bin numbering
386 for(Int_t i=0;i<fNVar; i++)fIndex[i]+=1;
388 if(!(ovfl==1 || unfl==1)){
389 SetElementError(fIndex,val);
392 AliInfo(Form(" input variables outside the grid, no value set"));
395 //____________________________________________________________________
396 void AliCFGrid::Fill(Double_t *var, Double_t weight)
401 // given a set of values of the input variable,
402 // with weight (by default w=1)
408 Int_t *unfl=new Int_t[fNVar];
409 Int_t *ovfl=new Int_t[fNVar];
411 for(Int_t i=0;i<fNVar;i++){
416 for(Int_t i=0;i<fNVar;i++){
417 Int_t nbins=fNVarBins[i]+1;
418 Float_t *bins=new Float_t[nbins];
419 for(Int_t ibin =0;ibin<nbins;ibin++){
420 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
423 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
426 if(var[i] < bins[0]){
433 if(var[i] > bins[nbins-1]){
440 //exclusive under/overflows
442 for(Int_t i=0;i<fNVar;i++){
444 for(Int_t j=0;j<fNVar;j++){
446 if(!(unfl[j]==0 && ovfl[j]==0))add=kFALSE;
448 if(add && unfl[i]==1)fNunfl[i]++;
449 if(add && ovfl[i]==1)fNovfl[i]++;
455 // Total number of entries, overflows and underflows
459 //if not ovfl/unfl, fill the element
461 if(!(isovfl==1 || isunfl==1)){
462 Int_t ind =GetBinIndex(fIndex);
464 if(fSumW2)fErr2[ind]+=(weight*weight);
467 //____________________________________________________________________
468 Float_t AliCFGrid::GetOverFlows( Int_t ivar) const {
470 // Get overflows in variable var
474 //____________________________________________________________________
475 Float_t AliCFGrid::GetUnderFlows( Int_t ivar) const {
477 // Get overflows in variable var
481 //____________________________________________________________________
482 Float_t AliCFGrid::GetEntries( ) const {
484 // Get total entries (in grid + over/underflows)
488 //___________________________________________________________________
489 TH1D *AliCFGrid::Project(Int_t ivar) const
492 // Make a 1D projection along variable ivar
495 Int_t nbins =fNVarBins[ivar];
496 Float_t *bins = new Float_t[nbins+1];
497 for (Int_t i=0;i<=fNVar;i++){
499 for(Int_t ibin =0;ibin<nbins+1;ibin++){
500 bins[ibin] = fVarBinLimits[ibin+fOffset[ivar]];
504 sprintf(pname,"%s%s_%i",GetName(),"_proj1D_var", ivar);
506 sprintf(htitle,"%s%s_%i",GetName(),"_proj1D_var", ivar);
510 //check if a projection with identical name exist
511 TObject *obj = gROOT->FindObject(pname);
512 if (obj && obj->InheritsFrom("TH1D")) {
518 proj1D =new TH1D(pname,htitle, nbins, bins);
523 Float_t *data= new Float_t[nbins];
524 Float_t *err= new Float_t[nbins];
526 for(Int_t ibin=0;ibin<nbins;ibin++)data[ibin]=0;
527 for(Int_t ibin=0;ibin<nbins;ibin++)err[ibin]=0;
528 for(Int_t iel=0;iel<fNDim;iel++){
529 data[GetBinIndex(ivar,iel)]+=fData[iel];
530 if(fSumW2)err[GetBinIndex(ivar,iel)]+=fErr2[iel];
533 for(Int_t ibin =0;ibin<nbins;ibin++){
534 proj1D->SetBinContent(ibin+1,data[ibin]);
535 proj1D->SetBinError(ibin+1,TMath::Sqrt(data[ibin]));
536 if(fSumW2)proj1D->SetBinError(ibin+1,TMath::Sqrt(err[ibin]));
542 proj1D->SetBinContent(nbins+1,GetOverFlows(ivar));
543 proj1D->SetBinContent(0,GetUnderFlows(ivar));
544 proj1D->SetEntries(fNentriesTot);
548 //___________________________________________________________________
549 TH2D *AliCFGrid::Project(Int_t ivar1, Int_t ivar2) const
552 // Make a 2D projection along variable ivar
554 Int_t nbins1 =fNVarBins[ivar1];
555 Int_t nbins2 =fNVarBins[ivar2];
557 Float_t *bins1 = new Float_t[nbins1+1];
558 Float_t *bins2 = new Float_t[nbins2+1];
560 for(Int_t ibin =0;ibin<nbins1+1;ibin++){
561 bins1[ibin] = fVarBinLimits[ibin+fOffset[ivar1]];
563 for(Int_t ibin =0;ibin<nbins2+1;ibin++){
564 bins2[ibin] = fVarBinLimits[ibin+fOffset[ivar2]];
568 sprintf(pname,"%s%s_%i_%i",GetName(),"_proj2D_var",ivar1,ivar2);
570 sprintf(htitle,"%s%s_%i_%i",GetName(),"_proj2D_var",ivar1,ivar2);
574 //check if a projection with identical name exist
575 TObject *obj = gROOT->FindObject(pname);
576 if (obj && obj->InheritsFrom("TH2D")) {
582 proj2D =new TH2D(pname,htitle, nbins1, bins1,nbins2,bins2);
590 Float_t **data=new Float_t*[nbins1];
591 Float_t *data2=new Float_t[nbins1*nbins2];
592 Float_t **err=new Float_t*[nbins1];
593 Float_t *err2=new Float_t[nbins1*nbins2];
594 for(Int_t i=0;i<nbins1;i++)data[i] = data2+i*nbins2;
595 for(Int_t i=0;i<nbins1;i++)err[i] = err2+i*nbins2;
597 for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
598 for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
599 data[ibin1][ibin2]=0;
604 for(Int_t iel=0;iel<fNDim;iel++){
605 data[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)]+=fData[iel];
606 if(fSumW2)err[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)]+=fErr2[iel];
609 for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
610 for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
611 proj2D->SetBinContent(ibin1+1,ibin2+1,data[ibin1][ibin2]);
612 proj2D->SetBinError(ibin1+1,ibin2+1,TMath::Sqrt(data[ibin1][ibin2]));
613 if(fSumW2)proj2D->SetBinError(ibin1+1,ibin2+1,TMath::Sqrt(err[ibin1][ibin2]));
614 sum+=data[ibin1][ibin2];
622 proj2D->SetBinContent(0,nbins2/2,GetUnderFlows(ivar1));
623 proj2D->SetBinContent(nbins1+1,nbins2/2,GetOverFlows(ivar1));
624 proj2D->SetBinContent(nbins1/2,0,GetUnderFlows(ivar2));
625 proj2D->SetBinContent(nbins1/2,nbins2+1,GetOverFlows(ivar2));
626 proj2D->SetEntries(fNentriesTot);
629 //___________________________________________________________________
630 TH3D *AliCFGrid::Project(Int_t ivar1, Int_t ivar2, Int_t ivar3) const
633 // Make a 3D projection along variable ivar
635 Int_t nbins1 =fNVarBins[ivar1];
636 Int_t nbins2 =fNVarBins[ivar2];
637 Int_t nbins3 =fNVarBins[ivar3];
639 Float_t *bins1 = new Float_t[nbins1+1];
640 Float_t *bins2 = new Float_t[nbins2+1];
641 Float_t *bins3 = new Float_t[nbins3+1];
643 for(Int_t ibin =0;ibin<nbins1+1;ibin++){
644 bins1[ibin] = fVarBinLimits[ibin+fOffset[ivar1]];
646 for(Int_t ibin =0;ibin<nbins2+1;ibin++){
647 bins2[ibin] = fVarBinLimits[ibin+fOffset[ivar2]];
649 for(Int_t ibin =0;ibin<nbins3+1;ibin++){
650 bins3[ibin] = fVarBinLimits[ibin+fOffset[ivar3]];
654 sprintf(pname,"%s%s_%i_%i_%i",GetName(),"_proj3D_var",ivar1,ivar2,ivar3);
656 sprintf(htitle,"%s%s_%i_%i_%i",GetName(),"_proj3D_var",ivar1,ivar2,ivar3);
660 //check if a projection with identical name exist
661 TObject *obj = gROOT->FindObject(pname);
662 if (obj && obj->InheritsFrom("TH3D")) {
668 proj3D =new TH3D(pname,htitle, nbins1,bins1,nbins2,bins2,nbins3,bins3);
677 Float_t ***data=new Float_t**[nbins1];
678 Float_t **data2=new Float_t*[nbins1*nbins2];
679 Float_t *data3=new Float_t[nbins1*nbins2*nbins3];
680 Float_t ***err=new Float_t**[nbins1];
681 Float_t **err2=new Float_t*[nbins1*nbins2];
682 Float_t *err3=new Float_t[nbins1*nbins2*nbins3];
683 for(Int_t i=0;i<nbins1;i++)data[i] = data2+i*nbins2;
684 for(Int_t i=0;i<nbins1;i++)err[i] = err2+i*nbins2;
685 for(Int_t i=0;i<nbins1;i++){
686 for(Int_t j=0;j<nbins2;j++){
687 data[i][j] = data3+i*nbins2*nbins3+j*nbins3;
688 err[i][j] = err3+i*nbins2*nbins3+j*nbins3;
691 for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
692 for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
693 for(Int_t ibin3 =0;ibin3<nbins3;ibin3++){
694 data[ibin1][ibin2][ibin3]=0;
695 err[ibin1][ibin2][ibin3]=0;
700 for(Int_t iel=0;iel<fNDim;iel++){
701 data[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)][GetBinIndex(ivar3,iel)]+=fData[iel];
702 if(fSumW2)err[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)][GetBinIndex(ivar3,iel)]+=fErr2[iel];
705 for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
706 for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
707 for(Int_t ibin3 =0;ibin3<nbins3;ibin3++){
708 proj3D->SetBinContent(ibin1+1,ibin2+1,ibin3+1,data[ibin1][ibin2][ibin3]);
709 proj3D->SetBinError(ibin1+1,ibin2+1,ibin3+1,TMath::Sqrt(data[ibin1][ibin2][ibin3]));
710 if(fSumW2)proj3D->SetBinError(ibin1+1,ibin2+1,ibin3+1,TMath::Sqrt(err[ibin1][ibin2][ibin3]));
711 sum+=data[ibin1][ibin2][ibin3];
723 proj3D->SetEntries(fNentriesTot);
727 //___________________________________________________________________
728 TH1D *AliCFGrid::Slice(Int_t ivar, Double_t *varMin, Double_t* varMax) const
731 // Make a slice along variable ivar in range [varMin,varMax]
734 Int_t nbins =fNVarBins[ivar];
735 Float_t *bins = new Float_t[nbins+1];
736 for (Int_t i=0;i<=fNVar;i++){
738 for(Int_t ibin =0;ibin<nbins+1;ibin++){
739 bins[ibin] = fVarBinLimits[ibin+fOffset[ivar]];
743 sprintf(pname,"%s%s_%i",GetName(),"_proj1D_var", ivar);
745 sprintf(htitle,"%s%s_%i",GetName(),"_proj1D_var", ivar);
749 //check if a projection with identical name exist
750 TObject *obj = gROOT->FindObject(pname);
751 if (obj && obj->InheritsFrom("TH1D")) {
757 proj1D =new TH1D(pname,htitle, nbins, bins);
763 Int_t *indexMin=new Int_t[fNVar];
764 Int_t *indexMax=new Int_t[fNVar];
767 //Find out the min and max bins
769 for(Int_t i=0;i<fNVar;i++){
770 Float_t xmin=varMin[i]; // the min values
771 Float_t xmax=varMax[i]; // the min values
772 Int_t nbins=fNVarBins[i]+1;
773 Float_t *bins=new Float_t[nbins];
774 for(Int_t ibin =0;ibin<nbins;ibin++){
775 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
777 indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
778 indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
783 Float_t *data= new Float_t[nbins];
784 for(Int_t ibin=0;ibin<nbins;ibin++)data[ibin]=0;
786 Int_t *index= new Int_t[fNVar];
787 Int_t ielmin=GetBinIndex(indexMin);
788 Int_t ielmax=GetBinIndex(indexMax);
789 for(Int_t iel=ielmin;iel<=ielmax;iel++){
790 GetBinIndex(iel,index);
792 for (Int_t j=0;j<fNVar;j++){
793 if(!(index[j]>=indexMin[j] && index[j]<=indexMax[j]))isIn=kFALSE;
796 if(isIn)data[GetBinIndex(ivar,iel)]+=fData[iel];
802 for(Int_t ibin =0;ibin<nbins;ibin++){
803 proj1D->SetBinContent(ibin+1,data[ibin]);
804 proj1D->SetBinError(ibin+1,TMath::Sqrt(data[ibin]));
810 proj1D->SetEntries(sum);
815 //____________________________________________________________________
816 void AliCFGrid::Add(AliCFVGrid* aGrid, Double_t c)
819 //add aGrid to the current one
822 if(aGrid->GetNVar()!=fNVar){
823 AliInfo("Different number of variables, cannot add the grids");
826 if(aGrid->GetNDim()!=fNDim){
827 AliInfo("Different number of dimensions, cannot add the grids!");
831 if(!fSumW2 && aGrid->GetSumW2())SumW2();
833 for(Int_t iel=0;iel<fNDim;iel++){
834 fData[iel]+=(c*aGrid->GetElement(iel));
836 Float_t err=aGrid->GetElementError(iel);
837 fErr2[iel]+=c*c*err*err;
841 //Add entries, overflows and underflows
843 fNentriesTot+= c*aGrid->GetEntries();
844 for(Int_t j=0;j<fNVar;j++){
845 fNunfl[j]+= c*aGrid->GetUnderFlows(j);
846 fNovfl[j]+= c*aGrid->GetOverFlows(j);
849 //____________________________________________________________________
850 void AliCFGrid::Add(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1,Double_t c2)
853 //add aGrid1 and aGrid2
856 if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
857 AliInfo("Different number of variables, cannot add the grids");
860 if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
861 AliInfo("Different number of dimensions, cannot add the grids!");
865 if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
867 Float_t cont1,cont2,err1,err2;
869 for(Int_t iel=0;iel<fNDim;iel++){
870 cont1=aGrid1->GetElement(iel);
871 cont2=aGrid2->GetElement(iel);
872 SetElement(iel,c1*cont1+c2*cont2);
874 err1=aGrid1->GetElementError(iel);
875 err2=aGrid2->GetElementError(iel);
876 SetElementError(iel,TMath::Sqrt(c1*c1*err1*err1+c2*c2*err2*err2));
880 //Add entries, overflows and underflows
882 fNentriesTot= c1*aGrid1->GetEntries()+c2*aGrid2->GetEntries();
883 for(Int_t j=0;j<fNVar;j++){
884 fNunfl[j]= c1*aGrid1->GetUnderFlows(j)+c2*aGrid2->GetUnderFlows(j);
885 fNovfl[j]= c1*aGrid1->GetOverFlows(j)+c2*aGrid2->GetOverFlows(j);
888 //____________________________________________________________________
889 void AliCFGrid::Multiply(AliCFVGrid* aGrid, Double_t c)
892 //multiply grid aGrid by the current one
895 if(aGrid->GetNVar()!=fNVar){
896 AliInfo("Different number of variables, cannot multiply the grids");
899 if(aGrid->GetNDim()!=fNDim){
900 AliInfo("Different number of dimensions, cannot multiply the grids!");
904 if(!fSumW2 && aGrid->GetSumW2())SumW2();
906 Float_t cont1,cont2,err1,err2;
908 for(Int_t iel=0;iel<fNDim;iel++){
909 cont1=GetElement(iel);
910 cont2=c*aGrid->GetElement(iel);
911 SetElement(iel,cont1*cont2);
913 err1=GetElementError(iel);
914 err2=aGrid->GetElementError(iel);
915 SetElementError(iel,TMath::Sqrt(c*c*(cont2*cont2*err1*err1+cont1*cont1*err2*err2)));
919 //Set entries to the number of bins, preserve original overflows and underflows
922 for(Int_t j=0;j<fNVar;j++){
923 fNunfl[j]= GetUnderFlows(j);
924 fNovfl[j]= GetOverFlows(j);
927 //____________________________________________________________________
928 void AliCFGrid::Multiply(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1, Double_t c2)
931 //multiply grids aGrid1 and aGrid2
934 if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
935 AliInfo("Different number of variables, cannot multiply the grids");
938 if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
939 AliInfo("Different number of dimensions, cannot multiply the grids!");
943 if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
945 Float_t cont1,cont2,err1,err2;
946 for(Int_t iel=0;iel<fNDim;iel++){
947 cont1=c1*aGrid1->GetElement(iel);
948 cont2=c2*aGrid2->GetElement(iel);
949 SetElement(iel,cont1*cont2);
951 err1=aGrid1->GetElementError(iel);
952 err2=aGrid2->GetElementError(iel);
953 SetElementError(iel,TMath::Sqrt(c1*c1*c2*c2*(cont2*cont2*err1*err1+cont1*cont1*err2*err2)));
957 //Set entries to the number of bins, preserve original overflows and underflows
960 for(Int_t j=0;j<fNVar;j++){
961 fNunfl[j]= GetUnderFlows(j);
962 fNovfl[j]= GetOverFlows(j);
965 //____________________________________________________________________
966 void AliCFGrid::Divide(AliCFVGrid* aGrid, Double_t c)
969 //divide current grid by grid aGrid
972 if(aGrid->GetNVar()!=fNVar){
973 AliInfo("Different number of variables, cannot divide the grids");
976 if(aGrid->GetNDim()!=fNDim){
977 AliInfo("Different number of dimensions, cannot divide the grids!");
980 if(!c){AliInfo(Form("c is %f, cannot divide!",c)); return;}
982 if(!fSumW2 && aGrid->GetSumW2())SumW2();
984 Float_t cont1,cont2,err1,err2,den;
985 for(Int_t iel=0;iel<fNDim;iel++){
986 cont1=GetElement(iel);
987 cont2=aGrid->GetElement(iel);
988 if(cont2)SetElement(iel,cont1/(c*cont2));
989 else SetElement(iel,0);
991 err1=GetElementError(iel);
992 err2=aGrid->GetElementError(iel);
993 if(!cont2){SetElementError(iel,0.); continue;}
994 den=cont2*cont2*cont2*c*c;
995 SetElementError(iel,TMath::Sqrt((cont2*cont2*err1*err1+cont1*cont1*err2*err2)/den));
999 //Set entries to the number of bins, preserve original overflows and underflows
1002 for(Int_t j=0;j<fNVar;j++){
1003 fNunfl[j]= GetUnderFlows(j);
1004 fNovfl[j]= GetOverFlows(j);
1007 //____________________________________________________________________
1008 void AliCFGrid::Divide(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1,Double_t c2, Option_t *option)
1011 //divide grids aGrid1,aGrid2
1014 TString opt = option;
1017 if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
1018 AliInfo("Different number of variables, cannot divide the grids");
1021 if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
1022 AliInfo("Different number of dimensions, cannot divide the grids!");
1025 if(!c2){AliInfo(Form("c2 is %f, cannot divide!",c2)); return;}
1027 if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
1029 Float_t cont1,cont2,err1,err2,r,den;
1031 for(Int_t iel=0;iel<fNDim;iel++){
1032 cont1=aGrid1->GetElement(iel);
1033 cont2=aGrid2->GetElement(iel);
1034 if(cont2)SetElement(iel,c1*cont1/(c2*cont2));
1035 else SetElement(iel,0);
1037 err1=aGrid1->GetElementError(iel);
1038 err2=aGrid2->GetElementError(iel);
1039 if(!cont2){SetElementError(iel,0.); continue;}
1040 if (opt.Contains("B")){
1043 SetElementError(iel,TMath::Sqrt(TMath::Abs(((1.-2.*r)*err1*err1+r*r*err2*err2)/(cont2*cont2))));
1045 SetElementError(iel,0.);
1048 den=cont2*cont2*cont2*cont2*c2*c2;
1049 SetElementError(iel,TMath::Sqrt(c1*c1*(cont2*cont2*err1*err1+cont1*cont1*err2*err2)/den));
1054 //Set entries to the number of bins, preserve original overflows and underflows
1057 for(Int_t j=0;j<fNVar;j++){
1058 fNunfl[j]= GetUnderFlows(j);
1059 fNovfl[j]= GetOverFlows(j);
1062 //____________________________________________________________________
1063 void AliCFGrid::Rebin(const Int_t* group)
1066 // Not yet implemented
1068 for(Int_t i=0;i<fNVar;i++){
1069 if(group[i]!=1)AliInfo(Form(" merging bins along dimension %i in groups of %i bins", i,group[i]));
1071 AliInfo(Form("This method was so far not implemented for AliCFGrid, but it is available in AliCFGridSparse"));
1074 //____________________________________________________________________
1075 void AliCFGrid::SumW2()
1078 //set calculation of the squared sum of the weighted entries
1081 fErr2=new Float_t [fNDim];
1083 for(Int_t iel=0;iel<fNDim;iel++){
1084 fErr2[iel]=fData[iel];
1090 //____________________________________________________________________
1091 void AliCFGrid::Copy(TObject& c) const
1096 AliCFGrid& target = (AliCFGrid &) c;
1098 target.fNentriesTot = fNentriesTot;
1100 target.fNunfl = fNunfl;
1102 target.fNovfl = fNovfl;
1104 target.fData = fData;
1106 target.fErr2 = fErr2;
1109 //____________________________________________________________________
1110 void AliCFGrid::SetExcludeOffEntriesInProj(Bool_t in)
1113 // require under/overflows in 'hidden dimensions' to be excluded
1114 // or included, when performing projections.
1115 // For AliCFGrid implementation, only option = kTRUE is available
1118 AliInfo(Form("This option is not available for AliCFGrid, Under/Overflows in hidden dimensions are always excluded"));
1122 fExclOffEntriesInProj=in;
1124 //____________________________________________________________________
1125 Bool_t AliCFGrid::GetExcludeOffEntriesInProj( ) const
1128 // return flag saying whether under/overflows are excluded in projections
1131 return fExclOffEntriesInProj;