00001 #define OPTNK
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00047 #include "TrkReco/TTrack.h"
00048 #include "TrkReco/TSegment.h"
00049
00050
00051
00052
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
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
00100
00101
00102 fitter(& TTrack::_fitter);
00103
00104
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
00111
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
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
00128
00129
00130
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
00145 _state(a._state),
00146 _mother(a._mother),
00147 _daughter(a._daughter) {
00148
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
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
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
00193 fitter(& TTrack::_fitter);
00194
00195 if(_helix->kappa() > 0.)_charge = 1.;
00196 else _charge = -1.;
00197
00198 _fitted = false;
00199 _fittedWithCathode = false;
00200
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
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
00272 const AList<TMLink> & cores = TTrackBase::cores();
00273 const AList<TMLink> * links = & cores;
00274 if (cores.length() == 0) links = & _links;
00275
00276
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
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);
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 if ( int(_charge) == 0 ) {
00348 std::cout << "HelCyl gets a straight line !!" << std::endl;
00349 return -1 ;
00350 }
00351
00352
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
00363 double dPhi;
00364 double zee;
00365
00366
00367
00368
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
00384
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
00406
00407
00408
00409 xp.setX( Cross1.x() );
00410 xp.setY( Cross1.y() );
00411 xp.setZ( _helix->x(dPhi).z() );
00412
00413
00414 if ( xp.z() > zb && xp.z() < zf ) {
00415 phi = dPhi;
00416
00417
00418
00419
00420 return 1 ;
00421 }
00422 }
00423
00424
00425
00426
00427 if ( fabs(tanl) < 0.1 ) {
00428
00429
00430
00431
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
00446
00447
00448
00449 if ( fabs(dPhi) > 2. * M_PI ) {
00450
00451
00452
00453
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
00464
00465
00466
00467 return 0 ;
00468 }
00469
00470 phi = dPhi ;
00471
00472
00473
00474
00475
00476 return status ;
00477
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
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
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
00802
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
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
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
00857
00858
00859
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
00950 if (_links.length() < 4) return -1;
00951
00952
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
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
00972 chi2 = 0.;
00973 for (unsigned j = 0; j < 5; ++j) dchi2da[j] = 0.;
00974 d2chi2d2a = SymMatrix(5, 0);
00975
00976
00977 unsigned i = 0;
00978 while (TMLink * l = _links[i++]) {
00979 const TMDCWireHit & h = * l->hit();
00980
00981
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
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
01001 HepVector3D v = onTrack2 - onWire2;
01002 double vmag = v.mag();
01003 double dDistance = vmag - distance;
01004
01005
01006 this->dxda2D(* l, dPhi, dxda, dyda, dzda);
01007
01008
01009
01010 dDda = (vmag > 0.)
01011 ? (v.x() * dxda +
01012 v.y() * dyda ) / vmag
01013 : Vector(5,0);
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
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
01035 l->update(onTrack2, onWire2, leftRight, pChi2);
01036 }
01037
01038
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
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
01054 unsigned i = 0;
01055 while (TMLink * l = _links[i++]) {
01056 const TMDCWireHit & h = * l->hit();
01057
01058
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
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
01074 HepVector3D v = onTrack2 - onWire2;
01075 double vmag = v.mag();
01076 double dDistance = vmag - distance;
01077
01078
01079 this->dxda2D(* l, dPhi, dxda, dyda, dzda);
01080
01081
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
01096 l->update(onTrack2, onWire2, leftRight, pChi2);
01097 }
01098
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
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
01122
01123
01124
01125 ++nTrial;
01126 }
01127
01128
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
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
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543 #if OLD_STEREO
01544 int
01545 TTrack::stereoHitForCurl(TMLink & link, AList<HepPoint3D> & arcZList) const
01546 {
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
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
01571 link.position(tmp);
01572 arcZList.removeAll();
01573
01574
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());
01587 d2[1] = vmag2*R[1]*R[1] + (wv*wv - vmag2*w.mag2());
01588
01589
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
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
01613 double l[2][2];
01614 double z[2][2];
01615
01616 if(ok_outer){
01617 l[0][0] = (- wv + d[0]) / vmag2;
01618 l[1][0] = (- wv - d[0]) / vmag2;
01619 z[0][0] = X.z() + l[0][0]*V.z();
01620 z[1][0] = X.z() + l[1][0]*V.z();
01621 }
01622
01623 if(ok_inner){
01624 l[0][1] = (- wv + d[1]) / vmag2;
01625 l[1][1] = (- wv - d[1]) / vmag2;
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
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
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
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
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
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
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
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
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
01825 deleteListForCurl(arcZList1, arcZList2);
01826 return -1;
01827 }
01828
01829
01830 HepPoint3D tmp1 = *arcZList1[flag1];
01831 HepPoint3D tmp2 = *arcZList2[flag2];
01832 link1.position(tmp1);
01833 link2.position(tmp2);
01834
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
01871
01872
01873
01874
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
01895 deleteListForCurl(arcZList1, arcZList2, arcZList3);
01896 return -1;
01897 }
01898
01899 if(ok1 == 0 && ok2 == 0 && ok3 == 0){
01900
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
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
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
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
02027 for(unsigned j = 0; j < 4; ++j)
02028 list[i]->arcZ(tmp,j);
02029
02030
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());
02038 d2[1] = vmag2*R[1]*R[1] + (wv*wv - vmag2*w.mag2());
02039
02040
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
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
02059 double l[2][2];
02060 double z[2][2];
02061
02062 if(ok_outer){
02063 l[0][0] = (- wv + d[0]) / vmag2;
02064 l[1][0] = (- wv - d[0]) / vmag2;
02065 z[0][0] = X.z() + l[0][0]*V.z();
02066 z[1][0] = X.z() + l[1][0]*V.z();
02067 }
02068
02069 if(ok_inner){
02070 l[0][1] = (- wv + d[1]) / vmag2;
02071 l[1][1] = (- wv - d[1]) / vmag2;
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
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
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
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
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
02182 ++index;
02183 }
02184 if(ok_xy[1][0]){
02185
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
02196 ++index;
02197 }
02198 if(ok_xy[0][1]){
02199
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
02210 ++index;
02211 }
02212 if(ok_xy[1][1]){
02213
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
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
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
02403
02404
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
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
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
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
02444
02445 const double Bz = -1000*m_pmgnIMF->getReferField();
02446 double rho = 333.564095/(kappa * Bz);
02447
02448
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
02487
02488
02489
02490
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
02547
02548
02549
02550
02551
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
02567 while(nTrial < 100){
02568
02569 chi2 = 0.;
02570 for (unsigned j=0;j<3;++j) dchi2da[j] = 0.;
02571 d2chi2d2a = SymMatrix(3, 0);
02572 usedWireNumber = 0;
02573
02574
02575 unsigned i = 0;
02576 while (TMLink * l = _links[i++]) {
02577 if(l->fit2D() == 0)continue;
02578 const TMDCWireHit &h = *l->hit();
02579
02580
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
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
02600 HepVector3D v = onTrack2 - onWire2;
02601 double vmag = v.mag();
02602 double dDistance = vmag - distance;
02603
02604
02605 if(this->dxda2D(*l, dPhi, dxda, dyda) != 0)continue;
02606
02607
02608
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
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
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
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
02684 unsigned i = 0;
02685 while (TMLink *l = _links[i++]) {
02686 if(l->fit2D() == 0)continue;
02687 const TMDCWireHit & h = * l->hit();
02688
02689
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
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
02705 HepVector3D v = onTrack2 - onWire2;
02706 double vmag = v.mag();
02707 double dDistance = vmag - distance;
02708
02709
02710 if(this->dxda2D(*l, dPhi, dxda, dyda) != 0)continue;
02711
02712
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
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
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
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
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
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
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
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
02931
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
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
02979
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();
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;
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.)
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
03053 #ifdef TRKRECO_DEBUG
03054
03055
03056 #endif
03057
03058 int
03059 TTrack::approach(TMLink & link, bool doSagCorrection) const {
03060
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
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
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
03098 double kappa = _helix->kappa();
03099 double phi0 = _helix->phi0();
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110 #ifdef TRKRECO_DEBUG
03111 double firstdfdphi = 0.;
03112 static bool first = true;
03113 if (first) {
03114
03115
03116
03117 }
03118 #endif
03119
03120
03121
03122
03123
03124
03125
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
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
03157 double t_d2Xd2Phi[2];
03158 t_d2Xd2Phi[0] = rcosPhi;
03159 t_d2Xd2Phi[1] = rsinPhi;
03160
03161
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
03178 firstdfdphi = dfdphi;
03179 }
03180
03181
03182 if (nTrial > 3) {
03183 std::cout << "TTrack::approach ... " << w.name() << " "
03184 << "dfdphi(0)=" << firstdfdphi
03185 << ",(" << nTrial << ")=" << dfdphi << endl;
03186 }
03187 #endif
03188
03189
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
03203
03204 dPhi -= dfdphi / d2fd2phi;
03205
03206
03207
03208
03209 ++nTrial;
03210 }
03211
03212
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
03220 #endif
03221
03222 return nTrial;
03223 }
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
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
03377
03378
03379
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
03397
03398
03399
03400
03401
03402
03403
03404
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){
03410 if (link.leftRight() == WireHitRight){
03411 lr = - lr;
03412 }
03413 }else{
03414 if (link.leftRight() == WireHitLeft){
03415 lr = - lr;
03416 }
03417 }
03418 if (link.leftRight() == 2) lr = ORIGIN;
03419
03420
03421 X += lr;
03422
03423
03424
03425 HepPoint3D tmp(-9999., -9999., 0.);
03426 HepVector3D x = HepVector3D(X.x(), X.y(), 0.);
03427 HepVector3D w = x - center;
03428
03429 HepVector3D V = h.wire()->direction();
03430
03431
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
03440
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
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
03470 double l[2];
03471 l[0] = (- wv + d) / vmag2;
03472 l[1] = (- wv - d) / vmag2;
03473
03474
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
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
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
03531 HepVector3D p[2];
03532 p[0] = x + l[0] * v;
03533 p[1] = x + l[1] * v;
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547 unsigned best = 0;
03548 if (ok[1]) best = 1;
03549
03550
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
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
03573 AList<TMLink> links = segment.cores();
03574 unsigned n = links.length();
03575
03576
03577
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
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
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
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
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
03791
03792
03793 }
03794
03795 std::string
03796 TrackStatus(const MdcRec_trk_add & a) {
03797
03798
03799
03800
03801
03802
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
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 }