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() :
52 // default constructor
54 //____________________________________________________________________
55 AliCFGrid::AliCFGrid(const Char_t* name, const Char_t* title) :
56 AliCFVGrid(name,title),
65 // default constructor
68 //____________________________________________________________________
69 AliCFGrid::AliCFGrid(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t * nBinIn, const Double_t *binLimitsIn) :
70 AliCFVGrid(name,title,nVarIn,nBinIn,binLimitsIn),
84 fNunfl=new Float_t[fNVar];
85 fNovfl= new Float_t[fNVar];
92 for(Int_t j=0;j<fNVar;j++){
100 fData = new Float_t[fNDim]; //num
106 //____________________________________________________________________
107 AliCFGrid::AliCFGrid(const AliCFGrid& c) :
120 ((AliCFGrid &)c).Copy(*this);
123 //____________________________________________________________________
124 AliCFGrid::~AliCFGrid()
129 if(fNunfl)delete fNunfl;
130 if(fNovfl)delete fNovfl;
131 if(fData)delete fData;
132 if(fSumW2)delete fErr2;
135 //____________________________________________________________________
136 AliCFGrid &AliCFGrid::operator=(const AliCFGrid &c)
139 // assigment operator
142 ((AliCFGrid &) c).Copy(*this);
145 //____________________________________________________________________
146 Float_t AliCFGrid::GetElement(Int_t bin) const
149 // Returns grid element bin
152 AliInfo(Form(" element index outside the grid, return -1"));
157 //____________________________________________________________________
158 Float_t AliCFGrid::GetElement(Int_t *bin) const
161 // Get the content in a bin corresponding to a set of bin indexes
163 //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
164 for(Int_t i=0;i<fNVar; i++)fIndex[i]=bin[i]-1;
165 Int_t ind =GetBinIndex(fIndex);
166 return GetElement(ind);
168 //____________________________________________________________________
169 Float_t AliCFGrid::GetElement(Double_t *var) const
172 // Get the content in a bin corresponding to a set of input variables
176 for(Int_t i=0;i<fNVar;i++){
177 Int_t nbins=fNVarBins[i]+1;
178 Float_t *bins=new Float_t[nbins];
179 for(Int_t ibin =0;ibin<nbins;ibin++){
180 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
183 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
187 if(var[i] < bins[0]){
193 if(var[i] > bins[nbins-1]){
200 //move to the TH/THnSparse convention in N-dim bin numbering
201 for(Int_t i=0;i<fNVar; i++)fIndex[i]+=1;
203 if(!(ovfl==1 || unfl==1)){
204 return GetElement(fIndex);
207 AliInfo(Form(" input variables outside the grid, return -1"));
211 //____________________________________________________________________
212 Float_t AliCFGrid::GetElementError(Int_t iel) const
215 // Return the error on grid element iel
218 AliInfo(Form(" element index outside the grid, return -1"));
221 if(fSumW2)return TMath::Sqrt(fErr2[iel]);
222 return TMath::Sqrt(fData[iel]);
224 //____________________________________________________________________
225 Float_t AliCFGrid::GetElementError(Int_t *bin) const
228 // Get the error in a bin corresponding to a set of bin indeces
230 //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
231 for(Int_t i=0;i<fNVar; i++)fIndex[i]=bin[i]-1;
232 Int_t ind =GetBinIndex(fIndex);
233 return GetElementError(ind);
236 //____________________________________________________________________
237 Float_t AliCFGrid::GetElementError(Double_t *var) const
240 // Get the error in a bin corresponding to a set of input variables
244 for(Int_t i=0;i<fNVar;i++){
245 Int_t nbins=fNVarBins[i]+1;
246 Float_t *bins=new Float_t[nbins];
247 for(Int_t ibin =0;ibin<nbins;ibin++){
248 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
251 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
254 if(var[i] < bins[0]){
260 if(var[i] > bins[nbins-1]){
266 //move to the TH/THnSparse convention in N-dim bin numbering
267 for(Int_t i=0;i<fNVar; i++)fIndex[i]+=1;
268 if(!(ovfl==1 || unfl==1)){
269 return GetElementError(fIndex);
272 AliInfo(Form(" input variables outside the grid, return -1"));
276 //____________________________________________________________________
277 void AliCFGrid::SetElement(Int_t iel, Float_t val)
280 // Sets grid element iel to val
283 AliInfo(Form(" element index outside the grid, no value set"));
288 //____________________________________________________________________
289 void AliCFGrid::SetElement(Int_t *bin, Float_t val)
292 // Sets grid element of bin indeces bin to val
294 //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
295 for(Int_t i=0;i<fNVar; i++)fIndex[i]=bin[i]-1;
296 Int_t ind =GetBinIndex(fIndex);
299 //____________________________________________________________________
300 void AliCFGrid::SetElement(Double_t *var, Float_t val)
303 // Set the content in a bin to value val corresponding to a set of input variables
307 for(Int_t i=0;i<fNVar;i++){
308 Int_t nbins=fNVarBins[i]+1;
309 Float_t *bins=new Float_t[nbins];
310 for(Int_t ibin =0;ibin<nbins;ibin++){
311 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
314 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
317 if(var[i] < bins[0]){
323 if(var[i] > bins[nbins-1]){
329 //move to the TH/THnSparse convention in N-dim bin numbering
330 for(Int_t i=0;i<fNVar; i++)fIndex[i]+=1;
331 if(!(ovfl==1 || unfl==1)){
332 SetElement(fIndex,val);
335 AliInfo(Form(" input variables outside the grid, no value set"));
338 //____________________________________________________________________
339 void AliCFGrid::SetElementError(Int_t iel, Float_t val)
342 // Set squared error on grid element iel to val*val
345 AliInfo(Form(" element index outside the grid, no value set"));
351 //____________________________________________________________________
352 void AliCFGrid::SetElementError(Int_t *bin, Float_t val)
355 // Set squared error to val on grid element of bin indeces bin
357 //-1 is to move from TH/ThnSparse N-dim bin convention to one in AliCFFrame
358 for(Int_t i=0;i<fNVar; i++)fIndex[i]=bin[i]-1;
359 Int_t ind =GetBinIndex(fIndex);
360 SetElementError(ind,val);
362 //____________________________________________________________________
363 void AliCFGrid::SetElementError(Double_t *var, Float_t val)
366 // Set squared error to val in a bin corresponding to a set of input variables
370 for(Int_t i=0;i<fNVar;i++){
371 Int_t nbins=fNVarBins[i]+1;
372 Float_t *bins=new Float_t[nbins];
373 for(Int_t ibin =0;ibin<nbins;ibin++){
374 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
377 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
380 if(var[i] < bins[0]){
386 if(var[i] > bins[nbins-1]){
392 //move to the TH/THnSparse convention in N-dim bin numbering
393 for(Int_t i=0;i<fNVar; i++)fIndex[i]+=1;
395 if(!(ovfl==1 || unfl==1)){
396 SetElementError(fIndex,val);
399 AliInfo(Form(" input variables outside the grid, no value set"));
402 //____________________________________________________________________
403 void AliCFGrid::Fill(Double_t *var, Double_t weight)
408 // given a set of values of the input variable,
409 // with weight (by default w=1)
415 Int_t *unfl=new Int_t[fNVar];
416 Int_t *ovfl=new Int_t[fNVar];
418 for(Int_t i=0;i<fNVar;i++){
423 for(Int_t i=0;i<fNVar;i++){
424 Int_t nbins=fNVarBins[i]+1;
425 Float_t *bins=new Float_t[nbins];
426 for(Int_t ibin =0;ibin<nbins;ibin++){
427 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
430 fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
433 if(var[i] < bins[0]){
440 if(var[i] > bins[nbins-1]){
447 //exclusive under/overflows
449 for(Int_t i=0;i<fNVar;i++){
451 for(Int_t j=0;j<fNVar;j++){
453 if(!(unfl[j]==0 && ovfl[j]==0))add=kFALSE;
455 if(add && unfl[i]==1)fNunfl[i]++;
456 if(add && ovfl[i]==1)fNovfl[i]++;
462 // Total number of entries, overflows and underflows
465 if(isunfl)fNunflTot++;
466 if(isovfl)fNovflTot++;
468 //if not ovfl/unfl, fill the element
470 if(!(isovfl==1 || isunfl==1)){
471 Int_t ind =GetBinIndex(fIndex);
473 if(fSumW2)fErr2[ind]+=(weight*weight);
476 //____________________________________________________________________
477 Float_t AliCFGrid::GetOverFlows( Int_t ivar) const {
479 // Get overflows in variable var
483 //____________________________________________________________________
484 Float_t AliCFGrid::GetOverFlows() const {
490 //____________________________________________________________________
491 Float_t AliCFGrid::GetUnderFlows( Int_t ivar) const {
493 // Get overflows in variable var
497 //____________________________________________________________________
498 Float_t AliCFGrid::GetUnderFlows() const {
504 //____________________________________________________________________
505 Float_t AliCFGrid::GetEntries( ) const {
507 // Get total entries (in grid + over/underflows)
511 //___________________________________________________________________
512 TH1D *AliCFGrid::Project(Int_t ivar) const
515 // Make a 1D projection along variable ivar
518 Int_t nbins =fNVarBins[ivar];
519 Float_t *bins = new Float_t[nbins+1];
520 for (Int_t i=0;i<=fNVar;i++){
522 for(Int_t ibin =0;ibin<nbins+1;ibin++){
523 bins[ibin] = fVarBinLimits[ibin+fOffset[ivar]];
527 sprintf(pname,"%s%s_%i",GetName(),"_proj1D_var", ivar);
529 sprintf(htitle,"%s%s_%i",GetName(),"_proj1D_var", ivar);
533 //check if a projection with identical name exist
534 TObject *obj = gROOT->FindObject(pname);
535 if (obj && obj->InheritsFrom("TH1D")) {
541 proj1D =new TH1D(pname,htitle, nbins, bins);
546 Float_t *data= new Float_t[nbins];
547 Float_t *err= new Float_t[nbins];
549 for(Int_t ibin=0;ibin<nbins;ibin++)data[ibin]=0;
550 for(Int_t ibin=0;ibin<nbins;ibin++)err[ibin]=0;
551 for(Int_t iel=0;iel<fNDim;iel++){
552 data[GetBinIndex(ivar,iel)]+=fData[iel];
553 if(fSumW2)err[GetBinIndex(ivar,iel)]+=fErr2[iel];
556 for(Int_t ibin =0;ibin<nbins;ibin++){
557 proj1D->SetBinContent(ibin+1,data[ibin]);
558 proj1D->SetBinError(ibin+1,TMath::Sqrt(data[ibin]));
559 if(fSumW2)proj1D->SetBinError(ibin+1,TMath::Sqrt(err[ibin]));
565 proj1D->SetBinContent(nbins+1,GetOverFlows(ivar));
566 proj1D->SetBinContent(0,GetUnderFlows(ivar));
567 proj1D->SetEntries(sum+GetUnderFlows(ivar)+GetOverFlows(ivar));
571 //___________________________________________________________________
572 TH2D *AliCFGrid::Project(Int_t ivar1, Int_t ivar2) const
575 // Make a 2D projection along variable ivar
577 Int_t nbins1 =fNVarBins[ivar1];
578 Int_t nbins2 =fNVarBins[ivar2];
580 Float_t *bins1 = new Float_t[nbins1+1];
581 Float_t *bins2 = new Float_t[nbins2+1];
583 for(Int_t ibin =0;ibin<nbins1+1;ibin++){
584 bins1[ibin] = fVarBinLimits[ibin+fOffset[ivar1]];
586 for(Int_t ibin =0;ibin<nbins2+1;ibin++){
587 bins2[ibin] = fVarBinLimits[ibin+fOffset[ivar2]];
591 sprintf(pname,"%s%s_%i_%i",GetName(),"_proj2D_var",ivar1,ivar2);
593 sprintf(htitle,"%s%s_%i_%i",GetName(),"_proj2D_var",ivar1,ivar2);
597 //check if a projection with identical name exist
598 TObject *obj = gROOT->FindObject(pname);
599 if (obj && obj->InheritsFrom("TH2D")) {
605 proj2D =new TH2D(pname,htitle, nbins1, bins1,nbins2,bins2);
613 Float_t **data=new Float_t*[nbins1];
614 Float_t *data2=new Float_t[nbins1*nbins2];
615 Float_t **err=new Float_t*[nbins1];
616 Float_t *err2=new Float_t[nbins1*nbins2];
617 for(Int_t i=0;i<nbins1;i++)data[i] = data2+i*nbins2;
618 for(Int_t i=0;i<nbins1;i++)err[i] = err2+i*nbins2;
620 for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
621 for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
622 data[ibin1][ibin2]=0;
627 for(Int_t iel=0;iel<fNDim;iel++){
628 data[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)]+=fData[iel];
629 if(fSumW2)err[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)]+=fErr2[iel];
632 for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
633 for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
634 proj2D->SetBinContent(ibin1+1,ibin2+1,data[ibin1][ibin2]);
635 proj2D->SetBinError(ibin1+1,ibin2+1,TMath::Sqrt(data[ibin1][ibin2]));
636 if(fSumW2)proj2D->SetBinError(ibin1+1,ibin2+1,TMath::Sqrt(err[ibin1][ibin2]));
637 sum+=data[ibin1][ibin2];
645 proj2D->SetBinContent(0,nbins2/2,GetUnderFlows(ivar1));
646 proj2D->SetBinContent(nbins1+1,nbins2/2,GetOverFlows(ivar1));
647 proj2D->SetBinContent(nbins1/2,0,GetUnderFlows(ivar2));
648 proj2D->SetBinContent(nbins1/2,nbins2+1,GetOverFlows(ivar2));
649 proj2D->SetEntries(sum+GetUnderFlows(ivar1)+GetOverFlows(ivar1)+GetUnderFlows(ivar2)+GetOverFlows(ivar2));
652 //___________________________________________________________________
653 TH3D *AliCFGrid::Project(Int_t ivar1, Int_t ivar2, Int_t ivar3) const
656 // Make a 3D projection along variable ivar
658 Int_t nbins1 =fNVarBins[ivar1];
659 Int_t nbins2 =fNVarBins[ivar2];
660 Int_t nbins3 =fNVarBins[ivar3];
662 Float_t *bins1 = new Float_t[nbins1+1];
663 Float_t *bins2 = new Float_t[nbins2+1];
664 Float_t *bins3 = new Float_t[nbins3+1];
666 for(Int_t ibin =0;ibin<nbins1+1;ibin++){
667 bins1[ibin] = fVarBinLimits[ibin+fOffset[ivar1]];
669 for(Int_t ibin =0;ibin<nbins2+1;ibin++){
670 bins2[ibin] = fVarBinLimits[ibin+fOffset[ivar2]];
672 for(Int_t ibin =0;ibin<nbins3+1;ibin++){
673 bins3[ibin] = fVarBinLimits[ibin+fOffset[ivar3]];
677 sprintf(pname,"%s%s_%i_%i_%i",GetName(),"_proj3D_var",ivar1,ivar2,ivar3);
679 sprintf(htitle,"%s%s_%i_%i_%i",GetName(),"_proj3D_var",ivar1,ivar2,ivar3);
683 //check if a projection with identical name exist
684 TObject *obj = gROOT->FindObject(pname);
685 if (obj && obj->InheritsFrom("TH3D")) {
691 proj3D =new TH3D(pname,htitle, nbins1,bins1,nbins2,bins2,nbins3,bins3);
700 Float_t ***data=new Float_t**[nbins1];
701 Float_t **data2=new Float_t*[nbins1*nbins2];
702 Float_t *data3=new Float_t[nbins1*nbins2*nbins3];
703 Float_t ***err=new Float_t**[nbins1];
704 Float_t **err2=new Float_t*[nbins1*nbins2];
705 Float_t *err3=new Float_t[nbins1*nbins2*nbins3];
706 for(Int_t i=0;i<nbins1;i++)data[i] = data2+i*nbins2;
707 for(Int_t i=0;i<nbins1;i++)err[i] = err2+i*nbins2;
708 for(Int_t i=0;i<nbins1;i++){
709 for(Int_t j=0;j<nbins2;j++){
710 data[i][j] = data3+i*nbins2*nbins3+j*nbins3;
711 err[i][j] = err3+i*nbins2*nbins3+j*nbins3;
714 for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
715 for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
716 for(Int_t ibin3 =0;ibin3<nbins3;ibin3++){
717 data[ibin1][ibin2][ibin3]=0;
718 err[ibin1][ibin2][ibin3]=0;
723 for(Int_t iel=0;iel<fNDim;iel++){
724 data[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)][GetBinIndex(ivar3,iel)]+=fData[iel];
725 if(fSumW2)err[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)][GetBinIndex(ivar3,iel)]+=fErr2[iel];
728 for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
729 for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
730 for(Int_t ibin3 =0;ibin3<nbins3;ibin3++){
731 proj3D->SetBinContent(ibin1+1,ibin2+1,ibin3+1,data[ibin1][ibin2][ibin3]);
732 proj3D->SetBinError(ibin1+1,ibin2+1,ibin3+1,TMath::Sqrt(data[ibin1][ibin2][ibin3]));
733 if(fSumW2)proj3D->SetBinError(ibin1+1,ibin2+1,ibin3+1,TMath::Sqrt(err[ibin1][ibin2][ibin3]));
734 sum+=data[ibin1][ibin2][ibin3];
745 proj3D->SetEntries(sum+GetUnderFlows(ivar1)+GetOverFlows(ivar1)+GetUnderFlows(ivar2)+GetOverFlows(ivar2)+GetUnderFlows(ivar3)+GetOverFlows(ivar3));
749 //___________________________________________________________________
750 TH1D *AliCFGrid::Slice(Int_t ivar, Double_t *varMin, Double_t* varMax) const
753 // Make a slice along variable ivar in range [varMin,varMax]
756 Int_t nbins =fNVarBins[ivar];
757 Float_t *bins = new Float_t[nbins+1];
758 for (Int_t i=0;i<=fNVar;i++){
760 for(Int_t ibin =0;ibin<nbins+1;ibin++){
761 bins[ibin] = fVarBinLimits[ibin+fOffset[ivar]];
765 sprintf(pname,"%s%s_%i",GetName(),"_proj1D_var", ivar);
767 sprintf(htitle,"%s%s_%i",GetName(),"_proj1D_var", ivar);
771 //check if a projection with identical name exist
772 TObject *obj = gROOT->FindObject(pname);
773 if (obj && obj->InheritsFrom("TH1D")) {
779 proj1D =new TH1D(pname,htitle, nbins, bins);
785 Int_t *indexMin=new Int_t[fNVar];
786 Int_t *indexMax=new Int_t[fNVar];
789 //Find out the min and max bins
791 for(Int_t i=0;i<fNVar;i++){
792 Float_t xmin=varMin[i]; // the min values
793 Float_t xmax=varMax[i]; // the min values
794 Int_t nbins=fNVarBins[i]+1;
795 Float_t *bins=new Float_t[nbins];
796 for(Int_t ibin =0;ibin<nbins;ibin++){
797 bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
799 indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
800 indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
805 Float_t *data= new Float_t[nbins];
806 for(Int_t ibin=0;ibin<nbins;ibin++)data[ibin]=0;
808 Int_t *index= new Int_t[fNVar];
809 Int_t ielmin=GetBinIndex(indexMin);
810 Int_t ielmax=GetBinIndex(indexMax);
811 for(Int_t iel=ielmin;iel<=ielmax;iel++){
812 GetBinIndex(iel,index);
814 for (Int_t j=0;j<fNVar;j++){
815 if(!(index[j]>=indexMin[j] && index[j]<=indexMax[j]))isIn=kFALSE;
818 if(isIn)data[GetBinIndex(ivar,iel)]+=fData[iel];
824 for(Int_t ibin =0;ibin<nbins;ibin++){
825 proj1D->SetBinContent(ibin+1,data[ibin]);
826 proj1D->SetBinError(ibin+1,TMath::Sqrt(data[ibin]));
832 proj1D->SetEntries(sum);
837 //____________________________________________________________________
838 void AliCFGrid::Add(AliCFVGrid* aGrid, Double_t c)
841 //add aGrid to the current one
844 if(aGrid->GetNVar()!=fNVar){
845 AliInfo("Different number of variables, cannot add the grids");
848 if(aGrid->GetNDim()!=fNDim){
849 AliInfo("Different number of dimensions, cannot add the grids!");
853 if(!fSumW2 && aGrid->GetSumW2())SumW2();
855 for(Int_t iel=0;iel<fNDim;iel++){
856 fData[iel]+=(c*aGrid->GetElement(iel));
858 Float_t err=aGrid->GetElementError(iel);
859 fErr2[iel]+=c*c*err*err;
863 //Add entries, overflows and underflows
865 fNentriesTot+= c*aGrid->GetEntries();
866 fNunflTot+= c*aGrid->GetUnderFlows();
867 fNovflTot+= c*aGrid->GetOverFlows();
868 for(Int_t j=0;j<fNVar;j++){
869 fNunfl[j]+= c*aGrid->GetUnderFlows(j);
870 fNovfl[j]+= c*aGrid->GetUnderFlows(j);
873 //____________________________________________________________________
874 void AliCFGrid::Add(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1,Double_t c2)
877 //add aGrid1 and aGrid2
880 if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
881 AliInfo("Different number of variables, cannot add the grids");
884 if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
885 AliInfo("Different number of dimensions, cannot add the grids!");
889 if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
891 Float_t cont1,cont2,err1,err2;
893 for(Int_t iel=0;iel<fNDim;iel++){
894 cont1=aGrid1->GetElement(iel);
895 cont2=aGrid2->GetElement(iel);
896 SetElement(iel,c1*cont1+c2*cont2);
898 err1=aGrid1->GetElementError(iel);
899 err2=aGrid2->GetElementError(iel);
900 SetElementError(iel,TMath::Sqrt(c1*c1*err1*err1+c2*c2*err2*err2));
904 //Add entries, overflows and underflows
906 fNentriesTot= c1*aGrid1->GetEntries()+c2*aGrid2->GetEntries();
907 fNunflTot= c1*aGrid1->GetUnderFlows()+c2*aGrid2->GetUnderFlows();
908 fNovflTot= c1*aGrid1->GetOverFlows()+c2*aGrid2->GetOverFlows();
909 for(Int_t j=0;j<fNVar;j++){
910 fNunfl[j]= c1*aGrid1->GetUnderFlows(j)+c2*aGrid2->GetUnderFlows(j);
911 fNovfl[j]= c1*aGrid1->GetUnderFlows(j)+c2*aGrid2->GetUnderFlows(j);
914 //____________________________________________________________________
915 void AliCFGrid::Multiply(AliCFVGrid* aGrid, Double_t c)
918 //multiply grid aGrid by the current one
921 if(aGrid->GetNVar()!=fNVar){
922 AliInfo("Different number of variables, cannot multiply the grids");
925 if(aGrid->GetNDim()!=fNDim){
926 AliInfo("Different number of dimensions, cannot multiply the grids!");
930 if(!fSumW2 && aGrid->GetSumW2())SumW2();
932 Float_t cont1,cont2,err1,err2;
934 for(Int_t iel=0;iel<fNDim;iel++){
935 cont1=GetElement(iel);
936 cont2=c*aGrid->GetElement(iel);
937 SetElement(iel,cont1*cont2);
939 err1=GetElementError(iel);
940 err2=aGrid->GetElementError(iel);
941 SetElementError(iel,TMath::Sqrt(c*c*(cont2*cont2*err1*err1+cont1*cont1*err2*err2)));
945 //Set entries to the number of bins, preserve original overflows and underflows
948 fNunflTot=GetUnderFlows();
949 fNovflTot=GetOverFlows();
950 for(Int_t j=0;j<fNVar;j++){
951 fNunfl[j]= GetUnderFlows(j);
952 fNovfl[j]= GetUnderFlows(j);
955 //____________________________________________________________________
956 void AliCFGrid::Multiply(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1, Double_t c2)
959 //multiply grids aGrid1 and aGrid2
962 if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
963 AliInfo("Different number of variables, cannot multiply the grids");
966 if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
967 AliInfo("Different number of dimensions, cannot multiply the grids!");
971 if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
973 Float_t cont1,cont2,err1,err2;
974 for(Int_t iel=0;iel<fNDim;iel++){
975 cont1=c1*aGrid1->GetElement(iel);
976 cont2=c2*aGrid2->GetElement(iel);
977 SetElement(iel,cont1*cont2);
979 err1=aGrid1->GetElementError(iel);
980 err2=aGrid2->GetElementError(iel);
981 SetElementError(iel,TMath::Sqrt(c1*c1*c2*c2*(cont2*cont2*err1*err1+cont1*cont1*err2*err2)));
985 //Set entries to the number of bins, preserve original overflows and underflows
988 fNunflTot=GetUnderFlows();
989 fNovflTot=GetOverFlows();
990 for(Int_t j=0;j<fNVar;j++){
991 fNunfl[j]= GetUnderFlows(j);
992 fNovfl[j]= GetUnderFlows(j);
995 //____________________________________________________________________
996 void AliCFGrid::Divide(AliCFVGrid* aGrid, Double_t c)
999 //divide current grid by grid aGrid
1002 if(aGrid->GetNVar()!=fNVar){
1003 AliInfo("Different number of variables, cannot divide the grids");
1006 if(aGrid->GetNDim()!=fNDim){
1007 AliInfo("Different number of dimensions, cannot divide the grids!");
1010 if(!c){AliInfo(Form("c is %f, cannot divide!",c)); return;}
1012 if(!fSumW2 && aGrid->GetSumW2())SumW2();
1014 Float_t cont1,cont2,err1,err2,den;
1015 for(Int_t iel=0;iel<fNDim;iel++){
1016 cont1=GetElement(iel);
1017 cont2=aGrid->GetElement(iel);
1018 if(cont2)SetElement(iel,cont1/(c*cont2));
1019 else SetElement(iel,0);
1021 err1=GetElementError(iel);
1022 err2=aGrid->GetElementError(iel);
1023 if(!cont2){SetElementError(iel,0.); continue;}
1024 den=cont2*cont2*cont2*c*c;
1025 SetElementError(iel,TMath::Sqrt((cont2*cont2*err1*err1+cont1*cont1*err2*err2)/den));
1029 //Set entries to the number of bins, preserve original overflows and underflows
1032 fNunflTot=GetUnderFlows();
1033 fNovflTot=GetOverFlows();
1034 for(Int_t j=0;j<fNVar;j++){
1035 fNunfl[j]= GetUnderFlows(j);
1036 fNovfl[j]= GetUnderFlows(j);
1039 //____________________________________________________________________
1040 void AliCFGrid::Divide(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1,Double_t c2, Option_t *option)
1043 //divide grids aGrid1,aGrid2
1046 TString opt = option;
1049 if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
1050 AliInfo("Different number of variables, cannot divide the grids");
1053 if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
1054 AliInfo("Different number of dimensions, cannot divide the grids!");
1057 if(!c2){AliInfo(Form("c2 is %f, cannot divide!",c2)); return;}
1059 if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
1061 Float_t cont1,cont2,err1,err2,r,den;
1063 for(Int_t iel=0;iel<fNDim;iel++){
1064 cont1=aGrid1->GetElement(iel);
1065 cont2=aGrid2->GetElement(iel);
1066 if(cont2)SetElement(iel,c1*cont1/(c2*cont2));
1067 else SetElement(iel,0);
1069 err1=aGrid1->GetElementError(iel);
1070 err2=aGrid2->GetElementError(iel);
1071 if(!cont2){SetElementError(iel,0.); continue;}
1072 if (opt.Contains("B")){
1075 SetElementError(iel,TMath::Sqrt(TMath::Abs(((1.-2.*r)*err1*err1+r*r*err2*err2)/(cont2*cont2))));
1077 SetElementError(iel,0.);
1080 den=cont2*cont2*cont2*cont2*c2*c2;
1081 SetElementError(iel,TMath::Sqrt(c1*c1*(cont2*cont2*err1*err1+cont1*cont1*err2*err2)/den));
1086 //Set entries to the number of bins, preserve original overflows and underflows
1089 fNunflTot=GetUnderFlows();
1090 fNovflTot=GetOverFlows();
1091 for(Int_t j=0;j<fNVar;j++){
1092 fNunfl[j]= GetUnderFlows(j);
1093 fNovfl[j]= GetUnderFlows(j);
1096 //____________________________________________________________________
1097 void AliCFGrid::SumW2()
1100 //set calculation of the squared sum of the weighted entries
1103 fErr2=new Float_t [fNDim];
1105 for(Int_t iel=0;iel<fNDim;iel++){
1106 fErr2[iel]=fData[iel];
1112 //____________________________________________________________________
1113 void AliCFGrid::Copy(TObject& c) const
1118 AliCFGrid& target = (AliCFGrid &) c;
1120 target.fNunflTot = fNunflTot;
1121 target.fNovflTot = fNovflTot;
1122 target.fNentriesTot = fNentriesTot;
1124 target.fNunfl = fNunfl;
1126 target.fNovfl = fNovfl;
1128 target.fData = fData;
1130 target.fErr2 = fErr2;