00001 #include "TrkExtAlg/ExtMucKal.h"
00002 #include "MucCalibAlg/MucIdTransform.h"
00003
00004 static const double Small( 0.01 );
00005 static const double Infinite( 1.0e10 );
00006 static const double kRad = 57.2958;
00007
00008 static const int fix_ = 1;
00009 static const int chi2lim_ = 100;
00010 ExtMucKal::ExtMucKal():FilterOK(false),Chi2_sub(-1),HitExist(false),m_jcb(6,6,0),m_samestrip(false),n_sigm(6)
00011 {;}
00012
00013 ExtMucKal::~ExtMucKal()
00014 {;}
00015
00016 bool ExtMucKal::ExtMucFilter()
00017 {
00018
00019 if(!HitExist) {FilterOK = false;return FilterOK;}
00020 m_samestrip = m_gapid[0]==m_nearesthit->Part()&& m_gapid[1]==m_nearesthit->Seg()&&m_gapid[2]==m_nearesthit->Gap()&&m_iStrip==m_nearesthit->Strip();
00021
00022
00023 Hep3Vector mom_unit = m_CurrentMomentum;
00024 mom_unit.setMag(1.0);
00025 Hep3Vector IntrPos_loc = m_nearesthit->GetGap()->TransformToGap(m_CurrentInsct);
00026 Hep3Vector mom_loc = m_nearesthit->GetGap()->RotateToGap(m_CurrentMomentum);
00027 MucGeoGap* nearestGap = m_nearesthit->GetGap();
00028
00029 m_orient = nearestGap->Orient();
00030 float sx,sy,sz;
00031 m_nearesthit->GetStrip()->GetCenterSigma(sx, sy, sz);
00032 if(m_orient==1) m_sigma = sx/sqrt(12.);
00033 if(m_orient==0) m_sigma = sy/sqrt(12.);
00034
00035 HepMatrix rotation = GetRoationMatrix(nearestGap);
00036 HepSymMatrix IntrErr_loc(6,0);
00037 IntrErr_loc.assign(rotation*m_CurrentInsctXPErr*rotation.T());
00038 Hep3Vector modpos_loc;
00039 Hep3Vector modmom_loc;
00040 HepSymMatrix moderr_loc(6,0);
00041
00042 double chisq =Fit(IntrPos_loc,mom_loc,IntrErr_loc);
00043 modpos_loc.setX(m_bm[0]);modpos_loc.setY(m_bm[1]);modpos_loc.setZ(m_bm[2]);
00044 modmom_loc.setX(m_bm[3]);modmom_loc.setY(m_bm[4]);modmom_loc.setZ(m_bm[5]);
00045 moderr_loc = m_Ebm;
00046 bool direction = false;
00047 double dirchange = (modmom_loc.theta()-1.5707963)*(mom_loc.theta()-1.5707963);
00048 if(dirchange<0.) {direction = true;
00049 }
00050
00051 Hep3Vector modpos_glob = m_nearesthit->GetGap()->TransformToGlobal(modpos_loc);
00052 Hep3Vector modmom_glob = m_nearesthit->GetGap()->RotateToGlobal(modmom_loc);
00053 HepSymMatrix moderr_glob(6,0);
00054 moderr_glob.assign(rotation.T()*moderr_loc*rotation);
00055
00056 if(chisq>0.&&chisq<100.&&!direction)
00057 {
00058
00059 FilterOK=true;
00060 Chi2_sub = chisq;
00061 m_err_mod = moderr_glob;
00062 m_pos_mod = modpos_glob;
00063 m_mom_mod = modmom_glob;
00064
00065 }
00066 return FilterOK;
00067 }
00068
00069
00070
00071 void ExtMucKal::XPmod(Hep3Vector &pos,Hep3Vector &mom,HepSymMatrix &err)
00072 {
00073 pos = m_pos_mod;
00074 mom = m_mom_mod;
00075 err = m_err_mod;
00076 }
00077
00078 vector<MucRecHit*> ExtMucKal::TrackHit()
00079 {
00080 vector<MucRecHit*> hitvec;
00081 vector<MucRecHit*> HitInGap = GapHit();
00082 int hitsize = HitInGap.size();
00083 double dist_nearest = 9999.;
00084 for ( int h = 0;h<hitsize;h++ )
00085 {
00086
00087 MucRecHit* myhit = HitInGap[h];
00088
00089 MucGeoGap* mygap = myhit->GetGap();
00090 HepMatrix rotation = GetRoationMatrix(mygap);
00091 HepSymMatrix IntrErr_loc(6,0);
00092 IntrErr_loc.assign(rotation*m_CurrentInsctXPErr*rotation.T());
00093 float sx,sy,sz;
00094 myhit->GetStrip()->GetCenterSigma(sx,sy,sz);
00095 double distance = GetDistance(myhit);
00096 double window = -9999.;
00097 int myorient = myhit->GetGap()->Orient();
00098 if(myorient==1)
00099 window = n_sigm*sqrt(IntrErr_loc(1,1)+sx*sx/12.);
00100
00101
00102 if(myorient==0)
00103 window = n_sigm*sqrt(IntrErr_loc(2,2)+sy*sy/12.);
00104
00105
00106
00107
00108
00109 if(fabs(distance)<window)
00110 {
00111 hitvec.push_back(myhit);
00112 if(dist_nearest>fabs(distance))
00113 {
00114
00115 HitExist =true;
00116 dist_nearest=fabs(distance);
00117 m_nearesthit = HitInGap[h];
00118 }
00119 }
00120 }
00121
00122 return hitvec;
00123 }
00124
00125 double ExtMucKal::GetDistance(const MucRecHit* hit)
00126 {
00127 if (!hit) {
00128 cout << "RecMucTrack:GetHitDistance-E1 null hit pointer!" << endl;
00129 return kInfinity;
00130 }
00131
00132 int part = hit->Part();
00133 int gap = hit->Gap();
00134 if ( (gap < 0) || (gap >= (int)MucID::getGapNum(part)) ) {
00135 cout << "RecMucTrack::GetHitDistance() bad gap number = " << gap << endl;
00136 return kInfinity;
00137 }
00138 HepPoint3D posHit = hit->GetCenterPos();
00139 HepPoint3D posHitLocal = hit->GetGap()->TransformToGap(posHit);
00140 HepPoint3D posInsctLocal = hit->GetGap()->TransformToGap(m_CurrentInsct);
00141 int orient = hit->GetGap()->Orient();
00142
00143 float distance = -9990;
00144 if(orient == 1) distance = (posHitLocal.x()-posInsctLocal.x());
00145 if(orient == 0) distance = (posHitLocal.y()-posInsctLocal.y());
00146
00147 return distance;
00148 }
00149
00150 bool ExtMucKal::MucKalIniti()
00151
00152 {
00153 MucGeoGap* box = MucGeoGeneral::Instance()->GetGap((int)m_gapid[0],(int)m_gapid[1],(int)m_gapid[2]);
00154 Hep3Vector mom_unit= m_CurrentMomentum;
00155 mom_unit.setMag(1.0);
00156 HepVector3D _interc = box->ProjectToGap(m_CurrentPosition,mom_unit);
00157 m_CurrentInsct = _interc;
00158 HepVector3D m_CurrentInsct_loc = box->TransformToGap(m_CurrentInsct);
00159 int iStrip = box->GuessStrip(m_CurrentInsct_loc.x(),m_CurrentInsct_loc.y(),m_CurrentInsct_loc.z());
00160 m_iStrip =iStrip;
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 bool iniOK = false;
00177 iniOK = JCB();
00178 m_CurrentInsctXPErr = m_CurrentXPErr.similarity( m_jcb );
00179 return iniOK;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 vector<MucRecHit*> ExtMucKal::GapHit()
00196 {
00197 vector<MucRecHit*> gaphit;
00198 int kDeltaSeg[3]={-1,0,1};
00199 MucDigiCol::iterator digiIter = m_MucDigiCol->begin();
00200 for ( ; digiIter != m_MucDigiCol->end(); digiIter++ )
00201 {
00202 Identifier mucId = (*digiIter)->identify();
00203 int part = MucID::barrel_ec(mucId);
00204 int segment = MucID::segment(mucId);
00205 int layer = MucID::layer(mucId);
00206 int strip = MucID::strip(mucId);
00207 int m_part =(int)m_gapid[0];
00208 int m_seg = (int)m_gapid[1];
00209 int m_gap = (int)m_gapid[2];
00210
00211
00212 if(m_part==part&&m_gap == layer)
00213 for(int s=0;s<3;s++)
00214 {
00215 int iSeg = m_seg+kDeltaSeg[s];
00216 if(iSeg<0) iSeg += MucID::getSegNum(m_part);
00217 if(iSeg>((int)MucID::getSegNum(m_part) - 1))iSeg -= MucID::getSegNum(m_part);
00218 if(iSeg==segment)
00219 {
00220 MucRecHit* hit = new MucRecHit(part,segment,layer,strip);
00221 gaphit.push_back(hit);
00222 }
00223 }
00224 }
00225 return gaphit;
00226 }
00227
00228 Hep3Vector ExtMucKal::GetHitGap()
00229 {
00230 m_hitgap.setX(m_nearesthit->Part());
00231 m_hitgap.setY(m_nearesthit->Seg());
00232 m_hitgap.setZ(m_nearesthit->Gap());
00233 return m_hitgap;
00234 }
00235
00236
00237 bool ExtMucKal::JCB()
00238 {
00239 HepMatrix m_xp_jcb(6,6,0);
00240 double dx( ( m_CurrentInsct - m_CurrentPosition ).mag() );
00241 double dp(0.);
00242 double p2( m_CurrentMomentum.mag2() );
00243 double p_abs( sqrt( p2 ) );
00244
00245 double p_inv;
00246 if( p_abs > Small && m_CurrentMomentum.mag() > Small ){
00247 p_inv = 1.0 / p_abs;
00248 } else {
00249 p_inv = Infinite;
00250 return 0;
00251 }
00252 double p2inv( p_inv * p_inv );
00253 double p3inv( p2inv * p_inv );
00254 double fdx( dx * p3inv );
00255
00256 double fdp( dp * p_inv );
00257 double px( m_CurrentMomentum.x() );
00258 double py( m_CurrentMomentum.y() );
00259 double pz( m_CurrentMomentum.z() );
00260 double px2( px * px );
00261 double py2( py * py );
00262 double pz2( pz * pz );
00263 double pxy( px * py );
00264 double pyz( py * pz );
00265 double pzx( pz * px );
00266 m_xp_jcb( 1, 1 ) = 1.0;
00267 m_xp_jcb( 1, 4 ) = fdx * ( py2 + pz2 );
00268 m_xp_jcb( 1, 5 ) = - fdx * pxy;
00269 m_xp_jcb( 1, 6 ) = - fdx * pzx;
00270 m_xp_jcb( 2, 2 ) = 1.0;
00271 m_xp_jcb( 2, 4 ) = - fdx * pxy;
00272 m_xp_jcb( 2, 5 ) = fdx * ( pz2 + px2 );
00273 m_xp_jcb( 2, 6 ) = - fdx * pyz;
00274
00275 m_xp_jcb( 3, 3 ) = 1.0;
00276 m_xp_jcb( 3, 4 ) = - fdx * pzx;
00277 m_xp_jcb( 3, 5 ) = - fdx * pyz;
00278 m_xp_jcb( 3, 6 ) = fdx * ( px2 + py2 );
00279
00280 m_xp_jcb( 4, 4 ) = 1.0 - fdp;
00281 m_xp_jcb( 5, 5 ) = 1.0 - fdp;
00282 m_xp_jcb( 6, 6 ) = 1.0 - fdp;
00283 m_jcb = m_xp_jcb;
00284 return 1;
00285
00286 }
00287
00288 HepMatrix ExtMucKal::GetRoationMatrix(MucGeoGap *box)
00289 {
00290
00291
00292 MucGeoGap* box_ = box;
00293 float thetaX,phiX,thetaY,phiY,thetaZ,phiZ;
00294 box->GetRotationMatrix(thetaX,phiX,thetaY,phiY,thetaZ,phiZ);
00295
00296 thetaX=thetaX/kRad;
00297 thetaY=thetaY/kRad;
00298 thetaZ=thetaZ/kRad;
00299 phiX=phiX/kRad;
00300 phiY=phiY/kRad;
00301 phiZ=phiZ/kRad;
00302 Hep3Vector colX, colY,colZ;
00303 colX.setRThetaPhi(1.,thetaX,phiX);
00304 colY.setRThetaPhi(1.,thetaY,phiY);
00305 colZ.setRThetaPhi(1.,thetaZ,phiZ);
00306
00307 HepMatrix rotation(6,6,0);
00308 rotation(1,1) = colX.x();
00309 rotation(1,2) = colX.y();
00310 rotation(1,3) = colX.z();
00311 rotation(2,1) = colY.x();
00312 rotation(2,2) = colY.y();
00313 rotation(2,3) = colY.z();
00314 rotation(3,1) = colZ.x();
00315 rotation(3,2) = colZ.y();
00316 rotation(3,3) = colZ.z();
00317
00318 rotation(4,4) = colX.x();
00319 rotation(4,5) = colX.y();
00320 rotation(4,6) = colX.z();
00321 rotation(5,4) = colY.x();
00322 rotation(5,5) = colY.y();
00323 rotation(5,6) = colY.z();
00324 rotation(6,4) = colZ.x();
00325 rotation(6,5) = colZ.y();
00326 rotation(6,6) = colZ.z();
00327 return rotation;
00328 }
00329
00330
00331 double ExtMucKal::Fit( Hep3Vector & pos, Hep3Vector & mom, HepSymMatrix & Epm)
00332 {
00333 static HepVector a(6,0);
00334 a[0] = pos.x();
00335 a[1] = pos.y();
00336 a[2] = pos.z();
00337 a[3] = mom.x();
00338 a[4] = mom.y();
00339 a[5] = mom.z();
00340 m_bm = a;
00341 m_Ebm = Epm;
00342
00343 HepMatrix V_meas(1,1,0);
00344 V_meas(1,1)= m_sigma*m_sigma;
00345 double mag2(m_bm[5]*m_bm[5]+m_bm[4]*m_bm[4]+m_bm[3]*m_bm[3]);
00346
00347 HepSymMatrix ebm(6,0);
00348 ebm.assign(m_Ebm);
00349
00350 HepVector v_bm(6,0);
00351
00352 v_bm = m_bm;
00353 v_bm[2] = 0;
00354
00355 HepMatrix H(1,6,0);
00356 if(m_orient == 1) H(1,1) = 1;
00357 if(m_orient == 0) H(1,2) = 1;
00358 HepMatrix ebm_HT(6,1,0);
00359 ebm_HT = ebm * H.T();
00360
00361 HepMatrix R(1,1,0);
00362
00363 HepMatrix R2(1,1,0);
00364 HepMatrix Aii(1,1,0);
00365 Aii(1,1)=(H * ebm_HT)(1,1);
00366 R = H * ebm_HT + V_meas;
00367
00368 R2 = Aii + V_meas;
00369 double aii = Aii(1,1);
00370
00371 HepMatrix K(6,1,0);
00372 int ierr;
00373 K = ebm_HT * R.inverse(ierr);
00374 double dist = GetDistance(m_nearesthit);
00375 double r = R2(1,1);
00376 double pull;
00377 if(r==0.)pull = 9999;
00378 else
00379 pull = dist/sqrt(r);
00380 m_pull = pull;
00381
00382
00383 HepVector diff_v_bm(6, 0);
00384 diff_v_bm = K * dist;
00385
00387
00388 if ((fabs(diff_v_bm[0]) > 2 * n_sigm * sqrt(V_meas(1,1)+fabs(m_Ebm(1,1)))&&m_orient==1) ||
00389 (fabs(diff_v_bm[1]) > 2 * n_sigm * sqrt(V_meas(1,1)+fabs(m_Ebm(2,2)))&&m_orient==0) ){
00390
00391 cout<<"KLMK:WARNING! Huge diff_v_bm found!Discard this fit!: "<<endl;
00392 return 99999;
00393 }
00394
00395 HepVector v_bm_mod = v_bm + diff_v_bm;
00396
00397 static const HepSymMatrix Id(6,1);
00398 HepMatrix ebm_mod(6,6,0);
00399 ebm_mod = (Id - K*H) * ebm;
00400 double r_bm;
00401 r_bm = (1 - (H*K)(1,1))*dist;
00402
00403 double Rk;
00404 Rk = (V_meas - H * ebm_mod * H.T())(1,1);
00405 double chi2;
00406 if(Rk==0.)
00407 chi2 = 99999;
00408 else
00409 chi2 = pull*pull;
00410 m_pull = pull;
00411 if (chi2>0 && chi2 < chi2lim_) {
00412 HepSymMatrix ebm_replace;
00413 ebm_replace.assign(ebm_mod);
00414 HepVector v_bm_replace;
00415 v_bm_replace = v_bm_mod;
00416 v_bm_replace[2] = 0;
00417 m_bm = v_bm_replace;
00418 m_Ebm= ebm_replace;
00419 if(fix_)
00420 {
00421 double mag2mod(m_bm[5]*m_bm[5]+m_bm[4]*m_bm[4]+m_bm[3]*m_bm[3]);
00422 v_bm_replace[3] = v_bm_replace[3]*sqrt(mag2)/sqrt(mag2mod);
00423 v_bm_replace[4] = v_bm_replace[4]*sqrt(mag2)/sqrt(mag2mod);
00424 v_bm_replace[5] = v_bm_replace[5]*sqrt(mag2)/sqrt(mag2mod);
00425 m_bm=v_bm_replace;
00426 }
00427
00428
00429
00430
00431
00432
00433 }
00434
00435
00436 return chi2;
00437 }
00438
00439
00440
00441