]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ITS/AliITSstatistics2.cxx
Fixes for not filled histograms and calculation of Dijet binning
[u/mrichter/AliRoot.git] / ITS / AliITSstatistics2.cxx
index edc692e75aa9b5b8563f7db2f200100b017b95f2..13d9869548109bb24ad5120f399f2464f0bb0c72 100644 (file)
@@ -1,16 +1,35 @@
+/**************************************************************************
+ * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
 //////////////////////////////////////////////////////////////////////////
-//  Alice ITS class to help keep statistical information                //
+//  Alice ITS class to help keep statistical information. Can also be   //
+// used to fit data to lines and other 2 dimentional sytistical         //
+// operations.                                                          //
 //                                                                      //
 // version: 0.0.0 Draft.                                                //
 // Date: April 18 1999                                                  //
 // By: Bjorn S. Nilsen                                                  //
+// Updated: 1.0.0, Date: September 6 2007, By: Bjorn S. Nilsen          //
 //                                                                      //
 //////////////////////////////////////////////////////////////////////////
-#include <stdio.h>
-#include <math.h>
-#include "TMath.h"
-#include "AliITSstatistics2.h"
-#include "Riostream.h"
+#include <stdio.h>     //  ios::fmtflags fmt used in PrintAscii
+#include "Riostream.h" // IO functions.
+#include "TMath.h"     // TMath::Sqrt() function used.
+#include "AliITSstatistics2.h" // Also defined TObject {base class}
 
 ClassImp(AliITSstatistics2)
 
@@ -19,10 +38,13 @@ AliITSstatistics2::AliITSstatistics2() :
 TObject(), // Base Class
 fN(-1),    // number of enetries -1 => Uninitilized
 fOrder(0), // maximum moment of distributions (^n)
-fX(0),    //[fOrder] array of sums of x^n
-fYx(0),   //[fOrder] array of sums of (xy)^n
-fY(0),    //[fOrder] array of sums of y^n
-fW(0){    //[fOrder] array of sums of w^n (weights)
+fX(0),     //[fOrder] array of sums of x^n
+fYx(0),    //[fOrder] array of sums of (xy)^n
+fY(0),     //[fOrder] array of sums of y^n
+fW(0)      //[fOrder] array of sums of w^n (weights)
+//,fDig(5)   // The number of significant digits to keep
+//,fOver(0)  //! In case of numerical precistion problems
+{
     // default constructor
     // Inputs:
     //   none.
@@ -41,8 +63,10 @@ fOrder(order), // maximum moment of distributions (^n)
 fX(new Double_t[order]),    //[fOrder] array of sums of x^n
 fYx(new Double_t[order]),   //[fOrder] array of sums of (xy)^n
 fY(new Double_t[order]),    //[fOrder] array of sums of y^n
-fW(new Double_t[order]){    //[fOrder] array of sums of w^n (weights)
-    // constructor to maximum moment/order order
+fW(new Double_t[order])     //[fOrder] array of sums of w^n (weights)
+//,fDig(5)   // The number of significant digits to keep
+//,fOver(0)                   //! In case of numeerical precistion problems
+{   // constructor to maximum moment/order order
     // Inputs:
     //   Int_t order   The maximum moment of distributions {for example x^n}
     Int_t i;
@@ -70,6 +94,8 @@ AliITSstatistics2::~AliITSstatistics2(){
     if(fY!=0)  delete[] fY;
     if(fYx!=0) delete[] fYx;
     if(fW!=0)  delete[] fW;
+    // if(fOver!=0) delete fOver; fOver=0;
+    // fDig=0;
     fX  = 0;
     fY  = 0;
     fYx = 0;
@@ -98,6 +124,9 @@ AliITSstatistics2& AliITSstatistics2::operator=(AliITSstatistics2 &source){
         this->fY[i] = source.fY[i];
         this->fW[i] = source.fW[i];
     } // end for i
+    // this->fDig = source.fDig;
+    // if(fOver!=0) this->fOver = new AliITSstatistics2(*(source.fOver));
+    // else fOver=0;
     return *this;
 }
 //_______________________________________________________________
@@ -108,7 +137,10 @@ fOrder(source.GetOrder()),// maximum moment of distributions (^n)
 fX(new Double_t[source.GetOrder()]),//[fOrder] array of sums of x^n
 fYx(new Double_t[source.GetOrder()]),//[fOrder] array of sums of (xy)^n
 fY(new Double_t[source.GetOrder()]),//[fOrder] array of sums of y^n
-fW(new Double_t[source.GetOrder()]){//[fOrder] array of sums of w^n (weights)
+fW(new Double_t[source.GetOrder()]) //[fOrder] array of sums of w^n (weights)
+//,fDig(source.fDig)                  // The number of significant digits to keep
+//,fOver(0)             //! In case of numerical precistion problems
+{
     // Copy constructor
     // Inputs:
     //   AliITSstatistics2 & source the source of this copy
@@ -117,13 +149,14 @@ fW(new Double_t[source.GetOrder()]){//[fOrder] array of sums of w^n (weights)
     // Return:
     //   A copy of the source.
 
-    if(this==&source) return;
     for(Int_t i=0;i<source.fOrder;i++){
         this->fX[i] = source.fX[i];
         this->fYx[i] = source.fYx[i];
         this->fY[i] = source.fY[i];
         this->fW[i] = source.fW[i];
     } // end for i
+    //if(fOver!=0) this->fOver = new AliITSstatistics2(*(source.fOver));
+    return;
 }
 //______________________________________________________________________
 void AliITSstatistics2::Reset(Int_t order){
@@ -160,8 +193,27 @@ void AliITSstatistics2::Reset(Int_t order){
     fY =  new Double_t[fOrder];
     fYx = new Double_t[fOrder];
     fW =  new Double_t[fOrder];
+    //if(fOver!=0) delete fOver; fOver = 0;
     return;
 }
+//----------------------------------------------------------------------
+/*
+void SetSignificantDigits(Int_t d){
+    // Sets the number of significant digits. If adding a value to
+    // one of this class' arrays looses significance at the fDig
+    // level, a new instance of this class is created to keep
+    // signigicance at or better than fDig level. if fDig<0, then
+    // this feature it disabled and significance can be lost.
+    // Inputs:
+    //    Int_t  d   The new significance level
+    // Outputs:
+    //    none.
+    // Return:
+    //    none.
+
+    fDig = d;
+}
+ */
 //______________________________________________________________________
 void AliITSstatistics2::AddValue(Double_t y,Double_t x,Double_t w=1.0){
     // add next x,y pair to statistics
@@ -178,8 +230,18 @@ void AliITSstatistics2::AddValue(Double_t y,Double_t x,Double_t w=1.0){
     const Double_t kBig=1.0e+38;
 
     if(y>kBig || x>kBig || w>kBig) return;
+    /*  If problem with precision, then creat/fill fOver
+       as a partical sum to be added to "this" later.
+       if(????fDig){
+       if(fOver==0){
+           fOver = new AliITSstatistics2(fOrder);
+       } // end if fOver==0
+       fOver->AddValue(y,x,w);
+       return;
+       } // end if(???)
+     */
     fN++;
-    for(i=0;i<fOrder;i++){
+    for(i=0;i<GetOrder();i++){
        xs  *= x;
        ys  *= y;
        yxs *= x*y;
@@ -201,11 +263,11 @@ Double_t AliITSstatistics2::GetXNth(Int_t order)const{
     //   The value sum{x^n}.
     Double_t s;
 
-    if(fW[0]!=0.0&&order<=fOrder) s = fX[order-1]/fW[0];
+    if(GetWN(1)!=0.0 && order<=GetOrder()) s = GetXN(order)/GetWN(1);
     else {
        s = 0.0;
        Error("GetXNth","error fOrder=%d fN=%d fW[0]=%f\n",
-              fOrder,fN,fW[0]);
+              GetOrder(),GetN(),GetWN(1));
     } // end else
     return s;
 }
@@ -220,11 +282,11 @@ Double_t AliITSstatistics2::GetYNth(Int_t order)const{
     //  The value sum{y^n}
     Double_t s;
 
-    if(fW[0]!=0.0&&order<=fOrder) s = fY[order-1]/fW[0];
+    if(GetWN(1)!=0.0&&order<=GetOrder()) s = GetYN(order)/GetWN(1);
     else {
        s = 0.0;
        Error("GetYNth","fOrder=%d fN=%d fW[0]=%f\n",
-              fOrder,fN,fW[0]);
+              GetOrder(),GetN(),GetWN(1));
     } // end else
     return s;
 }
@@ -239,11 +301,11 @@ Double_t AliITSstatistics2::GetYXNth(Int_t order)const{
     //  The value sum{(xy)^n}
     Double_t s;
 
-    if(fW[0]!=0.0&&order<=fOrder) s = fYx[order-1]/fW[0];
+    if(GetWN(1)!=0.0&&order<=GetOrder()) s = GetYXN(order)/GetWN(1);
     else {
        s = 0.0;
        Error("GetYXNth","fOrder=%d fN=%d fW[0]=%f\n",
-              fOrder,fN,fW[0]);
+             GetOrder(),GetN(),GetWN(1));
     } // end else
     return s;
 }
@@ -260,8 +322,8 @@ Double_t AliITSstatistics2::GetRMSX()const{
 
     x  = GetMeanX(); // first order
     x2 = GetXNth(2); // second order
-    w  = fW[0];     // first order - 1.
-    ww = fW[1];     // second order - 1.
+    w  = GetWN(1);   // first order
+    ww = GetWN(2);   // second order
 
     if(w*w==ww) return (-1.0);
     s = (x2-x*x)*w*w/(w*w-ww);
@@ -280,8 +342,8 @@ Double_t AliITSstatistics2::GetRMSY()const{
 
     x  = GetMeanY(); // first order
     x2 = GetYNth(2); // second order
-    w  = fW[0];     // first order - 1.
-    ww = fW[1];     // second order - 1.
+    w  = GetWN(1);   // first order
+    ww = GetWN(2);   // second order
 
     if(w*w==ww) return (-1.0);
     s = (x2-x*x)*w*w/(w*w-ww);
@@ -300,8 +362,8 @@ Double_t AliITSstatistics2::GetRMSYX()const{
 
     x  = GetMeanYX(); // first order
     x2 = GetYXNth(2); // second order
-    w  = fW[0];     // first order - 1.
-    ww = fW[1];     // second order - 1.
+    w  = GetWN(1);   // first order
+    ww = GetWN(2);     // second order
 
     if(w*w==ww) return (-1.0);
     s = (x2-x*x)*w*w/(w*w-ww);
@@ -320,8 +382,8 @@ Double_t AliITSstatistics2::GetErrorMeanY()const{
     Double_t rms,w,ww,s;
 
     rms = GetRMSY();
-    w   = fW[0];
-    ww  = fW[1];
+    w   = GetWN(1);
+    ww  = GetWN(2);
     s   = rms*rms*ww/(w*w);
     return TMath::Sqrt(s);
 }
@@ -338,8 +400,8 @@ Double_t AliITSstatistics2::GetErrorMeanX()const{
     Double_t rms,w,ww,s;
 
     rms = GetRMSX();
-    w   = fW[0];
-    ww  = fW[1];
+    w   = GetWN(1);
+    ww  = GetWN(2);
     s   = rms*rms*ww/(w*w);
     return TMath::Sqrt(s);
 }
@@ -356,8 +418,8 @@ Double_t AliITSstatistics2::GetErrorMeanYX()const{
     Double_t rms,w,ww,s;
 
     rms = GetRMSYX();
-    w   = fW[0];
-    ww  = fW[1];
+    w   = GetWN(1);
+    ww  = GetWN(2);
     s   = rms*rms*ww/(w*w);
     return TMath::Sqrt(s);
 }
@@ -374,11 +436,11 @@ Double_t AliITSstatistics2::GetErrorRMSY()const{
     //  The error on the rms
     Double_t x,x2,x3,x4,w,ww,m2,m4,n,s;
 
-    if(fW[0]!=(Double_t)fN||GetN()<4) return (-1.);
+    if(GetWN(1)!=(Double_t)GetN()||GetN()<4) return (-1.);
     x  = GetMeanY(); // first order
     x2 = GetYNth(2); // second order
-    w  = fW[0];     // first order - 1.
-    ww = fW[1];     // second order - 1.
+    w  = GetWN(1);   // first order
+    ww = GetWN(2);   // second order
     if(w*w==ww) return (-1.0);
     s = (x2-x*x)*w*w/(w*w-ww);
 
@@ -404,11 +466,11 @@ Double_t AliITSstatistics2::GetErrorRMSX()const{
     //  The error on the rms
     Double_t x,x2,x3,x4,w,ww,m2,m4,n,s;
 
-    if(fW[0]!=(Double_t)fN||GetN()<4) return (-1.);
+    if(GetWN(1)!=(Double_t)GetN()||GetN()<4) return (-1.);
     x  = GetMeanX(); // first order
     x2 = GetXNth(2); // second order
-    w  = fW[0];     // first order - 1.
-    ww = fW[1];     // second order - 1.
+    w  = GetWN(1);   // first order
+    ww = GetWN(2);   // second order
     if(w*w==ww) return (-1.0);
     s = (x2-x*x)*w*w/(w*w-ww);
 
@@ -434,11 +496,11 @@ Double_t AliITSstatistics2::GetErrorRMSYX()const{
     //  The error on the rms
     Double_t x,x2,x3,x4,w,ww,m2,m4,n,s;
 
-    if(fW[0]!=(Double_t)fN||GetN()<4) return (-1.);
+    if(GetWN(1)!=(Double_t)GetN()||GetN()<4) return (-1.);
     x  = GetMeanYX(); // first order
     x2 = GetYXNth(2); // second order
-    w  = fW[0];     // first order - 1.
-    ww = fW[1];     // second order - 1.
+    w  = GetWN(1);    // first order
+    ww = GetWN(2);    // second order
     if(w*w==ww) return (-1.0);
     s = (x2-x*x)*w*w/(w*w-ww);
 
@@ -452,20 +514,38 @@ Double_t AliITSstatistics2::GetErrorRMSYX()const{
     return TMath::Sqrt(s);
 }
 //_______________________________________________________________________
-Double_t AliITSstatistics2::FitToLine(Double_t &a,Double_t &b)const{
-    // fit to y = ax+b returns Chi squared or -1.0 if an error
+Double_t AliITSstatistics2::FitToLine(Double_t &a,Double_t &ea,
+                                     Double_t &b,Double_t &eb)const{
+    // fit to y = ax+b returns Chi squared or -1.0 if an error.
+    // The fitting is done by analitically minimizing 
+    /*
+      Begin_Latex
+      \begin{equation*}
+      \Chi^{2}=\sum_{i} (y_{i}-a x_{i} -b)^{2} w_{i}
+      \end{equation*}
+      Where if the weight used in 
+      AliITSstatistics2::AddValue(Double_t y,Double_t x,Double_t w=1.0)
+      is of the form
+      \begin{equation*}
+      w_{i}=\frac{1}{\delta y^{2}}.
+      \end{equation*}
+      Then we get the typicall chi square minimization.
+      End_Latex
+     */
     // Inputs:
     //   none.
     // Outputs:
     //   Double_t  a   The slope parameter
+    //   Double_t  ea  Error on fitted slope parameter
     //   Double_t  b   The intercept paramter
+    //   Double_t  eb  Error on fitted intercept parameter
     // Return:
     //  The Chi^2 of the fit
     Double_t c,d,e,f,g,h;
 
-    a = b = 0.0;
-    if(fOrder<2 || fN<3){
-        Error("FitToLine","Order=%d<2 or N=%d<3",fOrder,fN);
+    a = ea = b = eb = 0.0;
+    if(GetOrder()<2 || GetN()<3){
+        Error("FitToLine","Order=%d<2 or N=%d<3",GetOrder(),GetN());
         return -1.0;
     } // end if
     c = GetWN(1);
@@ -476,19 +556,60 @@ Double_t AliITSstatistics2::FitToLine(Double_t &a,Double_t &b)const{
     h = c*g-e*e;
     b = d*g-f*e;
     a = c*f-d*e;
-    if(h!=0.0){
-       a = a/h;
-       b = b/h;
-    }else{
+    if(h==0.0){
        Error("FitToLine","vertical line: fOrder=%d fN=%d "
-              "GetWN(1)=%g X GetXN(2)=%g - GetXN(1)=%g^2 = 0",fOrder,fN,c,g,e);
+              "GetWN(1)=%g X GetXN(2)=%g - GetXN(1)=%g^2 = 0",
+             GetOrder(),GetN(),c,g,e);
        return -1.0;
     } // end if h
-    return GetChiSquared(a,b);
+    a = a/h;
+    b = b/h;
+    // Now for the errors.
+    ea = c*c*g+(a*a-1.0)*c*e*e;
+    ea = ea/(h*h);
+    if(ea<0.0){
+      Error("FitToLine","ea=%g is less than zero",ea);
+      return -2.0;
+    } // end if ea<0
+    ea = TMath::Sqrt(ea);
+    eb = c*g*g-2.0*d*e*g-2.0*(1.0-b)*c*e*e*g+2.0*(1.0-b)*d*e*e*e+
+          GetYN(2)*e*e+(1.0-b)*(1.0-b)*c*e*e*e*e;
+    eb = eb/(h*h);
+    if(eb<0.0){
+      Error("FitToLine","eb=%g is less than zero",eb);
+      return -2.0;
+    } // end if ea<0
+    eb = TMath::Sqrt(eb);
+    c = GetChiSquared(a,b);
+    if(c<=0.0){ // must be a numerical precision problem.
+    } // end if
+    return c;
 }
 //_______________________________________________________________________
 Double_t AliITSstatistics2::GetChiSquared(Double_t a,Double_t b)const{
-    //  returns Chi^2 value of data to line y=ax+b with given a,b
+    //  Returns Chi^2 value of data to line y=ax+b with given a,b.
+    /*
+      Begin_Latex
+      Note: The Chi^2 value is computed from the expression
+      \begin{equation*}
+      \chi^{2}=\sum_{i}{w_{i}y_{i}^{2}} + b^{2}\sum_{i}{w_{i}}
+                -2b\sum_{i}{w_{i}y_{i}}-2a\sum_{i}{w_{i}y_{i}x_{i}}
+                +2ab\sum_{i}{w_{i}x_{i}}
+                +a^{2}\sum_{i}w_{i}x_{i}^{2}
+      \end{equation*}
+      and not form the expression
+      \begin{equation*}
+      \chi^{2}= \sum_{i}{(y_{i}-ax_{i}-b)^{2}w_{i}.
+      \end{equation*}
+      Consiquently, there are occations when numerically these
+      two expressions will not agree. In fact the form code here
+      can give negitive values. This happens when the numerical
+      significance is larger than the $\chi^{2}$ value. This should
+      not be confused the the error values which can be returned.
+      At present there is no check on the numberical significance
+      of any results.
+      End_Latex
+     */
     // Inputs:
     //   Double_t  a   The slope parameter
     //   Double_t  b   The intercept paramter
@@ -500,7 +621,7 @@ Double_t AliITSstatistics2::GetChiSquared(Double_t a,Double_t b)const{
 
     c2 = GetYN(2)+b*b*GetWN(1)+
         a*a*GetXN(2)-2.0*b*GetYN(1)-2.0*a*GetYXN(1)+2.0*b*a*GetXN(1);
-    c2 /= (Double_t)fN - 2.0;
+    c2 /= (Double_t)GetN() - 2.0;
     return c2;
 }
 //______________________________________________________________________
@@ -515,7 +636,7 @@ void AliITSstatistics2::PrintAscii(ostream *os)const{
     Int_t i;
 #if defined __GNUC__
 #if __GNUC__ > 2
-    ios::fmtflags fmt;
+    ios::fmtflags fmt;  // Standard IO format object, required for output.
 #else
     Int_t fmt;
 #endif
@@ -527,12 +648,15 @@ void AliITSstatistics2::PrintAscii(ostream *os)const{
 #endif
 #endif
 
-    *os << fN <<" "<< fOrder;
+    *os << fN <<" "<< GetOrder();
     fmt = os->setf(ios::scientific); // set scientific floating point output
-    for(i=0;i<fOrder;i++) *os <<" "<< fX[i];
-    for(i=0;i<fOrder;i++) *os <<" "<< fYx[i];
-    for(i=0;i<fOrder;i++) *os <<" "<< fY[i];
-    for(i=0;i<fOrder;i++) *os <<" "<< fW[i];
+    for(i=0;i<GetOrder();i++) *os <<" "<< GetXN(i+1);
+    for(i=0;i<GetOrder();i++) *os <<" "<< GetYXN(i+1);
+    for(i=0;i<GetOrder();i++) *os <<" "<< GetYN(i+1);
+    for(i=0;i<GetOrder();i++) *os <<" "<< GetWN(i+1);
+    //if(fOver!=0) { *os << " " << fDig;
+    //*os << " " << fOver;
+    // } else *os << " " << fDig;
     os->flags(fmt); // reset back to old Formating.
     return;
 }
@@ -554,6 +678,9 @@ void AliITSstatistics2::ReadAscii(istream *is){
     for(i=0;i<fOrder;i++) *is >> fYx[i];
     for(i=0;i<fOrder;i++) *is >> fY[i];
     for(i=0;i<fOrder;i++) *is >> fW[i];
+    //*is >> fDig;
+    // if(fDig>0) *is >> fOver;
+    // else fDig *= -1;
 }
 //______________________________________________________________________
 ostream &operator<<(ostream &os,const AliITSstatistics2 &s){
@@ -583,3 +710,4 @@ istream &operator>>(istream &is,AliITSstatistics2 &s){
     s.ReadAscii(&is);
     return is;
 }
+