Install macros
[u/mrichter/AliRoot.git] / TPC / Calib / AliTPCFitPad.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 //                                                                        
18 //       === Class for fitting properties specific to pad regions ===
19 //
20 //    For each pad size region a separate TLinearFitter object is assigned.
21 //    Commonly used functions such as getting the center of a pad size
22 //    region or visualization functions are provided. Also, choosing the
23 //    segment and pad type is made easy due to different methods that
24 //    can calculate these informations from other coordinates.
25 //
26 ////////////////////////////////////////////////////////////////////////////
27
28 #include "AliTPCFitPad.h"
29
30 ClassImp(AliTPCFitPad)
31
32
33
34
35 AliTPCFitPad::AliTPCFitPad(Int_t ndim, const char* formula, Option_t* opt) :
36    AliTPCCalPadRegion("", ""),
37    fNdim(ndim),
38    fFormula(formula),
39    fOpt(opt)
40 {
41    //
42    // Constructor. The parameters are used for generating new TLinearFitter
43    // objects and are described in its documentation.
44    //
45 }
46
47 AliTPCFitPad& AliTPCFitPad::operator=(const AliTPCFitPad& rhs)
48 {
49   //
50   // Assignment operator.
51   //
52   
53   if (this != &rhs) {
54     AliTPCCalPadRegion::operator=(rhs);
55     fNdim = rhs.fNdim;
56     fFormula = rhs.fFormula;
57     fOpt = rhs.fOpt;
58   }
59   return *this;
60 }
61
62 AliTPCFitPad::AliTPCFitPad(const AliTPCFitPad& rhs):
63   AliTPCCalPadRegion(rhs),
64   fNdim(rhs.fNdim),
65   fFormula(rhs.fFormula),
66   fOpt(rhs.fOpt)
67
68 {
69   //
70   // Copy constructor
71   //
72 }
73
74 AliTPCFitPad::~AliTPCFitPad() {
75    //
76    // Destructor.
77    //
78
79    Delete();
80 }
81
82
83
84 void AliTPCFitPad::Add(AliTPCFitPad* fit) {
85    //
86    // Adds another AliTPCFitPad object to this object. The formula should be the
87    // same, though it won't be checked!
88    //
89
90    for (UInt_t iSegment = 0; iSegment < GetNSegments(); iSegment++) {
91       for (UInt_t iPadType = 0; iPadType < GetNPadTypes(); iPadType++) {
92          TLinearFitter* fitter = fit->GetFitterSimple(iSegment, iPadType);
93          // parameter workaround == kTRUE because it is not possible to add another
94          // TLinearFitter object to a "virgin" one. Thus a dummy data point is added
95          // and cleared again immediately afterwards. Due to a broken TLinearFitter
96          // copy constructor this is a necessary workaround.
97          if (fitter) {
98             cout << "TLinearFitter::Add called for " << iSegment << ", " << iPadType << endl;
99             GetFitter(iSegment, iPadType, kTRUE)->Add(fitter);
100          }
101       }
102    }
103 }
104
105 TLinearFitter* AliTPCFitPad::GetFitterSimple(UInt_t segment, UInt_t padType) {
106    //
107    // This method returns the fitter corresponding to segment and pad type.
108    // In contrast to GetFitter() no fitter will be created, if it does
109    // not exist, but a null pointer is returned.
110    //
111    
112    return (TLinearFitter*)(GetObject(segment, padType));
113 }
114
115 TLinearFitter* AliTPCFitPad::GetFitter(UInt_t segment, UInt_t padType, Bool_t workaround) {
116    //
117    // This method returns the fitter corresponding
118    // to segment and pad type.
119    // If the fitter doesn't exist yet, it will be created on the fly
120    // according to the parameters passed to the constructor.
121    //
122    // The workaround parameter should always be kFALSE. (It is only used by the Add method.)
123    //
124
125    TLinearFitter* fitter = GetFitterSimple(segment, padType);
126    if (fitter == 0 || fitter->GetNumberTotalParameters() !=fNdim) {
127      fitter = new TLinearFitter(fNdim, fFormula, fOpt);
128      fitter->StoreData(kFALSE);
129      SetObject(fitter, segment, padType);
130      fitter = (TLinearFitter*)(GetObject(segment, padType));
131      if (workaround) {
132        Double_t x[1000];
133        for (Int_t i = 0; i < fNdim; i++) x[i] = 3.141592;
134        fitter->AddPoint(x, 31.41592);
135        fitter->ClearPoints();
136        //cout << "workaround called for " << segment << ", " << padType << endl;
137      }
138    }
139    return fitter;
140 }
141
142 Int_t AliTPCFitPad::Evaluate(Bool_t robust, Double_t frac) {
143    //
144    // Evaluates all fitters. Returns 0 if successful, 1 in case of an error.
145    // If the robust option is set to kTRUE a robust fit is performed with frac as
146    // the minimal fraction of good points (see TLinearFitter::EvalRobust for details).
147    // Beware: Robust fitting is much slower!
148    //
149
150    Int_t returnCode = 0;
151    for (UInt_t iSegment = 0; iSegment < GetNSegments(); iSegment++) {
152       for (UInt_t iPadType = 0; iPadType < GetNPadTypes(); iPadType++) {
153          if (TLinearFitter* fitter = GetFitterSimple(iSegment, iPadType)) {
154             Int_t status = robust ? fitter->EvalRobust(frac) : fitter->Eval();
155             if (status != 0) {
156                returnCode = 1;
157                Error("Evaluate", "Error in evaluation of fitter in segment %d, pad region %d", iSegment, iPadType);
158             }
159          }
160       }
161    }
162    return returnCode;
163 }