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

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 // $Id: TCosmicFitter.cxx,v 1.12 2011/12/05 04:49:50 maoh Exp $
00003 //-----------------------------------------------------------------------------
00004 // Filename : TCosmicFitter.cc
00005 // Section  : Tracking
00006 // Owner    : Yoshi Iwasaki
00007 // Email    : yoshihito.iwasaki@kek.jp
00008 //-----------------------------------------------------------------------------
00009 // Description : A class to fit a TTrackBase object to a helix.
00010 //               See http://bsunsrv1.kek.jp/~yiwasaki/tracking/
00011 //-----------------------------------------------------------------------------
00012 
00013 #define HEP_SHORT_NAMES
00014 #include <float.h>
00015 //#include "tables/cdc.h"
00016 #include "CLHEP/Matrix/Vector.h"
00017 #include "CLHEP/Matrix/SymMatrix.h"
00018 #include "CLHEP/Matrix/DiagMatrix.h"
00019 #include "CLHEP/Matrix/Matrix.h"
00020 //#include "panther/panther.h"
00021 //#include "panther/panther_manager.h"
00022 #include "TrkReco/TCosmicFitter.h"
00023 #include "TrkReco/TTrack.h"
00024 
00025 #include "TrkReco/TrkReco.h"
00026 
00027 #include "MdcCalibFunSvc/IMdcCalibFunSvc.h"
00028 #include "MdcCalibFunSvc/MdcCalibFunSvc.h"
00029 
00030 #include "GaudiKernel/MsgStream.h"
00031 #include "GaudiKernel/AlgFactory.h"
00032 #include "GaudiKernel/ISvcLocator.h"
00033 #include "GaudiKernel/IMessageSvc.h"
00034 #include "GaudiKernel/IDataProviderSvc.h"
00035 #include "GaudiKernel/IDataManagerSvc.h"
00036 #include "GaudiKernel/SmartDataPtr.h"
00037 #include "GaudiKernel/IDataProviderSvc.h"
00038 #include "GaudiKernel/PropertyMgr.h"
00039 #include "GaudiKernel/IJobOptionsSvc.h"
00040 #include "GaudiKernel/IMessageSvc.h"
00041 #include "GaudiKernel/Bootstrap.h"
00042 #include "GaudiKernel/StatusCode.h"
00043 
00044 #include "GaudiKernel/ContainedObject.h"
00045 #include "GaudiKernel/SmartRef.h"
00046 #include "GaudiKernel/SmartRefVector.h"
00047 #include "GaudiKernel/ObjectVector.h"
00048 #include "EventModel/EventModel.h"
00049 
00050 #include  "EvTimeEvent/RecEsTime.h"
00051 
00052 #include "CLHEP/Matrix/Matrix.h"
00053 #include "GaudiKernel/StatusCode.h"
00054 #include "GaudiKernel/IInterface.h"
00055 #include "GaudiKernel/Kernel.h"
00056 #include "GaudiKernel/Service.h"
00057 #include "GaudiKernel/ISvcLocator.h"
00058 #include "GaudiKernel/SvcFactory.h"
00059 #include "GaudiKernel/IDataProviderSvc.h"
00060 #include "GaudiKernel/Bootstrap.h"
00061 #include "GaudiKernel/MsgStream.h"
00062 #include "GaudiKernel/SmartDataPtr.h"
00063 #include "GaudiKernel/IMessageSvc.h"
00064 
00065 
00066 using CLHEP::HepVector;
00067 using CLHEP::HepSymMatrix;
00068 using CLHEP::HepDiagMatrix;
00069 using CLHEP::HepMatrix;
00070 
00071 typedef CLHEP::HepMatrix Matrix;
00072 
00073 #define CAL_TOF_HELIX 0
00074 
00075 #define NTrailMax 100
00076 #define Convergence 1.0e-5
00077 
00078 /*
00079 extern "C" void calcdc_sag3_(int*, float*, float[3], float*, float*, float*);
00080 extern "C" void calcdc_driftdist_(int*, int*, int*, 
00081                 float[3], float[3], float*, float*, float*);
00082 */
00083 
00084 TCosmicFitter::TCosmicFitter(const std::string & name) : TMFitter(name) {
00085 //jialk
00086    StatusCode scmgn = Gaudi::svcLocator()->service("MagneticFieldSvc",m_pmgnIMF); 
00087   if(scmgn!=StatusCode::SUCCESS) { 
00088     std::cout<< "Unable to open Magnetic field service"<<std::endl;
00089   }
00090 
00091 }
00092 
00093 TCosmicFitter::~TCosmicFitter() {
00094 }
00095 
00096 int
00097 TCosmicFitter::fit(TTrackBase & b) const {
00098 
00099 //  double t0_bes;
00100 //  TrkReco::t0(t0_bes);
00101 //  const double t0_bes = TrkReco::t0();
00102 
00103     //...Already fitted ?...
00104     if (b.fitted()) return TFitAlreadyFitted;
00105 
00106     int err = fit(b, 0.);
00107     if (! err) b._fitted = true;
00108 
00109     return err;
00110 }
00111 
00112 int
00113 TCosmicFitter::fit(TTrackBase & b, float t0Offset) const {
00114 
00115 #ifdef TRKRECO_DEBUG_DETAIL
00116     std::cout << "    TCosmicFitter::fit ..." << std::endl;
00117 #endif
00118 
00119     IMdcCalibFunSvc* l_mdcCalFunSvc;
00120     Gaudi::svcLocator() -> service("MdcCalibFunSvc", l_mdcCalFunSvc);
00121 
00122     //...Check # of hits...
00123     if (b.links().length() < 5) return TFitErrorFewHits;
00124     unsigned nValid = 0;
00125     for (unsigned i = 0; i < b.links().length(); i++) {
00126         unsigned state = b.links()[i]->hit()->state();
00127         if (state & WireHitInvalidForFit) continue;
00128         if (state & WireHitFittingValid) ++nValid;
00129     }
00130     if (nValid < 5) return TFitErrorFewHits;
00131 
00132     //...Type check...
00133     //    if (b.type() != Track) return TFitUnavailable;
00134     if (b.objectType() != Track) return TFitUnavailable;
00135     TTrack & t = (TTrack &) b;
00136 
00137     //read t0 from TDS-------------------------------------//
00138     double _t0_bes = -1.;
00139     IMessageSvc *msgSvc;
00140     Gaudi::svcLocator()->service("MessageSvc", msgSvc);
00141     MsgStream log(msgSvc, "TCosmicFitter");
00142 
00143     IDataProviderSvc* eventSvc = NULL;
00144     Gaudi::svcLocator()->service("EventDataSvc", eventSvc);
00145 
00146     SmartDataPtr<RecEsTimeCol> aevtimeCol(eventSvc,"/Event/Recon/RecEsTimeCol");
00147     if (aevtimeCol) {
00148       RecEsTimeCol::iterator iter_evt = aevtimeCol->begin();
00149       _t0_bes = (*iter_evt)->getTest();
00150 //      cout<<"  tev: "<<setw(4)<<_t0_bes<<endl;
00151     }else{
00152       log << MSG::WARNING << "Could not find RecEsTimeCol" << endreq;
00153     }
00154 //    if (_t0_bes < 7.) _t0_bes = 7.;
00155     //----------------------------------------------------//
00156 
00157     //...Setup...
00158     Vector a(5), da(5);
00159     a = t.helix().a();
00160     Vector dxda(5);
00161     Vector dyda(5);
00162     Vector dzda(5);
00163     Vector dDda(5);
00164     Vector dchi2da(5);
00165     SymMatrix d2chi2d2a(5, 0);
00166     double chi2;
00167     // double chi2Old = 10e99;
00168     double chi2Old = DBL_MAX;
00169     const double convergence = Convergence;
00170     bool allAxial = true;
00171     Matrix e(3, 3);
00172     Vector f(3);
00173     int err = 0;
00174     double factor = 1.0;//jtanaka0715
00175 
00176     Vector maxDouble(5);
00177     for (unsigned i = 0; i < 5; i++) maxDouble[i] = (FLT_MAX);
00178 
00179     //...Fitting loop...
00180     unsigned nTrial = 0;
00181     while (nTrial < NTrailMax) {
00182 
00183         //...Set up...
00184         chi2 = 0.;
00185         for (unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
00186         d2chi2d2a = SymMatrix(5, 0);
00187         
00188 #if CAL_TOF_HELIX
00189         //cal the time pass through the chamber
00190         const float Rad = 81; // cm
00191         float dRho = t.helix().a()[0];
00192         float Lproj = sqrt(Rad*Rad - dRho*dRho);
00193         float tlmd = t.helix().a()[4];
00194         float fct = sqrt(1. + tlmd * tlmd);
00195 #endif
00196 
00197         //...Loop with hits...
00198         unsigned i = 0;
00199         while (TMLink * l = t.links()[i++]) {
00200             const TMDCWireHit & h = * l->hit();
00201 
00202             //...Check state...
00203             if (h.state() & WireHitInvalidForFit) continue;
00204             if (! (h.state() & WireHitFittingValid)) continue;
00205 
00206             //...Check wire...
00207             if (! nTrial)
00208                 if (h.wire()->stereo()) allAxial = false;
00209 
00210             //...Cal. closest points...
00211             int doSagCorrection = 0;
00212 //          if(nTrial && !allAxial ) doSagCorrection = 1; //Liuqg
00213             t.approach(* l, doSagCorrection);
00214             double dPhi = l->dPhi();
00215             const HepPoint3D & onTrack = l->positionOnTrack();
00216             const HepPoint3D & onWire = l->positionOnWire();
00217 
00218 #ifdef TRKRECO_DEBUG_DETAIL
00219 //          std::cout << "    in fit " << onTrack << ", " << onWire;
00220 //          h.dump();
00221 #endif      
00222 
00223             //...Obtain drift distance and its error...
00224             unsigned leftRight = WireHitRight;
00225             if (onWire.cross(onTrack).z() < 0.) leftRight = WireHitLeft;
00226             double distance = h.drift(leftRight);
00227             double eDistance = h.dDrift(leftRight);
00228             //... 
00229             if(nTrial  && !allAxial){
00230                int side = leftRight;
00231 
00232                double Tfly = _t0_bes/220.*(110.-onWire.y());
00233 #if CAL_TOF_HELIX
00234                float Rad_wire = sqrt(x[0]*x[0]+x[1]*x[1]); // cm
00235                float L_wire = sqrt(Rad_wire*Rad_wire - dRho*dRho);
00236                float flyLength = Lproj - L_wire;
00237                if (x[1]<0) flyLength = Lproj + L_wire;
00238                Tfly = flyLength/29.98*sqrt(1.0+(0.105/0.5)*(0.105/0.5))*fct; //approxiate... cm/ns
00239 #endif
00240                float time = l->hit()->reccdc()->tdc - Tfly;
00241           
00242                int wire    = h.wire()->localId();
00243                int layerId = h.wire()->layerId();
00244                float dist =  distance;
00245                float edist = eDistance;
00246            double T0 = l_mdcCalFunSvc->getT0(layerId,wire);
00247            double rawadc = 0.;
00248            rawadc =l->hit()->reccdc()->adc;
00249 
00250            double timeWalk = l_mdcCalFunSvc->getTimeWalk(layerId, rawadc);
00251            double drifttime =time -T0-timeWalk;
00252            dist = l_mdcCalFunSvc->driftTimeToDist(drifttime,layerId, wire, side, 0.0);
00253                edist = l_mdcCalFunSvc->getSigma(layerId, side, dist, 0.0);
00254                dist = dist/10.0; //mm->cm
00255                edist = edist/10.0;
00256 //             if(layerId<20) edist = 9999.;
00257 
00258 //zsl          calcdc_driftdist_(&doPropDelay,&wire,&side,p,x,&time,&dist,&edist);
00259 
00260                distance = (double) dist;
00261                eDistance = (double) edist;
00262 
00263                l->drift(distance,0);  //update
00264                l->drift(distance,1);
00265                l->dDrift(eDistance,0);
00266                l->dDrift(eDistance,1);
00267                l->tof(Tfly);
00268             }
00269             double eDistance2 = eDistance * eDistance;
00270 
00271             //...Residual...
00272             HepVector3D v = onTrack - onWire;
00273             double vmag = v.mag();
00274             double dDistance = vmag - distance;
00275 
00276             //...dxda...
00277             this->dxda(*l, t.helix(), dPhi, dxda, dyda, dzda, doSagCorrection);
00278 
00279             //...Chi2 related...
00280             // dDda = (v.x() * dxda + v.y() * dyda + v.z() * dzda) / vmag;
00281             HepVector3D vw = h.wire()->direction();
00282             dDda = (vmag > 0.)
00283                 ? ((v.x() * (1. - vw.x() * vw.x()) -
00284                     v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
00285                    * dxda + 
00286                    (v.y() * (1. - vw.y() * vw.y()) -
00287                     v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
00288                    * dyda + 
00289                    (v.z() * (1. - vw.z() * vw.z()) -
00290                     v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
00291                    * dzda) / vmag
00292                 : Vector(5,0);
00293             if(vmag<=0.0) {
00294               std::cout << "    in fit " << onTrack << ", " << onWire;
00295               h.dump();
00296             }
00297             dchi2da += (dDistance / eDistance2) * dDda;
00298             d2chi2d2a += vT_times_v(dDda) / eDistance2;
00299             double pChi2 = dDistance * dDistance / eDistance2;
00300             chi2 += pChi2;
00301 
00302             //...Store results...
00303             l->update(onTrack, onWire, leftRight, pChi2);
00304         }
00305 
00306         //...Check condition...
00307         double change = chi2Old - chi2;
00308         if (fabs(change) < convergence) break;
00309         //if (change < 0.) break;
00310         //jtanaka -- from traffs -- Ozaki-san added this part to traffs.        
00311         if (change < 0.){
00312 #ifdef TRKRECO_DEBUG_DETAIL
00313           std::cout << "chi2Old, chi2=" << chi2Old <<" "<< chi2 << std::endl;
00314 #endif
00315           //change to the old value.
00316           a += factor*da;
00317 //        a[2] = 0.000000001;
00318           t._helix->a(a);
00319 
00320           chi2 = 0.;
00321           for (unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
00322           d2chi2d2a = SymMatrix(5, 0);
00323 
00324           //...Loop with hits...
00325           unsigned i = 0;
00326           while (TMLink * l = t.links()[i++]) {
00327               const TMDCWireHit & h = * l->hit();
00328             
00329             //...Check state...
00330             if (h.state() & WireHitInvalidForFit) continue;
00331             if (! (h.state() & WireHitFittingValid)) continue;
00332 
00333             //...Check wire...
00334             if (! nTrial)
00335               if (h.wire()->stereo()) allAxial = false;
00336             
00337             //...Cal. closest points...
00338             int doSagCorrection = 0;
00339 //            if( nTrial  && !allAxial ) doSagCorrection = 1;  //Liuqg
00340             t.approach(* l, doSagCorrection);
00341             double dPhi = l->dPhi();
00342             const HepPoint3D & onTrack = l->positionOnTrack();
00343             const HepPoint3D & onWire = l->positionOnWire();
00344 
00345 #ifdef TRKRECO_DEBUG_DETAIL
00346             // std::cout << "    in fit in case of change < 0. " << onTrack << ", " << onWire;
00347             // h.dump();
00348 #endif      
00349             
00350             //...Obtain drift distance and its error...
00351             unsigned leftRight = WireHitRight;
00352             if (onWire.cross(onTrack).z() < 0.) leftRight = WireHitLeft;
00353             double distance = h.drift(leftRight);
00354             double eDistance = h.dDrift(leftRight);
00355             if(nTrial  && !allAxial){
00356                int side = leftRight;
00357 
00358                double Tfly = _t0_bes/220.*(110.-onWire.y());
00359 #if CAL_TOF_HELIX
00360                float Rad_wire = sqrt(x[0]*x[0]+x[1]*x[1]); // cm
00361                float L_wire = sqrt(Rad_wire*Rad_wire - dRho*dRho);
00362                float flyLength = Lproj - L_wire;
00363                if (x[1]<0) flyLength = Lproj + L_wire;
00364                Tfly = flyLength/29.98*sqrt(1.0+(0.105/10)*(0.105/10))*fct; //approxiate... cm/ns
00365 #endif
00366 
00367                float time = l->hit()->reccdc()->tdc - Tfly;
00368 
00369                int wire    = h.wire()->localId();
00370                int layerId = h.wire()->layerId();
00371                float dist= distance;
00372                float edist = eDistance;
00373 //               int doPropDelay = 1; // 
00374            
00375            double T0 = l_mdcCalFunSvc->getT0(layerId,wire);
00376            double rawadc = 0.;
00377            rawadc =l->hit()->reccdc()->adc;
00378            double timeWalk = l_mdcCalFunSvc->getTimeWalk(layerId, rawadc);
00379            double drifttime =time -T0-timeWalk;
00380            dist = l_mdcCalFunSvc->driftTimeToDist(drifttime,layerId, wire, side, 0.0);
00381                edist = l_mdcCalFunSvc->getSigma(layerId, side, dist, 0.0);
00382                dist = dist/10.0; //mm->cm
00383                edist = edist/10.0;
00384 //             if (layerId<20) edist = 9999.;
00385 
00386 //zsl          calcdc_driftdist_(&doPropDelay,&wire,&side,p,x,&time,&dist,&edist);
00387 
00388                distance = (double) dist;
00389                eDistance = (double) edist;
00390 
00391                l->drift(distance,0);   //update
00392                l->drift(distance,1);
00393                l->dDrift(eDistance,0);
00394                l->dDrift(eDistance,1);
00395                l->tof(Tfly);
00396             }
00397             double eDistance2 = eDistance * eDistance;
00398 
00399             //...Residual...
00400             HepVector3D v = onTrack - onWire;
00401             double vmag = v.mag();
00402             double dDistance = vmag - distance;
00403             
00404             //...dxda...
00405             this->dxda(*l, t.helix(), dPhi, dxda, dyda, dzda, doSagCorrection);
00406             
00407             //...Chi2 related...
00408             //dDda = (v.x() * dxda + v.y() * dyda + v.z() * dzda) / vmag;
00409             HepVector3D vw = h.wire()->direction();
00410             dDda = (vmag > 0.)
00411                 ? ((v.x() * (1. - vw.x() * vw.x()) -
00412                     v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
00413                    * dxda + 
00414                    (v.y() * (1. - vw.y() * vw.y()) -
00415                     v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
00416                    * dyda + 
00417                    (v.z() * (1. - vw.z() * vw.z()) -
00418                     v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
00419                    * dzda) / vmag
00420                 : Vector(5,0);
00421             if(vmag<=0.0) {
00422               std::cout << "    in fit " << onTrack << ", " << onWire;
00423               h.dump();
00424             }
00425             dchi2da += (dDistance / eDistance2) * dDda;
00426             d2chi2d2a += vT_times_v(dDda) / eDistance2;
00427             double pChi2 = dDistance * dDistance / eDistance2;
00428             chi2 += pChi2;
00429             
00430             //...Store results...
00431             l->update(onTrack, onWire, leftRight, pChi2);
00432           }
00433           //break;
00434           factor *= 0.75;
00435 #ifdef TRKRECO_DEBUG_DETAIL 
00436           std::cout << "factor = " << factor << std::endl;
00437           std::cout << "chi2 = " << chi2 << std::endl;
00438 #endif
00439           if(factor < 0.01)break;
00440         }
00441 
00442         chi2Old = chi2;
00443 
00444         //...Cal. helix parameters for next loop...
00445         if (allAxial) {
00446             f = dchi2da.sub(1, 3);
00447             e = d2chi2d2a.sub(1, 3);
00448             f = solve(e, f);
00449             da[0] = f[0];
00450             da[1] = f[1];
00451             da[2] = f[2];
00452             da[3] = 0.;
00453             da[4] = 0.;
00454         }
00455         else {
00456             da = solve(d2chi2d2a, dchi2da);
00457         }
00458 
00459 #ifdef TRKRECO_DEBUG_DETAIL
00460         //std::cout << "    fit " << nTrial << " : " << da << std::endl;
00461         //std::cout << "        d2chi " << d2chi2d2a << std::endl;
00462         //std::cout << "        dchi2 " << dchi2da << std::endl;
00463 #endif      
00464 
00465         a -= factor*da;
00466 //      a[2] = 0.000000001;
00467         t._helix->a(a);
00468         ++nTrial;
00469     }
00470 
00471     //...Cal. error matrix...
00472     SymMatrix Ea(5, 0);
00473     unsigned dim;
00474     if (allAxial) {
00475         dim = 3;
00476         SymMatrix Eb(3, 0), Ec(3, 0);
00477         Eb = d2chi2d2a.sub(1, 3);
00478         Ec = Eb.inverse(err);
00479         Ea[0][0] = Ec[0][0];
00480         Ea[0][1] = Ec[0][1];
00481         Ea[0][2] = Ec[0][2];
00482         Ea[1][1] = Ec[1][1];
00483         Ea[1][2] = Ec[1][2];
00484         Ea[2][2] = Ec[2][2];
00485     }
00486     else {
00487         dim = 5;
00488         Ea = d2chi2d2a.inverse(err);
00489     }
00490 
00491     //...Store information...
00492     if (! err) {
00493         t._helix->a(a);
00494         t._helix->Ea(Ea);
00495     }
00496     else {
00497         err = TFitFailed;
00498     }
00499 
00500     t._ndf = nValid - dim;
00501     t._chi2 = chi2;
00502     // t._fitted = true;
00503     
00504     return err;
00505 }
00506 
00507 /*
00508 
00509 // addition by matsu ( 1999/07/05 )
00510 int 
00511 TCosmicFitter::fitWithCathode( TTrackBase &b, float t0Offset,
00512                                float windowSize , int SysCorr ) {
00513 
00514 #ifdef TRKRECO_DEBUG_DETAIL
00515     std::cout << "    TCosmicFitter::fitCathode ..." << std::endl;
00516 #endif
00517 
00518     //...Already fitted ? ...
00519     if (b.fittedWithCathode()) return 0;
00520 
00521     //...Check # of his...
00522     if( b.nCores() < 5 ) return -1;
00523 
00524    //...Type check...
00525     if (b.objectType() != Track) return TFitUnavailable;
00526     TTrack & t = (TTrack &) b;
00527 
00528     //...for cathode ndf...
00529     int NusedCathode(0);
00530 
00531     //...Setup...
00532     unsigned nTrial = 0;
00533     Vector a(5), da(5);
00534     a = t.helix().a();
00535     Vector dxda(5);
00536     Vector dyda(5);
00537     Vector dzda(5);
00538     Vector dDda(5);
00539     Vector dDzda(5);  // for cathode z
00540     Vector dchi2da(5);
00541     SymMatrix d2chi2d2a(5, 0);
00542     double chi2;
00543     double chi2Old = DBL_MAX;
00544     const double convergence = Convergence;
00545     bool allAxial = true;
00546     int LayerStat(0); // layer status  axial:0 stereo:1 cathode:2
00547     Matrix e(3, 3);
00548     Vector f(3);
00549     int err = 0;
00550     double factor = 1.0;
00551 
00552     const AList<TMDCCatHit> & chits = t.catHits();
00553 
00554     Vector maxDouble(5);
00555     for (unsigned i = 0; i < 5; i++) maxDouble[i] = (FLT_MAX);
00556 
00557     //...Fitting loop...
00558     while(nTrial < NTrailMax){
00559 
00560       //...Set up...
00561       chi2 = 0.;
00562       NusedCathode = 0;
00563       for (unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
00564       d2chi2d2a = SymMatrix(5, 0);
00565 
00566       //...Loop with hits...
00567       unsigned i = 0;
00568        AList<TMLink> cores = t.cores();
00569       while (TMLink * l = cores[i++]) {
00570 
00571           const TMDCWireHit & h = * l->hit();
00572 
00573        // Check layer status ( cathode added ) 
00574         LayerStat = 0;
00575         if ( h.wire()->stereo() ) LayerStat = 1;
00576         unsigned nlayer = h.wire()->layerId();
00577         if (nlayer == 0 || nlayer == 1 || nlayer == 2 ) LayerStat = 2;
00578 
00579         //...Check wire...
00580         if (! nTrial)
00581           if (h.wire()->stereo() || LayerStat == 2 ) allAxial = false;
00582 
00583         //...Cal. closest points...
00584         int doSagCorrection = 0;
00585         if(nTrial && !allAxial ) doSagCorrection = 1; 
00586         t.approach(* l, doSagCorrection );
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 fitCathode " << 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.drift(leftRight);
00600         double eDistance = h.dDrift(leftRight);
00601             //... 
00602             if(nTrial  && !allAxial){
00603                int wire = h.wire()->id();
00604                int side = leftRight;
00605                if(side==0) side = -1;
00606                float x[3]={ onWire.x(), onWire.y(), onWire.z()};
00607                float p[3]={t.p().x(), t.p().y(), t.p().z()};
00608                float time = l->hit()->reccdc()->tdc + t0Offset;
00609                float dist =  distance;
00610                float edist = eDistance;
00611                int doPropDelay = 1;
00612                calcdc_driftdist_(
00613                &doPropDelay,&wire,&side,p,x,&time,&dist,&edist);
00614                distance = (double) dist;
00615                eDistance = (double) edist;
00616             }
00617         double eDistance2 = eDistance * eDistance;
00618 
00619         //...Residual...
00620         HepVector3D v = onTrack - onWire;
00621         double vmag = v.mag();
00622         double dDistance = vmag - distance;
00623 
00624         //...dxda...
00625         this->dxda( *l, t.helix(), dPhi, dxda, dyda, dzda , doSagCorrection );
00626 
00627         // ... Chi2 related ...
00628         double pChi2(0.);
00629 
00630         if( LayerStat == 0 || LayerStat == 1 ){
00631             // dDda = (v.x() * dxda + v.y() * dyda + v.z() * dzda) / vmag;
00632             Vector3 vw = h.wire()->direction();
00633             dDda = (vmag > 0.)
00634                 ? ((v.x() * (1. - vw.x() * vw.x()) -
00635                     v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
00636                    * dxda + 
00637                    (v.y() * (1. - vw.y() * vw.y()) -
00638                     v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
00639                    * dyda + 
00640                    (v.z() * (1. - vw.z() * vw.z()) -
00641                     v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
00642                    * dzda) / vmag
00643                 :  Vector(5,0);
00644             if(vmag<=0.0) {
00645               std::cout << "    in fit " << onTrack << ", " << onWire;
00646               h.dump();
00647             }
00648           dchi2da += (dDistance / eDistance2) * dDda;
00649           d2chi2d2a += vT_times_v(dDda) / eDistance2;
00650           double pChi2 = dDistance * dDistance / eDistance2;
00651           chi2 += pChi2;
00652 
00653         } else {
00654 
00655 
00656           dDda = ( v.x() * dxda + v.y() * dyda )/v.perp();
00657           dchi2da += (dDistance/eDistance2) * dDda;
00658           d2chi2d2a += vT_times_v(dDda)/eDistance2;
00659 
00660           pChi2 = 0;
00661           pChi2 += (dDistance/eDistance) * (dDistance/eDistance) ;
00662 
00663           if ( l->usecathode() >= 3 ) {
00664 
00665             TMDCClust * mclust = l->getmclust();
00666 
00667               double dDistanceZ(t.helix().x(dPhi).z());
00668 
00669               if( SysCorr ){
00670                 if( !nTrial ) {
00671                   mclust->zcalc( atan( t.helix().tanl()) );
00672                   mclust->esterz( atan( t.helix().tanl()) );
00673                 }
00674 
00675                 dDistanceZ -= mclust->zclustWithSysCorr();
00676              } else {
00677                 dDistanceZ -= mclust->zclust();
00678              }
00679               
00680              double eDistanceZ(mclust->erz());
00681              if( !eDistanceZ ) eDistanceZ = 99999.;
00682 
00683 
00684               double eDistance2Z = eDistanceZ * eDistanceZ;
00685               double pChi2z = 0;
00686               pChi2z = (dDistanceZ/eDistanceZ);
00687               pChi2z *= pChi2z;
00688 
00689 #ifdef TRKRECO_DEBUG_DETAIL
00690               std::cout << "dDistanceZ = " << dDistanceZ << std::endl;
00691 #endif
00692 
00693       //.... requirement for use of cluster
00694       if( nTrial == 0 && 
00695           fabs(dDistanceZ)< windowSize && 
00696             mclust->chits().length() == 1 
00697           ) l->setusecathode(4 );
00698 
00699       if( l->usecathode() == 4 ){
00700                 NusedCathode++;
00701                 dDzda = dzda ; 
00702                 dchi2da += (dDistanceZ/eDistance2Z) * dDzda;
00703                 d2chi2d2a += vT_times_v(dDzda)/eDistance2Z;
00704                 pChi2 +=  pChi2z ;
00705 
00706             }
00707           }
00708         
00709         } // end Chi2 related
00710 
00711         chi2 += pChi2;
00712 
00713 
00714         //...Store results...
00715         l->update(onTrack, onWire, leftRight, pChi2);
00716       
00717 
00718       } // TMLink loop end
00719 
00720       //...Check condition...
00721       double change = chi2Old - chi2;
00722       //if(TRKRECO_DEBUG_DETAIL>0)  std::cout << "chi2 change = " <<change << std::endl;
00723    
00724       if (fabs(change) < convergence) break;
00725       if (change < 0.) {
00726 
00727 #ifdef TRKRECO_DEBUG_DETAIL
00728           std::cout << "chi2Old, chi2=" << chi2Old <<" "<< chi2 << std::endl;
00729 #endif
00730 
00731           NusedCathode = 0;
00732           //change to the old value.
00733           a += factor*da;
00734           t._helix->a(a);
00735 
00736 
00737           chi2 = 0.;
00738           for (unsigned j = 0; j < 5; j++) dchi2da[j] = 0.;
00739           d2chi2d2a = SymMatrix(5, 0);
00740 
00741           
00742           //...Loop with hits...
00743           unsigned i = 0;
00744           while (TMLink * l = cores[i++]) {
00745 
00746               const TMDCWireHit & h = * l->hit();
00747 
00748      // Check layer status ( cathode added )          
00749         LayerStat = 0;
00750         if ( h.wire()->stereo() ) LayerStat = 1;
00751         unsigned nlayer = h.wire()->layerId();
00752         if (nlayer == 0 || nlayer == 1 || nlayer == 2 ) LayerStat = 2;
00753 
00754      //...Cal. closest points...
00755        int doSagCorrection = 0;
00756        if( nTrial  && !allAxial ) doSagCorrection = 1; 
00757         t.approach(* l , doSagCorrection );
00758         double dPhi = l->dPhi();
00759         const HepPoint3D & onTrack = l->positionOnTrack();
00760         const HepPoint3D & onWire = l->positionOnWire();
00761 
00762 #ifdef TRKRECO_DEBUG_DETAIL
00763         // std::cout << "    in fitCathode " << onTrack << ", " << onWire;
00764         // h.dump();
00765 #endif      
00766 
00767         //...Obtain drift distance and its error...
00768         unsigned leftRight = WireHitRight;
00769         if (onWire.cross(onTrack).z() < 0.)     leftRight = WireHitLeft;
00770         double distance = h.drift(leftRight);
00771         double eDistance = h.dDrift(leftRight);
00772        if(nTrial  && !allAxial){
00773                int wire = h.wire()->id();
00774                int side = leftRight;
00775                if(side==0) side = -1;
00776                float x[3]={ onWire.x(), onWire.y(), onWire.z()};
00777                float p[3]={t.p().x(), t.p().y(), t.p().z()};
00778                float time = l->hit()->reccdc()->tdc + t0Offset;
00779                float dist= distance;
00780                float edist = eDistance;
00781                int doPropDelay = 1; // 
00782                calcdc_driftdist_(
00783                &doPropDelay,&wire,&side,p,x,&time,&dist,&edist);
00784                distance = (double) dist;
00785                eDistance = (double) edist;
00786          }
00787         double eDistance2 = eDistance * eDistance;
00788 
00789         //...Residual...
00790         HepVector3D v = onTrack - onWire;
00791         double vmag = v.mag();
00792         double dDistance = vmag - distance;
00793 
00794         //...dxda...
00795         this->dxda(* l, t.helix(), dPhi, dxda, dyda, dzda , doSagCorrection );
00796 
00797         // ... Chi2 related ...
00798         double pChi2(0.);
00799 
00800 
00801         if( LayerStat == 0 || LayerStat == 1 ){
00802             // dDda = (v.x() * dxda + v.y() * dyda + v.z() * dzda) / vmag;
00803             Vector3 vw = h.wire()->direction();
00804             dDda = (vmag > 0.)
00805                 ? ((v.x() * (1. - vw.x() * vw.x()) -
00806                     v.y() * vw.x() * vw.y() - v.z() * vw.x() * vw.z())
00807                    * dxda + 
00808                    (v.y() * (1. - vw.y() * vw.y()) -
00809                     v.z() * vw.y() * vw.z() - v.x() * vw.y() * vw.x())
00810                    * dyda + 
00811                    (v.z() * (1. - vw.z() * vw.z()) -
00812                     v.x() * vw.z() * vw.x() - v.y() * vw.z() * vw.y())
00813                    * dzda) / vmag
00814                 : Vector(5,0);
00815             if(vmag<=0.0) {
00816               std::cout << "    in fit " << onTrack << ", " << onWire;
00817               h.dump();
00818             }
00819           dchi2da += (dDistance / eDistance2) * dDda;
00820           d2chi2d2a += vT_times_v(dDda) / eDistance2;
00821           double pChi2 = dDistance * dDistance / eDistance2;
00822           chi2 += pChi2;
00823 
00824         } else {
00825 
00826           dDda = ( v.x() * dxda + v.y() * dyda )/v.perp();
00827           dchi2da += (dDistance/eDistance2) * dDda;
00828           d2chi2d2a += vT_times_v(dDda)/eDistance2;
00829 
00830           pChi2 = 0;
00831           pChi2 += (dDistance/eDistance) * (dDistance/eDistance) ;
00832 
00833           if( l->usecathode() == 4 ){
00834             
00835             TMDCClust * mclust = l->getmclust();
00836 
00837             if( mclust ){
00838                 NusedCathode++;
00839 
00840               double dDistanceZ(t.helix().x(dPhi).z());
00841               if( SysCorr ) dDistanceZ -= mclust->zclustWithSysCorr();
00842               else          dDistanceZ -= mclust->zclust();
00843 
00844               double eDistanceZ(99999.);
00845               if( mclust->erz() != 0. ) eDistanceZ = mclust->erz();
00846 
00847               double eDistance2Z = eDistanceZ * eDistanceZ;
00848               double pChi2z = 0;
00849               pChi2z = (dDistanceZ/eDistanceZ);
00850               pChi2z *= pChi2z;
00851 
00852                 dDzda = dzda ; 
00853                 dchi2da += (dDistanceZ/eDistance2Z) * dDzda;
00854                 d2chi2d2a += vT_times_v(dDzda)/eDistance2Z;
00855                 pChi2 +=  pChi2z ;
00856             }
00857 
00858            }
00859         
00860         } // end Chi2 related
00861 
00862         chi2 += pChi2;
00863 
00864 
00865         //...Store results...
00866         l->update(onTrack, onWire, leftRight, pChi2);
00867       
00868           }
00869 
00870            //break;
00871 
00872           factor *= 0.75;
00873 #ifdef TRKRECO_DEBUG_DETAIL 
00874           std::cout << "factor = " << factor << std::endl;
00875           std::cout << "chi2 = " << chi2 << std::endl;
00876 #endif
00877           if(factor < 0.01)break;
00878 
00879       }
00880 
00881       chi2Old = chi2;
00882       
00883       //...Cal. helix parameters for next loop...
00884       if (allAxial) {
00885         f = dchi2da.sub(1, 3);
00886         e = d2chi2d2a.sub(1, 3);
00887         f = solve(e, f);
00888         da[0] = f[0];
00889         da[1] = f[1];
00890         da[2] = f[2];
00891         da[3] = 0.;
00892         da[4] = 0.;
00893       }
00894       else {
00895         da = solve(d2chi2d2a, dchi2da);
00896       }
00897       
00898 #ifdef TRKRECO_DEBUG_DETAIL
00899       //std::cout << "    fit " << nTrial << " : " << da << std::endl;
00900       //std::cout << "        d2chi " << d2chi2d2a << std::endl;
00901       //std::cout << "        dchi2 " << dchi2da << std::endl;
00902 #endif      
00903       
00904       a -= da;
00905       t._helix->a(a);
00906       ++nTrial;
00907     }
00908 
00909 
00910     //...Cal. error matrix...
00911     SymMatrix Ea(5, 0);
00912     unsigned dim;
00913     if (allAxial) {
00914       dim = 3;
00915       SymMatrix Eb(3, 0), Ec(3, 0);
00916       Eb = d2chi2d2a.sub(1, 3);
00917       Ec = Eb.inverse(err);
00918       Ea[0][0] = Ec[0][0];
00919       Ea[0][1] = Ec[0][1];
00920       Ea[0][2] = Ec[0][2];
00921       Ea[1][1] = Ec[1][1];
00922       Ea[1][2] = Ec[1][2];
00923       Ea[2][2] = Ec[2][2];
00924     }
00925     else {
00926       dim = 5;
00927       Ea = d2chi2d2a.inverse(err);
00928     }
00929     
00930     //...Store information...
00931     if (! err) {
00932       t._helix->a(a);
00933       t._helix->Ea(Ea);
00934     } else {
00935       err = TFitFailed;
00936     }
00937       
00938     t._ndf = t.nCores() + NusedCathode - dim;
00939 
00940     t._chi2 = chi2;
00941 
00942     t._fittedWithCathode = true;
00943     
00944     return err;
00945 }
00946 
00947 // end of addition
00948 
00949 */
00950 
00951 
00952 int
00953 TCosmicFitter::dxda(const TMLink & link,
00954                     const Helix & h,
00955                     double dPhi,
00956                     Vector & dxda,
00957                     Vector & dyda,
00958                     Vector & dzda,
00959                     int doSagCorrection) const {
00960 
00961     //...Setup...
00962     const TMDCWire & w = * link.wire();
00963     Vector a = h.a();
00964     double dRho  = a[0];
00965     double phi0  = a[1];
00966     double kappa = a[2];
00967    // double rho   = Helix::ConstantAlpha / kappa;
00968    // double rho   = 333.564095 / kappa;
00969     double rho   = 333.564095/(-1000*(m_pmgnIMF->getReferField())) / kappa;    
00970 cout<<"TCosmicFitter::rho: "<<333.564095/(-1000*(m_pmgnIMF->getReferField()))<<endl;
00971     double tanLambda = a[4];
00972 
00973     double sinPhi0 = sin(phi0);
00974     double cosPhi0 = cos(phi0);
00975     double sinPhi0dPhi = sin(phi0 + dPhi);
00976     double cosPhi0dPhi = cos(phi0 + dPhi);
00977     Vector dphida(5);
00978     //... sag correction
00979     HepPoint3D xw = w.xyPosition();
00980     HepPoint3D wireBackwardPosition = w.backwardPosition();
00981     HepVector3D v = w.direction();
00982 
00983     if(doSagCorrection ){
00984       cout<<"doSagCorrection in TCosmicFitter!"<<endl;
00985       int  wireID = w.id();
00986       float wirePosition[3];
00987       float wireZ = link.positionOnTrack().z();
00988       float dydz =0;
00989       float ybSag = 0;
00990       float yfSag = 0;
00991       if(wireZ >w.backwardPosition().z() &&
00992          wireZ < w.forwardPosition().z()    ){
00993 
00994 //zsl        calcdc_sag3_(&wireID, &wireZ, wirePosition, &dydz, &ybSag, &yfSag);   
00995   
00996         //... wire Position
00997         xw.setX( (double) wirePosition[0]);
00998         xw.setY( (double) wirePosition[1]);
00999         xw.setZ( (double) wirePosition[2]);
01000         //...
01001         wireBackwardPosition.setY((double) ybSag);
01002         //...
01003         //...        v.setY((double) dydz);
01004         HepVector3D v_aux(w.forwardPosition().x() - w.backwardPosition().x(),
01005                            yfSag - ybSag,
01006                            w.forwardPosition().z() - w.backwardPosition().z());
01007         v = v_aux.unit();      
01008       }
01009     }
01010 
01011     //...Axial case...
01012     if (w.axial()) {
01013       //        HepPoint3D d = h.center() - w.xyPosition();
01014         HepPoint3D d = h.center() - xw;
01015         double dmag2 = d.mag2();
01016 
01017         dphida[0] = (sinPhi0 * d.x() - cosPhi0 * d.y()) / dmag2;
01018         dphida[1] = (dRho + rho)    * (cosPhi0 * d.x() + sinPhi0 * d.y())
01019             / dmag2 - 1.;
01020         dphida[2] = (- rho / kappa) * (sinPhi0 * d.x() - cosPhi0 * d.y())
01021             / dmag2;
01022         dphida[3] = 0.;
01023         dphida[4] = 0.;
01024     }
01025 
01026     //...Stereo case...
01027     else {
01028         HepPoint3D onTrack = h.x(dPhi);
01029         Vector c(3);
01030         //c = HepPoint3D(w.backwardPosition() - (v * w.backwardPosition()) * v);
01031         c = HepPoint3D(wireBackwardPosition - (v * wireBackwardPosition) * v);
01032 
01033         Vector x(3);
01034         x = onTrack;
01035 
01036         Vector dxdphi(3);
01037         dxdphi[0] =   rho * sinPhi0dPhi;
01038         dxdphi[1] = - rho * cosPhi0dPhi;
01039         dxdphi[2] = - rho * tanLambda;
01040 
01041         Vector d2xdphi2(3);
01042         d2xdphi2[0] = rho * cosPhi0dPhi;
01043         d2xdphi2[1] = rho * sinPhi0dPhi;
01044         d2xdphi2[2] = 0.;
01045 
01046         double dxdphi_dot_v = dxdphi[0]*v.x() + dxdphi[1]*v.y() + dxdphi[2]*v.z();
01047         double x_dot_v      = x[0]*v.x() + x[1]*v.y() + x[2]*v.z();
01048 
01049         double dfdphi = - (dxdphi[0] - dxdphi_dot_v*v.x()) * dxdphi[0] 
01050                         - (dxdphi[1] - dxdphi_dot_v*v.y()) * dxdphi[1]
01051                         - (dxdphi[2] - dxdphi_dot_v*v.z()) * dxdphi[2]
01052                         - (x[0] - c[0] - x_dot_v*v.x()) * d2xdphi2[0]
01053                         - (x[1] - c[1] - x_dot_v*v.y()) * d2xdphi2[1];
01054                     /*  - (x[2] - c[2] - x_dot_v*v.z()) * d2xdphi2[2];  = 0. */
01055 
01056 
01057         //dxda_phi, dyda_phi, dzda_phi : phi is fixed
01058         Vector dxda_phi(5);
01059         dxda_phi[0] =  cosPhi0;
01060         dxda_phi[1] = -(dRho + rho)*sinPhi0 + rho*sinPhi0dPhi; 
01061         dxda_phi[2] = -(rho/kappa)*( cosPhi0 - cosPhi0dPhi );
01062         dxda_phi[3] =  0.;
01063         dxda_phi[4] =  0.;
01064 
01065         Vector dyda_phi(5);
01066         dyda_phi[0] =  sinPhi0;
01067         dyda_phi[1] =  (dRho + rho)*cosPhi0 - rho*cosPhi0dPhi;
01068         dyda_phi[2] = -(rho/kappa)*( sinPhi0 - sinPhi0dPhi );
01069         dyda_phi[3] =  0.;
01070         dyda_phi[4] =  0.;
01071         
01072         Vector dzda_phi(5);
01073         dzda_phi[0] =  0.;
01074         dzda_phi[1] =  0.;
01075         dzda_phi[2] =  (rho/kappa)*tanLambda*dPhi;
01076         dzda_phi[3] =  1.;
01077         dzda_phi[4] = -rho*dPhi;
01078 
01079         Vector d2xdphida(5);
01080         d2xdphida[0] =  0.;
01081         d2xdphida[1] =  rho*cosPhi0dPhi; 
01082         d2xdphida[2] = -(rho/kappa)*sinPhi0dPhi; 
01083         d2xdphida[3] =  0.;
01084         d2xdphida[4] =  0.;
01085 
01086         Vector d2ydphida(5);
01087         d2ydphida[0] = 0.;
01088         d2ydphida[1] = rho*sinPhi0dPhi;
01089         d2ydphida[2] = (rho/kappa)*cosPhi0dPhi; 
01090         d2ydphida[3] = 0.;
01091         d2ydphida[4] = 0.;
01092 
01093         Vector d2zdphida(5);
01094         d2zdphida[0] =  0.;
01095         d2zdphida[1] =  0.;
01096         d2zdphida[2] =  (rho/kappa)*tanLambda;
01097         d2zdphida[3] =  0.;
01098         d2zdphida[4] = -rho;
01099  
01100         Vector dfda(5);
01101         for( int i = 0; i < 5; i++ ){
01102           double d_dot_v = v.x()*dxda_phi[i] 
01103                          + v.y()*dyda_phi[i] 
01104                          + v.z()*dzda_phi[i];
01105           dfda[i] = - (dxda_phi[i] - d_dot_v*v.x()) * dxdphi[0]
01106                     - (dyda_phi[i] - d_dot_v*v.y()) * dxdphi[1]
01107                     - (dzda_phi[i] - d_dot_v*v.z()) * dxdphi[2]
01108                     - (x[0] - c[0] - x_dot_v*v.x()) * d2xdphida[i]
01109                     - (x[1] - c[1] - x_dot_v*v.y()) * d2ydphida[i]
01110                     - (x[2] - c[2] - x_dot_v*v.z()) * d2zdphida[i];
01111           dphida[i] = - dfda[i] /dfdphi;
01112         }
01113     }
01114 
01115     dxda[0] = cosPhi0 + rho * sinPhi0dPhi * dphida[0];
01116     dxda[1] = - (dRho + rho) * sinPhi0 + rho * sinPhi0dPhi * (1. + dphida[1]);
01117     dxda[2] = - rho / kappa * (cosPhi0 - cosPhi0dPhi)
01118               + rho * sinPhi0dPhi * dphida[2];
01119     dxda[3] = rho * sinPhi0dPhi * dphida[3];
01120     dxda[4] = rho * sinPhi0dPhi * dphida[4];
01121 
01122     dyda[0] = sinPhi0 - rho * cosPhi0dPhi * dphida[0];
01123     dyda[1] = (dRho + rho) * cosPhi0 - rho * cosPhi0dPhi * (1. + dphida[1]);
01124     dyda[2] = - rho / kappa * (sinPhi0 - sinPhi0dPhi)
01125               - rho * cosPhi0dPhi * dphida[2];
01126     dyda[3] = - rho * cosPhi0dPhi * dphida[3];
01127     dyda[4] = - rho * cosPhi0dPhi * dphida[4];
01128 
01129     dzda[0] = - rho * tanLambda * dphida[0];
01130     dzda[1] = - rho * tanLambda * dphida[1];
01131     dzda[2] = rho / kappa * tanLambda * dPhi - rho * tanLambda * dphida[2];
01132     dzda[3] = 1. - rho * tanLambda * dphida[3];
01133     dzda[4] = - rho * dPhi - rho * tanLambda * dphida[4];
01134     
01135     return 0;
01136 }

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