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