00001
00002
00003
00004
00005
00006
00008
00009
00010
00011
00012
00013
00014
00015 #include <cassert>
00016 #include <cmath>
00017 #include <float.h>
00018
00019 #include <TMath.h>
00020
00021 #include "MessageService/MsgService.h"
00022 #include "MinosObjectMap/MomNavigator.h"
00023
00024 #include "Algorithm/AlgConfig.h"
00025 #include "Algorithm/AlgFactory.h"
00026 #include "Algorithm/AlgHandle.h"
00027
00028 #include "Candidate/CandContext.h"
00029
00030 #include "CandFitTrackCam/AlgFitTrackCam.h"
00031 #include "CandFitTrackCam/AlgFitTrackCam.h"
00032 #include "CandFitTrackCam/CandFitTrackCamHandle.h"
00033
00034 #include "Calibrator/Calibrator.h"
00035
00036 #include "Validity/VldContext.h"
00037
00038 #include "CandData/CandRecord.h"
00039 #include "CandData/CandHeader.h"
00040
00041 #include "RecoBase/CandStrip.h"
00042 #include "RecoBase/CandStripHandle.h"
00043 #include "RecoBase/CandTrackHandle.h"
00044 #include "RecoBase/AlgTrack.h"
00045 #include "RecoBase/CandSliceHandle.h"
00046 #include "RecoBase/CandStripListHandle.h"
00047 #include "CandDigit/CandDigitListHandle.h"
00048
00049 #include "BField/BField.h"
00050
00051 #include "Swimmer/SwimGeo.h"
00052 #include "Swimmer/SwimSwimmer.h"
00053 #include "Swimmer/SwimStepper.h"
00054 #include "Swimmer/SwimPrintStepAction.h"
00055 #include "Swimmer/SwimParticle.h"
00056 #include "Swimmer/SwimZCondition.h"
00057 #include "Swimmer/SwimPlaneInterface.h"
00058
00059 #include "GeoSwimmer/GeoSwimmer.h"
00060 #include "GeoSwimmer/GeoSwimParticle.h"
00061 #include "GeoSwimmer/GeoSwimZCondition.h"
00062
00063 #include "UgliGeometry/UgliGeomHandle.h"
00064
00065 #include "DataUtil/GetMomFromRange.h"
00066
00067 #include <sys/time.h>
00068
00069 ClassImp(AlgFitTrackCam)
00070
00071 CVSID("$Id: AlgFitTrackCam.cxx,v 1.75 2009/12/28 19:18:05 musser Exp $");
00072
00074 AlgFitTrackCam::AlgFitTrackCam()
00075 {
00076 }
00078
00079
00081 AlgFitTrackCam::~AlgFitTrackCam()
00082 {
00083 }
00085
00086
00088 void AlgFitTrackCam::RunAlg(AlgConfig & ac,
00089 CandHandle &ch, CandContext &cx)
00090 {
00091
00092
00093
00094
00095 if(!ac.Get("UseGeoSwimmer",UseGeoSwimmer)) cout << "Couldn't Get UseGeoSwimmer\n";
00096
00097
00098 assert(ch.InheritsFrom("CandFitTrackCamHandle"));
00099 CandFitTrackCamHandle &cth = dynamic_cast<CandFitTrackCamHandle &>(ch);
00100
00101 nbfield=0;
00102 bave=0;
00103 TIter FitTrackStripItr = cth.GetDaughterIterator();
00104 while(CandStripHandle* FitTrackStrip = dynamic_cast<CandStripHandle*>(FitTrackStripItr())) cth.RemoveDaughter(FitTrackStrip);
00105
00106 assert(cx.GetDataIn());
00107
00108
00109 assert(cx.GetDataIn()->InheritsFrom("CandTrackHandle"));
00110 track = dynamic_cast<const CandTrackHandle*>(cx.GetDataIn());
00111 if( !track || track->GetNDaughters()<1 ) { return; }
00112 cth.SetFinderTrack((CandTrackHandle*)(track));
00113
00114 const CandSliceHandle* slice = dynamic_cast<const CandSliceHandle*>(track->GetCandSlice());
00115 assert(slice);
00116 cth.SetCandSlice(slice);
00117
00118
00120
00122
00123 debug=false;
00124
00125
00127 if( track->GetEndZ() > track->GetVtxZ() ) {ZIncreasesWithTime=true;}
00128 else {ZIncreasesWithTime=false;}
00129
00130 SaveData=false;
00131 SwimThroughShower=false;
00132 PassTrack=true;
00133
00134 MaxPlane=-20;
00135 MinPlane=500;
00136
00137 DeltaZ=-99;
00138 DeltaPlane=-99;
00139 ShowerEntryPlane=-99;
00140
00141 NIter=0; TotalNSwimFail=0; NumFinderStrips=0;
00142
00143 for (unsigned int i=0; i<5; ++i) {
00144 x_k[i]=0; x_k_minus[i]=0; H_k[i]=0; K_k[i]=0;
00145 VtxCov[i]=-999; EndCov[i]=-999;
00146 for (unsigned int j=0; j<5; ++j) {
00147 C_k[i][j]=0; C_k_minus[i][j]=0; C_k_intermediate[i][j]=0;
00148 F_k[i][j]=0; F_k_minus[i][j]=0;
00149 Q_k[i][j]=0; Q_k_minus[i][j]=0;
00150 Identity[i][j]=0;
00151 }
00152 }
00153
00154 Identity[0][0]=1; Identity[1][1]=1; Identity[2][2]=1; Identity[3][3]=1; Identity[4][4]=1;
00156
00157
00158
00160 x_k_minus[0]=track->GetVtxU();
00161 x_k_minus[1]=track->GetVtxV();
00162 if(track->GetVtxDirCosZ()!=0.) {
00163 x_k_minus[2]=track->GetVtxDirCosU()/track->GetVtxDirCosZ();
00164 x_k_minus[3]=track->GetVtxDirCosV()/track->GetVtxDirCosZ();
00165 }
00166 x_k_minus[4]=0.;
00167 x_k4_biased=0;
00169
00170
00171
00173 CandRecord* candrec = (CandRecord*)(cx.GetCandRecord());
00174 assert(candrec);
00175
00176 vldc = (VldContext*)(candrec->GetVldContext());
00177 assert(vldc);
00178
00179 CandHeader* candhead = (CandHeader*)(candrec->GetCandHeader());
00180 assert(candhead);
00181
00182 MSG("AlgFitTrackCam",Msg::kSynopsis) << "RunAlg, New track, Run: " << candhead->GetRun()
00183 << " Snarl: " << candhead->GetSnarl() << endl;
00185
00186
00187
00189 InitialFramework(slice,cx);
00190 GetFitData(MinPlane,MaxPlane);
00191 RunTheFitter(cth);
00193
00194
00195
00197 if(vldc->GetDetector()==Detector::kNear) {CleanNDLists(cth,cx);}
00198
00199 for (unsigned int i=0; i<490; ++i) {
00200 InitTrkStripData[i].clear();
00201 SlcStripData[i].clear();
00202 TrkStripData[i].clear();
00203 FilteredData[i].clear();
00204 }
00206 }
00208
00209
00210
00212 void AlgFitTrackCam::InitialFramework(const CandSliceHandle* slice,CandContext &cx)
00213 {
00214
00215 Detector::Detector_t detector = vldc->GetDetector();
00216
00217 TIter SlcStripItr = slice->GetDaughterIterator();
00218 TIter TrkStripItr = track->GetDaughterIterator();
00219
00220
00221 int SlicePlane;
00222
00223 while(CandStripHandle* SlcStrip = dynamic_cast<CandStripHandle*>(SlcStripItr()))
00224 {
00225 SlicePlane=SlcStrip->GetPlane();
00226 if(detector==Detector::kNear && SlicePlane>=121) {continue;}
00227
00228 StripStruct temp;
00229 temp.csh=SlcStrip;
00230
00231 SlcStripData[SlicePlane].push_back(temp);
00232 }
00233 SlcStripItr.Reset();
00234
00235
00236
00237 int TrackPlane;
00238 MeanTrackTime=0;
00239
00240 while(CandStripHandle* TrkStrip = dynamic_cast<CandStripHandle*>(TrkStripItr()))
00241 {
00242 TrackPlane=TrkStrip->GetPlane();
00243 if(detector==Detector::kNear && TrackPlane>=121) {continue;}
00244
00245 StripStruct temp;
00246 temp.csh=TrkStrip;
00247
00248 InitTrkStripData[TrackPlane].push_back(temp);
00249 NumFinderStrips++;
00250
00251
00252 if (TrackPlane>MaxPlane) {MaxPlane=TrackPlane;}
00253 if (TrackPlane<MinPlane) {MinPlane=TrackPlane;}
00254
00255 if(detector==Detector::kNear) {MeanTrackTime+=NDStripBegTime(TrkStrip);}
00256 }
00257 TrkStripItr.Reset();
00258
00259
00260 if(detector==Detector::kNear) {
00261 if(NumFinderStrips!=0) {MeanTrackTime/=double(NumFinderStrips);}
00262 GenerateNDSpectStrips(slice,cx);
00263 }
00264
00265 }
00267
00268
00269
00271 void AlgFitTrackCam::ShowerStrips()
00272 {
00273 MSG("AlgFitTrackCam",Msg::kDebug) << "ShowerStrips, Look for large vertex shower" << endl;
00274
00275
00276 int Increment; int NumberOfStrips;
00277 int Plane; int NewPlane;
00278
00279 int VtxShwWindow=8;
00280 int StripsForShw=4;
00281 double PEThreshold=2.;
00282
00283 if(ZIncreasesWithTime==true) {Plane=MinPlane; Increment=1;}
00284 else {Plane=MaxPlane; Increment=-1;}
00285 NewPlane=Plane;
00286
00287
00288
00290 while(abs(Plane-NewPlane)<=VtxShwWindow && NewPlane>=MinPlane && NewPlane<=MaxPlane) {
00291
00292 if(SlcStripData[NewPlane].size()>0) {
00293 NumberOfStrips=0;
00294
00295
00296
00297
00298
00299 if(FilteredData[NewPlane].size()>0) {
00300 if(SlcStripData[NewPlane][0].csh->GetPlaneView()==2) {
00301 StripsForShw=min(7,int( 4+(0.25*fabs(FilteredData[NewPlane][0].x_k2)) ));
00302 }
00303 else {StripsForShw=min(7,int( 4+(0.25*fabs(FilteredData[NewPlane][0].x_k3)) ));}
00304 }
00305 else {StripsForShw=4;}
00306
00307
00308
00309 for(unsigned int j=0; j<SlcStripData[NewPlane].size(); ++j) {
00310 if(SlcStripData[NewPlane][j].csh->GetCharge()>PEThreshold) {NumberOfStrips++;}
00311 }
00312
00313
00314
00315
00316 if(NumberOfStrips>=StripsForShw) {ShowerEntryPlane=NewPlane; SwimThroughShower=true; break;}
00317
00318 NewPlane+=Increment;
00319 }
00320 else {NewPlane+=Increment;}
00321 }
00323
00324
00325
00326
00328 if(SwimThroughShower==true) {
00329 NewPlane=ShowerEntryPlane+Increment;
00330 int PlanesSinceLastHit=0;
00331 int PlaneWindow=4;
00332
00333 while(PlanesSinceLastHit<PlaneWindow && NewPlane>=MinPlane && NewPlane<=MaxPlane) {
00334 if(SlcStripData[NewPlane].size()>0) {
00335 NumberOfStrips=0;
00336
00337
00338 if(FilteredData[NewPlane].size()>0) {
00339 if(SlcStripData[NewPlane][0].csh->GetPlaneView()==2) {
00340 StripsForShw=min(7,int(4+(0.25*fabs(FilteredData[NewPlane][0].x_k2)) ));
00341 }
00342 else {StripsForShw=min(7,int(4+(0.25*fabs(FilteredData[NewPlane][0].x_k3)) ));}
00343 }
00344 else {StripsForShw=4;}
00345
00346
00347
00348 for(unsigned int j=0; j<SlcStripData[NewPlane].size(); ++j) {
00349 if(SlcStripData[NewPlane][j].csh->GetCharge()>PEThreshold) {NumberOfStrips++;}
00350 }
00351 if(NumberOfStrips>=StripsForShw) {
00352 ShowerEntryPlane=NewPlane; NewPlane+=Increment; PlanesSinceLastHit=0;
00353 }
00354 else {PlanesSinceLastHit++; NewPlane+=Increment;}
00355
00356 }
00357 else {PlanesSinceLastHit++; NewPlane+=Increment;}
00358 }
00359 }
00361 }
00363
00364
00365
00367 void AlgFitTrackCam::RunTheFitter(CandFitTrackCamHandle &cth)
00368 {
00369 MSG("AlgFitTrackCam",Msg::kSynopsis) << "RunTheFitter, Call methods in the appropriate order" << endl;
00370 GetInitialCovarianceMatrix(true);
00371
00372
00374 Detector::Detector_t detector = vldc->GetDetector();
00375
00376
00377 if(ZIncreasesWithTime==true)
00378 {
00379
00380 NIter++;
00381 LastIteration=false;
00382
00383
00384 StoreFilteredData(MinPlane);
00385 SaveData=true; GoForwards();
00386 ResetCovarianceMatrix();
00387
00388
00389 ShowerStrips();
00390 if(SwimThroughShower==true) {RemoveTrkHitsInShw();}
00391
00392 for (unsigned int i=0; i<490; ++i) {FilteredData[i].clear();}
00393 StoreFilteredData(MaxPlane); GoBackwards();
00394
00395 if(SwimThroughShower==true) {ShowerSwim();}
00396 ResetCovarianceMatrix();
00397
00398 bool StripsFound = FindTheStrips(cth,false);
00399 EndofRangePlane=MaxPlane;
00400
00401 if(StripsFound==true) {
00402 for(int nint=0;nint<2;nint++){
00403 if(nint==0) MSG("AlgFitTrackCam",Msg::kSynopsis) << "Bias Fit" << endl;
00404 if(nint==1) MSG("AlgFitTrackCam",Msg::kSynopsis) << "Un-Biased Fit" << endl;
00405 NIter++;
00406 if(nint==1)LastIteration = true;
00407
00408
00409 for (unsigned int i=0; i<490; ++i) {TrkStripData[i].clear();}
00410 GetFitData(MinPlane,MaxPlane);
00411
00412
00413 StoreFilteredData(MinPlane);
00414 SaveData=true; GoForwards();
00415
00416 if(detector==Detector::kNear && nint==0) {SpectrometerSwim(cth);}
00417 ResetCovarianceMatrix();
00418
00419
00420
00421 StoreFilteredData(EndofRangePlane);
00422 SaveData=true; GoBackwards();
00423
00424 if(nint==0) {
00425 x_k4_biased= x_k[4];
00426 eqp_biased = pow(VtxCov[4],0.5);
00427 }
00428 ResetCovarianceMatrix();
00429 }
00430 }
00431 else {PassTrack=false;}
00432 }
00433
00434
00435
00436 else
00437 {
00438
00439 NIter++;
00440 LastIteration=false;
00441
00442
00443 StoreFilteredData(MaxPlane);
00444 SaveData=true; GoBackwards();
00445 ResetCovarianceMatrix();
00446
00447
00448
00449 ShowerStrips();
00450 if(SwimThroughShower==true) {RemoveTrkHitsInShw();}
00451
00452 for (unsigned int i=0; i<490; ++i) {FilteredData[i].clear();}
00453 StoreFilteredData(MinPlane); GoForwards();
00454
00455 if(SwimThroughShower==true) {ShowerSwim();}
00456
00457 if(detector==Detector::kNear) {SpectrometerSwim(cth);}
00458 ResetCovarianceMatrix();
00459
00460 bool StripsFound = FindTheStrips(cth,false);
00461 EndofRangePlane=MinPlane;
00462
00463 if(StripsFound==true) {
00464 for(int nint=0;nint<2;nint++){
00465 if(nint==1)LastIteration = true;
00466 NIter++;
00467
00468
00469 for (unsigned int i=0; i<490; ++i) {TrkStripData[i].clear();}
00470 GetFitData(MinPlane,MaxPlane);
00471
00472
00473 StoreFilteredData(MaxPlane);
00474 SaveData=true; GoBackwards();
00475 ResetCovarianceMatrix();
00476
00477
00478
00479 StoreFilteredData(EndofRangePlane);
00480 SaveData=true; GoForwards();
00481
00482 ResetCovarianceMatrix();
00483 if(nint==0) {
00484 x_k4_biased= x_k[4];
00485 eqp_biased = pow(VtxCov[4],0.5);
00486 }
00487 }
00488 }
00489 else {PassTrack=false;}
00490
00491 }
00493
00494
00495
00496
00498
00499
00500 if(x_k[4]!=0. && PassTrack==true) {
00501
00502
00503
00504
00505
00506 x_k4_biased *=1.01+(0.1*fabs(x_k[4]));
00507
00508
00509
00510 FillGapsInTrack();
00511 bool FinalStripsFound = FindTheStrips(cth,true);
00512
00513
00514 if(FinalStripsFound==true) {
00515
00516
00517 int NumInUView=0; int NumInVView=0;
00518
00519 TIter FitTrackStripItr = cth.GetDaughterIterator();
00520 while(CandStripHandle* FitTrackStrip = dynamic_cast<CandStripHandle*>(FitTrackStripItr())){
00521 if(FitTrackStrip->GetPlaneView()==2) {NumInUView++;}
00522 else if(FitTrackStrip->GetPlaneView()==3) {NumInVView++;}
00523
00524 if(NumInUView>1 && NumInVView>1) {break;}
00525 }
00526
00527 if(NumInUView>1 && NumInVView>1) {
00528 cth.SetPass(1);
00529 SetTrackProperties(cth);
00530 }
00531 else {
00532 PassTrack=false;
00533 }
00534
00535 }
00536
00537 else {
00538 PassTrack=false;
00539 }
00540 }
00541
00542
00543
00544 if(x_k[4]==0. || PassTrack==false) {
00545
00546
00547 vector<CandStripHandle*> Daughters;
00548
00549 TIter FitTrackStripItr = cth.GetDaughterIterator();
00550 while(CandStripHandle* FitTrackStrip = dynamic_cast<CandStripHandle*>(FitTrackStripItr()))
00551 {Daughters.push_back(FitTrackStrip);}
00552
00553 for(unsigned int i=0; i<Daughters.size(); ++i) {cth.RemoveDaughter(Daughters[i]);}
00554 Daughters.clear();
00555
00556
00557
00558 TIter TrkStripItr = track->GetDaughterIterator();
00559 while(CandStripHandle* TrkStrip = dynamic_cast<CandStripHandle*>(TrkStripItr()))
00560 {cth.AddDaughterLink(*TrkStrip);}
00561
00562
00563 cth.SetPass(0);
00564 cth.SetMomentumCurve(0.); cth.SetEMCharge(0); cth.SetVtxQPError(-999.);
00565 SetPropertiesFromFinderTrack(cth);
00566 }
00568 }
00570
00572 void AlgFitTrackCam::RemoveTrkHitsInShw()
00573 {
00574
00575
00576 MSG("AlgFitTrackCam",Msg::kDebug) << "RemoveTrkHitsInShw, Discard track finding data in shower" << endl;
00577
00578 int NumTrackStripsLeft=0;
00579
00580 if(ZIncreasesWithTime==true) {
00581 for(int i=ShowerEntryPlane; i<=MaxPlane; ++i) {
00582 if(TrkStripData[i].size()>0) {NumTrackStripsLeft++;}
00583 }
00584 }
00585 else if(ZIncreasesWithTime==false) {
00586 for(int i=MinPlane; i<=ShowerEntryPlane; ++i) {
00587 if(TrkStripData[i].size()>0) {NumTrackStripsLeft++;}
00588 }
00589 }
00590
00591
00592 if(NumTrackStripsLeft>5) {
00593 if(ZIncreasesWithTime==true) {
00594 for(int i=MinPlane; i<=ShowerEntryPlane; ++i) {TrkStripData[i].clear();}
00595 }
00596 else if(ZIncreasesWithTime==false) {
00597 for(int i=ShowerEntryPlane; i<=MaxPlane; ++i) {TrkStripData[i].clear(); }
00598 }
00599 }
00600
00601 else {
00602 MSG("AlgFitTrackCam",Msg::kDebug) << "RemoveTrkHitsInShw, not enough hits after removal. Must use all finder data." << endl;
00603 SwimThroughShower=false;
00604 }
00605
00606
00607
00608 MaxPlane=-20; MinPlane=500;
00609 for (int i=0; i<490; ++i) {
00610 if(TrkStripData[i].size()>0) {
00611 if(i>MaxPlane) {MaxPlane=i;}
00612 if(i<MinPlane) {MinPlane=i;}
00613 }
00614 }
00615
00616 }
00618
00619
00621 void AlgFitTrackCam::ShowerSwim()
00622 {
00623
00624
00625
00626
00627 MSG("AlgFitTrackCam",Msg::kDebug) << "ShowerSwim, improved track finding in shower" << endl;
00628
00629
00630 int Plane; int NewPlane;
00631 double StateVector[5]; double NState[5];
00632 bool GoForward; bool SwimBack;
00633 int PlanesSinceLastHit=0;
00634 int PlaneView;
00635 int Increment;
00636
00637 double StripDistance; double MinDistanceToStrip;
00638 double StripWidth=4.108e-2;
00639
00640
00641 if(ZIncreasesWithTime==true) {GoForward=false; Plane=MinPlane; Increment=-1;}
00642 else {GoForward=true; Plane=MaxPlane; Increment=1;}
00643
00644 NewPlane=Plane+Increment;
00645
00646
00647
00648
00649 while(PlanesSinceLastHit<4 && NewPlane>0 && NewPlane<=485) {
00650 if(SlcStripData[NewPlane].size()>0) {
00651
00652 if(SlcStripData[NewPlane][0].csh->GetPlaneView()==2) {PlaneView=0;}
00653 else {PlaneView=1;}
00654
00655 for(int i=0; i<5; ++i) {StateVector[i]=x_k_minus[i];}
00656 SwimBack=Swim(StateVector, NState, Plane, NewPlane, GoForward);
00657 if(!SwimBack){break;}
00658 for(int i=0; i<5; ++i) {x_k[i]=NState[i];}
00659
00660
00661
00662
00663
00664 CandStripHandle* CurrentStrip=0;
00665 MinDistanceToStrip=(1.5*StripWidth)+ fabs(0.0055*x_k[PlaneView+2]);
00666
00667 for(unsigned int j=0; j<SlcStripData[NewPlane].size(); ++j) {
00668 StripDistance=fabs(SlcStripData[NewPlane][j].csh->GetTPos()-x_k[PlaneView]);
00669
00670 if(StripDistance<MinDistanceToStrip) {
00671 MinDistanceToStrip=StripDistance;
00672 CurrentStrip=SlcStripData[NewPlane][j].csh;
00673 }
00674 }
00675
00676
00677
00678 if(CurrentStrip) {
00679 StripStruct temp;
00680 temp.csh = CurrentStrip;
00681 InitTrkStripData[NewPlane].push_back(temp);
00682
00683
00684 GetFitData(NewPlane,NewPlane);
00685
00686
00687 if (PlaneView==1) {H_k[0]=0; H_k[1]=1; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
00688 else {H_k[0]=1; H_k[1]=0; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
00689
00690 bool CombiPropagatorOk=GetCombiPropagator(Plane,NewPlane,GoForward);
00691
00692 if(CombiPropagatorOk ) {
00693 GetNoiseMatrix(Plane,NewPlane);
00694 ExtrapCovMatrix();
00695 CalcKalmanGain(NewPlane);
00696 UpdateStateVector(Plane,NewPlane,GoForward);
00697 UpdateCovMatrix();
00698 MoveArrays();
00699 StoreFilteredData(NewPlane);
00700
00701 if(ZIncreasesWithTime) {MinPlane=NewPlane; Plane=MinPlane;}
00702 else {MaxPlane=NewPlane; Plane=MaxPlane;}
00703 NewPlane=Plane+Increment;
00704
00705 PlanesSinceLastHit=0;
00706 }
00707 }
00708 else {NewPlane+=Increment; PlanesSinceLastHit++;}
00709
00710 }
00711 else {NewPlane+=Increment; PlanesSinceLastHit++;}
00712 }
00713
00714
00715 SwimThroughShower=false;
00716
00717 }
00719
00720
00721
00723 void AlgFitTrackCam::GetFitData(int Plane1, int Plane2)
00724 {
00725
00726
00727
00728
00729 double MisalignmentError=4e-6;
00730 double SumChargeTPos=0; double SumCharge=0; int MaxStrip=-20; int MinStrip=200;
00731 bool NewStripFound=true;
00732
00733 int ThisStrip;
00734
00735
00736 for(int i=Plane1; i<=Plane2; ++i) {
00737 if(InitTrkStripData[i].size()>0) {
00738
00739
00740 for(unsigned int j=0; j<InitTrkStripData[i].size(); ++j) {
00741 if(InitTrkStripData[i][j].csh->GetStrip()<MinStrip) {MinStrip=InitTrkStripData[i][j].csh->GetStrip();}
00742 if(InitTrkStripData[i][j].csh->GetStrip()>MaxStrip) {MaxStrip=InitTrkStripData[i][j].csh->GetStrip();}
00743 }
00744
00745
00746
00748 NewStripFound=true;
00749
00750 while(NewStripFound==true) {
00751
00752 NewStripFound=false;
00753
00754 for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
00755
00756 ThisStrip=SlcStripData[i][j].csh->GetStrip();
00757
00758 if( ThisStrip==(MaxStrip+1) ) {
00759 MaxStrip+=1;
00760 NewStripFound=true;
00761
00762 InitTrkStripData[i].push_back(SlcStripData[i][j]);
00763 }
00764
00765 if( ThisStrip==(MinStrip-1) ) {
00766 MinStrip-=1;
00767 NewStripFound=true;
00768
00769 InitTrkStripData[i].push_back(SlcStripData[i][j]);
00770 }
00771 }
00772 }
00774
00775
00776
00777
00779 for(unsigned int j=0; j<InitTrkStripData[i].size(); ++j) {
00780 SumCharge+=InitTrkStripData[i][j].csh->GetCharge();
00781
00782
00783 PlaneView::PlaneView_t plnvw =InitTrkStripData[i][j].csh->GetPlaneView();
00784 Double_t orthopos = track->GetV(InitTrkStripData[i][j].csh->GetPlane());
00785 if(plnvw == PlaneView::kV){
00786 orthopos = track->GetU(InitTrkStripData[i][j].csh->GetPlane());
00787 }
00788
00789 SumChargeTPos+=InitTrkStripData[i][j].csh->GetCharge()*InitTrkStripData[i][j].csh->GetTPos();
00790 }
00791
00792
00793 if(SumCharge!=0.) {
00794 TrkDataStruct temp;
00795
00796 temp.ZPos=InitTrkStripData[i][0].csh->GetZPos();
00797 temp.PlaneView=InitTrkStripData[i][0].csh->GetPlaneView();
00798
00799 temp.TPos=SumChargeTPos/SumCharge;
00800 temp.TPosError=( (1.406305333e-4 * (1 + MaxStrip-MinStrip) )+ MisalignmentError);
00801
00802 TrkStripData[i].push_back(temp);
00803 }
00805
00806
00807
00808 SumChargeTPos=0; SumCharge=0; MaxStrip=-20; MinStrip=200;
00809 }
00810 }
00811
00812 }
00814
00815
00816
00818 void AlgFitTrackCam::FillGapsInTrack()
00819 {
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829 int CurrentPlane; int ForwardsPlane; int BackwardsPlane;
00830 int Plane; int NewPlane; bool GoForward;
00831 double StateVector[5]; double Prediction[5]; bool GetPrediction;
00832 for(int i=0; i<5; i++) { Prediction[i]=0.; }
00833
00834
00835 for (int i=MinPlane; i<=MaxPlane; ++i) {
00836 if(SlcStripData[i].size()>0) {
00837
00838 if(FilteredData[i].size()==0) {
00839
00840
00841
00843
00844 CurrentPlane=i+1; ForwardsPlane=-99;
00845
00846 while(CurrentPlane<=MaxPlane && CurrentPlane<=(i+2)) {
00847 if(FilteredData[CurrentPlane].size()>0) {ForwardsPlane=CurrentPlane; break;}
00848 else {CurrentPlane++;}
00849 }
00850
00851
00852 CurrentPlane=i-1; BackwardsPlane=-99;
00853
00854 while(CurrentPlane>=MinPlane && CurrentPlane>=(i-2) ) {
00855 if(FilteredData[CurrentPlane].size()>0) {BackwardsPlane=CurrentPlane; break;}
00856 else {CurrentPlane--;}
00857 }
00859
00860
00861
00863 if(ForwardsPlane!=-99 && BackwardsPlane!=-99) {
00864
00865
00866 GetPrediction=false;
00867 NewPlane=i;
00868 if(ZIncreasesWithTime==true) {Plane=ForwardsPlane; GoForward=false;}
00869 else{Plane=BackwardsPlane; GoForward=true;}
00870 if(FilteredData[Plane].size()>0) {
00871 StateVector[0] = FilteredData[Plane][0].x_k0;
00872 StateVector[1] = FilteredData[Plane][0].x_k1;
00873 StateVector[2] = FilteredData[Plane][0].x_k2;
00874 StateVector[3] = FilteredData[Plane][0].x_k3;
00875 StateVector[4] = FilteredData[Plane][0].x_k4;
00876 GetPrediction=Swim(StateVector, Prediction, Plane, NewPlane, GoForward);
00877
00878 if(GetPrediction==true) {
00879
00880 FiltDataStruct temp;
00881 temp.x_k0 = Prediction[0];
00882 temp.x_k1 = Prediction[1];
00883 temp.x_k2 = Prediction[2];
00884 temp.x_k3 = Prediction[3];
00885 temp.x_k4 = Prediction[4];
00886 FilteredData[i].push_back(temp);
00887 }
00888 }
00889
00890 }
00892 }
00893 }
00894 }
00895
00896 }
00898
00899
00900
00902 bool AlgFitTrackCam::FindTheStrips(CandFitTrackCamHandle &cth, bool MakeTheTrack)
00903 {
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00916 for (unsigned int i=0; i<490; ++i) {InitTrkStripData[i].clear();}
00917
00918 double Extrem1=0; double Extrem2=0;
00919 double StripCentre=0;
00920 double StripWidth=4.108e-2;
00921 double HalfStripWidth=0.5*StripWidth;
00922 double TwoStripWidth=2.*StripWidth;
00923 double PEthresh = 3.0;
00924 double MinDistanceToStrip;
00926
00927 int NoOfHitPlanes=0; int Counter=0; int PlanesAdded=0;
00928 Bool_t foundMIP=false;
00929 Bool_t RemovedHit=false;
00930
00931 float minDist;
00932 for (int i=MinPlane; i<=MaxPlane; ++i) {if(FilteredData[i].size()>0) {NoOfHitPlanes++;} }
00933
00934
00936
00937 if(ZIncreasesWithTime==true){
00938 for (int i=MinPlane; i<=MaxPlane; ++i) {
00939 if(FilteredData[i].size()>0) {
00940 Counter++;
00941 int numStrips = 0;
00942 minDist=1e6;
00943
00944
00945 if(SlcStripData[i][0].csh->GetPlaneView()==2) {
00946 Extrem1=FilteredData[i][0].x_k0 + (0.0055*FilteredData[i][0].x_k2);
00947 Extrem2=FilteredData[i][0].x_k0 - (0.0055*FilteredData[i][0].x_k2);
00948 }
00949 else {
00950 Extrem1=FilteredData[i][0].x_k1 + (0.0055*FilteredData[i][0].x_k3);
00951 Extrem2=FilteredData[i][0].x_k1 - (0.0055*FilteredData[i][0].x_k3);
00952 }
00953
00954
00955
00957 bool PlaneAdded=false;
00958 if(fabs(Extrem1-Extrem2)<StripWidth) {
00959 for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
00960 StripCentre=SlcStripData[i][j].csh->GetTPos();
00961 MinDistanceToStrip=HalfStripWidth;
00962 if(fabs(StripCentre-Extrem1)<minDist)minDist =fabs(StripCentre-Extrem1);
00963 if(fabs(StripCentre-Extrem2)<minDist)minDist =fabs(StripCentre-Extrem2);
00964 if(fabs(StripCentre-Extrem1)<HalfStripWidth || fabs(StripCentre-Extrem2)<HalfStripWidth) {
00965 if(Counter>1 || SlcStripData[i][j].csh->GetCharge()>PEthresh || foundMIP==true || SlcStripData[i].size()==1){
00966 foundMIP=true;
00967 if(MakeTheTrack==true) {cth.AddDaughterLink(*SlcStripData[i][j].csh);}
00968 InitTrkStripData[i].push_back(SlcStripData[i][j]);
00969
00970 if(!PlaneAdded)PlanesAdded++;
00971 PlaneAdded=true;
00972 }
00973
00974 numStrips++;
00975 }
00976 }
00977 }
00979
00980
00981
00982
00984 else {
00985 for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
00986 StripCentre=SlcStripData[i][j].csh->GetTPos();
00987 MinDistanceToStrip=HalfStripWidth;
00988 if(fabs(StripCentre-Extrem1)<minDist)minDist =fabs(StripCentre-Extrem1);
00989 if(fabs(StripCentre-Extrem2)<minDist)minDist =fabs(StripCentre-Extrem2);
00990
00991 if( fabs(StripCentre-Extrem1)<HalfStripWidth || fabs(StripCentre-Extrem2)<HalfStripWidth
00992 || (Extrem1>StripCentre && Extrem2<StripCentre)
00993 || (Extrem1<StripCentre && Extrem2>StripCentre) ) {
00994 if(Counter>1 || SlcStripData[i][j].csh->GetCharge()>PEthresh || foundMIP==true){
00995 foundMIP=true;
00996 if(MakeTheTrack==true) {cth.AddDaughterLink(*SlcStripData[i][j].csh);}
00997 InitTrkStripData[i].push_back(SlcStripData[i][j]);
00998 if(!PlaneAdded)PlanesAdded++;
00999 PlaneAdded=true;
01000 }
01001 numStrips++;
01002 }
01003 }
01004 }
01006
01007
01009 if(numStrips==0) {
01010 CandStripHandle* CurrentStrip=0;
01011
01012
01013 if(Counter>2) {
01014 MinDistanceToStrip = TwoStripWidth;
01015 if(MakeTheTrack==true) MinDistanceToStrip = 2*TwoStripWidth;
01016 }
01017 else {MinDistanceToStrip=StripWidth;}
01018 for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
01019 StripCentre=SlcStripData[i][j].csh->GetTPos();
01020
01021
01022 if(fabs(StripCentre-Extrem1)<minDist)minDist =fabs(StripCentre-Extrem1);
01023 if(fabs(StripCentre-Extrem2)<minDist)minDist =fabs(StripCentre-Extrem2);
01024 if(fabs(StripCentre-Extrem1)<MinDistanceToStrip) {
01025 MinDistanceToStrip=StripCentre-Extrem1;
01026 CurrentStrip=SlcStripData[i][j].csh;
01027 }
01028 if(fabs(StripCentre-Extrem2)<MinDistanceToStrip) {
01029 MinDistanceToStrip=StripCentre-Extrem2;
01030 CurrentStrip=SlcStripData[i][j].csh;
01031 }
01032 }
01033
01034
01035 if(CurrentStrip) {
01036 if(Counter>1 || CurrentStrip->GetCharge()>PEthresh || foundMIP==true){
01037 foundMIP=true;
01038 if(MakeTheTrack==true) {cth.AddDaughterLink(*CurrentStrip);}
01039 StripStruct temp;
01040 temp.csh = CurrentStrip;
01041 InitTrkStripData[i].push_back(temp);
01042 PlanesAdded++;
01043 PlaneAdded=true;
01044 }
01045 }
01046 }
01047 }
01048 if(PlanesAdded==3 && !RemovedHit ){
01049 Int_t np = 0;
01050 Int_t planebuf[3];
01051 Int_t pln = MinPlane;
01052 while(np<3 && pln<490){
01053 if(InitTrkStripData[pln].size()>0){
01054 planebuf[np] = InitTrkStripData[pln][0].csh->GetPlane();
01055 np++;
01056 }
01057 pln++;
01058 }
01059 if(np==3 && SlcStripData[planebuf[0]].size()>1){
01060 if(abs(planebuf[1]-planebuf[0])/abs(planebuf[2]-planebuf[1])>1.5){
01061 for(unsigned int j=0; j<InitTrkStripData[planebuf[0]].size(); ++j) {
01062 CandStripHandle* Strip = InitTrkStripData[planebuf[0]][j].csh;
01063 cth.RemoveDaughter(Strip);
01064 RemovedHit=true;
01065 }
01066 InitTrkStripData[planebuf[0]].clear();
01067 }
01068 }
01069 }
01070 }
01071 }
01072 else{
01073 for (int i=MaxPlane; i>=MinPlane; --i) {
01074 if(FilteredData[i].size()>0) {
01075 Counter++;
01076 int numStrips=0;
01077
01078
01079
01080
01081 if(SlcStripData[i][0].csh->GetPlaneView()==2) {
01082 Extrem1=FilteredData[i][0].x_k0 + (0.0055*FilteredData[i][0].x_k2);
01083 Extrem2=FilteredData[i][0].x_k0 - (0.0055*FilteredData[i][0].x_k2);
01084 }
01085 else {
01086 Extrem1=FilteredData[i][0].x_k1 + (0.0055*FilteredData[i][0].x_k3);
01087 Extrem2=FilteredData[i][0].x_k1 - (0.0055*FilteredData[i][0].x_k3);
01088 }
01089
01090
01091
01092
01094 bool PlaneAdded=false;
01095 if(fabs(Extrem1-Extrem2)<StripWidth) {
01096 for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
01097 StripCentre=SlcStripData[i][j].csh->GetTPos();
01098
01099 if(fabs(StripCentre-Extrem1)<HalfStripWidth || fabs(StripCentre-Extrem2)<HalfStripWidth) {
01100 if(Counter>1 || SlcStripData[i][j].csh->GetCharge()>PEthresh || foundMIP|| SlcStripData[i].size()==1){
01101 foundMIP=true;
01102 if(MakeTheTrack==true) {cth.AddDaughterLink(*SlcStripData[i][j].csh);}
01103 InitTrkStripData[i].push_back(SlcStripData[i][j]);
01104 numStrips++;
01105 if(!PlaneAdded)PlanesAdded++;
01106 PlaneAdded=true;
01107 }
01108 }
01109 }
01110 }
01112
01113
01114
01115
01117 else {
01118 bool PlaneAdded=false;
01119 for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
01120 StripCentre=SlcStripData[i][j].csh->GetTPos();
01121
01122 if( fabs(StripCentre-Extrem1)<HalfStripWidth || fabs(StripCentre-Extrem2)<HalfStripWidth
01123 || (Extrem1>StripCentre && Extrem2<StripCentre)
01124 || (Extrem1<StripCentre && Extrem2>StripCentre) ) {
01125 if(Counter>1 || SlcStripData[i][j].csh->GetCharge()>PEthresh || foundMIP){
01126 foundMIP=true;
01127 if(MakeTheTrack==true) {cth.AddDaughterLink(*SlcStripData[i][j].csh);}
01128 InitTrkStripData[i].push_back(SlcStripData[i][j]);
01129 numStrips++;
01130 if(!PlaneAdded)PlanesAdded++;
01131 PlaneAdded=true;
01132 }
01133 }
01134 }
01135 }
01137
01138
01139
01141 if(numStrips==0) {
01142 CandStripHandle* CurrentStrip=0;
01143
01144
01145 if(Counter>2) {
01146 MinDistanceToStrip = TwoStripWidth;
01147 if(MakeTheTrack==true) MinDistanceToStrip = 2*TwoStripWidth;
01148 }
01149 else {MinDistanceToStrip=StripWidth;}
01150
01151 for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
01152 StripCentre=SlcStripData[i][j].csh->GetTPos();
01153
01154
01155 if(fabs(StripCentre-Extrem1)<MinDistanceToStrip) {
01156 MinDistanceToStrip=StripCentre-Extrem1;
01157 CurrentStrip=SlcStripData[i][j].csh;
01158 }
01159 if(fabs(StripCentre-Extrem2)<MinDistanceToStrip) {
01160 MinDistanceToStrip=StripCentre-Extrem2;
01161 CurrentStrip=SlcStripData[i][j].csh;
01162 }
01163 }
01164
01165
01166 if(CurrentStrip) {
01167 if(Counter>1 || CurrentStrip->GetCharge()>PEthresh || foundMIP){
01168 foundMIP=true;
01169 if(MakeTheTrack==true) {cth.AddDaughterLink(*CurrentStrip);}
01170 StripStruct temp;
01171 temp.csh = CurrentStrip;
01172 InitTrkStripData[i].push_back(temp);
01173 PlanesAdded++;
01174 PlaneAdded=true;
01175 }
01176 }
01177 }
01179 }
01180 if(PlanesAdded==3 && !RemovedHit){
01181 Int_t np = 0;
01182 Int_t planebuf[3];
01183 Int_t pln = MaxPlane;
01184 while(np<3 && pln>=0){
01185 if(InitTrkStripData[pln].size()>0){
01186 planebuf[np]= InitTrkStripData[pln][0].csh->GetPlane();
01187 np++;
01188 }
01189 pln--;
01190 }
01191 if(np==3 && SlcStripData[planebuf[0]].size()>1){
01192 if(abs(planebuf[1]-planebuf[0])/abs(planebuf[2]-planebuf[1])>1.5){
01193 for(unsigned int j=0; j<InitTrkStripData[planebuf[0]].size(); ++j) {
01194 CandStripHandle* Strip = InitTrkStripData[planebuf[0]][j].csh;
01195 cth.RemoveDaughter(Strip);
01196 RemovedHit=true;
01197 }
01198 InitTrkStripData[planebuf[0]].clear();
01199 }
01200 }
01201 }
01202 }
01203 }
01205
01206
01207
01208 MaxPlane=-20; MinPlane=500;
01209 for (int i=0; i<490; ++i) {
01210 if(InitTrkStripData[i].size()>0) {
01211 if(i>MaxPlane) {MaxPlane=i;}
01212 if(i<MinPlane) {MinPlane=i;}
01213 }
01214 }
01215
01216 if(MaxPlane==-20 || MinPlane==500) {return false;}
01217 else {return true;}
01218
01219 }
01221
01222
01223
01225 void AlgFitTrackCam::GoForwards()
01226 {
01227
01228 MSG("AlgFitTrackCam",Msg::kSynopsis) << "GoForwards, carry out fit in positive z direction" << endl;
01229 MSG("AlgFitTrackCam",Msg::kSynopsis) << "Fitting from StartPlane=" << MinPlane << " to EndPlane=" << MaxPlane << endl;
01230
01231
01232
01233 Int_t StartPlane = MinPlane; Int_t EndPlane=MaxPlane;
01234 if(!ZIncreasesWithTime){
01235 StartPlane = EndofRangePlane;
01236 }
01237 else EndofRangePlane = MaxPlane;
01238
01239 for (int i=StartPlane; i<=EndPlane; ++i) {
01240 EndofRange = false;
01241 if (TrkStripData[i].size()>0) {
01242 if (PassTrack) {
01243
01244 int NewPlane=-99;
01245 int k=(i+1);
01246 while (k<=MaxPlane) {
01247 if (TrkStripData[k].size()>0) {NewPlane=k; break;}
01248 ++k;
01249 }
01250 if (NewPlane!=-99) {
01251
01252 if (TrkStripData[NewPlane][0].PlaneView==3) {H_k[0]=0; H_k[1]=1; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
01253 else if (TrkStripData[NewPlane][0].PlaneView==2) {H_k[0]=1; H_k[1]=0; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
01254
01255 MSG("AlgFitTrackCam",Msg::kVerbose) << "GoForwards, Plane " << i << " ZPos " << TrkStripData[i][0].ZPos
01256 << " PlaneView " << TrkStripData[i][0].PlaneView << endl;
01257 MSG("AlgFitTrackCam",Msg::kVerbose) << " NewPlane " << NewPlane << " NewZPos " << TrkStripData[NewPlane][0].ZPos
01258 << " NewPlaneView " << TrkStripData[NewPlane][0].PlaneView << endl;
01259
01260 bool CombiPropagatorOk=GetCombiPropagator(i,NewPlane,true);
01261
01262 if(CombiPropagatorOk ) {
01263 GetNoiseMatrix(i,NewPlane);
01264 ExtrapCovMatrix();
01265 CalcKalmanGain(NewPlane);
01266 UpdateStateVector(i,NewPlane,true);
01267 UpdateCovMatrix();
01268 MoveArrays();
01269 if(SaveData) {StoreFilteredData(NewPlane);}
01270 MSG("AlgFitTrackCam",Msg::kVerbose) << "GoForwards, Filtered q/p " << x_k[4] << endl;
01271 }
01272 else
01273 {
01274 PassTrack=false;
01275 }
01276 }
01277
01278 }
01279 else {MSG("AlgFitTrackCam",Msg::kSynopsis) << "GoForwards, Outside of detector - track failed" << endl;}
01280 }
01281
01282 if(EndofRange && LastIteration && ZIncreasesWithTime){
01283 EndofRangePlane=i;
01284 MSG("AlgFitTrackCam",Msg::kSynopsis) << "End of range on plane " << EndofRangePlane << endl;
01285 break;
01286 }
01287 }
01288
01289
01290
01291 if(NIter>1) {
01292 if(ZIncreasesWithTime==true) {
01293 EndCov[0]=C_k[0][0]; EndCov[1]=C_k[1][1];
01294 EndCov[2]=C_k[2][2]; EndCov[3]=C_k[3][3];
01295 EndCov[4]=C_k[4][4];
01296 }
01297 else {
01298 VtxCov[0]=C_k[0][0]; VtxCov[1]=C_k[1][1];
01299 VtxCov[2]=C_k[2][2]; VtxCov[3]=C_k[3][3];
01300 VtxCov[4]=C_k[4][4];
01301 }
01302 }
01303
01304 MSG("AlgFitTrackCam",Msg::kSynopsis) << "GoForwards, Finished" << endl;
01305 }
01307
01308
01309
01311 void AlgFitTrackCam::GoBackwards()
01312 {
01313
01314 MSG("AlgFitTrackCam",Msg::kSynopsis) << "GoBackwards, carry out fit in negative z direction" << endl;
01315 MSG("AlgFitTrackCam",Msg::kSynopsis) << "Fitting from StartPlane=" << MaxPlane << " to EndPlane=" << MinPlane << " end of range plane = " << EndofRangePlane << endl;
01316
01317 Int_t StartPlane = MaxPlane; Int_t EndPlane=MinPlane;
01318 if(ZIncreasesWithTime){
01319 StartPlane = EndofRangePlane;
01320 }
01321 else EndofRangePlane = MinPlane;
01322
01323 for (int i=StartPlane; i>=EndPlane; --i) {
01324 if (TrkStripData[i].size()>0) {
01325 if (PassTrack) {
01326
01327
01328 int NewPlane=-99;
01329 int k=(i-1);
01330 while (k>=MinPlane) {
01331 if (TrkStripData[k].size()>0) {NewPlane=k; break;}
01332 --k;
01333 }
01334
01335
01336 if (NewPlane!=-99) {
01337
01338 if (TrkStripData[NewPlane][0].PlaneView==3) {H_k[0]=0; H_k[1]=1; H_k[2]=0; H_k[3]=0; H_k[4]=0;} else if (TrkStripData[NewPlane][0].PlaneView==2) {H_k[0]=1; H_k[1]=0; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
01339
01340 MSG("AlgFitTrackCam",Msg::kVerbose) << "GoBackwards, Plane " << i << " ZPos " << TrkStripData[i][0].ZPos
01341 << " PlaneView " << TrkStripData[i][0].PlaneView << endl;
01342 MSG("AlgFitTrackCam",Msg::kVerbose) << " NewPlane " << NewPlane << " NewZPos " << TrkStripData[NewPlane][0].ZPos
01343 << " NewPlaneView " << TrkStripData[NewPlane][0].PlaneView << endl;
01344
01345 bool CombiPropagatorOk=GetCombiPropagator(i,NewPlane,false);
01346
01347 if(CombiPropagatorOk ) {
01348 GetNoiseMatrix(i,NewPlane);
01349 ExtrapCovMatrix();
01350 CalcKalmanGain(NewPlane);
01351 UpdateStateVector(i,NewPlane,false);
01352 UpdateCovMatrix();
01353 MoveArrays();
01354 if(SaveData) {StoreFilteredData(NewPlane);}
01355 MSG("AlgFitTrackCam",Msg::kVerbose) << "GoBackwards, Filtered q/p " << x_k[4] << endl;
01356 }
01357 else {
01358 PassTrack=false;
01359 }
01360 }
01361
01362 }
01363 else {MSG("AlgFitTrackCam",Msg::kSynopsis) << "GoBackwards, Outside detector - track failed" << endl;}
01364 }
01365
01366 if(EndofRange && LastIteration && !ZIncreasesWithTime){
01367 EndofRangePlane = i;
01368 break;
01369 }
01370
01371 }
01372
01373
01374
01375 if(NIter>1) {
01376 if(ZIncreasesWithTime==true) {
01377 VtxCov[0]=C_k[0][0]; VtxCov[1]=C_k[1][1];
01378 VtxCov[2]=C_k[2][2]; VtxCov[3]=C_k[3][3];
01379 VtxCov[4]=C_k[4][4];
01380 }
01381 else {
01382 EndCov[0]=C_k[0][0]; EndCov[1]=C_k[1][1];
01383 EndCov[2]=C_k[2][2]; EndCov[3]=C_k[3][3];
01384 EndCov[4]=C_k[4][4];
01385 }
01386 }
01387
01388 MSG("AlgFitTrackCam",Msg::kSynopsis) << "GoBackwards, Finished" << endl;
01389 }
01391
01392
01393
01395 bool AlgFitTrackCam::GetCombiPropagator(const int Plane, const int NewPlane, const bool GoForward)
01396 {
01397
01398
01399
01400
01401 for (int i=0; i<5; ++i) {
01402 for (int j=0; j<5; ++j) {
01403 F_k_minus[i][j]=0;
01404 }
01405 }
01406
01407 F_k_minus[0][0]=1; F_k_minus[1][1]=1;
01408 F_k_minus[2][2]=1; F_k_minus[3][3]=1;
01409
01410 DeltaZ=fabs(TrkStripData[NewPlane][0].ZPos-TrkStripData[Plane][0].ZPos);
01411 DeltaPlane=abs(NewPlane-Plane);
01412
01413
01414 double PState[5]; double NState[5]; double StateVector[5];
01415 double Increment=0.01;
01416 bool SwimInc=false; bool SwimDec=false;
01417 int nswimfail=0;
01418
01419 if(GoForward==true) {F_k_minus[0][2]=DeltaZ; F_k_minus[1][3]=DeltaZ;}
01420 else if(GoForward==false) {F_k_minus[0][2]=-DeltaZ; F_k_minus[1][3]=-DeltaZ;}
01421
01422
01423
01424 while((SwimInc==false || SwimDec==false) && nswimfail<=10) {
01425
01426 Increment=0.05*fabs(x_k_minus[4]);
01427 if(Increment<.01) {Increment=.01;}
01428
01429 for(int j=0; j<5; ++j) {StateVector[j]=x_k_minus[j];}
01430
01431
01432 StateVector[4]+=Increment;
01433 SwimInc=Swim(StateVector, NState, Plane, NewPlane, GoForward);
01434
01435 StateVector[4]=x_k_minus[4];
01436
01437
01438 StateVector[4]-=Increment;
01439 SwimDec=Swim(StateVector, PState, Plane, NewPlane, GoForward);
01440
01441
01442 if(SwimInc==false || SwimDec==false) {
01443 MSG("AlgFitTrackCam",Msg::kVerbose) << "GetCombiPropagator, Swim failed - Double momentum and swim again" << endl;
01444 x_k_minus[4]*=0.5;
01445 nswimfail++; TotalNSwimFail++;
01446 break;
01447 }
01448
01449
01450 else {
01451 if(Increment!=0.) {
01452 for(int j=0; j<5; ++j) {
01453 F_k_minus[j][4] = (NState[j]-PState[j]) / (2*Increment);
01454 }
01455 }
01456 else {F_k_minus[4][4]=1;}
01457 }
01458
01459 }
01460
01461 if(nswimfail>10) {MSG("AlgFitTrackCam",Msg::kDebug) << "GetCombiPropagator, nswimfail>10, fail track" << endl; return false;}
01462
01463
01464
01465 if(debug) {
01466 cout << "Combi F_k_minus" << endl;
01467 for(int i=0; i<5; ++i) {
01468 for(int j=0; j<5; ++j) {
01469 cout << F_k_minus[i][j] << " ";
01470 }
01471 cout << endl;
01472 }
01473 }
01474
01475 return true;
01476 }
01478
01479
01480
01482 bool AlgFitTrackCam::Swim(double* StateVector, double* Output, const int Plane,
01483 const int NewPlane,const bool GoForward, double* dS, double* Range, double* dE)
01484 {
01485
01486
01487
01488
01489 BField * bf = new BField(*vldc,-1,0);
01490 SwimSwimmer* myswimmer = new SwimSwimmer(*vldc,bf);
01491
01492 if(UseGeoSwimmer) GeoSwimmer::Instance()->Initialize(*vldc);
01493
01494 double invSqrt2 = pow(1./2.,0.5);
01495 double charge = 0.;
01496 bool done = false;
01497
01498 if(fabs(StateVector[4])>1.e-10) {
01499 double modp = fabs(1./StateVector[4]);
01500
01501
01502 if(ZIncreasesWithTime==false) {modp=-modp;}
01503
01504 double dsdz = pow((1.+pow(StateVector[2],2)+pow(StateVector[3],2)),0.5);
01505 double dxdz = invSqrt2*(StateVector[2]-StateVector[3]);
01506 double dydz = invSqrt2*(StateVector[2]+StateVector[3]);
01507
01508
01509 if(StateVector[4]>0.) charge = 1.;
01510 else if(StateVector[4]<0.) charge = -1.;
01511
01512 TVector3 position(invSqrt2*(StateVector[0]-StateVector[1]),
01513 invSqrt2*(StateVector[0]+StateVector[1]),
01514 SlcStripData[Plane][0].csh->GetZPos());
01515
01516 TVector3 momentum(modp*(dxdz/dsdz),
01517 modp*(dydz/dsdz),
01518 modp/dsdz);
01519
01520 TVector3 bfield = bf->GetBField(position);
01521 bave += TMath::Sqrt(bfield[0]*bfield[0]+bfield[1]*bfield[1]+bfield[2]*bfield[2]);
01522 nbfield++;
01523
01524 SwimParticle muon(position,momentum);
01525 muon.SetCharge(charge);
01526 SwimZCondition zc(SlcStripData[NewPlane][0].csh->GetZPos());
01527
01528 if( (GoForward==true && ZIncreasesWithTime==true) || (GoForward==false && ZIncreasesWithTime==false) ) {
01529 if(UseGeoSwimmer) {
01530 done = GeoSwimmer::Instance()->SwimForward(muon,SlcStripData[NewPlane][0].csh->GetZPos());
01531 } else {
01532 done = myswimmer->SwimForward(muon,zc);
01533 }
01534 }
01535 else if( (GoForward==true && ZIncreasesWithTime==false) || (GoForward==false && ZIncreasesWithTime==true) ) {
01536 if(UseGeoSwimmer) {
01537 done = GeoSwimmer::Instance()->SwimBackward(muon,SlcStripData[NewPlane][0].csh->GetZPos());
01538 } else {
01539 done = myswimmer->SwimBackward(muon,zc);
01540 }
01541 }
01542 if(done==true) {
01543 if(muon.GetDirection().Z()!=0. && muon.GetMomentumModulus()!=0.) {
01544 Output[0]=invSqrt2*(muon.GetPosition().Y()+muon.GetPosition().X());
01545 Output[1]=invSqrt2*(muon.GetPosition().Y()-muon.GetPosition().X());
01546 Output[2]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())+(muon.GetDirection().X()/muon.GetDirection().Z()));
01547 Output[3]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())-(muon.GetDirection().X()/muon.GetDirection().Z()));
01548 Output[4]=muon.GetCharge()/muon.GetMomentumModulus();
01549
01550 if(dS) {*dS=muon.GetS();} if(Range) {*Range=muon.GetRange();} if(dE){*dE=muon.GetMomentumModulus()-momentum.Mag();}
01551 }
01552 else {done=false;}
01553 }
01554
01555 }
01556
01557 else{
01558
01559 double delz = (SlcStripData[NewPlane][0].csh->GetZPos()-SlcStripData[Plane][0].csh->GetZPos());
01560 Output[0]=StateVector[0] + StateVector[2]*delz;
01561 Output[1]=StateVector[1] + StateVector[3]*delz;
01562 Output[2]=StateVector[2];
01563 Output[3]=StateVector[3];
01564 Output[4]=StateVector[4];
01565
01566 done=true;
01567 }
01568
01569 delete myswimmer;
01570 delete bf;
01571 return done;
01572 }
01574
01575
01576
01578 bool AlgFitTrackCam::Swim(double* StateVector, double* Output, const double z,
01579 const int NewPlane,const bool GoForward, double* dS, double* Range, double* dE)
01580 {
01581
01582
01583
01584
01585 BField * bf = new BField(*vldc,-1,0);
01586 SwimSwimmer* myswimmer = new SwimSwimmer(*vldc,bf);
01587
01588 if(UseGeoSwimmer) GeoSwimmer::Instance()->Initialize(*vldc);
01589
01590 double invSqrt2 = pow(1./2.,0.5);
01591 double charge = 0.;
01592 bool done = false;
01593
01594 if(fabs(StateVector[4])>1.e-10) {
01595 double modp = fabs(1./StateVector[4]);
01596
01597
01598 if(ZIncreasesWithTime==false) {modp=-modp;}
01599
01600 double dsdz = pow((1.+pow(StateVector[2],2)+pow(StateVector[3],2)),0.5);
01601 double dxdz = invSqrt2*(StateVector[2]-StateVector[3]);
01602 double dydz = invSqrt2*(StateVector[2]+StateVector[3]);
01603
01604
01605 if(StateVector[4]>0.) charge = 1.;
01606 else if(StateVector[4]<0.) charge = -1.;
01607
01608 TVector3 position(invSqrt2*(StateVector[0]-StateVector[1]),
01609 invSqrt2*(StateVector[0]+StateVector[1]),
01610 z);
01611
01612 TVector3 momentum(modp*(dxdz/dsdz),
01613 modp*(dydz/dsdz),
01614 modp/dsdz);
01615 SwimParticle muon(position,momentum);
01616 muon.SetCharge(charge);
01617 SwimZCondition zc(SlcStripData[NewPlane][0].csh->GetZPos());
01618
01619
01620
01621 if( (GoForward==true && ZIncreasesWithTime==true) || (GoForward==false && ZIncreasesWithTime==false) ) {
01622 if(UseGeoSwimmer) {
01623 done = GeoSwimmer::Instance()->SwimForward(muon,SlcStripData[NewPlane][0].csh->GetZPos());
01624 } else {
01625 done = myswimmer->SwimForward(muon,zc);
01626 }
01627 }
01628 else if( (GoForward==true && ZIncreasesWithTime==false) || (GoForward==false && ZIncreasesWithTime==true) ) {
01629 if(UseGeoSwimmer) {
01630 done = GeoSwimmer::Instance()->SwimBackward(muon,SlcStripData[NewPlane][0].csh->GetZPos());
01631
01632 } else {
01633 done = myswimmer->SwimBackward(muon,zc);
01634 }
01635 }
01636 if(done==true) {
01637 if(muon.GetDirection().Z()!=0. && muon.GetMomentumModulus()!=0.) {
01638 Output[0]=invSqrt2*(muon.GetPosition().Y()+muon.GetPosition().X());
01639 Output[1]=invSqrt2*(muon.GetPosition().Y()-muon.GetPosition().X());
01640 Output[2]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())+(muon.GetDirection().X()/muon.GetDirection().Z()));
01641 Output[3]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())-(muon.GetDirection().X()/muon.GetDirection().Z()));
01642 Output[4]=muon.GetCharge()/muon.GetMomentumModulus();
01643
01644 if(dS) {*dS=muon.GetS();} if(Range) {*Range=muon.GetRange();} if(dE){*dE=muon.GetMomentumModulus()-momentum.Mag();}
01645 }
01646 else {done=false;}
01647 }
01648
01649 }
01650
01651 else{
01652
01653 double delz = (SlcStripData[NewPlane][0].csh->GetZPos()-z);
01654 Output[0]=StateVector[0] + StateVector[2]*delz;
01655 Output[1]=StateVector[1] + StateVector[3]*delz;
01656 Output[2]=StateVector[2];
01657 Output[3]=StateVector[3];
01658 Output[4]=StateVector[4];
01659
01660 done=true;
01661 }
01662
01663 delete myswimmer;
01664 delete bf;
01665
01666 return done;
01667 }
01669
01670
01671
01673 bool AlgFitTrackCam::Swim(double* StateVector, double* Output, const int Plane,
01674 const double Zend,const bool GoForward, double* dS, double* Range, double* dE)
01675 {
01676
01677
01678
01679
01680
01681 BField * bf = new BField(*vldc,-1,0);
01682 SwimSwimmer* myswimmer = new SwimSwimmer(*vldc,bf);
01683
01684 if(UseGeoSwimmer) GeoSwimmer::Instance()->Initialize(*vldc);
01685
01686 double invSqrt2 = pow(1./2.,0.5);
01687 double charge = 0.;
01688 bool done = false;
01689
01690 if(fabs(StateVector[4])>1.e-10) {
01691 double modp = fabs(1./StateVector[4]);
01692
01693
01694 if(ZIncreasesWithTime==false) {modp=-modp;}
01695
01696 double dsdz = pow((1.+pow(StateVector[2],2)+pow(StateVector[3],2)),0.5);
01697 double dxdz = invSqrt2*(StateVector[2]-StateVector[3]);
01698 double dydz = invSqrt2*(StateVector[2]+StateVector[3]);
01699
01700
01701 if(StateVector[4]>0.) charge = 1.;
01702 else if(StateVector[4]<0.) charge = -1.;
01703
01704 TVector3 position(invSqrt2*(StateVector[0]-StateVector[1]),
01705 invSqrt2*(StateVector[0]+StateVector[1]),
01706 SlcStripData[Plane][0].csh->GetZPos());
01707
01708
01709 TVector3 momentum(modp*(dxdz/dsdz),
01710 modp*(dydz/dsdz),
01711 modp/dsdz);
01712 SwimParticle muon(position,momentum);
01713 muon.SetCharge(charge);
01714 SwimZCondition zc(Zend);
01715
01716
01717 if( (GoForward==true && ZIncreasesWithTime==true) || (GoForward==false && ZIncreasesWithTime==false) ) {
01718 if(UseGeoSwimmer){
01719 done = GeoSwimmer::Instance()->SwimForward(muon,Zend);
01720 } else {
01721 done = myswimmer->SwimForward(muon,zc);
01722 }
01723 }
01724 else if( (GoForward==true && ZIncreasesWithTime==false) || (GoForward==false && ZIncreasesWithTime==true) ) {
01725 if(UseGeoSwimmer){
01726 done = GeoSwimmer::Instance()->SwimBackward(muon,Zend);
01727 } else {
01728 done = myswimmer->SwimBackward(muon,zc);
01729 }
01730 }
01731 if(done==true) {
01732 if(muon.GetDirection().Z()!=0. && muon.GetMomentumModulus()!=0.) {
01733 Output[0]=invSqrt2*(muon.GetPosition().Y()+muon.GetPosition().X());
01734 Output[1]=invSqrt2*(muon.GetPosition().Y()-muon.GetPosition().X());
01735 Output[2]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())+(muon.GetDirection().X()/muon.GetDirection().Z()));
01736 Output[3]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())-(muon.GetDirection().X()/muon.GetDirection().Z()));
01737 Output[4]=muon.GetCharge()/muon.GetMomentumModulus();
01738
01739 if(dS) {*dS=muon.GetS();} if(Range) {*Range=muon.GetRange();} if(dE){*dE=muon.GetMomentumModulus()-momentum.Mag();}
01740 }
01741 else {done=false;}
01742 }
01743
01744 }
01745
01746 else{
01747
01748 double delz = (Zend-SlcStripData[Plane][0].csh->GetZPos());
01749 Output[0]=StateVector[0] + StateVector[2]*delz;
01750 Output[1]=StateVector[1] + StateVector[3]*delz;
01751 Output[2]=StateVector[2];
01752 Output[3]=StateVector[3];
01753 Output[4]=StateVector[4];
01754
01755 done=true;
01756 }
01757
01758 delete myswimmer;
01759 delete bf;
01760 return done;
01761 }
01763
01764
01765
01767 void AlgFitTrackCam::ResetCovarianceMatrix()
01768 {
01769
01770
01771 DeltaPlane=0; DeltaZ=0;
01772 GetInitialCovarianceMatrix(false);
01773 }
01775
01776
01777
01779 void AlgFitTrackCam::GetInitialCovarianceMatrix(const bool FirstIteration)
01780 {
01781
01782
01783 if(FirstIteration==true) {
01784
01785 for(int i=0; i<5; ++i) {
01786 for(int j=0; j<5; ++j) {
01787 C_k_minus[i][j]=0.;
01788 }
01789 }
01790
01791
01792 C_k_minus[0][0]=0.25; C_k_minus[1][1]=0.25;
01793 C_k_minus[2][2]=100.; C_k_minus[3][3]=100.;
01794 C_k_minus[4][4]=1.;
01795
01796
01797 if(ZIncreasesWithTime==true) {
01798 C_k_minus[0][4]=7.5e-5; C_k_minus[1][4]=7.5e-5;
01799 C_k_minus[4][0]=7.5e-5; C_k_minus[4][1]=7.5e-5;
01800 }
01801 else if(ZIncreasesWithTime==false) {
01802 C_k_minus[0][4]=-7.5e-5; C_k_minus[1][4]=-7.5e-5;
01803 C_k_minus[4][0]=-7.5e-5; C_k_minus[4][1]=-7.5e-5;
01804 }
01805
01806
01807 }
01808
01809 else if(FirstIteration==false) {
01810
01811
01812
01813 for(int i=0; i<5; ++i) {C_k_minus[i][i]*=100;}
01814
01815
01816
01817 C_k_minus[0][0]=min(C_k_minus[0][0],0.25); C_k_minus[1][1]=min(C_k_minus[1][1],0.25);
01818 C_k_minus[2][2]=min(C_k_minus[2][2],100.); C_k_minus[3][3]=min(C_k_minus[3][3],100.);
01819 C_k_minus[4][4]=min(C_k_minus[4][4],1.);
01820
01821 double cov_xqp = 7.5e-5;
01822
01823 for(int i=0; i<2; ++i){
01824 if(fabs(C_k_minus[i][4])>cov_xqp) C_k_minus[i][4] = (C_k_minus[i][4] > 0 ? cov_xqp : -cov_xqp);
01825 if(fabs(C_k_minus[4][i])>cov_xqp) C_k_minus[4][i] = (C_k_minus[4][i] > 0 ? cov_xqp : -cov_xqp);
01826 }
01827
01828 cov_xqp /= 0.06;
01829
01830 for(int i=2; i<4; ++i){
01831 if(fabs(C_k_minus[i][4])>cov_xqp) C_k_minus[i][4] = (C_k_minus[i][4] > 0 ? cov_xqp : -cov_xqp);
01832 if(fabs(C_k_minus[4][i])>cov_xqp) C_k_minus[4][i] = (C_k_minus[4][i] > 0 ? cov_xqp : -cov_xqp);
01833 }
01834 }
01835
01836
01837
01838 if(debug) {
01839 cout << "Initial covariance matrix" << endl;
01840 for(int p=0; p<5; ++p){
01841 for(int q=0; q<5; ++q){
01842 cout << C_k_minus[p][q] << " ";
01843 }
01844 cout << endl;
01845 }
01846 }
01847
01848 }
01850
01851
01852
01854 void AlgFitTrackCam::GetNoiseMatrix(const int Plane, const int NewPlane)
01855 {
01856
01857
01858
01859 for (int p=0; p<5; ++p) {
01860 for (int q=0; q<5; ++q) {
01861 Q_k_minus[p][q]=0; }
01862 }
01863
01864
01865 double dsdzSquared = 1.+pow(x_k_minus[2],2)+pow(x_k_minus[3],2);
01866 double dsdz = pow(dsdzSquared,0.5);
01867
01868
01869 if (DeltaPlane!=-99 && DeltaZ!=-99) {
01870 double qp = x_k_minus[4];
01871 if(fabs(qp)<0.01) qp = (qp>0 ? 0.01 : -0.01);
01872 int izdir = ((NewPlane-Plane)>0 ? 0 : 1);
01873
01874 double LocalRadiationLength=(dsdz * double(DeltaPlane) * 1.47);
01875
01876 double SigmaMS=(0.0136 * fabs(qp) * pow(LocalRadiationLength,0.5)
01877 * (1. + (0.038 * log(LocalRadiationLength)) ));
01878 double SigmaMSSquared=pow(SigmaMS,2);
01879
01880 double Sigma33Squared=0.5*SigmaMSSquared*dsdzSquared*(1.+pow(x_k_minus[2],2));
01881
01882 double Sigma34Squared=0.5*SigmaMSSquared*dsdzSquared*(x_k_minus[2]*x_k_minus[3]);
01883
01884 double Sigma44Squared=0.5*SigmaMSSquared*dsdzSquared*(1.+pow(x_k_minus[3],2));;
01885
01886
01887
01888 SwimGeo *spil = SwimGeo::Instance(*(const_cast<VldContext*>(vldc)));
01889 double z1 = spil->GetSteel(TrkStripData[Plane][0].ZPos,izdir)->GetZ();
01890 double z2 = spil->GetSteel(z1,izdir)->GetZ();
01891
01892 double dzscatter = fabs(TrkStripData[NewPlane][0].ZPos-0.5*(z1+z2));
01893 double dzscatter2 = pow(dzscatter,2);
01894
01895 UgliGeomHandle ugh(*vldc);
01896 BField bf(*vldc,-1,0);
01897 TVector3 uvz;
01898
01899 uvz(0) = x_k_minus[0];
01900 uvz(1) = x_k_minus[1];
01901 uvz(2) = ugh.GetNearestSteelPlnHandle(TrkStripData[Plane][0].ZPos).GetZ0();
01902
01903 TVector3 buvz = bf.GetBField(uvz, true);
01904 buvz[0] *= 0.3;
01905 buvz[1] *= 0.3;
01906 buvz[2] *= 0.3;
01907
01908 double beta2inv = 1.0-0.0011*qp*qp;
01909
01910 double eloss = 0.038 * double(DeltaPlane);
01911 double sigmaeloss2 = 0.25*eloss*dsdz*beta2inv*qp*qp;
01912 sigmaeloss2 *= sigmaeloss2;
01913
01914
01915
01916 Q_k_minus[0][0]=dzscatter2*Sigma33Squared;
01917 Q_k_minus[0][1]=dzscatter2*Sigma34Squared;
01918 Q_k_minus[0][2]=dzscatter*Sigma33Squared;
01919 Q_k_minus[0][3]=dzscatter*Sigma34Squared;
01920 Q_k_minus[0][4]=dzscatter*sigmaeloss2*double(DeltaPlane)*buvz(1)*0.0254*dsdz*(1.+pow(x_k_minus[2],2));
01921
01922 Q_k_minus[1][0]=dzscatter2*Sigma34Squared;
01923 Q_k_minus[1][1]=dzscatter2*Sigma44Squared;
01924 Q_k_minus[1][2]=dzscatter*Sigma34Squared;
01925 Q_k_minus[1][3]=dzscatter*Sigma44Squared;
01926 Q_k_minus[1][4]=dzscatter*sigmaeloss2*double(DeltaPlane)*buvz(0)*0.0254*dsdz*(1.+pow(x_k_minus[3],2));
01927
01928 Q_k_minus[2][0]=dzscatter*Sigma33Squared;
01929 Q_k_minus[2][1]=dzscatter*Sigma34Squared;
01930 Q_k_minus[2][2]=Sigma33Squared;
01931 Q_k_minus[2][3]=Sigma34Squared;
01932 Q_k_minus[2][4]=sigmaeloss2*double(DeltaPlane)*buvz(1)*0.0254*dsdz*(1.+pow(x_k_minus[2],2));
01933
01934 Q_k_minus[3][0]=dzscatter*Sigma34Squared;
01935 Q_k_minus[3][1]=dzscatter*Sigma44Squared;
01936 Q_k_minus[3][2]=Sigma34Squared;
01937 Q_k_minus[3][3]=Sigma44Squared;
01938 Q_k_minus[3][4]=sigmaeloss2*double(DeltaPlane)*buvz(0)*0.0254*dsdz*(1.+pow(x_k_minus[3],2));
01939
01940 Q_k_minus[4][0]=dzscatter*sigmaeloss2*double(DeltaPlane)*buvz(1)*0.0254*dsdz*(1.+pow(x_k_minus[2],2));
01941 Q_k_minus[4][1]=dzscatter*sigmaeloss2*double(DeltaPlane)*buvz(0)*0.0254*dsdz*(1.+pow(x_k_minus[3],2));
01942 Q_k_minus[4][2]=sigmaeloss2*double(DeltaPlane)*buvz(1)*0.0254*dsdz*(1.+pow(x_k_minus[2],2));
01943 Q_k_minus[4][3]=sigmaeloss2*double(DeltaPlane)*buvz(0)*0.0254*dsdz*(1.+pow(x_k_minus[3],2));
01944 Q_k_minus[4][4]=sigmaeloss2;
01945 }
01946
01947
01948
01949 if(debug) {
01950 cout << "1e6 * Q_k_minus" << endl;
01951 for(int i=0; i<5; ++i) {
01952 for(int j=0; j<5; ++j) {
01953 cout << 1e6*Q_k_minus[i][j] << " ";
01954 }
01955 cout << endl;
01956 }
01957 }
01958
01959 }
01961
01962
01963
01965 void AlgFitTrackCam::ExtrapCovMatrix()
01966 {
01967
01968
01969
01970 for (int i=0; i<5; ++i) {
01971 for (int j=0; j<5; ++j) {
01972 C_k_intermediate[i][j]=0;
01973
01974 for (int l=0; l<5; ++l) {
01975 for (int m=0; m<5; ++m) {
01976 C_k_intermediate[i][j]+=F_k_minus[i][m]*C_k_minus[m][l]*F_k_minus[j][l];
01977 }
01978 }
01979
01980 C_k_intermediate[i][j]+=Q_k_minus[i][j];
01981 }
01982
01983 }
01984
01985
01986
01987 double covlim = 1.e-8;
01988
01989 for(int i=0; i<5; ++i) {
01990 if(C_k_intermediate[i][i]<covlim) {
01991 MSG("AlgFitTrackCam",Msg::kVerbose) << "Negative diagonal element in C_k_intermediate" << endl;
01992 C_k_intermediate[i][i]=covlim;
01993 }
01994 }
01995
01996
01997
01998 if(debug) {
01999 cout << "C_k_intermediate" << endl;
02000 for(int i=0; i<5; ++i) {
02001 for(int j=0; j<5; ++j) {
02002 cout << C_k_intermediate[i][j] << " ";
02003 }
02004 cout << endl;
02005 }
02006 }
02007
02008 }
02010
02011
02012
02014 void AlgFitTrackCam::CalcKalmanGain(const int NewPlane)
02015 {
02016
02017
02018
02019 double Denominator=0;
02020
02021
02022 if(TrkStripData[NewPlane][0].PlaneView==2) {Denominator=C_k_intermediate[0][0];}
02023 else {Denominator=C_k_intermediate[1][1];}
02024
02025
02026
02027 Denominator+=TrkStripData[NewPlane][0].TPosError;
02028
02029 MSG("AlgFitTrackCam",Msg::kVerbose) << "V_k " << TrkStripData[NewPlane][0].TPosError
02030 << ", Kalman Gain Denominator " << Denominator << endl;
02031
02032 if (Denominator!=0.) {
02033 for (int i=0; i<5; ++i) {
02034 K_k[i]=0;
02035
02036 for (int m=0; m<5; ++m) {K_k[i]+=(C_k_intermediate[i][m])*(H_k[m]);}
02037
02038 K_k[i]=K_k[i]/Denominator;
02039 }
02040
02041 MSG("AlgFitTrackCam",Msg::kVerbose) << "Kalman Gain: "
02042 << K_k[0] << " " << K_k[1] << " " << K_k[2] << " "
02043 << K_k[3] << " " << K_k[4] << endl;
02044 }
02045 else MSG("AlgFitTrackCam",Msg::kDebug) << "V_k + (H_k * C_k_intermediate * H_k_transpose) is zero!" << endl;
02046 }
02048
02049
02050
02052 void AlgFitTrackCam::UpdateStateVector(const int Plane, const int NewPlane, const bool GoForward)
02053 {
02054
02055
02056
02057
02058 double HFx=0;
02059 double m_k=0;
02060 double MeasurementFactor=0;
02061 int nswimfail=0;
02062
02063
02064
02065
02067 double StateVector[5];
02068 double Prediction[5];
02069 bool GetPrediction=false;
02070
02071 for(int i=0; i<5; ++i) {StateVector[i]=x_k_minus[i];}
02072
02073
02074 for(int i=0; i<5; i++) {
02075 double delz = (SlcStripData[NewPlane][0].csh->GetZPos()-SlcStripData[Plane][0].csh->GetZPos());
02076 Prediction[0]=StateVector[0] + StateVector[2]*delz;
02077 Prediction[1]=StateVector[1] + StateVector[3]*delz;
02078 Prediction[2]=StateVector[2];
02079 Prediction[3]=StateVector[3];
02080 Prediction[4]=StateVector[4];
02081 }
02082
02083
02085 while(GetPrediction==false && nswimfail<=10) {
02086 MSG("AlgFitTrackCam",Msg::kVerbose) << " state " << StateVector[0] << " "
02087 << StateVector[1] << " " << StateVector[2] << " "
02088 << StateVector[3] << " " << StateVector[4] << endl;
02089
02090 GetPrediction=Swim(StateVector, Prediction, Plane, NewPlane, GoForward);
02091
02092 MSG("AlgFitTrackCam",Msg::kVerbose) << " predict state " << Prediction[0] << " "
02093 << Prediction[1] << " " << Prediction[2] << " "
02094 << Prediction[3] << " " << Prediction[4] << endl;
02095
02096 if(GetPrediction==false) {
02097 StateVector[4]*=0.5;
02098 nswimfail++; TotalNSwimFail++;
02099 MSG("AlgFitTrackCam",Msg::kVerbose) << "UpdateStateVector, Prediction failed - Double momentum and swim again" << endl;
02100 }
02101 }
02102
02103 if(nswimfail>10) {
02104 MSG("AlgFitTrackCam",Msg::kDebug) << "UpdateStateVector, nswimfail>10, fail track" << endl;
02105 PassTrack=false;
02106 }
02108
02109
02111
02112
02113
02114 CheckValues(Prediction, NewPlane);
02115
02116
02117
02119 if(TrkStripData[NewPlane][0].PlaneView==2) {HFx=Prediction[0];}
02120 if(TrkStripData[NewPlane][0].PlaneView==3) {HFx=Prediction[1];}
02121
02122 MSG("AlgFitTrackCam",Msg::kVerbose) << "HFx " << HFx << endl;
02124
02125
02126
02128 m_k=TrkStripData[NewPlane][0].TPos;
02129 MSG("AlgFitTrackCam",Msg::kVerbose) << "m_k " << TrkStripData[NewPlane][0].TPos << endl;
02130
02131 MeasurementFactor=(m_k-HFx);
02133
02134
02135
02137 for (int i=0; i<5; ++i) {
02138 x_k[i]=0.;
02139 x_k[i]+=Prediction[i]+(K_k[i]*MeasurementFactor);
02140 }
02142
02143
02144
02145 CheckValues(x_k, NewPlane);
02146
02147
02148
02149
02150
02151 double Maxqp = 4.;
02152 if(fabs(x_k_minus[4])==Maxqp &&
02153 ( (GoForward==true && ZIncreasesWithTime==true)
02154 || (GoForward==false && ZIncreasesWithTime==false) ) )
02155 {
02156 if(!LastIteration) x_k[4] = (x_k_minus[4]>0 ? Maxqp : -Maxqp);
02157 }
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171 if( (GoForward==true && ZIncreasesWithTime==true && NewPlane >= EndofRangePlane )
02172 || (GoForward==false && ZIncreasesWithTime==false && NewPlane <= EndofRangePlane ) )
02173 {
02174 double majority_curvature = this->MajorityCurvature();
02175 MSG("AlgFitTrackCam",Msg::kDebug) << " Checking Last Plane: Q/P=" << x_k[4] << " MajorityCurvature = " << majority_curvature << endl;
02176
02177 if( ( majority_curvature<-0.33 && x_k[4]>0.0 )
02178 || ( majority_curvature>+0.33 && x_k[4]<0.0 ) ){
02179 MSG("AlgFitTrackCam",Msg::kDebug) << " Disregard charge sign in last plane: NewPlane=" << NewPlane << " " << x_k[4] << "-> " << -x_k[4] << endl;
02180 x_k[4] = -x_k[4];
02181 }
02182 }
02183
02184
02185 MSG("AlgFitTrackCam",Msg::kVerbose) << "Filtered State vector: "
02186 << x_k[0] << " " << x_k[1] << " " << x_k[2] << " "
02187 << x_k[3] << " " << x_k[4] << endl;
02188 }
02190
02192 double AlgFitTrackCam::MajorityCurvature()
02193 {
02194
02195
02196 Double_t majority_curvature = 0.0;
02197 Double_t majority_counter = 0.0;
02198 Double_t total_counter = 0.0;
02199
02200 for(int i=MinPlane; i<=MaxPlane; ++i) {
02201 if( FilteredData[i].size()>0 ) {
02202 if( FilteredData[i][0].x_k4>0.0 ) majority_counter += 1.0;
02203 if( FilteredData[i][0].x_k4<0.0 ) majority_counter -= 1.0;
02204 total_counter += 1.0;
02205 }
02206 }
02207
02208 if( total_counter>0.0 ){
02209 majority_curvature = majority_counter/total_counter;
02210 }
02211
02212 return majority_curvature;
02213 }
02215
02216
02218 void AlgFitTrackCam::UpdateCovMatrix()
02219 {
02220
02221
02222
02223 for (int i=0; i<5; ++i) {
02224 for (int j=0; j<5; ++j) {
02225 C_k[i][j]=0;
02226 for (int m=0; m<5; ++m) {
02227 C_k[i][j]+=(Identity[i][m] - K_k[i]*H_k[m]) * C_k_intermediate[m][j];
02228 }
02229 }
02230 }
02231
02232
02233
02234 double covlim = 1.e-8;
02235
02236 for(int i=0; i<5; ++i) {
02237 if(C_k[i][i]<covlim) {
02238 MSG("AlgFitTrackCam",Msg::kVerbose) << "Negative diagonal element in C_k" << endl;
02239 C_k[i][i]=covlim;
02240 }
02241 }
02242
02243
02244
02245 if(debug) {
02246 cout << "Filtered Covariance matrix" << endl;
02247 for(int i=0; i<5; ++i) {
02248 for(int j=0; j<5; ++j) {
02249 cout << C_k[i][j] << " ";
02250 }
02251 cout << endl;
02252 }
02253 }
02254
02255 }
02257
02258
02259
02261 void AlgFitTrackCam::MoveArrays()
02262 {
02263
02264
02265
02266 for (int i=0; i<5; ++i) {
02267 for (int j=0; j<5; ++j) {
02268 C_k_minus[i][j]=C_k[i][j];
02269 }
02270 }
02271
02272 for (int l=0; l<5; ++l) {
02273 x_k_minus[l]=x_k[l];
02274 }
02275 }
02277
02278
02279
02281 void AlgFitTrackCam::CheckValues(double* Input, const int NewPlane)
02282 {
02283
02284
02285
02286
02287
02288 double Maxqp=4.; double Maxqpfrac=1.2;
02289 double Range=track->GetRange(NewPlane);
02290
02291
02292
02293
02294
02295 if(fabs(Input[4])>4.0) EndofRange=true;
02296
02297 if(Range>0. && (Maxqpfrac*500/Range)<Maxqp) {Maxqp=(Maxqpfrac*500/Range);}
02298 MSG("AlgFitTrackCam",Msg::kVerbose) << " Range " << Range << " Maxqp " << Maxqp << endl;
02299
02300
02301
02302
02303
02304 if(fabs(Input[4])>Maxqp){
02305 MSG("AlgFitTrackCam",Msg::kVerbose) << "CheckValues, Range check correction" << endl;
02306 Input[4]=(Input[4]>0 ? Maxqp : -Maxqp);
02307 }
02308
02309
02310
02311 double Maxgradient=25.;
02312
02313 if(fabs(Input[2])>Maxgradient) {
02314 MSG("AlgFitTrackCam",Msg::kVerbose) << "CheckValues, Gradient correction, U" << endl;
02315 Input[2]=(Input[2]>0 ? Maxgradient : -Maxgradient);
02316 }
02317
02318 if(fabs(Input[3])>Maxgradient) {
02319 MSG("AlgFitTrackCam",Msg::kVerbose) << "CheckValues, Gradient correction, V" << endl;
02320 Input[3]=(Input[3]>0 ? Maxgradient : -Maxgradient);
02321 }
02322
02323
02324
02325 if(fabs(Input[0])<5000. && fabs(Input[1])<5000.) {PassTrack=true;}
02326 else {
02327 PassTrack=false;
02328 }
02329 }
02331
02332
02333
02335 void AlgFitTrackCam::StoreFilteredData(const int NewPlane)
02336 {
02337
02338 MSG("AlgFitTrackCam",Msg::kVerbose) << "StoreFilteredData" << endl;
02339
02340 FiltDataStruct temp;
02341
02342 temp.x_k0=x_k[0]; temp.x_k1=x_k[1];
02343 temp.x_k2=x_k[2]; temp.x_k3=x_k[3];
02344 temp.x_k4=x_k[4];
02345
02346
02347 FilteredData[NewPlane].insert(FilteredData[NewPlane].begin(),temp);
02348
02349 MSG("AlgFitTrackCam",Msg::kSynopsis) << " StoreData [" << NewPlane << "] x_k[4] = " << x_k[4] << " Entry=" << FilteredData[NewPlane].size() << endl;
02350 }
02352
02353
02354
02356 void AlgFitTrackCam::SetTrackProperties(CandFitTrackCamHandle &cth)
02357 {
02358 int VtxPlane;
02359 int EndPlane;
02360 double dsdz;
02361 double VtxQP;
02362
02363 if(nbfield>0) bave /=nbfield;
02364
02365
02366 MSG("AlgFitTrackCam",Msg::kSynopsis) << "Set Track Properties:" << endl;
02367
02368
02370
02371 if(ZIncreasesWithTime==true) {VtxPlane=MinPlane; EndPlane=MaxPlane;}
02372 else {VtxPlane=MaxPlane; EndPlane=MinPlane;}
02373
02374
02376
02377
02378 VtxQP = FilteredData[VtxPlane][0].x_k4;
02379
02380
02381 VtxQP *= 1.013;
02382
02383
02384
02385
02386
02387
02388
02389
02390 Double_t pcabsinvtemp = TMath::Max(TMath::Abs(VtxQP), (Double_t) FLT_MIN);
02391 cth.SetMomentumCurve(1./pcabsinvtemp);
02392
02393 cth.SetRangeBiasedQP(x_k4_biased);
02394 cth.SetRangeBiasedEQP(eqp_biased);
02395
02396 if( VtxQP>0.0 ) {cth.SetEMCharge(1.);}
02397 else if( VtxQP<0.0 ) {cth.SetEMCharge(-1.);}
02398 cth.SetVtxQPError(pow(VtxCov[4],0.5));
02399
02400 MSG("AlgFitTrackCam",Msg::kSynopsis) << " Q/P = " << VtxQP << ", Q/P(biased) = " << x_k4_biased << ", sigma(Q/P) = " << pow(VtxCov[4],0.5) << " Sigma Q/P _biased "<< eqp_biased << endl;
02401
02402
02404
02405
02406 cth.SetVtxU(FilteredData[VtxPlane][0].x_k0);
02407 cth.SetVtxV(FilteredData[VtxPlane][0].x_k1);
02408 cth.SetVtxZ(SlcStripData[VtxPlane][0].csh->GetZPos());
02409 cth.SetVtxPlane(VtxPlane);
02410
02411 cth.SetEndU(FilteredData[EndPlane][0].x_k0);
02412 cth.SetEndV(FilteredData[EndPlane][0].x_k1);
02413
02414 cth.SetEndZ(SlcStripData[EndPlane][0].csh->GetZPos());
02415 cth.SetEndPlane(EndPlane);
02416
02417
02418
02419 dsdz=pow(1.+pow(FilteredData[VtxPlane][0].x_k2,2)+pow(FilteredData[VtxPlane][0].x_k3,2),0.5);
02420 if(ZIncreasesWithTime==false) {dsdz=-dsdz;}
02421
02422 cth.SetVtxDirCosU(FilteredData[VtxPlane][0].x_k2/dsdz);
02423 cth.SetVtxDirCosV(FilteredData[VtxPlane][0].x_k3/dsdz);
02424 cth.SetVtxDirCosZ(1./dsdz);
02425
02426 cth.SetDirCosU(FilteredData[VtxPlane][0].x_k2/dsdz);
02427 cth.SetDirCosV(FilteredData[VtxPlane][0].x_k3/dsdz);
02428 cth.SetDirCosZ(1./dsdz);
02429
02430 dsdz=pow(1.+pow(FilteredData[EndPlane][0].x_k2,2)+pow(FilteredData[EndPlane][0].x_k3,2),0.5);
02431 if(ZIncreasesWithTime==false) {dsdz=-dsdz;}
02432
02433 cth.SetEndDirCosU(FilteredData[EndPlane][0].x_k2/dsdz);
02434 cth.SetEndDirCosV(FilteredData[EndPlane][0].x_k3/dsdz);
02435 cth.SetEndDirCosZ(1./dsdz);
02436
02437
02438 cth.SetEndQP(FilteredData[EndPlane][0].x_k4);
02439
02440
02441 cth.SetVtxUError(pow(VtxCov[0],0.5));
02442 cth.SetVtxVError(pow(VtxCov[1],0.5));
02443 cth.SetVtxdUError(pow(VtxCov[2],0.5));
02444 cth.SetVtxdVError(pow(VtxCov[3],0.5));
02445
02446
02447 cth.SetEndUError(pow(EndCov[0],0.5));
02448 cth.SetEndVError(pow(EndCov[1],0.5));
02449 cth.SetEnddUError(pow(EndCov[2],0.5));
02450 cth.SetEnddVError(pow(EndCov[3],0.5));
02451 cth.SetEndQPError(pow(EndCov[4],0.5));
02452
02454
02455 cth.SetBave(bave);
02456
02457
02459 cth.SetNTrackStrip(cth.GetNDaughters());
02460 cth.SetNTrackDigit(cth.GetNDigit());
02461
02462 cth.SetNIterate(NIter);
02463 cth.SetNSwimFail(TotalNSwimFail);
02464
02465
02466
02467 for (int i=0; i<490; ++i) {TrkStripData[i].clear();}
02468 GetFitData(MinPlane,MaxPlane);
02469
02470
02471
02472 double Chi2=0; double Chi2Contrib=0; int NDOF=0; double FilteredTPos=0;
02473
02474 for(int i=MinPlane; i<=MaxPlane; ++i) {
02475 if(TrkStripData[i].size()>0) {
02476
02477 if(TrkStripData[i][0].TPosError>0.) {
02478 cth.SetTrackPointError(i,pow(TrkStripData[i][0].TPosError,0.5));
02479
02480 if(TrkStripData[i][0].PlaneView==2) {FilteredTPos=FilteredData[i][0].x_k0;}
02481 else {FilteredTPos=FilteredData[i][0].x_k1;}
02482
02483 Chi2Contrib = pow((TrkStripData[i][0].TPos-FilteredTPos),2) / TrkStripData[i][0].TPosError;
02484 cth.SetPlaneChi2(i,Chi2Contrib);
02485
02486 Chi2+=Chi2Contrib;
02487
02488 NDOF++;
02489 }
02490 }
02491 }
02492 cth.SetChi2(Chi2);
02493 cth.SetNDOF(NDOF-5);
02494
02495
02496
02497 for(int i=MinPlane; i<=MaxPlane; ++i) {
02498 if(FilteredData[i].size()>0) {
02499 cth.SetU(i,FilteredData[i][0].x_k0);
02500 cth.SetV(i,FilteredData[i][0].x_k1);
02501 cth.SetPlaneQP(i,FilteredData[i][0].x_k4);
02502 }
02503 }
02504
02505
02506
02507 CalculateTrace(cth);
02508
02509
02510
02511 SetT(&cth);
02512 SetRangeAnddS(cth);
02513
02514
02515
02516 cth.SetMomentum(cth.GetMomentumCurve());
02517 if(cth.IsContained()){
02518 cth.SetMomentum(cth.GetMomentumRange());
02519 }
02520
02521
02522
02523
02524 TIter FitTrackStripItr = cth.GetDaughterIterator();
02525 while(CandStripHandle* FitTrackStrip = dynamic_cast<CandStripHandle*>(FitTrackStripItr()))
02526 {
02527 if(ShowerEntryPlane!=-99) {
02528 if( (ZIncreasesWithTime==true && FitTrackStrip->GetPlane()<=ShowerEntryPlane)
02529 || (ZIncreasesWithTime==false && FitTrackStrip->GetPlane()>=ShowerEntryPlane) ) {
02530 cth.SetInShower(FitTrackStrip,2);
02531 }
02532 else {cth.SetInShower(FitTrackStrip,0);}
02533 }
02534 else {cth.SetInShower(FitTrackStrip,0);}
02535 }
02536
02537
02538
02539 TimingFit(cth);
02540
02541
02542
02543 Calibrator& cal = Calibrator::Instance();
02544 cal.ReInitialise(*vldc);
02545 Calibrate(&cth);
02546
02547
02548 }
02550
02551
02552
02554 void AlgFitTrackCam::TimingFit(CandFitTrackCamHandle &cth)
02555 {
02556
02557
02558
02560 double s; double t; double q; double w; int n=0;
02561 double Uncertainty=1.0; double MinUncertainty=1.0;
02562 double MinCT=-3000.;
02563
02564
02565 StripListTime=9.e30;
02566
02567
02568 double dSOffset=0.; double Sign=-1.; double dS[490];
02569 if(ZIncreasesWithTime==true) {dSOffset=cth.GetdS(MinPlane); Sign=1.;}
02570
02571
02572 double Qp[490]; double Qm[490];
02573 double CTp[490]; double CTm[490];
02574 int Skipp[490]; int Skipm[490];
02575 double C=3.e8;
02576
02577 double ErrorParam[3];
02578 ErrorParam[0]=1.; ErrorParam[1]=0.; ErrorParam[2]=0.;
02579
02580
02581 for(int i=0; i<490; ++i) {
02582 dS[i]=0.; CTm[i]=0.; CTp[i]=0.;
02583 Qp[i]=0.; Qm[i]=0.;
02584 Skipp[i]=0; Skipm[i]=0;
02585 }
02586
02588
02589
02590
02592 vector<StripStruct> TimeFitStripData[490];
02593
02594 TIter MyStripItr = cth.GetDaughterIterator();
02595
02596 while(CandStripHandle* MyStrip = dynamic_cast<CandStripHandle*>(MyStripItr()))
02597 {
02598 int MyPlane = MyStrip->GetPlane();
02599
02600 StripStruct temp;
02601 temp.csh = MyStrip;
02602
02603 if( cth.GetdS(MyPlane)>-0.99 ){
02604 TimeFitStripData[MyPlane].push_back(temp);
02605 }
02606
02607 }
02609
02610
02611
02613 if(vldc->GetDetector()==Detector::kFar) {
02614
02615
02616
02617
02618 ErrorParam[0]=0.58; ErrorParam[1]=0.69; ErrorParam[2]=-0.33;
02619 MinUncertainty=ErrorParam[0];
02620
02621
02622 for(int i=MinPlane; i<=MaxPlane; ++i) {
02623
02624 if(TimeFitStripData[i].size()>0) {
02625 dS[i]=Sign*(dSOffset-cth.GetdS(i));
02626
02627 CTp[i]=C*cth.GetT(i,StripEnd::kPositive);
02628 CTm[i]=C*cth.GetT(i,StripEnd::kNegative);
02629
02630 if(CTp[i]>MinCT && CTp[i]<StripListTime) {StripListTime=CTp[i];}
02631 if(CTm[i]>MinCT && CTm[i]<StripListTime) {StripListTime=CTm[i];}
02632
02633 for(unsigned int j=0; j<TimeFitStripData[i].size(); ++j) {
02634 Qp[i]+=TimeFitStripData[i][j].csh->GetCharge(StripEnd::kPositive);
02635 Qm[i]+=TimeFitStripData[i][j].csh->GetCharge(StripEnd::kNegative);
02636 }
02637 }
02638 }
02639
02640
02641 if(StripListTime<8.e30) {
02642 for(int i=MinPlane; i<=MaxPlane; ++i) {
02643 if(TimeFitStripData[i].size()>0) {
02644 CTp[i]-=StripListTime;
02645 CTm[i]-=StripListTime;
02646 }
02647 }
02648 }
02649 else {StripListTime=0.;}
02650
02651 }
02653
02654
02655
02656
02658 if(vldc->GetDetector()==Detector::kNear) {
02659
02660 MinUncertainty=1.19;
02661 ErrorParam[0]=1.13; ErrorParam[1]=0.63; ErrorParam[2]=-0.21;
02662
02663 double Index=1.77; double DistFromCentre=0.; double CTime=0.; double FibreDist=0.;
02664 double halfLength=0.; double DigChg=0.; double PlaneDigChg;
02665
02666 StripEnd::StripEnd_t StpEnd = StripEnd::kUnknown;
02667 CandStripHandle* strip; CandDigitHandle* digit;
02668
02669 UgliGeomHandle ugh = UgliGeomHandle(*vldc);
02670 UgliStripHandle striphandle;
02671
02672
02673
02674 for(int i=MinPlane; i<=MaxPlane; ++i)
02675 {
02676 if(TimeFitStripData[i].size()>0) {dS[i]=Sign*(dSOffset-cth.GetdS(i));}
02677 PlaneDigChg=0.;
02678
02679
02680 for(unsigned int j=0; j<TimeFitStripData[i].size(); ++j) {
02681 strip = TimeFitStripData[i][j].csh;
02682 CandDigitHandleItr digitItr(strip->GetDaughterIterator());
02683
02684 Qp[i]+=strip->GetCharge(StripEnd::kPositive);
02685
02686
02687
02689 while( (digit = digitItr()) ) {
02690 StpEnd=digit->GetPlexSEIdAltL().GetEnd();
02691
02692 if(StpEnd==StripEnd::kPositive) {
02693 FibreDist = 0.; DistFromCentre = 0.; CTime=0.; DigChg=0.;
02694 UgliStripHandle stripHandle = ugh.GetStripHandle(strip->GetStripEndId());
02695 halfLength = stripHandle.GetHalfLength();
02696
02697 if(strip->GetPlaneView()==2) {DistFromCentre = cth.GetV(i);}
02698 if(strip->GetPlaneView()==3) {DistFromCentre = -cth.GetU(i);}
02699
02700 FibreDist = (halfLength + DistFromCentre + stripHandle.ClearFiber(StpEnd)
02701 + stripHandle.WlsPigtail(StpEnd));
02702
02703 CTime = C*(strip->GetTime(StpEnd)) - Index*FibreDist;
02704 DigChg=digit->GetCharge();
02705
02706 PlaneDigChg+=DigChg; CTp[i]+=DigChg*CTime;
02707
02708 if(CTime>MinCT && CTime<StripListTime) {StripListTime=CTime;}
02709 }
02710 }
02712 }
02713 if(PlaneDigChg>0.) CTp[i]/=PlaneDigChg;
02714 }
02715
02716
02717
02718 if(StripListTime<8.e30) {
02719 for(int i=MinPlane; i<=MaxPlane; ++i) {
02720 if(TimeFitStripData[i].size()>0) {
02721 CTp[i]-=StripListTime;
02722 }
02723 }
02724 }
02725 else {StripListTime=0.;}
02726
02727 }
02729
02730
02731
02732
02734
02735 double Sqs=0; double Sqt=0; double Sqss=0; double Sqst=0; double Sqtt=0; double Sq=0;
02736 double TimeSlope=-999; double TimeOffset=-999; double RMS=-999;
02737 double CTCut = 0.; bool CalculateChi2=true;
02738
02739
02740
02741 for(int itr=0; itr<3; ++itr) {
02742
02743 for(int i=MinPlane; i<=MaxPlane; ++i) {
02744
02745
02746 if(TimeFitStripData[i].size()>0) {
02747
02748
02749 s=dS[i]; q=Qp[i]; t=CTp[i];
02750
02751 if (q<25) {Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*q);}
02752 else {Uncertainty=MinUncertainty;}
02753 w = 1.0/pow(Uncertainty,2.0);
02754
02755 if(q>0. && t>MinCT && Skipp[i]==0) {
02756 if(itr==0) {Sq+=w; Sqs+=w*s; Sqt+=w*t; Sqss+=w*s*s; Sqst+=w*s*t; Sqtt+=w*t*t; n++;}
02757
02758 else if(fabs(t-TimeOffset-(s*TimeSlope)) > CTCut) {
02759 Sqs-=w*s; Sqt-=w*t; Sqss-=w*s*s; Sqst-=w*s*t; Sqtt-=w*t*t; Sq-=w; n--; Skipp[i]=1;
02760 }
02761 }
02762
02763
02764
02765 s=dS[i]; q=Qm[i]; t=CTm[i];
02766
02767 if (q<25) {Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*q);}
02768 else {Uncertainty=MinUncertainty;}
02769 w = 1.0/pow(Uncertainty,2.0);
02770
02771 if(q>0. && t>MinCT && Skipm[i]==0) {
02772 if(itr==0) {Sq+=w; Sqs+=w*s; Sqt+=w*t; Sqss+=w*s*s; Sqst+=w*s*t; Sqtt+=w*t*t; n++;}
02773
02774 else if(fabs(t-TimeOffset-(s*TimeSlope)) > CTCut) {
02775 Sqs-=w*s; Sqt-=w*t; Sqss-=w*s*s; Sqst-=w*s*t; Sqtt-=w*t*t; Sq-=w; n--; Skipm[i]=1;
02776 }
02777 }
02778
02779 }
02780 }
02781
02782
02783 if( (Sq*Sqss-Sqs*Sqs)!=0. && Sq!=0. ) {
02784 TimeSlope = (Sq*Sqst-Sqs*Sqt)/(Sq*Sqss-Sqs*Sqs);
02785 TimeOffset = (Sqt*Sqss-Sqs*Sqst)/(Sq*Sqss-Sqs*Sqs);
02786 if( ((Sqtt/Sq)-((Sqt/Sq)*(Sqt/Sq)))>0. ) {
02787 RMS = pow((Sqtt/Sq)-((Sqt/Sq)*(Sqt/Sq)),0.5);
02788 CTCut = 3.+RMS;
02789 }
02790 else {CTCut = 3.5;}
02791 }
02792 else {CalculateChi2=false; break;}
02793 }
02795
02796
02797
02798
02800 if(n!=0 && CalculateChi2==true) {
02801
02802
02804 cth.SetTimeOffset((TimeOffset+StripListTime)/C);
02805 cth.SetTimeSlope(TimeSlope/C);
02806
02807 if(ZIncreasesWithTime==true) {
02808 cth.SetVtxT((TimeOffset+StripListTime)/C);
02809 cth.SetEndT((TimeOffset+StripListTime)/C+(dS[MaxPlane]*TimeSlope/C));
02810 }
02811 else {
02812 cth.SetEndT((TimeOffset+StripListTime)/C);
02813 cth.SetVtxT((TimeOffset+StripListTime)/C+(dS[MaxPlane]*TimeSlope/C));
02814 }
02816
02817
02818
02820 double Residual2; double Chi2=0;
02821
02822 for(int i=MinPlane; i<=MaxPlane; ++i) {
02823
02824 if(TimeFitStripData[i].size()>0) {
02825
02826 s=dS[i]; q=Qp[i]; t=CTp[i];
02827 if(q>0. && t>MinCT && Skipp[i]==0) {
02828 Residual2=pow(t-TimeOffset-(s*TimeSlope),2);
02829
02830
02831 if (q<25) {Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*q);}
02832 else {Uncertainty=MinUncertainty;}
02833
02834 if(Uncertainty!=0.) {Chi2+=Residual2/pow(Uncertainty,2);}
02835 }
02836
02837
02838
02839 q=Qm[i]; t=CTm[i];
02840 if(q>0. && t>MinCT && Skipm[i]==0) {
02841 Residual2=pow(t-TimeOffset-(s*TimeSlope),2);
02842
02843
02844 if (q<25) {Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*q);}
02845 else {Uncertainty=MinUncertainty;}
02846
02847 if(Uncertainty!=0.) {Chi2+=Residual2/pow(Uncertainty,2);}
02848 }
02849 }
02850
02851 }
02852
02853 cth.SetTimeFitChi2(Chi2);
02854 cth.SetNTimeFitDigit(n);
02855 }
02857
02858
02859
02860
02862 double CTIntercept[2]; double Csigma[2]; double Ctrunc[2];
02863 double ChiSqPositive=-999; double ChiSqNegative=-999;
02864 int ChiSqNdfPos=-999; int ChiSqNdfNeg=-999;
02865 double Swtt[2]; double Swt[2]; double Sw[2]; int npts[2]={0,0};
02866
02867 if(Sq!=0.) {
02868 CTIntercept[0]=Sqt/Sq; Csigma[0]=-99999.9; Ctrunc[0]=-99999.9;
02869 CTIntercept[1]=Sqt/Sq; Csigma[1]=-99999.9; Ctrunc[1]=-99999.9;
02870
02871 for(int itr=0; itr<2; ++itr)
02872 {
02873 Swtt[0]=0.; Swt[0]=0.; Sw[0]=0.; npts[0]=0;
02874 Swtt[1]=0.; Swt[1]=0.; Sw[1]=0.; npts[1]=0;
02875
02876 for(int i=0; i<490; ++i)
02877 {
02878
02879 if(Qp[i]>0. && CTp[i]>MinCT) {
02880 q=Qp[i];
02881
02882 if (q<25) {Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*q);}
02883 else {Uncertainty=MinUncertainty;}
02884 w = 1.0/pow(Uncertainty,2.0);
02885
02886 t=CTp[i]-dS[i]+CTIntercept[0];
02887 if(Ctrunc[0]<0. || fabs(t)<Ctrunc[0]) {Swtt[0]+=w*t*t; Swt[0]+=w*t; Sw[0]+=w; ++npts[0];}
02888
02889 t=CTp[i]+dS[i]+CTIntercept[1];
02890 if(Ctrunc[1]<0. || fabs(t)<Ctrunc[1]) {Swtt[1]+=w*t*t; Swt[1]+=w*t; Sw[1]+=w; ++npts[1];}
02891 }
02892
02893
02894 if(Qm[i]>0. && CTm[i]>MinCT) {
02895 q=Qm[i];
02896
02897 if (q<25) {Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*q);}
02898 else {Uncertainty=MinUncertainty;}
02899 w = 1.0/pow(Uncertainty,2.0);
02900
02901 t=CTm[i]-dS[i]+CTIntercept[0];
02902 if(Ctrunc[0]<0. || fabs(t)<Ctrunc[0]) {Swtt[0]+=w*t*t; Swt[0]+=w*t; Sw[0]+=w; ++npts[0];}
02903
02904 t=CTm[i]+dS[i]+CTIntercept[1];
02905 if(Ctrunc[1]<0. || fabs(t)<Ctrunc[1]) {Swtt[1]+=w*t*t; Swt[1]+=w*t; Sw[1]+=w; ++npts[1];}
02906 }
02907 }
02908
02909
02910 if(npts[0]>1 && Sw[0]!=0.) {
02911 CTIntercept[0]=CTIntercept[0]-Swt[0]/Sw[0]; Csigma[0]=0.;
02912 if((Swtt[0]/Sw[0])-(Swt[0]/Sw[0])*(Swt[0]/Sw[0])>0.) {Csigma[0]=pow((Swtt[0]/Sw[0])-(Swt[0]/Sw[0])*(Swt[0]/Sw[0]),0.5);}
02913 ChiSqPositive=Csigma[0]; ChiSqNdfPos=npts[0]-1;
02914 Ctrunc[0]=Csigma[0]+3.;
02915 }
02916
02917
02918 if(npts[1]>1 && Sw[1]!=0.) {
02919 CTIntercept[1]=CTIntercept[1]-Swt[1]/Sw[1]; Csigma[1]=0.;
02920 if((Swtt[1]/Sw[1])-(Swt[1]/Sw[1])*(Swt[1]/Sw[1])>0.) {Csigma[1]=pow((Swtt[1]/Sw[1])-(Swt[1]/Sw[1])*(Swt[1]/Sw[1]),0.5);}
02921 ChiSqNegative=Csigma[1]; ChiSqNdfNeg=npts[1]-1;
02922 Ctrunc[1]=Csigma[1]+3.;
02923 }
02924
02925 }
02926 }
02927
02928 cth.SetTimeForwardFitRMS(ChiSqPositive);
02929 cth.SetTimeForwardFitNDOF(ChiSqNdfPos);
02930 cth.SetTimeBackwardFitRMS(ChiSqNegative);
02931 cth.SetTimeBackwardFitNDOF(ChiSqNdfNeg);
02933
02934 }
02936
02937
02938
02940 void AlgFitTrackCam::SetRangeAnddS(CandFitTrackCamHandle& cth)
02941 {
02942
02943
02944 MSG("AlgFitTrackCam",Msg::kSynopsis) << "SetRangeAnddS from swimmer values between " << MinPlane << "/" << MaxPlane << endl;
02945
02946 UgliGeomHandle ugh = UgliGeomHandle(*vldc);
02947
02948 int ZDir; int VtxPlane; int EndPlane; int Increment;
02949 Detector::Detector_t detector = vldc->GetDetector();
02950 double dS; double dRange; double dP;
02951
02952
02953
02955
02956
02957
02958
02959
02960 if(ZIncreasesWithTime==true) {ZDir=1; EndPlane=MaxPlane; VtxPlane=MinPlane; Increment=-1;}
02961 else {ZDir=-1; EndPlane=MinPlane; VtxPlane=MaxPlane; Increment=1;}
02962
02963 PlexPlaneId plnid(detector,EndPlane,false);
02964 PlexPlaneId endplnid(detector,EndPlane,false);
02965
02966 double Zscint = SlcStripData[EndPlane][0].csh->GetZPos();
02967 double Znextscint = Zscint;
02968
02969 UgliScintPlnHandle scintpln = ugh.GetScintPlnHandle(plnid);
02970 double Zend = Zscint + double(ZDir)*scintpln.GetHalfThickness();
02971
02972 PlexPlaneId nextscint = endplnid.GetAdjoinScint(ZDir);
02973 UgliScintPlnHandle nextscintpln = ugh.GetScintPlnHandle(nextscint);
02974 if(nextscintpln.IsValid() && nextscint.GetPlaneView()!=PlaneView::kUnknown){
02975 Znextscint = nextscintpln.GetZ0();
02976 }
02977 else{
02978 nextscint = endplnid;
02979 }
02980
02981 plnid = plnid.GetAdjoinSteel(ZDir);
02982 if(plnid.IsValid()){
02983 UgliSteelPlnHandle steelpln = ugh.GetSteelPlnHandle(plnid);
02984 Zend = steelpln.GetZ0() - double(ZDir)*steelpln.GetHalfThickness();
02985 }
02986
02987
02988 if(detector==Detector::kNear && EndPlane>=121) {
02989 for(int i=0;i<2;i++){
02990 if(plnid.GetAdjoinSteel(ZDir).IsValid()){
02991 PlexPlaneId plnid_after = plnid.GetAdjoinSteel(ZDir);
02992 if(plnid_after.IsValid()) {
02993 plnid = plnid_after;
02994 UgliSteelPlnHandle steelpln = ugh.GetSteelPlnHandle(plnid);
02995 Zend = steelpln.GetZ0() - double(ZDir)*steelpln.GetHalfThickness();
02996 }
02997 }
02998 }
02999 }
03000
03001
03002 float u_end = FilteredData[EndPlane][0].x_k0;
03003 float v_end = FilteredData[EndPlane][0].x_k1;
03004 float du_end = FilteredData[EndPlane][0].x_k2;
03005 float dv_end = FilteredData[EndPlane][0].x_k3;
03006 float delz = Znextscint-Zscint;
03007 float u_extrap = u_end +delz*du_end;
03008 float v_extrap = v_end +delz*dv_end;
03009 float x_extrap = 0.707*(u_extrap-v_extrap);
03010 float y_extrap = 0.707*(u_extrap+v_extrap);
03011
03012 PlaneCoverage::PlaneCoverage_t kPC = PlaneCoverage::kComplete;
03013 if(detector==Detector::kNear) kPC=PlaneCoverage::kNearFull;
03014
03015 bool isInOutline = fPL.IsInside(x_extrap,y_extrap,nextscint.GetPlaneView(),kPC,false);
03016 bool isInCoil = isInOutline && !fPL.IsInside(x_extrap,y_extrap,nextscint.GetPlaneView(),kPC,true);
03017
03018 double S = 0; double Range = 0; double Prange = 0.0;
03019 double StateVector[5]; double Output[5];
03020 double chargesign = -1;
03021 bool GoForward = true; bool done=true; bool swimOK=true;
03022
03023
03024 if(isInCoil){
03025 float zCoil = Znextscint;
03026 float u_extrapC = u_extrap;
03027 float v_extrapC = v_extrap;
03028 float x_extrapC = x_extrap;
03029 float y_extrapC = y_extrap;
03030 while(isInCoil){
03031 zCoil -= 1.0*Munits::cm*ZDir;
03032 float delzC = zCoil - Zscint;
03033 u_extrapC = u_end +delzC*du_end;
03034 v_extrapC = v_end +delzC*dv_end;
03035 x_extrapC = 0.707*(u_extrapC-v_extrapC);
03036 y_extrapC = 0.707*(u_extrapC+v_extrapC);
03037 isInCoil = !fPL.IsInside(x_extrapC,y_extrapC,nextscint.GetPlaneView(),kPC,true) && ((zCoil>Zscint && ZDir==1) || (zCoil<Zscint && ZDir==-1)) ;
03038 }
03039 float zMinCoil = zCoil;
03040 if(zMinCoil<Zscint && ZDir==1) zMinCoil=Zscint;
03041 if(zMinCoil>Zscint && ZDir==-1) zMinCoil=Zscint;
03042
03043 zCoil = Znextscint;
03044 isInCoil = true;
03045 while(isInCoil){
03046 zCoil += 1.0*Munits::cm*ZDir;
03047 float delzC = zCoil - Zscint;
03048 u_extrapC = u_end +delzC*du_end;
03049 v_extrapC = v_end +delzC*dv_end;
03050 x_extrapC = 0.707*(u_extrapC-v_extrapC);
03051 y_extrapC = 0.707*(u_extrapC+v_extrapC);
03052 float zmin; float zmax;
03053 ugh.GetZExtent(zmin,zmax);
03054 isInCoil = !fPL.IsInside(x_extrapC,y_extrapC,nextscint.GetPlaneView(),kPC,true) && ((zCoil<zmax && ZDir==1) || (zCoil>zmin && ZDir==-1));
03055 }
03056 float zMaxCoil = zCoil;
03057 float zmin; float zmax;
03058 ugh.GetZExtent(zmin,zmax);
03059 if(zMaxCoil>zmax && ZDir==1) zMaxCoil=zmax;
03060 if(zMaxCoil<zmin && ZDir==-1) zMaxCoil=zmin;
03061
03062
03063 float zMidCoil = 0.5*(zMinCoil + zMaxCoil);
03064 float delzC = zMidCoil -Zscint;
03065 u_extrapC = u_end +delzC*du_end;
03066 v_extrapC = v_end +delzC*dv_end;
03067 x_extrapC = 0.707*(u_extrapC-v_extrapC);
03068 y_extrapC = 0.707*(u_extrapC+v_extrapC);
03069
03070 StateVector[0] = u_extrapC; Output[0]=StateVector[0];
03071 StateVector[1] = v_extrapC; Output[1]=StateVector[1];
03072 StateVector[2] = FilteredData[EndPlane][0].x_k2; Output[2]=StateVector[2];
03073 StateVector[3] = FilteredData[EndPlane][0].x_k3; Output[3]=StateVector[3];
03074 chargesign = -1;
03075 if(FilteredData[EndPlane][0].x_k4!=0.) {chargesign = FilteredData[EndPlane][0].x_k4/fabs(FilteredData[EndPlane][0].x_k4);}
03076
03077 GoForward = !ZIncreasesWithTime;
03078 StateVector[4] = 10.*chargesign; Output[4]=StateVector[4];
03079
03080 double dsdz = pow((1. + pow(StateVector[2],2) + pow(StateVector[3],2)),0.5);
03081
03082 Prange = 0.095*dsdz;
03083 if(detector==Detector::kNear && EndPlane>121) Prange = 0.2*dsdz;
03084 Prange += 0.5*dsdz*0.1*fabs(zMaxCoil-zMinCoil)*2.357*1.97;
03085
03086 swimOK = Swim(StateVector, Output, zMidCoil, EndPlane , GoForward, &dS, &dRange, &dP);
03087
03088 if(swimOK ){
03089 S = dS; Range = dRange; Prange = fabs(dP);
03090 cth.SetdS(EndPlane,S);
03091 cth.SetRange(EndPlane,Range);
03092 }
03093 if(!swimOK) {Output[4] = chargesign/Prange;}
03094
03095 }
03096
03097 else{
03098
03099 if((Zend<Zscint && ZDir==1) || (Zend>Zscint && ZDir==-1)) {
03100 MSG("AlgFitTrackCam",Msg::kWarning) << " Zend on wrong side of last scint! " << endl;
03101 Zend=Zscint;
03102 }
03103
03104
03105 StateVector[0]=FilteredData[EndPlane][0].x_k0; Output[0]=StateVector[0];
03106 StateVector[1]=FilteredData[EndPlane][0].x_k1; Output[1]=StateVector[1];
03107 StateVector[2]=FilteredData[EndPlane][0].x_k2; Output[2]=StateVector[2];
03108 StateVector[3]=FilteredData[EndPlane][0].x_k3; Output[3]=StateVector[3];
03109 StateVector[4]=FilteredData[EndPlane][0].x_k4; Output[4]=StateVector[4];
03110 chargesign = -1;
03111 if(StateVector[4]!=0.) {chargesign = StateVector[4]/fabs(StateVector[4]);}
03112
03113 GoForward = ZIncreasesWithTime;
03114 done = Swim(StateVector, Output, EndPlane, Zend, GoForward, &dS, &dRange, &dP);
03115
03116 GoForward = !ZIncreasesWithTime;
03117 double dsdz = pow((1. + pow(StateVector[2],2) + pow(StateVector[3],2)),0.5);
03118 S = 0; Range = 10.0*dsdz; Prange = 0.095*dsdz;
03119 swimOK = false;
03120 if(done){
03121 for(int j=0;j<5;j++) {StateVector[j]=Output[j];}
03122
03123
03124 StateVector[4] = chargesign * 10.52;
03125 swimOK = Swim(StateVector, Output, Zend, EndPlane , GoForward, &dS, &dRange, &dP);
03126 if(swimOK){
03127 S += dS; Range += dRange; Prange += fabs(dP);
03128 cth.SetdS(EndPlane,S);
03129 cth.SetRange(EndPlane,Range);
03130 }
03131 }
03132 if(!swimOK) {Output[4] = chargesign/Prange;}
03133 }
03134
03135 int thisplane = EndPlane;
03136
03137 bool firstplane=true;
03138 for(int i=EndPlane+Increment; Increment*i<=Increment*VtxPlane; i+=Increment) {
03139 if(FilteredData[i].size()>0) {
03140 double delU = FilteredData[i][0].x_k0 - StateVector[0] ;
03141 double delV = FilteredData[i][0].x_k1 - StateVector[1] ;
03142 double dSperPlane=0.;
03143 if(thisplane!=i) {dSperPlane = pow(delU*delU + delV*delV,0.5)/double(abs(thisplane-i));}
03144
03145
03146 if(dSperPlane < 1.5*Munits::m) {
03147 StateVector[0]=FilteredData[i][0].x_k0;
03148 StateVector[1]=FilteredData[i][0].x_k1;
03149 StateVector[2]=FilteredData[i][0].x_k2;
03150 StateVector[3]=FilteredData[i][0].x_k3;
03151
03152 chargesign=-1;
03153 if(FilteredData[i][0].x_k4!=0.) {chargesign = FilteredData[i][0].x_k4/fabs(FilteredData[i][0].x_k4);}
03154 }
03155
03156 StateVector[4] = chargesign * fabs(Output[4]);
03157 done = Swim(StateVector, Output, thisplane, i , GoForward, &dS, &dRange, &dP);
03158 if(done){
03159 S+=dS; Range+=dRange; Prange+=fabs(dP);
03160 cth.SetdS(i,S); cth.SetRange(i,Range);
03161 firstplane=false;
03162 }
03163 else {
03164 MSG("AlgFitTrackCam",Msg::kDebug) << " swim fail " << endl;
03165 }
03166 thisplane=i;
03167 }
03168 }
03169
03170 PlexPlaneId vtxplnid(detector,VtxPlane,false);
03171 PlexPlaneId plnid_before = vtxplnid.GetAdjoinSteel(-ZDir);
03172
03173 if(plnid_before.IsValid()) {
03174 plnid = plnid_before;
03175 UgliSteelPlnHandle steelpln = ugh.GetSteelPlnHandle(plnid);
03176 double Zstart = steelpln.GetZ0();
03177 StateVector[0]=FilteredData[VtxPlane][0].x_k0;
03178 StateVector[1]=FilteredData[VtxPlane][0].x_k1;
03179 StateVector[2]=FilteredData[VtxPlane][0].x_k2;
03180 StateVector[3]=FilteredData[VtxPlane][0].x_k3;
03181 StateVector[4]=Output[4];
03182 Swim(StateVector, Output, VtxPlane, Zstart, GoForward, &dS,&dRange,&dP);
03183 S+=dS; Range+=dRange; Prange+=fabs(dP);
03184
03185 cth.SetRange(VtxPlane,Range);
03186 cth.SetdS(VtxPlane,S);
03187 }
03188
03189
03190
03191
03192
03193 float ecorr = 1.0;
03194 if(vldc->GetDetector()==Detector::kNear && vldc->GetSimFlag()==SimFlag::kData) ecorr = 1.008;
03195
03196 cth.SetMomentumRange(Prange*ecorr);
03197 CandTrackHandle* findertrack = cth.GetFinderTrack();
03198 if(((detector==Detector::kFar && Prange>21.) || (detector==Detector::kNear && Prange>12.)) && findertrack) {cth.SetMomentumRange(findertrack->GetMomentum());}
03199 }
03201
03202
03203
03205 void AlgFitTrackCam::SetPropertiesFromFinderTrack(CandFitTrackCamHandle &cth)
03206 {
03207
03208
03209 MSG("AlgFitTrackCam",Msg::kSynopsis) << "SetPropertiesFromFinderTrack" << endl;
03210 cth.SetDirCosU(track->GetDirCosU());
03211 cth.SetDirCosV(track->GetDirCosV());
03212 cth.SetDirCosZ(track->GetDirCosZ());
03213 cth.SetVtxU(track->GetVtxU());
03214 cth.SetVtxV(track->GetVtxV());
03215 cth.SetVtxZ(track->GetVtxZ());
03216 cth.SetVtxT(track->GetVtxT());
03217 cth.SetVtxPlane(track->GetVtxPlane());
03218
03219 cth.SetEndDirCosU(track->GetEndDirCosU());
03220 cth.SetEndDirCosV(track->GetEndDirCosV());
03221 cth.SetEndDirCosZ(track->GetEndDirCosZ());
03222 cth.SetEndU(track->GetEndU());
03223 cth.SetEndV(track->GetEndV());
03224 cth.SetEndZ(track->GetEndZ());
03225 cth.SetEndT(track->GetEndT());
03226 cth.SetEndPlane(track->GetEndPlane());
03227
03228 cth.SetMomentumRange(track->GetMomentum());
03229 cth.SetMomentum(track->GetMomentum());
03230
03231 cth.SetTimeSlope(track->GetTimeSlope());
03232 cth.SetTimeOffset(track->GetTimeOffset());
03233 cth.SetTimeFitChi2(track->GetTimeFitChi2());
03234 cth.SetNTimeFitDigit(track->GetNTimeFitDigit());
03235 cth.SetTimeForwardFitRMS(track->GetTimeForwardFitRMS());
03236 cth.SetTimeForwardFitNDOF(track->GetTimeForwardFitNDOF());
03237 cth.SetTimeBackwardFitRMS(track->GetTimeBackwardFitRMS());
03238 cth.SetTimeBackwardFitNDOF(track->GetTimeBackwardFitNDOF());
03239
03240
03241
03242 int direction=1;
03243 if(ZIncreasesWithTime==false) {direction=-1;}
03244
03245 for(int i=cth.GetVtxPlane(); i*direction<=cth.GetEndPlane()*direction; i+=direction){
03246 if(track->IsTPosValid(i)) {
03247 cth.SetTrackPointError(i,track->GetTrackPointError(i));
03248 cth.SetdS(i,track->GetdS(i));
03249 cth.SetRange(i,track->GetRange(i));
03250 cth.SetU(i,track->GetU(i));
03251 cth.SetV(i,track->GetV(i));
03252 }
03253 }
03254
03255 CalculateTrace(cth);
03256 SetT(&cth);
03257
03258 Calibrator& cal = Calibrator::Instance();
03259 cal.ReInitialise(*vldc);
03260 Calibrate(&cth);
03261
03262
03263 }
03265
03266
03267
03268
03270 void AlgFitTrackCam::GenerateNDSpectStrips(const CandSliceHandle *slice,CandContext &cx)
03271 {
03272 MSG("AlgFitTrackCam",Msg::kDebug) << "GenerateNDSpectStrips" << endl;
03273
03274 bool AlreadyAssigned;
03275
03276
03277 CandContext cxx(this,cx.GetMom());
03278
03279
03280 AlgFactory &af = AlgFactory::GetInstance();
03281 AlgHandle stripah = af.GetAlgHandle("AlgStripSR","default");
03282
03283
03284 TIter SlcStripItr = slice->GetDaughterIterator();
03285 StripStruct temp;
03286
03287
03288 while(CandStripHandle* SlcStrip = dynamic_cast<CandStripHandle*>(SlcStripItr())) {
03289 if (SlcStrip->GetPlane()>120 && (SlcStrip->GetPlaneView()==PlaneView::kU || SlcStrip->GetPlaneView()==PlaneView::kV) ) {
03290 AlreadyAssigned=false;
03291
03292 TIter digitItr(SlcStrip->GetDaughterIterator());
03293 CandDigitHandle* dig = dynamic_cast<CandDigitHandle*>(digitItr());
03294 const PlexSEIdAltL& altl = dig->GetPlexSEIdAltL();
03295 int siz = altl.size();
03296
03297 for (int ind = 0; ind<siz; ++ind) {
03298
03299 if(AlreadyAssigned) {break;}
03300
03301 TObjArray diglist;
03302 TIter newstripdauItr(SlcStrip->GetDaughterIterator());
03303
03304 while(CandDigitHandle* olddig = dynamic_cast<CandDigitHandle*>(newstripdauItr())) {
03305 CandDigitHandle* newdig = olddig->DupHandle();
03306 PlexSEIdAltL& newaltl = newdig->GetPlexSEIdAltLWritable();
03307
03308
03309 if(NumFinderStrips<=newaltl.GetBestWeight()) {AlreadyAssigned=true; delete newdig;}
03310 else {
03311 for (int newind = 0; newind < siz; ++newind) {
03312 if(newind==ind){newaltl[newind].SetWeight((float)NumFinderStrips);}
03313 else{newaltl[newind].SetWeight((float)0.);}
03314 }
03315
03316 newdig->SetCandRecord(olddig->GetCandRecord());
03317 diglist.Add(newdig);
03318 }
03319
03320 }
03321
03322 if(1+diglist.GetLast()>0) {
03323 cxx.SetDataIn(&diglist);
03324 CandStripHandle newstrip = CandStrip::MakeCandidate(stripah,cxx);
03325 newstrip.SetCandRecord(slice->GetCandRecord());
03326 CandStripHandle* daustrip = new CandStripHandle(newstrip);
03327
03328 for (int i=0; i<=diglist.GetLast(); ++i) {
03329 CandDigitHandle* deldig = dynamic_cast<CandDigitHandle*>(diglist.At(i));
03330 delete deldig;
03331 }
03332 temp.csh=daustrip;
03333 SlcStripData[SlcStrip->GetPlane()].push_back(temp);
03334 }
03335 }
03336 }
03337 }
03338 SlcStripItr.Reset();
03339 }
03340
03342
03343
03344
03346 void AlgFitTrackCam::SpectrometerSwim(CandFitTrackCamHandle &cth)
03347 {
03348 MSG("AlgFitTrackCam",Msg::kDebug) << "SpectrometerSwim, improved track finding in spectrometer" << endl;
03349
03350
03351
03352 bool AddedStrip = false;
03353 int Plane; int NewPlane;
03354 double StateVector[5]; double NState[5]; double temp_x_k[5];
03355 bool GoForward; bool SpectSwim;
03356 int ActivePlanesSinceLastHit=0;
03357 int PlaneView; int Increment; int Counter;
03358 double LastHitTimes[2]={MeanTrackTime,MeanTrackTime};
03359 double TimeWindow=40.e-9;
03360
03361 double StripDistance; double MinDistanceToStrip;
03362 double SwimError2;
03363 double StripWidth = 4.108e-2;
03364 double PlanePitch = 0.0594;
03365
03366 bool TrackInActiveRegion;
03367 GoForward=true; Plane=MaxPlane; Increment=1;
03368
03369
03370
03371 while(ActivePlanesSinceLastHit<6 && Plane<121) {
03372 Plane += Increment;
03373 double u = x_k_minus[0] + x_k_minus[2]*(Plane-MaxPlane)*PlanePitch;
03374 double v = x_k_minus[1] + x_k_minus[3]*(Plane-MaxPlane)*PlanePitch;
03375
03376
03377 if(fabs(u) > 5000 || fabs(v) > 5000){
03378 MSG("AlgFitTrackCam", Msg::kError) << "SpectrometerSwim - unexpectedly large u or v (u="
03379 << u << " v=" << v << ") bailing out." << endl;
03380 return;
03381 }
03382
03383 if (NDPlaneIsActive(Plane, u, v, 0.3)) ActivePlanesSinceLastHit++;
03384 }
03385
03386
03387 if(ActivePlanesSinceLastHit>5 || abs(121-MaxPlane)>=40) {return;}
03388
03389
03390 ActivePlanesSinceLastHit=0;
03391 Plane = MaxPlane; NewPlane = Plane+1;
03392
03393
03394
03395 while(ActivePlanesSinceLastHit<8 && abs(NewPlane-Plane)<=70 && NewPlane<=290 && PassTrack==true) {
03396
03397 PlexPlaneId plexPlane(Detector::kNear,NewPlane, 0);
03398 if(SlcStripData[NewPlane].size()>0 && plexPlane.IsValid() && plexPlane.GetPlaneCoverage()!=PlaneCoverage::kNoActive) {
03399
03400 if(SlcStripData[NewPlane][0].csh->GetPlaneView()==2) {PlaneView=0;}
03401 else {PlaneView=1;}
03402
03403 for(int i=0; i<5; ++i) {StateVector[i]=x_k_minus[i];}
03404
03405
03406
03407 SpectSwim = Swim(StateVector, NState, Plane, NewPlane, GoForward);
03408
03409
03410 if(!SpectSwim && (NewPlane-Plane)>=40) {
03411 break;}
03412
03413
03414 if(!SpectSwim && StateVector[4]!=0) {
03415 Counter=0;
03416
03417 while(!SpectSwim && Counter<2) {
03418 StateVector[4]*=0.5;
03419 SpectSwim = Swim(StateVector, NState, Plane, NewPlane, GoForward);
03420
03421 if(!SpectSwim) {Counter++;}
03422 }
03423 }
03424
03425 if(!SpectSwim) {break;}
03426
03427 for(int i=0; i<5; ++i) {temp_x_k[i]=NState[i];}
03428
03429
03430 SwimError2 = C_k[PlaneView][PlaneView] + (C_k[PlaneView+2][PlaneView+2]*PlanePitch*PlanePitch*(NewPlane-Plane)*(NewPlane-Plane));
03431 MinDistanceToStrip = 3.0 * pow(StripWidth*StripWidth + SwimError2,0.5);
03432
03433
03434
03435 CandStripHandle* CurrentStrip = 0;
03436 for(unsigned int j=0; j<SlcStripData[NewPlane].size(); ++j) {
03437 StripDistance = fabs(SlcStripData[NewPlane][j].csh->GetTPos()-temp_x_k[PlaneView]);
03438
03439 if(StripDistance<MinDistanceToStrip
03440 && fabs(0.5*(LastHitTimes[0]+LastHitTimes[1])-NDStripBegTime(SlcStripData[NewPlane][j].csh,temp_x_k[0],temp_x_k[1]))<TimeWindow) {
03441 MinDistanceToStrip=StripDistance;
03442 CurrentStrip=SlcStripData[NewPlane][j].csh;
03443 }
03444 }
03445
03446
03447
03448 if(CurrentStrip) {
03449 LastHitTimes[1]=LastHitTimes[0];
03450 LastHitTimes[0]=NDStripBegTime(CurrentStrip,temp_x_k[0],temp_x_k[1]);
03451
03452 StripStruct temp;
03453 temp.csh = CurrentStrip;
03454 InitTrkStripData[NewPlane].push_back(temp);
03455
03456
03457 GetFitData(NewPlane,NewPlane);
03458
03459
03460 if (PlaneView==1) {H_k[0]=0; H_k[1]=1; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
03461 else {H_k[0]=1; H_k[1]=0; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
03462
03463 bool CombiPropagatorOk = GetCombiPropagator(Plane,NewPlane,GoForward);
03464
03465 if(CombiPropagatorOk) {
03466 GetNoiseMatrix(Plane,NewPlane);
03467 ExtrapCovMatrix();
03468 CalcKalmanGain(NewPlane);
03469 UpdateStateVector(Plane,NewPlane,GoForward);
03470 UpdateCovMatrix();
03471 MoveArrays();
03472 StoreFilteredData(NewPlane);
03473
03474 MaxPlane=NewPlane; Plane=MaxPlane;
03475 NewPlane=Plane+Increment;
03476
03477 ActivePlanesSinceLastHit=0;
03478 }
03479
03480
03482
03483
03484 CandTrackHandle * findertrack = cth.GetFinderTrack();
03485 if(findertrack) {
03486 bool SlushyOnEntry = CandHandle::IsSlushyEnabled();
03487 CandHandle::SetSlushyEnabled(kTRUE);
03488 AddedStrip = true;
03489 findertrack->AddDaughterLink(*CurrentStrip);
03490 findertrack->SetEndPlane(CurrentStrip->GetPlane());
03491 findertrack->SetEndZ(CurrentStrip->GetZPos());
03492 findertrack->SetEndU(FilteredData[CurrentStrip->GetPlane()][0].x_k0);
03493 findertrack->SetEndV(FilteredData[CurrentStrip->GetPlane()][0].x_k1);
03494 double dsdz = sqrt(1+pow(FilteredData[CurrentStrip->GetPlane()][0].x_k2,2)+pow(FilteredData[CurrentStrip->GetPlane()][0].x_k3,2));
03495 if(!ZIncreasesWithTime) dsdz=-dsdz;
03496 findertrack->SetEndDirCosU(FilteredData[CurrentStrip->GetPlane()][0].x_k2/dsdz);
03497 findertrack->SetEndDirCosV(FilteredData[CurrentStrip->GetPlane()][0].x_k3/dsdz);
03498 findertrack->SetEndDirCosZ(1/dsdz);
03499 if(!SlushyOnEntry) CandHandle::SetSlushyEnabled(kFALSE);
03500 }
03502
03503 }
03504 else {
03505 TrackInActiveRegion=NDPlaneIsActive(NewPlane, temp_x_k[0], temp_x_k[1], 0.3);
03506 if(plexPlane.IsValid() && plexPlane.GetPlaneCoverage()!=PlaneCoverage::kNoActive && TrackInActiveRegion)
03507 {ActivePlanesSinceLastHit++;}
03508 NewPlane+=Increment;
03509 }
03510 }
03511 else {
03512 double u = x_k_minus[0] + x_k_minus[2]*(NewPlane-Plane)*PlanePitch;
03513 double v = x_k_minus[1] + x_k_minus[3]*(NewPlane-Plane)*PlanePitch;
03514
03515 TrackInActiveRegion=NDPlaneIsActive(NewPlane, u, v, 0.3);
03516
03517 if(plexPlane.IsValid() && plexPlane.GetPlaneCoverage()!=PlaneCoverage::kNoActive && TrackInActiveRegion)
03518 {ActivePlanesSinceLastHit++;}
03519 NewPlane+=Increment;
03520 }
03521 }
03522
03523
03524
03526 if(AddedStrip) {
03527 CandTrackHandle * findertrack = cth.GetFinderTrack();
03528 if(findertrack) {
03529 bool SlushyOnEntry = CandHandle::IsSlushyEnabled();
03530 CandHandle::SetSlushyEnabled(kTRUE);
03531
03532 SetUVZT(findertrack);
03533 Double_t range = findertrack->GetRange();
03534 if (range>0.) {
03535 findertrack->SetMomentum(GetMomFromRange(range));
03536 }
03537 if(!SlushyOnEntry) CandHandle::SetSlushyEnabled(kFALSE);
03538 }
03539 }
03541 EndofRangePlane=MaxPlane;
03542 }
03544
03545
03546
03548 bool AlgFitTrackCam::NDPlaneIsActive(int plane, float u, float v, float projErr)
03549 {
03550
03551
03552 PlexPlaneId plexPlane(Detector::kNear,plane, 0);
03553 if(!plexPlane.IsValid()) {return false;}
03554 if(plexPlane.GetPlaneCoverage()==PlaneCoverage::kNoActive) {return false;}
03555 if(projErr<0.3)projErr=0.3;
03556 float x = 0.707*(u-v);
03557 float y = 0.707*(u+v);
03558 float dist,xedge,yedge;
03559 fPL.DistanceToEdge(x, y,
03560 plexPlane.GetPlaneView(),
03561 plexPlane.GetPlaneCoverage(),
03562 dist, xedge, yedge);
03563 bool isInside = fPL.IsInside(x, y,
03564 plexPlane.GetPlaneView(),
03565 plexPlane.GetPlaneCoverage());
03566 isInside &= dist>projErr;
03567
03568 return isInside;
03569 }
03571
03572
03573
03575 void AlgFitTrackCam::CleanNDLists(CandFitTrackHandle &cth,CandContext &cx)
03576 {
03577
03578
03579
03580
03581
03582
03584 for(int iplane=121; iplane<=290; ++iplane){
03585 for(unsigned int i=0; i<SlcStripData[iplane].size(); ++i){
03586 CandStripHandle* delstrip = SlcStripData[iplane][i].csh;
03587 delete delstrip;
03588 }
03589 }
03591
03592 bool SlushyOnEntry = CandHandle::IsSlushyEnabled();
03593 CandHandle::SetSlushyEnabled(kTRUE);
03594
03595
03597 const MomNavigator* mom = cx.GetMom();
03598 CandRecord* crec = dynamic_cast<CandRecord *> (mom->GetFragment("CandRecord", "PrimaryCandidateRecord"));
03599
03600
03601 CandStripListHandle* StripListOH = dynamic_cast<CandStripListHandle *>
03602 (crec->FindCandHandle("CandStripListHandle"));
03603 CandStripListHandle* StripList = StripListOH->DupHandle();
03604
03605 CandDigitListHandle* DigitListOH = dynamic_cast<CandDigitListHandle *>
03606 (crec->FindCandHandle("CandDigitListHandle","canddigitlist"));
03607 CandDigitListHandle* DigitList = DigitListOH->DupHandle();
03608
03609 CandSliceHandle* Slice = dynamic_cast<CandSliceHandle*>(cth.GetCandSliceWritable());
03611
03612
03613
03614
03616 vector<CandStripHandle*> StripsToAdd;
03617 vector<CandStripHandle*> StripsToRemove;
03618
03619 vector<CandStripHandle*> SliceStripsToAdd;
03620 vector<CandStripHandle*> SliceStripsToRemove;
03621
03622 vector<CandDigitHandle*> DigitsToAdd;
03623 vector<CandDigitHandle*> DigitsToRemove;
03624
03625
03626 CandStripHandleItr TrkStripItr(cth.GetDaughterIterator());
03627 for(CandStripHandle* TrkStrip=TrkStripItr(); TrkStrip; TrkStrip=TrkStripItr()){
03628
03629 if(TrkStrip->GetPlane()>120 ) {
03630 CandDigitHandleItr TrkDigitItr(TrkStrip->GetDaughterIterator());
03631 CandDigitHandle* TrkDigit = dynamic_cast<CandDigitHandle*>(TrkDigitItr());
03632
03633
03635 if(StripList) {
03636 bool AddedTrkStrip = false;
03637 CandStripHandleItr stripItr(StripList->GetDaughterIterator());
03638
03639 for(CandStripHandle* strip=stripItr(); strip ; strip=stripItr()) {
03640 if(strip->GetPlane()==TrkStrip->GetPlane()){
03641 CandDigitHandleItr digitItr(strip->GetDaughterIterator());
03642 CandDigitHandle* digit = dynamic_cast<CandDigitHandle*>(digitItr());
03643 bool SameCandStrip = false;
03644 bool SameHit = false;
03645
03646 if(TrkStrip->IsEqual(strip)) {SameCandStrip = true;}
03647
03648 if(digit->GetChannelId()==TrkDigit->GetChannelId() &&
03649 strip->GetCharge(CalDigitType::kNone)==TrkStrip->GetCharge(CalDigitType::kNone))
03650 {SameHit=true;}
03651
03652 if(!SameCandStrip && SameHit) {
03653 StripsToRemove.push_back(strip);
03654 if(!AddedTrkStrip) {StripsToAdd.push_back(TrkStrip);}
03655 AddedTrkStrip=true;
03656 }
03657 }
03658 }
03659 }
03661
03662
03663
03664
03666 if(Slice){
03667 bool AddedTrkStrip = false;
03668 CandStripHandleItr stripItr(Slice->GetDaughterIterator());
03669
03670 for(CandStripHandle* strip=stripItr(); strip; strip=stripItr()) {
03671 if(strip->GetPlane()==TrkStrip->GetPlane()){
03672 CandDigitHandleItr digitItr(strip->GetDaughterIterator());
03673 CandDigitHandle* digit = dynamic_cast<CandDigitHandle*>(digitItr());
03674 bool SameCandStrip = false;
03675 bool SameHit = false;
03676
03677 if(TrkStrip->IsEqual(strip)) {SameCandStrip=true;}
03678
03679 if(digit->GetChannelId()==TrkDigit->GetChannelId() &&
03680 strip->GetCharge(CalDigitType::kNone)==TrkStrip->GetCharge(CalDigitType::kNone))
03681 {SameHit=true;}
03682
03683 if(!SameCandStrip && SameHit) {
03684 SliceStripsToRemove.push_back(strip);
03685 if(!AddedTrkStrip) {SliceStripsToAdd.push_back(TrkStrip);}
03686 AddedTrkStrip=true;
03687 }
03688 }
03689 }
03690 }
03692
03693
03694
03696 if(DigitList) {
03697 CandDigitHandleItr TrkDigitItr2(TrkStrip->GetDaughterIterator());
03698 for(TrkDigit=TrkDigitItr2(); TrkDigit ; TrkDigit=TrkDigitItr2()) {
03699 bool AddedTrkDigit=false;
03700 CandDigitHandleItr DigitItr(DigitList->GetDaughterIterator());
03701
03702 for(CandDigitHandle* digit=DigitItr(); digit; digit=DigitItr()) {
03703 bool SameCandDigit=false;
03704 bool SameHit=false;
03705
03706 if(TrkDigit->IsEqual(digit)) {SameCandDigit=true;}
03707
03708 if(digit->GetChannelId()==TrkDigit->GetChannelId() &&
03709 digit->GetCharge(CalDigitType::kNone)==TrkDigit->GetCharge(CalDigitType::kNone))
03710 {SameHit=true;}
03711
03712 if(!SameCandDigit && SameHit) {
03713 DigitsToRemove.push_back(digit);
03714 if(!AddedTrkDigit) {DigitsToAdd.push_back(TrkDigit);}
03715 AddedTrkDigit=true;
03716 }
03717 }
03718 }
03719 }
03721
03723 }
03724 }
03725
03726
03727
03729 for(unsigned int i=0; i<StripsToAdd.size(); ++i) {StripList->AddDaughterLink(*(StripsToAdd[i]));}
03730 for(unsigned int i=0; i<StripsToRemove.size(); ++i) {StripList->RemoveDaughter(StripsToRemove[i]);}
03731 StripsToAdd.clear();
03732 StripsToRemove.clear();
03733
03734 for(unsigned int i=0; i<SliceStripsToAdd.size(); ++i) {Slice->AddDaughterLink(*(SliceStripsToAdd[i]));}
03735 for(unsigned int i=0; i<SliceStripsToRemove.size(); ++i) {Slice->RemoveDaughter(SliceStripsToRemove[i]);}
03736 SliceStripsToAdd.clear();
03737 SliceStripsToRemove.clear();
03738
03739 for(unsigned int i=0; i<DigitsToAdd.size(); ++i) {DigitList->AddDaughterLink(*(DigitsToAdd[i]));}
03740 for(unsigned int i=0; i<DigitsToRemove.size(); ++i) {DigitList->RemoveDaughter(DigitsToRemove[i]);}
03741 DigitsToAdd.clear();
03742 DigitsToRemove.clear();
03744
03745
03747
03748
03749 delete StripList;
03750 delete DigitList;
03751
03752 if(!SlushyOnEntry) CandHandle::SetSlushyEnabled(kFALSE);
03753 }
03755
03756
03757
03759 double AlgFitTrackCam::NDStripBegTime(CandStripHandle* Strip, double U, double V)
03760 {
03761 double BegTime=999; double Time=0;
03762 double Index=1.77; double DistFromCentre=0.;
03763 double FibreDist=0.; double halfLength=0.;
03764
03765
03766 if(U==0) {U=track->GetU(Strip->GetPlane());}
03767 if(V==0) {V=track->GetV(Strip->GetPlane());}
03768
03769 StripEnd::StripEnd_t StpEnd = StripEnd::kUnknown;
03770 CandDigitHandle* digit;
03771
03772 UgliGeomHandle ugh = UgliGeomHandle(*vldc);
03773 UgliStripHandle Striphandle;
03774
03775 CandDigitHandleItr digitItr(Strip->GetDaughterIterator());
03776
03777
03778
03780 while( (digit = digitItr()) ) {
03781 StpEnd=digit->GetPlexSEIdAltL().GetEnd();
03782
03783 if(StpEnd==StripEnd::kPositive) {
03784 FibreDist = 0.; DistFromCentre = 0.; Time=0.;
03785 UgliStripHandle StripHandle = ugh.GetStripHandle(Strip->GetStripEndId());
03786 halfLength = StripHandle.GetHalfLength();
03787
03788 if(Strip->GetPlaneView()==2) {DistFromCentre = V;}
03789 if(Strip->GetPlaneView()==3) {DistFromCentre = -U;}
03790
03791 FibreDist = (halfLength + DistFromCentre + StripHandle.ClearFiber(StpEnd)
03792 + StripHandle.WlsPigtail(StpEnd));
03793
03794 Time = digit->GetSubtractedTime(CalTimeType::kT0) - (Index/3.e8)*FibreDist;
03795
03796 if(Time<BegTime) {BegTime=Time;}
03797 }
03798 }
03799
03800 return BegTime;
03801 }
03803
03804
03805
03807 void AlgFitTrackCam::Trace(const char * ) const
03808 {
03809 }