/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Muc/MucRecEvent/MucRecEvent-00-02-52/src/MucRec3DRoad.cxx

Go to the documentation of this file.
00001 //$id$
00002 //
00003 //$log$
00004 
00005 /*
00006  *    2003/12/25   Zhengyun You     Peking University
00007  * 
00008  *    2005/02/27   Zhengyun You      Peking University
00009  *                 transplanted to Gaudi framework
00010  */
00011 
00012 #include <iostream>
00013 #include <vector>
00014 #include <CLHEP/Vector/ThreeVector.h>
00015 #include <CLHEP/Geometry/Point3D.h>
00016 
00017 #include "Identifier/MucID.h"
00018 #include "MucGeomSvc/MucGeomSvc.h"
00019 #include "MucGeomSvc/MucConstant.h"
00020 #include "MucRecEvent/MucRecHit.h"
00021 #include "MucRecEvent/MucRec2DRoad.h"
00022 #include "MucRecEvent/MucRec3DRoad.h"
00023 #include "MucRecEvent/MucRecLineFit.h"
00024 
00025 // Constructor.
00026 MucRec3DRoad::MucRec3DRoad(MucRec2DRoad *road0, MucRec2DRoad *road1)
00027   : m_Road0(road0), m_Road1(road1),
00028     m_Index(-1), 
00029     m_Part(road0->GetPart()),
00030     m_Seg(road0->GetSeg()),
00031     m_LastGap(0),
00032     m_Group(-1)
00033 {
00034   float x, y, z;
00035   road0->GetVertexPos(x, y, z);
00036   m_VertexPos.setX(x);
00037   m_VertexPos.setY(y);
00038   m_VertexPos.setZ(z);
00039 
00040   // If the part numbers don't match, something is seriously wrong!
00041   if ( (road1->GetPart() != m_Part) || (road1->GetSeg() != m_Seg) ) {
00042     cout << "MucRec3DRoad(ctor)-E1  mismatched 2D roads:"
00043          << "  x part  = " << road0->GetPart() << " seg = " << road0->GetSeg() << endl
00044          << "  y part  = " << road1->GetPart() << " seg = " << road1->GetSeg() << endl;
00045     m_Part  = -1;
00046     m_Seg   = -1;
00047   }
00048   
00049   // Compute the last-gap parameter; take the deeper of the 1D roads.
00050   if ( road1->GetLastGap() > road0->GetLastGap() ) {
00051     m_LastGap = road1->GetLastGap();
00052   } else {
00053     m_LastGap = road0->GetLastGap();
00054   }
00055 
00056   // Check that the two 1D roads have clusters in the same panels.
00057   // FIXME:  logic needs more thought!
00058 
00059   // Calculate the chi-square and number of degrees of freedom of the
00060   // 2-D trajectory (use the "simple" fits).
00061   // FIXME:  Can we calc. chi-square without brute force?
00062 
00063   m_DOF  = m_Road0->GetDegreesOfFreedom() + m_Road1->GetDegreesOfFreedom();
00064   m_Chi2 = 0.0;
00065 
00066   for (int gap = 0; gap < (int)MucID::getGapMax(); gap++) 
00067   {
00068     MucRecHit* hit;
00069     float dist, sigma;
00070     hit = m_Road0->GetHit(gap);
00071     if (hit) {
00072       if ( hit->Part() == 1 ) sigma  = hit->GetCenterSigma().y(); // ???
00073       else                        sigma  = hit->GetCenterSigma().y();
00074       
00075       dist   = m_Road0->GetHitDistance(hit) / sigma;
00076       m_Chi2 += dist * dist;
00077       //cout<<"in MucRec3DRoad dist1="<<dist<<" hitdis "<<dist*sigma<<" sigma="<<sigma<<" chi2="<<m_Chi2<<endl;
00078     }
00079     
00080     hit = m_Road1->GetHit(gap);
00081     if (hit) {
00082       if ( hit->Part() == 1 ) {
00083             // sigma  = fabs(sqrt( (hit->GetCenterSigma().x())*(hit->GetCenterSigma().x())
00084       //               + (hit->GetCenterSigma().y())*(hit->GetCenterSigma().y()) ));
00085               sigma  = hit->GetCenterSigma().x();
00086       }
00087       else {
00088               sigma  = hit->GetCenterSigma().x();
00089       }
00090       dist   = m_Road1->GetHitDistance(hit) / sigma;
00091       m_Chi2 += dist * dist;
00092       // cout<<"in MucRec3DRoad dist2="<<dist<<" hitdis "<<dist*sigma<<" sigma="<<sigma<<" chi2="<<m_Chi2<<endl;
00093     }
00094   }
00095   
00096 }
00097 
00098 // Copy constructor.
00099 MucRec3DRoad::MucRec3DRoad(const MucRec3DRoad& source)
00100   : m_VertexPos(source.m_VertexPos),
00101     m_VertexSigma(source.m_VertexSigma),
00102     m_Road0(source.m_Road0), m_Road1(source.m_Road1),
00103     m_Index(source.m_Index),
00104     m_Part(source.m_Part), m_Seg(source.m_Seg),
00105     m_LastGap(source.m_LastGap), 
00106     m_Chi2(source.m_Chi2), m_DOF(source.m_DOF),
00107     m_Group(source.m_Group)
00108 { }
00109 
00110 // Destructor.
00111 MucRec3DRoad::~MucRec3DRoad()
00112 {
00113   // The 3D road objects do not "own" 2D objects, so don't delete them
00114   // here!
00115 }
00116 
00117 // Set the index for this road.
00118 void
00119 MucRec3DRoad::SetIndex(const int& index)
00120 {
00121   if (index >= 0) m_Index = index;
00122 }
00123 
00124 // Set the group index for this road.
00125 void
00126 MucRec3DRoad::SetGroup(const int& Group)
00127 {
00128   if (Group >= 0) m_Group = Group;
00129 }
00130 
00131 // Set the fit parameters : slope and intercept for XZ and YZ.
00132 void 
00133 MucRec3DRoad::SetSimpleFitParams(const float& slopeZX, 
00134                                     const float& interceptZX,
00135                                     const float& slopeZY, 
00136                                     const float& interceptZY)
00137 {
00138   m_SlopeZX     = slopeZX; 
00139   m_InterceptZX = interceptZX;
00140   m_SlopeZY     = slopeZY; 
00141   m_InterceptZY = interceptZY;
00142 }
00143 
00144 
00145 // the index for this road in the current event.
00146 int
00147 MucRec3DRoad::GetIndex() const
00148 {
00149   return m_Index;
00150 }
00151 
00152 // the group index for this road in the current event.
00153 int
00154 MucRec3DRoad::GetGroup() const
00155 {
00156   return m_Group;
00157 }
00158 
00159 // In which part was this road found?
00160 int
00161 MucRec3DRoad::GetPart() const
00162 {
00163   return m_Part;
00164 }
00165 
00166 // In which seg was this road found?
00167 int
00168 MucRec3DRoad::GetSeg() const
00169 {
00170   return m_Seg;
00171 }
00172 
00173 // Which gap is the last one with hits attached to this road?
00174 int
00175 MucRec3DRoad::GetLastGap() const
00176 {
00177   return m_LastGap;
00178 }
00179 
00180 // How many gaps provide hits attached to this road?
00181 int
00182 MucRec3DRoad::GetNGapsWithHits() const
00183 {
00184   int count = 0;
00185   for (int gap = 0; gap < (int)MucID::getGapMax(); gap++) {
00186     if ( (m_Road0->GetHitsPerGap(gap) > 0) || (m_Road1->GetHitsPerGap(gap) > 0) ) {
00187       count++;
00188     }
00189   }
00190   return count;
00191 }
00192 
00193 // How many hits in all does this road contain?
00194 int
00195 MucRec3DRoad::GetTotalHits() const
00196 {
00197   return ( m_Road0->GetTotalHits() + m_Road1->GetTotalHits() );
00198 }
00199 
00200 // How many hits per gap does this road contain?
00201 int
00202 MucRec3DRoad::GetHitsPerGap(const int& gap) const
00203 {
00204   if ( (gap < 0) || (gap >= (int)MucID::getGapMax()) ) {
00205     cout << "MucRec3DRoad::HitsPerGap-E1  invalid gap = " << gap << endl;
00206     return 0;
00207   }
00208 
00209   return ( m_Road0->GetHitsPerGap(gap) + m_Road1->GetHitsPerGap(gap) );
00210 }
00211 
00212 // How many hits were attached in the gap with the most attached hits?
00213 int
00214 MucRec3DRoad::GetMaxHitsPerGap() const
00215 {
00216   int nHit0 = m_Road0->GetMaxHitsPerGap();
00217   int nHit1 = m_Road1->GetMaxHitsPerGap();
00218   if( nHit0 > nHit1 ) {
00219     return nHit0;
00220   }
00221   else {
00222     return nHit1;
00223   }
00224 }
00225 
00226 // Does this road contain any hits in the given gap?
00227 bool
00228 MucRec3DRoad::HasHitInGap(const int& gap) const
00229 {
00230   if ( (gap < 0) || (gap >= (int)MucID::getGapMax()) ) {
00231     cout << "MucRec3DRoad::HasHitInGap-E2  invalid gap = " << gap << endl;
00232     return false;
00233   }
00234   
00235   return ( m_Road0->HasHitInGap(gap) || m_Road1->HasHitInGap(gap) );
00236 }
00237 
00238 // How many hits do two roads share?
00239 int
00240 MucRec3DRoad::GetNSharedHits(const MucRec3DRoad* road) const
00241 {
00242   if (!road) {
00243     return 0;
00244   }
00245 
00246   int count = 0;
00247   count += m_Road0->GetNSharedHits( road->Get2DRoad(int(0)) );
00248   count += m_Road1->GetNSharedHits( road->Get2DRoad(int(1)) );
00249 
00250   return count;
00251 }
00252 
00253 // Difference between the last gap in the two 2-D roads.
00254 int
00255 MucRec3DRoad::GetLastGapDelta() const
00256 {
00257   return abs( m_Road0->GetLastGap() - m_Road1->GetLastGap() );
00258 }
00259 
00260 // Difference between the number of hits in the two 2-D roads.
00261 int
00262 MucRec3DRoad::GetTotalHitsDelta() const
00263 {
00264   return abs( m_Road0->GetTotalHits() - m_Road1->GetTotalHits() );
00265 }
00266 
00267 // How many degrees of freedom in the trajectory fit?
00268 int
00269 MucRec3DRoad::GetDegreesOfFreedom() const
00270 {
00271   return m_DOF;
00272 }
00273 
00274 // Chi-square parameter (per degree of freedom) of the trajectory fit.
00275 float
00276 MucRec3DRoad::GetReducedChiSquare() const
00277 {
00278   if (m_DOF < 0) {
00279     return -1.0;
00280   } 
00281   else {
00282     if (m_DOF == 0) {
00283       return 0.0;
00284     }
00285     else {
00286       return (m_Chi2/m_DOF);
00287     }
00288   }
00289 }
00290 
00291 // Get Z-X dimension slope.
00292 float 
00293 MucRec3DRoad::GetSlopeZX() const
00294 {
00295   return m_SlopeZX;
00296 }
00297 
00298 // Get Z-X dimension intercept.
00299 float 
00300 MucRec3DRoad::GetInterceptZX() const
00301 {
00302   return m_InterceptZX;
00303 }
00304 
00305 // Get Z-Y dimension slope.
00306 float 
00307 MucRec3DRoad::GetSlopeZY() const
00308 {
00309   return m_SlopeZY;
00310 }
00311 
00312 // Get Z-Y dimension intercept.
00313 float 
00314 MucRec3DRoad::GetInterceptZY() const
00315 {
00316   return m_InterceptZY;
00317 }
00318 
00319 // Get a pointer to the hit attached in a particular gap.
00320 MucRecHit*
00321 MucRec3DRoad::GetHit(const int& gap) const
00322 {
00323   if ( (gap < 0) || (gap >= (int)MucID::getGapMax()) ) {
00324     cout << "MucRec3DRoad::GetHit-E1  invalid gap = " << gap << endl;
00325     return 0;
00326   }
00327   
00328   if ( m_Road0->GetHit(gap) ) {
00329     return m_Road0->GetHit(gap);
00330   }
00331   else {
00332     if ( m_Road1->GetHit(gap) ) {
00333       return m_Road1->GetHit(gap);
00334     }
00335   }
00336   return 0;
00337 }
00338 
00339 int 
00340 MucRec3DRoad::RefitNoCurrentGap(  const int &gap,
00341                          float &slopeZX,
00342                          float &interceptZX,
00343                          float &slopeZY,
00344                          float &interceptZY)
00345 {
00346   float vx,  vy,  vk,  vr;
00347   float x0,  y0,  k0,  r0;
00348   float svx, svy, svk, svr;
00349   float sx0, sy0, sk0, sr0;
00350   int   xdof, ydof;
00351   float chi2x, chi2y;
00352   float spos0, spos1;
00353 
00354   // Determine the projection point of the "simple" fit to the desired gap.
00355   int status1, status2;
00356 
00357   // now these 2 2D road have been refit without current gap!
00358   if( m_Part == 1 ) {
00359     status1 = m_Road0->SimpleFitNoCurrentGap(gap, vr, r0, svr, sr0, chi2x, xdof);
00360     status2 = m_Road1->SimpleFitNoCurrentGap(gap, vk, k0, svk, sk0, chi2y, ydof);
00361 
00362     m_Road0->GetPosSigma(spos0);
00363     m_Road1->GetPosSigma(spos1);
00364 
00365     TransformPhiRToXY(vk,  vr,  k0,  r0,
00366           vx,  vy,  x0,  y0);
00367 
00368 //    TransformPhiRToXY(svk, svr, sk0, sr0, svx, svy, sx0, sy0);
00369     TransformPhiRToXY(vk+svk, vr+svr, k0+sk0, r0+sr0, svx, svy, sx0, sy0);
00370     svx -= vx; svy -= vy; sx0 -= x0; sy0 -= y0;
00371   }
00372   else {
00373     status1 = m_Road0->SimpleFitNoCurrentGap(gap, vy, y0, svy, sy0, chi2y, ydof);
00374     status2 = m_Road1->SimpleFitNoCurrentGap(gap, vx, x0, svx, sx0, chi2x, xdof);
00375     m_Road0->GetPosSigma(spos0);
00376     m_Road1->GetPosSigma(spos1);
00377   }
00378 
00379   if(status1 == -1 || status2 == -1) return -1;
00380   slopeZX = vx; interceptZX = x0;
00381   slopeZY = vy; interceptZY = y0;
00382   
00383   return 0;
00384 }
00385 
00386 // Where does the trajectory of this road intersect a specific strip? ---for calib
00387 vector<Identifier>
00388 MucRec3DRoad::ProjectToStrip(const int& part, const int& gap, const HepPoint3D& gPoint, const Hep3Vector&gDirection)
00389 {
00390   if ( (part < 0) || (part >= (int)MucID::getPartNum()) ) {
00391     cout << "MucRec3DRoad::Project-E1  invalid part = " << part << endl;
00392   } 
00393 
00394   if ( (gap < 0) || (gap >= (int)MucID::getGapMax()) ) {
00395     cout << "MucRec3DRoad::Project-E1  invalid gap = " << gap << endl;
00396   }
00397  
00398   return MucGeoGeneral::Instance()->FindIntersectStrips(part, gap, gPoint, gDirection);
00399 } 
00400 
00401 vector<Identifier>
00402 MucRec3DRoad::ProjectToStrip(const int& part, const int& gap, const HepPoint3D& gPoint, const Hep3Vector&gDirection, vector<int>&padID, vector<float>&intersect_x, vector<float>&intersect_y, vector<float>&intersect_z)
00403 {
00404   if ( (part < 0) || (part >= (int)MucID::getPartNum()) ) {
00405     cout << "MucRec3DRoad::Project-E1  invalid part = " << part << endl;
00406   }
00407 
00408   if ( (gap < 0) || (gap >= (int)MucID::getGapMax()) ) {
00409     cout << "MucRec3DRoad::Project-E1  invalid gap = " << gap << endl;
00410   }
00411 
00412   return MucGeoGeneral::Instance()->FindIntersectStrips(part, gap, gPoint, gDirection, padID, intersect_x, intersect_y, intersect_z);
00413 }
00414 
00415 // Where does the trajectory of this road intersect a specific gap?
00416 void
00417 MucRec3DRoad::ProjectWithSigma(const int& gap, float& x, float& y, float& z, float& sigmaX, float& sigmaY, float& sigmaZ)
00418 {
00419   x = 0.0; sigmaX = 0.0;
00420   y = 0.0; sigmaY = 0.0;
00421   z = 0.0; sigmaZ = 0.0;
00422 
00423   if ( (gap < 0) || (gap >= (int)MucID::getGapMax()) ) {
00424     cout << "MucRec3DRoad::Project-E1  invalid gap = " << gap << endl;
00425     return;
00426   }
00427 
00428   float vx,  vy,  vk,  vr;
00429   float x0,  y0,  k0,  r0;
00430   float svx, svy, svk, svr;
00431   float sx0, sy0, sk0, sr0;
00432   int   xdof, ydof;
00433   float chi2x, chi2y;
00434   float spos0, spos1;
00435 
00436   // Determine the projection point of the "simple" fit to the desired gap.
00437   if( m_Part == 1 ) {
00438     m_Road0->GetSimpleFitParams(vr, r0, svr, sr0, chi2x, xdof);
00439     m_Road1->GetSimpleFitParams(vk, k0, svk, sk0, chi2y, ydof);
00440     m_Road0->GetPosSigma(spos0);
00441     m_Road1->GetPosSigma(spos1);
00442     
00443     TransformPhiRToXY(vk,  vr,  k0,  r0, vx,  vy,  x0,  y0);
00444     //TransformPhiRToXY(svk, svr, sk0, sr0, svx, svy, sx0, sy0);
00445     TransformPhiRToXY(vk+svk, vr+svr, k0+sk0, r0+sr0, svx, svy, sx0, sy0);
00446     svx -= vx; svy -= vy; sx0 -= x0; sy0 -= y0;
00447   }
00448   else {
00449     m_Road0->GetSimpleFitParams(vy, y0, svy, sy0, chi2y, ydof);
00450     m_Road1->GetSimpleFitParams(vx, x0, svx, sx0, chi2x, xdof);
00451     m_Road0->GetPosSigma(spos0);
00452     m_Road1->GetPosSigma(spos1);
00453         
00454   }
00455 
00456 /*    
00457   cout << " vr " << vr << " vk " << vk << endl;
00458   cout << " r0 " << r0 << " k0 " << k0 << endl;
00459   cout << " vx " << vx << " vy " << vy << endl;
00460   cout << " x0 " << x0 << " y0 " << y0 << endl;
00461 */  
00462 
00463   MucGeoGeneral::Instance()->FindIntersection(m_Part, m_Seg, gap,
00464                                               vx,  vy,  1.0, x0,  y0,  0.0,
00465                                               svx, svy, 0.0, sx0, sy0, 0.0,
00466                                               x, y, z,
00467                                               sigmaX, sigmaY, sigmaZ);
00468 /*
00469   if(fabs(vr)>10000)  ///////////////////if fabs(vr) too big, r0 will be intersection in x coordinate!!!
00470     MucGeoGeneral::Instance()->FindIntersection(m_Part, m_Seg, gap,
00471         vx,  vy,  1.0, x0,  y0,  r0,
00472         svx, svy, 0.0, sx0, sy0, 0.0,
00473         x, y, z,
00474         sigmaX, sigmaY, sigmaZ);
00475 */
00476 
00477   sigmaX = spos1;
00478   sigmaY = spos0;
00479   sigmaZ = 0.0;
00480 
00481   float a, b, c;
00482   float sa, sb, sc; int whichhalf;
00483   //cout<<"in MucRec3DRoad xyz form linefit "<<x<<" "<<y<<" "<<z<<endl;
00484 
00485   if( m_Part == 1 ) {
00486     m_Road1->GetSimpleFitParams(a, b, c, whichhalf, sa, sb, sc, chi2x, ydof);
00487     //cout<<"in MucRec3DRoad "<<vy<<" "<<y0<<" "<<a<<" "<<b<<" "<<c<<endl;
00488   }
00489 
00490   return;
00491 }
00492 
00493 // Where does the trajectory of this road intersect a specific gap?
00494 void
00495 MucRec3DRoad::ProjectNoCurrentGap(const int& gap, float& x, float& y, float& z, float& sigmaX, float& sigmaY, float& sigmaZ,
00496                                   float& quad_x1, float& quad_y1, float& quad_z1, float& quad_x2, float& quad_y2, float& quad_z2)
00497 {
00498 
00499   x = 0.0; sigmaX = 0.0;
00500   y = 0.0; sigmaY = 0.0;
00501   z = 0.0; sigmaZ = 0.0;
00502 
00503   if ( (gap < 0) || (gap >= (int)MucID::getGapMax()) ) {
00504     cout << "MucRec3DRoad::Project-E1  invalid gap = " << gap << endl;
00505     return;
00506   }
00507 
00508   float vx,  vy,  vk,  vr;
00509   float x0,  y0,  k0,  r0;
00510   float svx, svy, svk, svr;
00511   float sx0, sy0, sk0, sr0;
00512   int   xdof, ydof;
00513   float chi2x, chi2y;
00514   float spos0, spos1;
00515 
00516   // Determine the projection point of the "simple" fit to the desired gap.
00517   
00518   // now these 2 2D road have been refit without current gap!
00519   if( m_Part == 1 ) {
00520     m_Road0->SimpleFitNoCurrentGap(gap, vr, r0, svr, sr0, chi2x, xdof);
00521     m_Road1->SimpleFitNoCurrentGap(gap, vk, k0, svk, sk0, chi2y, ydof);
00522 
00523     m_Road0->GetPosSigma(spos0);
00524     m_Road1->GetPosSigma(spos1);
00525     
00526     TransformPhiRToXY(vk,  vr,  k0,  r0, vx,  vy,  x0,  y0);
00527     
00528     //TransformPhiRToXY(svk, svr, sk0, sr0, svx, svy, sx0, sy0);
00529     TransformPhiRToXY(vk+svk, vr+svr, k0+sk0, r0+sr0, svx, svy, sx0, sy0);
00530     svx -= vx; svy -= vy; sx0 -= x0; sy0 -= y0;
00531   } 
00532   else {
00533     m_Road0->SimpleFitNoCurrentGap(gap, vy, y0, svy, sy0, chi2y, ydof);
00534     m_Road1->SimpleFitNoCurrentGap(gap, vx, x0, svx, sx0, chi2x, xdof);
00535     m_Road0->GetPosSigma(spos0);
00536     m_Road1->GetPosSigma(spos1);
00537         
00538   } 
00539   /*  
00540   cout << " vr " << vr << " vk " << vk << endl;
00541   cout << " r0 " << r0 << " k0 " << k0 << endl;
00542   cout << " vx " << vx << " vy " << vy << endl;
00543   cout << " x0 " << x0 << " y0 " << y0 << endl;
00544   */
00545 
00546   MucGeoGeneral::Instance()->FindIntersection(m_Part, m_Seg, gap,
00547                 vx,  vy,  1.0, x0,  y0,  0.0,
00548                 svx, svy, 0.0, sx0, sy0, 0.0,
00549                 x, y, z,  
00550                 sigmaX, sigmaY, sigmaZ); 
00551   if(fabs(vr)>10000)  
00552     MucGeoGeneral::Instance()->FindIntersection(m_Part, m_Seg, gap,
00553         vx,  vy,  1.0, x0,  y0,  r0,
00554         svx, svy, 0.0, sx0, sy0, 0.0,
00555         x, y, z,  
00556         sigmaX, sigmaY, sigmaZ); 
00557         
00558   sigmaX = spos1;
00559   sigmaY = spos0;
00560   sigmaZ = 0.0;
00561 
00562   float a, b, c;
00563   float sa, sb, sc; int whichhalf;
00564 
00565   //calc orient now
00566   int orient = 0;
00567   if(m_Part == 1 && gap%2 == 0) orient = 1;
00568   if(m_Part != 1 && gap%2 == 1) orient = 1;
00569 
00570   if(orient == 0) m_Road0->GetSimpleFitParams(a, b, c, whichhalf, sa, sb, sc, chi2x, ydof);
00571   else            m_Road1->GetSimpleFitParams(a, b, c, whichhalf, sa, sb, sc, chi2x, ydof);
00572 
00573   //cout<<"orient = "<<orient<<"  abc: "<<a<<" "<<b<<" "<<c<<endl;
00574   quad_x1 = -9999; quad_y1 = -9999; quad_z1 = -9999; quad_x2 = -9999; quad_y2 = -9999; quad_z2 = -9999; 
00575 
00576   if(orient == 0 && m_Road0->GetQuadFitOk()  ||  orient == 1 && m_Road1->GetQuadFitOk() )
00577   MucGeoGeneral::Instance()->FindIntersectionQuadLocal(m_Part, m_Seg, gap,
00578         a, b, c, whichhalf, quad_x1, quad_y1, quad_z1, quad_x2, quad_y2, quad_z2, sigmaX, sigmaY, sigmaZ);
00579 
00580   return;
00581 }
00582 
00583 void
00584 MucRec3DRoad::Project(const int &gap, const float vx, const float x0,const float vy,const float y0 , float &x, float &y, float &z)
00585 {
00586   float svx=0, svy=0, sx0=0, sy0=0;
00587   float sigmaX,sigmaY,sigmaZ;
00588   MucGeoGeneral::Instance()->FindIntersection(m_Part, m_Seg, gap,
00589                 vx,  vy,  1.0, x0,  y0,  0.0,
00590                 svx, svy, 0.0, sx0, sy0, 0.0,
00591                 x, y, z,
00592                 sigmaX, sigmaY, sigmaZ);
00593 }
00594 
00595 // Where does the trajectory of this road intersect two surface of a specific gap?
00596 // a line or a parabola!
00597 void
00598 MucRec3DRoad::Project(const int& gap, float& x1, float& y1, float& z1, float& x2, float& y2, float& z2) //x1: inner; x2: outer
00599 {
00600   float sigmaX1, sigmaY1, sigmaZ1;
00601   float sigmaX2, sigmaY2, sigmaZ2;
00602 
00603   x1 = 0.0; sigmaX1 = 0.0;
00604   y1 = 0.0; sigmaY1 = 0.0;
00605   z1 = 0.0; sigmaZ1 = 0.0;
00606   x2 = 0.0; sigmaX2 = 0.0;
00607   y2 = 0.0; sigmaY2 = 0.0;
00608   z2 = 0.0; sigmaZ2 = 0.0;
00609 
00610   if ( (gap < 0) || (gap >= (int)MucID::getGapMax()) ) {
00611     cout << "MucRec3DRoad::Project-E1  invalid gap = " << gap << endl;
00612     return;
00613   }
00614 
00615   float vx,  vy,  vk,  vr;
00616   float x0,  y0,  k0,  r0;
00617   float svx, svy, svk, svr;
00618   float sx0, sy0, sk0, sr0;
00619   int   xdof, ydof;
00620   float chi2x, chi2y;
00621 
00622   // Determine the projection point of the "simple" fit to the desired gap.
00623 
00624   if( m_Part == 1 ) {
00625     m_Road0->GetSimpleFitParams(vr, r0, svr, sr0, chi2x, xdof);
00626     m_Road1->GetSimpleFitParams(vk, k0, svk, sk0, chi2y, ydof);
00627     TransformPhiRToXY(vk,  vr,  k0,  r0, 
00628                       vx,  vy,  x0,  y0);
00629 
00630     //cout<<"in MucRec3DRoad after vx,vy"<<endl;
00631     TransformPhiRToXY(svk, svr, sk0, sr0,
00632                       svx, svy, sx0, sy0);
00633   }
00634   else {
00635     m_Road0->GetSimpleFitParams(vy, y0, svy, sy0, chi2y, ydof);
00636     m_Road1->GetSimpleFitParams(vx, x0, svx, sx0, chi2x, xdof);
00637   }
00638   /*  
00639   cout << " vr " << vr << " vk " << vk << endl;
00640   cout << " r0 " << r0 << " k0 " << k0 << endl;
00641   cout << " vx " << vx << " vy " << vy << endl;
00642   cout << " x0 " << x0 << " y0 " << y0 << endl;
00643   */
00644 
00645   MucGeoGeneral::Instance()->FindIntersectionSurface(m_Part, m_Seg, gap,
00646                                                      vx,  vy,  1.0, x0,  y0,  0.0,
00647                                                      svx, svy, 0.0, sx0, sy0, 0.0,
00648                                                      x1, y1, z1, x2, y2, z2,
00649                                                      sigmaX1, sigmaY1, sigmaZ1,
00650                                                      sigmaX2, sigmaY2, sigmaZ2);
00651 
00652   float a, b, c;
00653   float sa, sb, sc; int whichhalf;
00654   //cout<<"in MucRec3DRoad xyz form linefit "<<x1<<" "<<y1<<" "<<z1<<" "<<x2<<" "<<y2<<" "<<z2<<endl;
00655 
00656   //if this trajectory is parabola!
00657   int projectwithquad = 0;
00658   if( m_Part == 1 && projectwithquad) {
00659     m_Road1->GetSimpleFitParams(a, b, c, whichhalf, sa, sb, sc, chi2x, ydof);
00660 
00661     //cout<<"in MucRec3DRoad "<<vy<<" "<<y0<<" "<<a<<" "<<b<<" "<<c<<endl;
00662     if(m_Road1->GetQuadFitOk()){
00663       MucGeoGeneral::Instance()->FindIntersectionSurface(m_Part, m_Seg, gap,
00664                                                          vy,  x0,  y0,  0.0,
00665                                                          a, b, c,  //y = a*x*x + b*x +c
00666                                                          whichhalf,
00667                                                          svx, svy, 0.0, sx0, sy0, 0.0,
00668                                                          x1, y1, z1, x2, y2, z2,
00669                                                          sigmaX1, sigmaY1, sigmaZ1);
00670     }
00671 
00672   }
00673 
00674   return;
00675 }
00676 
00677 // get a pointer to the 2D road in the 3D road
00678 MucRec2DRoad* 
00679 MucRec3DRoad::Get2DRoad(const int& orient) const
00680 {
00681   if (orient == 0) {
00682     return m_Road0;
00683   }
00684   else {
00685     return m_Road1;
00686   }
00687 }
00688 
00689 // Get indices of all hits in the road.
00690 vector<Identifier>
00691 MucRec3DRoad::GetHitsID() const
00692   
00693 {
00694   vector<Identifier> idCon;
00695   vector<Identifier>::iterator hit;
00696   vector<Identifier> hitRoad0 = m_Road0->GetHitsID();
00697   vector<Identifier> hitRoad1 = m_Road1->GetHitsID();
00698 
00699   // List will be ordered by orientation.
00700 
00701   // Road0 first ...
00702   for ( hit = hitRoad0.begin(); hit != hitRoad0.end(); hit++) {
00703     int index = *hit;
00704     idCon.push_back(*hit);
00705     //cout << " MucRec3DRoad::HitIndices Road0 = " << index << endl;
00706   }
00707   
00708   // ... then Road1.
00709   for ( hit = hitRoad1.begin(); hit != hitRoad1.end();hit++) {
00710     int index = *hit;
00711     idCon.push_back(*hit);
00712     //cout << " MucRec3DRoad::HitIndices Road1 = " << index << endl;
00713   }
00714   
00715   return idCon;
00716 }
00717 
00718 // Transform the Phi, ZR cord. to ZX, ZY cord.
00719 void
00720 MucRec3DRoad::TransformPhiRToXY(const float& vk, const float& vr,
00721                                    const float& k0, const float& r0,
00722                                    float& vx, float& vy, 
00723                                    float& x0, float& y0) const
00724 {
00725   vx = 0.0; vy = 0.0;
00726   x0 = 0.0; y0 = 0.0;
00727 
00728   // cout << vk << "  " << vr << "  " << endl; 
00729 
00730   //float pi  = 3.1415926536;
00731   float phi = 0.25*kPi*m_Seg; 
00732 
00733   // From  y0 = vk * x0 + k0;
00734   //       y0 - r0*sin(phi)
00735   //      ------------------  = tan(phi + 0.5*kPi); 
00736   //       x0 - r0*cos(phi)
00737 
00738   if ( cos(phi) + vk*sin(phi) == 0.0 ) {
00739     cout << " track parallel to gap, some error occurs! " << endl;
00740     // m_Seg = 1, and vk = -1;
00741     //            2,           0;
00742     //            3,           1;
00743     //            5,          -1;
00744     //            6,           0;
00745     //            7,           1;
00746   }
00747   else {
00748     /*
00749     vx = vr / ( cos(phi) + vk*sin(phi) );
00750     vy = vk * vx;
00751     x0 = (r0 - k0)  / ( cos(phi) + vk );
00752     y0 = vk * x0 + k0;
00753     */
00754 
00755     float atan_vk = atan(vk);
00756     if(atan_vk<0) atan_vk += kPi;
00757 
00758     //float deltaPhi = fabs(atan(vk)) - int( fabs(atan(vk))/(0.25*kPi) )*0.25*kPi;
00759     //if (deltaPhi > 0.125*kPi) deltaPhi = 0.25*kPi - delta
00760 
00761     float deltaPhi =  atan_vk - (m_Seg%4)*(0.25*kPi);
00762 
00763     //vx = vr*cos(deltaPhi)*GetVxSign(vk)/sqrt(1.0+vk*vk);  //change to vr/cos()... liangyt 2007.4.10
00764     //I think it should be vr/cos...
00765 
00766     vx = (vr/fabs(cos(deltaPhi)))*GetVxSign(vk)/sqrt(1.0+vk*vk);
00767     vy = vk*vx;
00768     x0 = (r0 - k0*sin(phi)) / (vk*sin(phi) + cos(phi));
00769     y0 = vk * x0 + k0;
00770 
00771     float safe_vr = vr;
00772 
00773     if(fabs(vr)>10000){
00774       if(vr>0) safe_vr = 10000;
00775       else     safe_vr = -10000;
00776       vx = (safe_vr/fabs(cos(deltaPhi)))*GetVxSign(vk)/sqrt(1.0+vk*vk);
00777       vy = vk*vx;
00778       y0 = -vy*r0;
00779       x0 = (y0 - k0)/vk;
00780     }
00781 
00782   }
00783 }
00784 
00785 float
00786 MucRec3DRoad::GetVxSign(const float vk) const
00787 {  
00788   float segmentPhiMin = 0.25*kPi*(m_Seg-2);
00789   float segmentPhiMax = 0.25*kPi*(m_Seg+2);
00790   if (m_Seg > 4) { 
00791     segmentPhiMin -= 2.0*kPi;
00792     segmentPhiMax -= 2.0*kPi;
00793   }
00794   
00795   // vk = tan(theta); theta = atan(vk); -90<theta<90
00796   float theta = atan(vk);
00797   if (theta >= segmentPhiMin && theta <= segmentPhiMax) return 1.0;
00798   else return -1.0;
00799 }
00800 
00801 // Print Hits Infomation.
00802 void
00803 MucRec3DRoad::PrintHitsInfo()
00804 {
00805   m_Road0->PrintHitsInfo();
00806   m_Road1->PrintHitsInfo();
00807 
00808   cout << "Intersection with each gap : " << endl;
00809   for (int iGap = 0; iGap <= m_LastGap; iGap++) {
00810     float x, y, z, sigmaX, sigmaY, sigmaZ;
00811     ProjectWithSigma(iGap, x, y, z, sigmaX, sigmaY, sigmaZ);
00812     cout << "   gap " << iGap 
00813          << " (" << x 
00814          << ", " << y
00815          << ", " << z
00816          << ")"
00817          << endl; 
00818   }
00819 }

Generated on Tue Nov 29 23:12:58 2016 for BOSS_7.0.2 by  doxygen 1.4.7