LCOV - code coverage report
Current view: top level - STAT - TStatToolkit.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 243 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 13 0.0 %

          Line data    Source code
       1             : #ifndef TSTATTOOLKIT_H
       2             : #define TSTATTOOLKIT_H
       3             : /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       4             :  * See cxx source for full Copyright notice                               */
       5             : 
       6             : //
       7             : // some utilities which do net exist in the standard ROOT
       8             : //
       9             : /// \file TStatToolkit.h
      10             : /// \class TStatToolkit
      11             : /// \brief Summary of statistics functions
      12             : #include "TMath.h"
      13             : #include "Riostream.h"
      14             : #include "TH1F.h"
      15             : #include "TH2F.h"
      16             : #include "TH3.h"
      17             : #include "THnBase.h"
      18             : #include "TF1.h"
      19             : #include "TTree.h"
      20             : #include "TChain.h"
      21             : #include "TObjString.h"
      22             : #include "TLinearFitter.h"
      23             : #include "TGraph2D.h"
      24             : #include "TGraph.h"
      25             : #include "TGraphErrors.h"
      26             : #include "TMultiGraph.h"
      27             : #include "TCanvas.h"
      28             : #include "TLatex.h"
      29             : #include "TCut.h"
      30             : #include "THashList.h"
      31             : #include "TFitResultPtr.h"
      32             : #include "TFitResult.h"
      33             : //
      34             : // includes neccessary for test functions
      35             : //
      36             : #include "TSystem.h"
      37             : #include "TRandom.h"
      38             : #include "TStopwatch.h"
      39             : #include "TTreeStream.h"
      40             : #include "AliSysInfo.h"
      41             : 
      42             : #include "TObject.h"
      43             : #include "TVectorD.h"
      44             : #include "TVectorF.h"
      45             : #include "TMatrixD.h"
      46             : #include "TMatrixF.h"
      47             : #include <float.h>
      48             : //#include "TGraph2D.h"
      49             : //#include "TGraph.h"
      50             : class THashList;
      51             : 
      52             : namespace TStatToolkit
      53             : {
      54             :   enum TStatType {kEntries, kSum, kMean, kRMS, kMedian, kLTM, kLTMRMS}; 
      55             :   enum ENormType {kL1, kL2, kLp, kMax, kHamming, kNNormType };   // http://en.wikipedia.org/w/index.php?title=Norm_(mathematics)&oldid=655824636
      56             :   //
      57             :   //
      58             :   void    EvaluateUni(Int_t nvectors, Double_t *data, Double_t &mean, Double_t &sigma, Int_t hh);
      59             :   void    EvaluateUniExternal(Int_t nvectors, Double_t *data, Double_t &mean, Double_t &sigma, Int_t hh, Float_t externalfactor=1);
      60             :   Int_t  Freq(Int_t n, const Int_t *inlist, Int_t *outlist, Bool_t down);    
      61             :   //
      62             :   // HISTOGRAMS TOOLS
      63             :   //
      64             :   template <typename T> 
      65             :   void TruncatedMean(const TH1 * his, TVectorT<T> *param, Float_t down=0, Float_t up=1.0, Bool_t verbose=kFALSE);
      66             :   void MedianFilter(TH1 * his1D, Int_t nmedian);
      67             : 
      68             :   template <typename T> Bool_t  LTMHisto(TH1 * his, TVectorT<T> &param , Float_t fraction=1);
      69             :   template <typename T> Int_t*  LTMUnbinned(int np, const T *arr, TVectorT<T> &params , Float_t keep=1.0);
      70             : 
      71             :   template <typename T> void Reorder(int np, T *arr, const int *idx);
      72             :   //
      73             :   template <typename T> 
      74             :   void LTM(TH1 * his, TVectorT<T> *param=0 , Float_t fraction=1,  Bool_t verbose=kFALSE);
      75             : 
      76             :   template <typename T> 
      77             :   Double_t  FitGaus(TH1* his, TVectorT<T> *param=0, TMatrixT<T> *matrix=0, Float_t xmin=0, Float_t xmax=0,  Bool_t verbose=kFALSE);
      78             : 
      79             :   template <typename T> 
      80             :   Double_t  FitGaus(Float_t *arr, Int_t nBins, Float_t xMin, Float_t xMax, TVectorT<T> *param=0, TMatrixT<T> *matrix=0, Bool_t verbose=kFALSE);
      81             :   Float_t  GetCOG(const Short_t *arr, Int_t nBins, Float_t xMin, Float_t xMax, Float_t *rms=0, Float_t *sum=0);
      82             : 
      83             :   TGraph2D *  MakeStat2D(TH3 * his, Int_t delta0, Int_t delta1, Int_t type);
      84             :   TGraphErrors *  MakeStat1D(TH2 * his, Int_t deltaBin, Double_t fraction, Int_t returnType, Int_t markerStyle, Int_t markerColor);
      85             : 
      86             :   Double_t RobustBinMedian(TH1* hist, Double_t fractionCut=1.);
      87             :   //
      88             :   // Graph tools
      89             :   //
      90             :   THashList *AddMetadata(TTree*, const char *vartagName,const char *varTagValue);
      91             :   TNamed *GetMetadata(TTree* tree, const char *vartagName);
      92             :   TGraph * MakeGraphSparse(TTree * tree, const char * expr="Entry", const char * cut="1",  Int_t mstyle=25, Int_t mcolor=1, Float_t msize=-1, Float_t offset=0.0);
      93             :   TGraphErrors * MakeGraphErrors(TTree * tree, const char * expr="Entry", const char * cut="1",  Int_t mstyle=25, Int_t mcolor=1, Float_t msize=-1, Float_t offset=0.0, Int_t entries=10000000, Int_t firstEntry=0);
      94             : 
      95             :   //
      96             :   // Fitting function
      97             :   //
      98             :   TString* FitPlane(TTree * tree, const char* drawCommand, const char* formula, const char* cuts, Double_t & chi2, Int_t &npoints,  TVectorD &fitParam, TMatrixD &covMatrix, Float_t frac=-1, Int_t start=0, Int_t stop=10000000, Bool_t fix0=kFALSE);
      99             :   TString* FitPlaneFixed(TTree * tree, const char* drawCommand, const char* formula, const char* cuts, Double_t & chi2, Int_t &npoints,  TVectorD &fitParam, TMatrixD &covMatrix, Float_t frac=-1, Int_t start=0, Int_t stop=10000000);
     100             :   //
     101             :   //Linear fitter helper function
     102             :   //
     103             :   TString* FitPlaneConstrain(TTree * tree, const char* drawCommand, const char* formula, const char* cuts, Double_t & chi2, Int_t &npoints,  TVectorD &fitParam, TMatrixD &covMatrix, Float_t frac=-1, Int_t start=0, Int_t stop=10000000, Double_t constrain=-1);
     104             :   Int_t GetFitIndex(const TString fString, const TString subString);
     105             :  TString FilterFit(const TString &input, const TString filter, TVectorD &vec, TMatrixD &covar);
     106             :  void Update1D(Double_t delta, Double_t sigma, Int_t s1, TMatrixD &param, TMatrixD &covar);
     107             :   void   Constrain1D(const TString &input, const TString filter, TVectorD &param, TMatrixD & covar, Double_t mean, Double_t sigma);
     108             :   TString  MakeFitString(const TString &input, const TVectorD &param, const TMatrixD & covar, Bool_t verbose=kFALSE);
     109             :   //
     110             :   // TTree function for the trending
     111             :   //
     112             :   Int_t  MakeStatAlias(TTree * tree, const char * expr, const char * cut, const char * alias);
     113             :   Int_t  SetStatusAlias(TTree * tree, const char * expr, const char * cut, const char * alias);
     114             :   TMultiGraph*  MakeStatusMultGr(TTree * tree, const char * expr, const char * cut, const char * alias, Int_t igr=0);  
     115             :   void  AddStatusPad(TCanvas* c1, Float_t padratio, Float_t bottommargin);
     116             :   void  DrawStatusGraphs(TObjArray* oaMultGr);
     117             :   TTree*  WriteStatusToTree(TObject* oStatusGr);
     118             :   TMultiGraph*  MakeStatusLines(TTree * tree, const char * expr, const char * cut, const char * alias);
     119             :   void  MakeSummaryTree(TTree* treeIn, TTreeSRedirector *pcstream, TObjString& sumID, TCut &selection);
     120             :   Double_t GetDefaultStat(TTree * tree, const char * var, const char * selection, TStatType statType);
     121             :   //
     122             :   //
     123             :   void MakeDistortionMap(Int_t iter, THnBase * histo, TTreeSRedirector *pcstream, TMatrixD &projectionInfo, Int_t dumpHisto=100,Int_t verbose=kFALSE);
     124             :   void MakeDistortionMapFast(THnBase * histo, TTreeSRedirector *pcstream, TMatrixD &projectionInfo, Int_t verbose=0,  Double_t fractionCut=0.1, const char * estimators=0);
     125             : 
     126             :   //
     127             :   // norm (distance) functions
     128             :   //
     129             :   void     CombineArray(TTree *tree, TVectorD &values);
     130             :   Double_t GetDistance(const TVectorD &values, const ENormType normType,
     131             :                               const Bool_t normaliseToEntries=kFALSE, const Double_t pvalue=1.);
     132             :   Double_t GetDistance(const Int_t size, const Double_t *values, const ENormType normType,
     133             :                               const Bool_t normaliseToEntries=kFALSE, const Double_t pvalue=1.);
     134             :   Double_t GetDistance(TTree * tree, const char * var, const char * selection,
     135             :                               const ENormType normType, const Bool_t normaliseToEntries=kFALSE, const Double_t pvalue=1.);
     136             :   //
     137             :   // TTree function for robust draw
     138             :   //
     139             :   TH1* DrawHistogram(TTree * tree, const char* drawCommand, const char* cuts = "1", const char* hname = "histo", const char* htitle = "histo", Int_t nsigma = 4, Float_t fraction = 0.75, TObjArray *description=0 );
     140             :   //
     141             :   // TestFunctions:
     142             :   //
     143             :   void TestGausFit(Int_t nhistos=5000);
     144             :   void CheckTreeAliases(TTree * tree, Int_t ncheck);
     145             :  //
     146             :  // min, max, mean ...
     147             :  template <typename T> 
     148             :    void GetMinMax(const T* arr, Long64_t n, double &minVal, double &maxVal);
     149             :  template <typename T> 
     150             :    void GetMinMaxMean(const T* arr, Long64_t n, double &minVal, double &maxVal, double &meanVal);
     151             :  
     152             : };
     153             : 
     154             : //___________________________________________________________
     155             : template <typename T>
     156             : void TStatToolkit::GetMinMax(const T* arr, Long64_t n, double &minVal, double &maxVal)
     157             : {
     158             :   // find min, max entries in the array in a single loop
     159           0 :   minVal =  DBL_MAX;
     160           0 :   maxVal = -DBL_MAX;
     161           0 :   for (int i=n;i--;) {
     162           0 :     double val = arr[i];
     163           0 :     if (val<minVal) minVal = val;
     164           0 :     if (val>maxVal) maxVal = val;
     165             :   }
     166           0 : }
     167             : 
     168             : //___________________________________________________________
     169             : template <typename T>
     170             : void TStatToolkit::GetMinMaxMean(const T* arr, Long64_t n, double &minVal, double &maxVal, double &meanVal)
     171             : {
     172             :   // find min, max entries in the array in a single loop
     173           0 :   minVal =  DBL_MAX;
     174           0 :   maxVal = -DBL_MAX;
     175           0 :   meanVal = 0;
     176           0 :   for (int i=n;i--;) {
     177           0 :     double val = arr[i];
     178           0 :     if (val<minVal) minVal = val;
     179           0 :     if (val>maxVal) maxVal = val;
     180           0 :     meanVal += val;
     181             :   }
     182           0 :   if (n) meanVal /= n;
     183           0 : }
     184             : 
     185             : //___TStatToolkit__________________________________________________________________________
     186             : template <typename T> 
     187             : void TStatToolkit::TruncatedMean(const TH1 * his, TVectorT<T> *param, Float_t down, Float_t up, Bool_t verbose){
     188             :   //
     189             :   //
     190             :   //
     191             :   Int_t nbins    = his->GetNbinsX();
     192             :   Float_t nentries = his->GetEntries();
     193             :   Float_t sum      =0;
     194             :   Float_t mean   = 0;
     195             :   Float_t sigma2 = 0;
     196             :   Float_t ncumul=0;  
     197             :   for (Int_t ibin=1;ibin<nbins; ibin++){
     198             :     ncumul+= his->GetBinContent(ibin);
     199             :     Float_t fraction = Float_t(ncumul)/Float_t(nentries);
     200             :     if (fraction>down && fraction<up){
     201             :       sum+=his->GetBinContent(ibin);
     202             :       mean+=his->GetBinCenter(ibin)*his->GetBinContent(ibin);
     203             :       sigma2+=his->GetBinCenter(ibin)*his->GetBinCenter(ibin)*his->GetBinContent(ibin);      
     204             :     }
     205             :   }
     206             :   mean/=sum;
     207             :   sigma2= TMath::Sqrt(TMath::Abs(sigma2/sum-mean*mean));
     208             :   if (param){
     209             :     (*param)[0] = his->GetMaximum();
     210             :     (*param)[1] = mean;
     211             :     (*param)[2] = sigma2;
     212             :     
     213             :   }
     214             :   if (verbose)  printf("Mean\t%f\t Sigma2\t%f\n", mean,sigma2);
     215             : }
     216             : 
     217             : template <typename T> 
     218             : Bool_t TStatToolkit::LTMHisto(TH1 *his1D, TVectorT<T> &params , Float_t fraction){
     219             :   //
     220             :   // LTM : Trimmed mean on histogram - Modified version for binned data
     221             :   // 
     222             :   // Robust statistic to estimate properties of the distribution
     223             :   // To handle binning error special treatment
     224             :   // for definition of unbinned data see:
     225             :   //     http://en.wikipedia.org/w/index.php?title=Trimmed_estimator&oldid=582847999
     226             :   //
     227             :   // Function parameters:
     228             :   //     his1D   - input histogram
     229             :   //     params  - vector with parameters
     230             :   //             - 0 - area
     231             :   //             - 1 - mean
     232             :   //             - 2 - rms 
     233             :   //             - 3 - error estimate of mean
     234             :   //             - 4 - error estimate of RMS
     235             :   //             - 5 - first accepted bin position
     236             :   //             - 6 - last accepted  bin position
     237             :   //
     238           0 :   Int_t nbins    = his1D->GetNbinsX();
     239           0 :   Int_t nentries = (Int_t)his1D->GetEntries();
     240             :   const Double_t kEpsilon=0.0000000001;
     241             : 
     242           0 :   if (nentries<=0) return 0;
     243           0 :   if (fraction>1) fraction=0;
     244           0 :   if (fraction<0) return 0;
     245           0 :   TVectorD vectorX(nbins);
     246           0 :   TVectorD vectorMean(nbins);
     247           0 :   TVectorD vectorRMS(nbins);
     248             :   Double_t sumCont=0;
     249           0 :   for (Int_t ibin0=1; ibin0<=nbins; ibin0++) sumCont+=his1D->GetBinContent(ibin0);
     250             :   //
     251           0 :   Double_t minRMS=his1D->GetRMS()*10000;
     252             :   Int_t maxBin=0;
     253             :   //
     254           0 :   for (Int_t ibin0=1; ibin0<nbins; ibin0++){
     255             :     Double_t sum0=0, sum1=0, sum2=0;
     256             :     Int_t ibin1=ibin0;
     257           0 :     for ( ibin1=ibin0; ibin1<=nbins; ibin1++){
     258           0 :       Double_t cont=his1D->GetBinContent(ibin1);
     259           0 :       Double_t x= his1D->GetBinCenter(ibin1);
     260           0 :       sum0+=cont;
     261           0 :       sum1+=cont*x;
     262           0 :       sum2+=cont*x*x;
     263           0 :       if ( (ibin0!=ibin1) && sum0>=fraction*sumCont) break;
     264           0 :     }
     265           0 :     vectorX[ibin0]=his1D->GetBinCenter(ibin0);
     266           0 :     if (sum0<fraction*sumCont) continue;
     267             :     //
     268             :     // substract fractions of bin0 and bin1 to keep sum0=fration*sumCont
     269             :     //
     270           0 :     Double_t diff = sum0-fraction*sumCont;
     271           0 :     Double_t mean = (sum0>0) ? sum1/sum0:0;
     272             :     //
     273           0 :     Double_t x0=his1D->GetBinCenter(ibin0);
     274           0 :     Double_t x1=his1D->GetBinCenter(ibin1);
     275           0 :     Double_t y0=his1D->GetBinContent(ibin0);
     276           0 :     Double_t y1=his1D->GetBinContent(ibin1);
     277             :     //
     278           0 :     Double_t d = y0+y1-diff;    //enties to keep 
     279             :     Double_t w0=0,w1=0;
     280           0 :     if (y0<=kEpsilon&&y1>kEpsilon){
     281           0 :       w1=d/y1;
     282           0 :     } 
     283           0 :     if (y1<=kEpsilon&&y0>kEpsilon){
     284           0 :       w0=d/y0;
     285           0 :     }
     286           0 :     if (y0>kEpsilon && y1>kEpsilon && x1>x0  ){
     287           0 :       w0 = (d*(x1-mean))/((x1-x0)*y0);
     288           0 :       w1 = (d-y0*w0)/y1;
     289             :       //
     290           0 :       if (w0>1) {w1+=(w0-1)*y0/y1; w0=1;}
     291           0 :       if (w1>1) {w0+=(w1-1)*y1/y0; w1=1;}
     292             :     }  
     293           0 :     if ( (x1>x0) &&TMath::Abs(y0*w0+y1*w1-d)>kEpsilon*sum0){
     294           0 :       printf(" TStatToolkit::LTMHisto error\n");
     295             :     }
     296           0 :     sum0-=y0+y1;
     297           0 :     sum1-=y0*x0;
     298           0 :     sum1-=y1*x1;
     299           0 :     sum2-=y0*x0*x0;
     300           0 :     sum2-=y1*x1*x1;
     301             :     //
     302           0 :     Double_t xx0=his1D->GetXaxis()->GetBinUpEdge(ibin0)-0.5*w0*his1D->GetBinWidth(ibin0);
     303           0 :     Double_t xx1=his1D->GetXaxis()->GetBinLowEdge(ibin1)+0.5*w1*his1D->GetBinWidth(ibin1);
     304           0 :     sum0+=y0*w0+y1*w1;
     305           0 :     sum1+=y0*w0*xx0;
     306           0 :     sum1+=y1*w1*xx1;
     307           0 :     sum2+=y0*w0*xx0*xx0;
     308           0 :     sum2+=y1*w1*xx1*xx1;
     309             : 
     310             :     //
     311             :     // choose the bin with smallest rms
     312             :     //
     313           0 :     if (sum0>0){
     314           0 :       vectorMean[ibin0]=sum1/sum0;
     315           0 :       vectorRMS[ibin0]=TMath::Sqrt(TMath::Abs(sum2/sum0-vectorMean[ibin0]*vectorMean[ibin0]));
     316           0 :       if (vectorRMS[ibin0]<minRMS){
     317           0 :         minRMS=vectorRMS[ibin0];
     318           0 :         params[0]=sum0;
     319           0 :         params[1]=vectorMean[ibin0];
     320           0 :         params[2]=vectorRMS[ibin0];
     321           0 :         params[3]=vectorRMS[ibin0]/TMath::Sqrt(sumCont*fraction);
     322           0 :         params[4]=0; // what is the formula for error of RMS???
     323           0 :         params[5]=ibin0;
     324           0 :         params[6]=ibin1;
     325           0 :         params[7]=his1D->GetBinCenter(ibin0);
     326           0 :         params[8]=his1D->GetBinCenter(ibin1);
     327             :         maxBin=ibin0;
     328           0 :       }
     329             :     }else{
     330           0 :       break;
     331             :     }
     332           0 :   }
     333             :   return kTRUE;
     334           0 : }
     335             : 
     336             : template <typename T> 
     337             : Double_t  TStatToolkit::FitGaus(TH1* his, TVectorT<T> *param, TMatrixT<T> */*matrix*/, Float_t xmin, Float_t xmax, Bool_t verbose){
     338             :   //
     339             :   //  Fit histogram with gaussian function
     340             :   //  
     341             :   //  Prameters:
     342             :   //       return value- chi2 - if negative ( not enough points)
     343             :   //       his        -  input histogram
     344             :   //       param      -  vector with parameters 
     345             :   //       xmin, xmax -  range to fit - if xmin=xmax=0 - the full histogram range used
     346             :   //  Fitting:
     347             :   //  1. Step - make logarithm
     348             :   //  2. Linear  fit (parabola) - more robust - always converge
     349             :   //  3. In case of small statistic bins are averaged
     350             :   //  
     351             :   static TLinearFitter fitter(3,"pol2");
     352             :   TVectorD  par(3);
     353             :   TVectorD  sigma(3);
     354             :   TMatrixD mat(3,3);
     355             :   if (his->GetMaximum()<4) return -1;  
     356             :   if (his->GetEntries()<12) return -1;  
     357             :   if (his->GetRMS()<mat.GetTol()) return -1;
     358             :   Float_t maxEstimate   = his->GetEntries()*his->GetBinWidth(1)/TMath::Sqrt((TMath::TwoPi()*his->GetRMS()));
     359             :   Int_t dsmooth = TMath::Nint(6./TMath::Sqrt(maxEstimate));
     360             : 
     361             :   if (maxEstimate<1) return -1;
     362             :   Int_t nbins    = his->GetNbinsX();
     363             :   Int_t npoints=0;
     364             :   //
     365             : 
     366             : 
     367             :   if (xmin>=xmax){
     368             :     xmin = his->GetXaxis()->GetXmin();
     369             :     xmax = his->GetXaxis()->GetXmax();
     370             :   }
     371             :   for (Int_t iter=0; iter<2; iter++){
     372             :     fitter.ClearPoints();
     373             :     npoints=0;
     374             :     for (Int_t ibin=1;ibin<nbins+1; ibin++){
     375             :       Int_t countB=1;
     376             :       Float_t entriesI =  his->GetBinContent(ibin);
     377             :       for (Int_t delta = -dsmooth; delta<=dsmooth; delta++){
     378             :         if (ibin+delta>1 &&ibin+delta<nbins-1){
     379             :           entriesI +=  his->GetBinContent(ibin+delta);
     380             :           countB++;
     381             :         }
     382             :       }
     383             :       entriesI/=countB;
     384             :       Double_t xcenter= his->GetBinCenter(ibin);
     385             :       if (xcenter<xmin || xcenter>xmax) continue;
     386             :       Double_t error=1./TMath::Sqrt(countB);
     387             :       Float_t   cont=2;
     388             :       if (iter>0){
     389             :         if (par[0]+par[1]*xcenter+par[2]*xcenter*xcenter>20) return 0;
     390             :         cont = TMath::Exp(par[0]+par[1]*xcenter+par[2]*xcenter*xcenter);
     391             :         if (cont>1.) error = 1./TMath::Sqrt(cont*Float_t(countB));
     392             :       }
     393             :       if (entriesI>1&&cont>1){
     394             :         fitter.AddPoint(&xcenter,TMath::Log(Float_t(entriesI)),error);
     395             :         npoints++;
     396             :       }
     397             :     }  
     398             :     if (npoints>3){
     399             :       fitter.Eval();
     400             :       fitter.GetParameters(par);
     401             :     }else{
     402             :       break;
     403             :     }
     404             :   }
     405             :   if (npoints<=3){
     406             :     return -1;
     407             :   }
     408             :   fitter.GetParameters(par);
     409             :   fitter.GetCovarianceMatrix(mat);
     410             :   if (TMath::Abs(par[1])<mat.GetTol()) return -1;
     411             :   if (TMath::Abs(par[2])<mat.GetTol()) return -1;
     412             :   Double_t chi2 = fitter.GetChisquare()/Float_t(npoints);
     413             :   //fitter.GetParameters();
     414             :   if (!param)  param  = new TVectorT<T>(3);
     415             :   // if (!matrix) matrix = new TMatrixD(3,3); // Covariance matrix to be implemented
     416             :   (*param)[1] = par[1]/(-2.*par[2]);
     417             :   (*param)[2] = 1./TMath::Sqrt(TMath::Abs(-2.*par[2]));
     418             :   (*param)[0] = TMath::Exp(par[0]+ par[1]* (*param)[1] +  par[2]*(*param)[1]*(*param)[1]);
     419             :   if (verbose){
     420             :     par.Print();
     421             :     mat.Print();
     422             :     param->Print();
     423             :     printf("Chi2=%f\n",chi2);
     424             :     TF1 * f1= new TF1("f1","[0]*exp(-(x-[1])^2/(2*[2]*[2]))",his->GetXaxis()->GetXmin(),his->GetXaxis()->GetXmax());
     425             :     f1->SetParameter(0, (*param)[0]);
     426             :     f1->SetParameter(1, (*param)[1]);
     427             :     f1->SetParameter(2, (*param)[2]);    
     428             :     f1->Draw("same");
     429             :   }
     430             :   return chi2;
     431             : }
     432             : 
     433             : template <typename T> 
     434             : void TStatToolkit::LTM(TH1 * his, TVectorT<T> *param , Float_t fraction,  Bool_t verbose){
     435             :   //
     436             :   // LTM : Trimmed mean on histogram - Modified version for binned data
     437             :   //
     438             :   // Robust statistic to estimate properties of the distribution
     439             :   // See http://en.wikipedia.org/w/index.php?title=Trimmed_estimator&oldid=582847999
     440             :   //
     441             :   // New faster version is under preparation
     442             :   //
     443           0 :   if (!param) return;
     444           0 :   (*param)[0]=0;
     445           0 :   (*param)[1]=0;
     446           0 :   (*param)[2]=0;  
     447           0 :   Int_t nbins    = his->GetNbinsX();
     448           0 :   Int_t nentries = (Int_t)his->GetEntries();
     449           0 :   if (nentries<=0) return;
     450           0 :   Double_t *data  = new Double_t[nentries];
     451             :   Int_t npoints=0;
     452           0 :   for (Int_t ibin=1;ibin<nbins; ibin++){
     453           0 :     Double_t entriesI = his->GetBinContent(ibin);
     454             :     //Double_t xcenter= his->GetBinCenter(ibin);
     455           0 :     Double_t x0 =  his->GetXaxis()->GetBinLowEdge(ibin);
     456           0 :     Double_t w  =  his->GetXaxis()->GetBinWidth(ibin);
     457           0 :     for (Int_t ic=0; ic<entriesI; ic++){
     458           0 :       if (npoints<nentries){
     459           0 :         data[npoints]= x0+w*Double_t((ic+0.5)/entriesI);
     460           0 :         npoints++;
     461           0 :       }
     462             :     }
     463             :   }
     464           0 :   Double_t mean, sigma;  
     465           0 :   Int_t npoints2=TMath::Min(Int_t(fraction*Float_t(npoints)),npoints-1);
     466           0 :   npoints2=TMath::Max(Int_t(0.5*Float_t(npoints)),npoints2);
     467           0 :   TStatToolkit::EvaluateUni(npoints, data, mean,sigma,npoints2);
     468           0 :   delete [] data;
     469           0 :   if (verbose)  printf("Mean\t%f\t Sigma2\t%f\n", mean,sigma);if (param){
     470           0 :     (*param)[0] = his->GetMaximum();
     471           0 :     (*param)[1] = mean;
     472           0 :     (*param)[2] = sigma;    
     473           0 :   }
     474           0 : }
     475             : 
     476             : 
     477             : template <typename T> 
     478             : Double_t  TStatToolkit::FitGaus(Float_t *arr, Int_t nBins, Float_t xMin, Float_t xMax, TVectorT<T> *param, TMatrixT<T> */*matrix*/, Bool_t verbose){
     479             :   //
     480             :   //  Fit histogram with gaussian function
     481             :   //  
     482             :   //  Prameters:
     483             :   //     nbins: size of the array and number of histogram bins
     484             :   //     xMin, xMax: histogram range
     485             :   //     param: paramters of the fit (0-Constant, 1-Mean, 2-Sigma)
     486             :   //     matrix: covariance matrix -- not implemented yet, pass dummy matrix!!!
     487             :   //
     488             :   //  Return values:
     489             :   //    >0: the chi2 returned by TLinearFitter
     490             :   //    -3: only three points have been used for the calculation - no fitter was used
     491             :   //    -2: only two points have been used for the calculation - center of gravity was uesed for calculation
     492             :   //    -1: only one point has been used for the calculation - center of gravity was uesed for calculation
     493             :   //    -4: invalid result!!
     494             :   //
     495             :   //  Fitting:
     496             :   //  1. Step - make logarithm
     497             :   //  2. Linear  fit (parabola) - more robust - always converge
     498             :   //  
     499           0 :   static TLinearFitter fitter(3,"pol2");
     500           0 :   static TMatrixD mat(3,3);
     501           0 :   static Double_t kTol = mat.GetTol();
     502           0 :   fitter.StoreData(kFALSE);
     503           0 :   fitter.ClearPoints();
     504           0 :   TVectorD  par(3);
     505           0 :   TVectorD  sigma(3);
     506           0 :   TMatrixD matA(3,3);
     507           0 :   TMatrixD b(3,1);
     508           0 :   Float_t rms = TMath::RMS(nBins,arr);
     509           0 :   Float_t max = TMath::MaxElement(nBins,arr);
     510           0 :   Float_t binWidth = (xMax-xMin)/(Float_t)nBins;
     511             : 
     512             :   Float_t meanCOG = 0;
     513             :   Float_t rms2COG = 0;
     514             :   Float_t sumCOG  = 0;
     515             : 
     516             :   Float_t entries = 0;
     517             :   Int_t nfilled=0;
     518             : 
     519           0 :   for (Int_t i=0; i<nBins; i++){
     520           0 :       entries+=arr[i];
     521           0 :       if (arr[i]>0) nfilled++;
     522             :   }
     523             : 
     524           0 :   if (max<4) return -4;
     525           0 :   if (entries<12) return -4;
     526           0 :   if (rms<kTol) return -4;
     527             : 
     528             :   Int_t npoints=0;
     529             :   //
     530             : 
     531             :   //
     532           0 :   for (Int_t ibin=0;ibin<nBins; ibin++){
     533           0 :       Float_t entriesI = arr[ibin];
     534           0 :     if (entriesI>1){
     535           0 :       Double_t xcenter = xMin+(ibin+0.5)*binWidth;
     536             :       
     537           0 :       Float_t error    = 1./TMath::Sqrt(entriesI);
     538           0 :       Float_t val = TMath::Log(Float_t(entriesI));
     539           0 :       fitter.AddPoint(&xcenter,val,error);
     540           0 :       if (npoints<3){
     541           0 :           matA(npoints,0)=1;
     542           0 :           matA(npoints,1)=xcenter;
     543           0 :           matA(npoints,2)=xcenter*xcenter;
     544           0 :           b(npoints,0)=val;
     545           0 :           meanCOG+=xcenter*entriesI;
     546           0 :           rms2COG +=xcenter*entriesI*xcenter;
     547           0 :           sumCOG +=entriesI;
     548           0 :       }
     549           0 :       npoints++;
     550           0 :     }
     551             :   }
     552             : 
     553             :   
     554             :   Double_t chi2 = 0;
     555           0 :   if (npoints>=3){
     556           0 :       if ( npoints == 3 ){
     557             :           //analytic calculation of the parameters for three points
     558           0 :           matA.Invert();
     559           0 :           TMatrixD res(1,3);
     560           0 :           res.Mult(matA,b);
     561           0 :           par[0]=res(0,0);
     562           0 :           par[1]=res(0,1);
     563           0 :           par[2]=res(0,2);
     564             :           chi2 = -3.;
     565           0 :       } else {
     566             :           // use fitter for more than three points
     567           0 :           fitter.Eval();
     568           0 :           fitter.GetParameters(par);
     569           0 :           fitter.GetCovarianceMatrix(mat);
     570           0 :           chi2 = fitter.GetChisquare()/Float_t(npoints);
     571             :       }
     572           0 :       if (TMath::Abs(par[1])<kTol) return -4;
     573           0 :       if (TMath::Abs(par[2])<kTol) return -4;
     574             : 
     575           0 :       if (!param)  param  = new TVectorT<T>(3);
     576             :       //if (!matrix) matrix = new TMatrixT<T>(3,3);  // !!!!might be a memory leek. use dummy matrix pointer to call this function! // Covariance matrix to be implemented
     577             : 
     578           0 :       (*param)[1] = par[1]/(-2.*par[2]);
     579           0 :       (*param)[2] = 1./TMath::Sqrt(TMath::Abs(-2.*par[2]));
     580           0 :       Double_t lnparam0 = par[0]+ par[1]* (*param)[1] +  par[2]*(*param)[1]*(*param)[1];
     581           0 :       if ( lnparam0>307 ) return -4;
     582           0 :       (*param)[0] = TMath::Exp(lnparam0);
     583           0 :       if (verbose){
     584           0 :           par.Print();
     585           0 :           mat.Print();
     586           0 :           param->Print();
     587           0 :           printf("Chi2=%f\n",chi2);
     588           0 :           TF1 * f1= new TF1("f1","[0]*exp(-(x-[1])^2/(2*[2]*[2]))",xMin,xMax);
     589           0 :           f1->SetParameter(0, (*param)[0]);
     590           0 :           f1->SetParameter(1, (*param)[1]);
     591           0 :           f1->SetParameter(2, (*param)[2]);
     592           0 :           f1->Draw("same");
     593           0 :       }
     594           0 :       return chi2;
     595             :   }
     596             : 
     597           0 :   if (npoints == 2){
     598             :       //use center of gravity for 2 points
     599           0 :       meanCOG/=sumCOG;
     600           0 :       rms2COG /=sumCOG;
     601           0 :       (*param)[0] = max;
     602           0 :       (*param)[1] = meanCOG;
     603           0 :       (*param)[2] = TMath::Sqrt(TMath::Abs(meanCOG*meanCOG-rms2COG));
     604             :       chi2=-2.;
     605           0 :   }
     606           0 :   if ( npoints == 1 ){
     607           0 :       meanCOG/=sumCOG;
     608           0 :       (*param)[0] = max;
     609           0 :       (*param)[1] = meanCOG;
     610           0 :       (*param)[2] = binWidth/TMath::Sqrt(12);
     611             :       chi2=-1.;
     612           0 :   }
     613           0 :   return chi2;
     614             : 
     615           0 : }
     616             : 
     617             : template <typename T> 
     618             : Int_t* TStatToolkit::LTMUnbinned(int np, const T *arr, TVectorT<T> &params , Float_t keep)
     619             : {
     620             :   //
     621             :   // LTM : Trimmed mean of unbinned array
     622             :   // 
     623             :   // Robust statistic to estimate properties of the distribution
     624             :   // To handle binning error special treatment
     625             :   // for definition of unbinned data see:
     626             :   //     http://en.wikipedia.org/w/index.php?title=Trimmed_estimator&oldid=582847999
     627             :   //
     628             :   // Function parameters:
     629             :   //     np      - number of points in the array
     630             :   //     arr     - data array (unsorted)
     631             :   //     params  - vector with parameters
     632             :   //             - 0 - area
     633             :   //             - 1 - mean
     634             :   //             - 2 - rms 
     635             :   //             - 3 - error estimate of mean
     636             :   //             - 4 - error estimate of RMS
     637             :   //             - 5 - first accepted element (of sorted array)
     638             :   //             - 6 - last accepted  element (of sorted array)
     639             :   //
     640             :   // On success returns index of sorted events 
     641             :   //
     642             :   static int book = 0;
     643             :   static int *index = 0;
     644             :   static float* w = 0;
     645           0 :   int keepN = np*keep;
     646           0 :   if (keepN>np) keepN = np;
     647           0 :   if (keepN<2) return 0;
     648           0 :   params[0] = 0.0f;
     649           0 :   if (book<np) {
     650           0 :     delete[] index;
     651           0 :     book = np;
     652           0 :     index = new int[book];
     653           0 :     delete[] w;
     654           0 :     w = new float[book+book];
     655           0 :   }
     656             :   //
     657           0 :   float *wx1 = w, *wx2 = wx1+np;
     658           0 :   TMath::Sort(np,arr,index,kFALSE); // sort in increasing order
     659             :   // build cumulants
     660             :   double sum1=0.0,sum2=0.0;
     661           0 :   for (int i=0;i<np;i++) {
     662           0 :     double x = arr[index[i]];
     663           0 :     wx1[i] = (sum1+=x);
     664           0 :     wx2[i] = (sum2+=x*x);
     665             :   }
     666           0 :   double minRMS = sum2+1e6;
     667           0 :   params[0] = keepN;
     668           0 :   int limI = np - keepN+1;
     669           0 :   for (int i=0;i<limI;i++) {
     670           0 :     int limJ = i+keepN-1;
     671           0 :     Double_t sum1 = double(wx1[limJ]) - double(i ? wx1[i-1] : 0.0);
     672           0 :     Double_t sum2 = double(wx2[limJ]) - double(i ? wx2[i-1] : 0.0);
     673           0 :     double mean = sum1/keepN;
     674           0 :     double rms2 = sum2/keepN - mean*mean;
     675             :     //    printf("%d : %d %e %e\n",i,limJ, mean, TMath::Sqrt(rms2));
     676           0 :     if (rms2>minRMS) continue;
     677             :     minRMS = rms2;
     678           0 :     params[1] = mean;
     679           0 :     params[2] = rms2;
     680           0 :     params[5] = i;
     681           0 :     params[6] = limJ;
     682           0 :   }
     683             :   //
     684           0 :   if (!params[0]) return 0;
     685           0 :   params[2] = TMath::Sqrt(params[2]);
     686           0 :   params[3] = params[2]/TMath::Sqrt(params[0]); // error on mean
     687           0 :   params[4] = params[3]/TMath::Sqrt(2.0); // error on RMS
     688           0 :   return index;
     689           0 : }
     690             : 
     691             : template <typename T> 
     692             : void TStatToolkit::Reorder(int np, T *arr, const int *idx)
     693             : {
     694             :   // rearange arr in order given by idx
     695             :   const int kMaxOnStack = 10000;
     696             :   // don't abuse stack
     697           0 :   T *arrCHeap=0, arrCstack[np<kMaxOnStack ? np:1], *arrC=np<kMaxOnStack ? &arrCstack[0] : (arrCHeap=new T[np]);
     698           0 :   memcpy(arrC,arr,np*sizeof(T));
     699           0 :   for (int i=np;i--;) arr[i] = arrC[idx[i]];
     700           0 :   delete[] arrCHeap;
     701             :   //
     702           0 : }
     703             : 
     704             : #endif

Generated by: LCOV version 1.11