/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Reconstruction/TrkReco/TrkReco-00-08-59-patch4-slc6tag/src/TTrack.cxx

Go to the documentation of this file.
00001 #define OPTNK
00002 //-----------------------------------------------------------------------------
00003 // $Id: TTrack.cxx,v 1.24.8.1 2012/10/29 03:46:45 xuqn Exp $
00004 //-----------------------------------------------------------------------------
00005 // Filename : TTrack.h
00006 // Section  : Tracking
00007 // Owner    : Yoshi Iwasaki
00008 // Email    : yoshihito.iwasaki@kek.jp
00009 //-----------------------------------------------------------------------------
00010 // Description : A class to represent a track in tracking.
00011 //               See http://bsunsrv1.kek.jp/~yiwasaki/tracking/
00012 //-----------------------------------------------------------------------------
00013 
00014 /* for isnan */
00015 #if defined(__sparc)
00016 #  if defined(__EXTENSIONS__)
00017 #    include <cmath>
00018 #  else
00019 #    define __EXTENSIONS__
00020 #    include <cmath>
00021 #    undef __EXTENSIONS__
00022 #  endif
00023 #elif defined(__GNUC__)
00024 #  if defined(_XOPEN_SOURCE)
00025 #    include <cmath>
00026 #  else
00027 #    define _XOPEN_SOURCE
00028 #    include <cmath>
00029 #    undef _XOPEN_SOURCE
00030 #  endif
00031 #endif
00032 #include <cfloat>
00033 #define HEP_SHORT_NAMES
00034 #include "CLHEP/String/Strings.h"
00035 #include "CLHEP/Matrix/Vector.h"
00036 #include "CLHEP/Matrix/SymMatrix.h"
00037 #include "CLHEP/Matrix/DiagMatrix.h"
00038 #include "CLHEP/Matrix/Matrix.h"
00039 #include "TrkReco/TCircle.h"
00040 #include "TrkReco/TMLine.h"
00041 #include "TrkReco/TMLink.h"
00042 #include "TrkReco/TMDCUtil.h"
00043 #include "TrkReco/TMDCWire.h"
00044 #include "TrkReco/TMDCWireHit.h"
00045 #include "TrkReco/TMDCWireHitMC.h"
00046 //#include "TrkReco/TMDCStrip.h"
00047 #include "TrkReco/TTrack.h"
00048 #include "TrkReco/TSegment.h"
00049 //#include "tables/cdc.h"
00050 //#include "tables/trk.h"
00051 //#include "tables/mdst.h"
00052 //#include "tables/hepevt.h"
00053 #include "MdcTables/MdcTables.h"
00054 #include "MdcTables/TrkTables.h"
00055 #include "MdcTables/MdstTables.h"
00056 #include "MdcTables/HepevtTables.h"
00057 
00058 #include "CLHEP/Matrix/Matrix.h"
00059 #include "GaudiKernel/StatusCode.h"
00060 #include "GaudiKernel/IInterface.h"
00061 #include "GaudiKernel/Kernel.h"
00062 #include "GaudiKernel/Service.h"
00063 #include "GaudiKernel/ISvcLocator.h"
00064 #include "GaudiKernel/SvcFactory.h"
00065 #include "GaudiKernel/IDataProviderSvc.h"
00066 #include "GaudiKernel/Bootstrap.h"
00067 #include "GaudiKernel/MsgStream.h"
00068 #include "GaudiKernel/SmartDataPtr.h"
00069 #include "GaudiKernel/IMessageSvc.h"
00070 
00071 
00072 
00073 using CLHEP::HepVector;
00074 using CLHEP::HepSymMatrix;
00075 using CLHEP::HepDiagMatrix;
00076 using CLHEP::HepMatrix;
00077 
00078 const THelixFitter
00079 TTrack::_fitter = THelixFitter("TTrack Default Helix Fitter");
00080 
00081 TTrack::TTrack(const TCircle & c)
00082 : TTrackBase(c.links()),
00083   _helix(new Helix(ORIGIN, Vector(5, 0), SymMatrix(5, 0))), 
00084   _charge(c.charge()),
00085   _ndf(0),
00086   _chi2(0.),
00087   _name("none"),
00088   _type(0),
00089   _state(0),
00090   _mother(0),
00091   _daughter(0) {
00092 
00093     //jialk
00094     StatusCode scmgn = Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF); 
00095     if(scmgn!=StatusCode::SUCCESS) { 
00096       std::cout<< __FILE__<<" "<<__LINE__<<" Unable to open Magnetic field service"<<std::endl;
00097     }
00098 
00099     //_fitter.setMagneticFieldPointer(m_pmgnIMF);//yzhang add 2012-05-04 
00100     //cout<<"TTrack: "<<m_pmgnIMF->getReferField()<<endl;
00101     //...Set a defualt fitter...
00102     fitter(& TTrack::_fitter);
00103 
00104     //...Calculate helix parameters...
00105     Vector a(5);
00106     a[1] = fmod(atan2(_charge * (c.center().y() - ORIGIN.y()),
00107                       _charge * (c.center().x() - ORIGIN.x()))
00108                 + 4. * M_PI,
00109                 2. * M_PI);
00110    // a[2] = Helix::ConstantAlpha / c.radius();
00111    // a[2] = 333.564095 / c.radius();
00112     const double Bz = -1000*m_pmgnIMF->getReferField();
00113     a[2] = 333.564095/ (c.radius() * Bz);
00114     a[0] = (c.center().x() - ORIGIN.x()) / cos(a[1]) - c.radius();
00115     a[3] = 0.;
00116     a[4] = 0.;
00117     _helix->a(a);
00118 
00119     //...Update links...
00120     unsigned n = _links.length();
00121     for (unsigned i = 0; i < n; i++)
00122         _links[i]->track(this);
00123 
00124     _fitted = false;
00125     _fittedWithCathode = false;
00126 /*
00127     //jialk
00128     StatusCode scmgn = Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF); 
00129     if(scmgn!=StatusCode::SUCCESS) { 
00130       std::cout<< __FILE__<<" "<<__LINE__<<" Unable to open Magnetic field service"<<std::endl;
00131     }
00132 */
00133 }
00134 
00135 TTrack::TTrack(const TTrack & a)
00136 : TTrackBase((TTrackBase &) a),
00137   _charge(a._charge),
00138   _segments(a._segments),
00139   _helix(new Helix(* a._helix)),
00140   _ndf(a._ndf),
00141   _chi2(a._chi2),
00142   _name("copy of " + a._name),
00143   _type(a._type),
00144 //  _catHits(a._catHits),
00145   _state(a._state),
00146   _mother(a._mother),
00147   _daughter(a._daughter) { 
00148   //jialk
00149   StatusCode scmgn = Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF); 
00150   if(scmgn!=StatusCode::SUCCESS) { 
00151     std::cout<< __FILE__<<" "<<__LINE__<<" Unable to open Magnetic field service"<<std::endl;
00152   }
00153 }
00154 
00155 /*TTrack::TTrack(const T3DLine & a)
00156 : TTrackBase((TTrackBase &) a),
00157   _charge(0),
00158   _helix(new Helix(* a.helix())),
00159   _ndf(a.ndf()),
00160   _chi2(a.chi2()),
00161   _name(0),
00162   _type(a.type()),
00163   _state(1),
00164   _mother(0),
00165   _daughter(0) {
00166 }*/
00167 
00168 TTrack::TTrack(const TRunge & a)
00169 : TTrackBase((TTrackBase &) a),
00170   _helix(new Helix( a.helix())),
00171   _ndf(a.ndf()),
00172   _chi2(a.chi2()),
00173   _name("no"),
00174   _type(0),
00175   _state(0),
00176   _mother(0),
00177   _daughter(0) {
00178     if(_helix->kappa() > 0.)_charge = 1.;
00179         else _charge = -1.;
00180 }
00181 TTrack::TTrack(const Helix & h)
00182 : TTrackBase(),
00183   _helix(new Helix(h)), 
00184   _ndf(0),
00185   _chi2(0.),
00186   _name("none"),
00187   _type(0),
00188   _state(0),
00189   _mother(0),
00190   _daughter(0) {
00191 
00192     //...Set a defualt fitter...
00193     fitter(& TTrack::_fitter);
00194 
00195     if(_helix->kappa() > 0.)_charge = 1.;
00196     else _charge = -1.;
00197 
00198     _fitted = false;
00199     _fittedWithCathode = false;
00200     //jialk
00201     StatusCode scmgn = Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF); 
00202     if(scmgn!=StatusCode::SUCCESS) { 
00203       std::cout<< __FILE__<<" "<<__LINE__<<" Unable to open Magnetic field service"<<std::endl;
00204     }
00205 }
00206 
00207 TTrack::TTrack()
00208 : TTrackBase(),
00209   _charge(1.),
00210   _helix(new Helix(ORIGIN, Vector(5, 0), SymMatrix(5, 0))),
00211   _ndf(0),
00212   _chi2(0.),
00213   _name("empty track"),
00214   _state(0),
00215   _mother(0),
00216   _daughter(0) {
00217   //jialk
00218   StatusCode scmgn = Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF); 
00219   if(scmgn!=StatusCode::SUCCESS) { 
00220     std::cout<< __FILE__<<" "<<__LINE__<<" Unable to open Magnetic field service"<<std::endl;
00221   }
00222 }
00223 
00224 TTrack::~TTrack() {
00225     delete _helix;
00226 }
00227 
00228 void
00229 TTrack::dump(const std::string & msg, const std::string & pre0) const {
00230     bool def = false;
00231     if (msg == "") def = true;
00232     std::string pre = pre0;
00233     std::string tab;
00234     for (unsigned i = 0; i < pre.length(); i++)
00235         tab += " ";
00236     if (def || msg.find("track") != std::string::npos || msg.find("detail") != std::string::npos) {
00237         std::cout << pre
00238                   << p() << "(pt=" << pt() << ")" << std::endl
00239                   << tab
00240                   << "links=" << _links.length()
00241                   << "(cores=" << nCores()
00242                   << "),chrg=" << _charge
00243                   << ",ndf=" << _ndf
00244                   << ",chi2=" << _chi2
00245                   << std::endl;
00246         pre = tab;
00247     }
00248     if (msg.find("helix") != std::string::npos || msg.find("detail") != std::string::npos) {
00249         std::cout << pre
00250                   << "pivot=" << _helix->pivot()
00251                   << ",center=" << _helix->center() << std::endl
00252                   << pre
00253                   << "helix=(" << _helix->a()[0] << "," << _helix->a()[1]<< ","
00254                   << _helix->a()[2] << "," << _helix->a()[3] << ","
00255                   << _helix->a()[4] << ")" << std::endl;
00256         pre = tab;
00257     }
00258     if (! def) TTrackBase::dump(msg, pre);
00259 }
00260 
00261 void
00262 TTrack::movePivot(void) {
00263      unsigned n = _links.length();
00264     if (! n) {
00265         std::cout << "TTrack::movePivot !!! can't move a pivot"
00266                   << " because of no link";
00267         std::cout << std::endl;
00268         return;
00269     }
00270 
00271     //...Check cores...
00272      const AList<TMLink> & cores = TTrackBase::cores();
00273     const AList<TMLink> * links = & cores;
00274     if (cores.length() == 0) links = & _links;
00275 
00276     //...Hit loop...
00277     unsigned innerMost = 0;
00278     unsigned innerMostLayer = (* links)[0]->wire()->layerId();
00279     n = links->length();
00280     for (unsigned i = 1; i < n; i++) {
00281         TMLink * l = (* links)[i];
00282         if (l->wire()->layerId() < innerMostLayer) {
00283             innerMost = i;
00284             innerMostLayer = l->wire()->layerId();
00285         }
00286     }
00287 
00288     //...Move pivot...
00289     HepPoint3D newPivot = (* links)[innerMost]->positionOnWire();
00290     if (quality() & TrackQuality2D)
00291         newPivot.setZ(0.);
00292     _helix->pivot(newPivot);
00293 }
00294 
00295 int 
00296 TTrack::approach(TMLink & l) const {
00297     return approach(l, false);
00298 }
00299 
00300 void
00301 TTrack::refine2D(AList<TMLink> & list, float maxSigma) {
00302     unsigned n = _links.length();
00303     AList<TMLink> bad;
00304     for (unsigned i = 0; i < n; ++i) {
00305         if (_links[i]->pull() > maxSigma) bad.append(_links[i]);
00306     }
00307     _links.remove(bad);
00308     if (bad.length()){
00309       _fitted = false;
00310       fit2D();
00311     }
00312     list.append(bad);
00313 }
00314 
00315 int
00316 TTrack::HelCyl(double rhole,
00317                double rCyl, 
00318                double zb,
00319                double zf,
00320                double epsl,
00321                double & phi,
00322                HepPoint3D & xp ) const {
00323 
00324 
00325   int status(0);        // return value
00326   //---------------------------------------------------------------------
00327   //  value     | ext |   status 
00328   //---------------------------------------------------------------------
00329   //     1.     |  OK |
00330   //    -1.     |  NO |  charge = 0
00331   //     0.     |  NO |  | tanl | < 0.1  ( neglect | lamda | < 5.7 deg. )
00332   //            |     |  or | dPhi | > 2 pi ( neglect curly track )
00333   //            |     |  or cannot reach to r=rhole at z = zb or zf.
00334   //     2.     |  OK |   backward , ext point set on z = zb
00335   //     3.     |  OK |   forward  , ext point set on z = zf
00336   //---------------------------------------------------------------------
00337   // * when value = 0,2,3 , ext(z) <= zb  or ext(z) >= zf
00338 
00339   //--- debug
00340   //  std::cout << "   "  << std::endl;
00341   //  std::cout << "HelCyl called ..  rhole=" << rhole << " rCyl=" << rCyl ; 
00342   //  std::cout << " zb=" << zb << " zf=" << zf << " epsl=" << epsl << std::endl;
00343   //--- debug end
00344 
00345   // Check of Charge
00346 
00347   if ( int(_charge) == 0 ) {
00348     std::cout << "HelCyl gets a straight line !!" << std::endl;
00349     return -1 ;
00350   }
00351 
00352   // parameters
00353 
00354   HepPoint3D CenterCyl( 0., 0., 0. );
00355   HepPoint3D CenterTrk = _helix->center();
00356   double  rTrk = fabs( _helix->radius() );
00357 
00358   double rPivot = fabs( _helix->pivot().perp() );
00359 
00360   double phi0 = _helix->a()[1];
00361   double tanl = _helix->a()[4];
00362   //  double zdz = _helix->pivot().z() + _helix->a()[3];
00363   double dPhi;
00364   double zee;
00365 
00366 
00367   // Calculate intersections between cylinder and track
00368   // if return value = 2 track hitting barrel part
00369 
00370   HepPoint3D Cross1, Cross2;
00371 
00372   if (intersection( CenterTrk,_charge * rTrk ,CenterCyl,rCyl,
00373                    epsl, 
00374                    Cross1,Cross2)
00375       == 2 ) {
00376 
00377     double phiCyl = atan2( _charge * ( CenterTrk.y() - Cross1.y() ),
00378                            _charge * ( CenterTrk.x() - Cross1.x() ) );
00379     phiCyl = ( phiCyl > 0. ) ? phiCyl : phiCyl + 2. * M_PI;
00380 
00381     dPhi = phiCyl - phi0;
00382 
00383     // dPhi region ( at cylinder )
00384     //          -pi <= dPhi < pi
00385 
00386 
00387     double PhiYobun = 1./ fabs( _helix->radius() );
00388     double zero = 0.00001;
00389 
00390     if( _charge >=0. ){
00391       if( dPhi > PhiYobun ) dPhi -= 2. * M_PI;
00392       if( -2. * M_PI  - zero <= dPhi <= ( -2.* M_PI + PhiYobun ) ) 
00393         dPhi += 2. * M_PI;
00394     }
00395 
00396     if( _charge < 0. ){
00397       if( dPhi < -PhiYobun ) dPhi += 2. * M_PI;
00398       if( 2. * M_PI + zero >= dPhi >= ( 2. * M_PI - PhiYobun ) )
00399         dPhi -= 2. * M_PI;
00400     }
00401 
00402     if( dPhi < - M_PI ) dPhi += 2. * M_PI;
00403     if( dPhi >= M_PI ) dPhi -= 2. * M_PI;
00404 
00405       //--debug 
00406       //  std::cout << "dPhi = " << dPhi << std::endl;
00407       //--debug end 
00408 
00409     xp.setX( Cross1.x() );
00410     xp.setY( Cross1.y() );
00411     xp.setZ( _helix->x(dPhi).z() );
00412     //    xp.setZ( zdz - _charge * rTrk * tanl * dPhi );
00413 
00414     if ( xp.z() > zb && xp.z() < zf ) {
00415       phi = dPhi;
00416  //--- debug ---
00417  //      std::cout << "return1 ( ext success )" <<  std::endl;
00418  //      std::cout << " xp:= " << xp.x() << ", " << xp.y() << ", " << xp.z() << std::endl;
00419   //--- debug  ----
00420       return 1 ;
00421     }
00422   }
00423 
00424 
00425   // tracks hitting endcaps
00426 
00427   if ( fabs(tanl) < 0.1 ) {
00428     //--- debug ---
00429     //    std::cout << "return0 ( ext failed , |tanl| < 0.1 )" <<  std::endl;
00430     //    std::cout << " xp:= " << xp.x() << ", " << xp.y() << ", " << xp.z() << std::endl;
00431     //--- debug ---
00432     return 0;
00433   }
00434 
00435   if ( tanl > 0. ) {
00436     zee = zf ;
00437     status = 3 ;
00438   } 
00439   else {
00440     zee = zb ;
00441     status = 2 ;
00442   }
00443 
00444   dPhi = _charge * ( _helix->x(0.).z() - zee )/rTrk/tanl;
00445   //  dPhi = _charge * ( zdz - zee )/rTrk/tanl;
00446 
00447   // Requre dPhi < 2*pi 
00448 
00449   if ( fabs(dPhi) > 2. * M_PI ) {
00450     //--- debug ---
00451     //    std::cout << " return0 ( ext failed , dPhi > 2pi )" << std::endl;
00452     //    std::cout << " xp:= " << xp.x() << ", " << xp.y() << ", " << xp.z() << std::endl;
00453     //--- debug  ---
00454     return 0 ;
00455   }
00456 
00457   xp.setX( _helix->x(dPhi).x() );
00458   xp.setY( _helix->x(dPhi).y() );
00459   xp.setZ( zee );
00460 
00461   double test = xp.perp2()  - rhole*rhole ;
00462   if ( test < 0. )  {
00463     //--- debug ---
00464     //    std::cout << "return0 ( cannot reach to rhole at z=edge )" << std::endl;
00465     //    std::cout << " xp:= " << xp.x() << ", " << xp.y() << ", " << xp.z() << std::endl;
00466     //--- debug ---
00467     return 0 ;
00468   }
00469 
00470   phi = dPhi ;
00471   //--- debug ---
00472   //  std::cout << "return" << status << std::endl;
00473   //  std::cout << " xp:= " << xp.x() << ", " << xp.y() << ", " << xp.z() << std::endl;
00474   //--- debug ---
00475 
00476   return status ;
00477 
00478 }
00479 
00480 /*
00481 void
00482 TTrack::findCatHit(unsigned trackid) {
00483 
00484   unsigned i = 0;
00485   //  while ( TMDC01CatHit * chit = _cathits.last() ) {
00486   //    _cathits.remove(chit);
00487   //    delete chit;
00488   //  }
00489 
00490   //--- debug ---
00491   //std::cout << std::endl << "FindCatHit  called !! " << std::endl << std::endl;
00492   //--- debug end ----
00493 
00494   // set cylinder geometry
00495   double rcyl[3];
00496   rcyl[0] = 8.80 ;
00497   rcyl[1] = 9.80 ;
00498   rcyl[2] = 10.85 ;
00499   double rhole = 8.00 ;
00500   double zb = -26.17 ;
00501   double zf =  45.87 ;
00502   double epsl = 0.01 ;
00503 
00504   // 
00505   HepPoint3D xp ;
00506   double phi ;
00507   TMDCCatHit * chit;
00508 
00509   // loop over layers and find cathits 
00510   
00511   for ( unsigned layer = 0 ; layer < 3 ; layer++ ) {
00512     if ( HelCyl (rhole, rcyl[layer], zb,zf,epsl, phi, xp ) == 1 ) {
00513       chit = new TMDCCatHit( this, trackid, layer, xp.x(), xp.y(), xp.z()) ;
00514       _catHits.append(chit); 
00515     }
00516   }
00517 
00518   //--- debug ---
00519   //if(_cathits.length()) {
00520   //  std::cout << std::endl;
00521   //  for ( int j = 0 ; j < _cathits.length() ; j++ ) {
00522   //    _cathits[j]->dump(" ", " ") ;
00523   //  }
00524   //}
00525   // chit->dump(" ", " ") ;
00526   //--- debug end ----
00527 
00528 }
00529 //--- Nagoya mods. 19981225 end ---------------------------
00530 
00531 
00532 //  int
00533 //  TTrack::fitx(void) {
00534 
00535 //  #ifdef TRKRECO_DEBUG_DETAIL
00536 //      std::cout << "TTrack::fit !!! This is obsolete !!!" << std::endl;
00537 //  #endif
00538 //      if (_fitted) return 0;
00539 
00540 //      //...Check # of hits...
00541 //      if (_links.length() < 5) return -1;
00542 
00543 //      //...Setup...
00544 //      unsigned nTrial = 0;
00545 //      Vector a(5), da(5);
00546 //      a = _helix->a();
00547 //      Vector dxda(5);
00548 //      Vector dyda(5);
00549 //      Vector dzda(5);
00550 //      Vector dDda(5);
00551 //      Vector dchi2da(5);
00552 //      SymMatrix d2chi2d2a(5, 0);
00553 //      double chi2;
00554 //      double chi2Old = 10e99;
00555 //      const double convergence = 1.0e-5;
00556 //      bool allAxial = true;
00557 //      Matrix e(3, 3);
00558 //      Vector f(3);
00559 //      int err = 0;
00560 //      double factor = 1.0;//jtanaka0715
00561 
00562 //      Vector maxDouble(5);
00563 //      for (unsigned i = 0; i < 5; i++) maxDouble[i] = (FLT_MAX);
00564 
00565 //      //...Fitting loop...
00566 //      while (nTrial < 100) {
00567 
00568 //      //...Set up...
00569 //      chi2 = 0.;
00570 //      for (unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
00571 //      d2chi2d2a = SymMatrix(5, 0);
00572 
00573 //      //...Loop with hits...
00574 //      unsigned i = 0;
00575 //      while (TMLink * l = _links[i++]) {
00576 //          const TMDCWireHit & h = * l->hit();
00577 
00578 //          //...Check state...
00579 //          if (h.state() & WireHitInvalidForFit) continue;
00580 
00581 //          //...Check wire...
00582 //          if (! nTrial)
00583 //              if (h.wire()->stereo()) allAxial = false;
00584 
00585 //          //...Cal. closest points...
00586 //          approach(* l);
00587 //          double dPhi = l->dPhi();
00588 //          const HepPoint3D & onTrack = l->positionOnTrack();
00589 //          const HepPoint3D & onWire = l->positionOnWire();
00590 
00591 //  #ifdef TRKRECO_DEBUG_DETAIL
00592 //  //      std::cout << "    in fit " << onTrack << ", " << onWire;
00593 //  //      h.dump();
00594 //  #endif          
00595 
00596 //          //...Obtain drift distance and its error...
00597 //          unsigned leftRight = WireHitRight;
00598 //          if (onWire.cross(onTrack).z() < 0.) leftRight = WireHitLeft;
00599 //          double distance = h.distance(leftRight);
00600 //          double eDistance = h.dDistance(leftRight);
00601 //          double eDistance2 = eDistance * eDistance;
00602 
00603 //          //...Residual...
00604 //          HepVector3D v = onTrack - onWire;
00605 //          double vmag = v.mag();
00606 //          double dDistance = vmag - distance;
00607 
00608 //          //...dxda...
00609 //          this->dxda(* l, dPhi, dxda, dyda, dzda);
00610 
00611 //          //...Chi2 related...
00612 //          // dDda = (v.x() * dxda + v.y() * dyda + v.z() * dzda) / vmag;
00613 //          Vector3 vw = h.wire()->direction();
00614 //              dDda = (vmag > 0.)
00615 //              ? ((v.x() * (1. - vw.x() * vw.x()) -
00616 //                  v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
00617 //                 * dxda + 
00618 //                 (v.y() * (1. - vw.y() * vw.y()) -
00619 //                  v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
00620 //                 * dyda + 
00621 //                 (v.z() * (1. - vw.z() * vw.z()) -
00622 //                  v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
00623 //                 * dzda) / vmag
00624 //              : Vector(5,0);
00625 //          if(vmag<=0.0) {
00626 //            std::cout << "    in fit " << onTrack << ", " << onWire;
00627 //            h.dump();
00628 //          }
00629 //          dchi2da += (dDistance / eDistance2) * dDda;
00630 //          d2chi2d2a += vT_times_v(dDda) / eDistance2;
00631 //          double pChi2 = dDistance * dDistance / eDistance2;
00632 //          chi2 += pChi2;
00633 
00634 //          //...Store results...
00635 //          l->update(onTrack, onWire, leftRight, pChi2);
00636 //      }
00637 
00638 //      //...Check condition...
00639 //      double change = chi2Old - chi2;
00640 //      if (fabs(change) < convergence) break;
00641 //      //if (change < 0.) break;
00642 //      //jtanaka -- from traffs -- Ozaki-san added this part to traffs.        
00643 //      if (change < 0.){
00644 //  #ifdef TRKRECO_DEBUG_DETAIL
00645 //            std::cout << "chi2Old, chi2=" << chi2Old <<" "<< chi2 << std::endl;
00646 //  #endif
00647 //        //change to the old value.
00648 //            a += factor*da;
00649 //            _helix->a(a);
00650 
00651 //            chi2 = 0.;
00652 //            for (unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
00653 //            d2chi2d2a = SymMatrix(5, 0);
00654           
00655 //            //...Loop with hits...
00656 //            unsigned i = 0;
00657 //            while (TMLink * l = _links[i++]) {
00658 //            const TMDCWireHit & h = * l->hit();
00659             
00660 //              //...Check wire...
00661 //              if (! nTrial)
00662 //                if (h.wire()->stereo()) allAxial = false;
00663             
00664 //              //...Cal. closest points...
00665 //              approach(* l);
00666 //              double dPhi = l->dPhi();
00667 //              const HepPoint3D & onTrack = l->positionOnTrack();
00668 //              const HepPoint3D & onWire = l->positionOnWire();
00669             
00670 //  #ifdef TRKRECO_DEBUG_DETAIL
00671 //              // std::cout << "    in fit in case of change < 0. " << onTrack << ", " << onWire;
00672 //              // h.dump();
00673 //  #endif      
00674             
00675 //              //...Obtain drift distance and its error...
00676 //              unsigned leftRight = WireHitRight;
00677 //              if (onWire.cross(onTrack).z() < 0.) leftRight = WireHitLeft;
00678 //              double distance = h.distance(leftRight);
00679 //              double eDistance = h.dDistance(leftRight);
00680 //              double eDistance2 = eDistance * eDistance;
00681             
00682 //              //...Residual...
00683 //              HepVector3D v = onTrack - onWire;
00684 //          double vmag = v.mag();
00685 //          double dDistance = vmag - distance;
00686             
00687 //              //...dxda...
00688 //              this->dxda(* l, dPhi, dxda, dyda, dzda);
00689             
00690 //              //...Chi2 related...
00691 //              //dDda = (v.x() * dxda + v.y() * dyda + v.z() * dzda) / vmag;
00692 //              Vector3 vw = h.wire()->direction();
00693 //              dDda = (vmag > 0.)
00694 //              ? ((v.x() * (1. - vw.x() * vw.x()) -
00695 //                  v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
00696 //                 * dxda + 
00697 //                 (v.y() * (1. - vw.y() * vw.y()) -
00698 //                  v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
00699 //                 * dyda + 
00700 //                 (v.z() * (1. - vw.z() * vw.z()) -
00701 //                  v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
00702 //                 * dzda) / vmag
00703 //              : Vector(5,0);
00704 //          if(vmag<=0.0) {
00705 //            std::cout << "    in fit " << onTrack << ", " << onWire;
00706 //            h.dump();
00707 //          }
00708 //              dchi2da += (dDistance / eDistance2) * dDda;
00709 //              d2chi2d2a += vT_times_v(dDda) / eDistance2;
00710 //              double pChi2 = dDistance * dDistance / eDistance2;
00711 //              chi2 += pChi2;
00712             
00713 //              //...Store results...
00714 //              l->update(onTrack, onWire, leftRight, pChi2);
00715 //            }
00716 //        //break;
00717 //        factor *= 0.75;
00718 //  #ifdef TRKRECO_DEBUG_DETAIL 
00719 //        std::cout << "factor = " << factor << std::endl;
00720 //        std::cout << "chi2 = " << chi2 << std::endl;
00721 //  #endif
00722 //        if(factor < 0.01)break;
00723 //          }
00724 
00725 //      chi2Old = chi2;
00726 
00727 //      //...Cal. helix parameters for next loop...
00728 //      if (allAxial) {
00729 //          f = dchi2da.sub(1, 3);
00730 //          e = d2chi2d2a.sub(1, 3);
00731 //          f = solve(e, f);
00732 //          da[0] = f[0];
00733 //          da[1] = f[1];
00734 //          da[2] = f[2];
00735 //          da[3] = 0.;
00736 //          da[4] = 0.;
00737 //      }
00738 //      else {
00739 //          da = solve(d2chi2d2a, dchi2da);
00740 //      }
00741 
00742 //  #ifdef TRKRECO_DEBUG_DETAIL
00743 //      //std::cout << "    fit " << nTrial << " : " << da << std::endl;
00744 //      //std::cout << "        d2chi " << d2chi2d2a << std::endl;
00745 //      //std::cout << "        dchi2 " << dchi2da << std::endl;
00746 //  #endif          
00747 
00748 //      a -= factor*da;
00749 //      _helix->a(a);
00750 //      ++nTrial;
00751 //      }
00752 
00753 //      //...Cal. error matrix...
00754 //      SymMatrix Ea(5, 0);
00755 //      unsigned dim;
00756 //      if (allAxial) {
00757 //      dim = 3;
00758 //      SymMatrix Eb(3, 0), Ec(3, 0);
00759 //      Eb = d2chi2d2a.sub(1, 3);
00760 //      Ec = Eb.inverse(err);
00761 //      Ea[0][0] = Ec[0][0];
00762 //      Ea[0][1] = Ec[0][1];
00763 //      Ea[0][2] = Ec[0][2];
00764 //      Ea[1][1] = Ec[1][1];
00765 //      Ea[1][2] = Ec[1][2];
00766 //      Ea[2][2] = Ec[2][2];
00767 //      }
00768 //      else {
00769 //      dim = 5;
00770 //      Ea = d2chi2d2a.inverse(err);
00771 //      }
00772 
00773 //      //...Store information...
00774 //      if (! err) {
00775 //      _helix->a(a);
00776 //      _helix->Ea(Ea);
00777 //      }
00778     
00779 //      _ndf = _links.length() - dim;
00780 //      _chi2 = chi2;
00781     
00782 //      _fitted = true;
00783 //      return err;
00784 //  }
00785 
00786 */
00787 
00788 int
00789 TTrack::dxda(const TMLink & link,
00790              double dPhi,
00791              Vector & dxda,
00792              Vector & dyda,
00793              Vector & dzda) const {
00794 
00795     //...Setup...
00796     const TMDCWire & w = * link.wire();
00797     Vector a = _helix->a();
00798     double dRho  = a[0];
00799     double phi0  = a[1];
00800     double kappa = a[2];
00801    // double rho   = Helix::ConstantAlpha / kappa;
00802    // double rho   = 333.564095 / kappa;
00803     const double Bz = -1000*m_pmgnIMF->getReferField();
00804     double rho   = 333.564095/(kappa * Bz); 
00805     double tanLambda = a[4];
00806 
00807     double sinPhi0 = sin(phi0);
00808     double cosPhi0 = cos(phi0);
00809     double sinPhi0dPhi = sin(phi0 + dPhi);
00810     double cosPhi0dPhi = cos(phi0 + dPhi);
00811     Vector dphida(5);
00812 
00813 //yzhang 2012-08-30
00814     //...Axial case...
00815 //    if (w.axial()) {
00816 //      HepPoint3D d = _helix->center() - w.xyPosition();
00817 //      double dmag2 = d.mag2();
00818 //
00819 //      dphida[0] = (sinPhi0 * d.x() - cosPhi0 * d.y()) / dmag2;
00820 //      dphida[1] = (dRho + rho)    * (cosPhi0 * d.x() + sinPhi0 * d.y())
00821 //          / dmag2 - 1.;
00822 //      dphida[2] = (- rho / kappa) * (sinPhi0 * d.x() - cosPhi0 * d.y())
00823 //          / dmag2;
00824 //      dphida[3] = 0.;
00825 //      dphida[4] = 0.;
00826 //    }
00827 //
00828 //    //...Stereo case...
00829 //    else {
00830         HepPoint3D onTrack = _helix->x(dPhi);
00831         HepVector3D v = w.direction();
00832         Vector c(3);
00833         c = HepPoint3D(w.backwardPosition() - (v * w.backwardPosition()) * v);
00834 
00835         Vector x(3);
00836         x = onTrack;
00837 
00838         Vector dxdphi(3);
00839         dxdphi[0] =   rho * sinPhi0dPhi;
00840         dxdphi[1] = - rho * cosPhi0dPhi;
00841         dxdphi[2] = - rho * tanLambda;
00842 
00843         Vector d2xdphi2(3);
00844         d2xdphi2[0] = rho * cosPhi0dPhi;
00845         d2xdphi2[1] = rho * sinPhi0dPhi;
00846         d2xdphi2[2] = 0.;
00847 
00848         double dxdphi_dot_v = dxdphi[0]*v.x() + dxdphi[1]*v.y() + dxdphi[2]*v.z();
00849         double x_dot_v      = x[0]*v.x() + x[1]*v.y() + x[2]*v.z();
00850 
00851         double dfdphi = - (dxdphi[0] - dxdphi_dot_v*v.x()) * dxdphi[0] 
00852                         - (dxdphi[1] - dxdphi_dot_v*v.y()) * dxdphi[1]
00853                         - (dxdphi[2] - dxdphi_dot_v*v.z()) * dxdphi[2]
00854                         - (x[0] - c[0] - x_dot_v*v.x()) * d2xdphi2[0]
00855                         - (x[1] - c[1] - x_dot_v*v.y()) * d2xdphi2[1];
00856                     /*  - (x[2] - c[2] - x_dot_v*v.z()) * d2xdphi2[2];  = 0. */
00857 
00858 
00859         //dxda_phi, dyda_phi, dzda_phi : phi is fixed
00860         Vector dxda_phi(5);
00861         dxda_phi[0] =  cosPhi0;
00862         dxda_phi[1] = -(dRho + rho)*sinPhi0 + rho*sinPhi0dPhi; 
00863         dxda_phi[2] = -(rho/kappa)*( cosPhi0 - cosPhi0dPhi );
00864         dxda_phi[3] =  0.;
00865         dxda_phi[4] =  0.;
00866 
00867         Vector dyda_phi(5);
00868         dyda_phi[0] =  sinPhi0;
00869         dyda_phi[1] =  (dRho + rho)*cosPhi0 - rho*cosPhi0dPhi;
00870         dyda_phi[2] = -(rho/kappa)*( sinPhi0 - sinPhi0dPhi );
00871         dyda_phi[3] =  0.;
00872         dyda_phi[4] =  0.;
00873         
00874         Vector dzda_phi(5);
00875         dzda_phi[0] =  0.;
00876         dzda_phi[1] =  0.;
00877         dzda_phi[2] =  (rho/kappa)*tanLambda*dPhi;
00878         dzda_phi[3] =  1.;
00879         dzda_phi[4] = -rho*dPhi;
00880 
00881         Vector d2xdphida(5);
00882         d2xdphida[0] =  0.;
00883         d2xdphida[1] =  rho*cosPhi0dPhi; 
00884         d2xdphida[2] = -(rho/kappa)*sinPhi0dPhi; 
00885         d2xdphida[3] =  0.;
00886         d2xdphida[4] =  0.;
00887 
00888         Vector d2ydphida(5);
00889         d2ydphida[0] = 0.;
00890         d2ydphida[1] = rho*sinPhi0dPhi;
00891         d2ydphida[2] = (rho/kappa)*cosPhi0dPhi; 
00892         d2ydphida[3] = 0.;
00893         d2ydphida[4] = 0.;
00894 
00895         Vector d2zdphida(5);
00896         d2zdphida[0] =  0.;
00897         d2zdphida[1] =  0.;
00898         d2zdphida[2] =  (rho/kappa)*tanLambda;
00899         d2zdphida[3] =  0.;
00900         d2zdphida[4] = -rho;
00901  
00902         Vector dfda(5);
00903         for( int i = 0; i < 5; i++ ){
00904           double d_dot_v = v.x()*dxda_phi[i] 
00905                          + v.y()*dyda_phi[i] 
00906                          + v.z()*dzda_phi[i];
00907           dfda[i] = - (dxda_phi[i] - d_dot_v*v.x()) * dxdphi[0]
00908                     - (dyda_phi[i] - d_dot_v*v.y()) * dxdphi[1]
00909                     - (dzda_phi[i] - d_dot_v*v.z()) * dxdphi[2]
00910                     - (x[0] - c[0] - x_dot_v*v.x()) * d2xdphida[i]
00911                     - (x[1] - c[1] - x_dot_v*v.y()) * d2ydphida[i]
00912                     - (x[2] - c[2] - x_dot_v*v.z()) * d2zdphida[i];
00913           dphida[i] = - dfda[i] /dfdphi;
00914         }
00915     //}
00916 
00917     dxda[0] = cosPhi0 + rho * sinPhi0dPhi * dphida[0];
00918     dxda[1] = - (dRho + rho) * sinPhi0 + rho * sinPhi0dPhi * (1. + dphida[1]);
00919     dxda[2] = - rho / kappa * (cosPhi0 - cosPhi0dPhi)
00920               + rho * sinPhi0dPhi * dphida[2];
00921     dxda[3] = rho * sinPhi0dPhi * dphida[3];
00922     dxda[4] = rho * sinPhi0dPhi * dphida[4];
00923 
00924     dyda[0] = sinPhi0 - rho * cosPhi0dPhi * dphida[0];
00925     dyda[1] = (dRho + rho) * cosPhi0 - rho * cosPhi0dPhi * (1. + dphida[1]);
00926     dyda[2] = - rho / kappa * (sinPhi0 - sinPhi0dPhi)
00927               - rho * cosPhi0dPhi * dphida[2];
00928     dyda[3] = - rho * cosPhi0dPhi * dphida[3];
00929     dyda[4] = - rho * cosPhi0dPhi * dphida[4];
00930 
00931     dzda[0] = - rho * tanLambda * dphida[0];
00932     dzda[1] = - rho * tanLambda * dphida[1];
00933     dzda[2] = rho / kappa * tanLambda * dPhi - rho * tanLambda * dphida[2];
00934     dzda[3] = 1. - rho * tanLambda * dphida[3];
00935     dzda[4] = - rho * dPhi - rho * tanLambda * dphida[4];
00936     
00937     return 0;
00938 }
00939 
00940 #define NEW_FIT2D 1
00941 #if !(NEW_FIT2D)
00942 int
00943 TTrack::fit2D(void) {
00944 #ifdef TRKRECO_DEBUG_DETAIL
00945   std::cout << "    TTrack::fit2D(r-phi) ..." << std::endl;
00946 #endif
00947   if (_fitted) return 0;
00948 
00949   //...Check # of hits...
00950   if (_links.length() < 4) return -1;
00951   //std::cout << "# = " << _links.length() << std::endl;
00952   //...Setup...
00953   unsigned nTrial = 0;
00954   Vector a = _helix->a();
00955   Vector da(5), dxda(5), dyda(5), dzda(5);
00956   Vector dDda(5), dchi2da(5);
00957   SymMatrix d2chi2d2a(5, 0);
00958   double chi2;
00959   double chi2Old = 1.0e+99;
00960   const double convergence = 1.0e-5;
00961   Matrix e(3, 3);
00962   Vector f(3);
00963   int err = 0;
00964   double factor = 1.0;
00965   
00966   //...Fitting loop...
00967   while (nTrial < 100) {
00968 #ifdef TRKRECO_DEBUG_DETAIL
00969     if(a[3] != 0. || a[4] != 0.)cerr << "Error in 2D functions of TTrack : a = " << a << std::endl;
00970 #endif
00971     //...Set up...
00972     chi2 = 0.;
00973     for (unsigned j = 0; j < 5; ++j) dchi2da[j] = 0.;
00974     d2chi2d2a = SymMatrix(5, 0);
00975 
00976     //...Loop with hits...
00977     unsigned i = 0;
00978     while (TMLink * l = _links[i++]) {
00979       const TMDCWireHit & h = * l->hit();
00980       
00981       //...Cal. closest points...
00982       approach2D(* l);
00983       double dPhi = l->dPhi();
00984       const HepPoint3D & onTrack = l->positionOnTrack();
00985       const HepPoint3D & onWire = l->positionOnWire();
00986 #ifdef TRKRECO_DEBUG_DETAIL
00987       if(onTrack.z() != 0.)cerr << "Error in 2D functions of TTrack : onTrack = " << onTrack << std::endl;
00988       if(onWire.z() != 0.)cerr << "Error in 2D functions of TTrack : onWire = " << onWire << std::endl;
00989 #endif
00990       HepPoint3D onTrack2(onTrack.x(),onTrack.y(),0.);
00991       HepPoint3D onWire2(onWire.x(),onWire.y(),0.);
00992 
00993       //...Obtain drift distance and its error...
00994       unsigned leftRight = WireHitRight;
00995       if (onWire2.cross(onTrack2).z() < 0.) leftRight = WireHitLeft;
00996       double distance = h.distance(leftRight);
00997       double eDistance = h.dDistance(leftRight);
00998       double eDistance2 = eDistance * eDistance;
00999 
01000       //...Residual...
01001       HepVector3D v = onTrack2 - onWire2;
01002       double vmag = v.mag();
01003       double dDistance = vmag - distance;
01004 
01005       //...dxda...
01006       this->dxda2D(* l, dPhi, dxda, dyda, dzda);
01007 
01008       //...Chi2 related...
01009       //Vector3 vw(0.,0.,1.);
01010       dDda = (vmag > 0.)
01011         ? (v.x() * dxda + 
01012            v.y() * dyda ) / vmag
01013         : Vector(5,0);
01014       //dDda = (vmag > 0.)
01015       //? ((v.x() * (1. - vw.x() * vw.x()) -
01016       //    v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
01017       //   * dxda + 
01018       //   (v.y() * (1. - vw.y() * vw.y()) -
01019       //    v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
01020       //   * dyda + 
01021       //   (v.z() * (1. - vw.z() * vw.z()) -
01022       //    v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
01023       //   * dzda) / vmag
01024       //: Vector(5,0);
01025       if(vmag<=0.0) {
01026         std::cout << "    in fit2D " << onTrack << ", " << onWire;
01027         h.dump();
01028       }
01029       dchi2da += (dDistance / eDistance2) * dDda;
01030       d2chi2d2a += vT_times_v(dDda) / eDistance2;
01031       double pChi2 = dDistance * dDistance / eDistance2;
01032       chi2 += pChi2;
01033       
01034       //...Store results...
01035       l->update(onTrack2, onWire2, leftRight, pChi2);
01036     }
01037 
01038     //...Check condition...
01039     double change = chi2Old - chi2;
01040     if (fabs(change) < convergence) break;
01041     if (change < 0.){
01042 #ifdef TRKRECO_DEBUG_DETAIL
01043       std::cout << "chi2Old, chi2=" << chi2Old <<" "<< chi2 << std::endl;
01044 #endif
01045       //change to the old value.
01046       a += factor*da;
01047       _helix->a(a);
01048 
01049       chi2 = 0.;
01050       for (unsigned j = 0; j < 5; ++j) dchi2da[j] = 0.;
01051       d2chi2d2a = SymMatrix(5, 0);
01052           
01053       //...Loop with hits...
01054       unsigned i = 0;
01055       while (TMLink * l = _links[i++]) {
01056         const TMDCWireHit & h = * l->hit();
01057         
01058         //...Cal. closest points...
01059         approach2D(* l);
01060         double dPhi = l->dPhi();
01061         const HepPoint3D & onTrack = l->positionOnTrack();
01062         const HepPoint3D & onWire = l->positionOnWire();
01063         HepPoint3D onTrack2(onTrack.x(),onTrack.y(),0.);
01064         HepPoint3D onWire2(onWire.x(),onWire.y(),0.);
01065         
01066         //...Obtain drift distance and its error...
01067         unsigned leftRight = WireHitRight;
01068         if (onWire2.cross(onTrack2).z() < 0.) leftRight = WireHitLeft;
01069         double distance = h.distance(leftRight);
01070         double eDistance = h.dDistance(leftRight);
01071         double eDistance2 = eDistance * eDistance;
01072             
01073         //...Residual...
01074         HepVector3D v = onTrack2 - onWire2;
01075         double vmag = v.mag();
01076         double dDistance = vmag - distance;
01077             
01078         //...dxda...
01079         this->dxda2D(* l, dPhi, dxda, dyda, dzda);
01080 
01081         //...Chi2 related...
01082         dDda = (vmag > 0.)
01083           ? (v.x() * dxda + 
01084              v.y() * dyda ) / vmag
01085           : Vector(5,0);
01086         if(vmag<=0.0) {
01087           std::cout << "    in fit2D " << onTrack << ", " << onWire;
01088           h.dump();
01089         }
01090         dchi2da += (dDistance / eDistance2) * dDda;
01091         d2chi2d2a += vT_times_v(dDda) / eDistance2;
01092         double pChi2 = dDistance * dDistance / eDistance2;
01093         chi2 += pChi2;
01094         
01095         //...Store results...
01096         l->update(onTrack2, onWire2, leftRight, pChi2);
01097       }
01098       //break;
01099       factor *= 0.75;
01100 #ifdef TRKRECO_DEBUG_DETAIL 
01101       std::cout << "factor = " << factor << std::endl;
01102       std::cout << "chi2 = " << chi2 << std::endl;
01103 #endif
01104       if(factor < 0.01)break;
01105     }
01106 
01107     chi2Old = chi2;
01108 
01109     //...Cal. helix parameters for next loop...
01110     f = dchi2da.sub(1, 3);
01111     e = d2chi2d2a.sub(1, 3);
01112     f = solve(e, f);
01113     da[0] = f[0];
01114     da[1] = f[1];
01115     da[2] = f[2];
01116     da[3] = 0.;
01117     da[4] = 0.;
01118     
01119     a -= factor*da;
01120     _helix->a(a);      
01121     //std::cout << nTrial << ": chi2 = " << chi2 
01122     // << ", helix = (" << a[0] << ", " << a[1] 
01123     // << ", " << a[2] << ", " << a[3] 
01124     // << ", " << a[4] << ")" << std::endl;
01125     ++nTrial;
01126   }
01127 
01128   //...Cal. error matrix...
01129   SymMatrix Ea(5, 0);
01130   unsigned dim = 3;
01131   SymMatrix Eb = d2chi2d2a.sub(1, 3);
01132   SymMatrix Ec = Eb.inverse(err);
01133   Ea[0][0] = Ec[0][0];
01134   Ea[0][1] = Ec[0][1];
01135   Ea[0][2] = Ec[0][2];
01136   Ea[1][1] = Ec[1][1];
01137   Ea[1][2] = Ec[1][2];
01138   Ea[2][2] = Ec[2][2];
01139 
01140   //...Store information...
01141   if (! err) {
01142     _helix->a(a);
01143     _helix->Ea(Ea);
01144   }
01145     
01146   _ndf = _links.length() - dim;
01147   _chi2 = chi2;
01148     
01149   _fitted = true;
01150   return err;
01151 }
01152 #endif
01153 
01154 /*
01155 int TTrack::fitWithCathode(float window, int SysCorr ) {
01156 
01157 #ifdef TRKRECO_DEBUG_DETAIL
01158     std::cout << "    TTrack::fitCathode ..." << std::endl;
01159 #endif
01160 
01161     if (_fittedWithCathode) return 0;
01162 
01163     //...Check # of hits...
01164     if (nCores() < 5) return -1;
01165 
01166     //...for cathode ndf...
01167     int NusedCathode(0);
01168 
01169     //...Setup...
01170     unsigned nTrial = 0;
01171     Vector a(5), da(5);
01172     a = _helix->a();
01173     Vector dxda(5);
01174     Vector dyda(5);
01175     Vector dzda(5);
01176     Vector dDda(5);
01177     Vector dDzda(5);  // for cathode z
01178     Vector dchi2da(5);
01179     SymMatrix d2chi2d2a(5, 0);
01180     double chi2;
01181     double chi2Old = 10e99;
01182     const double convergence = 1.0e-5;
01183     bool allAxial = true;
01184     int LayerStat(0); // layer status  axial:0 stereo:1 cathode:2
01185     Matrix e(3, 3);
01186     Vector f(3);
01187     int err = 0;
01188     double factor = 1.0;
01189 
01190     const AList<TMDCCatHit> & chits = _catHits;
01191 
01192     Vector maxDouble(5);
01193     for (unsigned i = 0; i < 5; i++) maxDouble[i] = (FLT_MAX);
01194 
01195     //...Fitting loop...
01196     while (nTrial < 100) {
01197 
01198       //...Set up...
01199       chi2 = 0.;
01200       NusedCathode = 0;
01201       for (unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
01202       d2chi2d2a = SymMatrix(5, 0);
01203 
01204       //...Loop with hits...
01205       unsigned i = 0;
01206       while (TMLink * l = cores()[i++]) {
01207 
01208           const TMDCWireHit & h = * l->hit();
01209 
01210         // Check layer status ( cathode added ) 
01211         LayerStat = 0;
01212         if ( h.wire()->stereo() ) LayerStat = 1;
01213         unsigned nlayer = h.wire()->layerId();
01214         if (nlayer == 0 || nlayer == 1 || nlayer == 2 ) LayerStat = 2;
01215 
01216         //...Check wire...
01217         if (! nTrial)
01218           if (h.wire()->stereo() || LayerStat == 2 ) allAxial = false;
01219 
01220         //...Cal. closest points...
01221         approach(* l);
01222         double dPhi = l->dPhi();
01223         const HepPoint3D & onTrack = l->positionOnTrack();
01224         const HepPoint3D & onWire = l->positionOnWire();
01225 
01226 #ifdef TRKRECO_DEBUG_DETAIL
01227         // std::cout << "    in fitCathode " << onTrack << ", " << onWire;
01228         // h.dump();
01229 #endif      
01230 
01231         //...Obtain drift distance and its error...
01232         unsigned leftRight = WireHitRight;
01233         if (onWire.cross(onTrack).z() < 0.)     leftRight = WireHitLeft;
01234         double distance = h.drift(leftRight);
01235         double eDistance = h.dDrift(leftRight);
01236         double eDistance2 = eDistance * eDistance;
01237 
01238         //...Residual...
01239         HepVector3D v = onTrack - onWire;
01240         double vmag = v.mag();
01241         double dDistance = vmag - distance;
01242 
01243         //...dxda...
01244         this->dxda(* l, dPhi, dxda, dyda, dzda);
01245 
01246         // ... Chi2 related ...
01247         double pChi2(0.);
01248 
01249         if( LayerStat == 0 || LayerStat == 1 ){
01250             // dDda = (v.x() * dxda + v.y() * dyda + v.z() * dzda) / vmag;
01251             Vector3 vw = h.wire()->direction();
01252             dDda = (vmag > 0.)
01253                 ? ((v.x() * (1. - vw.x() * vw.x()) -
01254                     v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
01255                    * dxda + 
01256                    (v.y() * (1. - vw.y() * vw.y()) -
01257                     v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
01258                    * dyda + 
01259                    (v.z() * (1. - vw.z() * vw.z()) -
01260                     v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
01261                    * dzda) / vmag
01262                 :  Vector(5,0);
01263             if(vmag<=0.0) {
01264               std::cout << "    in fit " << onTrack << ", " << onWire;
01265               h.dump();
01266             }
01267           dchi2da += (dDistance / eDistance2) * dDda;
01268           d2chi2d2a += vT_times_v(dDda) / eDistance2;
01269           double pChi2 = dDistance * dDistance / eDistance2;
01270           chi2 += pChi2;
01271 
01272         } else {
01273 
01274 
01275           dDda = ( v.x() * dxda + v.y() * dyda )/v.perp();
01276           dchi2da += (dDistance/eDistance2) * dDda;
01277           d2chi2d2a += vT_times_v(dDda)/eDistance2;
01278 
01279           pChi2 = 0;
01280           pChi2 += (dDistance/eDistance) * (dDistance/eDistance) ;
01281 
01282           if ( l->usecathode() >= 3 ) {
01283 
01284             TMDCClust * mclust = l->getmclust();
01285 
01286               double dDistanceZ(this->helix().x(dPhi).z());
01287 
01288               if( SysCorr ){
01289                 if( !nTrial ) {
01290                   mclust->zcalc( atan( this->helix().tanl()) );
01291                   mclust->esterz( atan( this->helix().tanl()) );
01292                 }
01293 
01294                 dDistanceZ -= mclust->zclustWithSysCorr();
01295              } else {
01296                 dDistanceZ -= mclust->zclust();
01297              }
01298               
01299              double eDistanceZ(mclust->erz());
01300              if( !eDistanceZ ) eDistanceZ = 99999.;
01301 
01302               double eDistance2Z = eDistanceZ * eDistanceZ;
01303               double pChi2z = 0;
01304               pChi2z = (dDistanceZ/eDistanceZ);
01305               pChi2z *= pChi2z;
01306 
01307 #ifdef TRKRECO_DEBUG_DETAIL
01308               std::cout << "dDistanceZ = " << dDistanceZ << std::endl;
01309 #endif
01310 
01311       //.... requirement for use of cluster
01312 
01313       if( nTrial == 0 && 
01314           fabs(dDistanceZ)< window && 
01315           mclust->chits().length() == 1 
01316           ) l->setusecathode(4);
01317 
01318       if( l->usecathode() == 4 ){
01319                 NusedCathode++;
01320                 dDzda = dzda ; 
01321                 dchi2da += (dDistanceZ/eDistance2Z) * dDzda;
01322                 d2chi2d2a += vT_times_v(dDzda)/eDistance2Z;
01323                 pChi2 +=  pChi2z ;
01324 
01325             }
01326           }
01327         
01328         } // end Chi2 related
01329 
01330         chi2 += pChi2;
01331 
01332 
01333         //...Store results...
01334         l->update(onTrack, onWire, leftRight, pChi2);
01335       
01336 
01337       } // Tlink loop end
01338 
01339       //...Check condition...
01340       double change = chi2Old - chi2;
01341       //if(TRKRECO_DEBUG_DETAIL>0)  std::cout << "chi2 change = " <<change << std::endl;
01342    
01343       if (fabs(change) < convergence) break;
01344       if (change < 0.) {
01345 
01346 #ifdef TRKRECO_DEBUG_DETAIL
01347           std::cout << "chi2Old, chi2=" << chi2Old <<" "<< chi2 << std::endl;
01348 #endif
01349 
01350           NusedCathode = 0;
01351           //change to the old value.
01352           a += factor*da;
01353           _helix->a(a);
01354 
01355           chi2 = 0.;
01356           for (unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
01357           d2chi2d2a = SymMatrix(5, 0);
01358 
01359           
01360           //...Loop with hits...
01361           unsigned i = 0;
01362           while (TMLink * l = _links[i++]) {
01363               const TMDCWireHit & h = * l->hit();
01364 
01365      // Check layer status ( cathode added )          
01366         LayerStat = 0;
01367         if ( h.wire()->stereo() ) LayerStat = 1;
01368         unsigned nlayer = h.wire()->layerId();
01369         if (nlayer == 0 || nlayer == 1 || nlayer == 2 ) LayerStat = 2;
01370 
01371         //...Cal. closest points...
01372         approach(* l);
01373         double dPhi = l->dPhi();
01374         const HepPoint3D & onTrack = l->positionOnTrack();
01375         const HepPoint3D & onWire = l->positionOnWire();
01376 
01377 #ifdef TRKRECO_DEBUG_DETAIL
01378         // std::cout << "    in fitCathode " << onTrack << ", " << onWire;
01379         // h.dump();
01380 #endif      
01381 
01382         //...Obtain drift distance and its error...
01383         unsigned leftRight = WireHitRight;
01384         if (onWire.cross(onTrack).z() < 0.)     leftRight = WireHitLeft;
01385         double distance = h.drift(leftRight);
01386         double eDistance = h.dDrift(leftRight);
01387         double eDistance2 = eDistance * eDistance;
01388 
01389         //...Residual...
01390         HepVector3D v = onTrack - onWire;
01391         double vmag = v.mag();
01392         double dDistance = vmag - distance;
01393 
01394         //...dxda...
01395         this->dxda(* l, dPhi, dxda, dyda, dzda);
01396 
01397         // ... Chi2 related ...
01398         double pChi2(0.);
01399 
01400         if( LayerStat == 0 || LayerStat == 1 ){
01401             // dDda = (v.x() * dxda + v.y() * dyda + v.z() * dzda) / vmag;
01402             Vector3 vw = h.wire()->direction();
01403             dDda = (vmag > 0.)
01404                 ? ((v.x() * (1. - vw.x() * vw.x()) -
01405                     v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
01406                    * dxda + 
01407                    (v.y() * (1. - vw.y() * vw.y()) -
01408                     v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
01409                    * dyda + 
01410                    (v.z() * (1. - vw.z() * vw.z()) -
01411                     v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
01412                    * dzda) / vmag
01413                 : Vector(5,0);
01414             if(vmag<=0.0) {
01415               std::cout << "    in fit " << onTrack << ", " << onWire;
01416               h.dump();
01417             }
01418           dchi2da += (dDistance / eDistance2) * dDda;
01419           d2chi2d2a += vT_times_v(dDda) / eDistance2;
01420           double pChi2 = dDistance * dDistance / eDistance2;
01421           chi2 += pChi2;
01422 
01423         } else {
01424 
01425           dDda = ( v.x() * dxda + v.y() * dyda )/v.perp();
01426           dchi2da += (dDistance/eDistance2) * dDda;
01427           d2chi2d2a += vT_times_v(dDda)/eDistance2;
01428 
01429           pChi2 = 0;
01430           pChi2 += (dDistance/eDistance) * (dDistance/eDistance) ;
01431 
01432           if( l->usecathode() == 4 ){
01433             
01434             TMDCClust * mclust = l->getmclust();
01435 
01436             if( mclust ){
01437                 NusedCathode++;
01438 
01439                double dDistanceZ(this->helix().x(dPhi).z());
01440                if( SysCorr ) dDistanceZ -= mclust->zclustWithSysCorr();
01441                else          dDistanceZ -= mclust->zclust();
01442 
01443               double eDistanceZ(99999.);
01444               if( mclust->erz() != 0. ) eDistanceZ = mclust->erz();
01445 
01446               double eDistance2Z = eDistanceZ * eDistanceZ;
01447               double pChi2z = 0;
01448               pChi2z = (dDistanceZ/eDistanceZ);
01449               pChi2z *= pChi2z;
01450 
01451                 dDzda = dzda ; 
01452                 dchi2da += (dDistanceZ/eDistance2Z) * dDzda;
01453                 d2chi2d2a += vT_times_v(dDzda)/eDistance2Z;
01454                 pChi2 +=  pChi2z ;
01455             }
01456 
01457            }
01458         
01459         } // end Chi2 related
01460 
01461         chi2 += pChi2;
01462 
01463 
01464         //...Store results...
01465         l->update(onTrack, onWire, leftRight, pChi2);
01466       
01467           }
01468 
01469            //break;
01470 
01471           factor *= 0.75;
01472 #ifdef TRKRECO_DEBUG_DETAIL 
01473           std::cout << "factor = " << factor << std::endl;
01474           std::cout << "chi2 = " << chi2 << std::endl;
01475 #endif
01476           if(factor < 0.01)break;
01477 
01478       }
01479 
01480       chi2Old = chi2;
01481       
01482       //...Cal. helix parameters for next loop...
01483       if (allAxial) {
01484         f = dchi2da.sub(1, 3);
01485         e = d2chi2d2a.sub(1, 3);
01486         f = solve(e, f);
01487         da[0] = f[0];
01488         da[1] = f[1];
01489         da[2] = f[2];
01490         da[3] = 0.;
01491         da[4] = 0.;
01492       }
01493       else {
01494         da = solve(d2chi2d2a, dchi2da);
01495       }
01496       
01497 #ifdef TRKRECO_DEBUG_DETAIL
01498       //std::cout << "    fit " << nTrial << " : " << da << std::endl;
01499       //std::cout << "        d2chi " << d2chi2d2a << std::endl;
01500       //std::cout << "        dchi2 " << dchi2da << std::endl;
01501 #endif      
01502       
01503       a -= da;
01504       _helix->a(a);
01505       ++nTrial;
01506     }
01507 
01508     //...Cal. error matrix...
01509     SymMatrix Ea(5, 0);
01510     unsigned dim;
01511     if (allAxial) {
01512       dim = 3;
01513       SymMatrix Eb(3, 0), Ec(3, 0);
01514       Eb = d2chi2d2a.sub(1, 3);
01515       Ec = Eb.inverse(err);
01516       Ea[0][0] = Ec[0][0];
01517       Ea[0][1] = Ec[0][1];
01518       Ea[0][2] = Ec[0][2];
01519       Ea[1][1] = Ec[1][1];
01520       Ea[1][2] = Ec[1][2];
01521       Ea[2][2] = Ec[2][2];
01522     }
01523     else {
01524       dim = 5;
01525       Ea = d2chi2d2a.inverse(err);
01526     }
01527     
01528     //...Store information...
01529     if (! err) {
01530       _helix->a(a);
01531       _helix->Ea(Ea);
01532     }
01533       
01534     _ndf = nCores() + NusedCathode - dim;
01535     _chi2 = chi2;
01536 
01537     _fittedWithCathode = true;
01538     
01539     return err;
01540 }
01541 */
01542 
01543 #if OLD_STEREO
01544 int
01545 TTrack::stereoHitForCurl(TMLink & link, AList<HepPoint3D> & arcZList) const 
01546 {
01547   /*
01548     ATTENTION!!!!!
01549     Elements of arcZList are made by "new". We must delete them out of this function!!!!!
01550 
01551     This function is used in "stereoHitForCurl(TMLink &link1, TMLink &link2)" and
01552     "stereoHitForCurl(TMLink &link1, TMLink &link2, TMLink &link3)" only.
01553     (I(jtanaka) checked it. --> no memory leak!!!)
01554 
01555     */
01556   
01557     //std::cout << "\n\nWire ID = " << link.hit()->wire()->id() << std::endl;
01558     const TMDCWireHit &h = *link.hit();
01559     HepVector3D X     = 0.5*(h.wire()->forwardPosition() +
01560                                   h.wire()->backwardPosition());
01561     
01562     HepPoint3D center = _helix->center();
01563     HepPoint3D tmp(-999., -999., 0.);
01564     HepVector3D x     = HepVector3D(X.x(), X.y(), 0.);
01565     HepVector3D w     = x - center;
01566     HepVector3D V     = h.wire()->direction();
01567     HepVector3D v     = HepVector3D(V.x(), V.y(), 0.);
01568     double   vmag2 = v.mag2();
01569     double   vmag  = sqrt(vmag2);
01570     //...temporary
01571     link.position(tmp);
01572     arcZList.removeAll();
01573 
01574     //...stereo?
01575     if (vmag == 0.){
01576         return -1;
01577     }
01578 
01579     double r  = _helix->curv();
01580     double R[2];
01581     double drift = h.drift(WireHitLeft);
01582     R[0] = r + drift;
01583     R[1] = r - drift;
01584     double wv = w.dot(v);
01585     double d2[2];
01586     d2[0] = vmag2*R[0]*R[0] + (wv*wv - vmag2*w.mag2()); //...= v^2*(r^2 - w^2*sin()^2)...outer
01587     d2[1] = vmag2*R[1]*R[1] + (wv*wv - vmag2*w.mag2()); //...= v^2*(r^2 - w^2*sin()^2)...inner
01588 
01589     //...No crossing in R/Phi plane...
01590     if (d2[0] < 0. && d2[1] < 0.) {
01591         return -1;
01592     }
01593 
01594     bool ok_inner, ok_outer;
01595     ok_inner = true;
01596     ok_outer = true;
01597     double d[2];
01598     d[0] = -1.; 
01599     d[1] = -1.;
01600     //...outer
01601     if(d2[0] >= 0.){
01602         d[0] = sqrt(d2[0]);
01603     }else{
01604         ok_outer = false;
01605     }
01606     if(d2[1] >= 0.){
01607         d[1] = sqrt(d2[1]);
01608     }else{
01609         ok_inner = false;
01610     }
01611     
01612     //...Cal. length and z to crossing points...
01613     double l[2][2];
01614     double z[2][2];
01615     //...outer
01616     if(ok_outer){
01617         l[0][0] = (- wv + d[0]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() + (r^2 - w^2*sin()^2)^0.5)/v
01618         l[1][0] = (- wv - d[0]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() - (r^2 - w^2*sin()^2)^0.5)/v
01619         z[0][0] = X.z() + l[0][0]*V.z();
01620         z[1][0] = X.z() + l[1][0]*V.z();
01621     }
01622     //...inner
01623     if(ok_inner){
01624         l[0][1] = (- wv + d[1]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() + (r^2 - w^2*sin()^2)^0.5)/v
01625         l[1][1] = (- wv - d[1]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() - (r^2 - w^2*sin()^2)^0.5)/v
01626         z[0][1] = X.z() + l[0][1]*V.z();
01627         z[1][1] = X.z() + l[1][1]*V.z();
01628     }
01629 
01630     //...Cal. xy position of crossing points...
01631     HepVector3D p[2][2];
01632     if(ok_outer){
01633         p[0][0] = x + l[0][0] * v;
01634         p[1][0] = x + l[1][0] * v;
01635         HepVector3D tmp_pc = p[0][0] - center;
01636         HepVector3D pc0 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
01637         p[0][0] -= drift/pc0.mag()*pc0;
01638         tmp_pc = p[1][0] - center;
01639         HepVector3D pc1 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
01640         p[1][0] -= drift/pc1.mag()*pc1;
01641     }
01642     if(ok_inner){
01643         p[0][1] = x + l[0][1] * v;
01644         p[1][1] = x + l[1][1] * v;
01645         HepVector3D tmp_pc = p[0][1] - center;
01646         HepVector3D pc0 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
01647         p[0][1] += drift/pc0.mag()*pc0;
01648         tmp_pc = p[1][1] - center;
01649         HepVector3D pc1 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
01650         p[1][1] += drift/pc1.mag()*pc1;
01651     }
01652 
01653     //...boolean
01654     bool ok_xy[2][2];
01655     if(ok_outer){
01656         ok_xy[0][0] = true;
01657         ok_xy[1][0] = true;
01658     }else{
01659         ok_xy[0][0] = false;
01660         ok_xy[1][0] = false;
01661     }
01662     if(ok_inner){
01663         ok_xy[0][1] = true;
01664         ok_xy[1][1] = true;
01665     }else{
01666         ok_xy[0][1] = false;
01667         ok_xy[1][1] = false;
01668     }
01669     if(ok_outer){
01670         if (_charge * (center.x() * p[0][0].y() - center.y() * p[0][0].x())  < 0.)
01671           ok_xy[0][0] = false;
01672         if (_charge * (center.x() * p[1][0].y() - center.y() * p[1][0].x())  < 0.)
01673           ok_xy[1][0] = false;
01674     }
01675     if(ok_inner){
01676         if (_charge * (center.x() * p[0][1].y() - center.y() * p[0][1].x())  < 0.)
01677           ok_xy[0][1] = false;
01678         if (_charge * (center.x() * p[1][1].y() - center.y() * p[1][1].x())  < 0.)
01679           ok_xy[1][1] = false;
01680     }
01681     if(!ok_inner && ok_outer && (!ok_xy[0][0]) && (!ok_xy[1][0])){
01682         return -1;
01683     }
01684     if(ok_inner && !ok_outer && (!ok_xy[0][1]) && (!ok_xy[1][1])){
01685         return -1;
01686     }
01687 
01688 #if 0
01689     std::cout << "Drift Dist. = " << h.distance(WireHitLeft) << std::endl;
01690     std::cout << "outer ok? = " << ok_outer << std::endl; 
01691     std::cout << "Z cand = " << z[0][0] << ", " << z[1][0] << std::endl;
01692     std::cout << "inner ok? = " << ok_inner << std::endl; 
01693     std::cout << "Z cand = " << z[0][1] << ", " << z[1][1] << std::endl; 
01694 #endif
01695 
01696     //...Check z position...
01697     if(ok_xy[0][0]){
01698         if (z[0][0] < h.wire()->backwardPosition().z() || 
01699             z[0][0] > h.wire()->forwardPosition().z()) ok_xy[0][0] = false;
01700     }
01701     if(ok_xy[1][0]){
01702         if (z[1][0] < h.wire()->backwardPosition().z() || 
01703             z[1][0] > h.wire()->forwardPosition().z()) ok_xy[1][0] = false;
01704     }
01705     if(ok_xy[0][1]){
01706         if (z[0][1] < h.wire()->backwardPosition().z() || 
01707             z[0][1] > h.wire()->forwardPosition().z()) ok_xy[0][1] = false;
01708     }
01709     if(ok_xy[1][1]){
01710         if (z[1][1] < h.wire()->backwardPosition().z() || 
01711             z[1][1] > h.wire()->forwardPosition().z()) ok_xy[1][1] = false;
01712     }
01713     if ((!ok_xy[0][0]) && (!ok_xy[1][0]) &&
01714           (!ok_xy[0][1]) && (!ok_xy[1][1])){
01715         return -1;
01716     }
01717 
01718     double cosdPhi, dPhi;
01719 
01720     if(ok_xy[0][0]){
01721         //...cal. arc length...
01722         cosdPhi = - center.dot((p[0][0] - center).unit()) / center.mag();
01723         if(fabs(cosdPhi) < 1.0){
01724           dPhi = acos(cosdPhi);
01725         }else if(cosdPhi >= 1.0){
01726           dPhi = 0.;
01727         }else{
01728           dPhi = M_PI;
01729         }
01730     
01731         HepPoint3D *arcZ = new HepPoint3D;
01732         arcZ->setX(r*dPhi);
01733         arcZ->setY(z[0][0]);
01734         arcZList.append(arcZ);
01735     }
01736     if(ok_xy[1][0]){
01737         //...cal. arc length...
01738         cosdPhi = - center.dot((p[1][0] - center).unit()) / center.mag();
01739         if(fabs(cosdPhi) < 1.0){
01740           dPhi = acos(cosdPhi);
01741         }else if(cosdPhi >= 1.0){
01742           dPhi = 0.;
01743         }else{
01744           dPhi = M_PI;
01745         }
01746         
01747         HepPoint3D *arcZ = new HepPoint3D;
01748         arcZ->setX(r*dPhi);
01749         arcZ->setY(z[1][0]);
01750         arcZList.append(arcZ);
01751     }
01752     if(ok_xy[0][1]){
01753         //...cal. arc length...
01754         cosdPhi = - center.dot((p[0][1] - center).unit()) / center.mag();
01755         if(cosdPhi>1.0) cosdPhi = 1.0;
01756         if(cosdPhi<-1.0) cosdPhi = -1.0;
01757 
01758         if(fabs(cosdPhi) < 1.0){
01759           dPhi = acos(cosdPhi);
01760         }else if(cosdPhi >= 1.0){
01761           dPhi = 0.;
01762         }else{
01763           dPhi = M_PI;
01764         }
01765         
01766         HepPoint3D *arcZ = new HepPoint3D;
01767         arcZ->setX(r*dPhi);
01768         arcZ->setY(z[0][1]);
01769         arcZList.append(arcZ);
01770     }
01771     if(ok_xy[1][1]){
01772         //...cal. arc length...
01773         cosdPhi = - center.dot((p[1][1] - center).unit()) / center.mag();
01774         if(cosdPhi>1.0) cosdPhi = 1.0;
01775         if(cosdPhi<-1.0) cosdPhi = -1.0;
01776         if(fabs(cosdPhi) < 1.0){
01777           dPhi = acos(cosdPhi);
01778         }else if(cosdPhi >= 1.0){
01779           dPhi = 0.;
01780         }else{
01781           dPhi = M_PI;
01782         }
01783         
01784         HepPoint3D *arcZ = new HepPoint3D;
01785         arcZ->setX(r*dPhi);
01786         arcZ->setY(z[1][1]);
01787         arcZList.append(arcZ);
01788     }
01789     
01790     if(arcZList.length() == 1 ||
01791          arcZList.length() == 2){
01792         return 0;
01793     }else{
01794         return -1;
01795     } 
01796 }
01797 
01798 
01799 int
01800 TTrack::stereoHitForCurl(TMLink &link1, TMLink &link2) const {
01801   int flag1, flag2;
01802   double minZ = 9999999.;
01803 
01804   AList<HepPoint3D> arcZList1;
01805   AList<HepPoint3D> arcZList2;
01806   if(stereoHitForCurl(link1,arcZList1) == 0){
01807     if(stereoHitForCurl(link2,arcZList2) == 0){
01808         //...finds
01809         int n1 = arcZList1.length();
01810         int n2 = arcZList2.length();
01811         for(int i=0;i<n1;i++){
01812           for(int j=0;j<n2;j++){
01813             if(fabs(arcZList1[i]->y()-arcZList2[j]->y()) < minZ){
01814                 minZ = fabs(arcZList1[i]->y()-arcZList2[j]->y());
01815                 flag1 = i;
01816                 flag2 = j;
01817             }
01818           }
01819         }
01820     }
01821   }
01822   
01823   if(minZ == 9999999.){
01824     //...deletes
01825     deleteListForCurl(arcZList1, arcZList2);
01826     return -1;
01827   }
01828 
01829   //...sets the best values
01830   HepPoint3D tmp1 = *arcZList1[flag1];
01831   HepPoint3D tmp2 = *arcZList2[flag2];
01832   link1.position(tmp1);
01833   link2.position(tmp2);
01834   //...deletes
01835   deleteListForCurl(arcZList1, arcZList2);
01836   return 0;
01837 }
01838 
01839 #if defined(__GNUG__)
01840 int 
01841 TArcOrder( const HepPoint3D **a, const HepPoint3D **b )
01842 {
01843   if( (*a)->x() < (*b)->x() ){
01844     return 1;
01845   }else if( (*a)->x() == (*b)->x() ){
01846     return 0;
01847   }else{
01848     return -1;
01849   }
01850 }
01851 #else
01852 extern "C" int 
01853 TArcOrder( const void *av, const void *bv )
01854 {
01855   const HepPoint3D **a((const HepPoint3D **)av);
01856   const HepPoint3D **b((const HepPoint3D **)bv);
01857   if( (*a)->x() < (*b)->x() ){
01858     return 1;
01859   }else if( (*a)->x() == (*b)->x() ){
01860     return 0;
01861   }else{
01862     return -1;
01863   }
01864 }
01865 #endif
01866 
01867 int
01868 TTrack::stereoHitForCurl(TMLink &link1, TMLink &link2, TMLink &link3) const 
01869 {
01870   //...definition of the return values
01871   //   -1 = error
01872   //    0 = normal = can use 3 links
01873   //   12 = can use 1 and 2 only
01874   //   23 = can use 2 and 3 only
01875 
01876   int flag1, flag2, flag3;
01877   double minZ1   = 9999999.;
01878   double minZ2   = 9999999.;
01879   double minZ01  = 9999999.;
01880   double minZ12  = 9999999.;
01881 
01882   AList<HepPoint3D> arcZList1;
01883   AList<HepPoint3D> arcZList2;
01884   AList<HepPoint3D> arcZList3;
01885   int ok1 = stereoHitForCurl(link1, arcZList1);
01886   int ok2 = stereoHitForCurl(link2, arcZList2);
01887   int ok3 = stereoHitForCurl(link3, arcZList3);
01888 
01889   if((ok1 != 0 && ok2 != 0 && ok3 != 0) ||
01890      (ok1 == 0 && ok2 != 0 && ok3 != 0) ||
01891      (ok1 != 0 && ok2 == 0 && ok3 != 0) ||
01892      (ok1 != 0 && ok2 != 0 && ok3 == 0) ||
01893      (ok1 == 0 && ok2 != 0 && ok3 == 0)){
01894     //...deletes
01895     deleteListForCurl(arcZList1, arcZList2, arcZList3);
01896     return -1;
01897   }
01898   
01899   if(ok1 == 0 && ok2 == 0 && ok3 == 0){
01900     //...finds
01901     double checkArc;
01902     int n1 = arcZList1.length();
01903     int n2 = arcZList2.length();
01904     int n3 = arcZList3.length();
01905     for(int i=0;i<n1;i++){
01906         for(int j=0;j<n2;j++){
01907           for(int k=0;k<n3;k++){
01908             AList<HepPoint3D> arcZ;
01909             arcZ.append(*arcZList1[i]);
01910             arcZ.append(*arcZList2[j]);
01911             arcZ.append(*arcZList3[k]);
01912             arcZ.sort(TArcOrder);
01913             double z01 = fabs(arcZ[0]->y()-arcZ[1]->y());
01914             double z12 = fabs(arcZ[1]->y()-arcZ[2]->y());
01915             if(z01 <= minZ1 && z12 <= minZ2){
01916                 minZ1 = z01;
01917                 minZ2 = z12;
01918                 flag1 = i;
01919                 flag2 = j;
01920                 flag3 = k;
01921             }
01922           }
01923         }
01924     }
01925     if(minZ1 == 9999999.||
01926          minZ2 == 9999999.){
01927         deleteListForCurl(arcZList1, arcZList2, arcZList3);
01928         return -1;
01929     }
01930     //...sets the best values
01931     HepPoint3D tmp1 = *arcZList1[flag1];
01932     HepPoint3D tmp2 = *arcZList2[flag2];
01933     HepPoint3D tmp3 = *arcZList3[flag3];
01934     link1.position(tmp1);
01935     link2.position(tmp2);
01936     link3.position(tmp3);
01937     deleteListForCurl(arcZList1, arcZList2, arcZList3);
01938     return 0;
01939   }else if(ok1 == 0 && ok2 == 0 && ok3 != 0){
01940     int n1 = arcZList1.length();
01941     int n2 = arcZList2.length();
01942     for(int i=0;i<n1;i++){
01943         for(int j=0;j<n2;j++){
01944           if(fabs(arcZList1[i]->y()-arcZList2[j]->y()) < minZ01){
01945             minZ01 = fabs(arcZList1[i]->y()-arcZList2[j]->y());
01946             flag1 = i;
01947             flag2 = j;
01948           }
01949         }
01950     }
01951     if(minZ01 == 9999999.){
01952         deleteListForCurl(arcZList1, arcZList2, arcZList3);
01953         return -1;
01954     }
01955     //...sets the best values
01956     HepPoint3D tmp1 = *arcZList1[flag1];
01957     HepPoint3D tmp2 = *arcZList2[flag2];
01958     link1.position(tmp1);
01959     link2.position(tmp2);
01960     deleteListForCurl(arcZList1, arcZList2, arcZList3);
01961     return 12;
01962   }else if(ok1 != 0 && ok2 == 0 && ok3 == 0){
01963     int n2 = arcZList2.length();
01964     int n3 = arcZList3.length();
01965     for(int i=0;i<n2;i++){
01966         for(int j=0;j<n3;j++){
01967           if(fabs(arcZList2[i]->y()-arcZList3[j]->y()) < minZ12){
01968             minZ12 = fabs(arcZList2[i]->y()-arcZList3[j]->y());
01969             flag2 = i;
01970             flag3 = j;
01971           }
01972         }
01973     }
01974     if(minZ12 == 9999999.){
01975         deleteListForCurl(arcZList1, arcZList2, arcZList3);
01976         return -1;
01977     }
01978     //...sets the best values
01979     HepPoint3D tmp2 = *arcZList2[flag2];
01980     HepPoint3D tmp3 = *arcZList3[flag3];
01981     link1.position(tmp2);
01982     link2.position(tmp3);
01983     deleteListForCurl(arcZList1, arcZList2, arcZList3);
01984     return 23;
01985   }else{
01986     deleteListForCurl(arcZList1, arcZList2, arcZList3);
01987     return -1;
01988   }
01989 }
01990 
01991 void
01992 TTrack::deleteListForCurl(AList<HepPoint3D> &l1,
01993                           AList<HepPoint3D> &l2) const {
01994     HepAListDeleteAll(l1);
01995     HepAListDeleteAll(l2);
01996 }
01997 
01998 void
01999 TTrack::deleteListForCurl(AList<HepPoint3D> &l1,
02000                           AList<HepPoint3D> &l2,
02001                           AList<HepPoint3D> &l3) const {
02002     HepAListDeleteAll(l1);
02003     HepAListDeleteAll(l2);
02004     HepAListDeleteAll(l3);
02005 }
02006 #endif //OLD_STEREO
02007 
02008 int
02009 TTrack::stereoHitForCurl(AList<TMLink> & list) const 
02010 {
02011   if(list.length() == 0)return -1;
02012 
02013   HepPoint3D center = _helix->center();
02014   HepPoint3D tmp(-999., -999., 0.);
02015   double r  = fabs(_helix->curv());
02016   for(unsigned i = 0, size = list.length(); i < size; ++i){
02017     TMDCWireHit &h = *const_cast<TMDCWireHit*>(list[i]->hit());
02018     HepVector3D X = 0.5*(h.wire()->forwardPosition() +
02019                       h.wire()->backwardPosition());
02020     HepVector3D x     = HepVector3D(X.x(), X.y(), 0.);
02021     HepVector3D w     = x - center;
02022     HepVector3D V     = h.wire()->direction();
02023     HepVector3D v     = HepVector3D(V.x(), V.y(), 0.);
02024     double   vmag2 = v.mag2();
02025     double   vmag  = sqrt(vmag2);
02026     //...temporary
02027     for(unsigned j = 0; j < 4; ++j)
02028       list[i]->arcZ(tmp,j);
02029     
02030     //...stereo?
02031     if (vmag == 0.) continue;
02032    
02033     double drift = h.drift(WireHitLeft);
02034     double R[2] = {r + drift, r - drift};
02035     double wv = w.dot(v);
02036     double d2[2];
02037     d2[0] = vmag2*R[0]*R[0] + (wv*wv - vmag2*w.mag2()); //...= v^2*(r^2 - w^2*sin()^2)...outer
02038     d2[1] = vmag2*R[1]*R[1] + (wv*wv - vmag2*w.mag2()); //...= v^2*(r^2 - w^2*sin()^2)...inner
02039     
02040     //...No crossing in R/Phi plane...
02041     if (d2[0] < 0. && d2[1] < 0.) continue;
02042 
02043     bool ok_inner(true);
02044     bool ok_outer(true);
02045     double d[2] = {-1., -1.};
02046     //...outer
02047     if(d2[0] >= 0.){
02048       d[0] = sqrt(d2[0]);
02049     }else{
02050       ok_outer = false;
02051     }
02052     if(d2[1] >= 0.){
02053       d[1] = sqrt(d2[1]);
02054     }else{
02055       ok_inner = false;
02056     }
02057     
02058     //...Cal. length and z to crossing points...
02059     double l[2][2];
02060     double z[2][2];
02061     //...outer
02062     if(ok_outer){
02063       l[0][0] = (- wv + d[0]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() + (r^2 - w^2*sin()^2)^0.5)/v
02064       l[1][0] = (- wv - d[0]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() - (r^2 - w^2*sin()^2)^0.5)/v
02065       z[0][0] = X.z() + l[0][0]*V.z();
02066       z[1][0] = X.z() + l[1][0]*V.z();
02067     }
02068     //...inner
02069     if(ok_inner){
02070       l[0][1] = (- wv + d[1]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() + (r^2 - w^2*sin()^2)^0.5)/v
02071       l[1][1] = (- wv - d[1]) / vmag2; //...= (-wvcos()+d)/v/v = (-wcos() - (r^2 - w^2*sin()^2)^0.5)/v
02072       z[0][1] = X.z() + l[0][1]*V.z();
02073       z[1][1] = X.z() + l[1][1]*V.z();
02074     }
02075     
02076     //...Cal. xy position of crossing points...
02077     HepVector3D p[2][2];
02078 #if 1
02079     HepVector3D tp[2][2];
02080 #endif
02081     if(ok_outer){
02082       p[0][0] = x + l[0][0] * v;
02083       p[1][0] = x + l[1][0] * v;
02084 #if 1
02085       tp[0][0] = p[0][0];
02086       tp[1][0] = p[1][0];
02087 #endif
02088       HepVector3D tmp_pc = p[0][0] - center;
02089       HepVector3D pc0 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
02090       p[0][0] -= drift/pc0.mag()*pc0;
02091       tmp_pc = p[1][0] - center;
02092       HepVector3D pc1 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
02093       p[1][0] -= drift/pc1.mag()*pc1;
02094     }
02095 #define JJTEST 0
02096     if(ok_inner){
02097       p[0][1] = x + l[0][1] * v;
02098       p[1][1] = x + l[1][1] * v;
02099 #if JJTEST
02100       tp[0][1] = p[0][1];
02101       tp[1][1] = p[1][1];
02102 #endif
02103       HepVector3D tmp_pc = p[0][1] - center;
02104       HepVector3D pc0 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
02105       p[0][1] += drift/pc0.mag()*pc0;
02106       tmp_pc = p[1][1] - center;
02107       HepVector3D pc1 = HepVector3D(tmp_pc.x(), tmp_pc.y(), 0.);
02108       p[1][1] += drift/pc1.mag()*pc1;
02109     }
02110 
02111     //...boolean
02112     bool ok_xy[2][2];
02113     if(ok_outer){
02114       ok_xy[0][0] = true;
02115       ok_xy[1][0] = true;
02116     }else{
02117       ok_xy[0][0] = false;
02118       ok_xy[1][0] = false;
02119     }
02120     if(ok_inner){
02121       ok_xy[0][1] = true;
02122       ok_xy[1][1] = true;
02123     }else{
02124       ok_xy[0][1] = false;
02125       ok_xy[1][1] = false;
02126     }
02127     if(ok_outer){
02128       if (_charge * (center.x() * p[0][0].y() - center.y() * p[0][0].x())  < 0.)
02129         ok_xy[0][0] = false;
02130       if (_charge * (center.x() * p[1][0].y() - center.y() * p[1][0].x())  < 0.)
02131         ok_xy[1][0] = false;
02132     }
02133     if(ok_inner){
02134       if (_charge * (center.x() * p[0][1].y() - center.y() * p[0][1].x())  < 0.)
02135         ok_xy[0][1] = false;
02136       if (_charge * (center.x() * p[1][1].y() - center.y() * p[1][1].x())  < 0.)
02137         ok_xy[1][1] = false;
02138     }
02139     if(!ok_inner && ok_outer && (!ok_xy[0][0]) && (!ok_xy[1][0])){
02140       continue;
02141     }
02142     if(ok_inner && !ok_outer && (!ok_xy[0][1]) && (!ok_xy[1][1])){
02143       continue;
02144     }
02145     
02146     //...Check z position...
02147     if(ok_xy[0][0]){
02148       if (z[0][0] < h.wire()->backwardPosition().z() || 
02149           z[0][0] > h.wire()->forwardPosition().z()) ok_xy[0][0] = false;
02150     }
02151     if(ok_xy[1][0]){
02152       if (z[1][0] < h.wire()->backwardPosition().z() || 
02153           z[1][0] > h.wire()->forwardPosition().z()) ok_xy[1][0] = false;
02154     }
02155     if(ok_xy[0][1]){
02156       if (z[0][1] < h.wire()->backwardPosition().z() || 
02157           z[0][1] > h.wire()->forwardPosition().z()) ok_xy[0][1] = false;
02158     }
02159     if(ok_xy[1][1]){
02160       if (z[1][1] < h.wire()->backwardPosition().z() || 
02161           z[1][1] > h.wire()->forwardPosition().z()) ok_xy[1][1] = false;
02162     }
02163     if ((!ok_xy[0][0]) && (!ok_xy[1][0]) &&
02164         (!ok_xy[0][1]) && (!ok_xy[1][1])){
02165       continue;
02166     }
02167     double cosdPhi, dPhi;
02168     unsigned index;
02169     index = 0;
02170     if(ok_xy[0][0]){
02171       //...cal. arc length...
02172       cosdPhi = - center.dot((p[0][0] - center).unit()) / center.mag();
02173       if(fabs(cosdPhi) < 1.0){
02174         dPhi = acos(cosdPhi);
02175       }else if(cosdPhi >= 1.0){
02176         dPhi = 0.;
02177       }else{
02178         dPhi = M_PI;
02179       }
02180       list[i]->arcZ(HepPoint3D(r*dPhi, z[0][0], 0.), index);
02181       //std::cout << r*dPhi << ", " << z[0][0] << std::endl;
02182       ++index;
02183     }
02184     if(ok_xy[1][0]){
02185       //...cal. arc length...
02186       cosdPhi = - center.dot((p[1][0] - center).unit()) / center.mag();
02187       if(fabs(cosdPhi) < 1.0){
02188         dPhi = acos(cosdPhi);
02189       }else if(cosdPhi >= 1.0){
02190         dPhi = 0.;
02191       }else{
02192         dPhi = M_PI;
02193       }
02194       list[i]->arcZ(HepPoint3D(r*dPhi, z[1][0], 0.), index);
02195       //std::cout << r*dPhi << ", " << z[1][0] << std::endl;
02196       ++index;
02197     }
02198     if(ok_xy[0][1]){
02199       //...cal. arc length...
02200       cosdPhi = - center.dot((p[0][1] - center).unit()) / center.mag();
02201       if(fabs(cosdPhi) < 1.0){
02202         dPhi = acos(cosdPhi);
02203       }else if(cosdPhi >= 1.0){
02204         dPhi = 0.;
02205       }else{
02206         dPhi = M_PI;
02207       }
02208       list[i]->arcZ(HepPoint3D(r*dPhi, z[0][1], 0.), index);
02209       //std::cout << r*dPhi << ", " << z[0][1] << std::endl;
02210       ++index;
02211     }
02212     if(ok_xy[1][1]){
02213       //...cal. arc length...
02214       cosdPhi = - center.dot((p[1][1] - center).unit()) / center.mag();
02215       if(fabs(cosdPhi) < 1.0){
02216         dPhi = acos(cosdPhi);
02217       }else if(cosdPhi >= 1.0){
02218         dPhi = 0.;
02219       }else{
02220         dPhi = M_PI;
02221       }
02222       list[i]->arcZ(HepPoint3D(r*dPhi, z[1][1], 0.), index);
02223       //std::cout << r*dPhi << ", " << z[1][1] << std::endl;
02224       ++index;
02225     }
02226  
02227 #if JJTEST
02228     double gmaxX = -9999. ,gminX = 9999.;
02229     double gmaxY = -9999. ,gminY = 9999.;
02230     FILE *gnuplot, *data;
02231     double step = 100.;
02232     double dStep = 2.*M_PI/step;
02233     if((data = fopen("dat1","w")) != NULL){
02234       if(ok_xy[0][0]){
02235         for(int ii=0;ii<step;++ii){
02236           double X = tp[0][0].x() + drift*cos(dStep*static_cast<double>(ii));
02237           double Y = tp[0][0].y() + drift*sin(dStep*static_cast<double>(ii));
02238           fprintf(data,"%lf, %lf\n",X,Y);
02239           if(gmaxX < X)gmaxX = X;
02240           if(gminX > X)gminX = X;
02241           if(gmaxY < Y)gmaxY = Y;
02242           if(gminY > Y)gminY = Y;
02243         }
02244       }
02245       fclose(data);
02246     }
02247     if((data = fopen("dat2","w")) != NULL){
02248       if(ok_xy[1][0]){
02249         for(int ii=0;ii<step;++ii){
02250           double X = tp[1][0].x() + drift*cos(dStep*static_cast<double>(ii));
02251           double Y = tp[1][0].y() + drift*sin(dStep*static_cast<double>(ii));
02252           fprintf(data,"%lf, %lf\n",X,Y);
02253           if(gmaxX < X)gmaxX = X;
02254           if(gminX > X)gminX = X;
02255           if(gmaxY < Y)gmaxY = Y;
02256           if(gminY > Y)gminY = Y;
02257         }
02258       }
02259       fclose(data);
02260     }
02261     if((data = fopen("dat3","w")) != NULL){
02262       if(ok_xy[0][1]){
02263         for(int ii=0;ii<step;++ii){
02264           double X = tp[0][1].x() + drift*cos(dStep*static_cast<double>(ii));
02265           double Y = tp[0][1].y() + drift*sin(dStep*static_cast<double>(ii));
02266           fprintf(data,"%lf, %lf\n",X,Y);
02267           if(gmaxX < X)gmaxX = X;
02268           if(gminX > X)gminX = X;
02269           if(gmaxY < Y)gmaxY = Y;
02270           if(gminY > Y)gminY = Y;
02271         }
02272       }
02273       fclose(data);
02274     }
02275     if((data = fopen("dat4","w")) != NULL){
02276       if(ok_xy[1][1]){
02277         for(int ii=0;ii<step;++ii){
02278           double X = tp[1][1].x() + drift*cos(dStep*static_cast<double>(ii));
02279           double Y = tp[1][1].y() + drift*sin(dStep*static_cast<double>(ii));
02280           fprintf(data,"%lf, %lf\n",X,Y);
02281           if(gmaxX < X)gmaxX = X;
02282           if(gminX > X)gminX = X;
02283           if(gmaxY < Y)gmaxY = Y;
02284           if(gminY > Y)gminY = Y;
02285         }
02286       }
02287       fclose(data);
02288     }
02289     HepVector3D tX = h.wire()->forwardPosition()-h.wire()->backwardPosition();
02290     HepVector3D tDist(tX.x(), tX.y(), 0.);
02291     double tD = tDist.mag();
02292     double vvvM = 1./ v.mag();
02293     HepVector3D tDire = vvvM*v;
02294     step = 2.;
02295     dStep = tD/step;
02296     if((data = fopen("dat5","w")) != NULL){
02297       for(int ii=0;ii<step+1;++ii){
02298         double X = h.wire()->backwardPosition().x()+dStep*static_cast<double>(ii)*tDire.x();
02299         double Y = h.wire()->backwardPosition().y()+dStep*static_cast<double>(ii)*tDire.y();
02300         fprintf(data,"%lf, %lf\n",X,Y);
02301         if(gmaxX < X)gmaxX = X;
02302         if(gminX > X)gminX = X;
02303         if(gmaxY < Y)gmaxY = Y;
02304         if(gminY > Y)gminY = Y;
02305       }
02306       fclose(data);
02307     }
02308     if((data = fopen("dat6","w")) != NULL){
02309       double X = h.wire()->backwardPosition().x();
02310       double Y = h.wire()->backwardPosition().y();
02311       fprintf(data,"%lf, %lf\n",X,Y);
02312       if(gmaxX < X)gmaxX = X;
02313       if(gminX > X)gminX = X;
02314       if(gmaxY < Y)gmaxY = Y;
02315       if(gminY > Y)gminY = Y;
02316       fclose(data);    
02317     }
02318     if((data = fopen("dat7","w")) != NULL){
02319       double X = h.wire()->forwardPosition().x();
02320       double Y = h.wire()->forwardPosition().y();
02321       fprintf(data,"%lf, %lf\n",X,Y);
02322       if(gmaxX < X)gmaxX = X;
02323       if(gminX > X)gminX = X;
02324       if(gmaxY < Y)gmaxY = Y;
02325       if(gminY > Y)gminY = Y;
02326       fclose(data);  
02327     }
02328     step = 300.;
02329     dStep = 2.*M_PI/step;
02330     if((data = fopen("dat8","w")) != NULL){
02331       for(int ii=0;ii<step;++ii){
02332         double X = center.x() + r*cos(dStep*static_cast<double>(ii));
02333         double Y = center.y() + r*sin(dStep*static_cast<double>(ii));
02334         fprintf(data,"%lf, %lf\n",X,Y);
02335       }
02336       fclose(data);
02337     }
02338     if((data = fopen("dat9","w")) != NULL){
02339       if(ok_xy[0][0]){
02340         double X = p[0][0].x();
02341         double Y = p[0][0].y();
02342         fprintf(data,"%lf, %lf\n",X,Y);
02343       }
02344       fclose(data);  
02345     }
02346     if((data = fopen("dat10","w")) != NULL){
02347       if(ok_xy[1][0]){
02348         double X = p[1][0].x();
02349         double Y = p[1][0].y();
02350         fprintf(data,"%lf, %lf\n",X,Y);
02351       }
02352       fclose(data);  
02353     }
02354     if((data = fopen("dat11","w")) != NULL){
02355       if(ok_xy[0][1]){
02356         double X = p[0][1].x();
02357         double Y = p[0][1].y();
02358         fprintf(data,"%lf, %lf\n",X,Y);
02359       }
02360       fclose(data);  
02361     }
02362     if((data = fopen("dat12","w")) != NULL){
02363       if(ok_xy[1][1]){
02364         double X = p[1][1].x();
02365         double Y = p[1][1].y();
02366         fprintf(data,"%lf, %lf\n",X,Y);
02367       }
02368       fclose(data);  
02369     }
02370     std::cout << "Drift Distance = " << drift << ", xy1cm -> z" << V.z()/v.mag() << "cm, xyDist(cm) = " << tD << std::endl;
02371     if(tX.z()<0.)std::cout << "ERROR : F < B" << std::endl;
02372     if((gnuplot = popen("gnuplot","w")) != NULL){
02373       fprintf(gnuplot,"set size 0.721,1.0 \n");
02374       fprintf(gnuplot,"set xrange [%f:%f] \n",gminX,gmaxX);
02375       fprintf(gnuplot,"set yrange [%f:%f] \n",gminY,gmaxY);
02376       fprintf(gnuplot,"plot \"dat1\" with line, \"dat2\" with line, \"dat3\" with line, \"dat4\" with line, \"dat5\" with line, \"dat6\", \"dat7\", \"dat8\" with line, \"dat9\", \"dat10\", \"dat11\", \"dat12\" \n");
02377       fflush(gnuplot);
02378       char tmp[8];
02379       gets(tmp);
02380       pclose(gnuplot);
02381     }
02382 #endif
02383   }
02384   return 0;
02385 }
02386 
02387 #if !(NEW_FIT2D)
02388 int 
02389 TTrack::approach2D(TMLink & l) const {
02390 
02391   //...Setup...
02392   const TMDCWire & w = * l.wire();
02393   Vector a = _helix->a();
02394   double kappa = a[2];
02395   double phi0  = a[1];
02396   HepPoint3D xc = _helix->center();
02397   HepPoint3D xw = w.xyPosition();
02398   HepPoint3D xt = _helix->x();
02399   HepVector3D v0, v1;
02400   v0 = xt - xc;
02401   v1 = xw - xc;
02402   //if (_charge > 0.) {
02403   //v0 *= -1;
02404   //v1 *= -1;
02405   //}
02406   double vCrs = v0.x() * v1.y() - v0.y() * v1.x();
02407   double vDot = v0.x() * v1.x() + v0.y() * v1.y();
02408   double dPhi = atan2(vCrs, vDot);
02409 
02410   //...Cal. phi to rotate...
02411   //double phiWire = atan2(_charge * (xc.y() - xw.y()),
02412   //                     _charge * (xc.x() - xw.x()));
02413   //phiWire = (phiWire > 0.) ? phiWire : phiWire + 2. * M_PI;
02414   //double dPhi = phiWire - phi0;
02415   
02416   //...Why this is needed?...
02417   //if ((_charge >= 0.) && (dPhi > 0.)) dPhi -= 2. * M_PI;
02418   //else if ((_charge < 0.) && (dPhi < 0.)) dPhi += 2. * M_PI;
02419   
02420   //std::cout << _helix->x(dPhi) << " , " << _helix->x(dPhi+0.2) << " , " << _helix->x(dPhi-0.1) << std::endl;
02421   
02422   l.positionOnTrack(_helix->x(dPhi));
02423   HepPoint3D x = xw;
02424   x.setZ(0.);
02425   l.positionOnWire(x);
02426   l.dPhi(dPhi);
02427   return 0;
02428 }
02429 
02430 int
02431 TTrack::dxda2D(const TMLink & link,
02432                double dPhi,
02433                Vector & dxda,
02434                Vector & dyda,
02435                Vector & dzda) const {
02436   
02437   //...Setup...
02438   const TMDCWire & w = * link.wire();
02439   Vector a = _helix->a();
02440   double dRho  = a[0];
02441   double phi0  = a[1];
02442   double kappa = a[2];
02443  // double rho   = Helix::ConstantAlpha / kappa;
02444  // double rho   = 333.564095 / kappa;
02445   const double Bz = -1000*m_pmgnIMF->getReferField();
02446   double rho   = 333.564095/(kappa * Bz);
02447 
02448   //double tanLambda = a[4];
02449   
02450   double sinPhi0 = sin(phi0);
02451   double cosPhi0 = cos(phi0);
02452   double sinPhi0dPhi = sin(phi0 + dPhi);
02453   double cosPhi0dPhi = cos(phi0 + dPhi);
02454   Vector dphida(5);
02455   
02456   HepPoint3D d = _helix->center() - w.xyPosition();
02457   double dmag2 = d.mag2();
02458   
02459   dphida[0] = (sinPhi0 * d.x() - cosPhi0 * d.y()) / dmag2;
02460   dphida[1] = (dRho + rho)    * (cosPhi0 * d.x() + sinPhi0 * d.y())
02461     / dmag2 - 1.;
02462   dphida[2] = (- rho / kappa) * (sinPhi0 * d.x() - cosPhi0 * d.y())
02463     / dmag2;
02464   dphida[3] = 0.;
02465   dphida[4] = 0.;
02466   
02467   dxda[0] = cosPhi0 + rho * sinPhi0dPhi * dphida[0];
02468   dxda[1] = - (dRho + rho) * sinPhi0 + rho * sinPhi0dPhi * (1. + dphida[1]);
02469   dxda[2] = - rho / kappa * (cosPhi0 - cosPhi0dPhi)
02470     + rho * sinPhi0dPhi * dphida[2];
02471   dxda[3] = rho * sinPhi0dPhi * dphida[3];
02472   dxda[4] = rho * sinPhi0dPhi * dphida[4];
02473   
02474   dyda[0] = sinPhi0 - rho * cosPhi0dPhi * dphida[0];
02475   dyda[1] = (dRho + rho) * cosPhi0 - rho * cosPhi0dPhi * (1. + dphida[1]);
02476   dyda[2] = - rho / kappa * (sinPhi0 - sinPhi0dPhi)
02477     - rho * cosPhi0dPhi * dphida[2];
02478   dyda[3] = - rho * cosPhi0dPhi * dphida[3];
02479   dyda[4] = - rho * cosPhi0dPhi * dphida[4];
02480   
02481   dzda[0] = 0.;
02482   dzda[1] = 0.;
02483   dzda[2] = 0.;
02484   dzda[3] = 1.;
02485   dzda[4] = - rho * dPhi;
02486   //dzda[0] = - rho * tanLambda * dphida[0];
02487   //dzda[1] = - rho * tanLambda * dphida[1];
02488   //dzda[2] = rho / kappa * tanLambda * dPhi - rho * tanLambda * dphida[2];
02489   //dzda[3] = 1. - rho * tanLambda * dphida[3];
02490   //dzda[4] = - rho * dPhi - rho * tanLambda * dphida[4];
02491 
02492   return 0;
02493 }
02494 #endif
02495 #if 0
02496 int 
02497 TTrack::svdHitForCurl(AList<TSvdHit>& svdList) const
02498 {
02499   HepPoint3D center = _helix->center();
02500   double r  = fabs(_helix->curv());
02501 
02502   for(unsigned i = 0, size = svdList.length(); i < size; ++i){
02503     HepPoint3D p(svdList[i]->x(), svdList[i]->y(), 0.);
02504     double cosdPhi = - center.dot((p - center).unit()) / center.mag();
02505     double dPhi;
02506     if(fabs(cosdPhi) < 1.0){
02507       dPhi = acos(cosdPhi);
02508     }else if(cosdPhi >= 1.0){
02509       dPhi = 0.;
02510     }else{
02511       dPhi = M_PI;
02512     }
02513     HepPoint3D tmp(r*dPhi, svdList[i]->z(), 0.);
02514     svdList[i]->arcZ(tmp);
02515   }
02516   return 0;
02517 }
02518 #endif
02519 
02520 #if defined(__GNUG__)
02521 int
02522 SortByPt(const TTrack ** a, const TTrack ** b) {
02523     if ((* a)->pt() < (* b)->pt()) return 1;
02524     else if
02525         ((* a)->pt() == (* b)->pt()) return 0;
02526     else return -1;
02527 }
02528 #else
02529 extern "C" int
02530 SortByPt(const void* av, const void* bv) {
02531   const TTrack ** a((const TTrack **)av);
02532   const TTrack ** b((const TTrack **)bv);
02533     if ((* a)->pt() < (* b)->pt()) return 1;
02534     else if
02535         ((* a)->pt() == (* b)->pt()) return 0;
02536     else return -1;
02537 }
02538 #endif
02539 
02540 #if NEW_FIT2D
02541 int
02542 TTrack::fit2D(unsigned ipFlag, double ipDistance, double ipError) {
02543 #ifdef TRKRECO_DEBUG_DETAIL
02544   std::cout << "    TTrack::fit2D(r-phi) ..." << std::endl;
02545 #endif
02546   //if(_fitted)return 0;
02547 
02548   //...Check # of hits...
02549 
02550   //std::cout << "# = " << _links.length() << std::endl;
02551   //...Setup...
02552   unsigned nTrial(0);
02553   Vector a(_helix->a());
02554   double chi2;
02555   double chi2Old = 1.0e+99;
02556   Vector dchi2da(3);
02557   SymMatrix d2chi2d2a(3,0);
02558   Vector da(5), dxda(3), dyda(3);
02559   Vector dDda(3);
02560   const double convergence = 1.0e-5;
02561   Vector f(3);
02562   int err = 0;
02563   double factor = 1.0;
02564   unsigned usedWireNumber = 0;  
02565 
02566   //...Fitting loop...
02567   while(nTrial < 100){
02568     //...Set up...
02569     chi2 = 0.;
02570     for (unsigned j=0;j<3;++j) dchi2da[j] = 0.;
02571     d2chi2d2a = SymMatrix(3, 0);
02572     usedWireNumber = 0;
02573 
02574     //...Loop with hits...
02575     unsigned i = 0;
02576     while (TMLink * l = _links[i++]) {
02577       if(l->fit2D() == 0)continue;
02578       const TMDCWireHit &h = *l->hit();
02579       
02580       //...Cal. closest points...
02581       if(approach2D(*l) != 0)continue;
02582       double dPhi = l->dPhi();
02583       const HepPoint3D & onTrack = l->positionOnTrack();
02584       const HepPoint3D & onWire  = l->positionOnWire();
02585       HepPoint3D onTrack2(onTrack.x(),onTrack.y(),0.);
02586       HepPoint3D onWire2(onWire.x(),onWire.y(),0.);
02587 
02588       //...Obtain drift distance and its error...
02589       unsigned leftRight = WireHitRight;
02590       if (onWire2.cross(onTrack2).z() < 0.) leftRight = WireHitLeft;
02591       double distance   = h.drift(leftRight);
02592       double eDistance  = h.dDrift(leftRight);
02593       double eDistance2 = eDistance * eDistance;
02594       if(eDistance == 0.){
02595         std::cout << "Error(?) : Drift Distance Error = 0 in fit2D of TrkReco." << std::endl;
02596         continue;
02597       }
02598 
02599       //...Residual...
02600       HepVector3D v = onTrack2 - onWire2;
02601       double vmag = v.mag();
02602       double dDistance = vmag - distance;
02603 
02604       //...dxda...
02605       if(this->dxda2D(*l, dPhi, dxda, dyda) != 0)continue;
02606 
02607       //...Chi2 related...
02608       //Vector3 vw(0.,0.,1.);
02609       dDda = (vmag > 0.)
02610         ? (v.x()*dxda+v.y()*dyda)/vmag
02611         : Vector(3,0);
02612       if(vmag<=0.0){
02613         std::cout << "    in fit2D " << onTrack << ", " << onWire;
02614         h.dump();
02615         continue;
02616       }
02617       dchi2da     += (dDistance/eDistance2)*dDda;
02618       d2chi2d2a   += vT_times_v(dDda)/eDistance2;
02619       double pChi2 = dDistance*dDistance/eDistance2;
02620       chi2        += pChi2;
02621       
02622       //...Store results...
02623       l->update(onTrack2, onWire2, leftRight, pChi2);
02624       ++usedWireNumber;
02625     }
02626     if(ipFlag != 0){
02627       double kappa = _helix->a()[2];
02628       double phi0  = _helix->a()[1];
02629       HepPoint3D xc(_helix->center());
02630       HepPoint3D onWire(0.,0.,0.);
02631       HepPoint3D xt(_helix->x());
02632       HepVector3D v0(xt-xc);
02633       HepVector3D v1(onWire-xc);
02634       double vCrs = v0.x() * v1.y() - v0.y() * v1.x();
02635       double vDot = v0.x() * v1.x() + v0.y() * v1.y();
02636       double dPhi = atan2(vCrs, vDot);      
02637       HepPoint3D onTrack(_helix->x(dPhi).x(),_helix->x(dPhi).y(),0.);
02638       double distance   = ipDistance;
02639       double eDistance  = ipError;
02640       double eDistance2 = eDistance * eDistance;
02641 
02642       HepVector3D v = onTrack - onWire;
02643       double vmag = v.mag();
02644       double dDistance = vmag - distance;
02645 
02646       if(this->dxda2D(dPhi, dxda, dyda) != 0)goto ipOff;
02647       
02648       dDda = (vmag > 0.)
02649         ? (v.x()*dxda+v.y()*dyda)/vmag
02650         : Vector(3,0);
02651       if(vmag<=0.0){
02652         goto ipOff;
02653       }
02654       dchi2da     += (dDistance/eDistance2)*dDda;
02655       d2chi2d2a   += vT_times_v(dDda)/eDistance2;
02656       double pChi2 = dDistance*dDistance/eDistance2;
02657       chi2        += pChi2;
02658       
02659       ++usedWireNumber;
02660     }
02661   ipOff:
02662     if(usedWireNumber < 4){
02663       err = -2;
02664       break;
02665     }
02666 
02667     //...Check condition...
02668     double change = chi2Old - chi2;
02669     if(fabs(change) < convergence)break;
02670     if(change < 0.){
02671 #ifdef TRKRECO_DEBUG_DETAIL
02672       std::cout << "chi2Old, chi2=" << chi2Old <<" "<< chi2 << std::endl;
02673 #endif
02674       //change to the old value.
02675       a += factor*da;
02676       _helix->a(a);
02677 
02678       chi2 = 0.;
02679       for (unsigned j=0;j<3;++j) dchi2da[j] = 0.;
02680       d2chi2d2a = SymMatrix(3,0);
02681       usedWireNumber = 0;
02682    
02683       //...Loop with hits...
02684       unsigned i = 0;
02685       while (TMLink *l = _links[i++]) {
02686         if(l->fit2D() == 0)continue;
02687         const TMDCWireHit & h = * l->hit();
02688         
02689         //...Cal. closest points...
02690         if(approach2D(*l) != 0)continue;
02691         double dPhi = l->dPhi();
02692         const HepPoint3D & onTrack = l->positionOnTrack();
02693         const HepPoint3D & onWire  = l->positionOnWire();
02694         HepPoint3D onTrack2(onTrack.x(),onTrack.y(),0.);
02695         HepPoint3D onWire2(onWire.x(),onWire.y(),0.);
02696         
02697         //...Obtain drift distance and its error...
02698         unsigned leftRight = WireHitRight;
02699         if (onWire2.cross(onTrack2).z() < 0.) leftRight = WireHitLeft;
02700         double distance   = h.drift(leftRight);
02701         double eDistance  = h.dDrift(leftRight);
02702         double eDistance2 = eDistance * eDistance;
02703             
02704         //...Residual...
02705         HepVector3D v = onTrack2 - onWire2;
02706         double vmag = v.mag();
02707         double dDistance = vmag - distance;
02708 
02709         //...dxda...
02710         if(this->dxda2D(*l, dPhi, dxda, dyda) != 0)continue;
02711 
02712         //...Chi2 related...
02713         dDda = (vmag>0.)
02714           ? (v.x()*dxda + v.y()*dyda)/vmag
02715           : Vector(3,0);
02716         if(vmag<=0.0) {
02717           std::cout << "    in fit2D " << onTrack << ", " << onWire;
02718           h.dump();
02719           continue;
02720         }
02721         dchi2da     += (dDistance/eDistance2)*dDda;
02722         d2chi2d2a   += vT_times_v(dDda)/eDistance2;
02723         double pChi2 = dDistance*dDistance/eDistance2;
02724         chi2        += pChi2;
02725         
02726         //...Store results...
02727         l->update(onTrack2, onWire2, leftRight, pChi2);
02728         ++usedWireNumber;
02729       }
02730       if(ipFlag != 0){
02731         double kappa = _helix->a()[2];
02732         double phi0  = _helix->a()[1];
02733         HepPoint3D xc(_helix->center());
02734         HepPoint3D onWire(0.,0.,0.);
02735         HepPoint3D xt(_helix->x());
02736         HepVector3D v0(xt-xc);
02737         HepVector3D v1(onWire-xc);
02738         double vCrs = v0.x() * v1.y() - v0.y() * v1.x();
02739         double vDot = v0.x() * v1.x() + v0.y() * v1.y();
02740         double dPhi = atan2(vCrs, vDot);      
02741         HepPoint3D onTrack(_helix->x(dPhi).x(),_helix->x(dPhi).y(),0.);
02742         double distance   = ipDistance;
02743         double eDistance  = ipError;
02744         double eDistance2 = eDistance * eDistance;
02745         
02746         HepVector3D v = onTrack - onWire;
02747         double vmag = v.mag();
02748         double dDistance = vmag - distance;
02749         
02750         if(this->dxda2D(dPhi, dxda, dyda) != 0)goto ipOff2;
02751         
02752         dDda = (vmag > 0.)
02753           ? (v.x()*dxda+v.y()*dyda)/vmag
02754           : Vector(3,0);
02755         if(vmag<=0.0){
02756           goto ipOff2;
02757         }
02758         dchi2da     += (dDistance/eDistance2)*dDda;
02759         d2chi2d2a   += vT_times_v(dDda)/eDistance2;
02760         double pChi2 = dDistance*dDistance/eDistance2;
02761         chi2        += pChi2;
02762         
02763         ++usedWireNumber;
02764       }
02765     ipOff2:
02766       if(usedWireNumber < 4){
02767         err = -2;
02768         break;
02769       }
02770       //break;
02771       factor *= 0.75;
02772 #ifdef TRKRECO_DEBUG_DETAIL 
02773       std::cout << "factor = " << factor << std::endl;
02774       std::cout << "chi2 = " << chi2 << std::endl;
02775 #endif
02776       if(factor < 0.01)break;
02777     }
02778 
02779     chi2Old = chi2;
02780 
02781     //...Cal. helix parameters for next loop...
02782     f = solve(d2chi2d2a, dchi2da);
02783     da[0] = f[0];
02784     da[1] = f[1];
02785     da[2] = f[2];
02786     da[3] = 0.;
02787     da[4] = 0.;
02788     
02789     a -= factor*da;
02790     _helix->a(a);      
02791     ++nTrial;
02792   }
02793   if(err){
02794     return err;
02795   }
02796 
02797   //...Cal. error matrix...
02798   SymMatrix Ea(5,0);
02799   unsigned dim = 3;
02800   SymMatrix Eb = d2chi2d2a;
02801   SymMatrix Ec = Eb.inverse(err);
02802   Ea[0][0] = Ec[0][0];
02803   Ea[0][1] = Ec[0][1];
02804   Ea[0][2] = Ec[0][2];
02805   Ea[1][1] = Ec[1][1];
02806   Ea[1][2] = Ec[1][2];
02807   Ea[2][2] = Ec[2][2];
02808 
02809   //...Store information...
02810   if(!err){
02811     _helix->a(a);
02812     _helix->Ea(Ea);
02813   }else{
02814     err = -2;
02815   }
02816     
02817   _ndf  = usedWireNumber-dim;
02818   _chi2 = chi2;
02819     
02820   //_fitted = true;
02821 
02822 #define JJJTEST 0
02823 #if JJJTEST
02824   double gmaxX = -9999. ,gminX = 9999.;
02825   double gmaxY = -9999. ,gminY = 9999.;
02826   FILE *gnuplot, *data;
02827   double step = 200.;
02828   double dStep = 2.*M_PI/step;
02829   for(int i=0,size = _links.length();i<size;++i){
02830     TMLink * l = _links[i];
02831     double drift = l->hit()->distance(0);
02832     char name[100] = "dat";
02833     char counter[10] = "";
02834     sprintf(counter,"%02d",i);
02835     strcat(name,counter);
02836     if((data = fopen(name,"w")) != NULL){
02837       for(int ii=0;ii<step;++ii){
02838         double X = l->wire()->xyPosition().x() + drift*cos(dStep*static_cast<double>(ii));
02839         double Y = l->wire()->xyPosition().y() + drift*sin(dStep*static_cast<double>(ii));
02840         fprintf(data,"%lf, %lf\n",X,Y);
02841         if(gmaxX < X)gmaxX = X;
02842         if(gminX > X)gminX = X;
02843         if(gmaxY < Y)gmaxY = Y;
02844         if(gminY > Y)gminY = Y;
02845       }
02846       fclose(data);
02847     }
02848   }
02849   step = 300.;
02850   dStep = 2.*M_PI/step;
02851   if((data = fopen("datc","w")) != NULL){
02852     for(int ii=0;ii<step;++ii){
02853       double X = _helix->center().x() + _helix->radius()*cos(dStep*static_cast<double>(ii));
02854       double Y = _helix->center().y() + _helix->radius()*sin(dStep*static_cast<double>(ii));
02855       fprintf(data,"%lf, %lf\n",X,Y);
02856     }
02857     fclose(data);
02858   }
02859   if((gnuplot = popen("gnuplot","w")) != NULL){
02860     fprintf(gnuplot,"set size 0.721,1.0 \n");
02861     fprintf(gnuplot,"set xrange [%f:%f] \n",gminX,gmaxX);
02862     fprintf(gnuplot,"set yrange [%f:%f] \n",gminY,gmaxY);
02863     if(_links.length() == 4){
02864       fprintf(gnuplot,"plot \"datc\" with line, \"dat00\" with line, \"dat01\" with line, \"dat02\" with line, \"dat03\" with line \n");
02865     }else if(_links.length() == 5){
02866       fprintf(gnuplot,"plot \"datc\" with line, \"dat00\" with line, \"dat01\" with line, \"dat02\" with line, \"dat03\" with line, \"dat04\" with line \n");
02867     }else if(_links.length() == 6){
02868       fprintf(gnuplot,"plot \"datc\" with line, \"dat00\" with line, \"dat01\" with line, \"dat02\" with line, \"dat03\" with line, \"dat04\" with line, \"dat05\" with line \n");
02869     }else if(_links.length() == 7){
02870       fprintf(gnuplot,"plot \"datc\" with line, \"dat00\" with line, \"dat01\" with line, \"dat02\" with line, \"dat03\" with line, \"dat04\" with line, \"dat05\" with line, \"dat06\" with line \n");
02871     }else if(_links.length() == 8){
02872       fprintf(gnuplot,"plot \"datc\" with line, \"dat00\" with line, \"dat01\" with line, \"dat02\" with line, \"dat03\" with line, \"dat04\" with line, \"dat05\" with line, \"dat06\" with line, \"dat07\" with line \n");
02873     }else if(_links.length() == 9){
02874       fprintf(gnuplot,"plot \"datc\" with line, \"dat00\" with line, \"dat01\" with line, \"dat02\" with line, \"dat03\" with line, \"dat04\" with line, \"dat05\" with line, \"dat06\" with line, \"dat07\" with line, \"dat08\" with line \n");
02875     }else if(_links.length() == 10){
02876       fprintf(gnuplot,"plot \"datc\" with line, \"dat00\" with line, \"dat01\" with line, \"dat02\" with line, \"dat03\" with line, \"dat04\" with line, \"dat05\" with line, \"dat06\" with line, \"dat07\" with line, \"dat08\" with line, \"dat09\" with line \n");
02877     }else if(_links.length() >= 11){
02878       fprintf(gnuplot,"plot \"datc\" with line, \"dat00\" with line, \"dat01\" with line, \"dat02\" with line, \"dat03\" with line, \"dat04\" with line, \"dat05\" with line, \"dat06\" with line, \"dat07\" with line, \"dat08\" with line, \"dat09\" with line, \"dat10\" with line \n");
02879     }
02880     fflush(gnuplot);
02881     char tmp[8];
02882     gets(tmp);
02883     pclose(gnuplot);
02884   }
02885 #endif //JJJTEST
02886 
02887   return err;
02888 }
02889 
02890 int 
02891 TTrack::approach2D(TMLink &l) const {
02892 
02893   const TMDCWire &w = *l.wire();
02894   double kappa = _helix->a()[2];
02895   double phi0  = _helix->a()[1];
02896   HepPoint3D xc(_helix->center());
02897   HepPoint3D xw(w.xyPosition());
02898   HepPoint3D xt(_helix->x());
02899   HepVector3D v0(xt-xc);
02900   HepVector3D v1(xw-xc);
02901 
02902   double vCrs = v0.x() * v1.y() - v0.y() * v1.x();
02903   double vDot = v0.x() * v1.x() + v0.y() * v1.y();
02904   double dPhi = atan2(vCrs, vDot);
02905 
02906   xt = _helix->x(dPhi);
02907   xt.setZ(0.);
02908   l.positionOnTrack(xt);
02909   xw.setZ(0.);
02910   l.positionOnWire(xw);
02911   l.dPhi(dPhi);
02912   return 0;
02913 }
02914 
02915 int
02916 TTrack::dxda2D(const TMLink & link,
02917                double dPhi,
02918                Vector & dxda,
02919                Vector & dyda) const {
02920   
02921   //...Setup...
02922   double kappa = (_helix->a())[2];
02923   if(kappa == 0.){
02924     std::cout << "Error(?) : kappa == 0 in dxda2D of TrkReco." << std::endl;
02925     return 1;
02926   }
02927   const TMDCWire &w = *link.wire();
02928   double dRho  = (_helix->a())[0];
02929   double phi0  = (_helix->a())[1];
02930  // double rho   = Helix::ConstantAlpha / kappa;
02931  // double rho   = 333.564095 / kappa;
02932   const double Bz = -1000*m_pmgnIMF->getReferField();
02933   double rho   = 333.564095/(kappa * Bz);  
02934 
02935   double sinPhi0 = sin(phi0);
02936   double cosPhi0 = cos(phi0);
02937   double sinPhi0dPhi = sin(phi0 + dPhi);
02938   double cosPhi0dPhi = cos(phi0 + dPhi);
02939   Vector dphida(3);
02940   
02941   HepPoint3D d = _helix->center() - w.xyPosition();
02942   d.setZ(0.);
02943   double dmag2 = d.mag2();
02944   
02945   if(dmag2 == 0.){
02946     std::cout << "Error(?) : Distance(center-xyPosition) == 0 in dxda2D of TrkReco." << std::endl;
02947     return 1;
02948   }
02949 
02950   dphida[0] = (sinPhi0*d.x()-cosPhi0*d.y())/dmag2;
02951   dphida[1] = (dRho+rho)*(cosPhi0*d.x()+sinPhi0 * d.y())/dmag2 - 1.;
02952   dphida[2] = (-rho/kappa)*(sinPhi0*d.x()-cosPhi0*d.y())/dmag2;
02953   
02954   dxda[0] = cosPhi0+rho*sinPhi0dPhi*dphida[0];
02955   dxda[1] = -(dRho+rho)*sinPhi0+rho*sinPhi0dPhi*(1.+dphida[1]);
02956   dxda[2] = -rho/kappa*(cosPhi0-cosPhi0dPhi)+rho*sinPhi0dPhi*dphida[2];
02957 
02958   dyda[0] = sinPhi0-rho*cosPhi0dPhi*dphida[0];
02959   dyda[1] = (dRho+rho)*cosPhi0-rho*cosPhi0dPhi*(1.+dphida[1]);
02960   dyda[2] = -rho/kappa*(sinPhi0-sinPhi0dPhi)-rho*cosPhi0dPhi*dphida[2];
02961   
02962   return 0;
02963 }
02964 
02965 int
02966 TTrack::dxda2D(double dPhi,
02967                Vector & dxda,
02968                Vector & dyda) const {
02969   
02970   //...Setup...
02971   double kappa = (_helix->a())[2];
02972   if(kappa == 0.){
02973     std::cout << "Error(?) : kappa == 0 in dxda2D of TrkReco." << std::endl;
02974     return 1;
02975   }
02976   double dRho  = (_helix->a())[0];
02977   double phi0  = (_helix->a())[1];
02978  // double rho   = Helix::ConstantAlpha / kappa;
02979  // double rho   = 333.564095 / kappa;  
02980   const double Bz = -1000*m_pmgnIMF->getReferField();
02981   double rho   = 333.564095/(kappa * Bz); 
02982 
02983   double sinPhi0 = sin(phi0);
02984   double cosPhi0 = cos(phi0);
02985   double sinPhi0dPhi = sin(phi0 + dPhi);
02986   double cosPhi0dPhi = cos(phi0 + dPhi);
02987   Vector dphida(3);
02988   
02989   HepPoint3D d = _helix->center(); // d = center - (0,0,0)
02990   d.setZ(0.);
02991   double dmag2 = d.mag2();
02992   
02993   if(dmag2 == 0.){
02994     std::cout << "Error(?) : Distance(center-xyPosition) == 0 in dxda2D of TrkReco." << std::endl;
02995     return 1;
02996   }
02997 
02998   dphida[0] = (sinPhi0*d.x()-cosPhi0*d.y())/dmag2;
02999   dphida[1] = (dRho+rho)*(cosPhi0*d.x()+sinPhi0 * d.y())/dmag2 - 1.;
03000   dphida[2] = (-rho/kappa)*(sinPhi0*d.x()-cosPhi0*d.y())/dmag2;
03001   
03002   dxda[0] = cosPhi0+rho*sinPhi0dPhi*dphida[0];
03003   dxda[1] = -(dRho+rho)*sinPhi0+rho*sinPhi0dPhi*(1.+dphida[1]);
03004   dxda[2] = -rho/kappa*(cosPhi0-cosPhi0dPhi)+rho*sinPhi0dPhi*dphida[2];
03005 
03006   dyda[0] = sinPhi0-rho*cosPhi0dPhi*dphida[0];
03007   dyda[1] = (dRho+rho)*cosPhi0-rho*cosPhi0dPhi*(1.+dphida[1]);
03008   dyda[2] = -rho/kappa*(sinPhi0-sinPhi0dPhi)-rho*cosPhi0dPhi*dphida[2];
03009   
03010   return 0;
03011 }
03012 #endif
03013 
03014 unsigned
03015 TTrack::defineType(void) const {
03016     bool highPt = true;
03017     if (pt() < 0.2) highPt = false;     //Bes
03018     bool fromIP = true;
03019     if (fabs(impact()) > 8.3) fromIP = false;
03020 
03021     if (fromIP && highPt) return _type = TrackTypeNormal;
03022     else if (fromIP && (! highPt)) return _type = TrackTypeCurl;
03023 
03024     if ((fabs(radius()) * 2. + fabs(impact())) < 81.)  //Bes
03025         return _type = TrackTypeCircle;
03026     return _type = TrackTypeCosmic;
03027 }
03028 
03029 std::string
03030 TrackType(unsigned type) {
03031     switch (type) {
03032     case TrackTypeUndefined:
03033         return std::string("undefined");
03034     case TrackTypeNormal:
03035         return std::string("normal");
03036     case TrackTypeCurl:
03037         return std::string("curl  ");
03038     case TrackTypeCircle:
03039         return std::string("circle");
03040     case TrackTypeCosmic:
03041         return std::string("cosmic");
03042     }
03043     return std::string("unknown  ");
03044 }
03045 
03046 #ifdef OPTNK
03047 #define t_dot(a,b) (a[0]*b[0]+a[1]*b[1]+a[2]*b[2])
03048 #define t_dot2(a,b) (a[0]*b[0]+a[1]*b[1])
03049 #define t_print(a,b) std::cout << b << " = " << a[0] << " " << a[1] << " " << a[2] << std::endl;
03050 #endif
03051 
03052 //#define TRKRECO_DEBUG
03053 #ifdef TRKRECO_DEBUG
03054 //#include "tuple/BelleTupleManager.h"
03055 //BelleHistogram * h_nTrial;
03056 #endif
03057 
03058 int 
03059 TTrack::approach(TMLink & link, bool doSagCorrection) const {
03060     //...Cal. dPhi to rotate...
03061     const TMDCWire & w = * link.wire();
03062     double wp[3]; w.xyPosition(wp);
03063     double wb[3]; w.backwardPosition(wb);
03064     double v[3];
03065     v[0] = w.direction().x();
03066     v[1] = w.direction().y();
03067     v[2] = w.direction().z();
03068     //...Sag correction...
03069     if (doSagCorrection) {
03070         HepVector3D dir = w.direction();
03071         HepPoint3D xw(wp[0], wp[1], wp[2]);
03072         HepPoint3D wireBackwardPosition(wb[0], wb[1], wb[2]);
03073         w.wirePosition(link.positionOnTrack().z(),
03074                        xw,
03075                        wireBackwardPosition,
03076                        dir);
03077         v[0] = dir.x();
03078         v[1] = dir.y();
03079         v[2] = dir.z();
03080         wp[0] = xw.x();
03081         wp[1] = xw.y();
03082         wp[2] = xw.z();
03083         wb[0] = wireBackwardPosition.x();
03084         wb[1] = wireBackwardPosition.y();
03085         wb[2] = wireBackwardPosition.z();
03086     }
03087     //...Cal. dPhi to rotate...
03088     const HepPoint3D & xc = _helix->center();
03089     double xt[3]; _helix->x(0., xt);
03090     double x0 = - xc.x();
03091     double y0 = - xc.y();
03092     double x1 = wp[0] + x0;
03093     double y1 = wp[1] + y0;
03094     x0 += xt[0];
03095     y0 += xt[1];
03096     double dPhi = atan2(x0 * y1 - y0 * x1, x0 * x1 + y0 * y1);
03097     //...Setup...
03098     double kappa = _helix->kappa();
03099     double phi0 = _helix->phi0();
03100 //yzhang 2012-08-30
03101     //...Axial case...
03102 //    if (w.axial()) {
03103 //      link.positionOnTrack(_helix->x(dPhi));
03104 //      HepPoint3D x(wp[0], wp[1], wp[2]);
03105 //      x.setZ(link.positionOnTrack().z());
03106 //      link.positionOnWire(x);
03107 //      link.dPhi(dPhi);
03108 //      return 0;
03109 //    }
03110 #ifdef TRKRECO_DEBUG
03111     double firstdfdphi = 0.;
03112     static bool first = true;
03113     if (first) {
03114 //      extern BelleTupleManager * BASF_Histogram;
03115 //      BelleTupleManager * m = BASF_Histogram;
03116 //      h_nTrial = m->histogram("TTrack::approach nTrial", 100, 0., 100.);
03117     }
03118 #endif
03119 
03120     //...Stereo case...
03121     // double rho = Helix::ConstantAlpha / kappa;
03122     // double rho = 333.564095 / kappa;
03123     // yzhang 2012-05-03 delete
03124     //double rho = 333.564095/  kappa;
03125     //yzhang add 
03126     Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF);
03127     if(m_pmgnIMF==NULL) {
03128       std::cout<< __FILE__<<" "<<__LINE__<<" Unable to open Magnetic field service"<<std::endl;
03129     }
03130     const double Bz = -1000*m_pmgnIMF->getReferField();
03131     double rho   = 333.564095/(kappa * Bz); 
03132     //zhangy
03133     double tanLambda = _helix->tanl();
03134     static Vector x(3);
03135     double t_x[3];
03136     double t_dXdPhi[3];
03137     const double convergence = 1.0e-5;
03138     double l;
03139     unsigned nTrial = 0;
03140     while (nTrial < 100) {
03141 
03142         x = link.positionOnTrack(_helix->x(dPhi));
03143         t_x[0] = x[0];
03144         t_x[1] = x[1];
03145         t_x[2] = x[2];
03146 
03147         l = v[0] * t_x[0] + v[1] * t_x[1] + v[2] * t_x[2]
03148             - v[0] * wb[0] - v[1] * wb[1] - v[2] * wb[2];
03149 
03150         double rcosPhi = rho * cos(phi0 + dPhi);
03151         double rsinPhi = rho * sin(phi0 + dPhi);
03152         t_dXdPhi[0] =   rsinPhi;
03153         t_dXdPhi[1] = - rcosPhi;
03154         t_dXdPhi[2] = - rho * tanLambda;
03155 
03156         //...f = d(Distance) / d phi...
03157         double t_d2Xd2Phi[2];
03158         t_d2Xd2Phi[0] = rcosPhi;
03159         t_d2Xd2Phi[1] = rsinPhi;
03160 
03161         //...iw new...
03162         double n[3];
03163         n[0] = t_x[0] - wb[0];
03164         n[1] = t_x[1] - wb[1];
03165         n[2] = t_x[2] - wb[2];
03166         
03167         double a[3];
03168         a[0] = n[0] - l * v[0];
03169         a[1] = n[1] - l * v[1];
03170         a[2] = n[2] - l * v[2];
03171         double dfdphi = a[0] * t_dXdPhi[0]
03172             + a[1] * t_dXdPhi[1]
03173             + a[2] * t_dXdPhi[2];
03174 
03175 #ifdef TRKRECO_DEBUG
03176         if (nTrial == 0) {
03177 //          break;
03178             firstdfdphi = dfdphi;
03179         }
03180 
03181         //...Check bad case...
03182         if (nTrial > 3) {
03183             std::cout << "TTrack::approach ... " << w.name() << " "
03184                       << "dfdphi(0)=" << firstdfdphi
03185                       << ",(" << nTrial << ")=" << dfdphi << endl;
03186         }
03187 #endif
03188 
03189         //...Is it converged?...
03190         if (fabs(dfdphi) < convergence)
03191             break;
03192 
03193         double dv = v[0] * t_dXdPhi[0]
03194             + v[1] * t_dXdPhi[1]
03195             + v[2] * t_dXdPhi[2];
03196         double t0 = t_dXdPhi[0] * t_dXdPhi[0]
03197             + t_dXdPhi[1] * t_dXdPhi[1]
03198             + t_dXdPhi[2] * t_dXdPhi[2];
03199         double d2fd2phi = t0 - dv * dv
03200             + a[0] * t_d2Xd2Phi[0]
03201             + a[1] * t_d2Xd2Phi[1];
03202 //          + a[2] * t_d2Xd2Phi[2];
03203 
03204         dPhi -= dfdphi / d2fd2phi;
03205 
03206 //      cout << "nTrial=" << nTrial << endl;
03207 //      cout << "iw f,df,dphi=" << dfdphi << "," << d2fd2phi << "," << dPhi << endl;
03208 
03209         ++nTrial;
03210     }
03211 
03212     //...Cal. positions...
03213     link.positionOnWire(HepPoint3D(wb[0] + l * v[0],
03214                                 wb[1] + l * v[1],
03215                                 wb[2] + l * v[2]));
03216     link.dPhi(dPhi);
03217 
03218 #ifdef TRKRECO_DEBUG
03219 //    h_nTrial->accumulate((float) nTrial + .5);
03220 #endif
03221 
03222     return nTrial;
03223 }
03224 
03225 /*
03226 void 
03227 TTrack::relationClusterWithWire(){
03228 //----------------------------------------------------------
03229 // Note: Selection of associating cluster to TMLink is done.
03230 //       if appropriate cluster was found ,
03231 //       relation to cluster is set to the TMLink.
03232 //----------------------------------------------------------
03233 
03234   int j = 0;
03235   while( TMLink *l = _links[j] ) {
03236 
03237   // initialization
03238    int flag(-1);
03239    l->setusecathode(0);
03240    double dPhi = l->dPhi();
03241    l->setZphiBeforeCathode( _helix->x(dPhi).z() );
03242 
03243    int k1  = 0;
03244    while( TMDCCatHit *c = _catHits[k1] ){
03245 
03246    // Matching of layer 
03247     if( c->layerID() != l->hit()->wire()->layerId() ) {
03248        k1++; continue;
03249        }
03250 
03251    // Matching of wire hit 
03252     AList<TMDCWireHit>& cwire = c->candwire();
03253     AList<TMDCClust>&  cclust = c->candclust();
03254 
03255     if( cwire.length() == 0 || cclust.length() == 0 ){
03256         k1++; continue;
03257        }
03258 
03259     int k2 = 0;
03260     while( TMDCWireHit *cw = cwire[k2] ){
03261       if( cw == l->hit() ){  flag = 1; break; }
03262         k2++;
03263      }
03264 
03265     if( flag == -1 ){
03266        k1++; continue;
03267     }
03268 
03269    // Selection of cluster
03270     flag = -1;
03271     float cand_sector = CathodeSectorId( cwire[k2]->wire()->id());
03272 
03273     // --- debug ---
03274     //      std::cout << "cand_sector = " << cand_sector << std::endl;
03275     //--- debug ---
03276 
03277     cand_sector = cand_sector - (int(cand_sector/8))*8;
03278 
03279     // --- debug ---
03280     // std::cout << "cand_sector(local) = " << cand_sector << std::endl;
03281     // --- debug ---
03282 
03283     int count_at_boundary(0);
03284     float tmaxpad_at_boundary(0.);
03285     TMDCClust * cc_at_boundary = NULL;
03286 
03287     k2 = 0;
03288     while( TMDCClust *cc = cclust[k2] ){
03289 
03290       unsigned cathit_sector = cc->maxpad()->sectorId();
03291       
03292     if( cand_sector == float(cathit_sector) ) {
03293       l->setusecathode(1);  l->setmclust(cc); break ;
03294     } else if( abs( cand_sector - float(cathit_sector)) == 0.5 ) {
03295 
03296         count_at_boundary += 1;
03297         l->setusecathode(1);
03298         l->setmclust(cc);
03299 
03300         if( count_at_boundary == 1 ) {
03301               cc_at_boundary = cc;
03302               tmaxpad_at_boundary = cc->tmaxpad();
03303         }
03304 
03305         //.. if 2 candidates exist at sector boundary,
03306         //   choose the best matching of T between cluster and wire 
03307         if( count_at_boundary == 2 ) {
03308           if( fabs( cc->tmaxpad() - l->hit()->reccdc()->m_tdc )
03309             > fabs( tmaxpad_at_boundary - l->hit()->reccdc()->m_tdc ) )
03310               l->setmclust(cc_at_boundary);
03311           break;
03312          }
03313 
03314     }
03315 
03316          k2++;
03317         }
03318     k1++;
03319     } // TMDCCatHit loop
03320 
03321    j++;
03322    } // TMLink loop
03323 
03324 }
03325 
03326 // addition by matsu ( 1999/07/05 )
03327 void TTrack::relationClusterWithLayer( int SysCorr ){
03328 
03329     //... selection of cathode cluster
03330     for(unsigned it0=0;it0<3;it0++){
03331     
03332       AList<TMLink> catLink = SameLayer( cores(), it0 );
03333 
03334       unsigned n(catLink.length());
03335       if( !n ) continue;
03336 
03337       int BestID(-1);
03338 
03339       double tmpz(DBL_MAX);
03340       for(unsigned it1=0;it1<n;it1++){
03341         TMLink & l = * catLink[it1];
03342 
03343        if( l.getmclust() && l.usecathode() != 0 ){
03344 
03345           l.setusecathode(2);
03346 
03347           double Zdiff(l.positionOnTrack().z());
03348           if(SysCorr ) Zdiff -=  l.getmclust()->zclustWithSysCorr();
03349           else         Zdiff -=  l.getmclust()->zclust();
03350           if( fabs(Zdiff) < tmpz ){
03351           tmpz = fabs(Zdiff);  BestID = it1;
03352           }
03353        }
03354       }
03355 
03356    if( BestID == -1 ) continue;
03357 
03358      for(unsigned it1=0;it1<n;it1++){
03359      TMLink & l = * catLink[it1];
03360      if( l.getmclust() && l.usecathode() != 0 ){
03361         if( it1 == BestID ) {
03362           l.setusecathode(3); break;
03363         }
03364        }
03365      }
03366    }
03367 }
03368 */
03369 
03370 
03371 int
03372 TTrack::szPosition(TMLink & link) const {
03373     const TMDCWireHit & h = * link.hit();
03374     HepVector3D X = 0.5 * (h.wire()->forwardPosition()
03375                         + h.wire()->backwardPosition());
03376     //    double theta = atan2(X.y(), X.x());
03377     //    HepVector3D lr(h.distance(WireHitLeft) * sin(theta),
03378     //          - h.distance(WireHitLeft) * cos(theta),
03379     //          0.);
03380 
03381     HepVector3D xx = HepVector3D(X.x(), X.y(), 0.);
03382     HepPoint3D center = _helix->center();
03383     HepVector3D yy = center - xx;
03384     HepVector3D ww = HepVector3D(yy.x(), yy.y(), 0.);
03385     double wwmag2 = ww.mag2();
03386     double wwmag = sqrt(wwmag2);
03387     HepVector3D lr(h.drift(WireHitLeft)/wwmag * ww.x(),
03388                 h.drift(WireHitLeft)/wwmag * ww.y(),
03389                 0.);
03390  
03391 #ifdef TRKRECO_DEBUG_DETAIL
03392     std::cout<<"old lr "<<lr<<endl;
03393     std::cout<<"old X "<<X<<endl;
03394     std::cout<<"link.leftRight "<<link.leftRight()<<endl;
03395 #endif
03396     //...Check left or right...
03397     //   // change to bes3 .. test..
03398     //if (link.leftRight() == WireHitRight) {
03399     //lr = - lr;
03400     //}
03401     //if (link.leftRight() == WireHitLeft) lr = - lr; 
03402     //else if (link.leftRight() == 2) lr = ORIGIN;
03403 
03404     //yzhang 2012-05-07 
03405     const double Bz = -1000*m_pmgnIMF->getReferField();
03406 #ifdef TRKRECO_DEBUG_DETAIL
03407     std::cout<<"charge "<<_charge<<" Bz "<<Bz<<endl;
03408 #endif
03409     if (_charge*Bz > 0){ //yzhang 2012-05-07 
03410       if (link.leftRight() == WireHitRight){
03411         lr = - lr;//right
03412       }
03413     }else{
03414       if (link.leftRight() == WireHitLeft){
03415         lr = - lr;//left
03416       }
03417     }
03418     if (link.leftRight() == 2) lr = ORIGIN;
03419     //zhangy
03420 
03421     X += lr;
03422 
03423     //...Prepare vectors...
03424     //    HepPoint3D center = _helix->center();
03425     HepPoint3D tmp(-9999., -9999., 0.);
03426     HepVector3D x = HepVector3D(X.x(), X.y(), 0.);
03427     HepVector3D w = x - center;
03428     // //modified the next sentence because the direction are different from belle.
03429     HepVector3D V = h.wire()->direction();
03430     //    //    to bes3
03431     // //    HepVector3D V = - h.wire()->direction();   
03432 
03433     HepVector3D v = HepVector3D(V.x(), V.y(), 0.);
03434     double vmag2 = v.mag2();
03435     double vmag = sqrt(vmag2);
03436     
03437     double r = _helix->curv();
03438     double wv = w.dot(v);
03439     //    //zsl for bes3
03440     //    wv = abs(wv);
03441     double d2 = wv * wv - vmag2 * (w.mag2() - r * r);
03442 #ifdef TRKRECO_DEBUG_DETAIL
03443     std::cout<<"lr "<<lr<<endl;
03444     std::cout<<"forwardPosition "<<h.wire()->forwardPosition()<<endl;
03445     std::cout<<"backwardPosition "<<h.wire()->backwardPosition()<<endl;
03446     std::cout<<"X "<<X<<endl;
03447     std::cout<<"center "<<center<<endl;
03448     std::cout<<"xx "<<xx<<endl;
03449     std::cout<<"ww "<<ww<<endl;
03450     std::cout<<"TTrack::wire direction:"<<h.wire()->direction()<<endl;
03451     std::cout<<"x "<<x<<endl;
03452     std::cout<<"w "<<w<<endl;
03453     std::cout<<"sz,Track::vmag:"<<vmag<<", helix_r:"<<r<<", wv:"<<wv<<", d:"<<sqrt(d2)<<endl;     
03454 #endif
03455 
03456      //...No crossing in R/Phi plane... This is too tight...
03457 
03458     if (d2 < 0.) {
03459         link.position(tmp);
03460 
03461 #ifdef TRKRECO_DEBUG
03462         std::cout << "TTrack !!! stereo: 0. > d2 = " << d2 << " "
03463                   << link.leftRight() << std::endl;
03464 #endif
03465         return -1;
03466     }
03467     double d = sqrt(d2);
03468 
03469     //...Cal. length to crossing points...
03470     double l[2];
03471     l[0] = (- wv + d) / vmag2;
03472     l[1] = (- wv - d) / vmag2;
03473 
03474     //...Cal. z of crossing points...
03475     bool ok[2];
03476     ok[0] = true;
03477     ok[1] = true;
03478     double z[2];
03479     z[0] = X.z() + l[0] * V.z();
03480     z[1] = X.z() + l[1] * V.z();
03481 #ifdef TRKRECO_DEBUG_DETAIL
03482     std::cout<<"X.z():"<<X.z()<<endl;
03483     std::cout<<"szPosition::z(0) "<<z[0]<<" z(1)"<<z[1]<<" leftRight "<<link.leftRight()<<endl;
03484     std::cout<<"szPosition::wire backwardPosition and forwardPosition:"<< h.wire()->backwardPosition().z()<<","<<h.wire()->forwardPosition().z()<<endl;
03485     std::cout << "    l0, l1 = " << l[0] << ", " << l[1] << std::endl;
03486     std::cout << "    z0, z1 = " << z[0] << ", " << z[1] << std::endl;
03487     std::cout << "    backward = " << h.wire()->backwardPosition().z() << std::endl;
03488     std::cout << "    forward = " << h.wire()->forwardPosition().z() << std::endl;
03489 #endif
03490 
03491     //...Check z position... //yzhang change 2012-05-03 
03492     //modified because Belle backward and forward are different from BESIII
03493     
03494     /*
03495     if (link.leftRight() == 2) {
03496         if (z[0] > h.wire()->backwardPosition().z()+20. 
03497             || z[0] < h.wire()->forwardPosition().z()-20.) ok[0] = false;
03498         if (z[1] > h.wire()->backwardPosition().z()+20.
03499             || z[1] < h.wire()->forwardPosition().z()-20.) ok[1] = false;
03500     }
03501     else {
03502         if (z[0] > h.wire()->backwardPosition().z()
03503             || z[0] < h.wire()->forwardPosition().z() ) ok[0] = false;
03504         if (z[1] > h.wire()->backwardPosition().z() 
03505             || z[1] < h.wire()->forwardPosition().z() ) ok[1] = false;
03506     }
03507     if ((! ok[0]) && (! ok[1])) {
03508         link.position(tmp);
03509         return -2;
03510     }*/
03511     //belle...
03512     if (link.leftRight() == 2) {
03513         if (z[0] < h.wire()->backwardPosition().z() - 20.
03514             || z[0] > h.wire()->forwardPosition().z() + 20.) ok[0] = false;
03515         if (z[1] < h.wire()->backwardPosition().z()-20.
03516             || z[1] > h.wire()->forwardPosition().z()+20.) ok[1] = false;
03517     }
03518     else {
03519         if (z[0] < h.wire()->backwardPosition().z()
03520             || z[0] > h.wire()->forwardPosition().z()) ok[0] = false;
03521         if (z[1] < h.wire()->backwardPosition().z()
03522             || z[1] > h.wire()->forwardPosition().z()) ok[1] = false;
03523     }
03524     if ((! ok[0]) && (! ok[1])) {
03525         link.position(tmp);
03526         return -2;
03527     }
03528     
03529 
03530     //...Cal. xy position of crossing points...
03531     HepVector3D p[2];
03532     p[0] = x + l[0] * v;
03533     p[1] = x + l[1] * v;
03534 /*    if (_charge * (center.x() * p[0].y() - center.y() * p[0].x())  < 0.)  //liuqg, cosmic...
03535         ok[0] = false;
03536     if (_charge * (center.x() * p[1].y() - center.y() * p[1].x())  < 0.)
03537         ok[1] = false;
03538     if ((! ok[0]) && (! ok[1])){
03539       //        double tmp1 = _charge * (center.x() * p[0].y() - center.y() * p[0].x());
03540       //        double tmp2 = _charge * (center.x() * p[1].y() - center.y() * p[1].x()) ;
03541       //        if (link.leftRight() == 2) std::cout<<tmp1<<" "<<tmp2<<std::endl;
03542         link.position(tmp);
03543         return -3;
03544     }
03545 */
03546     //...Which one is the best?... Study needed...
03547     unsigned best = 0;
03548     if (ok[1]) best = 1;
03549 
03550     //...Cal. arc length...
03551     double cosdPhi = - center.dot((p[best] - center).unit()) / center.mag();
03552     double dPhi;
03553     if(fabs(cosdPhi)<=1.0) {
03554         dPhi = acos(cosdPhi);
03555     } else if (cosdPhi>1.0) {
03556         dPhi = 0.0;
03557     } else {
03558         dPhi = M_PI;
03559     }
03560 
03561     //...Finish...
03562     tmp.setX(r * dPhi);
03563     tmp.setY(z[best]);
03564     link.position(tmp);
03565 
03566     return 0;
03567 }
03568 
03569 int
03570 TTrack::szPosition(const TSegment & segment, TMLink & a) const {
03571 
03572     //...Pick up a wire which represents segment position...
03573     AList<TMLink> links = segment.cores();
03574     unsigned n = links.length();
03575 //    std::cout<<" szPosition TTrack:: segment.cores().length():"<<n<<endl;
03576 //    for (unsigned i = 1; i < n; i++) {  
03577 //       std::cout<<"drift distance"<<links[i]->hit()->drift()<<endl;
03578 //    }  
03579     if (! n) return -1;
03580     TMLink * minL = links[0];
03581     float minDist = links[0]->drift();
03582 #ifdef TRKRECO_DEBUG_DETAIL
03583     std::cout<<"minDist szPosition TTrack:"<<minDist<<endl;
03584 #endif
03585     for (unsigned i = 1; i < n; i++) {
03586         if (links[i]->hit()->drift() < minDist) {
03587             minDist = links[i]->drift();
03588 #ifdef TRKRECO_DEBUG_DETAIL
03589             std::cout<<"minDist szPosition TTrack:"<<minDist<<endl;   
03590 #endif
03591             minL = links[i];
03592         }
03593     }
03594 
03595     //...sz calculation...
03596     a.position(minL->position());
03597     a.leftRight(2);
03598     a.hit(minL->hit());
03599     int err = szPosition(a);
03600 #ifdef TRKRECO_DEBUG_DETAIL
03601         std::cout<<"err of szPosition TTrack:"<<err<<endl;      
03602 #endif
03603     if (err) return -2;
03604     return 0;
03605 }
03606 
03607 int
03608 TTrack::szPosition(const HepPoint3D & p, HepPoint3D & sz) const {
03609 
03610     //...Cal. arc length...
03611     HepPoint3D center = _helix->center();
03612     HepPoint3D xy = p;
03613     xy.setZ(0.);
03614     double cosdPhi = - center.dot((xy - center).unit()) / center.mag();
03615     double dPhi;
03616     if (fabs(cosdPhi) <= 1.0) {
03617         dPhi = acos(cosdPhi);
03618     }
03619     else if (cosdPhi > 1.0) {
03620         dPhi = 0.0;
03621     }
03622     else {
03623         dPhi = M_PI;
03624     }
03625 
03626     //...Finish...
03627     sz.setX(_helix->curv() * dPhi);
03628     sz.setY(p.z());
03629     sz.setZ(0.);
03630 
03631     return 0;
03632 }
03633 
03634 void
03635 TTrack::assign(unsigned hitMask) {
03636     hitMask |= WireHitUsed;
03637 
03638     unsigned n = _links.length();
03639     for (unsigned i = 0; i < n; i++) {
03640         TMLink * l = _links[i];
03641         const TMDCWireHit * h = l->hit();
03642 #ifdef TRKRECO_DEBUG
03643         if (h->track()) {
03644             std::cout << "TTrack::assign !!! hit(" << h->wire()->name();
03645             std::cout << ") already assigned" << std::endl;
03646         }
03647 #endif
03648 
03649         //...This function will be moved to TTrackManager...
03650         h->track((TTrack *) this);
03651         h->state(h->state() | hitMask);
03652     }
03653 }
03654 
03655 Helix
03656 Track2Helix(const MdcTrk_localz & t) {
03657     HepVector a(5);
03658     Hep3Vector p(t.pivot[0], t.pivot[1], t.pivot[2]);
03659     HepSymMatrix er(5,0);
03660     a(1) = t.helix[0];
03661     a(2) = t.helix[1];
03662     a(3) = t.helix[2];
03663     a(4) = t.helix[3];
03664     a(5) = t.helix[4];
03665     er(1,1) = t.error[0];
03666     er(2,1) = t.error[1];
03667     er(2,2) = t.error[2];
03668     er(3,1) = t.error[3];
03669     er(3,2) = t.error[4];
03670     er(3,3) = t.error[5];
03671     er(4,1) = t.error[6];
03672     er(4,2) = t.error[7];
03673     er(4,3) = t.error[8];
03674     er(4,4) = t.error[9];
03675     er(5,1) = t.error[10];
03676     er(5,2) = t.error[11];
03677     er(5,3) = t.error[12];
03678     er(5,4) = t.error[13];
03679     er(5,5) = t.error[14];
03680     return Helix(p, a, er);
03681 }
03682 
03683 Helix
03684 Track2Helix(const MdcRec_trk & t) {
03685     HepVector a(5);
03686     Hep3Vector p(t.pivot[0], t.pivot[1], t.pivot[2]);
03687     HepSymMatrix er(5,0);
03688     a(1) = t.helix[0];
03689     a(2) = t.helix[1];
03690     a(3) = t.helix[2];
03691     a(4) = t.helix[3];
03692     a(5) = t.helix[4];
03693     er(1,1) = t.error[0];
03694     er(2,1) = t.error[1];
03695     er(2,2) = t.error[2];
03696     er(3,1) = t.error[3];
03697     er(3,2) = t.error[4];
03698     er(3,3) = t.error[5];
03699     er(4,1) = t.error[6];
03700     er(4,2) = t.error[7];
03701     er(4,3) = t.error[8];
03702     er(4,4) = t.error[9];
03703     er(5,1) = t.error[10];
03704     er(5,2) = t.error[11];
03705     er(5,3) = t.error[12];
03706     er(5,4) = t.error[13];
03707     er(5,5) = t.error[14];
03708     return Helix(p, a, er);
03709 }
03710 
03711 Helix
03712 Track2Helix(const Mdst_trk_fit & t) {
03713     HepVector a(5);
03714     Hep3Vector p(t.pivot_x, t.pivot_y, t.pivot_z);
03715     HepSymMatrix er(5,0);
03716     a(1) = t.helix[0];
03717     a(2) = t.helix[1];
03718     a(3) = t.helix[2];
03719     a(4) = t.helix[3];
03720     a(5) = t.helix[4];
03721     er(1,1) = t.error[0];
03722     er(2,1) = t.error[1];
03723     er(2,2) = t.error[2];
03724     er(3,1) = t.error[3];
03725     er(3,2) = t.error[4];
03726     er(3,3) = t.error[5];
03727     er(4,1) = t.error[6];
03728     er(4,2) = t.error[7];
03729     er(4,3) = t.error[8];
03730     er(4,4) = t.error[9];
03731     er(5,1) = t.error[10];
03732     er(5,2) = t.error[11];
03733     er(5,3) = t.error[12];
03734     er(5,4) = t.error[13];
03735     er(5,5) = t.error[14];
03736     return Helix(p, a, er);
03737 }
03738 
03739 std::string
03740 TrackKinematics(const Helix & h) {
03741     static const HepPoint3D IP(0., 0., 0.);
03742     Helix hIp = h;
03743     hIp.pivot(IP);
03744 
03745     float chrg = hIp.a()[2] / fabs(hIp.a()[2]);
03746     std::string s;
03747     if (chrg > 0.) s = "+";
03748     else           s = "-";
03749 
03750     float x[4];
03751     x[0] = fabs(hIp.a()[0]);
03752     x[1] = hIp.a()[3];
03753     x[2] = 1. / fabs(hIp.a()[2]);
03754     x[3] = (1. / fabs(hIp.a()[2])) * hIp.a()[4];
03755 
03756     if ((x[0] < 2.) && (fabs(x[1]) < 4.)) s += "i ";
03757     else                                  s += "  ";
03758 
03759     for (unsigned i = 0; i < 4; i++) {
03760         if (i) s += " ";
03761 
03762         if (x[i] < 0.) s += "-";
03763         else           s += " ";
03764 
03765         int y = int(fabs(x[i]));
03766         s += itostring(y) + ".";
03767         float z = fabs(x[i]);
03768         for (unsigned j = 0; j < 3; j++) {
03769             z *= 10.;
03770             y = (int(z) % 10);
03771             s += itostring(y);
03772         }
03773     }
03774 
03775     return s;
03776 }
03777 
03778 std::string
03779 TrackStatus(const TTrack & t) {
03780     return TrackStatus(t.finder(),
03781                        t.type(),
03782                        t.quality(),
03783                        t.fitting(),
03784                        0,
03785                        0);
03786 }
03787 
03788 std::string
03789 TrackStatus(const MdcRec_trk & c) {
03790 //    const reccdc_trk_add & a =
03791 //      * (reccdc_trk_add *) BsGetEnt(RECMDC_TRK_ADD, c.m_ID, BBS_No_Index);
03792 //    return TrackStatus(a);
03793 }
03794 
03795 std::string
03796 TrackStatus(const MdcRec_trk_add & a) {
03797 //    return TrackStatus(a.decision,
03798 //                     a.kind,
03799 //                     a.quality,
03800 //                     a.stat,
03801 //                     a.mother,
03802 //                     a.daughter);
03803 }
03804 
03805 std::string
03806 TrackStatus(unsigned md,
03807             unsigned mk,
03808             unsigned mq,
03809             unsigned ms,
03810             unsigned mm,
03811             unsigned ma) {
03812 
03813     std::string f;
03814     if (md & TrackOldConformalFinder) f += "o";
03815     if (md & TrackFastFinder) f += "f";
03816     if (md & TrackSlowFinder) f += "s";
03817     if (md & TrackCurlFinder) f += "c";
03818     if (md & TrackTrackManager) f += "t";
03819     if (f == "") f = "?";
03820 
03821     std::string k;
03822     if (mk & TrackTypeNormal) k += "Norm";
03823     if (mk & TrackTypeCurl) k += "Curl";
03824     if (mk & TrackTypeCircle) k += "Circ";
03825     if (mk & TrackTypeIncomingCosmic) k += "Inco";
03826     if (mk & TrackTypeOutgoingCosmic) k += "Outc";
03827     if (mk & TrackTypeKink) k += "Kink";
03828     if (mk & TrackTypeSVDOnly) k += "Svd";
03829     if (k == "") k = "?";
03830 
03831     std::string b;
03832     if (mq & TrackQualityOutsideCurler) b += "Curlback";
03833     if (mq & TrackQualityAfterKink) b += "Afterkink";
03834     if (mq & TrackQualityCosmic) b += "Cosmic";
03835     if (mq & TrackQuality2D) b += "2D";
03836     if (b == "") b = "ok";
03837 
03838     std::string s;
03839     if (ms & TrackFitGlobal) s += "HFit";
03840     if (ms & TrackFitCosmic) s += "CFit";
03841     if (ms & TrackFitCdcKalman) s += "CKal";
03842     if (ms & TrackFitSvdCdcKalman) s += "SKal";
03843     if (s == "") s = "?";
03844 
03845     int m = mm;
03846     if (m) --m;
03847 
03848     int d = ma;
03849     if (d) --d;
03850 
03851     std::string p = " ";
03852     return f + p + k + p + b + p + s + p + itostring(m) + p + itostring(d);
03853 }
03854 
03855 std::string
03856 TrackInformation(const TTrack & t) {
03857     const AList<TMLink> cores = t.cores();
03858     unsigned n = cores.length();
03859     unsigned nS = NStereoHits(cores);
03860     unsigned nA = n - nS;
03861     std::string p;
03862     if (! PositiveDefinite(t.helix())) p = " negative";
03863     if (HelixHasNan(t.helix())) p += " NaN";
03864     return TrackInformation(nA, nS, n, t.chi2()) + p;
03865 }
03866 
03867 std::string
03868 TrackInformation(const MdcRec_trk & r) {
03869     std::string p;
03870     if (PositiveDefinite(Track2Helix(r))) p = " posi";
03871     else                                  p = " nega";
03872     if (HelixHasNan(Track2Helix(r))) p += " with NaN";
03873     return TrackInformation(r.nhits - r.nster,
03874                             r.nster,
03875                             r.nhits,
03876                             r.chiSq) + p;
03877 }
03878 
03879 std::string
03880 TrackInformation(unsigned nA, unsigned nS, unsigned n, float chisq) {
03881     std::string s;
03882 
03883     s += "a" + itostring(int(nA));
03884     s += " s" + itostring(int(nS));
03885     s += " n" + itostring(int(n));
03886     // s += " ndf" + std::string(int(r.m_ndf));
03887     float x = chisq;
03888 
03889     if (x < 0.) s += " -";
03890     else        s += " ";
03891 
03892     int y = int(fabs(x));
03893     s += itostring(y) + ".";
03894     float z = fabs(x);
03895     for (unsigned j = 0; j < 1; j++) {
03896         z *= 10.;
03897         y = (int(z) % 10);
03898         s += itostring(y);
03899     }
03900 
03901     return s;
03902 }
03903 
03904 std::string
03905 TrackLayerUsage(const TTrack & t) {
03906     unsigned n[11];
03907     NHitsSuperLayer(t.links(), n);
03908     std::string nh;
03909     for (unsigned i = 0; i < 11; i++) {
03910         nh += itostring(n[i]);
03911         if (i % 2) nh += "-";
03912         else if (i < 10) nh += ",";
03913     }
03914     return nh;
03915 }
03916 
03917 bool
03918 PositiveDefinite(const Helix & h) {
03919     const SymMatrix & e = h.Ea();
03920     SymMatrix e2 = e.sub(1, 2);
03921     SymMatrix e3 = e.sub(1, 3);
03922     SymMatrix e4 = e.sub(1, 4);
03923 
03924     bool positive = true;
03925     if (e[0][0] <= 0.) positive = false;
03926     else if (e2.determinant() <= 0.) positive = false;
03927     else if (e3.determinant() <= 0.) positive = false;
03928     else if (e4.determinant() <= 0.) positive = false;
03929     else if (e.determinant() <= 0.) positive = false;
03930     return positive;
03931 }
03932 
03933 bool
03934 HelixHasNan(const Helix & h) {
03935     const Vector & a = h.a();
03936     for (unsigned i = 0; i < 5; i++)
03937         if (isnan(a[i]))
03938             return true;
03939     const SymMatrix & Ea = h.Ea();
03940     for (unsigned i = 0; i < 5; i++)
03941         for (unsigned j = 0; j <= i; j++)
03942             if (isnan(Ea[i][j]))
03943                 return true;
03944     return false;
03945 }
03946 
03947 Helix
03948 Track2Helix(const Gen_hepevt & t) {
03949     float charge = 1;
03950     if (t.idhep == 11) charge = -1;
03951     else if (t.idhep == -11) charge = 1;
03952     else if (t.idhep == 13) charge = -1;
03953     else if (t.idhep == -13) charge = 1;
03954     else if (t.idhep == 211) charge = 1;
03955     else if (t.idhep == -211) charge = -1;
03956     else if (t.idhep == 321) charge = 1;
03957     else if (t.idhep == -321) charge = -1;
03958     else if (t.idhep == 2212) charge = 1;
03959     else if (t.idhep == -2212) charge = -1;
03960     else {
03961         std::cout << "Track2Helix(gen_hepevt) !!! charge of id=";
03962         std::cout << t.idhep << " is unknown" << std::endl;
03963     }
03964 
03965     Hep3Vector mom(t.P[0], t.P[1], t.P[2]);
03966     Hep3Vector pos(t.V[0] / 10., t.V[1] / 10., t.V[2] / 10.);
03967     return Helix(pos, mom, charge);
03968 }

Generated on Tue Nov 29 23:14:16 2016 for BOSS_7.0.2 by  doxygen 1.4.7