LCOV - code coverage report
Current view: top level - STEER/STEERBase - AliTRDNDFast.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 192 0.5 %
Date: 2016-06-14 17:26:59 Functions: 1 26 3.8 %

          Line data    Source code
       1             : // Author: Daniel.Lohner@cern.ch
       2             : 
       3             : #include "AliTRDNDFast.h"
       4             : #include "AliLog.h"
       5             : #include "TCanvas.h"
       6             : #include "TMath.h"
       7             : 
       8             : extern Double_t langaufunc(Double_t *x, Double_t *par) {
       9             : 
      10             :     // needs protection, parameter [3]>0!!!!!
      11             :     // needs protection, parameter [4]>0!!!!!
      12             : 
      13             :     //Fit parameters:
      14             :     //par[0]=Width (scale) parameter of Landau density
      15             :     //par[1]=Most Probable (MP, location) parameter of Landau density
      16             :     //par[2]=Total area (integral -inf to inf, normalization constant)
      17             :     //par[3]=Width (sigma) of convoluted Gaussian function
      18             :     //par[4]=Exponential Slope Parameter
      19             :     //
      20             :     //In the Landau distribution (represented by the CERNLIB approximation),
      21             :     //the maximum is located at x=-0.22278298 with the location parameter=0.
      22             :     //This shift is corrected within this function, so that the actual
      23             :     //maximum is identical to the MP parameter.
      24             : 
      25             :     // Numeric constants
      26             :     Double_t invsq2pi = 0.3989422804014;   // (2 pi)^(-1/2)
      27             :     Double_t mpshift  = -0.22278298;       // Landau maximum location
      28             : 
      29             :     // Control constants
      30             :     Double_t np = 100.0;      // number of convolution stpdf
      31             :     Double_t sc =   5.0;      // convolution extends to +-sc Gaussian sigmas
      32             : 
      33             :     // Variables
      34             :     Double_t xx;
      35             :     Double_t mpc;
      36             :     Double_t fland;
      37             :     Double_t sum = 0.0;
      38             :     Double_t xlow,xupp;
      39             :     Double_t step;
      40             :     Double_t i;
      41             : 
      42             :     // MP shift correction
      43           0 :     mpc = par[1] - mpshift * par[0];
      44             : 
      45             :     // Range of convolution integral
      46           0 :     xlow = x[0] - sc * par[3];
      47           0 :     xupp = x[0] + sc * par[3];
      48             : 
      49           0 :     if(xlow<0)xlow=0;
      50           0 :     if(xupp<xlow)cout<<"ERROR: Convolution around Negative MPV"<<endl;
      51             : 
      52           0 :     step = (xupp-xlow) / np;
      53             : 
      54             :     // Convolution integral of Landau and Gaussian by sum
      55           0 :     for(i=1.0; i<=np/2; i++) {
      56           0 :         xx = xlow + (i-.5) * step;
      57           0 :         fland = TMath::Landau(xx,mpc,par[0])*TMath::Exp(-par[4]*xx) / par[0];   // mpc taken out
      58           0 :         sum += fland * TMath::Gaus(x[0],xx,par[3]);
      59             : 
      60           0 :         xx = xupp - (i-.5) * step;
      61           0 :         fland = TMath::Landau(xx,mpc,par[0])*TMath::Exp(-par[4]*xx) / par[0];   // mpc taken out
      62           0 :         sum += fland * TMath::Gaus(x[0],xx,par[3]);
      63             :     }
      64             : 
      65           0 :     return (par[2] * step * sum * invsq2pi / par[3]);
      66             : }
      67             : 
      68             : 
      69             : 
      70         176 : ClassImp(AliTRDNDFast);
      71             : 
      72           0 : AliTRDNDFast::AliTRDNDFast(): TObject(),
      73           0 :     fNDim(0),
      74           0 :     fTitle(""),
      75           0 :     fFunc(NULL),
      76           0 :     fHistos(NULL),
      77           0 :     fPars()
      78           0 : {
      79             :     // default constructor
      80           0 : }
      81             : 
      82           0 : AliTRDNDFast::AliTRDNDFast(const char *name,Int_t ndim,Int_t nbins,Double_t xlow,Double_t xup): TObject(),
      83           0 : fNDim(ndim),
      84           0 : fTitle(name),
      85           0 : fFunc(NULL),
      86           0 : fHistos(NULL),
      87           0 : fPars()
      88           0 : {
      89           0 :     Init();
      90           0 :     for(Int_t idim=0;idim<fNDim;idim++){
      91           0 :         fHistos[idim]=new TH1F(Form("%s_axis_%d",fTitle.Data(),idim),Form("%s_axis_%d",fTitle.Data(),idim),nbins,xlow,xup);
      92           0 :         fHistos[idim]->SetDirectory(0);
      93             :     }
      94           0 : }
      95             : 
      96           0 : AliTRDNDFast::AliTRDNDFast(const AliTRDNDFast &ref) : TObject(ref),
      97           0 : fNDim(ref.fNDim),
      98           0 : fTitle(ref.fTitle),
      99           0 : fFunc(NULL),
     100           0 : fHistos(NULL),
     101           0 : fPars()
     102           0 : {
     103           0 :     Cleanup();
     104           0 :     Init();
     105           0 :     for(Int_t idim=0;idim<fNDim;idim++){
     106           0 :         fHistos[idim]=(TH1F*)ref.fHistos[idim]->Clone(Form("%s_axis_%d",GetName(),idim));
     107           0 :         fHistos[idim]->SetDirectory(0);
     108           0 :         for(Int_t ipar=0;ipar<kNpar;ipar++)fPars[idim][ipar]=ref.fPars[idim][ipar];
     109             :     }
     110           0 : }
     111             : 
     112             : AliTRDNDFast &AliTRDNDFast::operator=(const AliTRDNDFast &ref){
     113             :     //
     114             :     // Assignment operator
     115             :     //
     116           0 :     if(this != &ref){
     117           0 :         TObject::operator=(ref);
     118           0 :         fNDim=ref.fNDim;
     119           0 :         fTitle=ref.fTitle;
     120           0 :         fFunc = ref.fFunc;
     121           0 :         for(Int_t idim=0;idim<fNDim;idim++){
     122           0 :           fHistos[idim]=(TH1F*)ref.fHistos[idim]->Clone(Form("%s_axis_%d",GetName(),idim));
     123           0 :           fHistos[idim]->SetDirectory(0);
     124           0 :           for(Int_t ipar=0;ipar<kNpar;ipar++)fPars[idim][ipar]=ref.fPars[idim][ipar];
     125             :         }
     126           0 :     }
     127           0 :     return *this;
     128             : }
     129             : 
     130           0 : AliTRDNDFast::~AliTRDNDFast(){
     131           0 :     Cleanup();
     132             : 
     133           0 : }
     134             : 
     135             : void AliTRDNDFast::Init(){
     136             : 
     137           0 :     for(Int_t ipar=0;ipar<kNpar;ipar++)fPars[ipar].Set(fNDim);
     138           0 :     fFunc=new TF1*[fNDim];
     139           0 :     fHistos=new TH1F*[fNDim];
     140           0 :     for(Int_t idim=0;idim<fNDim;idim++){
     141           0 :         fHistos[idim]=NULL;
     142           0 :         for(Int_t ipar=0;ipar<kNpar;ipar++)fPars[ipar].SetAt(0,idim);
     143           0 :         fFunc[idim]=NULL;
     144             :     }
     145           0 : }
     146             : 
     147             : void AliTRDNDFast::Cleanup(){
     148           0 :     if(fHistos){
     149           0 :         for(Int_t idim=0;idim<fNDim;idim++){
     150           0 :             if(fHistos[idim]){
     151           0 :                 delete fHistos[idim];
     152           0 :                 fHistos[idim]=NULL;
     153           0 :             }
     154             :         }
     155           0 :         delete[] fHistos;
     156           0 :         fHistos=NULL;
     157           0 :     }
     158           0 :     for(Int_t ipar=0;ipar<kNpar;ipar++){
     159           0 :       fPars[ipar].Reset();
     160             :     }
     161           0 :     if(fFunc){
     162           0 :         for(Int_t idim=0;idim<fNDim;idim++){
     163           0 :             if(fFunc[idim]){
     164           0 :                 delete fFunc[idim];
     165           0 :                 fFunc[idim]=NULL;
     166           0 :             }
     167             :         }
     168           0 :         delete[] fFunc;
     169           0 :         fFunc=NULL;
     170           0 :     }
     171           0 : }
     172             : 
     173             : void AliTRDNDFast::PrintPars(){
     174           0 :     for(Int_t idim=0;idim<fNDim;idim++){
     175           0 :         for(Int_t ipar=0;ipar<kNpar;ipar++)cout<<idim<<" "<<ipar<<" "<<GetParam(idim,ipar)<<endl;
     176             :     }
     177           0 : }
     178             : 
     179             : void AliTRDNDFast::ScaleLangauFun(TF1 *func,Double_t mpv){
     180             : 
     181           0 :     Double_t start[kNpar],low[kNpar],high[kNpar];
     182           0 :     for(Int_t ii=0;ii<kNpar;ii++){
     183           0 :         start[ii]=func->GetParameter(ii);
     184           0 :         func->GetParLimits(ii,low[ii],high[ii]);
     185             :     }
     186             : 
     187           0 :     Double_t scalefactor=mpv/start[1];
     188             : 
     189           0 :     for(Int_t ii=0;ii<kNpar;ii++){
     190             :         Double_t scale=1;
     191           0 :         if(ii==0||ii==1||ii==3)scale=scalefactor;
     192           0 :         if(ii==4)scale=1./scalefactor;
     193           0 :         start[ii]*=scale;
     194           0 :         low[ii]*=scale;
     195           0 :         high[ii]*=scale;
     196           0 :         func->SetParLimits(ii, low[ii], high[ii]);
     197             :     }
     198           0 :     func->SetParameters(start);
     199           0 : }
     200             : 
     201             : //---------------------------------------------------------------
     202             : //---------------------------------------------------------------
     203             : TF1 *AliTRDNDFast::GetLangauFun(TString funcname,Double_t range[2],Double_t scalefactor){
     204             : 
     205           0 :     Double_t start[kNpar] = {120, 1000, 1, 100, 1e-5};
     206           0 :     Double_t low[kNpar] = {10, 300, 0.01, 1, 0.};
     207           0 :     Double_t high[kNpar] = {1000, 3000, 100, 1000, 1.};
     208             : 
     209           0 :     TF1 *hlandauE=new TF1(funcname.Data(),langaufunc,0,range[1],kNpar);
     210           0 :     hlandauE->SetParameters(start);
     211           0 :     hlandauE->SetParNames("Width","MP","Area","GSigma","delta");
     212           0 :     for (int i=0; i<kNpar; i++) {
     213           0 :         hlandauE->SetParLimits(i, low[i], high[i]);
     214             :     }
     215             : 
     216           0 :     if(scalefactor!=1){ScaleLangauFun(hlandauE,scalefactor*start[1]);}
     217             : 
     218           0 :     return hlandauE;
     219           0 : }
     220             : 
     221             : TF1 *AliTRDNDFast::FitLandau(TString name,TH1F *htemp,Double_t range[2],TString option){
     222             : 
     223           0 :     TF1 *fitlandau1D=GetLangauFun(name,range);
     224           0 :     TF1 fit("land","landau");
     225           0 :     Double_t max=htemp->GetXaxis()->GetBinCenter(htemp->GetMaximumBin());
     226           0 :     fit.SetParameter(1,max);
     227           0 :     fit.SetParLimits(1,0,htemp->GetXaxis()->GetXmax());
     228           0 :     fit.SetParameter(2,0.3*max); // MPV may never become negative!!!!!
     229           0 :     htemp->Fit("land",option.Data(),"",range[0],range[1]);
     230           0 :     ScaleLangauFun(fitlandau1D,fit.GetParameter(1));
     231           0 :     htemp->Fit(fitlandau1D,option.Data(),"",range[0],range[1]); // range for references
     232             :     return fitlandau1D;
     233           0 : }
     234             : 
     235             : void AliTRDNDFast::BuildHistos(){
     236             : 
     237           0 :     for(Int_t idim=0;idim<fNDim;idim++){
     238           0 :         fHistos[idim]->Reset();
     239             :         // Fill Histo
     240           0 :         Double_t pars[kNpar];
     241           0 :         for(Int_t ipar=0;ipar<kNpar;ipar++)pars[ipar]=GetParam(idim,ipar);
     242             :         // Also Fill overflow bins!!!
     243           0 :         for(Int_t ii=1;ii<=fHistos[idim]->GetNbinsX()+1;ii++){
     244           0 :             Double_t xval=fHistos[idim]->GetXaxis()->GetBinCenter(ii);
     245           0 :             Double_t val=langaufunc(&xval,&pars[0]);
     246             :             //Double_t val=fFunc[idim]->Eval(xval);
     247           0 :             fHistos[idim]->SetBinContent(ii,val);
     248           0 :         }
     249             :         // Normalization
     250           0 :       if(fHistos[idim]->Integral(1,fHistos[idim]->GetNbinsX(),"width")!=0) fHistos[idim]->Scale(1./fHistos[idim]->Integral(1,fHistos[idim]->GetNbinsX(),"width"));
     251           0 :     }
     252           0 : }
     253             : 
     254             : void AliTRDNDFast::Build(Double_t **pars){
     255             :     // pars[ndim][npar]
     256           0 :     for(Int_t idim=0;idim<fNDim;idim++){
     257           0 :         for(Int_t ipar=0;ipar<kNpar;ipar++){
     258           0 :             fPars[ipar].SetAt(pars[idim][ipar],idim);
     259             :         }
     260             :     }
     261           0 :     BuildHistos();
     262           0 : }
     263             : 
     264             : 
     265             : void AliTRDNDFast::Build(TH1F **hdEdx,TString path){
     266             : 
     267           0 :     Double_t range[2];
     268             : 
     269           0 :     TCanvas *CANV=new TCanvas("a","a");
     270           0 :     if(fNDim==2)CANV->Divide(2,1);
     271           0 :     if(fNDim==3)CANV->Divide(2,2);
     272           0 :     if(fNDim>6)CANV->Divide(3,3);
     273             :     // Fit and Extract Parameters
     274           0 :     for(Int_t idim=0;idim<fNDim;idim++){
     275           0 :         CANV->cd(idim+1);
     276           0 :         gPad->SetLogy();
     277           0 :         range[0]=hdEdx[idim]->GetXaxis()->GetXmin();
     278           0 :         range[1]=hdEdx[idim]->GetXaxis()->GetXmax();
     279             :         // Norm Histogram
     280             : 
     281           0 :         if(hdEdx[idim]->Integral(1,hdEdx[idim]->GetNbinsX(),"width")!=0) hdEdx[idim]->Scale(1./hdEdx[idim]->Integral(1,hdEdx[idim]->GetNbinsX(),"width"));
     282             :         // Fit Histogram
     283           0 :         fFunc[idim]=FitLandau(Form("fit%d",idim),hdEdx[idim],range,"RMB0");
     284             :         // Norm Landau
     285           0 :         if(fFunc[idim]->Integral(range[0],range[1])!=0.0) fFunc[idim]->SetParameter(2,fFunc[idim]->GetParameter(2)/fFunc[idim]->Integral(range[0],range[1]));
     286             :         else {
     287           0 :             fFunc[idim]->SetParameter(2,fFunc[idim]->GetParameter(2));
     288             :         }
     289           0 :         hdEdx[idim]->DrawCopy();
     290           0 :         fFunc[idim]->DrawCopy("same");
     291             :         // Set Pars
     292           0 :         for(Int_t ipar=0;ipar<kNpar;ipar++){
     293           0 :             AliDebug(3,Form("parameters: %f %f %f %i %i \n",fFunc[idim]->GetParameter(ipar),fFunc[idim]->GetParError(ipar),fFunc[idim]->GetChisquare(),fFunc[idim]->GetNDF(),idim));
     294           0 :             fPars[ipar].SetAt(fFunc[idim]->GetParameter(ipar),idim);
     295             :         }
     296             :     }
     297           0 :     if(path!="")CANV->Print(Form("%s/%s_Build.pdf",path.Data(),fTitle.Data()));
     298           0 :     delete CANV;
     299             : 
     300           0 :     BuildHistos();
     301           0 : }
     302             : 
     303             : Double_t AliTRDNDFast::Eval(Double_t *point) const{
     304             :     Double_t val=1;
     305           0 :     for(Int_t idim=0;idim<fNDim;idim++){
     306           0 :         Int_t bin=fHistos[idim]->GetXaxis()->FindBin(point[idim]);
     307           0 :         val*=fHistos[idim]->GetBinContent(bin);
     308             :     }
     309           0 :     return val;
     310             : }
     311             : 
     312             : void AliTRDNDFast::Random(Double_t *point) const{
     313           0 :     for(Int_t idim=0;idim<fNDim;idim++){
     314           0 :         point[idim]=fHistos[idim]->GetRandom();
     315             :     }
     316           0 : }
     317             : 
     318             : void AliTRDNDFast::Random(Double_t *point,AliTRDNDFast *nd0,AliTRDNDFast *nd1,Double_t w0,Double_t w1){
     319           0 :     for(Int_t idim=0;idim<nd0->fNDim;idim++){
     320           0 :         point[idim]=GetRandomInterpolation(nd0->fHistos[idim],nd1->fHistos[idim],w0,w1);
     321             :     }
     322           0 : }
     323             : 
     324             : Int_t AliTRDNDFast::BinarySearchInterpolation(Int_t start,Int_t end,Double_t *a0,Double_t *a1,Double_t w0,Double_t w1,Double_t val){
     325             : 
     326           0 :     if((end-start)==1)return start;
     327           0 :     Int_t mid=Int_t((end+start)/2);
     328           0 :     Double_t valmid=(w0*a0[mid]+w1*a1[mid])/(w0+w1);
     329           0 :     if(val>=valmid)return BinarySearchInterpolation(mid,end,a0,a1,w0,w1,val);
     330           0 :     return BinarySearchInterpolation(start,mid,a0,a1,w0,w1,val);
     331           0 : }
     332             : 
     333             : Double_t AliTRDNDFast::GetRandomInterpolation(TH1F *hist0,TH1F *hist1,Double_t w0,Double_t w1){
     334             : 
     335             :     // Draw Random Variable
     336           0 :     Double_t rand=gRandom->Rndm();
     337             : 
     338             :     // Get Integral Arrays
     339           0 :     Double_t *integral0=hist0->GetIntegral();
     340           0 :     Double_t *integral1=hist1->GetIntegral();
     341             : 
     342           0 :     Int_t nbinsX=hist0->GetNbinsX();
     343             : 
     344           0 :     Int_t ibin=BinarySearchInterpolation(1,nbinsX+1,integral0,integral1,w0,w1,rand);
     345           0 :     return hist0->GetXaxis()->GetBinCenter(ibin);
     346             : }
     347             : 
     348             : 
     349             : 

Generated by: LCOV version 1.11