LCOV - code coverage report
Current view: top level - STEER/CDB - AliSplineFit.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 19 655 2.9 %
Date: 2016-06-14 17:26:59 Functions: 3 27 11.1 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 2006-07, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : //-------------------------------------------------------------------------
      17             : //                Implementation of the AliSplineFit class
      18             : //   The class performs a spline fit on an incoming TGraph. The graph is
      19             : //   divided into several parts (identified by knots between each part).
      20             : //   Spline fits are performed on each part. According to user parameters,
      21             : //   the function, first and second derivative are requested to be continuous
      22             : //   at each knot.
      23             : //        Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
      24             : //   Adjustments by Haavard Helstrup,  Haavard.Helstrup@cern.ch
      25             : //-------------------------------------------------------------------------
      26             : 
      27             : 
      28             : #include "AliSplineFit.h"
      29             : #include "AliLog.h"
      30             : 
      31         128 : ClassImp(AliSplineFit)
      32             : 
      33             : TLinearFitter* AliSplineFit::fitterStatic()
      34             : {
      35           0 :   static TLinearFitter* fit = new TLinearFitter(4,"pol3","");
      36           0 :   return fit;
      37           0 : }
      38             : 
      39        1605 : AliSplineFit::AliSplineFit() :
      40        1605 :   fBDump(kFALSE),
      41        1605 :   fGraph (0),
      42        1605 :   fNmin (0),
      43        1605 :   fMinPoints(0),
      44        1605 :   fSigma (0),
      45        1605 :   fMaxDelta (0),
      46        1605 :   fN0 (0),
      47        1605 :   fParams (0),
      48        1605 :   fCovars (0),
      49        1605 :   fIndex (0),
      50        1605 :   fN    (0),
      51        1605 :   fChi2  (0.0),
      52        1605 :   fX   (0),
      53        1605 :   fY0  (0),
      54        1605 :   fY1  (0),
      55        1605 :   fChi2I (0)
      56             :   //
      57             :   // Default constructor
      58             :   //
      59        9630 : { }
      60             : 
      61             : 
      62             : 
      63             : AliSplineFit::AliSplineFit(const AliSplineFit& source) :
      64           0 :   TObject(source),
      65           0 :   fBDump (source.fBDump),
      66           0 :   fGraph (source.fGraph),
      67           0 :   fNmin  (source.fNmin),
      68           0 :   fMinPoints (source.fMinPoints),
      69           0 :   fSigma (source.fSigma),
      70           0 :   fMaxDelta (source.fMaxDelta),
      71           0 :   fN0    (source.fN0),
      72           0 :   fParams (0),
      73           0 :   fCovars (0),
      74           0 :   fIndex (0),
      75           0 :   fN     (source.fN),
      76           0 :   fChi2  (0.0),
      77           0 :   fX   (0),
      78           0 :   fY0  (0),
      79           0 :   fY1  (0),
      80           0 :   fChi2I  (source.fChi2I)
      81           0 : {
      82             : //
      83             : //  Copy constructor
      84             : //
      85           0 :   fIndex = new Int_t[fN0];
      86           0 :   fParams = new TClonesArray("TVectorD",fN0);
      87           0 :   fCovars = new TClonesArray("TMatrixD",fN0);
      88           0 :   fParams = (TClonesArray*)source.fParams->Clone();
      89           0 :   fCovars = (TClonesArray*)source.fCovars->Clone();
      90           0 :   for (Int_t i=0; i<fN0; i++) fIndex[i] = source.fIndex[i];
      91             : 
      92           0 :   fX     = new Double_t[fN];
      93           0 :   fY0    = new Double_t[fN];
      94           0 :   fY1    = new Double_t[fN];
      95           0 :   fChi2I = new Double_t[fN];
      96           0 :   for (Int_t i=0; i<fN; i++){
      97           0 :     fX[i]  = source.fX[i];
      98           0 :     fY0[i] = source.fY0[i];
      99           0 :     fY1[i] = source.fY1[i];
     100           0 :     fChi2I[i] = source.fChi2I[i];
     101             :   }
     102           0 : }
     103             : 
     104             : AliSplineFit& AliSplineFit::operator=(const AliSplineFit& source){
     105             : //
     106             : //  assignment operator
     107             : //
     108           0 :   if (&source == this) return *this;
     109             : 
     110             : //
     111             : // reassign memory as previous fit could have a different size
     112             : //
     113             : 
     114           0 :   if ( fN0 != source.fN0) {
     115             : 
     116           0 :     delete fParams;
     117           0 :     delete fCovars;
     118           0 :     delete []fIndex;
     119             : 
     120           0 :     fN0 = source.fN0;
     121           0 :     fIndex = new Int_t[fN0];
     122           0 :     fParams = new TClonesArray("TVectorD",fN0);
     123           0 :     fCovars = new TClonesArray("TMatrixD",fN0);
     124           0 :   }
     125           0 :   if ( fN != source.fN) {
     126             : 
     127           0 :     delete []fX;
     128           0 :     delete []fY0;
     129           0 :     delete []fY1;
     130           0 :     delete []fChi2I;
     131           0 :     fN = source.fN;
     132           0 :     fX     = new Double_t[fN];
     133           0 :     fY0    = new Double_t[fN];
     134           0 :     fY1    = new Double_t[fN];
     135           0 :     fChi2I = new Double_t[fN];
     136           0 :   }
     137             : 
     138             : // use copy constructor (without reassigning memory) to copy values
     139             : 
     140           0 :   return *this;
     141           0 : }
     142             : 
     143             : 
     144           0 : AliSplineFit::~AliSplineFit(){
     145             :   //
     146             :   // destructor. Don't delete fGraph, as this normally comes as input parameter
     147             :   //
     148           0 :   delete []fX;
     149           0 :   delete []fY0;
     150           0 :   delete []fY1;
     151           0 :   delete []fChi2I;
     152           0 :   delete fParams;
     153           0 :   delete fCovars;
     154           0 :   delete []fIndex;
     155           0 : }
     156             : 
     157             : Double_t   AliSplineFit::Eval(Double_t x, Int_t deriv) const{
     158             :   //
     159             :   // evaluate value at x
     160             :   //   deriv = 0: function value
     161             :   //         = 1: first derivative
     162             :   //         = 2: 2nd derivative
     163             :   //         = 3: 3rd derivative
     164             :   //
     165             :   //  a2 = -(3*a0 -3*b0 + 2*a1*dx +b1*dx)/(dx*dx)
     166             :   //  a3 = -(-2*a0+2*b0 - a1*dx - b1*dx)/(dx*dx*dx)
     167             : 
     168           0 :   Int_t index = TMath::BinarySearch(fN,fX,x);
     169           0 :   if (index<0) index =0;
     170           0 :   if (index>fN-2) index =fN-2;
     171             :   //
     172           0 :   Double_t dx   = x-fX[index];
     173           0 :   Double_t dxc  = fX[index+1]-fX[index];
     174           0 :   if (dxc<=0)    return fY0[index];
     175           0 :   Double_t y0   = fY0[index];
     176           0 :   Double_t y1   = fY1[index];
     177           0 :   Double_t y01  = fY0[index+1];
     178           0 :   Double_t y11  = fY1[index+1];
     179           0 :   Double_t y2   = -(3.*y0-3.*y01+2*y1*dxc+y11*dxc)/(dxc*dxc);
     180           0 :   Double_t y3   = -(-2.* y0 + 2*y01 -  y1*dxc - y11*dxc) /(dxc*dxc*dxc);
     181           0 :   Double_t val = y0+y1*dx+y2*dx*dx+y3*dx*dx*dx;
     182           0 :   if (deriv==1) val = y1+2.*y2*dx+3.*y3*dx*dx;
     183           0 :   if (deriv==2) val = 2.*y2+6.*y3*dx;
     184           0 :   if (deriv==3) val = 6*y3;
     185             :   return val;
     186           0 : }
     187             : 
     188             : 
     189             : TGraph * AliSplineFit::GenerGraph(Int_t npoints, Double_t fraction, Double_t s1, Double_t s2, Double_t s3, Int_t der){
     190             :   //
     191             :   // generate random graph 
     192             :   // xrange 0,1
     193             :   // yrange 0,1
     194             :   // s1, s2, s3 -  sigma of derivative
     195             :   // fraction   -  
     196             : 
     197           0 :   Double_t *value = new Double_t[npoints];
     198           0 :   Double_t *time  = new Double_t[npoints];
     199             :   Double_t d0=0, d1=0,d2=0,d3=0;
     200           0 :   value[0] = d0;
     201           0 :   time[0]  = 0;
     202           0 :   for(Int_t i=1; i<npoints; i++){
     203           0 :     Double_t dtime = 1./npoints;
     204             :     Double_t dd1 = dtime;
     205           0 :     Double_t dd2 = dd1*dd1;
     206           0 :     Double_t dd3 = dd2*dd1;
     207           0 :     d0 += d1*dd1 + d2*dd2/2. + d3*dd3/6.;
     208           0 :     d1 += d2*dd1 +d3*dd2/2;
     209           0 :     d2 += d3*dd1;
     210           0 :     value[i] = d0;
     211           0 :     time[i]  = time[i-1]+dtime;
     212           0 :     d1 =(1.-fraction)*d1+fraction*(gRandom->Exp(s1))*(gRandom->Rndm()-0.5);
     213           0 :     d2 =(1.-fraction)*d2+fraction*(gRandom->Exp(s2))*(gRandom->Rndm()-0.5);
     214           0 :     d3 =(1.-fraction)*d3+fraction*(gRandom->Exp(s3))*(gRandom->Rndm()-0.5);
     215           0 :     if (gRandom->Rndm()<fraction) d3 =(1.-fraction)*d3+fraction*(gRandom->BreitWigner(0,s3));
     216             :   }
     217           0 :   Double_t dmean = (value[npoints-1]-value[0])/(time[npoints-1]-time[0]);
     218             :   Double_t min = value[0];
     219             :   Double_t max = value[0];
     220           0 :   for (Int_t i=0; i<npoints; i++){
     221           0 :     value[i]  = value[i]-dmean*(time[i]-time[0]); 
     222           0 :     if (value[i]<min) min=value[i];
     223           0 :     if (value[i]>max) max=value[i];
     224             :   }
     225             : 
     226           0 :   for (Int_t i=0; i<npoints; i++){
     227           0 :     value[i]  = (value[i]-min)/(max-min); 
     228             :   }
     229           0 :   if (der==1) for (Int_t i=1; i<npoints; i++){
     230           0 :     value[i-1]  =  (value[i]-value[i-1])/(time[i]-time[i-1]);
     231           0 :   }
     232             : 
     233           0 :   TGraph * graph = new TGraph(npoints,time,value);
     234             : 
     235           0 :   delete [] value;
     236           0 :   delete [] time; 
     237           0 :   return graph;  
     238           0 : }
     239             : 
     240             : 
     241             : TGraph * AliSplineFit::GenerNoise(TGraph * graph0, Double_t sigma0){
     242             :   //
     243             :   // add noise to graph
     244             :   //
     245             : 
     246           0 :   Int_t npoints=graph0->GetN();
     247           0 :   Double_t *value = new Double_t[npoints];
     248           0 :   Double_t *time  = new Double_t[npoints];
     249           0 :   for(Int_t i=0; i<npoints; i++){
     250           0 :     time[i]  = graph0->GetX()[i];
     251           0 :     value[i] = graph0->GetY()[i]+gRandom->Gaus(0,sigma0);
     252             :   }
     253           0 :   TGraph * graph = new TGraph(npoints,time,value);
     254             : 
     255           0 :   delete [] value;
     256           0 :   delete [] time;
     257           0 :   return graph;  
     258           0 : }
     259             : 
     260             : 
     261             : TGraph * AliSplineFit::MakeGraph(Double_t xmin, Double_t xmax, Int_t npoints, Int_t deriv) const {
     262             :   //
     263             :   // if npoints<=0 draw derivative
     264             :   //
     265             : 
     266             :   TGraph *graph =0;
     267           0 :   if (npoints<=0) {
     268           0 :     if (deriv<=0) 
     269           0 :       return new TGraph(fN,fX,fY0);
     270           0 :     else if (deriv==1) 
     271           0 :       return new TGraph(fN,fX,fY1);
     272           0 :     else if(deriv>2)
     273           0 :       return new TGraph(fN-1,fX,fChi2I);
     274             :     else {
     275           0 :       AliWarning("npoints == 0 et deriv == 2: unhandled condition");
     276           0 :       return 0;
     277             :     }
     278             :   }
     279           0 :   Double_t * x = new Double_t[npoints+1];
     280           0 :   Double_t * y = new Double_t[npoints+1];
     281           0 :   for (Int_t ip=0; ip<=npoints; ip++){
     282           0 :     x[ip] = xmin+ (xmax-xmin)*(Double_t(ip)/Double_t(npoints));
     283           0 :     y[ip] = Eval(x[ip],deriv);
     284             :   }
     285             : 
     286           0 :   graph = new TGraph(npoints,x,y);
     287           0 :   delete [] x;
     288           0 :   delete [] y;
     289             :   return graph;
     290           0 : }
     291             : 
     292             : TGraph * AliSplineFit::MakeDiff(TGraph * graph0) const {
     293             :   //
     294             :   // Make graph of difference to reference graph
     295             :   //
     296             :   
     297           0 :   Int_t npoints=graph0->GetN();
     298             :   TGraph *graph =0;
     299           0 :   Double_t * x = new Double_t[npoints];
     300           0 :   Double_t * y = new Double_t[npoints];
     301           0 :   for (Int_t ip=0; ip<npoints; ip++){
     302           0 :     x[ip] = graph0->GetX()[ip];
     303           0 :     y[ip] = Eval(x[ip],0)-graph0->GetY()[ip];
     304             :   }
     305           0 :   graph = new TGraph(npoints,x,y);
     306           0 :   delete [] x;
     307           0 :   delete [] y;
     308           0 :   return graph;
     309           0 : }
     310             : 
     311             : 
     312             : TH1F * AliSplineFit::MakeDiffHisto(TGraph * graph0) const {
     313             :   //
     314             :   // Make histogram of difference to reference graph
     315             :   //
     316             : 
     317           0 :   Int_t npoints=graph0->GetN();
     318             :   Float_t min=1e38,max=-1e38;
     319           0 :   for (Int_t ip=0; ip<npoints; ip++){
     320           0 :     Double_t x = graph0->GetX()[ip];
     321           0 :     Double_t y = Eval(x,0)-graph0->GetY()[ip];
     322           0 :     if (ip==0) {
     323           0 :       min = y;
     324             :       max = y;
     325           0 :     }else{
     326           0 :       if (y<min) min=y;
     327           0 :       if (y>max) max=y;
     328             :     }
     329             :   }
     330             : 
     331           0 :   TH1F *his = new TH1F("hdiff","hdiff", 100, min, max);
     332           0 :   for (Int_t ip=0; ip<npoints; ip++){
     333           0 :     Double_t x = graph0->GetX()[ip];
     334           0 :     Double_t y = Eval(x,0)-graph0->GetY()[ip];
     335           0 :     his->Fill(y);
     336             :   }
     337             : 
     338           0 :   return his;
     339           0 : }
     340             : 
     341             : 
     342             : 
     343             : void AliSplineFit::InitKnots(TGraph * graph, Int_t min, Int_t iter, Double_t maxDelta){
     344             :   //
     345             :   // initialize knots + estimate sigma of noise + make initial parameters
     346             :   //
     347             :   //
     348             : 
     349             :   const Double_t kEpsilon = 1.e-7;
     350           0 :   fGraph  = graph;
     351           0 :   fNmin   = min;
     352           0 :   fMaxDelta = maxDelta;
     353           0 :   Int_t npoints = fGraph->GetN();
     354             : 
     355             :   // Make simple spline if too few points in graph
     356             : 
     357           0 :   if (npoints < fMinPoints ) {
     358           0 :     CopyGraph();
     359           0 :     return;
     360             :   }
     361             : 
     362           0 :   fN0           = (npoints/fNmin)+1;
     363           0 :   Float_t delta = Double_t(npoints)/Double_t(fN0-1);
     364             : 
     365           0 :   fParams = new TClonesArray("TVectorD",fN0);
     366           0 :   fCovars = new TClonesArray("TMatrixD",fN0);
     367           0 :   fIndex  = new Int_t[fN0];
     368           0 :   TLinearFitter fitterLocal(4,"pol3");  // local fitter
     369             :   Double_t sigma2 =0;
     370             : 
     371             : 
     372           0 :   Double_t yMin=graph->GetY()[0];
     373           0 :   Double_t yMax=graph->GetY()[0];
     374             : 
     375           0 :   for (Int_t iKnot=0; iKnot<fN0; iKnot++){
     376           0 :     Int_t index0 = TMath::Nint(Double_t(iKnot)*Double_t(delta));
     377           0 :     Int_t index1 = TMath::Min(TMath::Nint(Double_t(iKnot+1)*Double_t(delta)),npoints-1);
     378           0 :     Int_t indexM = (iKnot>0) ? fIndex[iKnot-1]:index0;
     379           0 :     fIndex[iKnot]=TMath::Min(index0, npoints-1);
     380           0 :     Float_t startX =graph->GetX()[fIndex[iKnot]];
     381             : 
     382           0 :     for (Int_t ipoint=indexM; ipoint<index1; ipoint++){
     383           0 :       Double_t dxl   =graph->GetX()[ipoint]-startX;
     384           0 :       Double_t  y    = graph->GetY()[ipoint];
     385           0 :       if (y<yMin) yMin=y;
     386           0 :       if (y>yMax) yMax=y;
     387           0 :       fitterLocal.AddPoint(&dxl,y,1);
     388           0 :     }
     389             : 
     390           0 :     fitterLocal.Eval();
     391           0 :     sigma2 += fitterLocal.GetChisquare()/Double_t((index1-indexM)-4.);
     392           0 :     TMatrixD   * covar = new ((*fCovars)[iKnot]) TMatrixD(4,4);
     393           0 :     TVectorD   * param = new ((*fParams)[iKnot]) TVectorD(4);
     394           0 :     fitterLocal.GetParameters(*param);
     395           0 :     fitterLocal.GetCovarianceMatrix(*covar);
     396           0 :     fitterLocal.ClearPoints();
     397             :   }
     398           0 :   fSigma  =TMath::Sqrt(sigma2/Double_t(fN0));   // mean sigma
     399           0 :   Double_t tDiff = ((yMax-yMin)+TMath::Abs(yMax)+TMath::Abs(yMin))*kEpsilon;
     400           0 :   fSigma += tDiff+fMaxDelta/TMath::Sqrt(npoints);
     401           0 :   fMaxDelta +=tDiff;
     402           0 :   for (Int_t iKnot=0; iKnot<fN0; iKnot++){
     403           0 :     TMatrixD & cov = *((TMatrixD*)fCovars->At(iKnot));
     404           0 :     cov*=fSigma*fSigma;
     405             :   }
     406           0 :   OptimizeKnots(iter);
     407             : 
     408           0 :   fN = 0;
     409           0 :   for (Int_t iKnot=0; iKnot<fN0; iKnot++) if (fIndex[iKnot]>=0) fN++;
     410           0 :   fX  = new Double_t[fN];
     411           0 :   fY0 = new Double_t[fN];
     412           0 :   fY1 = new Double_t[fN];
     413           0 :   fChi2I = new Double_t[fN];
     414             :   Int_t iKnot=0;
     415           0 :   for (Int_t i=0; i<fN0; i++){
     416           0 :     if (fIndex[i]<0) continue;
     417           0 :     if (iKnot>=fN) {
     418           0 :       printf("AliSplineFit::InitKnots: Knot number > Max knot number\n");
     419           0 :       break;
     420             :     }
     421           0 :     TVectorD   * param = (TVectorD*) fParams->At(i);
     422           0 :     fX[iKnot]  = fGraph->GetX()[fIndex[i]];
     423           0 :     fY0[iKnot] = (*param)(0);
     424           0 :     fY1[iKnot] = (*param)(1);
     425           0 :     fChi2I[iKnot] = 0;
     426           0 :     iKnot++;
     427           0 :   }
     428           0 : }
     429             : 
     430             : 
     431             : Int_t AliSplineFit::OptimizeKnots(Int_t nIter){
     432             :   //
     433             :   //
     434             :   //
     435             :   const Double_t kMaxChi2= 5;
     436             :   Int_t nKnots=0;
     437           0 :   TTreeSRedirector cstream("SplineIter.root");
     438           0 :   for (Int_t iIter=0; iIter<nIter; iIter++){
     439           0 :     if (fBDump) cstream<<"Fit"<<
     440           0 :       "iIter="<<iIter<<
     441           0 :       "fit.="<<this<<
     442             :       "\n";
     443             :     nKnots=2;
     444           0 :     for (Int_t iKnot=1; iKnot<fN0-1; iKnot++){
     445           0 :       if (fIndex[iKnot]<0) continue;   //disabled knot
     446           0 :       Double_t chi2 = CheckKnot(iKnot); 
     447           0 :       Double_t startX = fGraph->GetX()[fIndex[iKnot]]; 
     448           0 :       if (fBDump) {
     449           0 :         TMatrixD   * covar = (TMatrixD*)fCovars->At(iKnot);
     450           0 :         TVectorD   * param = (TVectorD*)fParams->At(iKnot);
     451           0 :         cstream<<"Chi2"<<
     452           0 :          "iIter="<<iIter<<
     453           0 :          "iKnot="<<iKnot<<
     454           0 :          "chi2="<<chi2<<
     455           0 :          "x="<<startX<<
     456           0 :          "param="<<param<<
     457           0 :          "covar="<<covar<<
     458             :          "\n";
     459           0 :       }
     460           0 :       if (chi2>kMaxChi2) { nKnots++;continue;}
     461           0 :       fIndex[iKnot]*=-1;
     462           0 :       Int_t iPrevious=iKnot-1;
     463           0 :       Int_t iNext    =iKnot+1;
     464           0 :       while (fIndex[iPrevious]<0) iPrevious--;
     465           0 :       while (fIndex[iNext]<0) iNext++;
     466           0 :       RefitKnot(iPrevious);
     467           0 :       RefitKnot(iNext);
     468           0 :       iKnot++;
     469           0 :       while (iKnot<fN0-1&& fIndex[iKnot]<0) iKnot++;
     470           0 :     }
     471             :   }
     472             :   return nKnots;
     473           0 : }
     474             : 
     475             : 
     476             : Bool_t   AliSplineFit::RefitKnot(Int_t iKnot){
     477             :   //
     478             :   //
     479             :   //
     480             : 
     481           0 :   Int_t iPrevious=(iKnot>0)  ?iKnot-1: 0;
     482           0 :   Int_t iNext    =(iKnot<fN0)?iKnot+1: fN0-1;
     483           0 :   while (iPrevious>0&&fIndex[iPrevious]<0) iPrevious--;
     484           0 :   while (iNext<fN0&&fIndex[iNext]<0) iNext++;
     485           0 :   if (iPrevious<0) iPrevious=0;
     486           0 :   if (iNext>=fN0) iNext=fN0-1;
     487             :   
     488           0 :   Double_t startX = fGraph->GetX()[fIndex[iKnot]]; 
     489           0 :   AliSplineFit::fitterStatic()->ClearPoints();
     490           0 :   Int_t indPrev = fIndex[iPrevious];
     491           0 :   Int_t indNext = fIndex[iNext];
     492           0 :   Double_t *graphX = fGraph->GetX();
     493           0 :   Double_t *graphY = fGraph->GetY();
     494             : 
     495             :   // make arrays for points to fit (to save time)
     496             : 
     497           0 :   Int_t nPoints = indNext-indPrev;
     498           0 :   Double_t *xPoint = new Double_t[3*nPoints];
     499           0 :   Double_t *yPoint = &xPoint[nPoints];
     500           0 :   Double_t *ePoint = &xPoint[2*nPoints];
     501             :   Int_t indVec=0;
     502           0 :   for (Int_t iPoint=indPrev; iPoint<indNext; iPoint++, indVec++){
     503           0 :     Double_t dxl   = graphX[iPoint]-startX;
     504           0 :     Double_t  y    = graphY[iPoint];
     505           0 :     xPoint[indVec] = dxl;
     506           0 :     yPoint[indVec] = y;
     507           0 :     ePoint[indVec] =  fSigma;
     508             : //    ePoint[indVec] =  fSigma+TMath::Abs(y)*kEpsilon;
     509             : //    AliSplineFit::fitterStatic.AddPoint(&dxl,y,fSigma+TMath::Abs(y)*kEpsilon);
     510             :   }
     511           0 :   AliSplineFit::fitterStatic()->AssignData(nPoints,1,xPoint,yPoint,ePoint);
     512           0 :   AliSplineFit::fitterStatic()->Eval();
     513             : 
     514             : //  delete temporary arrays
     515             : 
     516           0 :   delete [] xPoint; 
     517             :   
     518           0 :   TMatrixD   * covar = (TMatrixD*)fCovars->At(iKnot);
     519           0 :   TVectorD   * param = (TVectorD*)fParams->At(iKnot);
     520           0 :   AliSplineFit::fitterStatic()->GetParameters(*param);
     521           0 :   AliSplineFit::fitterStatic()->GetCovarianceMatrix(*covar);
     522           0 :   return 0;
     523             : }
     524             : 
     525             : 
     526             : Float_t AliSplineFit::CheckKnot(Int_t iKnot){
     527             :   //
     528             :   //
     529             :   //
     530             : 
     531           0 :   Int_t iPrevious=iKnot-1;
     532           0 :   Int_t iNext    =iKnot+1;
     533           0 :   while (fIndex[iPrevious]<0) iPrevious--;
     534           0 :   while (fIndex[iNext]<0) iNext++;
     535           0 :   TVectorD &pPrevious = *((TVectorD*)fParams->At(iPrevious));
     536           0 :   TVectorD &pNext     = *((TVectorD*)fParams->At(iNext));
     537           0 :   TVectorD &pKnot     = *((TVectorD*)fParams->At(iKnot));
     538           0 :   TMatrixD &cPrevious = *((TMatrixD*)fCovars->At(iPrevious));
     539           0 :   TMatrixD &cNext     = *((TMatrixD*)fCovars->At(iNext));
     540           0 :   TMatrixD &cKnot     = *((TMatrixD*)fCovars->At(iKnot));
     541           0 :   Double_t xPrevious = fGraph->GetX()[fIndex[iPrevious]];
     542           0 :   Double_t xNext     = fGraph->GetX()[fIndex[iNext]];
     543           0 :   Double_t xKnot     = fGraph->GetX()[fIndex[iKnot]];
     544             : 
     545             :   // extra variables introduced to save processing time
     546             : 
     547           0 :   Double_t dxc  = xNext-xPrevious;
     548           0 :   Double_t invDxc = 1./dxc;
     549           0 :   Double_t invDxc2 = invDxc*invDxc;
     550           0 :   TMatrixD  tPrevious(4,4);
     551           0 :   TMatrixD  tNext(4,4);
     552             : 
     553           0 :   tPrevious(0,0) = 1;    tPrevious(1,1) = 1;
     554           0 :   tPrevious(2,0) = -3.*invDxc2;
     555           0 :   tPrevious(2,1) = -2.*invDxc;
     556           0 :   tPrevious(3,0) =  2.*invDxc2*invDxc;
     557           0 :   tPrevious(3,1) =  1.*invDxc2;
     558           0 :   tNext(2,0)     =  3.*invDxc2;      tNext(2,1)     = -1*invDxc;
     559           0 :   tNext(3,0)     = -2.*invDxc2*invDxc;  tNext(3,1)     =  1.*invDxc2;
     560           0 :   TMatrixD  tpKnot(4,4);
     561           0 :   TMatrixD  tpNext(4,4);
     562           0 :   Double_t dx = xKnot-xPrevious;
     563           0 :   tpKnot(0,0) = 1;      tpKnot(1,1) = 1;        tpKnot(2,2) = 1;        tpKnot(3,3) = 1;
     564           0 :   tpKnot(0,1) = dx;     tpKnot(0,2) = dx*dx;    tpKnot(0,3) = dx*dx*dx;
     565           0 :   tpKnot(1,2) = 2.*dx;  tpKnot(1,3) = 3.*dx*dx;
     566           0 :   tpKnot(2,3) = 3.*dx;
     567             :   Double_t dxn = xNext-xPrevious;
     568           0 :   tpNext(0,0) = 1;       tpNext(1,1) = 1;        tpNext(2,2) = 1;        tpNext(3,3) = 1;
     569           0 :   tpNext(0,1) = dxn;     tpNext(0,2) = dxn*dxn;    tpNext(0,3) = dxn*dxn*dxn;
     570           0 :   tpNext(1,2) = 2.*dxn;  tpNext(1,3) = 3.*dxn*dxn;
     571           0 :   tpNext(2,3) = 3.*dxn;
     572             : 
     573             :   //
     574             :   // matrix and vector at previous
     575             :   //
     576             : 
     577           0 :   TVectorD  sPrevious = tPrevious*pPrevious+tNext*pNext;
     578           0 :   TVectorD  sKnot     = tpKnot*sPrevious;
     579           0 :   TVectorD  sNext     = tpNext*sPrevious;
     580             :   
     581           0 :   TMatrixD csPrevious00(tPrevious, TMatrixD::kMult,cPrevious);
     582           0 :   csPrevious00 *= tPrevious.T();
     583           0 :   TMatrixD csPrevious01(tNext,TMatrixD::kMult,cNext);
     584           0 :   csPrevious01*=tNext.T();
     585           0 :   TMatrixD  csPrevious(csPrevious00,TMatrixD::kPlus,csPrevious01);
     586           0 :   TMatrixD  csKnot(tpKnot,TMatrixD::kMult,csPrevious);
     587           0 :   csKnot*=tpKnot.T();
     588           0 :   TMatrixD  csNext(tpNext,TMatrixD::kMult,csPrevious);
     589           0 :   csNext*=tpNext.T();
     590             : 
     591           0 :   TVectorD dPrevious = pPrevious-sPrevious;
     592           0 :   TVectorD dKnot     = pKnot-sKnot;
     593           0 :   TVectorD dNext     = pNext-sNext;
     594             :   //
     595             :   //
     596           0 :   TMatrixD prec(4,4);
     597           0 :   prec(0,0) = (fMaxDelta*fMaxDelta);
     598           0 :   prec(1,1) = prec(0,0)*invDxc2;
     599           0 :   prec(2,2) = prec(1,1)*invDxc2;
     600           0 :   prec(3,3) = prec(2,2)*invDxc2;
     601             : 
     602             : //   prec(0,0) = (fMaxDelta*fMaxDelta);
     603             : //   prec(1,1) = (fMaxDelta*fMaxDelta)/(dxc*dxc);
     604             : //   prec(2,2) = (fMaxDelta*fMaxDelta)/(dxc*dxc*dxc*dxc);
     605             : //   prec(3,3) = (fMaxDelta*fMaxDelta)/(dxc*dxc*dxc*dxc*dxc*dxc);
     606             : 
     607           0 :   csPrevious+=cPrevious;
     608           0 :   csPrevious+=prec;
     609           0 :   csPrevious.Invert(); 
     610           0 :   Double_t  chi2P     = dPrevious*(csPrevious*dPrevious);
     611             : 
     612           0 :   csKnot+=cKnot;
     613           0 :   csKnot+=prec;
     614           0 :   csKnot.Invert();
     615           0 :   Double_t  chi2K     = dKnot*(csKnot*dKnot);
     616             :   
     617           0 :   csNext+=cNext;
     618           0 :   csNext+=prec;
     619           0 :   csNext.Invert();
     620           0 :   Double_t  chi2N     = dNext*(csNext*dNext);    
     621             : 
     622           0 :   return (chi2P+chi2K+chi2N)/8.;
     623             : 
     624             : 
     625           0 : }
     626             : 
     627             : void AliSplineFit::SplineFit(Int_t nder){
     628             :   //
     629             :   // Cubic spline fit of graph
     630             :   //
     631             :   // nder
     632             :   // nder<0  - no continuity requirement
     633             :   //     =0  - continous  0 derivative
     634             :   //     =1  - continous  1 derivative
     635             :   //     >1  - continous  2 derivative
     636             :   //
     637           0 :   if (!fGraph) return;
     638             :   TGraph * graph = fGraph;
     639           0 :   if (nder>1) nder=2;
     640           0 :   Int_t nknots  = fN;
     641           0 :   if (nknots < 2 ) return;
     642           0 :   Int_t npoints = graph->GetN(); 
     643           0 :   if (npoints < fMinPoints ) return;
     644             :   //
     645             :   //
     646             :   // spline fit
     647             :   // each knot 4 parameters  
     648             :   //
     649             :   TMatrixD       *pmatrix = 0;
     650             :   TVectorD       *pvalues = 0;  
     651           0 :   if (nder>1){
     652           0 :     pmatrix = new TMatrixD(4*(nknots-1)+3*(nknots-2), 4*(nknots-1)+3*(nknots-2));
     653           0 :     pvalues = new TVectorD(4*(nknots-1)+3*(nknots-2));
     654           0 :   }
     655           0 :   if (nder==1){
     656           0 :     pmatrix = new TMatrixD(4*(nknots-1)+2*(nknots-2), 4*(nknots-1)+2*(nknots-2));
     657           0 :     pvalues = new TVectorD(4*(nknots-1)+2*(nknots-2));
     658           0 :   }
     659           0 :   if (nder==0){
     660           0 :     pmatrix = new TMatrixD(4*(nknots-1)+1*(nknots-2), 4*(nknots-1)+1*(nknots-2));
     661           0 :     pvalues = new TVectorD(4*(nknots-1)+1*(nknots-2));
     662           0 :   }
     663           0 :   if (nder<0){
     664           0 :     pmatrix = new TMatrixD(4*(nknots-1)+0*(nknots-2), 4*(nknots-1)+0*(nknots-2));
     665           0 :     pvalues = new TVectorD(4*(nknots-1)+0*(nknots-2));
     666           0 :   }
     667             :   
     668             :   
     669             :   TMatrixD &matrix = *pmatrix;
     670             :   TVectorD &values = *pvalues;
     671             :   Int_t    current = 0;
     672             : //
     673             : //  defined extra variables (current4 etc.) to save processing time.
     674             : //  fill normal matrices, then copy to sparse matrix.
     675             : //  
     676           0 :   Double_t *graphX = graph->GetX();
     677           0 :   Double_t *graphY = graph->GetY();
     678           0 :   for (Int_t ip=0;ip<npoints;ip++){
     679           0 :     if (current<nknots-2&&graphX[ip]>fX[current+1]) current++;
     680           0 :     Double_t xmiddle = (fX[current+1]+fX[current])*0.5;
     681           0 :     Double_t x1 = graphX[ip]- xmiddle;
     682           0 :     Double_t x2 = x1*x1;
     683           0 :     Double_t x3 = x2*x1;
     684           0 :     Double_t x4 = x2*x2;
     685           0 :     Double_t x5 = x3*x2;
     686           0 :     Double_t x6 = x3*x3;
     687           0 :     Double_t y  = graphY[ip];
     688           0 :     Int_t current4 = 4*current;
     689             : 
     690           0 :     matrix(current4  , current4  )+=1;
     691           0 :     matrix(current4  , current4+1)+=x1;
     692           0 :     matrix(current4  , current4+2)+=x2;
     693           0 :     matrix(current4  , current4+3)+=x3;
     694             :     //
     695           0 :     matrix(current4+1, current4  )+=x1;
     696           0 :     matrix(current4+1, current4+1)+=x2;
     697           0 :     matrix(current4+1, current4+2)+=x3;
     698           0 :     matrix(current4+1, current4+3)+=x4;
     699             :     //
     700           0 :     matrix(current4+2, current4  )+=x2;
     701           0 :     matrix(current4+2, current4+1)+=x3;
     702           0 :     matrix(current4+2, current4+2)+=x4;
     703           0 :     matrix(current4+2, current4+3)+=x5;
     704             :     //
     705           0 :     matrix(current4+3, current4  )+=x3;
     706           0 :     matrix(current4+3, current4+1)+=x4;
     707           0 :     matrix(current4+3, current4+2)+=x5;
     708           0 :     matrix(current4+3, current4+3)+=x6;
     709             :     //
     710           0 :     values(current4  ) += y;
     711           0 :     values(current4+1) += y*x1;
     712           0 :     values(current4+2) += y*x2;
     713           0 :     values(current4+3) += y*x3;
     714             :   }
     715             :   //
     716             :   // constraint 0
     717             :   //
     718           0 :   Int_t offset =4*(nknots-1)-1;
     719           0 :   if (nder>=0) for (Int_t iknot = 1; iknot<nknots-1; iknot++){
     720             : 
     721           0 :     Double_t dxm  =  (fX[iknot]-fX[iknot-1])*0.5;
     722           0 :     Double_t dxp  = -(fX[iknot+1]-fX[iknot])*0.5;
     723           0 :     Double_t dxm2 = dxm*dxm;
     724           0 :     Double_t dxp2 = dxp*dxp;
     725           0 :     Double_t dxm3 = dxm2*dxm;
     726           0 :     Double_t dxp3 = dxp2*dxp;
     727           0 :     Int_t iknot4  = 4*iknot;
     728           0 :     Int_t iknot41 = 4*(iknot-1);
     729           0 :     Int_t offsKnot = offset+iknot;
     730             :     //
     731             :     // condition on knot
     732             :     //
     733             :     // a0[i] = a0m[i-1]  + a1m[i-1]*dxm + a2m[i-1]*dxm^2 + a3m[i-1]*dxm^3
     734             :     // a0[i] = a0m[i-0]  + a1m[i-0]*dxp + a2m[i-0]*dxp^2 + a3m[i-0]*dxp^3
     735             :     // (a0m[i-1]  + a1m[i-1]*dxm + a2m[i-1]*dxm^2 + a3m[i-1]*dxm^3) -
     736             :     // (a0m[i-0]  + a1m[i-0]*dxp + a2m[i-0]*dxp^2 + a3m[i-0]*dxp^3)  = 0
     737             :     
     738           0 :     matrix(offsKnot, iknot41  )=1;
     739           0 :     matrix(offsKnot, iknot4   )=-1;
     740             : 
     741           0 :     matrix(offsKnot, iknot41+1)=dxm;
     742           0 :     matrix(offsKnot, iknot4 +1)=-dxp;
     743             : 
     744           0 :     matrix(offsKnot, iknot41+2)=dxm2;
     745           0 :     matrix(offsKnot, iknot4 +2)=-dxp2;
     746             : 
     747           0 :     matrix(offsKnot, iknot41+3)=dxm3;
     748           0 :     matrix(offsKnot, iknot4 +3)=-dxp3;
     749             : 
     750           0 :     matrix(iknot41  , offsKnot)=1;
     751           0 :     matrix(iknot41+1, offsKnot)=dxm;
     752           0 :     matrix(iknot41+2, offsKnot)=dxm2;
     753           0 :     matrix(iknot41+3, offsKnot)=dxm3;
     754           0 :     matrix(iknot4  , offsKnot)=-1;
     755           0 :     matrix(iknot4+1, offsKnot)=-dxp;
     756           0 :     matrix(iknot4+2, offsKnot)=-dxp2;
     757           0 :     matrix(iknot4+3, offsKnot)=-dxp3;
     758           0 :   }
     759             :   //
     760             :   // constraint 1
     761             :   //
     762           0 :   offset =4*(nknots-1)-1+(nknots-2);
     763           0 :   if (nder>=1)for (Int_t iknot = 1; iknot<nknots-1; iknot++){
     764             : 
     765           0 :     Double_t dxm  =  (fX[iknot]-fX[iknot-1])*0.5;
     766           0 :     Double_t dxp  = -(fX[iknot+1]-fX[iknot])*0.5;
     767           0 :     Double_t dxm2 = dxm*dxm;
     768           0 :     Double_t dxp2 = dxp*dxp;
     769           0 :     Int_t iknot4  = 4*iknot;
     770           0 :     Int_t iknot41 = 4*(iknot-1);
     771           0 :     Int_t offsKnot = offset+iknot;
     772             :     //
     773             :     // condition on knot derivation
     774             :     //
     775             :     // a0d[i] =  a1m[i-1] + 2*a2m[i-1]*dxm + 3*a3m[i-1]*dxm^2
     776             :     // a0d[i] =  a1m[i-0] + 2*a2m[i-0]*dxp + 3*a3m[i-0]*dxp^2
     777             :     
     778             :     //
     779           0 :     matrix(offsKnot, iknot41+1)= 1;
     780           0 :     matrix(offsKnot, iknot4 +1)=-1;
     781             : 
     782           0 :     matrix(offsKnot, iknot41+2)= 2.*dxm;
     783           0 :     matrix(offsKnot, iknot4 +2)=-2.*dxp;
     784             : 
     785           0 :     matrix(offsKnot, iknot41+3)= 3.*dxm2;
     786           0 :     matrix(offsKnot, iknot4 +3)=-3.*dxp2;
     787             : 
     788           0 :     matrix(iknot41+1, offsKnot)=1;
     789           0 :     matrix(iknot41+2, offsKnot)=2.*dxm;
     790           0 :     matrix(iknot41+3, offsKnot)=3.*dxm2;
     791             : 
     792           0 :     matrix(iknot4+1, offsKnot)=-1.;
     793           0 :     matrix(iknot4+2, offsKnot)=-2.*dxp;
     794           0 :     matrix(iknot4+3, offsKnot)=-3.*dxp2;
     795           0 :   }
     796             :   //
     797             :   // constraint 2
     798             :   //
     799           0 :   offset =4*(nknots-1)-1+2*(nknots-2);
     800           0 :   if (nder>=2) for (Int_t iknot = 1; iknot<nknots-1; iknot++){
     801             : 
     802           0 :     Double_t dxm  =  (fX[iknot]-fX[iknot-1])*0.5;
     803           0 :     Double_t dxp  = -(fX[iknot+1]-fX[iknot])*0.5;
     804           0 :     Int_t iknot4  = 4*iknot;
     805           0 :     Int_t iknot41 = 4*(iknot-1);
     806           0 :     Int_t offsKnot = offset+iknot;
     807             :     //
     808             :     // condition on knot second derivative
     809             :     //
     810             :     // a0dd[i] =  2*a2m[i-1] + 6*a3m[i-1]*dxm
     811             :     // a0dd[i] =  2*a2m[i-0] + 6*a3m[i-0]*dxp    
     812             :     //
     813             :     //
     814           0 :     matrix(offsKnot, iknot41+2)= 2.;
     815           0 :     matrix(offsKnot, iknot4 +2)=-2.;
     816             : 
     817           0 :     matrix(offsKnot, iknot41+3)= 6.*dxm;
     818           0 :     matrix(offsKnot, iknot4 +3)=-6.*dxp;
     819             : 
     820           0 :     matrix(iknot41+2, offsKnot)=2.;
     821           0 :     matrix(iknot41+3, offsKnot)=6.*dxm;
     822             : 
     823           0 :     matrix(iknot4+2, offsKnot)=-2.;
     824           0 :     matrix(iknot4+3, offsKnot)=-6.*dxp;
     825           0 :   }
     826             :  
     827             : // sparse matrix to do fit
     828             :   
     829           0 :   TMatrixDSparse smatrix(matrix);
     830           0 :   TDecompSparse svd(smatrix,0);
     831           0 :   Bool_t ok;
     832           0 :   const TVectorD results = svd.Solve(values,ok);
     833             : 
     834           0 :   for (Int_t iknot = 0; iknot<nknots-1; iknot++){
     835             : 
     836           0 :     Double_t dxm  =  -(fX[iknot+1]-fX[iknot])*0.5;
     837             : 
     838           0 :     fY0[iknot] = results(4*iknot)+ results(4*iknot+1)*dxm+results(4*iknot+2)*dxm*dxm+
     839           0 :       results(4*iknot+3)*dxm*dxm*dxm;
     840             : 
     841           0 :     fY1[iknot] = results(4*iknot+1)+2.*results(4*iknot+2)*dxm+
     842           0 :       3*results(4*iknot+3)*dxm*dxm;
     843             :   }
     844             :   Int_t   iknot2= nknots-1;
     845             :   Int_t   iknot = nknots-2;
     846           0 :   Double_t dxm   =  (fX[iknot2]-fX[iknot2-1])*0.5;
     847             : 
     848           0 :   fY0[iknot2] = results(4*iknot)+ results(4*iknot+1)*dxm+results(4*iknot+2)*dxm*dxm+
     849           0 :     results(4*iknot+3)*dxm*dxm*dxm;
     850             : 
     851           0 :   fY1[iknot2] = results(4*iknot+1)+2.*results(4*iknot+2)*dxm+
     852           0 :       3*results(4*iknot+3)*dxm*dxm;
     853             : 
     854           0 :   delete  pmatrix;
     855           0 :   delete  pvalues;
     856             : 
     857           0 : }
     858             : 
     859             : 
     860             : 
     861             : 
     862             : 
     863             : void AliSplineFit::MakeKnots0(TGraph * graph, Double_t maxdelta, Int_t minpoints){
     864             :   //
     865             :   // make knots  - restriction max distance and minimum points
     866             :   //
     867             : 
     868           0 :   Int_t npoints  = graph->GetN();
     869           0 :   Double_t *xknots = new Double_t[npoints]; 
     870           0 :   for (Int_t ip=0;ip<npoints;ip++) xknots[ip]=0;
     871             :   //
     872             :   Int_t nknots =0;
     873             :   Int_t ipoints =0;
     874             :   //
     875             :   // generate knots
     876             :   //
     877           0 :   for (Int_t ip=0;ip<npoints;ip++){
     878           0 :     if (graph->GetX()[ip]-xknots[nknots-1]>maxdelta && ipoints>minpoints){
     879           0 :       xknots[nknots] = graph->GetX()[ip];
     880             :       ipoints=1;
     881           0 :       nknots++;
     882           0 :     }
     883           0 :     ipoints++;
     884             :   }
     885           0 :   if (npoints-ipoints>minpoints){
     886           0 :     xknots[nknots] = graph->GetX()[npoints-1];
     887           0 :     nknots++;
     888           0 :   }else{
     889           0 :     xknots[nknots-1] = graph->GetX()[npoints-1];
     890             :   }
     891             : 
     892           0 :   fN = nknots;
     893           0 :   fX = new Double_t[nknots];
     894           0 :   fY0 = new Double_t[nknots];
     895           0 :   fY1 = new Double_t[nknots];
     896           0 :   fChi2I= new Double_t[nknots];
     897           0 :   for (Int_t i=0; i<nknots; i++) fX[i]= xknots[i];  
     898           0 :   delete [] xknots;
     899           0 : }
     900             : 
     901             : 
     902             : 
     903             : 
     904             : void AliSplineFit::MakeSmooth(TGraph * graph, Float_t ratio, Option_t * type){
     905             :   //
     906             :   // Interface to GraphSmooth
     907             :   //
     908             : 
     909           0 :   TGraphSmooth smooth;
     910           0 :   Int_t    npoints2 = TMath::Nint(graph->GetN()*ratio);  
     911           0 :   TGraph * graphT0 = smooth.SmoothKern(graph,type,ratio);
     912           0 :   if (!graphT0) return;
     913           0 :   TGraph  graphT1(npoints2);
     914           0 :   for (Int_t ipoint=0; ipoint<npoints2; ipoint++){
     915           0 :     Int_t pointS = TMath::Nint(ipoint/ratio);
     916           0 :     if (ipoint==npoints2-1) pointS=graph->GetN()-1;
     917           0 :     graphT1.SetPoint(ipoint, graphT0->GetX()[pointS] , graphT0->GetY()[pointS]);
     918             :   }  
     919           0 :   TSpline3 spline2("spline", &graphT1);
     920           0 :   Update(&spline2, npoints2);
     921           0 : }
     922             : 
     923             : 
     924             : void AliSplineFit::Update(TSpline3 *spline, Int_t nknots){
     925             :   //
     926             :   //
     927             :   //
     928             : 
     929           0 :   fN = nknots;
     930           0 :   fX = new Double_t[nknots];
     931           0 :   fY0 = new Double_t[nknots];
     932           0 :   fY1 = new Double_t[nknots];
     933           0 :   Double_t d0, d1;
     934           0 :   fChi2I= 0;
     935           0 :   for (Int_t i=0; i<nknots; i++) {
     936           0 :     spline->GetCoeff(i,fX[i],fY0[i], fY1[i],d0,d1);
     937             :   }
     938           0 : }
     939             : 
     940             : 
     941             : 
     942             : 
     943             : void AliSplineFit::Test(Int_t npoints, Int_t ntracks, Float_t snoise){  
     944             :   //
     945             :   // test function
     946             :   //
     947             : 
     948           0 :   AliSplineFit fit;
     949           0 :   AliSplineFit fitS;
     950             :   TGraph * graph0=0;
     951             :   TGraph * graph1=0;
     952             :   
     953           0 :   TTreeSRedirector *pcstream = new TTreeSRedirector("TestSmooth.root");
     954           0 :   for (Int_t i=0; i<ntracks; i++){
     955           0 :     graph0 = AliSplineFit::GenerGraph(npoints,0.05,0,0,1,0);  
     956           0 :     graph1 = AliSplineFit::GenerNoise(graph0,snoise);  
     957           0 :     fit.InitKnots(graph1, 10,10, 0.00);
     958           0 :     TGraph *d0 = fit.MakeDiff(graph0);
     959           0 :     TGraph *g0 = fit.MakeGraph(0,1,1000,0);
     960           0 :     fit.SplineFit(2);
     961           0 :     TH1F * h2 = fit.MakeDiffHisto(graph0);
     962           0 :     TGraph *d2 = fit.MakeDiff(graph0);
     963           0 :     TGraph *g2 = fit.MakeGraph(0,1,1000,0);
     964           0 :     fit.SplineFit(1);
     965           0 :     TH1F * h1 = fit.MakeDiffHisto(graph0);
     966           0 :     TGraph *d1 = fit.MakeDiff(graph0);
     967           0 :     TGraph *g1 = fit.MakeGraph(0,1,1000,0);
     968             : 
     969           0 :     Float_t ratio = Float_t(fit.fN)/Float_t(npoints);
     970           0 :     fitS.MakeSmooth(graph1,ratio,"box");
     971           0 :     TGraph *dS = fitS.MakeDiff(graph0);
     972           0 :     TGraph *gS = fit.MakeGraph(0,1,1000,0);
     973             : 
     974           0 :     TH1F * hS = fitS.MakeDiffHisto(graph0);
     975           0 :     Double_t mean2  = h2->GetMean();
     976           0 :     Double_t sigma2 = h2->GetRMS();
     977           0 :     Double_t mean1  = h1->GetMean();
     978           0 :     Double_t sigma1 = h1->GetRMS();
     979           0 :     Double_t meanS  = hS->GetMean();
     980           0 :     Double_t sigmaS = hS->GetRMS();
     981           0 :     char fname[100];
     982           0 :     if (fit.fN<20){
     983           0 :       snprintf(fname,100,"pol%d",fit.fN);
     984             :     }else{
     985           0 :       snprintf(fname,100,"pol%d",19);
     986             :     }
     987           0 :     TF1 fpol("fpol",fname);
     988           0 :     graph1->Fit(&fpol);
     989           0 :     TGraph dpol(*graph1);
     990           0 :     TGraph gpol(*graph1);
     991           0 :     for (Int_t ipoint=0; ipoint<graph1->GetN(); ipoint++){
     992           0 :       dpol.GetY()[ipoint]= graph0->GetY()[ipoint]-
     993           0 :         fpol.Eval(graph0->GetX()[ipoint]);
     994           0 :       gpol.GetY()[ipoint]= fpol.Eval(graph0->GetX()[ipoint]);
     995             :     }
     996           0 :     (*pcstream)<<"Test"<<
     997           0 :       "Event="<<i<<
     998           0 :       "Graph0.="<<graph0<<
     999           0 :       "Graph1.="<<graph1<<
    1000           0 :       "G0.="<<g0<<
    1001           0 :       "G1.="<<g1<<
    1002           0 :       "G2.="<<g2<<
    1003           0 :       "GS.="<<gS<<
    1004           0 :       "GP.="<<&gpol<<
    1005           0 :       "D0.="<<d0<<
    1006           0 :       "D1.="<<d1<<
    1007           0 :       "D2.="<<d2<<
    1008           0 :       "DS.="<<dS<<
    1009           0 :       "DP.="<<&dpol<<
    1010           0 :       "Npoints="<<fit.fN<<
    1011           0 :       "Mean1="<<mean1<<
    1012           0 :       "Mean2="<<mean2<<
    1013           0 :       "MeanS="<<meanS<<
    1014           0 :       "Sigma1="<<sigma1<<
    1015           0 :       "Sigma2="<<sigma2<<
    1016           0 :       "SigmaS="<<sigmaS<<
    1017             :       "\n";
    1018             :     
    1019           0 :     delete graph0;
    1020           0 :     delete graph1;
    1021           0 :     delete g1;
    1022           0 :     delete g2;
    1023           0 :     delete gS;
    1024           0 :     delete h1;
    1025           0 :     delete h2;
    1026           0 :     delete hS;
    1027           0 :   }
    1028           0 :   delete pcstream;
    1029           0 : }
    1030             : 
    1031             : void AliSplineFit::Cleanup(){
    1032             :  //
    1033             :  // deletes extra information to reduce amount of information stored on the data
    1034             :  // base
    1035             :     
    1036             :  //    delete fGraph;  fGraph=0;   // Don't delete fGraph -- input parameter 
    1037           0 :      delete fParams; fParams=0;
    1038           0 :      delete fCovars; fCovars=0;
    1039           0 :      delete [] fIndex; fIndex=0;
    1040           0 :      delete [] fChi2I; fChi2I=0;
    1041           0 : }
    1042             : 
    1043             : 
    1044             : void AliSplineFit::CopyGraph() {
    1045             :   //
    1046             :   // enter graph points directly to fit parameters 
    1047             :   // (to bee used when too few points are available)
    1048             :   //
    1049           0 :   fN = fGraph->GetN();   
    1050           0 :   fX = new Double_t[fN];
    1051           0 :   fY0 = new Double_t[fN];
    1052           0 :   fY1 = new Double_t[fN];
    1053           0 :   for (Int_t i=0; i<fN; i++ ) {
    1054           0 :     fX[i]  = fGraph->GetX()[i];
    1055           0 :     fY0[i] = fGraph->GetY()[i];     
    1056           0 :     fY1[i] = 0;
    1057             :   }
    1058           0 : }

Generated by: LCOV version 1.11