1 | |
2 | |
3 | |
4 | |
5 | #include "DFDCSegment_factory.h" |
6 | #include "DANA/DApplication.h" |
7 | |
8 | #include <math.h> |
9 | |
10 | #define HALF_CELL0.5 0.5 |
11 | #define MAX_DEFLECTION0.15 0.15 |
12 | #define EPS1e-8 1e-8 |
13 | #define KILL_RADIUS5.0 5.0 |
14 | #define MATCH_RADIUS5.0 5.0 |
15 | #define ADJACENT_MATCH_RADIUS2.0 2.0 |
16 | #define SIGN_CHANGE_CHISQ_CUT10.0 10.0 |
17 | #define BEAM_VARIANCE0.01 0.01 // cm^2 |
18 | #define USED_IN_SEGMENT0x8 0x8 |
19 | #define CORRECTED0x10 0x10 |
20 | #define MAX_ITER10 10 |
21 | #define MIN_TANL2.0 2.0 |
22 | #define ONE_THIRD0.33333333333333333 0.33333333333333333 |
23 | #define SQRT31.73205080756887719 1.73205080756887719 |
24 | |
25 | |
26 | |
27 | inline double fdc_y_variance(double alpha,double x){ |
28 | return 0.00060+0.0064*tan(alpha)*tan(alpha)+0.0004*fabs(x); |
29 | } |
30 | |
31 | bool DFDCSegment_package_cmp(const DFDCPseudo* a, const DFDCPseudo* b) { |
32 | return a->wire->layer>b->wire->layer; |
33 | } |
34 | |
35 | DFDCSegment_factory::DFDCSegment_factory() { |
36 | _log = new JStreamLog(std::cout, "FDCSEGMENT >>"); |
37 | *_log << "File initialized." << endMsg; |
38 | } |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | DFDCSegment_factory::~DFDCSegment_factory() { |
46 | delete _log; |
47 | } |
48 | |
49 | |
50 | |
51 | |
52 | jerror_t DFDCSegment_factory::brun(JEventLoop* eventLoop, int runnumber) { |
53 | DApplication* dapp=dynamic_cast<DApplication*>(eventLoop->GetJApplication()); |
54 | |
55 | const DGeometry *geom = dapp->GetDGeometry(runnumber); |
56 | |
57 | geom->GetTargetZ(TARGET_Z); |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | return NOERROR; |
65 | } |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | jerror_t DFDCSegment_factory::evnt(JEventLoop* eventLoop, int eventNo) { |
72 | myeventno=eventNo; |
73 | |
74 | vector<const DFDCPseudo*>pseudopoints; |
75 | eventLoop->Get(pseudopoints); |
76 | |
77 | |
78 | |
79 | if (pseudopoints.size()>=3){ |
80 | |
81 | vector<const DFDCPseudo*>package[4]; |
82 | for (vector<const DFDCPseudo*>::const_iterator i=pseudopoints.begin(); |
83 | i!=pseudopoints.end();i++){ |
84 | package[((*i)->wire->layer-1)/6].push_back(*i); |
85 | } |
86 | |
87 | |
88 | for (int j=0;j<4;j++){ |
89 | std::sort(package[j].begin(),package[j].end(),DFDCSegment_package_cmp); |
90 | |
91 | |
92 | if (package[j].size()>2) FindSegments(package[j]); |
93 | } |
94 | } |
95 | |
96 | return NOERROR; |
97 | } |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | jerror_t DFDCSegment_factory::RiemannLineFit(vector<const DFDCPseudo *>points, |
104 | DMatrix &CR,vector<xyz_t>&XYZ){ |
105 | unsigned int n=points.size()+1; |
106 | vector<int>bad(n); |
107 | |
108 | for (unsigned int m=0;m<n-1;m++){ |
109 | double r2=points[m]->xy.Mod2(); |
110 | double denom= N[0]*N[0]+N[1]*N[1]; |
111 | double numer=dist_to_origin+r2*N[2]; |
112 | double ratio=numer/denom; |
113 | |
114 | DVector2 xy_int0(-N[0]*ratio,-N[1]*ratio); |
115 | double temp=denom*r2-numer*numer; |
116 | if (temp<0){ |
117 | bad[m]=1; |
118 | XYZ[m].xy=xy_int0; |
119 | continue; |
120 | } |
121 | temp=sqrt(temp)/denom; |
122 | |
123 | |
124 | DVector2 delta(N[1]*temp,-N[0]*temp); |
125 | DVector2 xy1=xy_int0+delta; |
126 | DVector2 xy2=xy_int0-delta; |
127 | double diff1=(xy1-points[m]->xy).Mod2(); |
128 | double diff2=(xy2-points[m]->xy).Mod2(); |
129 | if (diff1>diff2){ |
130 | XYZ[m].xy=xy2; |
131 | } |
132 | else{ |
133 | XYZ[m].xy=xy1; |
134 | } |
135 | } |
136 | |
137 | XYZ[n-1].xy.Set(0.,0.); |
138 | |
139 | |
140 | |
141 | unsigned int start=0; |
142 | for (unsigned int i=0;i<bad.size();i++){ |
143 | if (!bad[i]){ |
144 | start=i; |
145 | break; |
146 | } |
147 | } |
148 | if ((start!=0 && ref_plane==0) || (start!=2&&ref_plane==2)) ref_plane=start; |
149 | |
150 | |
151 | double sumv=0.,sumx=0.; |
152 | double sumy=0.,sumxx=0.,sumxy=0.; |
153 | double sperp=0.,sperp_old=0.,ratio,Delta; |
154 | double z=0,zlast=0; |
155 | double two_rc=2.*rc; |
156 | DVector2 oldxy=XYZ[start].xy; |
157 | for (unsigned int k=start;k<n;k++){ |
158 | zlast=z; |
159 | sperp_old=sperp; |
160 | if (!bad[k]){ |
161 | DVector2 diffxy=XYZ[k].xy-oldxy; |
162 | ratio=diffxy.Mod()/(two_rc); |
163 | |
164 | sperp=sperp_old+(ratio>1?two_rc*(M_PI_21.57079632679489661923):two_rc*asin(ratio)); |
165 | |
166 | z=XYZ[k].z; |
167 | |
168 | |
169 | double inv_var=1./CR(k,k); |
170 | sumv+=inv_var; |
171 | sumy+=sperp*inv_var; |
172 | sumx+=z*inv_var; |
173 | sumxx+=z*z*inv_var; |
174 | sumxy+=sperp*z*inv_var; |
175 | |
176 | |
177 | |
178 | |
179 | oldxy=XYZ[k].xy; |
180 | } |
181 | } |
182 | |
183 | Delta=sumv*sumxx-sumx*sumx; |
184 | double denom=sumv*sumxy-sumy*sumx; |
185 | if (fabs(Delta)>EPS1e-8 && fabs(denom)>EPS1e-8){ |
186 | |
187 | tanl=-Delta/denom; |
188 | |
189 | |
190 | var_tanl=sumv/Delta*(tanl*tanl*tanl*tanl); |
191 | |
192 | |
193 | sperp-=sperp_old; |
194 | zvertex=zlast-tanl*sperp; |
195 | } |
196 | else{ |
197 | |
198 | zvertex=TARGET_Z; |
199 | if (sperp<EPS1e-8){ |
200 | |
201 | |
202 | |
203 | tanl=57.3; |
204 | } |
205 | else tanl=(zlast-zvertex)/sperp; |
206 | var_tanl=100.; |
207 | |
208 | |
209 | } |
210 | |
211 | return NOERROR; |
212 | } |
213 | |
214 | |
215 | |
216 | |
217 | jerror_t DFDCSegment_factory::UpdatePositionsAndCovariance(unsigned int n, |
218 | double r1sq,vector<xyz_t>&XYZ,DMatrix &CRPhi,DMatrix &CR){ |
219 | double delta_x=XYZ[ref_plane].xy.X()-xc; |
220 | double delta_y=XYZ[ref_plane].xy.Y()-yc; |
221 | double r1=sqrt(r1sq); |
222 | double denom=delta_x*delta_x+delta_y*delta_y; |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | DMatrix C(n,n); |
229 | DMatrix S(n,n); |
230 | |
231 | |
232 | Phi1=atan2(delta_y,delta_x); |
233 | double z1=XYZ[ref_plane].z; |
234 | double y1=XYZ[ref_plane].xy.X(); |
235 | double x1=XYZ[ref_plane].xy.Y(); |
236 | double var_R1=CR(ref_plane,ref_plane); |
237 | for (unsigned int k=0;k<n;k++){ |
238 | double sperp=charge*(XYZ[k].z-z1)/tanl; |
239 | double phi_s=Phi1+sperp/rc; |
240 | double sinp=sin(phi_s); |
241 | double cosp=cos(phi_s); |
242 | XYZ[k].xy.Set(xc+rc*cosp,yc+rc*sinp); |
243 | |
244 | |
245 | |
246 | |
247 | |
248 | double Phi=XYZ[k].xy.Phi(); |
249 | double sinPhi=sin(Phi); |
250 | double cosPhi=cos(Phi); |
251 | double dRPhi_dx=Phi*cosPhi-sinPhi; |
252 | double dRPhi_dy=Phi*sinPhi+cosPhi; |
253 | |
254 | double rc_sinphi_over_denom=rc*sinp/denom; |
255 | |
256 | |
257 | double dx_dx1=rc_sinphi_over_denom*delta_y; |
258 | double dx_dy1=-rc_sinphi_over_denom*delta_x; |
259 | double dx_dtanl=sinp*sperp/tanl; |
260 | |
261 | double rc_cosphi_over_denom=rc*cosp/denom; |
262 | |
263 | |
264 | double dy_dx1=-rc_cosphi_over_denom*delta_y; |
265 | double dy_dy1=rc_cosphi_over_denom*delta_x; |
266 | double dy_dtanl=-cosp*sperp/tanl; |
267 | |
268 | double dRPhi_dx1=dRPhi_dx*dx_dx1+dRPhi_dy*dy_dx1; |
269 | double dRPhi_dy1=dRPhi_dx*dx_dy1+dRPhi_dy*dy_dy1; |
270 | double dRPhi_dtanl=dRPhi_dx*dx_dtanl+dRPhi_dy*dy_dtanl; |
271 | |
272 | double dR_dx1=cosPhi*dx_dx1+sinPhi*dy_dx1; |
273 | double dR_dy1=cosPhi*dx_dy1+sinPhi*dy_dy1; |
274 | double dR_dtanl=cosPhi*dx_dtanl+sinPhi*dy_dtanl; |
275 | |
276 | double cdist=dist_to_origin+r1sq*N[2]; |
277 | double n2=N[0]*N[0]+N[1]*N[1]; |
278 | |
279 | double ydenom=y1*n2+N[1]*cdist; |
280 | double dy1_dr1=-r1*(2.*N[1]*N[2]*y1+2.*N[2]*cdist-N[0]*N[0])/ydenom; |
281 | double var_y1=dy1_dr1*dy1_dr1*var_R1; |
282 | |
283 | double xdenom=x1*n2+N[0]*cdist; |
284 | double dx1_dr1=-r1*(2.*N[0]*N[2]*x1+2.*N[2]*cdist-N[1]*N[1])/xdenom; |
285 | double var_x1=dx1_dr1*dx1_dr1*var_R1; |
286 | |
287 | CRPhi(k,k)=dRPhi_dx1*dRPhi_dx1*var_x1+dRPhi_dy1*dRPhi_dy1*var_y1 |
288 | +dRPhi_dtanl*dRPhi_dtanl*var_tanl; |
289 | CR(k,k)=dR_dx1*dR_dx1*var_x1+dR_dy1*dR_dy1*var_y1 |
290 | +dR_dtanl*dR_dtanl*var_tanl; |
291 | |
292 | |
293 | double stemp=XYZ[k].xy.Mod()/(4.*rc); |
294 | double ctemp=1.-stemp*stemp; |
295 | if (ctemp>0){ |
296 | S(k,k)=stemp; |
297 | C(k,k)=sqrt(ctemp); |
298 | } |
299 | else{ |
300 | S(k,k)=0.; |
301 | C(k,k)=1.; |
302 | } |
303 | } |
304 | |
305 | |
306 | CRPhi=C*CRPhi*C+S*CR*S; |
307 | |
308 | return NOERROR; |
309 | } |
310 | |
311 | |
312 | |
313 | |
314 | |
315 | |
316 | jerror_t DFDCSegment_factory::RiemannCircleFit(vector<const DFDCPseudo *>points, |
317 | DMatrix &CRPhi){ |
318 | unsigned int n=points.size()+1; |
319 | DMatrix X(n,3); |
320 | DMatrix Xavg(1,3); |
321 | DMatrix A(3,3); |
322 | |
323 | DMatrix OnesT(1,n); |
324 | double W_sum=0.; |
325 | DMatrix W(n,n); |
326 | |
327 | |
328 | |
329 | |
330 | |
331 | |
332 | |
333 | |
334 | |
335 | |
336 | for (unsigned int i=0;i<n-1;i++){ |
337 | X(i,0)=points[i]->xy.X(); |
338 | X(i,1)=points[i]->xy.Y(); |
339 | X(i,2)=points[i]->xy.Mod2(); |
340 | OnesT(0,i)=1.; |
341 | W(i,i)=1./CRPhi(i,i); |
342 | W_sum+=W(i,i); |
343 | } |
344 | unsigned int last_index=n-1; |
345 | OnesT(0,last_index)=1.; |
346 | W(last_index,last_index)=1./CRPhi(last_index,last_index); |
347 | W_sum+=W(last_index,last_index); |
348 | var_avg=1./W_sum; |
349 | Xavg=var_avg*(OnesT*(W*X)); |
350 | |
351 | xavg[0]=Xavg(0,0); |
352 | xavg[1]=Xavg(0,1); |
353 | xavg[2]=Xavg(0,2); |
354 | |
355 | A=DMatrix(DMatrix::kTransposed,X)*(W*X) |
356 | -W_sum*(DMatrix(DMatrix::kTransposed,Xavg)*Xavg); |
357 | if(!A.IsValid())return UNRECOVERABLE_ERROR; |
358 | |
359 | |
360 | |
361 | |
362 | double B2=-(A(0,0)+A(1,1)+A(2,2)); |
363 | double B1=A(0,0)*A(1,1)-A(1,0)*A(0,1)+A(0,0)*A(2,2)-A(2,0)*A(0,2) |
364 | +A(1,1)*A(2,2)-A(2,1)*A(1,2); |
365 | double B0=-A.Determinant(); |
366 | if(B0==0 || !finite(B0))return UNRECOVERABLE_ERROR; |
367 | |
368 | |
369 | |
370 | |
371 | |
372 | |
373 | |
374 | |
375 | |
376 | |
377 | |
378 | |
379 | |
380 | |
381 | |
382 | double Q=(3.*B1-B2*B2)/9.e4; |
383 | double R=(9.*B2*B1-27.*B0-2.*B2*B2*B2)/54.e6; |
384 | double Q1=Q*Q*Q+R*R; |
385 | if (Q1<0) Q1=sqrt(-Q1); |
386 | else{ |
387 | return VALUE_OUT_OF_RANGE; |
388 | } |
389 | |
390 | |
391 | |
392 | |
393 | |
394 | |
395 | double temp=100.*sqrt(cbrt(R*R+Q1*Q1)); |
396 | double theta1=ONE_THIRD0.33333333333333333*atan2(Q1,R); |
397 | double sum_over_2=temp*cos(theta1); |
398 | double diff_over_2=-temp*sin(theta1); |
399 | |
400 | double lambda_min=-ONE_THIRD0.33333333333333333*B2-sum_over_2+SQRT31.73205080756887719*diff_over_2; |
401 | |
402 | |
403 | N[0]=1.; |
404 | N[1]=(A(1,0)*A(0,2)-(A(0,0)-lambda_min)*A(1,2)) |
405 | /(A(0,1)*A(2,1)-(A(1,1)-lambda_min)*A(0,2)); |
406 | N[2]=(A(2,0)*(A(1,1)-lambda_min)-A(1,0)*A(2,1)) |
407 | /(A(1,2)*A(2,1)-(A(2,2)-lambda_min)*(A(1,1)-lambda_min)); |
408 | |
409 | |
410 | double denom=sqrt(N[0]*N[0]+N[1]*N[1]+N[2]*N[2]); |
411 | for (int i=0;i<3;i++){ |
412 | N[i]/=denom; |
413 | } |
414 | |
415 | |
416 | dist_to_origin=-(N[0]*Xavg(0,0)+N[1]*Xavg(0,1)+N[2]*Xavg(0,2)); |
417 | |
418 | |
419 | double two_N2=2.*N[2]; |
420 | xc=-N[0]/two_N2; |
421 | yc=-N[1]/two_N2; |
422 | rc=sqrt(1.-N[2]*N[2]-4.*dist_to_origin*N[2])/fabs(two_N2); |
423 | |
424 | return NOERROR; |
425 | } |
426 | |
427 | |
428 | |
429 | |
430 | |
431 | jerror_t DFDCSegment_factory::RiemannHelicalFit(vector<const DFDCPseudo*>points, |
432 | DMatrix &CR,vector<xyz_t>&XYZ){ |
433 | double Phi; |
434 | unsigned int num_points=points.size()+1; |
435 | DMatrix CRPhi(num_points,num_points); |
436 | |
437 | |
438 | XYZ[num_points-1].z=TARGET_Z; |
439 | for (unsigned int m=0;m<points.size();m++){ |
440 | XYZ[m].z=points[m]->wire->origin.z(); |
441 | |
442 | |
443 | Phi=points[m]->xy.Phi(); |
444 | double cosPhi=cos(Phi); |
445 | double sinPhi=sin(Phi); |
446 | double Phi_cosPhi=Phi*cosPhi; |
447 | double Phi_sinPhi=Phi*sinPhi; |
448 | double Phi_cosPhi_minus_sinPhi=Phi_cosPhi-sinPhi; |
449 | double Phi_sinPhi_plus_cosPhi=Phi_sinPhi+cosPhi; |
450 | CRPhi(m,m) |
451 | =Phi_cosPhi_minus_sinPhi*Phi_cosPhi_minus_sinPhi*points[m]->covxx |
452 | +Phi_sinPhi_plus_cosPhi*Phi_sinPhi_plus_cosPhi*points[m]->covyy |
453 | +2.*Phi_sinPhi_plus_cosPhi*Phi_cosPhi_minus_sinPhi*points[m]->covxy; |
454 | |
455 | CR(m,m)=cosPhi*cosPhi*points[m]->covxx |
456 | +sinPhi*sinPhi*points[m]->covyy |
457 | +2.*sinPhi*cosPhi*points[m]->covxy; |
458 | } |
459 | CR(points.size(),points.size())=BEAM_VARIANCE0.01; |
460 | CRPhi(points.size(),points.size())=BEAM_VARIANCE0.01; |
461 | |
462 | |
463 | jerror_t error=NOERROR; |
464 | |
465 | error=RiemannCircleFit(points,CRPhi); |
466 | if (error!=NOERROR) return error; |
467 | |
468 | |
469 | |
470 | error=RiemannLineFit(points,CR,XYZ); |
471 | if (error!=NOERROR) return error; |
472 | |
473 | |
474 | charge=GetCharge(points.size(),XYZ,CR,CRPhi); |
475 | |
476 | double r1sq=XYZ[ref_plane].xy.Mod2(); |
477 | UpdatePositionsAndCovariance(num_points,r1sq,XYZ,CRPhi,CR); |
478 | |
479 | |
480 | error=RiemannCircleFit(points,CRPhi); |
481 | if (error!=NOERROR) return error; |
482 | |
483 | |
484 | error=RiemannLineFit(points,CR,XYZ); |
485 | if (error!=NOERROR) return error; |
486 | |
487 | |
488 | charge=GetCharge(points.size(),XYZ,CR,CRPhi); |
489 | |
490 | r1sq=XYZ[ref_plane].xy.Mod2(); |
491 | UpdatePositionsAndCovariance(num_points,r1sq,XYZ,CRPhi,CR); |
492 | |
493 | |
494 | error=RiemannCircleFit(points,CRPhi); |
495 | if (error!=NOERROR) return error; |
496 | |
497 | |
498 | error=RiemannLineFit(points,CR,XYZ); |
499 | if (error!=NOERROR) return error; |
500 | |
501 | |
502 | charge=GetCharge(points.size(),XYZ,CR,CRPhi); |
503 | |
504 | |
505 | ref_plane=0; |
506 | r1sq=XYZ[ref_plane].xy.Mod2(); |
507 | UpdatePositionsAndCovariance(num_points,r1sq,XYZ,CRPhi,CR); |
508 | |
509 | |
510 | chisq=0.; |
511 | for (unsigned int m=0;m<points.size();m++){ |
512 | double sperp=charge*(XYZ[m].z-XYZ[ref_plane].z)/tanl; |
513 | double phi_s=Phi1+sperp/rc; |
514 | DVector2 XY(xc+rc*cos(phi_s),yc+rc*sin(phi_s)); |
515 | chisq+=(XY-points[m]->xy).Mod2()/CR(m,m); |
516 | } |
517 | return NOERROR; |
518 | } |
519 | |
520 | |
521 | |
522 | |
523 | |
524 | |
525 | jerror_t DFDCSegment_factory::FindSegments(vector<const DFDCPseudo*>points){ |
526 | |
527 | used.clear(); |
528 | |
529 | |
530 | |
531 | double old_z=points[0]->wire->origin.z(); |
532 | vector<unsigned int>x_list; |
533 | x_list.push_back(0); |
534 | for (unsigned int i=0;i<points.size();i++){ |
| 1 | Loop condition is false. Execution continues on line 541 | |
|
535 | used.push_back(false); |
536 | if (points[i]->wire->origin.z()!=old_z){ |
537 | x_list.push_back(i); |
538 | } |
539 | old_z=points[i]->wire->origin.z(); |
540 | } |
541 | x_list.push_back(points.size()); |
542 | |
543 | unsigned int start=0; |
544 | |
545 | while (start<x_list.size()-1){ |
| 2 | | Loop condition is true. Entering loop body | |
|
546 | int num_used=0; |
547 | |
548 | for (unsigned int i=0;i<points.size();i++){ |
| 3 | | Loop condition is false. Execution continues on line 552 | |
|
549 | if(used[i]==true) num_used++; |
550 | } |
551 | |
552 | if (points.size()-num_used<3) break; |
| |
553 | |
554 | |
555 | for (unsigned int i=x_list[start];i<x_list[start+1];i++){ |
| 5 | | Dereference of null pointer |
|
556 | if (used[i]==false){ |
557 | used[i]=true; |
558 | chisq=1.e8; |
559 | |
560 | |
561 | tanl=D=z0=phi0=Phi1=xc=yc=rc=0.; |
562 | charge=1.; |
563 | |
564 | |
565 | DVector2 XY=points[i]->xy; |
566 | |
567 | |
568 | vector<const DFDCPseudo*>neighbors; |
569 | neighbors.push_back(points[i]); |
570 | unsigned int match=0; |
571 | double delta,delta_min=1000.; |
572 | for (unsigned int k=0;k<x_list.size()-1;k++){ |
573 | delta_min=1000.; |
574 | match=0; |
575 | for (unsigned int m=x_list[k];m<x_list[k+1];m++){ |
576 | delta=(XY-points[m]->xy).Mod(); |
577 | if (delta<delta_min && delta<MATCH_RADIUS5.0){ |
578 | delta_min=delta; |
579 | match=m; |
580 | } |
581 | } |
582 | if (match!=0 |
583 | && used[match]==false |
584 | ){ |
585 | XY=points[match]->xy; |
586 | used[match]=true; |
587 | neighbors.push_back(points[match]); |
588 | } |
589 | } |
590 | unsigned int num_neighbors=neighbors.size(); |
591 | |
592 | |
593 | |
594 | if (num_neighbors<3) continue; |
595 | |
596 | bool do_sort=false; |
597 | |
598 | for (unsigned int k=0;k<points.size();k++){ |
599 | if (!used[k]){ |
600 | for (unsigned int j=0;j<num_neighbors;j++){ |
601 | delta=(points[k]->xy-neighbors[j]->xy).Mod(); |
602 | |
603 | if (delta<ADJACENT_MATCH_RADIUS2.0 && |
604 | abs(neighbors[j]->wire->wire-points[k]->wire->wire)<=1 |
605 | && neighbors[j]->wire->origin.z()==points[k]->wire->origin.z()){ |
606 | used[k]=true; |
607 | neighbors.push_back(points[k]); |
608 | do_sort=true; |
609 | } |
610 | } |
611 | } |
612 | } |
613 | |
614 | if (do_sort) |
615 | std::sort(neighbors.begin(),neighbors.end(),DFDCSegment_package_cmp); |
616 | |
617 | |
618 | unsigned int num_points_on_segment=neighbors.size()+1; |
619 | vector<xyz_t>XYZ(num_points_on_segment); |
620 | DMatrix CR(num_points_on_segment,num_points_on_segment); |
621 | |
622 | |
623 | |
624 | |
625 | ref_plane=2; |
626 | |
627 | |
628 | jerror_t error=RiemannHelicalFit(neighbors,CR,XYZ); |
629 | |
630 | if (error==NOERROR){ |
631 | |
632 | phi0=atan2(-xc,yc); |
633 | if (charge<0) phi0+=M_PI3.14159265358979323846; |
634 | |
635 | |
636 | D=-charge*rc-xc/sin(phi0); |
637 | |
638 | |
639 | DFDCSegment *segment = new DFDCSegment; |
640 | |
641 | |
642 | segment->q=charge; |
643 | segment->phi0=phi0; |
644 | segment->D=D; |
645 | segment->tanl=tanl; |
646 | segment->z_vertex=zvertex; |
647 | |
648 | segment->hits=neighbors; |
649 | segment->xc=xc; |
650 | segment->yc=yc; |
651 | segment->rc=rc; |
652 | segment->Phi1=Phi1; |
653 | segment->chisq=chisq; |
654 | |
655 | |
656 | |
657 | |
658 | _data.push_back(segment); |
659 | } |
660 | } |
661 | } |
662 | |
663 | while (start<x_list.size()-1){ |
664 | if (used[x_list[start]]==false) break; |
665 | start++; |
666 | } |
667 | } |
668 | |
669 | return NOERROR; |
670 | } |
671 | |
672 | |
673 | double DFDCSegment_factory::GetCharge(unsigned int n,vector<xyz_t>&XYZ, |
674 | DMatrix &CR, |
675 | DMatrix &CRPhi){ |
676 | double inv_var=0.; |
677 | double sumv=0.; |
678 | double sumy=0.; |
679 | double sumx=0.; |
680 | double sumxx=0.,sumxy=0,Delta; |
681 | double slope,r2; |
682 | double phi_old=XYZ[0].xy.Phi(); |
683 | for (unsigned int k=0;k<n;k++){ |
684 | double tempz=XYZ[k].z; |
685 | double phi_z=XYZ[k].xy.Phi(); |
686 | |
687 | if (fabs(phi_z-phi_old)>M_PI3.14159265358979323846){ |
688 | if (phi_old<0) phi_z-=2.*M_PI3.14159265358979323846; |
689 | else phi_z+=2.*M_PI3.14159265358979323846; |
690 | } |
691 | r2=XYZ[k].xy.Mod2(); |
692 | inv_var=r2/(CRPhi(k,k)+phi_z*phi_z*CR(k,k)); |
693 | sumv+=inv_var; |
694 | sumy+=phi_z*inv_var; |
695 | sumx+=tempz*inv_var; |
696 | sumxx+=tempz*tempz*inv_var; |
697 | sumxy+=phi_z*tempz*inv_var; |
698 | phi_old=phi_z; |
699 | } |
700 | Delta=sumv*sumxx-sumx*sumx; |
701 | slope=(sumv*sumxy-sumy*sumx)/Delta; |
702 | |
703 | |
704 | if (slope<0.) return -1.; |
705 | return 1.; |
706 | } |
707 | |
708 | |
709 | |
710 | |
711 | |
712 | |
713 | |
714 | |
715 | |
716 | |
717 | |
718 | |
719 | |
720 | |
721 | |
722 | |
723 | |
724 | |
725 | |
726 | |
727 | |
728 | |
729 | |
730 | |
731 | |
732 | |
733 | |
734 | |
735 | |
736 | |
737 | |
738 | |
739 | |
740 | |
741 | |
742 | |
743 | |
744 | |
745 | |
746 | |
747 | |
748 | |
749 | |
750 | |
751 | |
752 | |
753 | |
754 | |
755 | |
756 | |
757 | |
758 | |
759 | |
760 | |
761 | |
762 | |
763 | |
764 | |
765 | |
766 | |
767 | |
768 | |
769 | |
770 | |
771 | |
772 | |
773 | |
774 | |
775 | |
776 | |
777 | |
778 | |
779 | |
780 | |
781 | |
782 | |
783 | |
784 | |
785 | |
786 | |
787 | |
788 | |
789 | |
790 | |
791 | |
792 | |
793 | |
794 | |
795 | |
796 | |
797 | |
798 | |
799 | |
800 | |
801 | |
802 | |
803 | |
804 | |
805 | |
806 | |