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