00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #define HEP_SHORT_NAMES
00014 #include <float.h>
00015
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
00021
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
00080
00081
00082
00083
00084 TCosmicFitter::TCosmicFitter(const std::string & name) : TMFitter(name) {
00085
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
00100
00101
00102
00103
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
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
00133
00134 if (b.objectType() != Track) return TFitUnavailable;
00135 TTrack & t = (TTrack &) b;
00136
00137
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
00151 }else{
00152 log << MSG::WARNING << "Could not find RecEsTimeCol" << endreq;
00153 }
00154
00155
00156
00157
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
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;
00175
00176 Vector maxDouble(5);
00177 for (unsigned i = 0; i < 5; i++) maxDouble[i] = (FLT_MAX);
00178
00179
00180 unsigned nTrial = 0;
00181 while (nTrial < NTrailMax) {
00182
00183
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
00190 const float Rad = 81;
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
00198 unsigned i = 0;
00199 while (TMLink * l = t.links()[i++]) {
00200 const TMDCWireHit & h = * l->hit();
00201
00202
00203 if (h.state() & WireHitInvalidForFit) continue;
00204 if (! (h.state() & WireHitFittingValid)) continue;
00205
00206
00207 if (! nTrial)
00208 if (h.wire()->stereo()) allAxial = false;
00209
00210
00211 int doSagCorrection = 0;
00212
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
00220
00221 #endif
00222
00223
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]);
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;
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;
00255 edist = edist/10.0;
00256
00257
00258
00259
00260 distance = (double) dist;
00261 eDistance = (double) edist;
00262
00263 l->drift(distance,0);
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
00272 HepVector3D v = onTrack - onWire;
00273 double vmag = v.mag();
00274 double dDistance = vmag - distance;
00275
00276
00277 this->dxda(*l, t.helix(), dPhi, dxda, dyda, dzda, doSagCorrection);
00278
00279
00280
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
00303 l->update(onTrack, onWire, leftRight, pChi2);
00304 }
00305
00306
00307 double change = chi2Old - chi2;
00308 if (fabs(change) < convergence) break;
00309
00310
00311 if (change < 0.){
00312 #ifdef TRKRECO_DEBUG_DETAIL
00313 std::cout << "chi2Old, chi2=" << chi2Old <<" "<< chi2 << std::endl;
00314 #endif
00315
00316 a += factor*da;
00317
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
00325 unsigned i = 0;
00326 while (TMLink * l = t.links()[i++]) {
00327 const TMDCWireHit & h = * l->hit();
00328
00329
00330 if (h.state() & WireHitInvalidForFit) continue;
00331 if (! (h.state() & WireHitFittingValid)) continue;
00332
00333
00334 if (! nTrial)
00335 if (h.wire()->stereo()) allAxial = false;
00336
00337
00338 int doSagCorrection = 0;
00339
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
00347
00348 #endif
00349
00350
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]);
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;
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
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;
00383 edist = edist/10.0;
00384
00385
00386
00387
00388 distance = (double) dist;
00389 eDistance = (double) edist;
00390
00391 l->drift(distance,0);
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
00400 HepVector3D v = onTrack - onWire;
00401 double vmag = v.mag();
00402 double dDistance = vmag - distance;
00403
00404
00405 this->dxda(*l, t.helix(), dPhi, dxda, dyda, dzda, doSagCorrection);
00406
00407
00408
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
00431 l->update(onTrack, onWire, leftRight, pChi2);
00432 }
00433
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
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
00461
00462
00463 #endif
00464
00465 a -= factor*da;
00466
00467 t._helix->a(a);
00468 ++nTrial;
00469 }
00470
00471
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
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
00503
00504 return err;
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
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
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
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
00968
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
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
00995
00996
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
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
01012 if (w.axial()) {
01013
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
01027 else {
01028 HepPoint3D onTrack = h.x(dPhi);
01029 Vector c(3);
01030
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
01055
01056
01057
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 }