X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=CORRFW%2FAliCFGridSparse.cxx;h=a5b975a8354f0bfb3e06384057c928aea6d2376e;hb=d1fa9007113e351df2c9f03662dc85c13c827029;hp=4a4179ea69b05a03685f01769f3ef61e385ef946;hpb=38b1447ff50cab27131d4cbf7704b00a403dc89c;p=u%2Fmrichter%2FAliRoot.git diff --git a/CORRFW/AliCFGridSparse.cxx b/CORRFW/AliCFGridSparse.cxx index 4a4179ea69b..a5b975a8354 100755 --- a/CORRFW/AliCFGridSparse.cxx +++ b/CORRFW/AliCFGridSparse.cxx @@ -33,95 +33,95 @@ #include "TH2D.h" #include "TH3D.h" #include "TAxis.h" +#include "AliCFUnfolding.h" //____________________________________________________________________ ClassImp(AliCFGridSparse) //____________________________________________________________________ AliCFGridSparse::AliCFGridSparse() : - AliCFVGrid(), + AliCFFrame(), + fSumW2(kFALSE), fData(0x0) { // default constructor } //____________________________________________________________________ AliCFGridSparse::AliCFGridSparse(const Char_t* name, const Char_t* title) : - AliCFVGrid(name,title), + AliCFFrame(name,title), + fSumW2(kFALSE), fData(0x0) { // default constructor } //____________________________________________________________________ -AliCFGridSparse::AliCFGridSparse(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t * nBinIn, const Double_t *binLimitsIn) : - AliCFVGrid(name,title,nVarIn,nBinIn,binLimitsIn), +AliCFGridSparse::AliCFGridSparse(const Char_t* name, const Char_t* title, Int_t nVarIn, const Int_t * nBinIn) : + AliCFFrame(name,title), + fSumW2(kFALSE), fData(0x0) { // // main constructor // - fData=new THnSparseF(name,title,fNVar,fNVarBins); - - if(binLimitsIn){ - for(Int_t ivar=0;ivarSetBinEdges(ivar, array); - delete array; - } - } + fData = new THnSparseF(name,title,nVarIn,nBinIn); } + //____________________________________________________________________ -AliCFGridSparse::AliCFGridSparse(const AliCFGridSparse& c) : - AliCFVGrid(c), - fData(c.fData) +AliCFGridSparse::~AliCFGridSparse() { // - // copy constructor + // destructor // - ((AliCFGridSparse &)c).Copy(*this); + if (fData) delete fData; } //____________________________________________________________________ -AliCFGridSparse::~AliCFGridSparse() +AliCFGridSparse::AliCFGridSparse(const AliCFGridSparse& c) : + AliCFFrame(c), + fSumW2(kFALSE), + fData(0x0) { // - // destructor + // copy constructor // - if(fData) delete fData; + ((AliCFGridSparse &)c).Copy(*this); } //____________________________________________________________________ -AliCFGridSparse &AliCFGridSparse::operator=(const AliCFGridSparse &c) +AliCFGridSparse& AliCFGridSparse::operator=(const AliCFGridSparse &c) { // // assigment operator // - if (this != &c) - ((AliCFGridSparse &) c).Copy(*this); + if (this != &c) c.Copy(*this); return *this; } //____________________________________________________________________ -void AliCFGridSparse::SetBinLimits(Int_t ivar, Double_t *array) +void AliCFGridSparse::SetBinLimits(Int_t ivar, Double_t min, Double_t max) +{ + // + // set a uniform binning for variable ivar + // + Int_t nBins = GetNBins(ivar); + Double_t * array = new Double_t[nBins+1]; + for (Int_t iEdge=0; iEdge<=nBins; iEdge++) array[iEdge] = min + iEdge * (max-min)/nBins ; + fData->SetBinEdges(ivar, array); + delete [] array ; +} + +//____________________________________________________________________ +void AliCFGridSparse::SetBinLimits(Int_t ivar, const Double_t *array) { // // setting the arrays containing the bin limits // fData->SetBinEdges(ivar, array); - //then fill the appropriate array in ALICFFrame, to be able to use - //the getter, in case.... - Int_t nbins=fNVarBins[ivar]+1; - for(Int_t i=0;iProjection(ivar); - return hist; -} -//___________________________________________________________________ -TH2D *AliCFGridSparse::Project(Int_t ivar1, Int_t ivar2) const -{ - // - // Make a 2D projection along variables ivar1 & ivar2 - // - - TH2D *hist=fData->Projection(ivar2,ivar1); //notice inverted axis (THnSparse uses TH3 2d-projection convention...) - return hist; - -} -//___________________________________________________________________ -TH3D *AliCFGridSparse::Project(Int_t ivar1, Int_t ivar2, Int_t ivar3) const -{ - // - // Make a 3D projection along variables ivar1 & ivar2 & ivar3 - // - - TH3D *hist=fData->Projection(ivar1,ivar2,ivar3); - return hist; - -} - -//___________________________________________________________________ -AliCFGridSparse* AliCFGridSparse::Project(Int_t nVars, Int_t* vars, Double_t* varMin, Double_t* varMax) const +AliCFGridSparse* AliCFGridSparse::MakeSlice(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax, Bool_t useBins) const { // // projects the grid on the nVars dimensions defined in vars. // axis ranges can be defined in arrays varMin, varMax + // If useBins=true, varMin and varMax are taken as bin numbers // // binning for new grid Int_t* bins = new Int_t[nVars]; for (Int_t iVar=0; iVarClone()); if (varMin && varMax) { - for (Int_t iAxis=0; iAxisGetAxis(iAxis)->SetRangeUser(varMin[iAxis],varMax[iAxis]); + for (Int_t iAxis=0; iAxisGetAxis(iAxis),varMin[iAxis],varMax[iAxis],useBins); } } else AliInfo("Keeping same axis ranges"); out->SetGrid(clone->Projection(nVars,vars)); + delete [] bins; + delete clone; return out; } + //____________________________________________________________________ -Float_t AliCFGridSparse::GetOverFlows(Int_t ivar) const +Float_t AliCFGridSparse::GetBinCenter(Int_t ivar, Int_t ibin) const { // - // Returns exclusive overflows in variable ivar - // - Int_t* bin = new Int_t[fNVar]; - memset(bin, 0, sizeof(Int_t) * fNVar); - Float_t ovfl=0.; - for (Long64_t i = 0; i < fData->GetNbins(); ++i) { - Double_t v = fData->GetBinContent(i, bin); - Bool_t add=kTRUE; - for(Int_t j=0;jGetAxis(ivar)->GetBinCenter(ibin); } //____________________________________________________________________ -Float_t AliCFGridSparse::GetUnderFlows(Int_t ivar) const +Float_t AliCFGridSparse::GetBinSize(Int_t ivar, Int_t ibin) const { // - // Returns exclusive overflows in variable ivar - // - Int_t* bin = new Int_t[fNVar]; - memset(bin, 0, sizeof(Int_t) * fNVar); - Float_t unfl=0.; - for (Long64_t i = 0; i < fData->GetNbins(); ++i) { - Double_t v = fData->GetBinContent(i, bin); - Bool_t add=kTRUE; - for(Int_t j=0;jGetAxis(ivar)->GetBinUpEdge(ibin) - fData->GetAxis(ivar)->GetBinLowEdge(ibin); } - //____________________________________________________________________ Float_t AliCFGridSparse::GetEntries() const { @@ -252,22 +196,16 @@ Float_t AliCFGridSparse::GetEntries() const } //____________________________________________________________________ -Float_t AliCFGridSparse::GetElement(Int_t index) const +Float_t AliCFGridSparse::GetElement(Long_t index) const { // - // Returns content of grid element index according to the - // linear indexing in AliCFFrame + // Returns content of grid element index // - Int_t *bin = new Int_t[fNVar]; - GetBinIndex(index, bin); - for(Int_t i=0;iGetBinContent(index); } //____________________________________________________________________ -Float_t AliCFGridSparse::GetElement(Int_t *bin) const +Float_t AliCFGridSparse::GetElement(const Int_t *bin) const { // // Get the content in a bin corresponding to a set of bin indexes @@ -276,38 +214,28 @@ Float_t AliCFGridSparse::GetElement(Int_t *bin) const } //____________________________________________________________________ -Float_t AliCFGridSparse::GetElement(Double_t *var) const +Float_t AliCFGridSparse::GetElement(const Double_t *var) const { // // Get the content in a bin corresponding to a set of input variables // - Long_t index=fData->GetBin(var,kFALSE); //this is the THnSparse index (do not allocate new cells if content is empty) - if(index<0){ - return 0.; - }else{ - return fData->GetBinContent(index); - } + Long_t index = fData->GetBin(var,kFALSE); + if (index<0) return 0.; + return fData->GetBinContent(index); } //____________________________________________________________________ -Float_t AliCFGridSparse::GetElementError(Int_t index) const +Float_t AliCFGridSparse::GetElementError(Long_t index) const { // - // Returns the error on the content of a bin according to a linear - // indexing in AliCFFrame + // Returns the error on the content // - Int_t *bin = new Int_t[fNVar]; - GetBinIndex(index, bin); - for(Int_t i=0;iGetBinError(index); } //____________________________________________________________________ -Float_t AliCFGridSparse::GetElementError(Int_t *bin) const +Float_t AliCFGridSparse::GetElementError(const Int_t *bin) const { // // Get the error in a bin corresponding to a set of bin indexes @@ -316,35 +244,31 @@ Float_t AliCFGridSparse::GetElementError(Int_t *bin) const } //____________________________________________________________________ -Float_t AliCFGridSparse::GetElementError(Double_t *var) const +Float_t AliCFGridSparse::GetElementError(const Double_t *var) const { // // Get the error in a bin corresponding to a set of input variables // Long_t index=fData->GetBin(var,kFALSE); //this is the THnSparse index (do not allocate new cells if content is empy) - if(index<0){ - return 0.; - }else{ - return fData->GetBinError(index); - } + if (index<0) return 0.; + return fData->GetBinError(index); } - //____________________________________________________________________ -void AliCFGridSparse::SetElement(Int_t index, Float_t val) +void AliCFGridSparse::SetElement(Long_t index, Float_t val) { // - // Sets grid element iel to val (linear indexing) in AliCFFrame + // Sets grid element value // - Int_t *bin = new Int_t[fNVar]; - GetBinIndex(index, bin); - for(Int_t i=0;iGetBinContent(index,bin); //affects the bin coordinates + SetElement(bin,val); + delete [] bin ; } + //____________________________________________________________________ -void AliCFGridSparse::SetElement(Int_t *bin, Float_t val) +void AliCFGridSparse::SetElement(const Int_t *bin, Float_t val) { // // Sets grid element of bin indeces bin to val @@ -352,33 +276,32 @@ void AliCFGridSparse::SetElement(Int_t *bin, Float_t val) fData->SetBinContent(bin,val); } //____________________________________________________________________ -void AliCFGridSparse::SetElement(Double_t *var, Float_t val) +void AliCFGridSparse::SetElement(const Double_t *var, Float_t val) { // // Set the content in a bin to value val corresponding to a set of input variables // - Long_t index=fData->GetBin(var); //THnSparse index: allocate the cell - Int_t *bin = new Int_t[fNVar]; + Long_t index=fData->GetBin(var,kTRUE); //THnSparse index: allocate the cell + Int_t *bin = new Int_t[GetNVar()]; fData->GetBinContent(index,bin); //trick to access the array of bins - fData->SetBinContent(bin,val); + SetElement(bin,val); delete [] bin; - } //____________________________________________________________________ -void AliCFGridSparse::SetElementError(Int_t index, Float_t val) +void AliCFGridSparse::SetElementError(Long_t index, Float_t val) { // // Sets grid element iel error to val (linear indexing) in AliCFFrame // - Int_t *bin = new Int_t[fNVar]; - GetBinIndex(index, bin); - for(Int_t i=0;iGetBinContent(index,bin); + SetElementError(bin,val); delete [] bin; } + //____________________________________________________________________ -void AliCFGridSparse::SetElementError(Int_t *bin, Float_t val) +void AliCFGridSparse::SetElementError(const Int_t *bin, Float_t val) { // // Sets grid element error of bin indeces bin to val @@ -386,15 +309,15 @@ void AliCFGridSparse::SetElementError(Int_t *bin, Float_t val) fData->SetBinError(bin,val); } //____________________________________________________________________ -void AliCFGridSparse::SetElementError(Double_t *var, Float_t val) +void AliCFGridSparse::SetElementError(const Double_t *var, Float_t val) { // // Set the error in a bin to value val corresponding to a set of input variables // Long_t index=fData->GetBin(var); //THnSparse index - Int_t *bin = new Int_t[fNVar]; + Int_t *bin = new Int_t[GetNVar()]; fData->GetBinContent(index,bin); //trick to access the array of bins - fData->SetBinError(bin,val); + SetElementError(bin,val); delete [] bin; } @@ -407,162 +330,121 @@ void AliCFGridSparse::SumW2() if(!fSumW2){ fData->CalculateErrors(kTRUE); } - fSumW2=kTRUE; } //____________________________________________________________________ -void AliCFGridSparse::Add(AliCFVGrid* aGrid, Double_t c) +void AliCFGridSparse::Add(const AliCFGridSparse* aGrid, Double_t c) { // //add aGrid to the current one // - - if(aGrid->GetNVar()!=fNVar){ - AliInfo("Different number of variables, cannot add the grids"); - return; - } - if(aGrid->GetNDim()!=fNDim){ - AliInfo("Different number of dimensions, cannot add the grids!"); + if (aGrid->GetNVar() != GetNVar()){ + AliError("Different number of variables, cannot add the grids"); return; } - if(!fSumW2 && aGrid->GetSumW2())SumW2(); - - - fData->Add(((AliCFGridSparse*)aGrid)->GetGrid(),c); - + if (!fSumW2 && aGrid->GetSumW2()) SumW2(); + fData->Add(aGrid->GetGrid(),c); } //____________________________________________________________________ -void AliCFGridSparse::Add(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1,Double_t c2) +void AliCFGridSparse::Add(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2) { // //Add aGrid1 and aGrid2 and deposit the result into the current one // - if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){ + if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) { AliInfo("Different number of variables, cannot add the grids"); return; } - if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){ - AliInfo("Different number of dimensions, cannot add the grids!"); - return; - } - if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2(); - + if (!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2(); fData->Reset(); - fData->Add(((AliCFGridSparse*)aGrid1)->GetGrid(),c1); - fData->Add(((AliCFGridSparse*)aGrid2)->GetGrid(),c2); - + fData->Add(aGrid1->GetGrid(),c1); + fData->Add(aGrid2->GetGrid(),c2); } //____________________________________________________________________ -void AliCFGridSparse::Multiply(AliCFVGrid* aGrid, Double_t c) +void AliCFGridSparse::Multiply(const AliCFGridSparse* aGrid, Double_t c) { // // Multiply aGrid to the current one // - - if(aGrid->GetNVar()!=fNVar){ - AliInfo("Different number of variables, cannot multiply the grids"); - return; - } - if(aGrid->GetNDim()!=fNDim){ - AliInfo("Different number of dimensions, cannot multiply the grids!"); + if (aGrid->GetNVar() != GetNVar()) { + AliError("Different number of variables, cannot multiply the grids"); return; } - if(!fSumW2 && aGrid->GetSumW2())SumW2(); - - THnSparse *h= ((AliCFGridSparse*)aGrid)->GetGrid(); - + if(!fSumW2 && aGrid->GetSumW2()) SumW2(); + THnSparse *h = aGrid->GetGrid(); fData->Multiply(h); fData->Scale(c); - } //____________________________________________________________________ -void AliCFGridSparse::Multiply(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1,Double_t c2) +void AliCFGridSparse::Multiply(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2) { // //Multiply aGrid1 and aGrid2 and deposit the result into the current one // - if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){ - AliInfo("Different number of variables, cannot multiply the grids"); - return; - } - if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){ - AliInfo("Different number of dimensions, cannot multiply the grids!"); + if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) { + AliError("Different number of variables, cannot multiply the grids"); return; - } + } - if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2(); - + if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2(); fData->Reset(); - THnSparse *h1= ((AliCFGridSparse*)aGrid1)->GetGrid(); - THnSparse *h2= ((AliCFGridSparse*)aGrid2)->GetGrid(); + THnSparse *h1 = aGrid1->GetGrid(); + THnSparse *h2 = aGrid2->GetGrid(); h2->Multiply(h1); h2->Scale(c1*c2); fData->Add(h2); } - - //____________________________________________________________________ -void AliCFGridSparse::Divide(AliCFVGrid* aGrid, Double_t c) +void AliCFGridSparse::Divide(const AliCFGridSparse* aGrid, Double_t c) { // // Divide aGrid to the current one // - - if(aGrid->GetNVar()!=fNVar){ - AliInfo("Different number of variables, cannot divide the grids"); - return; - } - if(aGrid->GetNDim()!=fNDim){ - AliInfo("Different number of dimensions, cannot divide the grids!"); + if (aGrid->GetNVar() != GetNVar()) { + AliError("Different number of variables, cannot divide the grids"); return; } - if(!fSumW2 && aGrid->GetSumW2())SumW2(); - - THnSparse *h= ((AliCFGridSparse*)aGrid)->GetGrid(); + if (!fSumW2 && aGrid->GetSumW2()) SumW2(); - fData->Divide(h); + THnSparse *h1 = aGrid->GetGrid(); + THnSparse *h2 = (THnSparse*)fData->Clone(); + fData->Divide(h2,h1); fData->Scale(c); - } //____________________________________________________________________ -void AliCFGridSparse::Divide(AliCFVGrid* aGrid1, AliCFVGrid* aGrid2, Double_t c1,Double_t c2, Option_t *option) +void AliCFGridSparse::Divide(const AliCFGridSparse* aGrid1, const AliCFGridSparse* aGrid2, Double_t c1,Double_t c2, Option_t *option) { // //Divide aGrid1 and aGrid2 and deposit the result into the current one - //bynomial errors are supported + //binomial errors are supported // - if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){ - AliInfo("Different number of variables, cannot divide the grids"); - return; - } - if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){ - AliInfo("Different number of dimensions, cannot divide the grids!"); + if (GetNVar() != aGrid1->GetNVar() || GetNVar() != aGrid2->GetNVar()) { + AliError("Different number of variables, cannot divide the grids"); return; } - if(!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2(); + if (!fSumW2 && (aGrid1->GetSumW2() || aGrid2->GetSumW2())) SumW2(); - - THnSparse *h1= ((AliCFGridSparse*)aGrid1)->GetGrid(); - THnSparse *h2= ((AliCFGridSparse*)aGrid2)->GetGrid(); + THnSparse *h1= aGrid1->GetGrid(); + THnSparse *h2= aGrid2->GetGrid(); fData->Divide(h1,h2,c1,c2,option); } @@ -576,140 +458,348 @@ void AliCFGridSparse::Rebin(const Int_t* group) // a given axis has to be divisible by the rebin group. // - for(Int_t i=0;iRebin(group); fData->Reset(); fData = rebinned; +} +//____________________________________________________________________ +void AliCFGridSparse::Scale(Long_t index, const Double_t *fact) +{ + // + //scale content of a certain cell by (positive) fact (with error) + // - //redefine the needed stuff + if (GetElement(index)==0 || fact[0]==0) return; - Int_t ndimTot=1; - Int_t nbinTot=0; + Double_t in[2], out[2]; + in[0]=GetElement(index); + in[1]=GetElementError(index); + GetScaledValues(fact,in,out); + SetElement(index,out[0]); + if (fSumW2) SetElementError(index,out[1]); +} +//____________________________________________________________________ +void AliCFGridSparse::Scale(const Int_t *bin, const Double_t *fact) +{ + // + //scale content of a certain cell by (positive) fact (with error) + // + if(GetElement(bin)==0 || fact[0]==0)return; - //number of bins in each dimension, auxiliary variables + Double_t in[2], out[2]; + in[0]=GetElement(bin); + in[1]=GetElementError(bin); + GetScaledValues(fact,in,out); + SetElement(bin,out[0]); + if(fSumW2)SetElementError(bin,out[1]); + +} +//____________________________________________________________________ +void AliCFGridSparse::Scale(const Double_t *var, const Double_t *fact) +{ + // + //scale content of a certain cell by (positive) fact (with error) + // + if(GetElement(var)==0 || fact[0]==0)return; - for(Int_t ivar=0;ivarGetAxis(ivar)->GetNbins(); - fNVarBins[ivar]=nbins; - ndimTot*=fNVarBins[ivar]; - nbinTot+=(fNVarBins[ivar]+1); - Int_t offset=0; - for(Int_t i =0;iComputeIntegral(); +} - //now the array of bin limits +//____________________________________________________________________ +Long64_t AliCFGridSparse::Merge(TCollection* list) +{ + // + // Merge a list of AliCFGridSparse with this (needed for PROOF). + // Returns the number of merged objects (including this). + // - delete fVarBinLimits; - fNVarBinLimits=nbinTot; - fVarBinLimits=new Double_t[fNVarBinLimits]; + if (!list) + return 0; + + if (list->IsEmpty()) + return 1; - for(Int_t ivar=0;ivarGetAxis(ivar)->GetXmin(); - Double_t high = fData->GetAxis(ivar)->GetXmax(); - const TArrayD *xbins = fData->GetAxis(ivar)->GetXbins(); - if (xbins->fN == 0){ - for(Int_t ibin=0;ibin<=fNVarBins[ivar];ibin++){ - fVarBinLimits[ibin+fOffset[ivar]] = low + ibin*(high-low)/((Double_t) fNVarBins[ivar]); - } - } - else{ - - for(Int_t ibin=0;ibin<=fNVarBins[ivar];ibin++) { - fVarBinLimits[ibin+fOffset[ivar]] = xbins->At(ibin); - } - } - } + TIterator* iter = list->MakeIterator(); + TObject* obj; + Int_t count = 0; + while ((obj = iter->Next())) { + AliCFGridSparse* entry = dynamic_cast (obj); + if (entry == 0) + continue; + this->Add(entry); + count++; + } + + return count+1; +} + +//____________________________________________________________________ +void AliCFGridSparse::GetScaledValues(const Double_t *fact, const Double_t *in, Double_t *out) const{ + // + // scale input *in and its error by (positive) fact (with error) + // and erite it to *out + // + out[0]=in[0]*fact[0]; + out[1]=TMath::Sqrt(in[1]*in[1]/in[0]/in[0] + +fact[1]*fact[1]/fact[0]/fact[0])*out[0]; + } + //____________________________________________________________________ void AliCFGridSparse::Copy(TObject& c) const { // // copy function // + AliCFFrame::Copy(c); AliCFGridSparse& target = (AliCFGridSparse &) c; - - if(fData)target.fData = fData; + target.fSumW2 = fSumW2 ; + if (fData) { + target.fData = (THnSparse*)fData->Clone(); + } } //____________________________________________________________________ -TH1D* AliCFGridSparse::Slice(Int_t iVar, Double_t *varMin, Double_t *varMax) const +TH1* AliCFGridSparse::Slice(Int_t iVar1, Int_t iVar2, Int_t iVar3, const Double_t *varMin, const Double_t *varMax, Bool_t useBins) const { // - // return a slice (1D-projection) on variable iVar while axis ranges are defined with varMin,varMax + // return a slice on variables iVar1 (and optionnally iVar2 (and iVar3)) while axis ranges are defined with varMin,varMax // arrays varMin and varMax contain the min and max values of each variable. - // therefore varMin and varMax must have their dimensions equal to fNVar - // - + // therefore varMin and varMax must have their dimensions equal to GetNVar() + // If useBins=true, varMin and varMax are taken as bin numbers + // if varmin or varmax point to null, all the range is taken, including over- and underflows + THnSparse* clone = (THnSparse*)fData->Clone(); - for (Int_t iAxis=0; iAxisGetAxis(iAxis)->SetRangeUser(varMin[iAxis],varMax[iAxis]); + if (varMin != 0x0 && varMax != 0x0) { + for (Int_t iAxis=0; iAxisGetAxis(iAxis),varMin[iAxis],varMax[iAxis],useBins); } - return clone->Projection(iVar); + + TH1* projection = 0x0 ; + TString name,title; + GetProjectionName (name ,iVar1,iVar2,iVar3); + GetProjectionTitle(title,iVar1,iVar2,iVar3); + + if (iVar3<0) { + if (iVar2<0) { + if (iVar1 >= GetNVar() || iVar1 < 0 ) { + AliError("Non-existent variable, return NULL"); + return 0x0; + } + projection = (TH1D*)clone->Projection(iVar1); + projection->SetTitle(Form("%s_proj-%s",GetTitle(),GetVarTitle(iVar1))); + for (Int_t iBin=1; iBin<=projection->GetNbinsX(); iBin++) { + Int_t origBin = GetAxis(iVar1)->GetFirst()+iBin-1; + TString binLabel = GetAxis(iVar1)->GetBinLabel(origBin) ; + if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel); + } + } + else { + if (iVar1 >= GetNVar() || iVar1 < 0 || + iVar2 >= GetNVar() || iVar2 < 0 ) { + AliError("Non-existent variable, return NULL"); + return 0x0; + } + projection = (TH2D*)clone->Projection(iVar2,iVar1); + for (Int_t iBin=1; iBin<=projection->GetNbinsX(); iBin++) { + Int_t origBin = GetAxis(iVar1)->GetFirst()+iBin-1; + TString binLabel = GetAxis(iVar1)->GetBinLabel(origBin) ; + if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel); + } + for (Int_t iBin=1; iBin<=projection->GetNbinsY(); iBin++) { + Int_t origBin = GetAxis(iVar2)->GetFirst()+iBin-1; + TString binLabel = GetAxis(iVar2)->GetBinLabel(origBin) ; + if (binLabel.CompareTo("") != 0) projection->GetYaxis()->SetBinLabel(iBin,binLabel); + } + } + } + else { + if (iVar1 >= GetNVar() || iVar1 < 0 || + iVar2 >= GetNVar() || iVar2 < 0 || + iVar3 >= GetNVar() || iVar3 < 0 ) { + AliError("Non-existent variable, return NULL"); + return 0x0; + } + projection = (TH3D*)clone->Projection(iVar1,iVar2,iVar3); + for (Int_t iBin=1; iBin<=projection->GetNbinsX(); iBin++) { + Int_t origBin = GetAxis(iVar1)->GetFirst()+iBin-1; + TString binLabel = GetAxis(iVar1)->GetBinLabel(origBin) ; + if (binLabel.CompareTo("") != 0) projection->GetXaxis()->SetBinLabel(iBin,binLabel); + } + for (Int_t iBin=1; iBin<=projection->GetNbinsY(); iBin++) { + Int_t origBin = GetAxis(iVar2)->GetFirst()+iBin-1; + TString binLabel = GetAxis(iVar2)->GetBinLabel(origBin) ; + if (binLabel.CompareTo("") != 0) projection->GetYaxis()->SetBinLabel(iBin,binLabel); + } + for (Int_t iBin=1; iBin<=projection->GetNbinsZ(); iBin++) { + Int_t origBin = GetAxis(iVar3)->GetFirst()+iBin-1; + TString binLabel = GetAxis(iVar3)->GetBinLabel(origBin) ; + if (binLabel.CompareTo("") != 0) projection->GetZaxis()->SetBinLabel(iBin,binLabel); + } + } + + projection->SetName (name .Data()); + projection->SetTitle(title.Data()); + + delete clone; + return projection ; } //____________________________________________________________________ -TH2D* AliCFGridSparse::Slice(Int_t iVar1, Int_t iVar2, Double_t *varMin, Double_t *varMax) const -{ +void AliCFGridSparse::SetAxisRange(TAxis* axis, Double_t min, Double_t max, Bool_t useBins) const { // - // return a slice (2D-projection) on variables iVar1 and iVar2 while axis ranges are defined with varMin,varMax - // arrays varMin and varMax contain the min and max values of each variable. - // therefore varMin and varMax must have their dimensions equal to fNVar + // sets axis range, and forces bit TAxis::kAxisRange // - THnSparse* clone = (THnSparse*)fData->Clone(); - for (Int_t iAxis=0; iAxisGetAxis(iAxis)->SetRangeUser(varMin[iAxis],varMax[iAxis]); - } - return clone->Projection(iVar1,iVar2); + if (useBins) axis->SetRange ((Int_t)min,(Int_t)max); + else axis->SetRangeUser( min, max); + //axis->SetBit(TAxis::kAxisRange); // uncomment when ROOT TAxis is fixed } //____________________________________________________________________ -TH3D* AliCFGridSparse::Slice(Int_t iVar1, Int_t iVar2, Int_t iVar3, Double_t *varMin, Double_t *varMax) const -{ +void AliCFGridSparse::SetRangeUser(Int_t iVar, Double_t varMin, Double_t varMax, Bool_t useBins) const { // - // return a slice (3D-projection) on variables iVar1, iVar2 and iVar3 while axis ranges are defined with varMin,varMax - // arrays varMin and varMax contain the min and max values of each variable. - // therefore varMin and varMax must have their dimensions equal to fNVar + // set range of axis iVar. // + SetAxisRange(fData->GetAxis(iVar),varMin,varMax,useBins); + //AliInfo(Form("AliCFGridSparse axis %d range has been modified",iVar)); + TAxis* currAxis = fData->GetAxis(iVar); + TString outString = Form("%s new range: %.1f < %s < %.1f", GetName(), currAxis->GetBinLowEdge(currAxis->GetFirst()), currAxis->GetTitle(), currAxis->GetBinUpEdge(currAxis->GetLast())); + TString binLabel = currAxis->GetBinLabel(currAxis->GetFirst()); + if ( ! binLabel.IsNull() ) { + outString += " ( "; + for ( Int_t ibin = currAxis->GetFirst(); ibin <= currAxis->GetLast(); ibin++ ) { + outString += Form("%s ", currAxis->GetBinLabel(ibin)); + } + outString += ")"; + } + AliWarning(outString.Data()); - THnSparse* clone = (THnSparse*)fData->Clone(); - for (Int_t iAxis=0; iAxisGetAxis(iAxis)->SetRangeUser(varMin[iAxis],varMax[iAxis]); +} + +//____________________________________________________________________ +void AliCFGridSparse::SetRangeUser(const Double_t *varMin, const Double_t *varMax, Bool_t useBins) const { + // + // set range of every axis. varMin and varMax must be of dimension GetNVar() + // + for (Int_t iAxis=0; iAxisProjection(iVar1,iVar2,iVar3); + AliInfo("AliCFGridSparse axes ranges have been modified"); } //____________________________________________________________________ -void AliCFGridSparse::SetRangeUser(Int_t iVar, Double_t varMin, Double_t varMax) { +Float_t AliCFGridSparse::GetOverFlows(Int_t ivar, Bool_t exclusive) const +{ // - // set range of axis iVar. + // Returns overflows in variable ivar + // Set 'exclusive' to true for an exclusive check on variable ivar // - fData->GetAxis(iVar)->SetRangeUser(varMin,varMax); - AliWarning(Form("THnSparse axis %d range has been modified",iVar)); + Int_t* bin = new Int_t[GetNVar()]; + memset(bin, 0, sizeof(Int_t) * GetNVar()); + Float_t ovfl=0.; + for (Long64_t i = 0; i < fData->GetNbins(); i++) { + Double_t v = fData->GetBinContent(i, bin); + Bool_t add=kTRUE; + if (exclusive) { + for(Int_t j=0;jGetNbins(); i++) { + Double_t v = fData->GetBinContent(i, bin); + Bool_t add=kTRUE; + if (exclusive) { + for(Int_t j=0;jGetAxis(iAxis)->SetBit(TAxis::kAxisRange,b); +void AliCFGridSparse::Smooth() { + // + // smoothing function: TO USE WITH CARE + // + + AliInfo("Your GridSparse is going to be smoothed"); + AliInfo(Form("N TOTAL BINS : %li",GetNBinsTotal())); + AliInfo(Form("N FILLED BINS : %li",GetNFilledBins())); + AliCFUnfolding::SmoothUsingNeighbours(fData); }