BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
MucRecLineFit.cxx
Go to the documentation of this file.
1//$id$
2//
3//$log$
4
5/*
6 * 2003/12/24 Zhengyun You Peking University
7 *
8 * 2004/09/12 Zhengyun You Peking University
9 * transplanted to Gaudi framework
10 */
11
12using namespace std;
13
14#include "MucRecEvent/MucRecLineFit.h"
15#include "MucGeomSvc/MucGeoGeneral.h"
16#include <iostream>
17#include <math.h>
18
20 // Constructor.
21}
22
24 // Destructor.
25}
26
27/* --------------------------------------------------------------
28
29 utiLineFit - a least squares straight line fitting program
30
31 DESCRIPTION:
32 Performs weighted least squares fit to line (Y = A*X + B )
33 using linear regression.
34
35 INPUT ARGUMENTS:
36 X(N),Y(N),W(N) - Input values and weights (N=1,2,3...)
37 N - Number of pairs of data points,
38 X - Array of data points in X-axis,
39 Y - Array of data points in Y-axis,
40 W - Array of weights for data points,
41
42 OUTPUT ARGUMENTS:
43 B - Y intercept of best fitted straight line,
44 SIGB - Standard deviation of B,
45 A - Slope of fitted straight line,
46 SIGA - Standard deviation of A,
47 CHISQ - Chi-square
48 LSWLF - = 0 return without error
49 = -1 got some fitting problems
50
51 AUTHOR:
52 Jawluen Tang, Physics department, UT-Austin
53 J. T. Mitchell - adapted for PHENIX use. Converted to C.
54
55 USAGE:
56 utiLineFit(X,Y,W,N,&A,&B,&CHISQ,&SIGA,&SIGB)
57 The arrays must start counting at element 1.
58
59--------------------------------------------------------------- */
60
61// add (part,seg,orient) to choose better coordinator.
62
63int MucRecLineFit::LineFit( float x[], float y[], float w[], int part, int seg, int orient,
64 int n, float* a, float* b, float* chisq, float* siga,
65 float* sigb ) {
66 if ( part > 2 || part < 0 )
67 {
68 cout << "BAD part id from MucRecLineFit" << endl;
69 return -1;
70 }
71
72 int status = -1;
73 float c, d, sigc, sigd;
74
75 if ( part != 1 )
76 {
77 for ( int i = 0; i < n; i++ )
78 {
79 float gap0z = ( MucGeoGeneral::Instance()->GetGap( part, seg, 0 )->GetCenter() ).z();
80 // cout<<"in MucRecLineFit change x from "<<x[i]<<" to ";
81 x[i] -= gap0z;
82 // cout<<x[i]<<endl;
83 }
84 status = LineFit( x, y, w, n, a, b, chisq, siga, sigb );
85 // cout<<"in MucRecLineFit sigb = "<<*sigb<<endl;
86 }
87 else
88 {
89 if ( orient == 0 )
90 { // need change x and y because x has error now.
91
92 for ( int i = 0; i < n; i++ )
93 {
94 float gap0r = ( MucGeoGeneral::Instance()->GetGap( part, 0, 0 )->GetCenter() ).x();
95 y[i] -= gap0r;
96 }
97 status = LineFit( y, x, w, n, &c, &d, chisq, &sigc, &sigd );
98 // need to recalculate a,b,siga,sigb now
99 // y=ax+b; x=cy+d
100 // a = 1/c; b = -d/c
101 // siga^2 = a^2/c^2 * sigc^2
102 // sigb^2 = b^2/c^2 * sigc^2 + b^2/d^2 * sigd^2;
103
104 *a = 1 / c;
105 *b = -1 * d / c;
106 *siga = 1 / c / c * sigc;
107 //*sigb = sqrt(fabs(1/c/c*sigd*sigd + d*d/c/c/c/c*sigc*sigc));
108 *sigb = sigd; ////////////
109 }
110 else
111 { // barrel... seg0,4 need not change; seg2,6 change x<->y; other seg need more complicate
112 // operation!
113 if ( seg == 0 || seg == 4 )
114 {
115 float gap0x = ( MucGeoGeneral::Instance()->GetGap( part, seg, 0 )->GetCenter() ).x();
116 for ( int i = 0; i < n; i++ ) { x[i] -= gap0x; }
117 status = LineFit( x, y, w, n, a, b, chisq, siga, sigb );
118 }
119 else if ( seg == 2 || seg == 6 )
120 {
121 float gap0y = ( MucGeoGeneral::Instance()->GetGap( part, seg, 0 )->GetCenter() ).y();
122 for ( int i = 0; i < n; i++ ) { y[i] -= gap0y; }
123 status = LineFit( y, x, w, n, &c, &d, chisq, &sigc, &sigd );
124 // need to recalculate a,b,siga,sigb now
125 *a = 1 / c;
126 *b = -1 * d / c;
127 *siga = 1 / c / c * sigc;
128 //*sigb = sqrt(fabs(1/c/c*sigd*sigd + d*d/c/c/c/c*sigc*sigc));
129 *sigb = sigd;
130 }
131 else
132 {
133 for ( int i = 0; i < n; i++ )
134 {
135 float temp = ( y[i] + x[i] ) / sqrt( 2.0 );
136 y[i] = ( y[i] - x[i] ) / sqrt( 2.0 );
137 x[i] = temp;
138 }
139
140 if ( seg == 1 || seg == 5 )
141 {
142 for ( int i = 0; i < n; i++ )
143 {
144 float gap0x =
145 ( MucGeoGeneral::Instance()->GetGap( part, seg - 1, 0 )->GetCenter() ).x();
146 x[i] -= gap0x;
147 }
148 status = LineFit( x, y, w, n, a, b, chisq, siga, sigb );
149 }
150 else if ( seg == 3 || seg == 7 )
151 {
152 for ( int i = 0; i < n; i++ )
153 {
154 float gap0y =
155 ( MucGeoGeneral::Instance()->GetGap( part, seg - 1, 0 )->GetCenter() ).y();
156 y[i] -= gap0y;
157 }
158 status = LineFit( y, x, w, n, a, b, chisq, siga, sigb );
159 }
160 }
161 }
162 }
163
164 return status;
165}
166
167int MucRecLineFit::LineFit( float x[], float y[], float w[], int n, float* a, float* b,
168 float* chisq, float* siga, float* sigb )
169
170{
171 double sum, sx, sy, sxx, sxy, syy, det;
172 float chi;
173
174 /* The variable "i" is declared 8 bytes long to avoid triggering an
175 apparent alignment bug in optimized code produced by gcc-2.95.3.
176 The bug doesn't seem to be present in gcc-3.2. */
177 long i;
178
179 chi = 99999999.0;
180
181 /* N must be >= 2 for this guy to work */
182 if ( n < 2 )
183 {
184 cout << "utiLineFit-W: Too few points for line fit \n" << endl;
185 return -1;
186 }
187
188 /* Initialization */
189 sum = 0.0;
190 sx = 0.0;
191 sy = 0.0;
192 sxx = 0.0;
193 sxy = 0.0;
194 syy = 0.0;
195
196 /* Find sum , sumx ,sumy, sumxx, sumxy */
197 for ( i = 0; i < n; i++ )
198 {
199 // cout<<"x: "<<x[i]<<" y: "<<y[i]<<" w: "<<w[i]<<endl;
200 sum = sum + w[i];
201 sx = sx + w[i] * x[i];
202 sy = sy + w[i] * y[i];
203 sxx = sxx + w[i] * x[i] * x[i];
204 sxy = sxy + w[i] * x[i] * y[i];
205 syy = syy + w[i] * y[i] * y[i];
206 }
207
208 det = sum * sxx - sx * sx;
209 if ( fabs( det ) < 1.0e-20 )
210 {
211 *a = 1.0e20;
212 *b = x[0];
213 *chisq = 0.0;
214 *siga = 0.0;
215 *sigb = 0.0;
216
217 return 0;
218 }
219
220 /* compute the best fitted parameters A,B */
221 *a = ( sum * sxy - sx * sy ) / det;
222 *b = ( sy * sxx - sxy * sx ) / det;
223
224 // cout<<"a: "<<*a<<" b: "<<*b<<endl;
225 /* calculate chi-square */
226 chi = 0.0;
227 for ( i = 0; i < n; i++ )
228 {
229 chi =
230 chi + ( w[i] ) * ( ( y[i] ) - *a * ( x[i] ) - *b ) * ( ( y[i] ) - *a * ( x[i] ) - *b );
231 }
232
233 *siga = sqrt( fabs( sum / det ) );
234 *sigb = sqrt( fabs( sxx / det ) );
235
236 *chisq = chi;
237 return 0;
238}
const Int_t n
Double_t x[10]
double w
HepPoint3D GetCenter() const
Get gap center position in global coordinate.
MucGeoGap * GetGap(const int part, const int seg, const int gap) const
Get a pointer to the gap identified by (part,seg,gap).
static MucGeoGeneral * Instance()
Get a pointer to the single instance of MucGeoGeneral.
MucRecLineFit()
Constructor.
~MucRecLineFit()
Destructor.
int LineFit(float x[], float y[], float w[], int n, float *a, float *b, float *chisq, float *siga, float *sigb)