BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
MucRec2DRoad.cxx
Go to the documentation of this file.
1//$id$
2//
3//$log$
4
5/*
6 * 2003/12/22 Zhengyun You Peking University
7 *
8 * 2005/02/24 Zhengyun You Peking University
9 * transplanted to Gaudi framework
10 */
11
12using namespace std;
13
14#include <CLHEP/Geometry/Point3D.h>
15#include <CLHEP/Vector/ThreeVector.h>
16#include <iostream>
17#include <vector>
18
19#include "Identifier/MucID.h"
20#include "MucGeomSvc/MucConstant.h"
21#include "MucRecEvent/MucRec2DRoad.h"
22#include "MucRecEvent/MucRecLineFit.h"
23#include "MucRecEvent/MucRecQuadFit.h"
24
25const double muckInfinity = 1e30;
26// Constructor.
27MucRec2DRoad::MucRec2DRoad( const int& part, const int& seg, const int& orient,
28 const float& xVertex, const float& yVertex, const float& zVertex,
29 const int& fittingMethod )
30 : m_VertexPos( xVertex, yVertex, zVertex )
31 , m_VertexSigma( 0.0, 0.0, 0.0 )
32 , m_Part( part )
33 , m_Seg( seg )
34 , m_Orient( orient )
35 , m_Chi2( 0.0 )
36 , m_DOF( 0 )
37 , m_MaxHitsPerGap( 0 )
38 , m_LastGap( 0 )
39 , m_TotalHits( 0 )
40 , m_FitOK( false )
41 , m_QuadFitOK( false )
42 , m_HitDistance( 5, float( muckInfinity ) )
43 , m_pHits( 0 )
44 , m_fittingMethod( fittingMethod ) {}
45
46// Assignment constructor.
48 // Assignment operator.
49 if ( this != &orig )
50 { // Watch out for self-assignment!
51 m_VertexPos = orig.m_VertexPos;
52 m_VertexSigma = orig.m_VertexSigma;
53 m_Index = orig.m_Index;
54 m_Part = orig.m_Part;
55 m_Seg = orig.m_Seg;
56 m_Orient = orig.m_Orient;
57 m_Chi2 = orig.m_Chi2;
58 m_DOF = orig.m_DOF;
59 m_FitOK = orig.m_FitOK;
60 m_MaxHitsPerGap = orig.m_MaxHitsPerGap;
61 m_LastGap = orig.m_LastGap;
62 m_TotalHits = orig.m_TotalHits;
63 m_HitDistance = orig.m_HitDistance;
64 m_pHits = orig.m_pHits;
65 m_fittingMethod = orig.m_fittingMethod;
66 }
67
68 return *this;
69}
70
71// Copy constructor.
73 : m_VertexPos( source.m_VertexPos )
74 , m_VertexSigma( source.m_VertexSigma )
75 , m_Index( source.m_Index )
76 , m_Part( source.m_Part )
77 , m_Seg( source.m_Seg )
78 , m_Orient( source.m_Orient )
79 , m_Chi2( source.m_Chi2 )
80 , m_DOF( source.m_DOF )
81 , m_MaxHitsPerGap( source.m_MaxHitsPerGap )
82 , m_LastGap( source.m_LastGap )
83 , m_TotalHits( source.m_TotalHits )
84 , m_FitOK( source.m_FitOK )
85 , m_HitDistance( source.m_HitDistance )
86 , m_pHits( source.m_pHits )
87 , m_fittingMethod( source.m_fittingMethod ) {}
88
89// Destructor.
91
92// Set the index for this road.
93void MucRec2DRoad::SetIndex( const int& index ) {
94 if ( index >= 0 ) m_Index = index;
95}
96
97// Attach the given hit this road.
98// Assume that this hit has been verified to be consistent with the road.
100 // cout << "MucRec2DRoad::AttachHit-I0 hit = " << hit << endl;
101 if ( !hit )
102 {
103 cout << "MucRec2DRoad::AttachHit-E1 null hit pointer!" << endl;
104 return;
105 }
106
107 int gap = hit->Gap();
108 if ( ( gap < 0 ) || ( gap >= (int)MucID::getGapMax() ) )
109 {
110 // The gap number of the hit is out of range.
111 cout << "MucRec2DRoad::AttachHit-W3 bad gap number = " << gap << endl;
112 return;
113 }
114
115 // Attach the hit to the road.
116 // bool hitExist = false;
117 for ( int i = 0; i < (int)m_pHits.size(); i++ )
118 {
119 if ( m_pHits[i] == hit ) return;
120 }
121 m_pHits.push_back( hit );
122 // cout << "before Count " << m_pHits.size() << endl;
123 // m_HitDistance[gap] = dX;
124
125 // Now recalculate the total number of hits and the max. number of
126 // hits per gap.
127 CountHits();
128 // cout << "after Count " << m_pHits.size() << endl;
129
130 // Redo the "simple" least-squares fit to the positions ...
131 float a, sa, b, sb, chi;
132 int n;
133 int status = SimpleFit( a, b, sa, sb, chi, n );
134 if ( status < 0 )
135 {
136 // cout << "MucRec2DRoad::AttachHit-E5 simple fit fail status = " << status << endl;
137 }
138
139 // cout << "Hit center = " << hit->GetCenterPos() << endl;
140 // cout << "After attach hit, slope = " << a << " intercept = " << b << endl;
141}
142
143// Attach the given hit this road.
144// Assume that this hit has been verified to be consistent with the road.
146 // cout << "MucRec2DRoad::AttachHit-I0 hit = " << hit << endl;
147 if ( !hit )
148 {
149 cout << "MucRec2DRoad::AttachHit-E1 null hit pointer!" << endl;
150 return;
151 }
152
153 int gap = hit->Gap();
154 if ( ( gap < 0 ) || ( gap >= (int)MucID::getGapMax() ) )
155 {
156 // The gap number of the hit is out of range.
157 cout << "MucRec2DRoad::AttachHit-W3 bad gap number = " << gap << endl;
158 return;
159 }
160
161 // Attach the hit to the road.
162 // bool hitExist = false;
163 for ( int i = 0; i < (int)m_pHits.size(); i++ )
164 {
165 if ( m_pHits[i] == hit ) return;
166 }
167 m_pHits.push_back( hit );
168 // cout << "before Count " << m_pHits.size() << endl;
169 // m_HitDistance[gap] = dX;
170
171 // Now recalculate the total number of hits and the max. number of
172 // hits per gap.
173 CountHits();
174 // cout << "after Count " << m_pHits.size() << endl;
175}
176
177// Max number of consecutive gaps allowed with no hits attached.
178// This parameter affects the calculation of the last gap.
179void MucRec2DRoad::SetMaxNSkippedGaps( const int& numGaps ) {
180 m_MaxNSkippedGaps = numGaps;
181 CountHits(); // recalculate the last gap and the hit counts.
182}
183
184// Calculate the best-fit straight line with "simple" weights.
185int MucRec2DRoad::SimpleFit( float& slope, float& intercept, float& sigmaSlope,
186 float& sigmaIntercept, float& chisq, int& ndof ) {
187 // hits in one track can not more than 100.
188 if ( m_pHits.size() > 100 )
189 {
190 cout << "MucRec2DRoad: too many hits in this track!" << endl;
191 return -1;
192 }
193 // Assign to temporary arrays to be used in fit.
194 float px[100];
195 float py[100];
196 float pw[100];
197 int npoints = 0;
198
199 vector<MucRecHit*>::const_iterator iHit;
200
201 float weight[100];
202
203 // for (int i = 0; i < m_pHits.size(); i++) {
204 // cout<<"info: "<<m_pHits[i]->Seg()<<" "<<m_pHits[i]->Gap()<<" "<<
205 // m_pHits[i]->Strip()<<endl;
206 // }
207 for ( int i = 0; i < m_pHits.size(); i++ )
208 {
209 weight[i] = 1;
210
211 for ( int j = 0; j < m_pHits.size(); j++ )
212 {
213
214 if ( j == i ) continue;
215 if ( m_pHits[i]->Part() == m_pHits[j]->Part() &&
216 m_pHits[i]->Seg() == m_pHits[j]->Seg() && m_pHits[i]->Gap() == m_pHits[j]->Gap() )
217 {
218 int deltaStrip = fabs( m_pHits[i]->Strip() - m_pHits[j]->Strip() );
219
220 // cout<<i<<" "<<m_pHits[i]->Seg()<<" "<<m_pHits[i]->Gap()<<"
221 // "<<m_pHits[i]->Strip()<<" - "<<m_pHits[j]->Strip()<<endl;
222 if ( deltaStrip == 0 ) { cout << "deltaStrip == 0 ? check it" << endl; }
223 else { weight[i] *= ( deltaStrip + 1 ) * ( deltaStrip + 1 ); }
224 }
225 }
226 }
227
228 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
229 {
230 if ( *iHit )
231 { // Check for a null pointer.
232
233 /*
234 float localx, localy, localz;
235 (*iHit)->GetStrip()->GetCenterPos(localx, localy, localz);
236 if ( m_Orient == 0) {
237 px[npoints] = localy;
238 py[npoints] = localz;
239 }
240 else {
241 px[npoints] = localx;
242 py[npoints] = localz;
243 }
244 npoints++;
245 }
246 }
247 */
248
249 Hep3Vector center = ( *iHit )->GetCenterPos();
250 Hep3Vector sigma = ( *iHit )->GetCenterSigma();
251 // Hep3Vector sigma(1.0, 1.0, 1.0);
252
253 if ( m_Part == 1 )
254 {
255 if ( m_Orient == 0 )
256 {
257 px[npoints] = center.z();
258 py[npoints] = sqrt( center.x() * center.x() + center.y() * center.y() );
259 if ( m_Seg == 2 )
260 py[npoints] = center.y(); // deal with seg2 seperately! because there is a hole
261 // here. 2006.11.9
262
263 pw[npoints] = 4.0 * 1.0 / ( sigma.y() * sigma.y() ) / weight[npoints];
264 }
265 else
266 {
267 px[npoints] = center.x();
268 py[npoints] = center.y();
269 pw[npoints] = 4.0 * 1.0 / ( sigma.x() * sigma.x() ) / weight[npoints];
270 }
271 }
272 else
273 {
274 if ( m_Orient == 0 )
275 {
276 px[npoints] = center.z();
277 py[npoints] = center.y();
278 pw[npoints] = 4.0 * 1.0 / ( sigma.y() * sigma.y() ) / weight[npoints];
279 }
280 else
281 {
282 px[npoints] = center.z();
283 py[npoints] = center.x();
284 pw[npoints] = 4.0 * 1.0 / ( sigma.x() * sigma.x() ) / weight[npoints];
285 }
286 }
287
288 // cout << " in MucRec2DRoad ID: " <<(*iHit)->Part()<<" "<<(*iHit)->Seg()<<"
289 // "<<(*iHit)->Gap()<<" "<< (*iHit)->Strip()<<" "<<px[npoints] << " " << py[npoints] <<
290 // " " << pw[npoints] << endl;
291 npoints++;
292
293 if ( npoints > 99 )
294 {
295 cout << "MucRec2DRoad: to many hits in this track, ignore it!" << endl;
296 return -1;
297 }
298 }
299 }
300 /*
301 float px2[100];
302 float py2[100];
303 for (int i = 0; i < m_pHits.size(); i++) {
304 int hitsInGap = 1;
305 px2[i] = -999; py2[i] = -999;
306 for(int j = 0; j < m_pHits.size(); j++){
307
308 if(j == i) continue;
309 if(m_pHits[i]->Part() == m_pHits[j]->Part() &&
310 m_pHits[i]->Seg() == m_pHits[j]->Seg() &&
311 m_pHits[i]->Gap() == m_pHits[j]->Gap() )
312 {
313 hitsInGap++;
314 px2[i] = (px[i]*(hitsInGap-1) + px[j])/hitsInGap;
315 py2[i] = (py[i]*(hitsInGap-1) + py[j])/hitsInGap;
316 cout<<hitsInGap<<" "<<px[i]<<" "<<px[j]<<" "<<px2[i]<<endl;
317 }
318 }
319 }
320
321 for(int i = 0; i < m_pHits.size(); i++){
322 if(px2[i] != -999&&py2[i] != -999){
323 px[i] = px2[i]; py[i] = py2[i];
324 }
325 }
326 */
327
328 ndof = npoints - 2;
329 if ( ndof < 0 ) return -1;
330
331 if ( npoints == 1 )
332 {
333 if ( m_Part == 1 )
334 {
335 if ( m_Orient == 0 )
336 {
337 px[npoints] = m_VertexPos.z();
338 py[npoints] =
339 sqrt( m_VertexPos.x() * m_VertexPos.x() + m_VertexPos.y() * m_VertexPos.y() );
340 if ( m_Seg == 2 ) py[npoints] = m_VertexPos.y();
341 }
342 else
343 {
344 px[npoints] = m_VertexPos.x();
345 py[npoints] = m_VertexPos.y();
346 }
347 }
348 else
349 {
350 if ( m_Orient == 0 )
351 {
352 px[npoints] = m_VertexPos.z();
353 py[npoints] = m_VertexPos.y();
354 }
355 else
356 {
357 px[npoints] = m_VertexPos.z();
358 py[npoints] = m_VertexPos.x();
359 }
360 }
361 pw[npoints] = 1.0;
362 npoints++;
363 }
364 else
365 {
366 if ( npoints == 0 ) { return -1; }
367 }
368
369 // Do the fits here.
370 MucRecLineFit fit;
371 int status = fit.LineFit( px, py, pw, npoints, &slope, &intercept, &chisq, &sigmaSlope,
372 &sigmaIntercept );
373
374 float tempslope, tempintercept, tempchisq, tempsigmaslope, sigmaPos;
375 int status4 = fit.LineFit( px, py, pw, m_Part, m_Seg, m_Orient, npoints, &tempslope,
376 &tempintercept, &tempchisq, &tempsigmaslope, &sigmaPos );
377
378 MucRecQuadFit quadfit;
379 float quad_a, quad_b, quad_c, sigmaquad_a, sigmaquad_b, sigmaquad_c, chisq_quad;
380 int whichhalf, status2 = 0;
381
382 if ( m_fittingMethod == 2 )
383 {
384 status2 = quadfit.QuadFit( px, py, pw, npoints, &quad_a, &quad_b, &quad_c, &whichhalf,
385 &chisq_quad, &sigmaquad_a, &sigmaquad_b, &sigmaquad_c );
386 }
387 // cout << " in MucRec2DRoad slope " << slope << " "<<intercept<<endl;
388
389 if ( slope > 1.0e10 || slope < -1.0e10 )
390 {
391 if ( m_Seg > 4 ) slope *= -1.0; // to avoid wrong direction
392 }
393
394 m_SimpleSlope = slope;
395 m_SimpleSlopeSigma = sigmaSlope;
396 m_SimpleIntercept = intercept;
397 m_SimpleInterceptSigma = sigmaIntercept;
398 m_SimplePosSigma = sigmaPos; // new 20071227
399 m_SimpleChi2 = chisq;
400 m_SimpleDOF = ndof;
401 m_SimpleFitOK = ( status == 0 ) && ( chisq < 1000.0 );
402 m_QuadFitOK = ( status2 == 1 );
403
404 m_SimpleQuad_a = quad_a;
405 m_SimpleQuad_b = quad_b;
406 m_SimpleQuad_c = quad_c;
407 m_SimpleQuad_whichhalf = whichhalf;
408 m_SimpleQuad_aSigma = sigmaquad_a;
409 m_SimpleQuad_bSigma = sigmaquad_b;
410 m_SimpleQuad_cSigma = sigmaquad_c;
411
412 return status;
413}
414
415/////////////////////////////////////////////////
416// Calculate the best-fit straight line with "simple" weights. add not use current gap!!!
417int MucRec2DRoad::SimpleFitNoCurrentGap( int currentgap, float& slope, float& intercept,
418 float& sigmaSlope, float& sigmaIntercept,
419 float& chisq, int& ndof ) {
420 // Assign to temporary arrays to be used in fit.
421 float px[100];
422 float py[100];
423 float pw[100];
424 int npoints = 0;
425
426 int notused = 0;
427
428 vector<MucRecHit*>::const_iterator iHit;
429
430 float pw2[100];
431 for ( int i = 0; i < 100; i++ )
432 {
433 pw2[i] = 1;
434 //----if( m_pHits[i]->Gap()==currentgap ) pw2[i] = 9999;
435 }
436
437 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
438 {
439 if ( *iHit )
440 { // Check for a null pointer.
441 if ( ( *iHit )->Gap() == currentgap ) continue;
442
443 Hep3Vector center = ( *iHit )->GetCenterPos();
444 Hep3Vector sigma = ( *iHit )->GetCenterSigma();
445 // Hep3Vector sigma(1.0, 1.0, 1.0);
446
447 if ( m_Part == 1 )
448 {
449 if ( m_Orient == 0 )
450 {
451 px[npoints] = center.z();
452 py[npoints] = sqrt( center.x() * center.x() + center.y() * center.y() );
453 if ( m_Seg == 2 )
454 py[npoints] = center.y(); // deal with seg2 seperately! because there is a hole
455 // here. 2006.11.9
456
457 pw[npoints] = 1.0 / ( sigma.y() * sigma.y() ) / pw2[npoints] / pw2[npoints];
458 }
459 else
460 {
461 px[npoints] = center.x();
462 py[npoints] = center.y();
463 pw[npoints] = 1.0 / ( sigma.x() * sigma.x() ) / pw2[npoints] / pw2[npoints];
464 }
465 }
466 else
467 {
468 if ( m_Orient == 0 )
469 {
470 px[npoints] = center.z();
471 py[npoints] = center.y();
472 pw[npoints] = 1.0 / ( sigma.y() * sigma.y() ) / pw2[npoints] / pw2[npoints];
473 }
474 else
475 {
476 px[npoints] = center.z();
477 py[npoints] = center.x();
478 pw[npoints] = 1.0 / ( sigma.x() * sigma.x() ) / pw2[npoints] / pw2[npoints];
479 }
480 }
481
482 // cout << " in MucRec2DRoad ID: " <<(*iHit)->Part()<<" "<<(*iHit)->Seg()<<"
483 // "<<(*iHit)->Gap()<<" "<< (*iHit)->Strip()<<" "<<px[npoints] << " " << py[npoints] <<
484 // " " << pw[npoints] << endl; cout<<"process ngap: "<<currentgap<<" current:
485 // "<<(*iHit)->Gap()<<" x: "<<px[npoints]<<" y: "<<py[npoints]<<" weight:
486 // "<<pw[npoints]<<endl;
487 npoints++;
488
489 if ( npoints > 99 )
490 {
491 cout << "MucRec2DRoad: to many hits in this track, ignore it!" << endl;
492 return -1;
493 }
494 }
495 }
496
497 ndof = npoints - 2;
498 if ( ndof < 0 ) return -1;
499
500 if ( npoints == 1 )
501 {
502 if ( m_Part == 1 )
503 {
504 if ( m_Orient == 0 )
505 {
506 px[npoints] = m_VertexPos.z();
507 py[npoints] =
508 sqrt( m_VertexPos.x() * m_VertexPos.x() + m_VertexPos.y() * m_VertexPos.y() );
509 if ( m_Seg == 2 ) py[npoints] = m_VertexPos.y();
510 }
511 else
512 {
513 px[npoints] = m_VertexPos.x();
514 py[npoints] = m_VertexPos.y();
515 }
516 }
517 else
518 {
519 if ( m_Orient == 0 )
520 {
521 px[npoints] = m_VertexPos.z();
522 py[npoints] = m_VertexPos.y();
523 }
524 else
525 {
526 px[npoints] = m_VertexPos.z();
527 py[npoints] = m_VertexPos.x();
528 }
529 }
530 pw[npoints] = 1.0;
531 npoints++;
532 }
533 else
534 {
535 if ( npoints == 0 ) { return -1; }
536 }
537
538 // Do the fits here.
539 MucRecLineFit fit;
540 int status = fit.LineFit( px, py, pw, npoints, &slope, &intercept, &chisq, &sigmaSlope,
541 &sigmaIntercept );
542
543 MucRecQuadFit quadfit;
544 float quad_a, quad_b, quad_c, sigmaquad_a, sigmaquad_b, sigmaquad_c, chisq_quad;
545 int whichhalf, status2 = 0;
546
547 if ( m_fittingMethod == 2 )
548 {
549 status2 = quadfit.QuadFit( px, py, pw, npoints, &quad_a, &quad_b, &quad_c, &whichhalf,
550 &chisq_quad, &sigmaquad_a, &sigmaquad_b, &sigmaquad_c );
551 }
552 // cout << " in MucRec2DRoad slope " << slope << " "<<intercept<<endl;
553
554 if ( slope > 1.0e10 || slope < -1.0e10 )
555 {
556 if ( m_Seg > 4 ) slope *= -1.0; // to avoid wrong direction
557 }
558
559 ////////2009-03-12
560 m_SimpleSlope = slope;
561 m_SimpleSlopeSigma = sigmaSlope;
562 m_SimpleIntercept = intercept;
563 m_SimpleInterceptSigma = sigmaIntercept;
564 // m_SimplePosSigma = sigmaPos; //new 20071227
565 m_SimpleChi2 = chisq;
566 m_SimpleDOF = ndof;
567 m_SimpleFitOK = ( status == 0 ) && ( chisq < 1000.0 );
568 m_QuadFitOK = ( status2 == 1 );
569
570 m_SimpleQuad_a = quad_a;
571 m_SimpleQuad_b = quad_b;
572 m_SimpleQuad_c = quad_c;
573 m_SimpleQuad_whichhalf = whichhalf;
574 m_SimpleQuad_aSigma = sigmaquad_a;
575 m_SimpleQuad_bSigma = sigmaquad_b;
576 m_SimpleQuad_cSigma = sigmaquad_c;
577
578 return status;
579}
580
581// Fit (with weights) the hit centers to a straight line.
582// This is a helper function for the Project methods.
583// Give an estimated position (x,y,z) of the point to which we will
584// project.
585int MucRec2DRoad::Fit( const float& x, const float& y, const float& z, float& slope,
586 float& intercept, float& sigmaSlope, float& sigmaIntercept,
587 float& chisq, int& ndof ) {
588 int status;
589
590 // If the "simple" fit has not been done yet, do it now.
591 if ( !m_SimpleFitOK )
592 {
593 // Least-squares fit to the positions ...
594 float a, sa, b, sb, chi;
595 int n;
596 status = SimpleFit( a, b, sa, sb, chi, n );
597 if ( status < 0 )
598 {
599 // cout << "MucRec2DRoad::Fit-E2 simple fit fail status = "
600 // << status << endl;
601 return status;
602 }
603 }
604
605 // Assign to temporary arrays to be used in fit.
606 float px[100];
607 float py[100];
608 float pw[100];
609 int npoints = 0;
610 float dx, dy, dr;
611
612 // include vertex point when do the fancy fitting
613 // if (m_Orient == kHORIZ) {
614 // px[npoints] = m_VertexPos.y();
615 // dx = px[npoints] - y;
616 //} else {
617 // px[npoints] = m_VertexPos.x();
618 // dx = px[npoints] - x;
619 //}
620 // pz[npoints] = m_VertexPos.z();
621 // dz = pz[npoints] - z;
622 // dr = sqrt(dx*dx + dz*dz);
623 // pw[npoints] = WeightFunc(m_SimpleChi2,dr);
624 // npoints++;
625
626 vector<MucRecHit*>::const_iterator iHit;
627
628 // Determine the weights based on the chi-square of the fit
629 // (the scatter of the points should be roughly related to the
630 // momentum) and the distance from the center to the estimated
631 // location.
632
633 // cout << m_pHits.size() << endl;
634 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
635 {
636 if ( *iHit )
637 { // Check for a null pointer.
638
639 Hep3Vector center = ( *iHit )->GetCenterPos();
640 Hep3Vector sigma = ( *iHit )->GetCenterSigma();
641
642 if ( m_Part == 1 )
643 { // change from 0 to 1 at 2006.11.30
644 if ( m_Orient == 0 )
645 {
646 px[npoints] = center.z();
647 dx = px[npoints] - z;
648 py[npoints] = sqrt( center.x() * center.x() + center.y() * center.y() );
649 if ( m_Seg == 2 )
650 py[npoints] = center.y(); // deal with seg2 seperately! because there is a hole
651 // here. 2006.11.9
652 dy = py[npoints] - sqrt( x * x + y * y );
653 }
654 else
655 {
656 px[npoints] = center.x();
657 dx = px[npoints] - x;
658 py[npoints] = center.y();
659 dy = py[npoints] - y;
660 }
661 }
662 else
663 {
664 if ( m_Orient == 0 )
665 {
666 px[npoints] = center.z();
667 dx = px[npoints] - z;
668 py[npoints] = center.y();
669 dy = py[npoints] - y;
670 }
671 else
672 {
673 px[npoints] = center.z();
674 dx = px[npoints] - z;
675 py[npoints] = center.x();
676 dy = py[npoints] - x;
677 }
678 }
679
680 dr = sqrt( dx * dx + dy * dy );
681 pw[npoints] = WeightFunc( m_SimpleChi2, dr );
682 // pw[npoints] = WeightFunc(m_SimpleChi2,dr);
683
684 // cout << " " << npoints << " "
685 // << px[npoints] << " " << py[npoints] << " " << pw[npoints]
686 // << " " << dx << " " << dy << " " << dr
687 // << endl;
688
689 npoints++;
690
691 if ( npoints > 99 )
692 {
693 cout << "MucRec2DRoad: to many hits in this track, ignore it!" << endl;
694 return -1;
695 }
696 }
697 }
698
699 // Refit ...
700 ndof = npoints - 2;
701 if ( npoints == 1 )
702 {
703 if ( m_Part == 1 )
704 { // change from 0 to 1 at 2006.11.30
705 if ( m_Orient == 0 )
706 {
707 px[npoints] = m_VertexPos.z();
708 py[npoints] =
709 sqrt( m_VertexPos.x() * m_VertexPos.x() + m_VertexPos.y() * m_VertexPos.y() );
710 if ( m_Seg == 2 ) py[npoints] = m_VertexPos.y();
711 }
712 else
713 {
714 px[npoints] = m_VertexPos.x();
715 py[npoints] = m_VertexPos.y();
716 }
717 }
718 else
719 {
720 if ( m_Orient == 0 )
721 {
722 px[npoints] = m_VertexPos.z();
723 py[npoints] = m_VertexPos.y();
724 }
725 else
726 {
727 px[npoints] = m_VertexPos.z();
728 py[npoints] = m_VertexPos.x();
729 }
730 }
731 pw[npoints] = 1.0;
732 npoints++;
733 }
734 else
735 {
736 if ( npoints == 0 ) { return -1; }
737 }
738
739 MucRecLineFit fit;
740 // cout << "npoints " << npoints << endl;
741 status = fit.LineFit( px, py, pw, npoints, &slope, &intercept, &chisq, &sigmaSlope,
742 &sigmaIntercept );
743 m_DOF = ndof;
744 m_Chi2 = chisq;
745
746 if ( status < 0 )
747 {
748 // cout << "MucRec2DRoad::Fit-E3 fit fail status = " << status << endl;
749 }
750
751 return status;
752}
753
754// Where does the trajectory of this road intersect a specific gap?
755void MucRec2DRoad::Project( const int& gap, float& x, float& y, float& z, float& x2, float& y2,
756 float& z2 ) {
757 float sigmaX, sigmaY, sigmaZ;
758
759 x = 0.0;
760 sigmaX = 0.0;
761 x2 = 0.0;
762 y = 0.0;
763 sigmaY = 0.0;
764 y2 = 0.0;
765 z = 0.0;
766 sigmaZ = 0.0;
767 z2 = 0.0;
768
769 if ( ( gap < 0 ) || ( gap >= (int)MucID::getGapMax() ) )
770 {
771 cout << "MucRec2DRoad::Project-E1 invalid gap = " << gap << endl;
772 return;
773 }
774
775 // Determine the projection point of the "simple" fit to the desired gap.
776 float x0, y0, z0, sigmaX0, sigmaY0, sigmaZ0;
777 float phi = m_Seg * 0.25 * kPi;
779
780 if ( m_Part == 1 )
781 {
782 if ( m_Orient == 0 )
783 {
784 geom->FindIntersection( m_Part, m_Seg, gap, m_SimpleSlope * cos( phi ),
785 m_SimpleSlope * sin( phi ), 1.0, m_SimpleIntercept * cos( phi ),
786 m_SimpleIntercept * sin( phi ), 0.0, m_SimpleSlopeSigma, 0.0,
787 0.0, m_SimpleInterceptSigma, 0.0, 0.0, x0, y0, z0, sigmaX0,
788 sigmaY0, sigmaZ0 );
789
790 if ( m_SimpleSlope > 10000 )
791 { // the line is in right center of this segment, we can not get intersection in y
792 // coordinate, in this case, m_SimpleIntercept is in z coordinate.
793 geom->FindIntersection( m_Part, m_Seg, gap, m_SimpleSlope * cos( phi ),
794 m_SimpleSlope * sin( phi ), 1.0, 0.0, 0.0, m_SimpleIntercept,
795 m_SimpleSlopeSigma, 0.0, 0.0, m_SimpleInterceptSigma, 0.0, 0.0,
796 x0, y0, z0, sigmaX0, sigmaY0, sigmaZ0 );
797 }
798 }
799 else
800 {
801 geom->FindIntersection( m_Part, m_Seg, gap, 1.0, m_SimpleSlope, 0.0, 0.0,
802 m_SimpleIntercept, 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0,
803 m_SimpleInterceptSigma, 0.0, x0, y0, z0, sigmaX0, sigmaY0,
804 sigmaZ0 );
805 // cout<<"in MucRec2DRoad line Project xyz0 = "<<x0<<" "<<y0<<" "<<z0<<endl;
806 }
807 }
808 else
809 {
810 if ( m_Orient == 0 )
811 {
812 geom->FindIntersection( m_Part, m_Seg, gap, m_SimpleSlope, m_SimpleSlope, 1.0, 0.0,
813 m_SimpleIntercept, 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0,
814 m_SimpleInterceptSigma, 0.0, x0, y0, z0, sigmaX0, sigmaY0,
815 sigmaZ0 );
816 }
817 else
818 {
819 geom->FindIntersection( m_Part, m_Seg, gap, m_SimpleSlope, m_SimpleSlope, 1.0,
820 m_SimpleIntercept, 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0,
821 m_SimpleInterceptSigma, 0.0, 0.0, x0, y0, z0, sigmaX0, sigmaY0,
822 sigmaZ0 );
823 }
824 // cout << " part " << m_Part
825 // << " seg " << m_Seg
826 // << " gap " << gap
827 // << " orient " << m_Orient
828 // << " slope = " << m_SimpleSlope
829 // << endl;
830 }
831
832 // cout << "In find intersection x0 = " << x0 << " y0 = " << y0 << " z0 = " << z0 << endl;
833
834 float a, b, sa, sb, chi2;
835 int ndof;
836
837 int status = Fit( x0, y0, z0, a, b, sa, sb, chi2, ndof );
838
839 // m_FitOK = (status == 0) && (chi2<1000.0);
840 // if (!fFitOK) {
841 // cout << "MucRec2DRoad::Project-E2 fit fail status = "
842 // << status << " npoints = " << npoints << " chi-sq = "
843 // << chi2 << endl;
844 // }
845
846 // // Assign to fields of TMuiRoad object.
847 // m_DOF = npoints - 2;
848 // m_Chi2 = chi2;
849
850 if ( m_Part == 1 )
851 { // change from 0 to 1 at 2006.11.30
852 if ( m_Orient == 0 )
853 {
854 geom->FindIntersection( m_Part, m_Seg, gap, a * cos( phi ), a * sin( phi ), 1.0,
855 // a, 0.0, 1.0,
856 b * cos( phi ), b * sin( phi ), 0.0, sa, 0.0, 0.0, sb, 0.0, 0.0,
857 x, y, z, sigmaX, sigmaY, sigmaZ );
858
859 if ( fabs( a ) > 10000 )
860 { ///
861 geom->FindIntersection( m_Part, m_Seg, gap, a * cos( phi ), a * sin( phi ), 1.0, 0.0,
862 0.0, b,
863 // a, 0.0, 1.0,
864 // b, 0.0, 0.0,
865 sa, 0.0, 0.0, sb, 0.0, 0.0, x, y, z, sigmaX, sigmaY, sigmaZ );
866 }
867 }
868 else
869 {
870 geom->FindIntersection( m_Part, m_Seg, gap, 1.0, a, 0.0, 0.0, b, 0.0, 0.0, sa, 0.0, 0.0,
871 sb, 0.0, x, y, z, sigmaX, sigmaY, sigmaZ );
872
873 if ( m_fittingMethod == 2 && m_QuadFitOK )
874 {
875 float a, b, c;
876 float sa, sb, sc, chi2x;
877 int ydof;
878 int whichhalf;
879
880 GetSimpleFitParams( a, b, c, whichhalf, sa, sb, sc, chi2x, ydof );
881 geom->FindIntersection( m_Part, m_Seg, gap, 10E30, 0.0, m_SimpleIntercept,
882 0.0, // vy = infinite
883 a, b, c, // y = a*x*x + b*x +c
884 whichhalf, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, x, y, z, x2, y2, z2,
885 sigmaX, sigmaY, sigmaZ );
886 }
887 }
888 }
889 else
890 {
891 if ( m_Orient == 0 )
892 {
893 geom->FindIntersection( m_Part, m_Seg, gap, a, a, 1.0, 0.0, b, 0.0, 0.0, sa, 0.0, 0.0,
894 sb, 0.0, x, y, z, sigmaX, sigmaY, sigmaZ );
895 }
896 else
897 {
898 geom->FindIntersection( m_Part, m_Seg, gap, a, a, 1.0, b, 0.0, 0.0, sa, 0.0, 0.0, sb,
899 0.0, 0.0, x, y, z, sigmaX, sigmaY, sigmaZ );
900 }
901 }
902
903 return;
904}
905
906// A unique identifier for this road in the current event.
907int MucRec2DRoad::GetIndex() const { return m_Index; }
908
909// In which part was this road found?
910int MucRec2DRoad::GetPart() const { return m_Part; }
911
912// In which seg was this road found?
913int MucRec2DRoad::GetSeg() const { return m_Seg; }
914
915// In which orientation was this road found?
916int MucRec2DRoad::GetOrient() const { return m_Orient; }
917
918// Position of the vertex point.
919void MucRec2DRoad::GetVertexPos( float& x, float& y, float& z ) const {
920 x = m_VertexPos.x();
921 y = m_VertexPos.y();
922 z = m_VertexPos.z();
923
924 return;
925}
926
927// Which gap is the last one with hits attached to this road?
928int MucRec2DRoad::GetLastGap() const { return m_LastGap; }
929
930// Return the number of hits in the gap with the most attached hits.
931int MucRec2DRoad::GetMaxHitsPerGap() const { return m_MaxHitsPerGap; }
932
933// Return the total number of hits attached to this road.
934int MucRec2DRoad::GetTotalHits() const { return m_TotalHits; }
935
936// How many gaps provide hits attached to this road?
938 const int ngap = (int)MucID::getGapMax();
939 int gap, count = 0;
940 vector<int> firedGap;
941 for ( gap = 0; gap < ngap; gap++ ) { firedGap.push_back( 0 ); }
942
943 vector<MucRecHit*>::const_iterator iHit;
944 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
945 {
946 if ( *iHit )
947 { // Check for a null pointer.
948 gap = ( *iHit )->Gap();
949 firedGap[gap] = 1;
950 }
951 }
952
953 for ( gap = 0; gap < ngap; gap++ ) { count += firedGap[gap]; }
954
955 return count;
956}
957
958// How many hits per gap does this road contain?
959int MucRec2DRoad::GetHitsPerGap( const int& gap ) const {
960 if ( ( gap < 0 ) || ( gap >= (int)MucID::getGapMax() ) )
961 {
962 cout << "MucRec2DRoad::GetHitsPerGap-E1 invalid gap = " << gap << endl;
963 return 0;
964 }
965
966 vector<MucRecHit*>::const_iterator iHit;
967 int hitsInGap = 0;
968
969 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
970 {
971
972 if ( !( *iHit ) )
973 {
974 cout << "MucRec2DRoad::GetHitsPerGap()-E2 null hit pointer !" << endl;
975 return 0;
976 }
977 else
978 {
979 if ( gap == ( *iHit )->Gap() ) hitsInGap += 1;
980 }
981 }
982
983 return hitsInGap;
984}
985
986// Does this road contain any hits in the given seg in a gap?
987bool MucRec2DRoad::HasHitInGap( const int& gap ) const {
988 if ( ( gap < 0 ) || ( gap >= (int)MucID::getGapMax() ) )
989 {
990 cout << "MucRec2DRoad::HasHitInGap-E2 invalid gap = " << gap << endl;
991 return false;
992 }
993
994 bool found = false;
995 vector<MucRecHit*>::const_iterator iHit;
996
997 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
998 {
999 if ( *iHit )
1000 { // Check for a null pointer.
1001 if ( ( *iHit )->Gap() == gap ) { found = true; }
1002 }
1003 }
1004
1005 return found;
1006}
1007
1008// How many hits do two roads share?
1010 if ( !road2 ) { return 0; }
1011
1012 int count = 0;
1013 vector<MucRecHit*>::const_iterator iHit1;
1014 vector<MucRecHit*>::const_iterator iHit2;
1015 MucRecHit * hit1, *hit2;
1016
1017 for ( iHit1 = m_pHits.begin(); iHit1 != m_pHits.end(); iHit1++ )
1018 {
1019 for ( iHit2 = road2->m_pHits.begin(); iHit2 != road2->m_pHits.end(); iHit2++ )
1020 {
1021 hit1 = ( *iHit1 );
1022 hit2 = ( *iHit2 );
1023
1024 if ( ( hit1 != 0 ) && ( hit2 != 0 ) )
1025 {
1026 if ( hit1->GetID() == hit2->GetID() ) { count++; }
1027 }
1028 }
1029 }
1030
1031 return count;
1032}
1033
1034// Slope of trajectory.
1035float MucRec2DRoad::GetSlope() const { return m_SimpleSlope; }
1036
1037// Intercept of trajectory.
1038float MucRec2DRoad::GetIntercept() const { return m_SimpleIntercept; }
1039
1040// Degrees of freedom of trajectory fit.
1041int MucRec2DRoad::GetDegreesOfFreedom() const { return m_SimpleDOF; }
1042
1043// Chi-square parameters (per degree of freedom) of trajectory fit.
1045 if ( ( !m_SimpleFitOK ) || ( m_SimpleDOF < 0 ) ) { return -1.0; }
1046 else if ( m_SimpleDOF == 0 ) { return 0.0; }
1047 else { return ( m_SimpleChi2 / m_SimpleDOF ); }
1048}
1049
1050// Get the parameters from the simple fit.
1051void MucRec2DRoad::GetSimpleFitParams( float& slope, float& intercept, float& sigmaSlope,
1052 float& sigmaIntercept, float& chisq, int& ndof ) const {
1053 slope = m_SimpleSlope;
1054 intercept = m_SimpleIntercept;
1055 sigmaSlope = m_SimpleSlopeSigma;
1056 sigmaIntercept = m_SimpleInterceptSigma;
1057 chisq = m_SimpleChi2;
1058 ndof = m_SimpleDOF;
1059
1060 return;
1061}
1062
1063void MucRec2DRoad::GetPosSigma( float& possigma ) const { possigma = m_SimplePosSigma; }
1064
1065// Get the parameters from the simple quad fit.
1066void MucRec2DRoad::GetSimpleFitParams( float& a, float& b, float& c, int& whichhalf,
1067 float& sigmaa, float& sigmab, float& sigmac,
1068 float& chisq, int& ndof ) const {
1069 a = m_SimpleQuad_a;
1070 b = m_SimpleQuad_b;
1071 c = m_SimpleQuad_c;
1072 whichhalf = m_SimpleQuad_whichhalf;
1073
1074 sigmaa = m_SimpleQuad_aSigma;
1075 sigmab = m_SimpleQuad_bSigma;
1076 sigmac = m_SimpleQuad_cSigma;
1077
1078 chisq = m_SimpleChi2;
1079 ndof = m_SimpleDOF;
1080
1081 return;
1082}
1083
1084// Get a pointer to the first found hit attached in a particular gap.
1085MucRecHit* MucRec2DRoad::GetHit( const int& gap ) const {
1086 if ( ( gap < 0 ) || ( gap >= (int)MucID::getGapMax() ) )
1087 {
1088 cout << "MucRec2DRoad::Hit-E1 invalid gap = " << gap << endl;
1089 return 0;
1090 }
1091
1092 vector<MucRecHit*>::const_iterator iHit;
1093
1094 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
1095 {
1096 if ( *iHit )
1097 { // Check for a null pointer.
1098 if ( ( *iHit )->Gap() == gap ) { return ( *iHit ); }
1099 }
1100 }
1101
1102 return 0L;
1103}
1104
1105// Distance from a hit to the projection of the road to the gap
1106// containing the hit.
1108 // Use straight-line projection?
1109 if ( !hit )
1110 {
1111 cout << "MucRec2DRoad::GetHitDistance-E1 null hit pointer!" << endl;
1112 return muckInfinity;
1113 }
1114
1115 int gap = hit->Gap();
1116 if ( ( gap < 0 ) || ( gap >= (int)MucID::getGapMax() ) )
1117 {
1118 cout << "MucRec2DRoad::HitDistance-W2 bad gap number = " << gap << endl;
1119 return muckInfinity;
1120 }
1121
1122 if ( hit->GetGap()->Orient() != m_Orient )
1123 {
1124 // The orientation of the hit is different from that of the road.
1125 cout << "MucRec2DRoad::GetHitDistance-W3 "
1126 << " hit has wrong orientation = " << hit->GetGap()->Orient() << endl;
1127 return muckInfinity;
1128 }
1129
1130 HepPoint3D r = hit->GetCenterPos();
1131 HepPoint3D rl = hit->GetGap()->TransformToGap( r );
1132 // cout << "hit center " << r << endl;
1133 // cout << "hit center local " << rl << endl;
1134
1135 // Determine the projection point of the "simple" fit to the desired gap.
1136 // FIXME(?): need to use fit with fancy weights instead?
1137 float delta, delta1, delta2;
1138 float x0, y0, z0;
1139 float x2, y2, z2;
1140 // float sigmaX0, sigmaY0, sigmaZ0;
1141
1142 // cout << "y:x = " << m_SimpleSlope << endl;
1143
1144 Project( gap, x0, y0, z0, x2, y2, z2 );
1145 // cout << " gap = " << gap << " x0 = " << x0
1146 // << " y0 = " << y0 << " z0 = " << z0
1147 // << endl;
1148
1149 if ( x0 == y0 && x0 == z0 && x0 == 0 )
1150 {
1151 x0 += -9999;
1152 y0 += -9999;
1153 z0 += -9999;
1154 } // cout<<"wrong intersection"<<endl;}
1155 if ( x2 == y2 && x2 == z2 && x2 == 0 )
1156 {
1157 x2 += -9999;
1158 y2 += -9999;
1159 z2 += -9999;
1160 } // cout<<"wrong intersection"<<endl;} //wrong intersection!!!
1161 HepPoint3D s = HepPoint3D( x0, y0, z0 );
1162 HepPoint3D s_2 = HepPoint3D( x2, y2, z2 );
1163 HepPoint3D sl = hit->GetGap()->TransformToGap( s );
1164 HepPoint3D s_2l = hit->GetGap()->TransformToGap( s_2 );
1165 // cout << "project center " << s << endl;
1166
1167 // cout << "project center local sl= " << sl << endl;
1168 // cout << "project center local sl= " << s_2l << endl;
1169 // cout << "project center local rl= " << rl << endl;
1170 if ( m_Part == 0 )
1171 {
1172 if ( m_Orient == 0 )
1173 {
1174 delta1 = fabs( sl.y() - rl.y() );
1175 delta2 = fabs( s_2l.y() - rl.y() );
1176 }
1177 else
1178 {
1179 delta1 = fabs( sl.x() - rl.x() );
1180 delta2 = fabs( s_2l.x() - rl.x() );
1181 }
1182 }
1183 else
1184 {
1185 if ( m_Orient == 0 )
1186 {
1187 delta1 = fabs( sl.y() - rl.y() );
1188 delta2 = fabs( s_2l.y() - rl.y() );
1189 }
1190 else
1191 {
1192 delta1 = fabs( sl.x() - rl.x() );
1193 delta2 = fabs( s_2l.x() - rl.x() );
1194 }
1195 }
1196 // if(which==0) {
1197 // if(delta1<delta2)delta = delta1;
1198 // else delta = delta2;
1199 // }
1200 // cout<<"which = "<<which<<" distance = "<<delta1<<" "<<delta2<<endl;
1201
1202 if ( delta1 < delta2 ) return delta1;
1203 else return delta2;
1204}
1205
1206// Determine the size of the search window in the given gap.
1207float MucRec2DRoad::GetSearchWindowSize( const int& gap ) const {
1208 if ( ( gap < 0 ) || ( gap >= (int)MucID::getGapMax() ) )
1209 {
1210 cout << "MucRec2DRoad::GetSearchWindowSize-E1 invalid gap = " << gap << endl;
1211 return 0.0;
1212 }
1213
1214 // Determine the projection point of the "simple" fit to the last
1215 // gap and the desired gap.
1216 // FIXME? the "delta-x" variable is calculated as the scalar
1217 // difference between the positions obtained by projecting to the
1218 // last gap and to the desired gap.
1219
1221 float x1, y1, z1, x2, y2, z2, dx, dy, dr;
1222 float sigmaX, sigmaY, sigmaZ;
1223
1224 if ( m_Part == 0 )
1225 {
1226 if ( m_Orient == 0 )
1227 {
1228 geom->FindIntersection( m_Part, 0, m_LastGap, 1.0, m_SimpleSlope, 0.0, 0.0,
1229 m_SimpleIntercept, 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0,
1230 m_SimpleInterceptSigma, 0.0, x1, y1, z1, sigmaX, sigmaY,
1231 sigmaZ );
1232 geom->FindIntersection( m_Part, 0, gap, 1.0, m_SimpleSlope, 0.0, 0.0, m_SimpleIntercept,
1233 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0, m_SimpleInterceptSigma,
1234 0.0, x2, y2, z2, sigmaX, sigmaY, sigmaZ );
1235 dx = z2 - z1;
1236 dy = sqrt( x2 * x2 + y2 * y2 ) - sqrt( x1 * x1 + y1 * y1 );
1237 }
1238 else
1239 {
1240 geom->FindIntersection( m_Part, m_Seg, m_LastGap, m_SimpleSlope, 0.0, 1.0,
1241 m_SimpleIntercept, 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0,
1242 m_SimpleInterceptSigma, 0.0, 0.0, x1, y1, z1, sigmaX, sigmaY,
1243 sigmaZ );
1244 geom->FindIntersection( m_Part, m_Seg, gap, m_SimpleSlope, 0.0, 1.0, m_SimpleIntercept,
1245 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0, m_SimpleInterceptSigma,
1246 0.0, 0.0, x2, y2, z2, sigmaX, sigmaY, sigmaZ );
1247 dx = x2 - x1;
1248 dy = y2 - y1;
1249 }
1250 }
1251 else
1252 {
1253 if ( m_Orient == 0 )
1254 {
1255 geom->FindIntersection( m_Part, m_Seg, m_LastGap, 0.0, m_SimpleSlope, 1.0, 0.0,
1256 m_SimpleIntercept, 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0,
1257 m_SimpleInterceptSigma, 0.0, x1, y1, z1, sigmaX, sigmaY,
1258 sigmaZ );
1259 geom->FindIntersection( m_Part, m_Seg, gap, 0.0, m_SimpleSlope, 1.0, 0.0,
1260 m_SimpleIntercept, 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0,
1261 m_SimpleInterceptSigma, 0.0, x2, y2, z2, sigmaX, sigmaY,
1262 sigmaZ );
1263 dx = z2 - z1;
1264 dy = y2 - y1;
1265 }
1266 else
1267 {
1268 geom->FindIntersection( m_Part, m_Seg, m_LastGap, m_SimpleSlope, 0.0, 1.0,
1269 m_SimpleIntercept, 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0,
1270 m_SimpleInterceptSigma, 0.0, 0.0, x1, y1, z1, sigmaX, sigmaY,
1271 sigmaZ );
1272 geom->FindIntersection( m_Part, m_Seg, gap, m_SimpleSlope, 0.0, 1.0, m_SimpleIntercept,
1273 0.0, 0.0, m_SimpleSlopeSigma, 0.0, 0.0, m_SimpleInterceptSigma,
1274 0.0, 0.0, x2, y2, z2, sigmaX, sigmaY, sigmaZ );
1275 dx = z2 - z1;
1276 dy = x2 - x1;
1277 }
1278 }
1279
1280 dr = sqrt( dx * dx + dy * dy );
1281
1282 return WindowFunc( m_SimpleChi2, dr );
1283}
1284
1285// Calculate the hit counts and last gap quantities.
1286void MucRec2DRoad::CountHits() {
1287 m_MaxHitsPerGap = 0;
1288 m_TotalHits = 0;
1289 m_LastGap = 0;
1290
1291 vector<MucRecHit*>::const_iterator iHit;
1292 const int ngap = (int)MucID::getGapNum( m_Part );
1293 vector<int> HitsPerGap;
1294 for ( int gap = 0; gap < ngap; gap++ ) { HitsPerGap.push_back( 0 ); }
1295
1296 // Fill HitsPerGap
1297 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
1298 {
1299 if ( !( *iHit ) )
1300 {
1301 cout << "MucRec2DRoad::CountHits()-E1 null hit pointer !" << endl;
1302 return;
1303 }
1304 else
1305 {
1306 int gap = ( *iHit )->Gap();
1307 HitsPerGap[gap]++;
1308 // cout << "gap " << gap << endl;
1309 }
1310 }
1311
1312 // Find the gap from where we should stop count,
1313 // namely in front of the gap there are more than
1314 // m_MaxNSkippedGaps gaps containing no hit.
1315
1316 int StopGap = ngap;
1317 /*
1318 for (int gap = m_MaxNSkippedGaps; gap < ngap; gap++) {
1319 int SubTotalHits = 0;
1320 for (int igap = gap-m_MaxNSkippedGaps; igap <= gap; igap++) {
1321 SubTotalHits += HitsPerGap[igap];
1322 }
1323 if (SubTotalHits == 0 ) {
1324 StopGap = gap - m_MaxNSkippedGaps;
1325 break;
1326 }
1327 }
1328 */
1329
1330 // cout << "StopGap " << StopGap << endl;
1331 // Now we might get correct counting on hits, last gap and MaxHitsPerGap
1332 for ( int gap = 0; gap < StopGap; gap++ )
1333 {
1334 m_TotalHits += HitsPerGap[gap];
1335 if ( m_MaxHitsPerGap < HitsPerGap[gap] ) m_MaxHitsPerGap = HitsPerGap[gap];
1336 if ( HitsPerGap[gap] > 0 ) m_LastGap = gap;
1337 }
1338}
1339
1340// Does the Hit exist in the road .
1342
1343 vector<MucRecHit*>::const_iterator iHit;
1344 bool HitExist = false;
1345
1346 // Also, if a track hits overlap region of two panels, we avoid
1347 // to double count hits in two panels
1348
1349 Identifier id = hit->GetID();
1350
1351 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
1352 {
1353 if ( *iHit )
1354 { // Check for a null pointer.
1355 if ( ( *iHit )->GetID() == id ) HitExist = true;
1356 }
1357 if ( HitExist ) break;
1358 }
1359
1360 return HitExist;
1361}
1362
1363// Get indices of all hits in the road.
1364vector<Identifier> MucRec2DRoad::GetHitsID() const {
1365 vector<Identifier> idCon;
1366
1367 vector<MucRecHit*>::const_iterator iHit;
1368 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
1369 {
1370 if ( *iHit )
1371 { // Check for a null pointer.
1372 Identifier id = ( *iHit )->GetID();
1373 idCon.push_back( id );
1374 /*
1375 cout << " MucRec2DRoad::HitIndices gap orientation twopack= "
1376 << (*iHit)->ChannelID().Plane() << " "
1377 << (*iHit)->ChannelID().Orient() << " "
1378 << (*iHit)->ChannelID().TwoPack() << endl;
1379 */
1380 }
1381 }
1382 return idCon;
1383}
1384
1385vector<MucRecHit*> MucRec2DRoad::GetHits() const { return m_pHits; }
1386
1387// Print Hits Infomation.
1389 vector<MucRecHit*>::const_iterator iHit;
1390 for ( iHit = m_pHits.begin(); iHit != m_pHits.end(); iHit++ )
1391 {
1392 if ( *iHit )
1393 { // Check for a null pointer.
1394 float xl, yl, zl;
1395 ( *iHit )->GetStrip()->GetCenterPos( xl, yl, zl );
1396 HepPoint3D vl( xl, yl, zl );
1397 HepPoint3D vg = ( *iHit )->GetGap()->TransformToGlobal( vl );
1398
1399 cout << " orient " << m_Orient << " part " << ( *iHit )->Part() << " seg "
1400 << ( *iHit )->Seg() << " gap " << ( *iHit )->Gap() << " strip "
1401 << ( *iHit )->Strip() << " pos (" << vg.x() << ", " << vg.y() << ", " << vg.z()
1402 << ")" << endl;
1403 }
1404 }
1405}
1406
1407// Function used to determine the search weight size
1408float MucRec2DRoad::WeightFunc( const float& chisq, const float& distance ) const {
1409 return 1.0;
1410}
1411
1412// Function used to determine the search window size
1413float MucRec2DRoad::WindowFunc( const float& chisq, const float& distance ) const {
1414 return 1.0;
1415}
HepGeom::Point3D< double > HepPoint3D
const Int_t n
DOUBLE_PRECISION count[3]
XmlRpcServer s
*********Class see also m_nmax DOUBLE PRECISION m_MasPhot DOUBLE PRECISION m_phsu DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_r2 DOUBLE PRECISION m_WtMass INTEGER m_nmax INTEGER m_Nevgen INTEGER m_IsFSR INTEGER m_MarTot *COMMON c_KarFin $ !Output file $ !Event serial number $ !alpha QED at Thomson limit $ !minimum energy at CMS for remooval $ !infrared dimensionless $ !dummy photon IR regulator $ !crude photon multiplicity enhancement factor *EVENT $ !MC crude volume of PhhSpace *Sfactors $ !YFS formfactor IR part only $ !YFS formfactor non IR finite part $ !mass weight
Definition KarFin.h:34
const double muckInfinity
HepPoint3D TransformToGap(const HepPoint3D gPoint) const
Transform a point from global coordinate to gap coordinate.
static MucGeoGeneral * Instance()
Get a pointer to the single instance of MucGeoGeneral.
void FindIntersection(const int part, const int seg, const int gap, const float vx, const float vy, const float vz, const float x0, const float y0, const float z0, const float sigmaVx, const float sigmaVy, const float sigmaVz, const float sigmaX0, const float sigmaY0, const float sigmaZ0, float &x, float &y, float &z, float &sigmaX, float &sigmaY, float &sigmaZ)
static value_type getGapMax()
Definition MucID.cxx:165
static value_type getGapNum(int part)
Definition MucID.cxx:141
~MucRec2DRoad()
Destructor.
int Fit(const float &x, const float &y, const float &z, float &slope, float &intercept, float &sigmaSlope, float &sigmaIntercept, float &chisq, int &ndof)
Fit (with weights) the hit center to a straight line.
vector< Identifier > GetHitsID() const
Get indices of all hits in the road.
int GetNGapsWithHits() const
How many gaps provide hits attached to this road?
bool HasHitInGap(const int &gap) const
Does this road contain any hits in the given gap?
void PrintHitsInfo() const
Print Hits Infomation.
int GetTotalHits() const
How many hits in all does this road contain?
int GetHitsPerGap(const int &gap) const
How many hits per gap does this road contain?
float GetReducedChiSquare() const
Chi-square parameter (per degree of freedom) of the trajectory fit.
void SetIndex(const int &index)
Set the index for this road.
void Project(const int &gap, float &x, float &y, float &z, float &x2, float &y2, float &z2)
Where does the trajectory of this road intersect a specific gap?
void GetVertexPos(float &x, float &y, float &z) const
Position of the vertex point.
void GetPosSigma(float &possigma) const
float WindowFunc(const float &chisq, const float &distance) const
MucRec2DRoad & operator=(const MucRec2DRoad &orig)
Assignment constructor.
float GetSearchWindowSize(const int &gap) const
Determine the size of the search window in the given gap.
float GetIntercept() const
Intercept of trajectory.
void AttachHit(MucRecHit *hit)
Attach the given hit to this road.
MucRec2DRoad(const int &part=0, const int &seg=0, const int &orient=0, const float &xVertex=0.0, const float &yVertex=0.0, const float &zVertex=0.0, const int &fittingMethod=0)
Constructor.
int GetMaxHitsPerGap() const
How many hits were attached in the gap with the most attached hits?
int GetLastGap() const
Which gap is the last one with hits attached to this road?
void AttachHitNoFit(MucRecHit *hit)
Attach the given hit to this road, but not fit this road.
float GetSlope() const
Slope of trajectory.
bool HasHit(MucRecHit *hit) const
Does the hit exist in the road .
int GetNSharedHits(const MucRec2DRoad *road) const
How many hits do two roads share?
void SetMaxNSkippedGaps(const int &nGaps)
int GetPart() const
In which part was this road found?
int SimpleFit(float &slope, float &intercept, float &sigmaSlope, float &sigmaIntercept, float &chisq, int &ndof)
Calculate the best-fit straight line with "simple" weights.
float GetHitDistance(const MucRecHit *hit)
Distance to a hit.
int GetDegreesOfFreedom() const
How many degrees of freedom in the trajectory fit?
int GetIndex() const
A unique identifier for this road in the current event.
void GetSimpleFitParams(float &slope, float &intercept, float &sigmaSlope, float &sigmaIntercept, float &chisq, int &ndof) const
Get the parameters from the simple fit.
vector< MucRecHit * > GetHits() const
float WeightFunc(const float &chisq, const float &distance) const
int GetSeg() const
In which segment was this road found?
int GetOrient() const
In which orientation was this road found?
MucRecHit * GetHit(const int &gap) const
Get a pointer to the first found hit attached in a particular gap.
int SimpleFitNoCurrentGap(int currentgap, float &slope, float &intercept, float &sigmaSlope, float &sigmaIntercept, float &chisq, int &ndof)
Calculate the best-fit straight line with "simple" weights. not use current gap!!!
MucGeoGap * GetGap() const
Get geometry data for the gap containing this hit.
Hep3Vector GetCenterPos() const
Get Center position of the strip (global coords).
Definition MucRecHit.cxx:93
Identifier GetID() const
Get soft identifier of this hit.
int LineFit(float x[], float y[], float w[], int n, float *a, float *b, float *chisq, float *siga, float *sigb)
int QuadFit(float x[], float y[], float w[], int n, float *a, float *b, float *c, int *half, float *chisq, float *siga, float *sigb, float *sigc)