00001 //----------------------------------------------------------------------------- 00002 // $Id: TCircleFitter.cxx,v 1.8 2010/03/31 09:58:59 liucy Exp $ 00003 //----------------------------------------------------------------------------- 00004 // Filename : TCircleFitter.cc 00005 // Section : Tracking 00006 // Owner : Yoshi Iwasaki 00007 // Email : yoshihito.iwasaki@kek.jp 00008 //----------------------------------------------------------------------------- 00009 // Description : A class to fit a TTrackBase object to a circle. 00010 // See http://bsunsrv1.kek.jp/~yiwasaki/tracking/ 00011 //----------------------------------------------------------------------------- 00012 00013 #include "TrkReco/TCircleFitter.h" 00014 #include "TrkReco/TTrackBase.h" 00015 #include "TrkReco/TCircle.h" 00016 #include "TrkReco/TMLink.h" 00017 //#include "lpav/Lpav.h" 00018 //#include "TrkReco/Lpav.h" 00019 #include "TrackUtil/Lpav.h" 00020 00021 TCircleFitter::TCircleFitter(const std::string & name) 00022 : TMFitter(name), _charge(0.), _radius(0.), _center(HepPoint3D(0., 0., 0.)) { 00023 } 00024 00025 TCircleFitter::~TCircleFitter() { 00026 } 00027 00028 int 00029 TCircleFitter::fit(TTrackBase & t) const { 00030 00031 #ifdef TRKRECO_DEBUG_DETAIL 00032 std::cout << " TCircleFitter::fit ..." << std::endl; 00033 #endif 00034 00035 //...Already fitted ?... 00036 if (t.fitted()) return TFitAlreadyFitted; 00037 00038 //...Check # of hits... 00039 if (t.links().length() < 3) return TFitErrorFewHits; 00040 00041 //...Hit loop... 00042 Lpav circle; 00043 /* 00044 circle.add_point(-173.011, 94.3169); 00045 circle.add_point(-187.6, 101.528); 00046 circle.add_point(-202.018, 108.601); 00047 circle.add_point(-216.639, 115.691); 00048 circle.add_point(-231.152, 122.49); 00049 circle.add_point(-246.207, 129.496); 00050 circle.add_point(-261.179, 136.407); 00051 circle.add_point(-275.198, 142.764); 00052 circle.add_point(-290.519, 149.572); 00053 circle.add_point(-304.42, 155.7); 00054 circle.add_point(-319.947, 162.285); 00055 circle.add_point(-335.495, 168.731); 00056 circle.add_point(-608.394, 264.577); 00057 circle.add_point(-612.842, 265.869); 00058 circle.add_point(-627.175, 270.011); 00059 circle.add_point(-643.654, 274.719); 00060 circle.add_point(-657.809, 278.683); 00061 circle.add_point(-674.464, 283.209); 00062 circle.add_point(-690.7, 287.541); 00063 circle.add_point(-704.925, 291.091); 00064 */ 00065 unsigned n = t.links().length(); 00066 00067 for (unsigned i = 0; i < n; i++) { 00068 TMLink * l = t.links()[i]; 00069 const TMDCWireHit * h = l->hit(); 00070 00071 //...Check next hit... 00072 HepPoint3D point; 00073 if (h->state() & WireHitPatternLeft) 00074 point = h->position(WireHitLeft); 00075 else if (h->state() & WireHitPatternRight) 00076 point = h->position(WireHitRight); 00077 else 00078 point = h->xyPosition(); 00079 // float weight = 1. / (h->distance() * h->distance()); 00080 // float weight = 1. / h->distance(); 00081 00082 // if (h->state() & WireHitPatternLeft) cout<<"h: "<<h->wire()->layerId()<<" local: " 00083 // <<h->wire()->localId()<<" TCirclefitter: L"<<endl; 00084 // else cout<<"h: "<<h->wire()->layerId()<<" local: " 00085 // <<h->wire()->localId()<<" TCirclefitter: R"<<endl; 00086 00087 circle.add_point(point.x(), point.y()); //, weight); 00088 //yuany 00089 00090 // cout<<"TCirclefitter("<<sqrt(point.x()*point.x()+point.y()*point.y())<<"," 00091 // <<point.y()/point.x()<<") dis:" 00092 // <<(h->drift(0))*10000/40<<" point "<<point<<" L "<<(h->state()&WireHitPatternLeft) 00093 // <<" R "<<(h->state()&WireHitPatternRight)<<endl; 00094 00095 // cout<<"TCirclefitter "<<point.x()<<" "<<point.y()<<" L "<<(h->state()&WireHitPatternLeft)<<" R "<<(h->state()&WireHitPatternRight)<<endl; 00096 } 00097 00098 if (circle.fit() < 0.0 || circle.kappa() == 0.0) return TFitFailed; 00099 //yuany 00100 // cout<<"circle chi2:"<<circle.fit()<<" kappa:"<<circle.kappa()<<" center:"<<circle.center()<<" radius:"<<circle.radius()<<endl; 00101 00102 HepVector v(circle.center()); 00103 _center.setX(v(1)); 00104 _center.setY(v(2)); 00105 _radius = circle.radius(); 00106 00107 //...Determine charge...Better way??? 00108 int qSum = 0; 00109 for (unsigned i = 0; i < n; i++) { 00110 TMLink * l = t.links()[i]; 00111 if (l == 0) continue; 00112 00113 const TMDCWireHit * h = l->hit(); 00114 if (h == 0) continue; 00115 00116 float q = (_center.cross(h->xyPosition())).z(); 00117 if (q > 0.) qSum += 1; 00118 else qSum -= 1; 00119 } 00120 if (qSum >= 0) _charge = +1.; 00121 else _charge = -1.; 00122 _radius *= _charge; 00123 00124 if (t.objectType() == Circle) 00125 ((TCircle &) t).property(_charge, _radius, _center); 00126 fitDone(t); 00127 return 0; 00128 }