Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

AlgFitTrackCam Class Reference

#include <AlgFitTrackCam.h>

Inheritance diagram for AlgFitTrackCam:

AlgBase AlgReco AlgTrack List of all members.

Public Member Functions

 AlgFitTrackCam ()
virtual ~AlgFitTrackCam ()
virtual void RunAlg (AlgConfig &ac, CandHandle &ch, CandContext &cx)
void InitialFramework (const CandSliceHandle *slice, CandContext &cx)
void RunTheFitter (CandFitTrackCamHandle &cth)
void StoreFilteredData (const int NewPlane)
void FillGapsInTrack ()
bool FindTheStrips (CandFitTrackCamHandle &cth, bool MakeTheTrack)
void GetFitData (int Plane1, int Plane2)
void ShowerStrips ()
void RemoveTrkHitsInShw ()
void ShowerSwim ()
void GoBackwards ()
void GoForwards ()
bool GetCombiPropagator (const int Plane, const int NewPlane, const bool GoForward)
bool Swim (double *StateVector, double *Output, const int Plane, const int NewPlane, const bool GoForward, double *dS=0, double *Range=0, double *dE=0)
bool Swim (double *StateVector, double *Output, const double zbeg, const int NewPlane, const bool GoForward, double *dS=0, double *Range=0, double *dE=0)
bool Swim (double *StateVector, double *Output, const int Plane, const double zend, const bool GoForward, double *dS=0, double *Range=0, double *dE=0)
void GetInitialCovarianceMatrix (const bool FirstIteration)
void GetNoiseMatrix (const int Plane, const int NewPlane)
void ExtrapCovMatrix ()
void CalcKalmanGain (const int NewPlane)
void UpdateStateVector (const int Plane, const int NewPlane, const bool GoForward)
void UpdateCovMatrix ()
void MoveArrays ()
void CheckValues (double *Input, const int NewPlane)
void SetTrackProperties (CandFitTrackCamHandle &cth)
void SetPropertiesFromFinderTrack (CandFitTrackCamHandle &cth)
void TimingFit (CandFitTrackCamHandle &cth)
void SetRangeAnddS (CandFitTrackCamHandle &cth)
void SpectrometerSwim (CandFitTrackCamHandle &cth)
void CleanNDLists (CandFitTrackHandle &cth, CandContext &cx)
bool NDPlaneIsActive (int plane, float u, float v, float projErr)
void GenerateNDSpectStrips (const CandSliceHandle *slice, CandContext &cx)
virtual void Trace (const char *c) const
void ResetCovarianceMatrix ()
double NDStripBegTime (CandStripHandle *Strip, double U=0, double V=0)

Private Attributes

vector< StripStructSlcStripData [490]
vector< StripStructInitTrkStripData [490]
vector< TrkDataStructTrkStripData [490]
vector< FiltDataStructFilteredData [490]
Int_t nbfield
Double_t bave
Bool_t EndofRange
Int_t EndofRangePlane
Bool_t LastIteration
double x_k4_biased
int UseGeoSwimmer
double x_k [5]
double x_k_minus [5]
double C_k [5][5]
double C_k_minus [5][5]
double C_k_intermediate [5][5]
double F_k [5][5]
double F_k_minus [5][5]
double Q_k [5][5]
double Q_k_minus [5][5]
double K_k [5]
int H_k [5]
int Identity [5][5]
double VtxCov [5]
double EndCov [5]
int MaxPlane
int MinPlane
double DeltaZ
double DeltaPlane
VldContextvldc
const CandTrackHandletrack
bool debug
bool ZIncreasesWithTime
bool PassTrack
bool SaveData
bool SwimThroughShower
int ShowerEntryPlane
int NIter
int TotalNSwimFail
int NumFinderStrips
double MeanTrackTime
PlaneOutline fPL
double StripListTime

Constructor & Destructor Documentation

AlgFitTrackCam::AlgFitTrackCam  ) 
 

Definition at line 71 of file AlgFitTrackCam.cxx.

00072 {
00073 }

AlgFitTrackCam::~AlgFitTrackCam  )  [virtual]
 

Definition at line 78 of file AlgFitTrackCam.cxx.

00079 {
00080 }


Member Function Documentation

void AlgFitTrackCam::CalcKalmanGain const int  NewPlane  ) 
 

Definition at line 1958 of file AlgFitTrackCam.cxx.

References C_k_intermediate, H_k, K_k, MSG, and TrkStripData.

Referenced by GoBackwards(), GoForwards(), ShowerSwim(), and SpectrometerSwim().

01959 {
01960   // K_k = C_k_intermediate * H_k^T * ( V_k + H_k * C_k_intermediate * H_k^T )^-1
01961   MSG("AlgFitTrackCam",Msg::kDebug) << "CalcKalmanGain" << endl;
01962 
01963   double Denominator=0;
01964 
01965   // H_k has only one non-zero element, so we can reduce matrix multiplication required
01966   if(TrkStripData[NewPlane][0].PlaneView==2) {Denominator=C_k_intermediate[0][0];}
01967   else {Denominator=C_k_intermediate[1][1];}
01968   
01969 
01970   // Add uncertainty in measurement
01971   Denominator+=TrkStripData[NewPlane][0].TPosError;
01972 
01973   MSG("AlgFitTrackCam",Msg::kVerbose) << "V_k " << TrkStripData[NewPlane][0].TPosError 
01974                                       << ", Kalman Gain Denominator " << Denominator << endl;
01975 
01976   if (Denominator!=0.) {
01977     for (int i=0; i<5; ++i) {
01978       K_k[i]=0;
01979       
01980       for (int m=0; m<5; ++m) {K_k[i]+=(C_k_intermediate[i][m])*(H_k[m]);}
01981       
01982       K_k[i]=K_k[i]/Denominator;
01983     }
01984 
01985     MSG("AlgFitTrackCam",Msg::kVerbose) << "Kalman Gain: " 
01986                                         << K_k[0] << " " << K_k[1] << " " << K_k[2] << " "
01987                                         << K_k[3] << " " << K_k[4] << endl;
01988   }
01989   else MSG("AlgFitTrackCam",Msg::kDebug) << "V_k + (H_k * C_k_intermediate * H_k_transpose) is zero!" << endl;
01990 }

void AlgFitTrackCam::CheckValues double *  Input,
const int  NewPlane
 

Definition at line 2190 of file AlgFitTrackCam.cxx.

References EndofRange, CandTrackHandle::GetRange(), MSG, PassTrack, and track.

Referenced by UpdateStateVector().

02191 {
02192   // Make range and gradient corrections
02193   // Possible source of offset in q/p resolutions
02194 
02195   // Range check
02196     
02197   double Maxqp=4.; double Maxqpfrac=1.2;
02198   double Range=track->GetRange(NewPlane);
02199 
02200   //JAM signal end of range found
02201   if(fabs(Input[4])>10.0) EndofRange=true; 
02202 
02203    if(Range>0. && (Maxqpfrac*500/Range)<Maxqp) {Maxqp=(Maxqpfrac*500/Range);}
02204   MSG("AlgFitTrackCam",Msg::kVerbose) << " Range " << Range << " Maxqp " << Maxqp << endl;
02205 
02206 
02207 
02208   if(LastIteration) Maxqp=40;
02209   if(fabs(Input[4])>Maxqp){
02210     //    cout << " CheckValues: Range check correction " << Input[4] << " " << Maxqp << endl;
02211     MSG("AlgFitTrackCam",Msg::kVerbose) << "CheckValues, Range check correction" << endl;
02212     Input[4]=(Input[4]>0 ? Maxqp : -Maxqp);
02213   }
02214   
02215   
02216   // Gradient check
02217   double Maxgradient=25.;
02218 
02219   if(fabs(Input[2])>Maxgradient) {
02220     MSG("AlgFitTrackCam",Msg::kVerbose) << "CheckValues, Gradient correction, U" << endl;
02221     Input[2]=(Input[2]>0 ? Maxgradient : -Maxgradient);
02222   }
02223 
02224   if(fabs(Input[3])>Maxgradient) {
02225     MSG("AlgFitTrackCam",Msg::kVerbose) << "CheckValues, Gradient correction, V" << endl;
02226     Input[3]=(Input[3]>0 ? Maxgradient : -Maxgradient);
02227   }
02228   
02229 
02230   // Check u and v values are not rubbish
02231   if(fabs(Input[0])<5000. && fabs(Input[1])<5000.) {PassTrack=true;}
02232   else {PassTrack=false;}
02233 }

void AlgFitTrackCam::CleanNDLists CandFitTrackHandle cth,
CandContext cx
 

Definition at line 3410 of file AlgFitTrackCam.cxx.

References CandHandle::AddDaughterLink(), digit(), CandDigitListHandle::DupHandle(), CandStripListHandle::DupHandle(), CandRecord::FindCandHandle(), CandRecoHandle::GetCandSliceWritable(), CandDigitHandle::GetChannelId(), CandDigitHandle::GetCharge(), CandStripHandle::GetCharge(), CandHandle::GetDaughterIterator(), MomNavigator::GetFragment(), CandContext::GetMom(), CandStripHandle::GetPlane(), CandHandle::IsEqual(), CandHandle::IsSlushyEnabled(), CandHandle::RemoveDaughter(), CandHandle::SetSlushyEnabled(), and SlcStripData.

Referenced by RunAlg().

03411 {
03412 
03413 
03414   // Sort out the lists for the ND spectrometer
03415 
03416   // Delete the strip handles created in GenerateNDSpectStrips.
03417   // All strip handles not added to a track daughter list are deleted here.
03419   for(int iplane=121; iplane<=290; ++iplane){
03420     for(unsigned int i=0; i<SlcStripData[iplane].size(); ++i){
03421       CandStripHandle* delstrip = SlcStripData[iplane][i].csh;
03422       delete delstrip; 
03423     }
03424   }
03426 
03427   bool SlushyOnEntry = CandHandle::IsSlushyEnabled();
03428   CandHandle::SetSlushyEnabled(kTRUE);
03429 
03430   // Get DigitList and StripList from CandRecord
03432   const MomNavigator* mom = cx.GetMom();
03433   CandRecord* crec = dynamic_cast<CandRecord *> (mom->GetFragment("CandRecord", "PrimaryCandidateRecord"));
03434 
03435   // DupHandle step added by gmieg.  Must delete StripList and DigitList.
03436   CandStripListHandle* StripListOH = dynamic_cast<CandStripListHandle *>
03437     (crec->FindCandHandle("CandStripListHandle"));
03438   CandStripListHandle* StripList = StripListOH->DupHandle();
03439 
03440   CandDigitListHandle* DigitListOH = dynamic_cast<CandDigitListHandle *>
03441     (crec->FindCandHandle("CandDigitListHandle","canddigitlist"));
03442   CandDigitListHandle* DigitList = DigitListOH->DupHandle();
03443 
03444   CandSliceHandle* Slice = dynamic_cast<CandSliceHandle*>(cth.GetCandSliceWritable());
03446 
03447  
03448   // Compare new fitted track, with DeMuxed spectrometer strips, 
03449   // to StripList, Slice and DigitList
03451   vector<CandStripHandle*> StripsToAdd;
03452   vector<CandStripHandle*> StripsToRemove;
03453 
03454   vector<CandStripHandle*> SliceStripsToAdd;
03455   vector<CandStripHandle*> SliceStripsToRemove;
03456 
03457   vector<CandDigitHandle*> DigitsToAdd;
03458   vector<CandDigitHandle*> DigitsToRemove;
03459 
03460 
03461   CandStripHandleItr TrkStripItr(cth.GetDaughterIterator());
03462   for(CandStripHandle* TrkStrip=TrkStripItr(); TrkStrip; TrkStrip=TrkStripItr()){
03463 
03464     if(TrkStrip->GetPlane()>120 ) {
03465       CandDigitHandleItr TrkDigitItr(TrkStrip->GetDaughterIterator());
03466       CandDigitHandle* TrkDigit = dynamic_cast<CandDigitHandle*>(TrkDigitItr());
03467 
03468       // Sort out StripList
03470       if(StripList) {
03471         bool AddedTrkStrip = false;
03472         CandStripHandleItr stripItr(StripList->GetDaughterIterator());
03473         
03474         for(CandStripHandle* strip=stripItr(); strip ; strip=stripItr()) {
03475           if(strip->GetPlane()==TrkStrip->GetPlane()){
03476             CandDigitHandleItr digitItr(strip->GetDaughterIterator());
03477             CandDigitHandle* digit = dynamic_cast<CandDigitHandle*>(digitItr());
03478             bool SameCandStrip = false;
03479             bool SameHit = false;
03480             
03481             if(TrkStrip->IsEqual(strip)) {SameCandStrip = true;}
03482             
03483             if(digit->GetChannelId()==TrkDigit->GetChannelId() &&
03484                strip->GetCharge(CalDigitType::kNone)==TrkStrip->GetCharge(CalDigitType::kNone))
03485               {SameHit=true;}
03486             
03487             if(!SameCandStrip && SameHit) {
03488               StripsToRemove.push_back(strip);
03489               if(!AddedTrkStrip) {StripsToAdd.push_back(TrkStrip);}
03490               AddedTrkStrip=true;
03491             }
03492           }
03493         }
03494       }
03496       
03497 
03498 
03499       // Sort out Slice
03501       if(Slice){
03502         bool AddedTrkStrip = false;
03503         CandStripHandleItr stripItr(Slice->GetDaughterIterator());
03504 
03505         for(CandStripHandle* strip=stripItr(); strip; strip=stripItr()) {
03506           if(strip->GetPlane()==TrkStrip->GetPlane()){
03507             CandDigitHandleItr digitItr(strip->GetDaughterIterator());
03508             CandDigitHandle* digit = dynamic_cast<CandDigitHandle*>(digitItr());
03509             bool SameCandStrip = false;
03510             bool SameHit = false;
03511 
03512             if(TrkStrip->IsEqual(strip)) {SameCandStrip=true;}
03513 
03514             if(digit->GetChannelId()==TrkDigit->GetChannelId() &&
03515                strip->GetCharge(CalDigitType::kNone)==TrkStrip->GetCharge(CalDigitType::kNone))
03516               {SameHit=true;}
03517 
03518             if(!SameCandStrip && SameHit) {
03519               SliceStripsToRemove.push_back(strip);
03520               if(!AddedTrkStrip) {SliceStripsToAdd.push_back(TrkStrip);}
03521               AddedTrkStrip=true;
03522             }
03523           }
03524         }
03525       }
03527 
03528 
03529       // Loop over track strip Digits, and rationalise DigitList
03531       if(DigitList) {
03532         CandDigitHandleItr TrkDigitItr2(TrkStrip->GetDaughterIterator());
03533         for(TrkDigit=TrkDigitItr2(); TrkDigit ; TrkDigit=TrkDigitItr2()) {
03534           bool AddedTrkDigit=false;
03535           CandDigitHandleItr DigitItr(DigitList->GetDaughterIterator());
03536 
03537           for(CandDigitHandle* digit=DigitItr(); digit; digit=DigitItr()) {
03538             bool SameCandDigit=false;
03539             bool SameHit=false;
03540 
03541             if(TrkDigit->IsEqual(digit)) {SameCandDigit=true;}
03542 
03543             if(digit->GetChannelId()==TrkDigit->GetChannelId() &&
03544                digit->GetCharge(CalDigitType::kNone)==TrkDigit->GetCharge(CalDigitType::kNone))
03545               {SameHit=true;}
03546 
03547             if(!SameCandDigit && SameHit) {
03548               DigitsToRemove.push_back(digit);
03549               if(!AddedTrkDigit) {DigitsToAdd.push_back(TrkDigit);}
03550               AddedTrkDigit=true;
03551             }
03552           }
03553         }
03554       }
03556     
03558     }
03559   } // End loop over track strips
03560 
03561 
03562   // Now make the actual modifications to the lists
03564   for(unsigned int i=0; i<StripsToAdd.size(); ++i) {StripList->AddDaughterLink(*(StripsToAdd[i]));}
03565   for(unsigned int i=0; i<StripsToRemove.size(); ++i) {StripList->RemoveDaughter(StripsToRemove[i]);}
03566   StripsToAdd.clear();
03567   StripsToRemove.clear();
03568 
03569   for(unsigned int i=0; i<SliceStripsToAdd.size(); ++i) {Slice->AddDaughterLink(*(SliceStripsToAdd[i]));}
03570   for(unsigned int i=0; i<SliceStripsToRemove.size(); ++i) {Slice->RemoveDaughter(SliceStripsToRemove[i]);}
03571   SliceStripsToAdd.clear();
03572   SliceStripsToRemove.clear();
03573 
03574   for(unsigned int i=0; i<DigitsToAdd.size(); ++i) {DigitList->AddDaughterLink(*(DigitsToAdd[i]));}
03575   for(unsigned int i=0; i<DigitsToRemove.size(); ++i) {DigitList->RemoveDaughter(DigitsToRemove[i]);}
03576   DigitsToAdd.clear();
03577   DigitsToRemove.clear();
03579 
03580   
03582 
03583   // Must delete DupHandle StripList and Digitlist (gmieg)
03584   delete StripList;
03585   delete DigitList;
03586 
03587   if(!SlushyOnEntry) CandHandle::SetSlushyEnabled(kFALSE); 
03588 }

void AlgFitTrackCam::ExtrapCovMatrix  ) 
 

Definition at line 1909 of file AlgFitTrackCam.cxx.

References C_k_intermediate, C_k_minus, F_k_minus, MSG, and Q_k_minus.

Referenced by GoBackwards(), GoForwards(), ShowerSwim(), and SpectrometerSwim().

01910 {
01911   // C_k_intermediate = (F_k_minus * C_k_minus * F_k_minus^T) + Q_k_minus
01912   MSG("AlgFitTrackCam",Msg::kDebug) << "ExtrapCovMatrix" << endl;
01913 
01914   for (int i=0; i<5; ++i) {
01915     for (int j=0; j<5; ++j) {  
01916       C_k_intermediate[i][j]=0;
01917       
01918       for (int l=0; l<5; ++l) {
01919         for (int m=0; m<5; ++m) {   
01920           C_k_intermediate[i][j]+=F_k_minus[i][m]*C_k_minus[m][l]*F_k_minus[j][l];
01921         }
01922       }
01923 
01924       C_k_intermediate[i][j]+=Q_k_minus[i][j];
01925     }
01926     
01927   }
01928 
01929 
01930   // Diagonal elements should be positive
01931   double covlim = 1.e-8;
01932 
01933   for(int i=0; i<5; ++i) {
01934     if(C_k_intermediate[i][i]<covlim) {
01935       MSG("AlgFitTrackCam",Msg::kVerbose) << "Negative diagonal element in C_k_intermediate" << endl;
01936       C_k_intermediate[i][i]=covlim;
01937     }
01938   }
01939 
01940 
01941   // Display
01942   if(debug) {
01943     cout << "C_k_intermediate" << endl;
01944     for(int i=0; i<5; ++i) {
01945       for(int j=0; j<5; ++j) {
01946         cout << C_k_intermediate[i][j] << " ";
01947       }
01948       cout << endl;
01949     }
01950   }
01951   
01952 }

void AlgFitTrackCam::FillGapsInTrack  ) 
 

Definition at line 794 of file AlgFitTrackCam.cxx.

References FilteredData, MaxPlane, MinPlane, MSG, SlcStripData, Swim(), FiltDataStruct::x_k0, FiltDataStruct::x_k1, FiltDataStruct::x_k2, FiltDataStruct::x_k3, FiltDataStruct::x_k4, and ZIncreasesWithTime.

Referenced by RunTheFitter().

00795 {
00796   // If there is no filtered data for a plane (between MinPlane and MaxPlane),
00797   // but this plane has hits in the slice, we interpolate from the nearest 
00798   // state vectors
00799   //
00800   // As with all filtered data, the interpolated data will be compared to
00801   // strip positions in the FindTheStrips method
00802   MSG("AlgFitTrackCam",Msg::kDebug) << "FillGapsInTrack" << endl;
00803 
00804 
00805   int CurrentPlane; int ForwardsPlane; int BackwardsPlane;
00806   int Plane; int NewPlane;  bool GoForward;
00807   double StateVector[5]; double Prediction[5]; bool GetPrediction;
00808   for(int i=0; i<5; i++) { Prediction[i]=0.; }
00809 
00810 
00811   for (int i=MinPlane; i<=MaxPlane; ++i) {   
00812     if(SlcStripData[i].size()>0) {
00813  
00814       if(FilteredData[i].size()==0) {
00815 
00816 
00817         // Find nearest filtered state vectors (within two planes) and ZPos differences
00819         // Forwards
00820         CurrentPlane=i+1; ForwardsPlane=-99;
00821 
00822         while(CurrentPlane<=MaxPlane && CurrentPlane<=(i+2)) {
00823           if(FilteredData[CurrentPlane].size()>0) {ForwardsPlane=CurrentPlane; break;}
00824           else {CurrentPlane++;}
00825         }
00826 
00827         // Backwards
00828         CurrentPlane=i-1; BackwardsPlane=-99;
00829 
00830         while(CurrentPlane>=MinPlane && CurrentPlane>=(i-2) ) {
00831           if(FilteredData[CurrentPlane].size()>0) {BackwardsPlane=CurrentPlane; break;}
00832           else {CurrentPlane--;}
00833         }
00835 
00836 
00837         // Find and store possible new filtered data, range and dS
00839         if(ForwardsPlane!=-99 && BackwardsPlane!=-99) {
00840 
00841           // Swimmer method
00842           GetPrediction=false;
00843           NewPlane=i;
00844           if(ZIncreasesWithTime==true) {Plane=ForwardsPlane; GoForward=false;}
00845           else{Plane=BackwardsPlane; GoForward=true;}
00846           if(FilteredData[Plane].size()>0) {
00847             StateVector[0] = FilteredData[Plane][0].x_k0;
00848             StateVector[1] = FilteredData[Plane][0].x_k1;
00849             StateVector[2] = FilteredData[Plane][0].x_k2;
00850             StateVector[3] = FilteredData[Plane][0].x_k3;
00851             StateVector[4] = FilteredData[Plane][0].x_k4;           
00852             GetPrediction=Swim(StateVector, Prediction, Plane, NewPlane, GoForward);
00853             
00854             if(GetPrediction==true) {
00855               // Store possible new state vector
00856               FiltDataStruct temp;
00857               temp.x_k0 = Prediction[0];
00858               temp.x_k1 = Prediction[1];
00859               temp.x_k2 = Prediction[2]; 
00860               temp.x_k3 = Prediction[3];
00861               temp.x_k4 = Prediction[4];              
00862               FilteredData[i].push_back(temp);
00863             }
00864           }
00865 
00866         }
00868       }
00869     }
00870   }
00871 
00872 }

bool AlgFitTrackCam::FindTheStrips CandFitTrackCamHandle cth,
bool  MakeTheTrack
 

Definition at line 878 of file AlgFitTrackCam.cxx.

References abs(), CandHandle::AddDaughterLink(), StripStruct::csh, FilteredData, CandStripHandle::GetCharge(), CandStripHandle::GetPlane(), InitTrkStripData, MaxPlane, MinPlane, CandHandle::RemoveDaughter(), SlcStripData, FiltDataStruct::x_k0, FiltDataStruct::x_k1, and ZIncreasesWithTime.

Referenced by RunTheFitter().

00879 { 
00880   // Given output data from Kalman filter, we find the strips that match most closely
00881   // and store the CandStripHandles in plane order in InitTrkStripData
00882   //
00883   // At end of track fitting, method is called with MakeTheTrack==true, so fit track
00884   // strips are finalised
00885 
00886   // JM ADDED 6/07:  Add pulse height requirement for first 3 hits at track vertex, and 
00887   //                 remove isolated single hit at vertex. This reduces tendency to add 
00888   //                 extra hits upstream of vertex.
00889   
00890   // Initialisations
00892   for (unsigned int i=0; i<490; ++i) {InitTrkStripData[i].clear();}
00893 
00894   double Extrem1=0; double Extrem2=0;
00895   double StripCentre=0;
00896   double StripWidth=4.108e-2;
00897   double HalfStripWidth=0.5*StripWidth;
00898   double TwoStripWidth=2.*StripWidth;  
00899   double PEthresh = 4.0;
00900   double MinDistanceToStrip;
00902   
00903   int NoOfHitPlanes=0; int Counter=0; int PlanesAdded=0;
00904   Bool_t foundMIP=false;
00905   for (int i=MinPlane; i<=MaxPlane; ++i) {if(FilteredData[i].size()>0) {NoOfHitPlanes++;} }
00906 
00907   // Loop over the entire output from Kalman filter
00909   
00910   if(ZIncreasesWithTime==true){
00911     for (int i=MinPlane; i<=MaxPlane; ++i) {   
00912       if(FilteredData[i].size()>0) {
00913         Counter++;
00914         int numStrips = 0;
00915         
00916         // Mark the possible extremities in transverse position within scintillator
00917         // by multiplying gradient by half scintillator thickness and adding or subtracting
00918         if(SlcStripData[i][0].csh->GetPlaneView()==2) {
00919           Extrem1=FilteredData[i][0].x_k0 + (0.0055*FilteredData[i][0].x_k2);
00920           Extrem2=FilteredData[i][0].x_k0 - (0.0055*FilteredData[i][0].x_k2);
00921         }
00922         else {
00923           Extrem1=FilteredData[i][0].x_k1 + (0.0055*FilteredData[i][0].x_k3);
00924           Extrem2=FilteredData[i][0].x_k1 - (0.0055*FilteredData[i][0].x_k3);
00925         }
00926         
00927         // Add strips in the case that only one strip can have its centre within 
00928         // half a strip width of an extremal position...
00930         if(fabs(Extrem1-Extrem2)<StripWidth) {
00931           for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
00932             StripCentre=SlcStripData[i][j].csh->GetTPos();
00933             
00934             if(fabs(StripCentre-Extrem1)<HalfStripWidth || fabs(StripCentre-Extrem2)<HalfStripWidth) {
00935               if(Counter>1 || SlcStripData[i][j].csh->GetCharge()>PEthresh || foundMIP==true){
00936                 foundMIP=true;
00937                 if(MakeTheTrack==true) {cth.AddDaughterLink(*SlcStripData[i][j].csh);}        
00938                 InitTrkStripData[i].push_back(SlcStripData[i][j]);
00939         
00940                 if(j==0)PlanesAdded++;          
00941               } 
00942               
00943               numStrips++;
00944             }
00945           }
00946         }
00948         
00949         
00950         // ...Otherwise, cover the cases where multiple strips can have their centre
00951         // within half a strip width of an extremal position
00953         else {
00954           for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
00955             StripCentre=SlcStripData[i][j].csh->GetTPos();
00956             
00957             if( fabs(StripCentre-Extrem1)<HalfStripWidth || fabs(StripCentre-Extrem2)<HalfStripWidth
00958                 || (Extrem1>StripCentre && Extrem2<StripCentre) 
00959                 || (Extrem1<StripCentre && Extrem2>StripCentre) ) {
00960               if(Counter>1 || SlcStripData[i][j].csh->GetCharge()>PEthresh || foundMIP==true){
00961                 foundMIP=true;
00962                 if(MakeTheTrack==true) {cth.AddDaughterLink(*SlcStripData[i][j].csh);}
00963                 InitTrkStripData[i].push_back(SlcStripData[i][j]);
00964                 if(j==0)PlanesAdded++;
00965               }
00966               numStrips++;            
00967 
00968             }
00969           }
00970         }
00972         // If we have found no strips, we consider looking further, finding the closest  
00973         // strip within a distance 'MinDistanceToStrip' of an extremal position
00975         if(numStrips==0) {
00976           CandStripHandle* CurrentStrip=0;
00977           
00978           // Be more demanding near track vertex
00979           if(Counter>2) {
00980             MinDistanceToStrip = TwoStripWidth;
00981             if(MakeTheTrack==true) MinDistanceToStrip = 2*TwoStripWidth;
00982           }
00983           else {MinDistanceToStrip=StripWidth;}
00984           for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
00985             StripCentre=SlcStripData[i][j].csh->GetTPos();
00986             
00987             // Find the closest strip and temporarily store its CandStripHandle
00988             if(fabs(StripCentre-Extrem1)<MinDistanceToStrip) {
00989               MinDistanceToStrip=StripCentre-Extrem1;
00990               CurrentStrip=SlcStripData[i][j].csh;
00991             }
00992             if(fabs(StripCentre-Extrem2)<MinDistanceToStrip) {
00993               MinDistanceToStrip=StripCentre-Extrem2;
00994               CurrentStrip=SlcStripData[i][j].csh;
00995             }
00996           }
00997           
00998           // If we have found a strip then we add it
00999           if(CurrentStrip) {
01000             if(Counter>1 || CurrentStrip->GetCharge()>PEthresh || foundMIP==true){
01001               foundMIP=true;
01002               if(MakeTheTrack==true) {cth.AddDaughterLink(*CurrentStrip);}          
01003               StripStruct temp;
01004               temp.csh = CurrentStrip;
01005               InitTrkStripData[i].push_back(temp);
01006               PlanesAdded++;
01007             }
01008           }
01009         }
01011       }
01012       if(PlanesAdded==3 ){  // remove first hit if it is separated by >1 plane from second
01013         Int_t np = 0;
01014         Int_t planebuf[3];
01015         Int_t pln = MinPlane;
01016         while(np<3 && pln<490){
01017           if(InitTrkStripData[pln].size()>0){
01018             planebuf[np] = InitTrkStripData[pln][0].csh->GetPlane();
01019             np++;
01020           }
01021           pln++;
01022         }
01023         if(np==3){
01024           if(abs(planebuf[1]-planebuf[0])/abs(planebuf[2]-planebuf[1])>1.5){
01025             for(unsigned int j=0; j<InitTrkStripData[planebuf[0]].size(); ++j) {
01026               CandStripHandle* Strip = InitTrkStripData[planebuf[0]][j].csh;     
01027               cth.RemoveDaughter(Strip);
01028             }
01029             InitTrkStripData[planebuf[0]].clear();
01030           }
01031         }
01032       }
01033     }
01034   }
01035   else{
01036     for (int i=MaxPlane; i>=MinPlane; --i) {   
01037       if(FilteredData[i].size()>0) {
01038         Counter++;
01039         int numStrips=0;
01040         
01041         
01042         // Mark the possible extremities in transverse position within scintillator
01043         // by multiplying gradient by half scintillator thickness and adding or subtracting
01044         if(SlcStripData[i][0].csh->GetPlaneView()==2) {
01045           Extrem1=FilteredData[i][0].x_k0 + (0.0055*FilteredData[i][0].x_k2);
01046           Extrem2=FilteredData[i][0].x_k0 - (0.0055*FilteredData[i][0].x_k2);
01047         }
01048         else {
01049           Extrem1=FilteredData[i][0].x_k1 + (0.0055*FilteredData[i][0].x_k3);
01050           Extrem2=FilteredData[i][0].x_k1 - (0.0055*FilteredData[i][0].x_k3);
01051         }
01052         
01053         
01054         // Add strips in the case that only one strip can have its centre within 
01055         // half a strip width of an extremal position...
01057         if(fabs(Extrem1-Extrem2)<StripWidth) {
01058           for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
01059             StripCentre=SlcStripData[i][j].csh->GetTPos();
01060             
01061             if(fabs(StripCentre-Extrem1)<HalfStripWidth || fabs(StripCentre-Extrem2)<HalfStripWidth) {
01062               if(Counter>1 || SlcStripData[i][j].csh->GetCharge()>PEthresh || foundMIP){
01063                 foundMIP=true;
01064                 if(MakeTheTrack==true) {cth.AddDaughterLink(*SlcStripData[i][j].csh);}
01065                 InitTrkStripData[i].push_back(SlcStripData[i][j]);
01066                 numStrips++;
01067                 if(j==0)PlanesAdded++;
01068               }      
01069             }
01070           }
01071         }
01073         
01074         
01075         // ...Otherwise, cover the cases where multiple strips can have their centre
01076         // within half a strip width of an extremal position
01078         else {
01079           for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
01080             StripCentre=SlcStripData[i][j].csh->GetTPos();
01081             
01082             if( fabs(StripCentre-Extrem1)<HalfStripWidth || fabs(StripCentre-Extrem2)<HalfStripWidth
01083                 || (Extrem1>StripCentre && Extrem2<StripCentre) 
01084                 || (Extrem1<StripCentre && Extrem2>StripCentre) ) {
01085               if(Counter>1 || SlcStripData[i][j].csh->GetCharge()>PEthresh || foundMIP){
01086                 foundMIP=true;
01087                 if(MakeTheTrack==true) {cth.AddDaughterLink(*SlcStripData[i][j].csh);}          
01088                 InitTrkStripData[i].push_back(SlcStripData[i][j]);
01089                 numStrips++;
01090                 if(j==0)PlanesAdded++;
01091               }
01092             }
01093           }
01094         }
01096         
01097         // If we have found no strips, we consider looking further, finding the closest  
01098         // strip within a distance 'MinDistanceToStrip' of an extremal position
01100         if(numStrips==0) {
01101           CandStripHandle* CurrentStrip=0;
01102           
01103           // Be more demanding near track vertex
01104           if(Counter>2) {
01105             MinDistanceToStrip = TwoStripWidth;
01106             if(MakeTheTrack==true) MinDistanceToStrip = 2*TwoStripWidth;
01107           }
01108           
01109           for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
01110             StripCentre=SlcStripData[i][j].csh->GetTPos();
01111             
01112             // Find the closest strip and temporarily store its CandStripHandle
01113             if(fabs(StripCentre-Extrem1)<MinDistanceToStrip) {
01114               MinDistanceToStrip=StripCentre-Extrem1;
01115               CurrentStrip=SlcStripData[i][j].csh;
01116             }
01117             if(fabs(StripCentre-Extrem2)<MinDistanceToStrip) {
01118               MinDistanceToStrip=StripCentre-Extrem2;
01119               CurrentStrip=SlcStripData[i][j].csh;
01120             }
01121           }
01122           
01123           // If we have found a strip then we add it
01124           if(CurrentStrip) {
01125             if(Counter>1 || CurrentStrip->GetCharge()>PEthresh || foundMIP){
01126               foundMIP=true;    
01127               if(MakeTheTrack==true) {cth.AddDaughterLink(*CurrentStrip);}
01128               StripStruct temp;
01129               temp.csh = CurrentStrip;
01130               InitTrkStripData[i].push_back(temp);
01131               PlanesAdded++;
01132             }
01133           }
01134         }
01136       }
01137      if(PlanesAdded==3 ){  // remove first hit if it is separated by >1 plane from second
01138         Int_t np = 0;
01139         Int_t planebuf[3];
01140         Int_t pln = MaxPlane;
01141         while(np<3 && pln>=0){
01142           if(InitTrkStripData[pln].size()>0){
01143             planebuf[np]= InitTrkStripData[pln][0].csh->GetPlane();
01144             np++;
01145           }
01146           pln--;
01147         }
01148         if(np==3){
01149           if(abs(planebuf[1]-planebuf[0])/abs(planebuf[2]-planebuf[1])>1.5){
01150           for(unsigned int j=0; j<InitTrkStripData[planebuf[0]].size(); ++j) {
01151             CandStripHandle* Strip = InitTrkStripData[planebuf[0]][j].csh;       
01152             cth.RemoveDaughter(Strip);
01153           }
01154           InitTrkStripData[planebuf[0]].clear();
01155           }
01156         }
01157       }
01158     }  
01159   }
01161   
01162 
01163   // Find new max and min planes
01164   MaxPlane=-20; MinPlane=500;
01165   for (int i=0; i<490; ++i) {   
01166     if(InitTrkStripData[i].size()>0) {
01167       if(i>MaxPlane) {MaxPlane=i;}
01168       if(i<MinPlane) {MinPlane=i;}
01169     }
01170   }
01171 
01172   if(MaxPlane==-20 || MinPlane==500) {return false;}
01173   else {return true;}
01174 
01175 }

void AlgFitTrackCam::GenerateNDSpectStrips const CandSliceHandle slice,
CandContext cx
 

Definition at line 3108 of file AlgFitTrackCam.cxx.

References StripStruct::csh, CandDigitHandle::DupHandle(), AlgFactory::GetAlgHandle(), PlexSEIdAltL::GetBestWeight(), CandHandle::GetCandRecord(), CandHandle::GetDaughterIterator(), AlgFactory::GetInstance(), CandContext::GetMom(), CandStripHandle::GetPlane(), CandStripHandle::GetPlaneView(), CandDigitHandle::GetPlexSEIdAltL(), CandDigitHandle::GetPlexSEIdAltLWritable(), CandStrip::MakeCandidate(), MSG, NumFinderStrips, CandHandle::SetCandRecord(), and SlcStripData.

Referenced by InitialFramework().

03109 {
03110   MSG("AlgFitTrackCam",Msg::kDebug) << "GenerateNDSpectStrips" << endl;
03111 
03112   bool AlreadyAssigned;
03113 
03114 
03115   CandContext cxx(this,cx.GetMom());
03116 
03117   // Get singleton instance of AlgFactory
03118   AlgFactory &af = AlgFactory::GetInstance();
03119   AlgHandle stripah = af.GetAlgHandle("AlgStripSR","default");
03120 
03121   // Store CandStripHandles and make the strips accessible by plane number
03122   TIter SlcStripItr = slice->GetDaughterIterator();
03123   StripStruct temp;
03124   
03125   // Store all strips in slice
03126   while(CandStripHandle* SlcStrip = dynamic_cast<CandStripHandle*>(SlcStripItr()))  {
03127     if (SlcStrip->GetPlane()>120 && (SlcStrip->GetPlaneView()==PlaneView::kU || SlcStrip->GetPlaneView()==PlaneView::kV) ) {
03128       AlreadyAssigned=false;
03129       
03130       TIter digitItr(SlcStrip->GetDaughterIterator());
03131       CandDigitHandle* dig = dynamic_cast<CandDigitHandle*>(digitItr());              
03132       const PlexSEIdAltL& altl = dig->GetPlexSEIdAltL();
03133       int siz = altl.size();
03134       
03135       for (int ind = 0; ind<siz; ++ind) {
03136         // Only want to make the single copy of an assigned strip
03137         if(AlreadyAssigned) {break;}
03138         
03139         TObjArray diglist;  
03140         TIter newstripdauItr(SlcStrip->GetDaughterIterator());
03141         
03142         while(CandDigitHandle* olddig = dynamic_cast<CandDigitHandle*>(newstripdauItr())) {
03143           CandDigitHandle* newdig = olddig->DupHandle();
03144           PlexSEIdAltL& newaltl = newdig->GetPlexSEIdAltLWritable(); 
03145           
03146           // Don't make any strips which have already been assigned to a 'better' track
03147           if(NumFinderStrips<=newaltl.GetBestWeight()) {AlreadyAssigned=true; delete newdig;}
03148           else {
03149             for (int newind = 0; newind < siz; ++newind) {
03150               if(newind==ind){newaltl[newind].SetWeight((float)NumFinderStrips);}
03151               else{newaltl[newind].SetWeight((float)0.);}
03152             }
03153             
03154             newdig->SetCandRecord(olddig->GetCandRecord());
03155             diglist.Add(newdig);   // diglist does not own newdig. These must be explicitly deleted 
03156           }
03157         
03158         }
03159         // Only make a new strip if we have any digits  
03160         if(1+diglist.GetLast()>0) {
03161           cxx.SetDataIn(&diglist);
03162           CandStripHandle newstrip = CandStrip::MakeCandidate(stripah,cxx);
03163           newstrip.SetCandRecord(slice->GetCandRecord());
03164           CandStripHandle* daustrip = new CandStripHandle(newstrip);
03165           
03166           for (int i=0; i<=diglist.GetLast(); ++i) {
03167             CandDigitHandle* deldig =  dynamic_cast<CandDigitHandle*>(diglist.At(i));
03168             delete deldig;
03169           }
03170           temp.csh=daustrip;      
03171           SlcStripData[SlcStrip->GetPlane()].push_back(temp);
03172         }
03173       }
03174     }
03175   }
03176   SlcStripItr.Reset();
03177 }

bool AlgFitTrackCam::GetCombiPropagator const int  Plane,
const int  NewPlane,
const bool  GoForward
 

Definition at line 1340 of file AlgFitTrackCam.cxx.

References abs(), DeltaPlane, DeltaZ, F_k_minus, MSG, Swim(), TotalNSwimFail, TrkStripData, and x_k_minus.

Referenced by GoBackwards(), GoForwards(), ShowerSwim(), and SpectrometerSwim().

01341 {
01342   // Combination propagator, essentially same as SR propagator, but
01343   // generation of matrix reduces calls to swimmer by 80%
01344   MSG("AlgFitTrackCam",Msg::kDebug) << "GetCombiPropagator" << endl;
01345 
01346   for (int i=0; i<5; ++i) {
01347     for (int j=0; j<5; ++j) {
01348       F_k_minus[i][j]=0;  
01349     }
01350   }
01351 
01352   F_k_minus[0][0]=1; F_k_minus[1][1]=1; 
01353   F_k_minus[2][2]=1; F_k_minus[3][3]=1;
01354   
01355   DeltaZ=fabs(TrkStripData[NewPlane][0].ZPos-TrkStripData[Plane][0].ZPos);
01356   DeltaPlane=abs(NewPlane-Plane);
01357 
01358   // Swimmer section for last column
01359   double PState[5];  double NState[5];  double StateVector[5];
01360   double Increment=0.01;
01361   bool SwimInc=false; bool SwimDec=false;
01362   int nswimfail=0;
01363   
01364   if(GoForward==true) {F_k_minus[0][2]=DeltaZ; F_k_minus[1][3]=DeltaZ;}
01365   else if(GoForward==false) {F_k_minus[0][2]=-DeltaZ; F_k_minus[1][3]=-DeltaZ;}
01366   
01367   
01368   // Give swimmer fixed number of opportunities for successful swim
01369   while((SwimInc==false || SwimDec==false) && nswimfail<=10) {
01370     
01371     Increment=0.05*fabs(x_k_minus[4]); 
01372     if(Increment<.01) {Increment=.01;}
01373        
01374     for(int j=0; j<5; ++j) {StateVector[j]=x_k_minus[j];}  
01375     
01376     // Increment then swim
01377     StateVector[4]+=Increment;
01378     SwimInc=Swim(StateVector, NState, Plane, NewPlane, GoForward);
01379     
01380     StateVector[4]=x_k_minus[4];
01381     
01382     // Decrement then swim
01383     StateVector[4]-=Increment;
01384     SwimDec=Swim(StateVector, PState, Plane, NewPlane, GoForward);
01385     
01386     // If swim failed, double momentum and swim again
01387     if(SwimInc==false || SwimDec==false) {
01388       MSG("AlgFitTrackCam",Msg::kVerbose) << "GetCombiPropagator, Swim failed - Double momentum and swim again" << endl;
01389       x_k_minus[4]*=0.5;
01390       nswimfail++; TotalNSwimFail++;
01391       break;
01392     }
01393     
01394     // Form last row of propagator matrix.  Need to transpose to get proper Kalman F_k_minus
01395     else {
01396       if(Increment!=0.) {
01397         for(int j=0; j<5; ++j) {
01398           F_k_minus[j][4] = (NState[j]-PState[j]) / (2*Increment);
01399         }
01400       }
01401       else {F_k_minus[4][4]=1;}
01402     }
01403     
01404   } // End while statement
01405   
01406   if(nswimfail>10) {MSG("AlgFitTrackCam",Msg::kDebug) << "GetCombiPropagator, nswimfail>10, fail track" << endl; return false;}
01407 
01408 
01409   // Display
01410   if(debug) {
01411     cout << "Combi F_k_minus" << endl;
01412     for(int i=0; i<5; ++i) {  
01413       for(int j=0; j<5; ++j) {
01414         cout << F_k_minus[i][j] << " ";
01415       }
01416       cout << endl;
01417     }
01418   }
01419   
01420   return true;
01421 }

void AlgFitTrackCam::GetFitData int  Plane1,
int  Plane2
 

Definition at line 699 of file AlgFitTrackCam.cxx.

References CandRecoHandle::GetCharge(), Plane::GetStrip(), CandTrackHandle::GetU(), CandTrackHandle::GetV(), InitTrkStripData, MSG, TrkDataStruct::PlaneView, SlcStripData, TrkDataStruct::TPos, TrkDataStruct::TPosError, track, TrkStripData, and TrkDataStruct::ZPos.

Referenced by RunAlg(), RunTheFitter(), SetTrackProperties(), ShowerSwim(), and SpectrometerSwim().

00700 {
00701   // Loop over the initial track strip data and create the final data for fitting
00702   MSG("AlgFitTrackCam",Msg::kDebug) << "GetFitData" << endl;
00703 
00704   // Initialisations
00705   double MisalignmentError=4e-6;  // Squared error for misalignment of strips
00706   double SumChargeTPos=0; double SumCharge=0; int MaxStrip=-20; int MinStrip=200;
00707   bool NewStripFound=true;
00708 
00709   int ThisStrip;
00710 
00711   // Get the data for region between the planes specified
00712   for(int i=Plane1; i<=Plane2; ++i) {
00713     if(InitTrkStripData[i].size()>0) {     
00714       
00715       // Find max and min strip numbers for strips in plane
00716       for(unsigned int j=0; j<InitTrkStripData[i].size(); ++j) {
00717         if(InitTrkStripData[i][j].csh->GetStrip()<MinStrip) {MinStrip=InitTrkStripData[i][j].csh->GetStrip();}
00718         if(InitTrkStripData[i][j].csh->GetStrip()>MaxStrip) {MaxStrip=InitTrkStripData[i][j].csh->GetStrip();}  
00719       }
00720 
00721 
00722       // Find continuous groups of strips
00724       NewStripFound=true;
00725       
00726       while(NewStripFound==true) {
00727         
00728         NewStripFound=false;
00729         
00730         for(unsigned int j=0; j<SlcStripData[i].size(); ++j) {
00731 
00732           ThisStrip=SlcStripData[i][j].csh->GetStrip();
00733 
00734           if( ThisStrip==(MaxStrip+1) ) {
00735             MaxStrip+=1;
00736             NewStripFound=true;
00737             
00738             InitTrkStripData[i].push_back(SlcStripData[i][j]);
00739           }
00740           
00741           if( ThisStrip==(MinStrip-1) ) {
00742             MinStrip-=1;
00743             NewStripFound=true;
00744             
00745             InitTrkStripData[i].push_back(SlcStripData[i][j]);
00746           }
00747         }
00748       }
00750 
00751 
00752 
00753       // Get the data for fitting
00755       for(unsigned int j=0; j<InitTrkStripData[i].size(); ++j) {
00756         SumCharge+=InitTrkStripData[i][j].csh->GetCharge();
00757 
00758         // JAM 11/08:  Change to support strip rotations
00759         PlaneView::PlaneView_t plnvw =InitTrkStripData[i][j].csh->GetPlaneView();
00760         Double_t orthopos = track->GetV(InitTrkStripData[i][j].csh->GetPlane());
00761         if(plnvw == PlaneView::kV){
00762           orthopos = track->GetU(InitTrkStripData[i][j].csh->GetPlane());
00763         }
00764         // JAM 11/08:  to activate strip rotation support add orthopos as argument to GetTPos()
00765         SumChargeTPos+=InitTrkStripData[i][j].csh->GetCharge()*InitTrkStripData[i][j].csh->GetTPos();
00766       }
00767 
00768       // Charge weighted TPos and Flat distribution error
00769       if(SumCharge!=0.) {
00770         TrkDataStruct temp;
00771         
00772         temp.ZPos=InitTrkStripData[i][0].csh->GetZPos();
00773         temp.PlaneView=InitTrkStripData[i][0].csh->GetPlaneView();
00774 
00775         temp.TPos=SumChargeTPos/SumCharge;
00776         temp.TPosError=( (1.406305333e-4 * (1 + MaxStrip-MinStrip) )+ MisalignmentError);
00777         
00778         TrkStripData[i].push_back(temp);
00779       }
00781 
00782 
00783       // Reset      
00784       SumChargeTPos=0; SumCharge=0; MaxStrip=-20; MinStrip=200;
00785     }
00786   }
00787   
00788 }

void AlgFitTrackCam::GetInitialCovarianceMatrix const bool  FirstIteration  ) 
 

Definition at line 1724 of file AlgFitTrackCam.cxx.

References C_k_minus, min, MSG, and ZIncreasesWithTime.

Referenced by ResetCovarianceMatrix(), and RunTheFitter().

01725 {
01726   MSG("AlgFitTrackCam",Msg::kDebug) << "GetInitialCovarianceMatrix" << endl;
01727 
01728   if(FirstIteration==true) {
01729     
01730     for(int i=0; i<5; ++i) {
01731       for(int j=0; j<5; ++j) {
01732         C_k_minus[i][j]=0.;
01733       }
01734     }
01735     
01736     // Diagonal terms
01737     C_k_minus[0][0]=0.25; C_k_minus[1][1]=0.25; 
01738     C_k_minus[2][2]=100.; C_k_minus[3][3]=100.; 
01739     C_k_minus[4][4]=1.;
01740     
01741     // Off diagonal terms. Taken from SR - Origin of this?
01742     if(ZIncreasesWithTime==true) {
01743       C_k_minus[0][4]=7.5e-5;  C_k_minus[1][4]=7.5e-5;
01744       C_k_minus[4][0]=7.5e-5;  C_k_minus[4][1]=7.5e-5;
01745     }
01746     else if(ZIncreasesWithTime==false) {
01747       C_k_minus[0][4]=-7.5e-5;  C_k_minus[1][4]=-7.5e-5;
01748       C_k_minus[4][0]=-7.5e-5;  C_k_minus[4][1]=-7.5e-5;
01749     }
01750     
01751     
01752   }
01753 
01754   else if(FirstIteration==false) {
01755     // Results are very sensitive to this multiplication. A large number means
01756     // that further iterations start with the same uncertainties as the first,
01757     // albeit with improved "track finder" strips
01758     for(int i=0; i<5; ++i) {C_k_minus[i][i]*=100;}
01759     
01760     
01761     // Make sure not larger than very first covariance elements
01762     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);
01763     C_k_minus[2][2]=min(C_k_minus[2][2],100.); C_k_minus[3][3]=min(C_k_minus[3][3],100.);
01764     C_k_minus[4][4]=min(C_k_minus[4][4],1.);
01765 
01766     double cov_xqp = 7.5e-5;             // Taken from SR - Origin of this?
01767     
01768     for(int i=0; i<2; ++i){
01769       if(fabs(C_k_minus[i][4])>cov_xqp) C_k_minus[i][4] = (C_k_minus[i][4] > 0 ? cov_xqp : -cov_xqp);
01770       if(fabs(C_k_minus[4][i])>cov_xqp) C_k_minus[4][i] = (C_k_minus[4][i] > 0 ? cov_xqp : -cov_xqp);
01771     }
01772 
01773     cov_xqp /= 0.06;                     // Taken from SR - Origin of this?
01774 
01775     for(int i=2; i<4; ++i){
01776       if(fabs(C_k_minus[i][4])>cov_xqp) C_k_minus[i][4] = (C_k_minus[i][4] > 0 ? cov_xqp : -cov_xqp);
01777       if(fabs(C_k_minus[4][i])>cov_xqp) C_k_minus[4][i] = (C_k_minus[4][i] > 0 ? cov_xqp : -cov_xqp);
01778     }
01779   }
01780 
01781 
01782   // Display
01783   if(debug) {
01784     cout << "Initial covariance matrix" << endl;
01785     for(int p=0; p<5; ++p){
01786       for(int q=0; q<5; ++q){
01787         cout << C_k_minus[p][q] << " ";
01788       }  
01789       cout << endl;
01790     }
01791   }
01792 
01793 }

void AlgFitTrackCam::GetNoiseMatrix const int  Plane,
const int  NewPlane
 

Definition at line 1799 of file AlgFitTrackCam.cxx.

References DeltaPlane, DeltaZ, BField::GetBField(), UgliGeomHandle::GetNearestSteelPlnHandle(), SwimGeo::GetSteel(), SwimPlaneInterface::GetZ(), UgliSteelPlnHandle::GetZ0(), SwimGeo::Instance(), MSG, pow(), Q_k_minus, TrkStripData, vldc, and x_k_minus.

Referenced by GoBackwards(), GoForwards(), ShowerSwim(), and SpectrometerSwim().

01800 {
01801   // This method is essentially the same as in SR fitter
01802   MSG("AlgFitTrackCam",Msg::kDebug) << "GetNoiseMatrix" << endl;
01803 
01804   for (int p=0; p<5; ++p) {
01805     for (int q=0; q<5; ++q) {
01806       Q_k_minus[p][q]=0;    }
01807   }
01808   
01809   // Get gradients, etc from x_k_minus
01810   double dsdzSquared = 1.+pow(x_k_minus[2],2)+pow(x_k_minus[3],2);
01811   double dsdz = pow(dsdzSquared,0.5);
01812 
01813   // Implement noise matrix as in SR
01814   if (DeltaPlane!=-99 && DeltaZ!=-99) {  
01815     double qp = x_k_minus[4];
01816     if(fabs(qp)<0.01) qp = (qp>0 ? 0.01 : -0.01);
01817     int izdir = ((NewPlane-Plane)>0 ? 0 : 1);
01818   
01819     double LocalRadiationLength=(dsdz * double(DeltaPlane) * 1.47); // 1.47 radiation lengths per iron plane
01820 
01821     double SigmaMS=(0.0136 * fabs(qp) * pow(LocalRadiationLength,0.5)
01822                     * (1. + (0.038 * log(LocalRadiationLength)) ));
01823     double SigmaMSSquared=pow(SigmaMS,2);
01824 
01825     double Sigma33Squared=0.5*SigmaMSSquared*dsdzSquared*(1.+pow(x_k_minus[2],2));
01826 
01827     double Sigma34Squared=0.5*SigmaMSSquared*dsdzSquared*(x_k_minus[2]*x_k_minus[3]);
01828 
01829     double Sigma44Squared=0.5*SigmaMSSquared*dsdzSquared*(1.+pow(x_k_minus[3],2));;
01830 
01831 
01832     // Treat steel as discrete scatter
01833     SwimGeo *spil = SwimGeo::Instance(*(const_cast<VldContext*>(vldc))); // Get edges of steel
01834     double z1 = spil->GetSteel(TrkStripData[Plane][0].ZPos,izdir)->GetZ();
01835     double z2 = spil->GetSteel(z1,izdir)->GetZ();
01836   
01837     double dzscatter = fabs(TrkStripData[NewPlane][0].ZPos-0.5*(z1+z2));
01838     double dzscatter2 = pow(dzscatter,2);
01839   
01840     UgliGeomHandle ugh(*vldc);
01841     BField bf(*vldc,-1,0);
01842     TVector3 uvz;
01843 
01844     uvz(0) = x_k_minus[0];
01845     uvz(1) = x_k_minus[1];
01846     uvz(2) = ugh.GetNearestSteelPlnHandle(TrkStripData[Plane][0].ZPos).GetZ0();
01847 
01848     TVector3 buvz = bf.GetBField(uvz, true);
01849     buvz[0] *= 0.3;
01850     buvz[1] *= 0.3;
01851     buvz[2] *= 0.3;
01852 
01853     
01854     double eloss = 0.038 * double(DeltaPlane);
01855     double sigmaeloss2 = 0.25*eloss*dsdz*qp*qp;
01856     sigmaeloss2 *= sigmaeloss2;
01857 
01858 
01859     // Fill elements of noise matrix
01860     Q_k_minus[0][0]=dzscatter2*Sigma33Squared;
01861     Q_k_minus[0][1]=dzscatter2*Sigma34Squared;
01862     Q_k_minus[0][2]=dzscatter*Sigma33Squared;
01863     Q_k_minus[0][3]=dzscatter*Sigma34Squared;
01864     Q_k_minus[0][4]=dzscatter*sigmaeloss2*double(DeltaPlane)*buvz(1)*0.0254*dsdz*(1.+pow(x_k_minus[2],2));
01865 
01866     Q_k_minus[1][0]=dzscatter2*Sigma34Squared;
01867     Q_k_minus[1][1]=dzscatter2*Sigma44Squared;
01868     Q_k_minus[1][2]=dzscatter*Sigma34Squared;
01869     Q_k_minus[1][3]=dzscatter*Sigma44Squared;
01870     Q_k_minus[1][4]=dzscatter*sigmaeloss2*double(DeltaPlane)*buvz(0)*0.0254*dsdz*(1.+pow(x_k_minus[3],2));
01871 
01872     Q_k_minus[2][0]=dzscatter*Sigma33Squared;
01873     Q_k_minus[2][1]=dzscatter*Sigma34Squared;
01874     Q_k_minus[2][2]=Sigma33Squared;
01875     Q_k_minus[2][3]=Sigma34Squared;
01876     Q_k_minus[2][4]=sigmaeloss2*double(DeltaPlane)*buvz(1)*0.0254*dsdz*(1.+pow(x_k_minus[2],2));
01877 
01878     Q_k_minus[3][0]=dzscatter*Sigma34Squared;
01879     Q_k_minus[3][1]=dzscatter*Sigma44Squared;
01880     Q_k_minus[3][2]=Sigma34Squared;
01881     Q_k_minus[3][3]=Sigma44Squared;
01882     Q_k_minus[3][4]=sigmaeloss2*double(DeltaPlane)*buvz(0)*0.0254*dsdz*(1.+pow(x_k_minus[3],2));
01883 
01884     Q_k_minus[4][0]=dzscatter*sigmaeloss2*double(DeltaPlane)*buvz(1)*0.0254*dsdz*(1.+pow(x_k_minus[2],2));
01885     Q_k_minus[4][1]=dzscatter*sigmaeloss2*double(DeltaPlane)*buvz(0)*0.0254*dsdz*(1.+pow(x_k_minus[3],2));
01886     Q_k_minus[4][2]=sigmaeloss2*double(DeltaPlane)*buvz(1)*0.0254*dsdz*(1.+pow(x_k_minus[2],2));
01887     Q_k_minus[4][3]=sigmaeloss2*double(DeltaPlane)*buvz(0)*0.0254*dsdz*(1.+pow(x_k_minus[3],2));
01888     Q_k_minus[4][4]=sigmaeloss2;
01889   }
01890  
01891 
01892   // Display
01893   if(debug) {
01894     cout << "1e6 * Q_k_minus" << endl;
01895     for(int i=0; i<5; ++i) {
01896       for(int j=0; j<5; ++j) {
01897         cout << 1e6*Q_k_minus[i][j] << " ";
01898       }
01899       cout << endl;
01900     }
01901   }
01902 
01903 }

void AlgFitTrackCam::GoBackwards  ) 
 

Definition at line 1261 of file AlgFitTrackCam.cxx.

References C_k, CalcKalmanGain(), EndCov, EndofRange, EndofRangePlane, ExtrapCovMatrix(), GetCombiPropagator(), GetNoiseMatrix(), H_k, LastIteration, MoveArrays(), MSG, NIter, PassTrack, StoreFilteredData(), TrkStripData, UpdateCovMatrix(), UpdateStateVector(), VtxCov, x_k, and ZIncreasesWithTime.

Referenced by RunTheFitter().

01262 { 
01263   // Carry out the Kalman fit along the track in the direction of decreasing z
01264   MSG("AlgFitTrackCam",Msg::kDebug) << "GoBackwards, carry out fit in negative z direction" << endl;
01265   Int_t StartPlane = MaxPlane; Int_t EndPlane=MinPlane;
01266   if(ZIncreasesWithTime){
01267     StartPlane = EndofRangePlane;
01268   }
01269   else EndofRangePlane = MinPlane;
01270  
01271   for (int i=StartPlane; i>=EndPlane; --i) {  
01272     if (TrkStripData[i].size()>0) {
01273       if (PassTrack) {
01274 
01275         //Find Prev Plane
01276         int NewPlane=-99;
01277         int k=(i-1);
01278         while (k>=MinPlane) {
01279           if (TrkStripData[k].size()>0) {NewPlane=k; break;}
01280           --k;
01281         }
01282         
01283         
01284         if (NewPlane!=-99) {
01285           // Define measurement function
01286           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;}
01287           
01288           MSG("AlgFitTrackCam",Msg::kVerbose) << "GoBackwards, Plane " << i << " ZPos " << TrkStripData[i][0].ZPos 
01289                                               << " PlaneView " << TrkStripData[i][0].PlaneView << endl
01290                                               << " NewPlane " << NewPlane << " NewZPos " << TrkStripData[NewPlane][0].ZPos 
01291                                               << " NewPlaneView " << TrkStripData[NewPlane][0].PlaneView << endl;
01292           
01293           bool CombiPropagatorOk=GetCombiPropagator(i,NewPlane,false);
01294           
01295           if(CombiPropagatorOk ) {
01296             GetNoiseMatrix(i,NewPlane);
01297             ExtrapCovMatrix();
01298             CalcKalmanGain(NewPlane);
01299             UpdateStateVector(i,NewPlane,false);
01300             UpdateCovMatrix();
01301             MoveArrays();
01302             if(SaveData) {StoreFilteredData(NewPlane);}
01303             MSG("AlgFitTrackCam",Msg::kVerbose) << "GoBackwards, Filtered q/p " << x_k[4] << endl;
01304           }
01305           else {PassTrack=false;}
01306         }
01307         
01308       }
01309       else {MSG("AlgFitTrackCam",Msg::kDebug) << "GoBackwards, Outside detector - track failed" << endl;}
01310     }
01311     //JAM end of range found
01312     if(EndofRange && LastIteration && !ZIncreasesWithTime){
01313       EndofRangePlane = i;
01314       break;
01315     }
01316 
01317   }
01318 
01319 
01320   // Store entries from covariance matrix for use in setting track properties
01321   if(NIter==2) {
01322     if(ZIncreasesWithTime==true) {
01323       VtxCov[0]=C_k[0][0]; VtxCov[1]=C_k[1][1];
01324       VtxCov[2]=C_k[2][2]; VtxCov[3]=C_k[3][3];
01325       VtxCov[4]=C_k[4][4];
01326     }
01327     else {
01328       EndCov[0]=C_k[0][0]; EndCov[1]=C_k[1][1];
01329       EndCov[2]=C_k[2][2]; EndCov[3]=C_k[3][3];
01330       EndCov[4]=C_k[4][4];
01331     }
01332   }
01333   
01334 }

void AlgFitTrackCam::GoForwards  ) 
 

Definition at line 1181 of file AlgFitTrackCam.cxx.

References C_k, CalcKalmanGain(), EndCov, EndofRange, EndofRangePlane, ExtrapCovMatrix(), GetCombiPropagator(), GetNoiseMatrix(), H_k, LastIteration, MoveArrays(), MSG, NIter, PassTrack, StoreFilteredData(), TrkStripData, UpdateCovMatrix(), UpdateStateVector(), VtxCov, x_k, and ZIncreasesWithTime.

Referenced by RunTheFitter().

01182 { 
01183   // Carry out the Kalman fit along the track in the direction of increasing z
01184   MSG("AlgFitTrackCam",Msg::kDebug) << "GoForwards, carry out fit in positive z direction" << endl;
01185 
01186   // JAM in 2nd iteration, stop when end of range is reached.
01187  
01188   Int_t StartPlane = MinPlane; Int_t EndPlane=MaxPlane;
01189   if(!ZIncreasesWithTime){
01190     StartPlane = EndofRangePlane;
01191   }
01192   else EndofRangePlane = MaxPlane;
01193 
01194   for (int i=StartPlane; i<=EndPlane; ++i) {
01195     EndofRange = false;
01196     if (TrkStripData[i].size()>0) {
01197       if (PassTrack) {
01198         // Find Next Plane
01199         int NewPlane=-99;
01200         int k=(i+1);
01201         while (k<=MaxPlane) {
01202           if (TrkStripData[k].size()>0) {NewPlane=k; break;}
01203           ++k;
01204         }
01205         if (NewPlane!=-99) {
01206           // Define measurement function
01207           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;}
01208           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;}
01209           
01210           MSG("AlgFitTrackCam",Msg::kVerbose) << "GoForwards, Plane " << i << " ZPos " << TrkStripData[i][0].ZPos 
01211                                               << " PlaneView " << TrkStripData[i][0].PlaneView << endl
01212                                               << " NewPlane " << NewPlane << " NewZPos " << TrkStripData[NewPlane][0].ZPos 
01213                                               << " NewPlaneView " << TrkStripData[NewPlane][0].PlaneView << endl;
01214           
01215           bool CombiPropagatorOk=GetCombiPropagator(i,NewPlane,true);
01216           
01217           if(CombiPropagatorOk ) {
01218             GetNoiseMatrix(i,NewPlane);
01219             ExtrapCovMatrix();
01220             CalcKalmanGain(NewPlane);
01221             UpdateStateVector(i,NewPlane,true);
01222             UpdateCovMatrix();
01223             MoveArrays();
01224             if(SaveData) {StoreFilteredData(NewPlane);}
01225             MSG("AlgFitTrackCam",Msg::kVerbose) << "GoForwards, Filtered q/p " << x_k[4] << endl;
01226           }
01227           else {PassTrack=false;}
01228         }
01229         
01230       }
01231       else {MSG("AlgFitTrackCam",Msg::kDebug) << "GoForwards, Outside of detector - track failed" << endl;}
01232     }
01233     //JAM end of range found
01234     if(EndofRange && LastIteration && ZIncreasesWithTime){
01235       EndofRangePlane=i;
01236       break;
01237     }
01238   }
01239 
01240 
01241   // Store entries from covariance matrix for use in setting track properties
01242   if(NIter==2) {
01243     if(ZIncreasesWithTime==true) {
01244       EndCov[0]=C_k[0][0]; EndCov[1]=C_k[1][1];
01245       EndCov[2]=C_k[2][2]; EndCov[3]=C_k[3][3];
01246       EndCov[4]=C_k[4][4];
01247     }
01248     else {
01249       VtxCov[0]=C_k[0][0]; VtxCov[1]=C_k[1][1];
01250       VtxCov[2]=C_k[2][2]; VtxCov[3]=C_k[3][3];
01251       VtxCov[4]=C_k[4][4];
01252     }
01253   }
01254 
01255 }

void AlgFitTrackCam::InitialFramework const CandSliceHandle slice,
CandContext cx
 

Definition at line 207 of file AlgFitTrackCam.cxx.

References StripStruct::csh, GenerateNDSpectStrips(), CandHandle::GetDaughterIterator(), VldContext::GetDetector(), CandStripHandle::GetPlane(), InitTrkStripData, MaxPlane, MeanTrackTime, MinPlane, NDStripBegTime(), NumFinderStrips, SlcStripData, track, and vldc.

Referenced by RunAlg().

00208 {
00209   // Store CandStripHandles and make the strips accessible by plane number
00210   Detector::Detector_t detector = vldc->GetDetector();
00211 
00212   TIter SlcStripItr = slice->GetDaughterIterator();
00213   TIter TrkStripItr = track->GetDaughterIterator();
00214 
00215   
00216   // Store all strips in slice
00217   int SlicePlane; 
00218 
00219   while(CandStripHandle* SlcStrip = dynamic_cast<CandStripHandle*>(SlcStripItr()))
00220     {
00221       SlicePlane=SlcStrip->GetPlane();
00222       if(detector==Detector::kNear && SlicePlane>=121) {continue;}
00223 
00224       StripStruct temp;
00225       temp.csh=SlcStrip;
00226      
00227       SlcStripData[SlicePlane].push_back(temp);
00228     }
00229   SlcStripItr.Reset();
00230 
00231 
00232   // Store all track strips found, except those in the Near Spectrometer
00233   int TrackPlane; 
00234   MeanTrackTime=0;
00235 
00236   while(CandStripHandle* TrkStrip = dynamic_cast<CandStripHandle*>(TrkStripItr()))
00237     {    
00238       TrackPlane=TrkStrip->GetPlane();
00239       if(detector==Detector::kNear && TrackPlane>=121) {continue;}
00240 
00241       StripStruct temp;
00242       temp.csh=TrkStrip;
00243 
00244       InitTrkStripData[TrackPlane].push_back(temp);
00245       NumFinderStrips++;
00246       
00247       // Identify ends of initial track
00248       if (TrackPlane>MaxPlane) {MaxPlane=TrackPlane;}
00249       if (TrackPlane<MinPlane) {MinPlane=TrackPlane;}
00250 
00251       if(detector==Detector::kNear) {MeanTrackTime+=NDStripBegTime(TrkStrip);}
00252     }
00253   TrkStripItr.Reset();
00254 
00255   // For DeMuxing ND Spectrometer
00256   if(detector==Detector::kNear) {
00257     if(NumFinderStrips!=0) {MeanTrackTime/=double(NumFinderStrips);}
00258     GenerateNDSpectStrips(slice,cx);
00259   }
00260 
00261 
00262 } 

void AlgFitTrackCam::MoveArrays  ) 
 

Definition at line 2170 of file AlgFitTrackCam.cxx.

References C_k, C_k_minus, MSG, x_k, and x_k_minus.

Referenced by GoBackwards(), GoForwards(), ShowerSwim(), and SpectrometerSwim().

02171 {
02172   // Move k to k-1 ready to consider next hit
02173   MSG("AlgFitTrackCam",Msg::kDebug) << "MoveArrays" << endl;
02174 
02175   for (int i=0; i<5; ++i) {
02176     for (int j=0; j<5; ++j) { 
02177       C_k_minus[i][j]=C_k[i][j];
02178     }
02179   }
02180   
02181   for (int l=0; l<5; ++l) {
02182     x_k_minus[l]=x_k[l];
02183   }
02184 }

bool AlgFitTrackCam::NDPlaneIsActive int  plane,
float  u,
float  v,
float  projErr
 

Definition at line 3383 of file AlgFitTrackCam.cxx.

References PlaneOutline::DistanceToEdge(), fPL, PlexPlaneId::GetPlaneCoverage(), PlexPlaneId::GetPlaneView(), PlaneOutline::IsInside(), and PlexPlaneId::IsValid().

Referenced by SpectrometerSwim().

03384 { 
03385   // Method to determine whether this u/v position is active
03386 
03387   PlexPlaneId plexPlane(Detector::kNear,plane, 0); 
03388   if(!plexPlane.IsValid()) {return false;}
03389   if(plexPlane.GetPlaneCoverage()==PlaneCoverage::kNoActive) {return false;}
03390   if(projErr<0.3)projErr=0.3;
03391   float x = 0.707*(u-v);
03392   float y = 0.707*(u+v);
03393   float dist,xedge,yedge;
03394   fPL.DistanceToEdge(x, y,
03395                      plexPlane.GetPlaneView(),
03396                      plexPlane.GetPlaneCoverage(),
03397                      dist, xedge, yedge);
03398   bool isInside = fPL.IsInside(x, y,
03399                                plexPlane.GetPlaneView(),
03400                                plexPlane.GetPlaneCoverage());
03401   isInside &= dist>projErr;
03402 
03403   return isInside;
03404 }

double AlgFitTrackCam::NDStripBegTime CandStripHandle Strip,
double  U = 0,
double  V = 0
 

Definition at line 3594 of file AlgFitTrackCam.cxx.

References BegTime, UgliStripHandle::ClearFiber(), digit(), CandHandle::GetDaughterIterator(), PlexSEIdAltL::GetEnd(), UgliStripHandle::GetHalfLength(), CandStripHandle::GetPlane(), CandStripHandle::GetPlaneView(), CandDigitHandle::GetPlexSEIdAltL(), CandStripHandle::GetStripEndId(), UgliGeomHandle::GetStripHandle(), CandDigitHandle::GetSubtractedTime(), CandTrackHandle::GetU(), CandTrackHandle::GetV(), track, vldc, and UgliStripHandle::WlsPigtail().

Referenced by InitialFramework(), and SpectrometerSwim().

03595 {
03596   double BegTime=999; double Time=0;
03597   double Index=1.77; double DistFromCentre=0.; 
03598   double FibreDist=0.; double halfLength=0.;
03599 
03600   // Get from track. Otherwise, will have guessed using Swimmer
03601   if(U==0) {U=track->GetU(Strip->GetPlane());}
03602   if(V==0) {V=track->GetV(Strip->GetPlane());}
03603 
03604   StripEnd::StripEnd_t StpEnd = StripEnd::kUnknown;
03605   CandDigitHandle* digit;
03606   
03607   UgliGeomHandle ugh = UgliGeomHandle(*vldc);
03608   UgliStripHandle Striphandle;
03609 
03610   CandDigitHandleItr digitItr(Strip->GetDaughterIterator());
03611 
03612 
03613   // Loop over digits on Strip. 
03615   while( (digit = digitItr()) ) { 
03616     StpEnd=digit->GetPlexSEIdAltL().GetEnd();
03617     
03618     if(StpEnd==StripEnd::kPositive) {
03619       FibreDist = 0.; DistFromCentre = 0.; Time=0.;
03620       UgliStripHandle StripHandle = ugh.GetStripHandle(Strip->GetStripEndId());
03621       halfLength = StripHandle.GetHalfLength(); 
03622       
03623       if(Strip->GetPlaneView()==2) {DistFromCentre = V;}
03624       if(Strip->GetPlaneView()==3) {DistFromCentre = -U;}
03625               
03626       FibreDist = (halfLength + DistFromCentre + StripHandle.ClearFiber(StpEnd) 
03627                    + StripHandle.WlsPigtail(StpEnd));
03628       
03629       Time = digit->GetSubtractedTime(CalTimeType::kT0) - (Index/3.e8)*FibreDist;
03630 
03631       if(Time<BegTime) {BegTime=Time;}
03632     }
03633   }
03634   
03635   return BegTime;
03636 }

void AlgFitTrackCam::RemoveTrkHitsInShw  ) 
 

Definition at line 547 of file AlgFitTrackCam.cxx.

References MaxPlane, MinPlane, MSG, SwimThroughShower, TrkStripData, and ZIncreasesWithTime.

Referenced by RunTheFitter().

00548 {
00549   // If the 'clean' section of track is large enough, remove the track finding
00550   // data for planes before the ShowerEntryPlane
00551   MSG("AlgFitTrackCam",Msg::kDebug) << "RemoveTrkHitsInShw, Discard track finding data in shower" << endl;
00552 
00553   int NumTrackStripsLeft=0;
00554   
00555   if(ZIncreasesWithTime==true) {
00556     for(int i=ShowerEntryPlane; i<=MaxPlane; ++i) {
00557       if(TrkStripData[i].size()>0) {NumTrackStripsLeft++;}
00558     }
00559   }
00560   else if(ZIncreasesWithTime==false) {
00561     for(int i=MinPlane; i<=ShowerEntryPlane; ++i) {
00562       if(TrkStripData[i].size()>0) {NumTrackStripsLeft++;}
00563     }
00564   }
00565   
00566   // Carry out removal if there will be 6 or more strips left afterwards
00567   if(NumTrackStripsLeft>5) { 
00568     if(ZIncreasesWithTime==true) {
00569       for(int i=MinPlane; i<=ShowerEntryPlane; ++i) {TrkStripData[i].clear();}
00570     }   
00571     else if(ZIncreasesWithTime==false) {
00572       for(int i=ShowerEntryPlane; i<=MaxPlane; ++i) {TrkStripData[i].clear();    }
00573     }
00574   } 
00575   // Otherwise note that we should not run the ShowerSwim method
00576   else {
00577     MSG("AlgFitTrackCam",Msg::kDebug) << "RemoveTrkHitsInShw, not enough hits after removal. Must use all finder data." << endl;
00578     SwimThroughShower=false;
00579   }
00580   
00581   
00582   // Find the new max and min planes
00583   MaxPlane=-20; MinPlane=500;
00584   for (int i=0; i<490; ++i) {   
00585     if(TrkStripData[i].size()>0) {
00586       if(i>MaxPlane) {MaxPlane=i;}
00587       if(i<MinPlane) {MinPlane=i;}
00588     }
00589   }
00590   
00591 }

void AlgFitTrackCam::ResetCovarianceMatrix  ) 
 

Definition at line 1712 of file AlgFitTrackCam.cxx.

References DeltaPlane, DeltaZ, and GetInitialCovarianceMatrix().

Referenced by RunTheFitter().

01713 {
01714   // Simple method reset variables/arrays to allow propagation again
01715 
01716   DeltaPlane=0; DeltaZ=0; 
01717   GetInitialCovarianceMatrix(false);
01718 }

void AlgFitTrackCam::RunAlg AlgConfig ac,
CandHandle ch,
CandContext cx
[virtual]
 

Implements AlgBase.

Definition at line 85 of file AlgFitTrackCam.cxx.

References bave, C_k, C_k_intermediate, C_k_minus, CleanNDLists(), debug, DeltaPlane, DeltaZ, EndCov, F_k, F_k_minus, FilteredData, Registry::Get(), CandRecord::GetCandHeader(), CandContext::GetCandRecord(), CandRecoHandle::GetCandSlice(), CandContext::GetDataIn(), CandHandle::GetDaughterIterator(), VldContext::GetDetector(), CandRecoHandle::GetEndZ(), GetFitData(), CandHandle::GetNDaughters(), CandHeader::GetRun(), CandHeader::GetSnarl(), RecMinos::GetVldContext(), CandRecoHandle::GetVtxDirCosU(), CandRecoHandle::GetVtxDirCosV(), CandRecoHandle::GetVtxDirCosZ(), CandRecoHandle::GetVtxU(), CandRecoHandle::GetVtxV(), CandRecoHandle::GetVtxZ(), H_k, Identity, InitialFramework(), InitTrkStripData, K_k, MaxPlane, MinPlane, MSG, nbfield, NIter, NumFinderStrips, PassTrack, Q_k, Q_k_minus, CandHandle::RemoveDaughter(), RunTheFitter(), SaveData, CandRecoHandle::SetCandSlice(), CandFitTrackHandle::SetFinderTrack(), ShowerEntryPlane, SlcStripData, SwimThroughShower, TotalNSwimFail, track, TrkStripData, UseGeoSwimmer, vldc, VtxCov, x_k, x_k4_biased, x_k_minus, and ZIncreasesWithTime.

00087 {
00088   // get alg parameters
00089   if(!ac.Get("UseGeoSwimmer",UseGeoSwimmer)) cout << "Couldn't Get\n";
00090 
00091  // Standard set-up
00092 
00093   assert(ch.InheritsFrom("CandFitTrackCamHandle"));
00094   CandFitTrackCamHandle &cth = dynamic_cast<CandFitTrackCamHandle &>(ch);
00095   
00096   nbfield=0;
00097   bave=0;
00098   TIter FitTrackStripItr = cth.GetDaughterIterator();
00099   while(CandStripHandle* FitTrackStrip = dynamic_cast<CandStripHandle*>(FitTrackStripItr())) cth.RemoveDaughter(FitTrackStrip);
00100   
00101   assert(cx.GetDataIn());
00102   
00103   // Get the track from the track finder
00104   assert(cx.GetDataIn()->InheritsFrom("CandTrackHandle"));
00105   track = dynamic_cast<const CandTrackHandle*>(cx.GetDataIn());
00106   if( !track || track->GetNDaughters()<1 )  { return; }
00107   cth.SetFinderTrack((CandTrackHandle*)(track));
00108   
00109   const CandSliceHandle* slice = dynamic_cast<const CandSliceHandle*>(track->GetCandSlice());
00110   assert(slice);
00111   cth.SetCandSlice(slice);
00112   
00113   
00115   // Track fitter //
00117   // Switch for screen output
00118   debug=false;
00119   
00120   // Initialisations
00122   if( track->GetEndZ() > track->GetVtxZ() )  {ZIncreasesWithTime=true;}
00123   else {ZIncreasesWithTime=false;}
00124   
00125   SaveData=false;
00126   SwimThroughShower=false;
00127   PassTrack=true;
00128   
00129   MaxPlane=-20;
00130   MinPlane=500;
00131 
00132   DeltaZ=-99;
00133   DeltaPlane=-99;
00134   ShowerEntryPlane=-99;
00135   
00136   NIter=0; TotalNSwimFail=0; NumFinderStrips=0;
00137   
00138   for (unsigned int i=0; i<5; ++i) {
00139     x_k[i]=0; x_k_minus[i]=0; H_k[i]=0; K_k[i]=0;
00140     VtxCov[i]=-999; EndCov[i]=-999;
00141     for (unsigned int j=0; j<5; ++j) {
00142       C_k[i][j]=0; C_k_minus[i][j]=0; C_k_intermediate[i][j]=0;
00143       F_k[i][j]=0; F_k_minus[i][j]=0;
00144       Q_k[i][j]=0; Q_k_minus[i][j]=0;
00145       Identity[i][j]=0;
00146     }
00147   }
00148   
00149   Identity[0][0]=1; Identity[1][1]=1; Identity[2][2]=1; Identity[3][3]=1; Identity[4][4]=1; 
00151   
00152   
00153   // Set initial parameters
00155   x_k_minus[0]=track->GetVtxU();
00156   x_k_minus[1]=track->GetVtxV();
00157   if(track->GetVtxDirCosZ()!=0.) {
00158     x_k_minus[2]=track->GetVtxDirCosU()/track->GetVtxDirCosZ();
00159     x_k_minus[3]=track->GetVtxDirCosV()/track->GetVtxDirCosZ();
00160   }
00161   x_k_minus[4]=0.;
00162   x_k4_biased=0;
00164   
00165   
00166   // Get header information
00168   CandRecord* candrec = (CandRecord*)(cx.GetCandRecord());
00169   assert(candrec);
00170   
00171   vldc = (VldContext*)(candrec->GetVldContext());
00172   assert(vldc);
00173   
00174   CandHeader* candhead = (CandHeader*)(candrec->GetCandHeader());
00175   assert(candhead);
00176   
00177   MSG("AlgFitTrackCam",Msg::kDebug) << "RunAlg, New track, Run: " << candhead->GetRun() 
00178                                     << " Snarl: " << candhead->GetSnarl() << endl;
00180   
00181   
00182   // Run the high level methods
00184   InitialFramework(slice,cx);
00185   GetFitData(MinPlane,MaxPlane);
00186   RunTheFitter(cth);
00188   
00189   
00190   // Clear up
00192   if(vldc->GetDetector()==Detector::kNear) {CleanNDLists(cth,cx);}
00193   
00194   for (unsigned int i=0; i<490; ++i) {
00195     InitTrkStripData[i].clear();
00196     SlcStripData[i].clear();
00197     TrkStripData[i].clear();
00198     FilteredData[i].clear();
00199   }
00201 }

void AlgFitTrackCam::RunTheFitter CandFitTrackCamHandle cth  ) 
 

Definition at line 364 of file AlgFitTrackCam.cxx.

References CandHandle::AddDaughterLink(), FillGapsInTrack(), FilteredData, FindTheStrips(), CandHandle::GetDaughterIterator(), VldContext::GetDetector(), GetFitData(), GetInitialCovarianceMatrix(), CandStripHandle::GetPlaneView(), GoBackwards(), GoForwards(), LastIteration, MaxPlane, MinPlane, MSG, NIter, PassTrack, CandHandle::RemoveDaughter(), RemoveTrkHitsInShw(), ResetCovarianceMatrix(), SaveData, CandFitTrackHandle::SetEMCharge(), CandFitTrackHandle::SetMomentumCurve(), CandFitTrackHandle::SetPass(), SetPropertiesFromFinderTrack(), SetTrackProperties(), CandFitTrackHandle::SetVtxQPError(), ShowerStrips(), ShowerSwim(), SpectrometerSwim(), StoreFilteredData(), SwimThroughShower, track, TrkStripData, vldc, x_k, x_k4_biased, and ZIncreasesWithTime.

Referenced by RunAlg().

00365 {
00366   MSG("AlgFitTrackCam",Msg::kDebug) << "RunTheFitter, Call methods in the appropriate order" << endl;
00367   GetInitialCovarianceMatrix(true);
00368   
00369   
00370   // Control the iterations backwards and forwards
00372   Detector::Detector_t detector = vldc->GetDetector();
00373 
00374   // Control iterations over a track for which ZIncreasesWithTime
00375   if(ZIncreasesWithTime==true)
00376     {
00377       // First iteration
00378       NIter++;
00379   
00380       // Vtx to End
00381 
00382       SaveData=true; StoreFilteredData(MinPlane); 
00383       LastIteration=false;
00384       GoForwards(); ResetCovarianceMatrix();
00385       
00386 
00387       // End back to vtx, swimming through any large vtx shower
00388       ShowerStrips();  // Try to identify vtx showers, now we have an idea of gradient
00389       if(SwimThroughShower==true) {RemoveTrkHitsInShw();}
00390       
00391       for (unsigned int i=0; i<490; ++i) {FilteredData[i].clear();}
00392       StoreFilteredData(MaxPlane); GoBackwards();
00393       
00394       if(SwimThroughShower==true) {ShowerSwim();}
00395       ResetCovarianceMatrix();
00396 
00397       bool StripsFound = FindTheStrips(cth,false);
00398       
00399       // Second iteration
00400       if(StripsFound==true) { // Guard against finding no strips
00401         for(int nint=0;nint<=1;nint++){  
00402           NIter++;
00403           if(nint==1)LastIteration = true;        
00404           // Vtx to End again, identifying any strips in ND spectrometer
00405           for (unsigned int i=0; i<490; ++i) {TrkStripData[i].clear();} 
00406           GetFitData(MinPlane,MaxPlane);        
00407           SaveData=false; GoForwards();
00408           
00409           if(detector==Detector::kNear && nint==0) {SpectrometerSwim(cth);}
00410           ResetCovarianceMatrix();
00411           
00412           // End back to vtx again
00413           for (unsigned int i=0; i<490; ++i) {FilteredData[i].clear();}
00414           if(nint==1) SaveData=true;  
00415           StoreFilteredData(MaxPlane);    
00416           GoBackwards();    ResetCovarianceMatrix();
00417           if(nint==0) x_k4_biased= x_k[4];
00418         }
00419       }
00420       else {PassTrack=false;}
00421     }
00422   
00423   
00424   // Control iterations over a track for which ZDecreasesWithTime
00425   else
00426     {
00427       // First iteration
00428       NIter++;
00429 
00430       // Vtx to End
00431       SaveData=true; StoreFilteredData(MaxPlane); 
00432       LastIteration=false;
00433 
00434       GoBackwards(); ResetCovarianceMatrix();
00435  
00436       // End back to vtx, swimming through any large vtx shower and
00437       // identifying any strips in ND spectrometer
00438       ShowerStrips();  // Try to identify vtx showers, now we have an idea of gradient
00439       if(SwimThroughShower==true) {RemoveTrkHitsInShw();}
00440 
00441       for (unsigned int i=0; i<490; ++i) {FilteredData[i].clear();}
00442       StoreFilteredData(MinPlane); GoForwards();
00443 
00444       if(SwimThroughShower==true) {ShowerSwim();}
00445 
00446       if(detector==Detector::kNear) {SpectrometerSwim(cth);}
00447       ResetCovarianceMatrix();
00448 
00449       bool StripsFound = FindTheStrips(cth,false);
00450 
00451       // Second iteration
00452       if(StripsFound==true) { // Guard against finding no strips
00453         for(int nint=0;nint<=1;nint++){  
00454           if(nint==1)LastIteration = true;                
00455           NIter++;
00456           // Vtx to End again
00457           for (unsigned int i=0; i<490; ++i) {TrkStripData[i].clear();} 
00458           GetFitData(MinPlane,MaxPlane);          
00459           SaveData=false; GoBackwards(); ResetCovarianceMatrix();
00460           
00461           // End to Vtx again
00462           for (unsigned int i=0; i<490; ++i) {FilteredData[i].clear();}
00463           if(nint==1)SaveData=true;  
00464           StoreFilteredData(MinPlane);
00465           GoForwards(); ResetCovarianceMatrix();
00466           if(nint==0) x_k4_biased= x_k[4];
00467         }
00468       }
00469       else {PassTrack=false;}
00470     }
00472   
00473   
00474 
00475   // Organise the output
00477 
00478   // If the fit was successful
00479   if(x_k[4]!=0. && PassTrack==true) {
00480         
00481     //JAM modify tweak following range bias removal
00482     // Tweak q/p to remove offset
00483     //    x_k[4]*=1.01+(0.1*fabs(x_k[4]));
00484 
00485     x_k4_biased *=1.01+(0.1*fabs(x_k[4]));
00486     x_k[4] *=1.013;
00487 
00488     // Find final strips and add them to the fitted track
00489     FillGapsInTrack();
00490     bool FinalStripsFound = FindTheStrips(cth,true);
00491     
00492     // If final strips found, set the fitted track properties
00493     if(FinalStripsFound==true) {
00494 
00495       // Check there is >1 strip in each view. If not, then fail track.
00496       int NumInUView=0; int NumInVView=0;
00497       
00498       TIter FitTrackStripItr = cth.GetDaughterIterator();
00499       while(CandStripHandle* FitTrackStrip = dynamic_cast<CandStripHandle*>(FitTrackStripItr()))
00500         {
00501           if(FitTrackStrip->GetPlaneView()==2) {NumInUView++;}
00502           else if(FitTrackStrip->GetPlaneView()==3) {NumInVView++;}
00503           
00504           if(NumInUView>1 && NumInVView>1) {break;}
00505         }
00506       
00507       if(NumInUView>1 && NumInVView>1) {
00508         cth.SetPass(1);
00509         SetTrackProperties(cth);
00510       }
00511       else {PassTrack=false;}
00512       
00513     }
00514     // Otherwise fail the track at this final stage
00515     else {PassTrack=false;}
00516   }
00517   
00518   
00519   // If the fit has failed (e.g. q/p is zero and/or u, v are nonsense)
00520   if(x_k[4]==0. || PassTrack==false) {
00521  
00522     // Remove any existing strips in the failed fitted track
00523     vector<CandStripHandle*> Daughters;
00524 
00525     TIter FitTrackStripItr = cth.GetDaughterIterator();
00526     while(CandStripHandle* FitTrackStrip = dynamic_cast<CandStripHandle*>(FitTrackStripItr()))
00527       {Daughters.push_back(FitTrackStrip);}
00528 
00529     for(unsigned int i=0; i<Daughters.size(); ++i) {cth.RemoveDaughter(Daughters[i]);}
00530     Daughters.clear();
00531 
00532 
00533     // Put strips from track finder in failed fitted track
00534     TIter TrkStripItr = track->GetDaughterIterator();
00535     while(CandStripHandle* TrkStrip = dynamic_cast<CandStripHandle*>(TrkStripItr()))
00536       {cth.AddDaughterLink(*TrkStrip);}
00537     
00538     // Set position/direction properties using the finder track
00539     cth.SetPass(0); 
00540     cth.SetMomentumCurve(0.); cth.SetEMCharge(0); cth.SetVtxQPError(-999.);
00541     SetPropertiesFromFinderTrack(cth);
00542   }
00544 }  

void AlgFitTrackCam::SetPropertiesFromFinderTrack CandFitTrackCamHandle cth  ) 
 

Definition at line 3043 of file AlgFitTrackCam.cxx.

References AlgTrack::CalculateTrace(), AlgReco::Calibrate(), CandRecoHandle::GetDirCosU(), CandRecoHandle::GetDirCosV(), CandRecoHandle::GetDirCosZ(), CandTrackHandle::GetdS(), CandRecoHandle::GetEndDirCosU(), CandRecoHandle::GetEndDirCosV(), CandRecoHandle::GetEndDirCosZ(), CandRecoHandle::GetEndPlane(), CandRecoHandle::GetEndT(), CandRecoHandle::GetEndU(), CandRecoHandle::GetEndV(), CandRecoHandle::GetEndZ(), CandTrackHandle::GetMomentum(), CandTrackHandle::GetNTimeFitDigit(), CandTrackHandle::GetRange(), CandTrackHandle::GetTimeBackwardFitNDOF(), CandTrackHandle::GetTimeBackwardFitRMS(), CandTrackHandle::GetTimeFitChi2(), CandTrackHandle::GetTimeForwardFitNDOF(), CandTrackHandle::GetTimeForwardFitRMS(), CandRecoHandle::GetTimeOffset(), CandRecoHandle::GetTimeSlope(), CandTrackHandle::GetTrackPointError(), CandTrackHandle::GetU(), CandTrackHandle::GetV(), CandRecoHandle::GetVtxPlane(), CandRecoHandle::GetVtxT(), CandRecoHandle::GetVtxU(), CandRecoHandle::GetVtxV(), CandRecoHandle::GetVtxZ(), Calibrator::Instance(), CandTrackHandle::IsTPosValid(), MSG, Calibrator::ReInitialise(), CandRecoHandle::SetDirCosU(), CandRecoHandle::SetDirCosV(), CandRecoHandle::SetDirCosZ(), CandTrackHandle::SetdS(), CandRecoHandle::SetEndDirCosU(), CandRecoHandle::SetEndDirCosV(), CandRecoHandle::SetEndDirCosZ(), CandRecoHandle::SetEndPlane(), CandRecoHandle::SetEndT(), CandRecoHandle::SetEndU(), CandRecoHandle::SetEndV(), CandRecoHandle::SetEndZ(), CandTrackHandle::SetMomentum(), CandFitTrackHandle::SetMomentumRange(), CandTrackHandle::SetNTimeFitDigit(), CandTrackHandle::SetRange(), AlgTrack::SetT(), CandTrackHandle::SetTimeBackwardFitNDOF(), CandTrackHandle::SetTimeBackwardFitRMS(), CandTrackHandle::SetTimeFitChi2(), CandTrackHandle::SetTimeForwardFitNDOF(), CandTrackHandle::SetTimeForwardFitRMS(), CandRecoHandle::SetTimeOffset(), CandRecoHandle::SetTimeSlope(), CandTrackHandle::SetTrackPointError(), CandTrackHandle::SetU(), CandTrackHandle::SetV(), CandRecoHandle::SetVtxPlane(), CandRecoHandle::SetVtxT(), CandRecoHandle::SetVtxU(), CandRecoHandle::SetVtxV(), CandRecoHandle::SetVtxZ(), track, vldc, and ZIncreasesWithTime.

Referenced by RunTheFitter().

03044 {
03045   // This method is only called if the fit fails. We set properties from finder track.
03046   // This clearly does not include fitted properties such as q/p or QPVtxError.
03047  MSG("AlgFitTrackCam",Msg::kDebug) << "SetPropertiesFromFinderTrack" << endl;
03048   cth.SetDirCosU(track->GetDirCosU());
03049   cth.SetDirCosV(track->GetDirCosV());
03050   cth.SetDirCosZ(track->GetDirCosZ());
03051   cth.SetVtxU(track->GetVtxU());
03052   cth.SetVtxV(track->GetVtxV());
03053   cth.SetVtxZ(track->GetVtxZ());
03054   cth.SetVtxT(track->GetVtxT());
03055   cth.SetVtxPlane(track->GetVtxPlane());
03056 
03057   cth.SetEndDirCosU(track->GetEndDirCosU());
03058   cth.SetEndDirCosV(track->GetEndDirCosV());
03059   cth.SetEndDirCosZ(track->GetEndDirCosZ());
03060   cth.SetEndU(track->GetEndU());
03061   cth.SetEndV(track->GetEndV());
03062   cth.SetEndZ(track->GetEndZ());
03063   cth.SetEndT(track->GetEndT());
03064   cth.SetEndPlane(track->GetEndPlane());
03065 
03066   cth.SetMomentumRange(track->GetMomentum());
03067   cth.SetMomentum(track->GetMomentum());
03068 
03069   cth.SetTimeSlope(track->GetTimeSlope());
03070   cth.SetTimeOffset(track->GetTimeOffset());
03071   cth.SetTimeFitChi2(track->GetTimeFitChi2());
03072   cth.SetNTimeFitDigit(track->GetNTimeFitDigit());
03073   cth.SetTimeForwardFitRMS(track->GetTimeForwardFitRMS());
03074   cth.SetTimeForwardFitNDOF(track->GetTimeForwardFitNDOF());
03075   cth.SetTimeBackwardFitRMS(track->GetTimeBackwardFitRMS());
03076   cth.SetTimeBackwardFitNDOF(track->GetTimeBackwardFitNDOF());
03077 
03078 
03079   // Set quantities required at each plane in finder track
03080   int direction=1;
03081   if(ZIncreasesWithTime==false) {direction=-1;}
03082 
03083   for(int i=cth.GetVtxPlane(); i*direction<=cth.GetEndPlane()*direction; i+=direction){
03084     if(track->IsTPosValid(i)) {
03085       cth.SetTrackPointError(i,track->GetTrackPointError(i));
03086       cth.SetdS(i,track->GetdS(i));
03087       cth.SetRange(i,track->GetRange(i));
03088       cth.SetU(i,track->GetU(i));
03089       cth.SetV(i,track->GetV(i));
03090     }
03091   }
03092 
03093   CalculateTrace(cth);  
03094   SetT(&cth);
03095 
03096   Calibrator& cal = Calibrator::Instance();
03097   cal.ReInitialise(*vldc);
03098   Calibrate(&cth);
03099 
03100 
03101 }

void AlgFitTrackCam::SetRangeAnddS CandFitTrackCamHandle cth  ) 
 

Definition at line 2779 of file AlgFitTrackCam.cxx.

References abs(), done(), FilteredData, fPL, PlexPlaneId::GetAdjoinScint(), PlexPlaneId::GetAdjoinSteel(), VldContext::GetDetector(), CandFitTrackHandle::GetFinderTrack(), UgliSteelPlnHandle::GetHalfThickness(), UgliPlnHandle::GetHalfThickness(), CandTrackHandle::GetMomentum(), PlexPlaneId::GetPlaneView(), UgliGeomHandle::GetScintPlnHandle(), VldContext::GetSimFlag(), UgliGeomHandle::GetSteelPlnHandle(), UgliSteelPlnHandle::GetZ0(), UgliPlnHandle::GetZ0(), UgliGeomHandle::GetZExtent(), PlaneOutline::IsInside(), PlexPlaneId::IsValid(), UgliScintPlnHandle::IsValid(), MSG, pow(), CandTrackHandle::SetdS(), CandFitTrackHandle::SetMomentumRange(), CandTrackHandle::SetRange(), SlcStripData, Swim(), vldc, and ZIncreasesWithTime.

Referenced by SetTrackProperties().

02780 {
02781 
02782   // Set range and dS as calculated by the swimmer
02783   MSG("AlgFitTrackCam",Msg::kDebug) << "SetRangeAnddS from swimmer values " << endl;
02784 
02785   UgliGeomHandle ugh = UgliGeomHandle(*vldc);
02786 
02787   int ZDir; int VtxPlane; int EndPlane; int Increment;
02788   Detector::Detector_t detector = vldc->GetDetector();
02789   double dS; double dRange; double dP;
02790 
02791 
02792   // Start at the end of the track and calculate the required additions to range
02794 
02795   // find ending Z position (defined as Z position where muon has 100 MeV of residual energy.  This corresponds to 1/2 inch of Fe.
02796 
02797   // NOTE: Average dP for 1" iron is 95 MeV.
02798  
02799   if(ZIncreasesWithTime==true) {ZDir=1; EndPlane=MaxPlane; VtxPlane=MinPlane; Increment=-1;}
02800   else {ZDir=-1; EndPlane=MinPlane; VtxPlane=MaxPlane; Increment=1;}
02801 
02802   PlexPlaneId plnid(detector,EndPlane,false);
02803   PlexPlaneId endplnid(detector,EndPlane,false);
02804 
02805   double Zscint = SlcStripData[EndPlane][0].csh->GetZPos();
02806   double Znextscint = Zscint;
02807 
02808   UgliScintPlnHandle scintpln = ugh.GetScintPlnHandle(plnid); 
02809   double Zend = Zscint + double(ZDir)*scintpln.GetHalfThickness();
02810 
02811   PlexPlaneId nextscint =  endplnid.GetAdjoinScint(ZDir);
02812   UgliScintPlnHandle nextscintpln = ugh.GetScintPlnHandle(nextscint);
02813   if(nextscintpln.IsValid() && nextscint.GetPlaneView()!=PlaneView::kUnknown){
02814     Znextscint = nextscintpln.GetZ0();
02815   }
02816   else{
02817     nextscint = endplnid;
02818   }
02819 
02820   plnid = plnid.GetAdjoinSteel(ZDir);
02821   if(plnid.IsValid()){
02822     UgliSteelPlnHandle steelpln = ugh.GetSteelPlnHandle(plnid);
02823     Zend = steelpln.GetZ0() - double(ZDir)*steelpln.GetHalfThickness();
02824   }
02825 
02826   // add two planes of steel for the ND spectrometer
02827   if(detector==Detector::kNear && EndPlane>=121) {
02828     for(int i=0;i<2;i++){
02829       if(plnid.GetAdjoinSteel(ZDir).IsValid()){
02830         PlexPlaneId plnid_after = plnid.GetAdjoinSteel(ZDir);
02831         if(plnid_after.IsValid()) {
02832           plnid = plnid_after;
02833           UgliSteelPlnHandle steelpln = ugh.GetSteelPlnHandle(plnid);
02834           Zend = steelpln.GetZ0() - double(ZDir)*steelpln.GetHalfThickness();
02835         }
02836       }
02837     }
02838   }
02839 
02840   // Determine whether track stops in coil
02841   float u_end = FilteredData[EndPlane][0].x_k0;
02842   float v_end = FilteredData[EndPlane][0].x_k1;
02843   float du_end = FilteredData[EndPlane][0].x_k2;
02844   float dv_end = FilteredData[EndPlane][0].x_k3;
02845   float delz = Znextscint-Zscint;
02846   float u_extrap = u_end +delz*du_end;
02847   float v_extrap = v_end +delz*dv_end;
02848   float x_extrap = 0.707*(u_extrap-v_extrap);
02849   float y_extrap = 0.707*(u_extrap+v_extrap);
02850 
02851   PlaneCoverage::PlaneCoverage_t kPC = PlaneCoverage::kComplete;
02852   if(detector==Detector::kNear) kPC=PlaneCoverage::kNearFull;
02853 
02854   bool isInOutline = fPL.IsInside(x_extrap,y_extrap,nextscint.GetPlaneView(),kPC,false);
02855   bool isInCoil = isInOutline && !fPL.IsInside(x_extrap,y_extrap,nextscint.GetPlaneView(),kPC,true);
02856 
02857   double S = 0; double Range = 0; double Prange = 0.0;
02858   double StateVector[5]; double Output[5];
02859   double chargesign = -1;
02860   bool GoForward = true; bool done=true; bool swimOK=true;
02861 
02862   // if in coil find midpoint and swim towards last hit from there
02863   if(isInCoil){
02864     float zCoil = Znextscint;
02865     float u_extrapC = u_extrap;
02866     float v_extrapC = v_extrap;
02867     float x_extrapC = x_extrap;
02868     float y_extrapC = y_extrap;
02869     while(isInCoil){
02870       zCoil -= 1.0*Munits::cm*ZDir;
02871       float delzC = zCoil - Zscint;
02872       u_extrapC = u_end +delzC*du_end;
02873       v_extrapC = v_end +delzC*dv_end;
02874       x_extrapC = 0.707*(u_extrapC-v_extrapC);
02875       y_extrapC = 0.707*(u_extrapC+v_extrapC);
02876       isInCoil = !fPL.IsInside(x_extrapC,y_extrapC,nextscint.GetPlaneView(),kPC,true);        
02877     }
02878     float zMinCoil = zCoil;
02879     if(zMinCoil<Zscint && ZDir==1)  zMinCoil=Zscint;
02880     if(zMinCoil>Zscint && ZDir==-1) zMinCoil=Zscint;
02881 
02882     zCoil = Znextscint;
02883     isInCoil = true;
02884     while(isInCoil){
02885       zCoil += 1.0*Munits::cm*ZDir;
02886       float delzC = zCoil - Zscint;
02887       u_extrapC = u_end +delzC*du_end;
02888       v_extrapC = v_end +delzC*dv_end;
02889       x_extrapC = 0.707*(u_extrapC-v_extrapC);
02890       y_extrapC = 0.707*(u_extrapC+v_extrapC);
02891       isInCoil = !fPL.IsInside(x_extrapC,y_extrapC,nextscint.GetPlaneView(),kPC,true);        
02892     }
02893     float zMaxCoil = zCoil;
02894     float zmin; float zmax;
02895     ugh.GetZExtent(zmin,zmax);
02896     if(zMaxCoil>zmax && ZDir==1)  zMaxCoil=zmax;
02897     if(zMaxCoil<zmin && ZDir==-1) zMaxCoil=zmin;
02898 
02899     // now swim from mid-coil back to endplane
02900     float zMidCoil = 0.5*(zMinCoil + zMaxCoil);
02901     float delzC  = zMidCoil -Zscint;
02902     u_extrapC = u_end +delzC*du_end;
02903     v_extrapC = v_end +delzC*dv_end;
02904     x_extrapC = 0.707*(u_extrapC-v_extrapC);
02905     y_extrapC = 0.707*(u_extrapC+v_extrapC);
02906     
02907     StateVector[0] = u_extrapC; Output[0]=StateVector[0];
02908     StateVector[1] = v_extrapC; Output[1]=StateVector[1];
02909     StateVector[2] = FilteredData[EndPlane][0].x_k2; Output[2]=StateVector[2];
02910     StateVector[3] = FilteredData[EndPlane][0].x_k3; Output[3]=StateVector[3];
02911     chargesign = -1;
02912     if(FilteredData[EndPlane][0].x_k4!=0.) {chargesign =  FilteredData[EndPlane][0].x_k4/fabs(FilteredData[EndPlane][0].x_k4);}
02913     
02914     GoForward = !ZIncreasesWithTime;
02915     StateVector[4] = 10.*chargesign; Output[4]=StateVector[4]; 
02916 
02917     double dsdz = pow((1. + pow(StateVector[2],2) + pow(StateVector[3],2)),0.5);    
02918     // set fallback to nominal energy loss in case coil swim fails
02919     Prange = 0.095*dsdz;
02920     if(detector==Detector::kNear && EndPlane>121) Prange = 0.2*dsdz;  
02921     Prange += 0.5*dsdz*0.1*fabs(zMaxCoil-zMinCoil)*2.357*1.97;
02922 
02923     swimOK = Swim(StateVector, Output, zMidCoil, EndPlane , GoForward, &dS, &dRange, &dP);
02924    
02925     if(swimOK ){
02926       S = dS; Range = dRange; Prange = fabs(dP);
02927       cth.SetdS(EndPlane,S); 
02928       cth.SetRange(EndPlane,Range);
02929     }
02930     if(!swimOK) {Output[4] = chargesign/Prange;}
02931   
02932   }
02933 
02934   else{
02935     // normal case - track does not end in coil
02936     if((Zend<Zscint && ZDir==1) || (Zend>Zscint && ZDir==-1)) {
02937       MSG("AlgFitTrackCam",Msg::kWarning) << " Zend on wrong side of last scint! " << endl;
02938       Zend=Zscint;
02939     }
02940     
02941     // now swim to Zend
02942     StateVector[0]=FilteredData[EndPlane][0].x_k0; Output[0]=StateVector[0];
02943     StateVector[1]=FilteredData[EndPlane][0].x_k1; Output[1]=StateVector[1];
02944     StateVector[2]=FilteredData[EndPlane][0].x_k2; Output[2]=StateVector[2];
02945     StateVector[3]=FilteredData[EndPlane][0].x_k3; Output[3]=StateVector[3];
02946     StateVector[4]=FilteredData[EndPlane][0].x_k4; Output[4]=StateVector[4];
02947     chargesign = -1;
02948     if(StateVector[4]!=0.) {chargesign = StateVector[4]/fabs(StateVector[4]);}
02949     
02950     GoForward = ZIncreasesWithTime;
02951     done = Swim(StateVector, Output, EndPlane, Zend, GoForward,  &dS, &dRange, &dP);
02952     
02953     GoForward = !ZIncreasesWithTime;
02954     double dsdz = pow((1. + pow(StateVector[2],2) + pow(StateVector[3],2)),0.5); 
02955     S = 0; Range = 10.0*dsdz; Prange = 0.095*dsdz;
02956     swimOK = false;
02957     if(done){
02958       for(int j=0;j<5;j++) {StateVector[j]=Output[j];}
02959       
02960       // now swim from Zend to EndPlane
02961       StateVector[4] = chargesign * 10.52;  // start @ P = 100 MeV (Eloss in 1/2 " Iron)
02962       swimOK = Swim(StateVector, Output, Zend, EndPlane , GoForward, &dS, &dRange, &dP);
02963       if(swimOK){
02964         S += dS; Range += dRange; Prange += fabs(dP);
02965         cth.SetdS(EndPlane,S); 
02966         cth.SetRange(EndPlane,Range);
02967       }
02968     }
02969     if(!swimOK) {Output[4] = chargesign/Prange;}
02970   }
02971   
02972   int thisplane = EndPlane;
02973   // now swim back to vertex
02974   bool firstplane=true;
02975  for(int i=EndPlane+Increment; Increment*i<=Increment*VtxPlane; i+=Increment) {
02976     if(FilteredData[i].size()>0) {
02977       double delU = FilteredData[i][0].x_k0 - StateVector[0] ;
02978       double delV = FilteredData[i][0].x_k1 - StateVector[1] ;
02979       double dSperPlane=0.;
02980       if(thisplane!=i) {dSperPlane = pow(delU*delU + delV*delV,0.5)/double(abs(thisplane-i));}
02981 
02982       // only update state vector if change in U/V is reasonable.
02983       if(dSperPlane < 1.5*Munits::m) {
02984         StateVector[0]=FilteredData[i][0].x_k0;
02985         StateVector[1]=FilteredData[i][0].x_k1;
02986         StateVector[2]=FilteredData[i][0].x_k2;
02987         StateVector[3]=FilteredData[i][0].x_k3;
02988 
02989         chargesign=-1;
02990         if(FilteredData[i][0].x_k4!=0.) {chargesign = FilteredData[i][0].x_k4/fabs(FilteredData[i][0].x_k4);}
02991       }
02992 
02993       StateVector[4] = chargesign * fabs(Output[4]);
02994       done = Swim(StateVector, Output, thisplane, i , GoForward, &dS, &dRange, &dP);
02995       if(done){
02996         S+=dS; Range+=dRange; Prange+=fabs(dP);
02997         cth.SetdS(i,S); cth.SetRange(i,Range);
02998         firstplane=false;
02999       }
03000       else {
03001         MSG("AlgFitTrackCam",Msg::kDebug) << " swim fail " << endl;
03002       }
03003       thisplane=i;
03004     }
03005   }
03006 
03007   PlexPlaneId vtxplnid(detector,VtxPlane,false);
03008   PlexPlaneId plnid_before = vtxplnid.GetAdjoinSteel(-ZDir);
03009   
03010   if(plnid_before.IsValid()) {
03011     plnid = plnid_before;
03012     UgliSteelPlnHandle steelpln = ugh.GetSteelPlnHandle(plnid);
03013     double Zstart = steelpln.GetZ0();
03014     StateVector[0]=FilteredData[VtxPlane][0].x_k0;
03015     StateVector[1]=FilteredData[VtxPlane][0].x_k1;
03016     StateVector[2]=FilteredData[VtxPlane][0].x_k2;
03017     StateVector[3]=FilteredData[VtxPlane][0].x_k3;
03018     StateVector[4]=Output[4];
03019     Swim(StateVector, Output, VtxPlane, Zstart, GoForward, &dS,&dRange,&dP);
03020     S+=dS; Range+=dRange; Prange+=fabs(dP);
03021 
03022     cth.SetRange(VtxPlane,Range);
03023     cth.SetdS(VtxPlane,S);
03024   }
03025 
03026   // if Prange < 21 GeV, use this value.  Otherwise, use finder track energy, which is somewhat less prone to gross errors.
03027  
03028   // apply fudge factor for nominal steel thickness in ND geometry.
03029   //********* !!!!!!!!!!!!! ***********
03030   float ecorr = 1.0;
03031  if(vldc->GetDetector()==Detector::kNear && vldc->GetSimFlag()==SimFlag::kData) ecorr = 1.008; 
03032   
03033   cth.SetMomentumRange(Prange*ecorr);
03034   CandTrackHandle* findertrack = cth.GetFinderTrack();
03035   if(((detector==Detector::kFar && Prange>21.) || (detector==Detector::kNear && Prange>12.)) && findertrack) {cth.SetMomentumRange(findertrack->GetMomentum());}
03036 
03037 }

void AlgFitTrackCam::SetTrackProperties CandFitTrackCamHandle cth  ) 
 

Definition at line 2257 of file AlgFitTrackCam.cxx.

References bave, AlgTrack::CalculateTrace(), AlgReco::Calibrate(), Chi2(), EndCov, FilteredData, CandHandle::GetDaughterIterator(), GetFitData(), CandFitTrackHandle::GetMomentumCurve(), CandFitTrackHandle::GetMomentumRange(), CandHandle::GetNDaughters(), CandRecoHandle::GetNDigit(), CandStripHandle::GetPlane(), Calibrator::Instance(), CandTrackHandle::IsContained(), MaxPlane, MinPlane, MSG, nbfield, NIter, pow(), Calibrator::ReInitialise(), CandFitTrackHandle::SetBave(), CandFitTrackHandle::SetChi2(), CandRecoHandle::SetDirCosU(), CandRecoHandle::SetDirCosV(), CandRecoHandle::SetDirCosZ(), CandFitTrackHandle::SetEMCharge(), CandRecoHandle::SetEndDirCosU(), CandRecoHandle::SetEndDirCosV(), CandRecoHandle::SetEndDirCosZ(), CandFitTrackHandle::SetEnddUError(), CandFitTrackHandle::SetEnddVError(), CandRecoHandle::SetEndPlane(), CandFitTrackHandle::SetEndQP(), CandFitTrackHandle::SetEndQPError(), CandRecoHandle::SetEndU(), CandFitTrackHandle::SetEndUError(), CandRecoHandle::SetEndV(), CandFitTrackHandle::SetEndVError(), CandRecoHandle::SetEndZ(), CandTrackHandle::SetInShower(), CandTrackHandle::SetMomentum(), CandFitTrackHandle::SetMomentumCurve(), CandFitTrackHandle::SetNDOF(), CandFitTrackHandle::SetNIterate(), CandFitTrackHandle::SetNSwimFail(), CandTrackHandle::SetNTrackDigit(), CandTrackHandle::SetNTrackStrip(), CandFitTrackHandle::SetPlaneChi2(), CandFitTrackHandle::SetPlaneQP(), SetRangeAnddS(), CandFitTrackCamHandle::SetRangeBiasedQP(), AlgTrack::SetT(), CandTrackHandle::SetTrackPointError(), CandTrackHandle::SetU(), CandTrackHandle::SetV(), CandRecoHandle::SetVtxDirCosU(), CandRecoHandle::SetVtxDirCosV(), CandRecoHandle::SetVtxDirCosZ(), CandFitTrackHandle::SetVtxdUError(), CandFitTrackHandle::SetVtxdVError(), CandRecoHandle::SetVtxPlane(), CandFitTrackHandle::SetVtxQPError(), CandRecoHandle::SetVtxU(), CandFitTrackHandle::SetVtxUError(), CandRecoHandle::SetVtxV(), CandFitTrackHandle::SetVtxVError(), CandRecoHandle::SetVtxZ(), ShowerEntryPlane, SlcStripData, TimingFit(), TotalNSwimFail, TrkStripData, vldc, VtxCov, x_k, x_k4_biased, and ZIncreasesWithTime.

Referenced by RunTheFitter().

02258 { 
02259 
02260   if(nbfield>0) bave /=nbfield;
02261   
02262   // Carry out the assignment of variables to the new fitted track 
02263   MSG("AlgFitTrackCam",Msg::kDebug) << "SetTrackProperties" << endl;
02264   
02265   
02266   // Momentum, charge and error on q/p
02268   if(x_k[4]!=0.) {cth.SetMomentumCurve(fabs(1./x_k[4]));}
02269   cth.SetRangeBiasedQP(x_k4_biased);
02270   if(x_k[4]>0.) {cth.SetEMCharge(1.);}
02271   else if(x_k[4]<0.) {cth.SetEMCharge(-1.);}
02272   
02273   cth.SetVtxQPError(pow(VtxCov[4],0.5));
02275   
02276   
02277   // Positions and angles  
02279   int VtxPlane;
02280   int EndPlane;
02281   double dsdz;
02282   
02283   if(ZIncreasesWithTime==true) {VtxPlane=MinPlane; EndPlane=MaxPlane;}
02284   else {VtxPlane=MaxPlane; EndPlane=MinPlane;}
02285   
02286   // Vtx and end coordinates  
02287   cth.SetVtxU(FilteredData[VtxPlane][0].x_k0);
02288   cth.SetVtxV(FilteredData[VtxPlane][0].x_k1);
02289   cth.SetVtxZ(SlcStripData[VtxPlane][0].csh->GetZPos());
02290   cth.SetVtxPlane(VtxPlane);
02291   
02292   cth.SetEndU(FilteredData[EndPlane][0].x_k0);
02293   cth.SetEndV(FilteredData[EndPlane][0].x_k1);
02294 
02295   cth.SetEndZ(SlcStripData[EndPlane][0].csh->GetZPos());
02296   cth.SetEndPlane(EndPlane);
02297   
02298   
02299   // Vtx and end direction cosines
02300   dsdz=pow(1.+pow(FilteredData[VtxPlane][0].x_k2,2)+pow(FilteredData[VtxPlane][0].x_k3,2),0.5);
02301   if(ZIncreasesWithTime==false) {dsdz=-dsdz;}
02302   
02303   cth.SetVtxDirCosU(FilteredData[VtxPlane][0].x_k2/dsdz);
02304   cth.SetVtxDirCosV(FilteredData[VtxPlane][0].x_k3/dsdz);
02305   cth.SetVtxDirCosZ(1./dsdz);
02306   
02307   cth.SetDirCosU(FilteredData[VtxPlane][0].x_k2/dsdz);
02308   cth.SetDirCosV(FilteredData[VtxPlane][0].x_k3/dsdz);
02309   cth.SetDirCosZ(1./dsdz);
02310     
02311   dsdz=pow(1.+pow(FilteredData[EndPlane][0].x_k2,2)+pow(FilteredData[EndPlane][0].x_k3,2),0.5);
02312   if(ZIncreasesWithTime==false) {dsdz=-dsdz;}
02313   
02314   cth.SetEndDirCosU(FilteredData[EndPlane][0].x_k2/dsdz);
02315   cth.SetEndDirCosV(FilteredData[EndPlane][0].x_k3/dsdz);
02316   cth.SetEndDirCosZ(1./dsdz);
02317   
02318   // End q/p value
02319   cth.SetEndQP(FilteredData[EndPlane][0].x_k4);
02320     
02321   // Errors on vtx positions and angles  
02322   cth.SetVtxUError(pow(VtxCov[0],0.5));
02323   cth.SetVtxVError(pow(VtxCov[1],0.5));
02324   cth.SetVtxdUError(pow(VtxCov[2],0.5));
02325   cth.SetVtxdVError(pow(VtxCov[3],0.5)); 
02326   
02327   // Errors on end positions, angles and q/p
02328   cth.SetEndUError(pow(EndCov[0],0.5));
02329   cth.SetEndVError(pow(EndCov[1],0.5));
02330   cth.SetEnddUError(pow(EndCov[2],0.5));
02331   cth.SetEnddVError(pow(EndCov[3],0.5)); 
02332   cth.SetEndQPError(pow(EndCov[4],0.5)); 
02333 
02335 
02336   cth.SetBave(bave);
02337 
02338   // More variables to be set, in order to ensure compatibility
02340   cth.SetNTrackStrip(cth.GetNDaughters());
02341   cth.SetNTrackDigit(cth.GetNDigit());
02342   
02343   cth.SetNIterate(NIter);
02344   cth.SetNSwimFail(TotalNSwimFail);
02345   
02346   
02347   // Obtain "fitting data" for the final track strips
02348   for (int i=0; i<490; ++i) {TrkStripData[i].clear();} 
02349   GetFitData(MinPlane,MaxPlane);
02350   
02351   
02352   // Set tpos error and Calculate chi2, NDOF
02353   double Chi2=0; double Chi2Contrib=0; int NDOF=0; double FilteredTPos=0;
02354   
02355   for(int i=MinPlane; i<=MaxPlane; ++i) {
02356     if(TrkStripData[i].size()>0) {
02357       
02358       if(TrkStripData[i][0].TPosError>0.) {
02359         cth.SetTrackPointError(i,pow(TrkStripData[i][0].TPosError,0.5));
02360         
02361         if(TrkStripData[i][0].PlaneView==2) {FilteredTPos=FilteredData[i][0].x_k0;}
02362         else {FilteredTPos=FilteredData[i][0].x_k1;}
02363         
02364         Chi2Contrib = pow((TrkStripData[i][0].TPos-FilteredTPos),2) / TrkStripData[i][0].TPosError;
02365         cth.SetPlaneChi2(i,Chi2Contrib);        
02366         
02367         Chi2+=Chi2Contrib;
02368         
02369         NDOF++;
02370       }
02371     }
02372   }
02373   cth.SetChi2(Chi2);
02374   cth.SetNDOF(NDOF-5); // Number of constraints set to 5
02375   
02376   
02377   // Assign U, V and q/p values
02378   for(int i=MinPlane; i<=MaxPlane; ++i) {
02379     if(FilteredData[i].size()>0) {
02380       cth.SetU(i,FilteredData[i][0].x_k0);
02381       cth.SetV(i,FilteredData[i][0].x_k1);
02382       cth.SetPlaneQP(i,FilteredData[i][0].x_k4);
02383     }
02384   }
02385   
02386   
02387   // Set Trace and TraceZ
02388   CalculateTrace(cth);
02389   
02390   
02391   // Fill time and range maps
02392   SetT(&cth);
02393   SetRangeAnddS(cth);
02394   
02395   
02396   // Set momentum to our best estimate (range or curvature)
02397   cth.SetMomentum(cth.GetMomentumCurve());
02398   if(cth.IsContained()){
02399     cth.SetMomentum(cth.GetMomentumRange());
02400   }
02401   
02402   
02403   // Identify track strips inside in vertex shower
02404   
02405   TIter FitTrackStripItr = cth.GetDaughterIterator();
02406   while(CandStripHandle* FitTrackStrip = dynamic_cast<CandStripHandle*>(FitTrackStripItr()))
02407     {
02408       if(ShowerEntryPlane!=-99) {
02409         if( (ZIncreasesWithTime==true && FitTrackStrip->GetPlane()<=ShowerEntryPlane)
02410             || (ZIncreasesWithTime==false && FitTrackStrip->GetPlane()>=ShowerEntryPlane) ) {
02411           cth.SetInShower(FitTrackStrip,2);
02412         }
02413         else {cth.SetInShower(FitTrackStrip,0);}
02414       }
02415       else {cth.SetInShower(FitTrackStrip,0);}
02416     }
02417   
02418   
02419   // Set all time related variables
02420   TimingFit(cth);
02421   
02422   
02423   // Calibrate, to get track pulse height in MIPs, GeV, etc
02424   Calibrator& cal = Calibrator::Instance();
02425   cal.ReInitialise(*vldc);
02426   Calibrate(&cth);
02427 
02428 
02429 }

void AlgFitTrackCam::ShowerStrips  ) 
 

Definition at line 268 of file AlgFitTrackCam.cxx.

References abs(), FilteredData, min, MinPlane, MSG, ShowerEntryPlane, SlcStripData, SwimThroughShower, and ZIncreasesWithTime.

Referenced by RunTheFitter().

00269 {
00270   MSG("AlgFitTrackCam",Msg::kDebug) << "ShowerStrips, Look for large vertex shower" << endl;
00271      
00272   // Initialisations
00273   int Increment; int NumberOfStrips;
00274   int Plane; int NewPlane;
00275 
00276   int VtxShwWindow=8; 
00277   int StripsForShw=4;
00278   double PEThreshold=2.;
00279 
00280   if(ZIncreasesWithTime==true) {Plane=MinPlane; Increment=1;}
00281   else {Plane=MaxPlane; Increment=-1;}
00282   NewPlane=Plane;
00283 
00284 
00285   // Identify any vertex showers
00287   while(abs(Plane-NewPlane)<=VtxShwWindow && NewPlane>=MinPlane && NewPlane<=MaxPlane) {
00288 
00289     if(SlcStripData[NewPlane].size()>0) {
00290       NumberOfStrips=0;
00291 
00292 
00293       // Set the number of hits on a plane required for the plane to be identified as 'in the 
00294       // shower'. We account for the gradient of the track, with the factor of 0.25 representing
00295       // the approximate ratio of strip thickness to strip width.
00296       if(FilteredData[NewPlane].size()>0) {
00297         if(SlcStripData[NewPlane][0].csh->GetPlaneView()==2) {
00298           StripsForShw=min(7,int( 4+(0.25*fabs(FilteredData[NewPlane][0].x_k2)) ));
00299         }
00300         else {StripsForShw=min(7,int( 4+(0.25*fabs(FilteredData[NewPlane][0].x_k3)) ));}
00301       }
00302       else {StripsForShw=4;}
00303 
00304 
00305       // Count number of strips on plane with greater than 2PEs
00306       for(unsigned int j=0; j<SlcStripData[NewPlane].size(); ++j) {
00307         if(SlcStripData[NewPlane][j].csh->GetCharge()>PEThreshold) {NumberOfStrips++;}
00308       }
00309 
00310 
00311       // If a vertex shower is found, note that we should use the Swimmer
00312       // to find the most likely track strips inside the shower
00313       if(NumberOfStrips>=StripsForShw) {ShowerEntryPlane=NewPlane; SwimThroughShower=true; break;}
00314       
00315       NewPlane+=Increment;
00316     }
00317     else {NewPlane+=Increment;}
00318   }
00320 
00321 
00322  
00323   // Find the plane at which the 'clean' section of track enters the shower
00325   if(SwimThroughShower==true) {
00326     NewPlane=ShowerEntryPlane+Increment;
00327     int PlanesSinceLastHit=0;
00328     int PlaneWindow=4;
00329 
00330     while(PlanesSinceLastHit<PlaneWindow && NewPlane>=MinPlane && NewPlane<=MaxPlane) {
00331       if(SlcStripData[NewPlane].size()>0) {
00332         NumberOfStrips=0;
00333 
00334         // Account for gradient of track, as before
00335         if(FilteredData[NewPlane].size()>0) { 
00336           if(SlcStripData[NewPlane][0].csh->GetPlaneView()==2) {
00337             StripsForShw=min(7,int(4+(0.25*fabs(FilteredData[NewPlane][0].x_k2)) ));
00338           }
00339           else {StripsForShw=min(7,int(4+(0.25*fabs(FilteredData[NewPlane][0].x_k3)) ));}
00340         }
00341         else {StripsForShw=4;}
00342 
00343 
00344         // Count number of strips on plane with greater than 2PEs
00345         for(unsigned int j=0; j<SlcStripData[NewPlane].size(); ++j) {
00346           if(SlcStripData[NewPlane][j].csh->GetCharge()>PEThreshold) {NumberOfStrips++;}
00347         }
00348         if(NumberOfStrips>=StripsForShw) {
00349           ShowerEntryPlane=NewPlane; NewPlane+=Increment; PlanesSinceLastHit=0;
00350         }
00351         else {PlanesSinceLastHit++; NewPlane+=Increment;}
00352         
00353       }
00354       else {PlanesSinceLastHit++; NewPlane+=Increment;}
00355     }
00356   }
00358 }

void AlgFitTrackCam::ShowerSwim  ) 
 

Definition at line 597 of file AlgFitTrackCam.cxx.

References CalcKalmanGain(), StripStruct::csh, ExtrapCovMatrix(), GetCombiPropagator(), GetFitData(), GetNoiseMatrix(), H_k, InitTrkStripData, MaxPlane, MinPlane, MoveArrays(), MSG, SlcStripData, StoreFilteredData(), Swim(), SwimThroughShower, UpdateCovMatrix(), UpdateStateVector(), x_k, x_k_minus, and ZIncreasesWithTime.

Referenced by RunTheFitter().

00598 {
00599   // Method is called if we have a large shower near the track vertex
00600   //
00601   // The Swimmer is used to find the most likely track strip in the shower
00602   // and this strip is added to the fit
00603   MSG("AlgFitTrackCam",Msg::kDebug) << "ShowerSwim, improved track finding in shower" << endl;
00604 
00605   // Initialisations
00606   int Plane; int NewPlane;
00607   double StateVector[5]; double NState[5];
00608   bool GoForward; bool SwimBack;
00609   int PlanesSinceLastHit=0;
00610   int PlaneView;
00611   int Increment;
00612   
00613   double StripDistance; double MinDistanceToStrip;
00614   double StripWidth=4.108e-2;
00615 
00616 
00617   if(ZIncreasesWithTime==true) {GoForward=false; Plane=MinPlane; Increment=-1;}
00618   else {GoForward=true; Plane=MaxPlane; Increment=1;}
00619 
00620   NewPlane=Plane+Increment;
00621 
00622 
00623   // Continue until we reach a 4 plane window with no likely hit or we reach 
00624   // the end of the detector
00625   while(PlanesSinceLastHit<4 && NewPlane>0 && NewPlane<=485) {
00626     if(SlcStripData[NewPlane].size()>0) {
00627 
00628       if(SlcStripData[NewPlane][0].csh->GetPlaneView()==2) {PlaneView=0;}
00629       else {PlaneView=1;}
00630       
00631       for(int i=0; i<5; ++i) {StateVector[i]=x_k_minus[i];}
00632       SwimBack=Swim(StateVector, NState, Plane, NewPlane, GoForward);
00633       if(!SwimBack){break;}
00634       for(int i=0; i<5; ++i) {x_k[i]=NState[i];}
00635  
00636  
00637       // Find the closest strip (within a distance 'MinDistanceToStrip') and
00638       // temporarily store CandStripHandle
00639       // Results are very sensitive to value of MinDistanceToStrip
00640       CandStripHandle* CurrentStrip=0;
00641       MinDistanceToStrip=(1.5*StripWidth)+ fabs(0.0055*x_k[PlaneView+2]);
00642       
00643       for(unsigned int j=0; j<SlcStripData[NewPlane].size(); ++j) {
00644         StripDistance=fabs(SlcStripData[NewPlane][j].csh->GetTPos()-x_k[PlaneView]);
00645         
00646         if(StripDistance<MinDistanceToStrip) {
00647           MinDistanceToStrip=StripDistance;
00648           CurrentStrip=SlcStripData[NewPlane][j].csh;
00649         }
00650       }            
00651       
00652       // If we find a likely track strip, add it to the fit data and call the Kalman
00653       // update equations before repeating process to find next track strips in the shower
00654       if(CurrentStrip) {
00655         StripStruct temp;
00656         temp.csh = CurrentStrip;
00657         InitTrkStripData[NewPlane].push_back(temp);
00658         
00659         // Convert the strip to data required for Kalman fit
00660         GetFitData(NewPlane,NewPlane);
00661 
00662         // Carry out the Kalman fit
00663         if (PlaneView==1) {H_k[0]=0; H_k[1]=1; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
00664         else {H_k[0]=1; H_k[1]=0; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
00665         
00666         bool CombiPropagatorOk=GetCombiPropagator(Plane,NewPlane,GoForward);
00667         
00668         if(CombiPropagatorOk ) {
00669           GetNoiseMatrix(Plane,NewPlane);
00670           ExtrapCovMatrix();
00671           CalcKalmanGain(NewPlane);
00672           UpdateStateVector(Plane,NewPlane,GoForward);
00673           UpdateCovMatrix();
00674           MoveArrays();
00675           StoreFilteredData(NewPlane);
00676           
00677           if(ZIncreasesWithTime) {MinPlane=NewPlane; Plane=MinPlane;}
00678           else {MaxPlane=NewPlane; Plane=MaxPlane;}
00679           NewPlane=Plane+Increment;
00680           
00681           PlanesSinceLastHit=0;
00682         }
00683       }
00684       else {NewPlane+=Increment; PlanesSinceLastHit++;}
00685       
00686     }
00687     else {NewPlane+=Increment; PlanesSinceLastHit++;}
00688   }
00689   
00690   // Note that shower swim is complete
00691   SwimThroughShower=false;
00692 
00693 }

void AlgFitTrackCam::SpectrometerSwim CandFitTrackCamHandle cth  ) 
 

Definition at line 3184 of file AlgFitTrackCam.cxx.

References abs(), CandHandle::AddDaughterLink(), C_k, CalcKalmanGain(), StripStruct::csh, ExtrapCovMatrix(), FilteredData, GetCombiPropagator(), CandFitTrackHandle::GetFinderTrack(), GetFitData(), GetMomFromRange(), GetNoiseMatrix(), CandStripHandle::GetPlane(), PlexPlaneId::GetPlaneCoverage(), CandTrackHandle::GetRange(), CandStripHandle::GetZPos(), H_k, InitTrkStripData, CandHandle::IsSlushyEnabled(), PlexPlaneId::IsValid(), MaxPlane, MeanTrackTime, MoveArrays(), MSG, NDPlaneIsActive(), NDStripBegTime(), PassTrack, pow(), CandRecoHandle::SetEndDirCosU(), CandRecoHandle::SetEndDirCosV(), CandRecoHandle::SetEndPlane(), CandRecoHandle::SetEndU(), CandRecoHandle::SetEndV(), CandRecoHandle::SetEndZ(), CandTrackHandle::SetMomentum(), CandHandle::SetSlushyEnabled(), AlgTrack::SetUVZT(), SlcStripData, StoreFilteredData(), Swim(), UpdateCovMatrix(), UpdateStateVector(), and x_k_minus.

Referenced by RunTheFitter().

03185 {
03186   MSG("AlgFitTrackCam",Msg::kDebug) << "SpectrometerSwim, improved track finding in spectrometer" << endl;
03187 
03188   // Initialisations
03189   // Sort out the lists for the ND spectrometer
03190   bool AddedStrip = false;
03191   int Plane; int NewPlane;
03192   double StateVector[5]; double NState[5]; double temp_x_k[5];
03193   bool GoForward; bool SpectSwim;
03194   int ActivePlanesSinceLastHit=0;
03195   int PlaneView; int Increment; int Counter;
03196   double LastHitTimes[2]={MeanTrackTime,MeanTrackTime};
03197   double TimeWindow=40.e-9;
03198 
03199   double StripDistance; double MinDistanceToStrip;
03200   double SwimError2;
03201   double StripWidth = 4.108e-2;
03202   double PlanePitch = 0.0594;
03203 
03204   bool TrackInActiveRegion;
03205   GoForward=true; Plane=MaxPlane; Increment=1;
03206 
03207   // Linear extrapolation from end of track to start of spectrometer.
03208   // Count number of active planes  
03209   while(ActivePlanesSinceLastHit<6 && Plane<121) {
03210     Plane += Increment;
03211     double u = x_k_minus[0] + x_k_minus[2]*(Plane-MaxPlane)*PlanePitch;
03212     double v = x_k_minus[1] + x_k_minus[3]*(Plane-MaxPlane)*PlanePitch;
03213 
03214     // 15 Feb 2008 - mitigate symptoms of a problem elsewhere - huge u and v can cause crash.
03215     if(fabs(u) > 5000 || fabs(v) > 5000){
03216       MSG("AlgFitTrackCam", Msg::kError) << "SpectrometerSwim - unexpectedly large u or v (u="
03217                                          << u << " v=" << v << ") bailing out." << endl;
03218       return;
03219     }
03220 
03221     if (NDPlaneIsActive(Plane, u, v, 0.3)) ActivePlanesSinceLastHit++;
03222   }
03223 
03224   // If we are clearly not near spectrometer, return from method
03225   if(ActivePlanesSinceLastHit>5 || abs(121-MaxPlane)>=40) {return;}
03226 
03227   // Set initial positions for swim
03228   ActivePlanesSinceLastHit=0;
03229   Plane = MaxPlane;  NewPlane = Plane+1;
03230 
03231   // Continue until we reach a 8 plane gap (counting only active planes) since prior
03232   // hit or we reach the end of the detector
03233   while(ActivePlanesSinceLastHit<8 && abs(NewPlane-Plane)<=70 && NewPlane<=290 && PassTrack==true) {
03234     
03235     PlexPlaneId plexPlane(Detector::kNear,NewPlane, 0); 
03236     if(SlcStripData[NewPlane].size()>0 && plexPlane.IsValid() && plexPlane.GetPlaneCoverage()!=PlaneCoverage::kNoActive) {
03237 
03238       if(SlcStripData[NewPlane][0].csh->GetPlaneView()==2) {PlaneView=0;}
03239       else {PlaneView=1;}
03240       
03241       for(int i=0; i<5; ++i) {StateVector[i]=x_k_minus[i];}
03242 
03243       // For the purposes of spectrometer track hit finding, don't allow track to range out before
03244       // we have swum all the hit spectrometer planes in this slice
03245       SpectSwim = Swim(StateVector, NState, Plane, NewPlane, GoForward);
03246 
03247       // If swim has failed and there is a large gap to next hit plane, stop the spectrometer swim.
03248       if(!SpectSwim && (NewPlane-Plane)>=40) {
03249         break;}
03250 
03251       // If swim has failed, but there is no large gap, make a momentum correction and swim again.
03252       if(!SpectSwim && StateVector[4]!=0) {
03253         Counter=0;
03254         // Double momentum and attempt to swim again
03255         while(!SpectSwim && Counter<2) {
03256           StateVector[4]*=0.5;  
03257           SpectSwim = Swim(StateVector, NState, Plane, NewPlane, GoForward);
03258           
03259           if(!SpectSwim) {Counter++;}
03260         }
03261       }
03262       
03263       if(!SpectSwim) {break;}
03264 
03265       for(int i=0; i<5; ++i) {temp_x_k[i]=NState[i];}
03266 
03267       // Calculate error in track extrapolation, based on covariance matrix on-diagonal elements
03268       SwimError2 = C_k[PlaneView][PlaneView] + (C_k[PlaneView+2][PlaneView+2]*PlanePitch*PlanePitch*(NewPlane-Plane)*(NewPlane-Plane)); 
03269       MinDistanceToStrip = 3.0 * pow(StripWidth*StripWidth + SwimError2,0.5);
03270       
03271 
03272       // Find the closest strip (within a distance 'MinDistanceToStrip') and temporarily store CandStripHandle
03273       CandStripHandle* CurrentStrip = 0;      
03274       for(unsigned int j=0; j<SlcStripData[NewPlane].size(); ++j) {
03275         StripDistance = fabs(SlcStripData[NewPlane][j].csh->GetTPos()-temp_x_k[PlaneView]);
03276 
03277         if(StripDistance<MinDistanceToStrip 
03278            && fabs(0.5*(LastHitTimes[0]+LastHitTimes[1])-NDStripBegTime(SlcStripData[NewPlane][j].csh,temp_x_k[0],temp_x_k[1]))<TimeWindow) {
03279           MinDistanceToStrip=StripDistance;
03280           CurrentStrip=SlcStripData[NewPlane][j].csh;
03281         }
03282       }
03283 
03284       // If we find a likely track strip, add it to the fit data and call the Kalman
03285       // update equations before repeating process to find next track strips in the shower
03286       if(CurrentStrip) {
03287         LastHitTimes[1]=LastHitTimes[0];
03288         LastHitTimes[0]=NDStripBegTime(CurrentStrip,temp_x_k[0],temp_x_k[1]);
03289 
03290         StripStruct temp;
03291         temp.csh = CurrentStrip;
03292         InitTrkStripData[NewPlane].push_back(temp);
03293         
03294         // Convert the strip to data required for Kalman fit
03295         GetFitData(NewPlane,NewPlane);
03296         
03297         // Carry out the Kalman fit
03298         if (PlaneView==1) {H_k[0]=0; H_k[1]=1; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
03299         else {H_k[0]=1; H_k[1]=0; H_k[2]=0; H_k[3]=0; H_k[4]=0;}
03300         
03301         bool CombiPropagatorOk = GetCombiPropagator(Plane,NewPlane,GoForward);
03302 
03303         if(CombiPropagatorOk) {
03304           GetNoiseMatrix(Plane,NewPlane);
03305           ExtrapCovMatrix();
03306           CalcKalmanGain(NewPlane);
03307           UpdateStateVector(Plane,NewPlane,GoForward);
03308           UpdateCovMatrix();
03309           MoveArrays();
03310           StoreFilteredData(NewPlane);
03311           
03312           MaxPlane=NewPlane; Plane=MaxPlane;
03313           NewPlane=Plane+Increment;
03314           
03315           ActivePlanesSinceLastHit=0;
03316         }
03317 
03318         // Extend finder track, including the ND Spectrometer hits found in the fit
03320 
03321        
03322         CandTrackHandle * findertrack = cth.GetFinderTrack();
03323         if(findertrack) {
03324           bool SlushyOnEntry = CandHandle::IsSlushyEnabled();
03325           CandHandle::SetSlushyEnabled(kTRUE);
03326           AddedStrip = true;
03327           findertrack->AddDaughterLink(*CurrentStrip);
03328           findertrack->SetEndPlane(CurrentStrip->GetPlane());
03329           findertrack->SetEndZ(CurrentStrip->GetZPos());
03330           findertrack->SetEndU(FilteredData[CurrentStrip->GetPlane()][0].x_k0);
03331           findertrack->SetEndV(FilteredData[CurrentStrip->GetPlane()][0].x_k1);
03332           findertrack->SetEndDirCosU(FilteredData[CurrentStrip->GetPlane()][0].x_k2);
03333           findertrack->SetEndDirCosV(FilteredData[CurrentStrip->GetPlane()][0].x_k3);
03334           if(!SlushyOnEntry) CandHandle::SetSlushyEnabled(kFALSE);
03335         }
03337         
03338       }
03339       else {
03340         TrackInActiveRegion=NDPlaneIsActive(NewPlane, temp_x_k[0], temp_x_k[1], 0.3);
03341         if(plexPlane.IsValid() && plexPlane.GetPlaneCoverage()!=PlaneCoverage::kNoActive && TrackInActiveRegion) 
03342           {ActivePlanesSinceLastHit++;}
03343         NewPlane+=Increment;
03344       }
03345     }
03346     else {
03347       double u = x_k_minus[0] + x_k_minus[2]*(NewPlane-Plane)*PlanePitch;
03348       double v = x_k_minus[1] + x_k_minus[3]*(NewPlane-Plane)*PlanePitch;
03349       
03350       TrackInActiveRegion=NDPlaneIsActive(NewPlane, u, v, 0.3); 
03351       
03352       if(plexPlane.IsValid() && plexPlane.GetPlaneCoverage()!=PlaneCoverage::kNoActive && TrackInActiveRegion) 
03353         {ActivePlanesSinceLastHit++;}
03354       NewPlane+=Increment; 
03355     }
03356   }
03357 
03358   
03359   // Sort out range and dS for finder track
03361   if(AddedStrip) {
03362     CandTrackHandle * findertrack = cth.GetFinderTrack();
03363     if(findertrack) {
03364       bool SlushyOnEntry = CandHandle::IsSlushyEnabled();
03365       CandHandle::SetSlushyEnabled(kTRUE);
03366       
03367       SetUVZT(findertrack);
03368       Double_t range = findertrack->GetRange();
03369       if (range>0.) {
03370         findertrack->SetMomentum(GetMomFromRange(range));   
03371       }
03372       if(!SlushyOnEntry) CandHandle::SetSlushyEnabled(kFALSE);
03373     }
03374   }
03376 
03377 }

void AlgFitTrackCam::StoreFilteredData const int  NewPlane  ) 
 

Definition at line 2239 of file AlgFitTrackCam.cxx.

References FilteredData, MSG, x_k, FiltDataStruct::x_k0, FiltDataStruct::x_k1, FiltDataStruct::x_k2, FiltDataStruct::x_k3, and FiltDataStruct::x_k4.

Referenced by GoBackwards(), GoForwards(), RunTheFitter(), ShowerSwim(), and SpectrometerSwim().

02240 {
02241   // Store the data required for matching Kalman output data to strips
02242   MSG("AlgFitTrackCam",Msg::kDebug) << "StoreFilteredData" << endl;
02243 
02244   FiltDataStruct temp;
02245   
02246   temp.x_k0=x_k[0]; temp.x_k1=x_k[1];
02247   temp.x_k2=x_k[2]; temp.x_k3=x_k[3];
02248   temp.x_k4=x_k[4];
02249 
02250   FilteredData[NewPlane].push_back(temp);
02251 }

bool AlgFitTrackCam::Swim double *  StateVector,
double *  Output,
const int  Plane,
const double  zend,
const bool  GoForward,
double *  dS = 0,
double *  Range = 0,
double *  dE = 0
 

Definition at line 1618 of file AlgFitTrackCam.cxx.

References done(), SwimParticle::GetCharge(), SwimParticle::GetDirection(), SwimParticle::GetMomentumModulus(), SwimParticle::GetPosition(), SwimParticle::GetRange(), SwimParticle::GetS(), GeoSwimmer::Initialize(), GeoSwimmer::Instance(), MSG, pow(), SwimParticle::SetCharge(), SlcStripData, SwimSwimmer::SwimBackward(), GeoSwimmer::SwimBackward(), SwimSwimmer::SwimForward(), GeoSwimmer::SwimForward(), vldc, and ZIncreasesWithTime.

01620 {
01621   MSG("AlgFitTrackCam",Msg::kDebug) << "Swim, specified end Z" << endl;
01622 
01623   // Initialisations
01624   // customize for bfield scaling.
01625 
01626   BField * bf = new BField(*vldc,-1,0);
01627   SwimSwimmer* myswimmer = new SwimSwimmer(*vldc,bf);
01628 
01629   if(UseGeoSwimmer) GeoSwimmer::Instance()->Initialize(*vldc);
01630 
01631   double invSqrt2 = pow(1./2.,0.5);
01632   double charge = 0.;
01633   bool done = false;
01634     
01635   if(fabs(StateVector[4])>1.e-10) {
01636     double modp = fabs(1./StateVector[4]);
01637     
01638     // Fix, to account for fact the cosmic muons could move in direction of negative z
01639     if(ZIncreasesWithTime==false) {modp=-modp;}
01640     
01641     double dsdz = pow((1.+pow(StateVector[2],2)+pow(StateVector[3],2)),0.5);
01642     double dxdz = invSqrt2*(StateVector[2]-StateVector[3]);
01643     double dydz = invSqrt2*(StateVector[2]+StateVector[3]);
01644   
01645     // Set up current muon details
01646     if(StateVector[4]>0.) charge = 1.;
01647     else if(StateVector[4]<0.) charge = -1.;
01648     
01649     TVector3 position(invSqrt2*(StateVector[0]-StateVector[1]),
01650                       invSqrt2*(StateVector[0]+StateVector[1]),
01651                       SlcStripData[Plane][0].csh->GetZPos());
01652 
01653 
01654     TVector3 momentum(modp*(dxdz/dsdz),
01655                       modp*(dydz/dsdz),
01656                       modp/dsdz);
01657     SwimParticle muon(position,momentum);
01658     muon.SetCharge(charge);
01659     SwimZCondition zc(Zend);
01660  
01661     // Do the swim, accounting for direction of motion w.r.t time too
01662     if( (GoForward==true && ZIncreasesWithTime==true)  || (GoForward==false && ZIncreasesWithTime==false) ) {
01663       if(UseGeoSwimmer){
01664         done = GeoSwimmer::Instance()->SwimForward(muon,Zend);
01665       } else {
01666         done = myswimmer->SwimForward(muon,zc);
01667       }   
01668     }
01669     else if( (GoForward==true && ZIncreasesWithTime==false)  || (GoForward==false && ZIncreasesWithTime==true) ) {
01670       if(UseGeoSwimmer){
01671         done = GeoSwimmer::Instance()->SwimBackward(muon,Zend);
01672       } else {
01673         done = myswimmer->SwimBackward(muon,zc);
01674       }    
01675     }
01676     if(done==true) {
01677       if(muon.GetDirection().Z()!=0. && muon.GetMomentumModulus()!=0.) {
01678         Output[0]=invSqrt2*(muon.GetPosition().Y()+muon.GetPosition().X());
01679         Output[1]=invSqrt2*(muon.GetPosition().Y()-muon.GetPosition().X());
01680         Output[2]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())+(muon.GetDirection().X()/muon.GetDirection().Z()));
01681         Output[3]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())-(muon.GetDirection().X()/muon.GetDirection().Z()));
01682         Output[4]=muon.GetCharge()/muon.GetMomentumModulus();
01683         // Get range and dS from the Swimmer
01684         if(dS) {*dS=muon.GetS();} if(Range) {*Range=muon.GetRange();} if(dE){*dE=muon.GetMomentumModulus()-momentum.Mag();}
01685       }
01686       else {done=false;}
01687     }
01688     
01689   }
01690 
01691   else{
01692     // If infinite momentum, use straight line extrapolation
01693     double delz = (Zend-SlcStripData[Plane][0].csh->GetZPos());
01694     Output[0]=StateVector[0] + StateVector[2]*delz;
01695     Output[1]=StateVector[1] + StateVector[3]*delz;
01696     Output[2]=StateVector[2];
01697     Output[3]=StateVector[3];
01698     Output[4]=StateVector[4];
01699 
01700     done=true;
01701   }    
01702   
01703   delete myswimmer;
01704   delete bf;
01705   return done;
01706 }

bool AlgFitTrackCam::Swim double *  StateVector,
double *  Output,
const double  zbeg,
const int  NewPlane,
const bool  GoForward,
double *  dS = 0,
double *  Range = 0,
double *  dE = 0
 

Definition at line 1523 of file AlgFitTrackCam.cxx.

References done(), SwimParticle::GetCharge(), SwimParticle::GetDirection(), SwimParticle::GetMomentumModulus(), SwimParticle::GetPosition(), SwimParticle::GetRange(), SwimParticle::GetS(), GeoSwimmer::Initialize(), GeoSwimmer::Instance(), MSG, pow(), SwimParticle::SetCharge(), SlcStripData, SwimSwimmer::SwimBackward(), GeoSwimmer::SwimBackward(), SwimSwimmer::SwimForward(), GeoSwimmer::SwimForward(), vldc, and ZIncreasesWithTime.

01525 {
01526   MSG("AlgFitTrackCam",Msg::kDebug) << "Swim, specified starting Z" << endl;
01527 
01528   // Initialisations
01529   // customize for bfield scaling.
01530   BField * bf = new BField(*vldc,-1,0);
01531   SwimSwimmer* myswimmer = new SwimSwimmer(*vldc,bf);
01532   
01533   if(UseGeoSwimmer) GeoSwimmer::Instance()->Initialize(*vldc);
01534 
01535   double invSqrt2 = pow(1./2.,0.5);
01536   double charge = 0.;
01537   bool done = false;
01538     
01539   if(fabs(StateVector[4])>1.e-10) {
01540     double modp = fabs(1./StateVector[4]);
01541     
01542     // Fix, to account for fact the cosmic muons could move in direction of negative z
01543     if(ZIncreasesWithTime==false) {modp=-modp;}
01544     
01545     double dsdz = pow((1.+pow(StateVector[2],2)+pow(StateVector[3],2)),0.5);
01546     double dxdz = invSqrt2*(StateVector[2]-StateVector[3]);
01547     double dydz = invSqrt2*(StateVector[2]+StateVector[3]);
01548     
01549     // Set up current muon details
01550     if(StateVector[4]>0.) charge = 1.;
01551     else if(StateVector[4]<0.) charge = -1.;
01552     
01553     TVector3 position(invSqrt2*(StateVector[0]-StateVector[1]),
01554                       invSqrt2*(StateVector[0]+StateVector[1]),
01555                       z);
01556 
01557     TVector3 momentum(modp*(dxdz/dsdz),
01558                       modp*(dydz/dsdz),
01559                       modp/dsdz);
01560     SwimParticle muon(position,momentum);
01561     muon.SetCharge(charge);
01562     SwimZCondition zc(SlcStripData[NewPlane][0].csh->GetZPos());
01563 
01564    
01565     // Do the swim, accounting for direction of motion w.r.t time too
01566     if( (GoForward==true && ZIncreasesWithTime==true)  || (GoForward==false && ZIncreasesWithTime==false) ) {
01567       if(UseGeoSwimmer) {
01568         done = GeoSwimmer::Instance()->SwimForward(muon,SlcStripData[NewPlane][0].csh->GetZPos());
01569       } else {
01570         done = myswimmer->SwimForward(muon,zc);
01571       } 
01572     }
01573     else if( (GoForward==true && ZIncreasesWithTime==false)  || (GoForward==false && ZIncreasesWithTime==true) ) {
01574       if(UseGeoSwimmer) {
01575         done = GeoSwimmer::Instance()->SwimBackward(muon,SlcStripData[NewPlane][0].csh->GetZPos());
01576 
01577       } else {
01578         done = myswimmer->SwimBackward(muon,zc);
01579       }     
01580     }
01581     if(done==true) {
01582       if(muon.GetDirection().Z()!=0. && muon.GetMomentumModulus()!=0.) {
01583         Output[0]=invSqrt2*(muon.GetPosition().Y()+muon.GetPosition().X());
01584         Output[1]=invSqrt2*(muon.GetPosition().Y()-muon.GetPosition().X());
01585         Output[2]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())+(muon.GetDirection().X()/muon.GetDirection().Z()));
01586         Output[3]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())-(muon.GetDirection().X()/muon.GetDirection().Z()));
01587         Output[4]=muon.GetCharge()/muon.GetMomentumModulus();
01588         // Get range and dS from the Swimmer
01589         if(dS) {*dS=muon.GetS();} if(Range) {*Range=muon.GetRange();} if(dE){*dE=muon.GetMomentumModulus()-momentum.Mag();} 
01590       }
01591       else {done=false;}
01592     }
01593     
01594   }
01595 
01596   else{
01597     // If infinite momentum, use straight line extrapolation
01598     double delz = (SlcStripData[NewPlane][0].csh->GetZPos()-z);
01599     Output[0]=StateVector[0] + StateVector[2]*delz;
01600     Output[1]=StateVector[1] + StateVector[3]*delz;
01601     Output[2]=StateVector[2];
01602     Output[3]=StateVector[3];
01603     Output[4]=StateVector[4];
01604 
01605     done=true;
01606   }    
01607   
01608   delete myswimmer;
01609   delete bf;
01610 
01611   return done;
01612 }

bool AlgFitTrackCam::Swim double *  StateVector,
double *  Output,
const int  Plane,
const int  NewPlane,
const bool  GoForward,
double *  dS = 0,
double *  Range = 0,
double *  dE = 0
 

Definition at line 1427 of file AlgFitTrackCam.cxx.

References bave, done(), BField::GetBField(), SwimParticle::GetCharge(), SwimParticle::GetDirection(), SwimParticle::GetMomentumModulus(), SwimParticle::GetPosition(), SwimParticle::GetRange(), SwimParticle::GetS(), GeoSwimmer::Initialize(), GeoSwimmer::Instance(), MSG, nbfield, pow(), SwimParticle::SetCharge(), SlcStripData, SwimSwimmer::SwimBackward(), GeoSwimmer::SwimBackward(), SwimSwimmer::SwimForward(), GeoSwimmer::SwimForward(), vldc, and ZIncreasesWithTime.

Referenced by FillGapsInTrack(), GetCombiPropagator(), SetRangeAnddS(), ShowerSwim(), SpectrometerSwim(), and UpdateStateVector().

01429 {
01430   MSG("AlgFitTrackCam",Msg::kDebug) << "Swim" << endl;
01431 
01432   // Initialisations
01433   // customize for bfield scaling.
01434   BField * bf = new BField(*vldc,-1,0);
01435   SwimSwimmer* myswimmer = new SwimSwimmer(*vldc,bf);
01436   
01437   if(UseGeoSwimmer) GeoSwimmer::Instance()->Initialize(*vldc);
01438  
01439   double invSqrt2 = pow(1./2.,0.5);
01440   double charge = 0.;
01441   bool done = false;
01442     
01443   if(fabs(StateVector[4])>1.e-10) {
01444     double modp = fabs(1./StateVector[4]);
01445     
01446     // Fix, to account for fact the cosmic muons could move in direction of negative z
01447     if(ZIncreasesWithTime==false) {modp=-modp;}
01448     
01449     double dsdz = pow((1.+pow(StateVector[2],2)+pow(StateVector[3],2)),0.5);
01450     double dxdz = invSqrt2*(StateVector[2]-StateVector[3]);
01451     double dydz = invSqrt2*(StateVector[2]+StateVector[3]);
01452     
01453     // Set up current muon details
01454     if(StateVector[4]>0.) charge = 1.;
01455     else if(StateVector[4]<0.) charge = -1.;
01456     
01457     TVector3 position(invSqrt2*(StateVector[0]-StateVector[1]),
01458                       invSqrt2*(StateVector[0]+StateVector[1]),
01459                       SlcStripData[Plane][0].csh->GetZPos());
01460 
01461     TVector3 momentum(modp*(dxdz/dsdz),
01462                       modp*(dydz/dsdz),
01463                       modp/dsdz);
01464 
01465     TVector3 bfield = bf->GetBField(position);
01466     bave += TMath::Sqrt(bfield[0]*bfield[0]+bfield[1]*bfield[1]+bfield[2]*bfield[2]);
01467     nbfield++;
01468 
01469     SwimParticle muon(position,momentum);
01470     muon.SetCharge(charge);
01471     SwimZCondition zc(SlcStripData[NewPlane][0].csh->GetZPos());
01472     // Do the swim, accounting for direction of motion w.r.t time too
01473     if( (GoForward==true && ZIncreasesWithTime==true)  || (GoForward==false && ZIncreasesWithTime==false) ) {
01474       if(UseGeoSwimmer) {
01475         done = GeoSwimmer::Instance()->SwimForward(muon,SlcStripData[NewPlane][0].csh->GetZPos());
01476       } else {
01477         done = myswimmer->SwimForward(muon,zc);
01478       }
01479     }
01480     else if( (GoForward==true && ZIncreasesWithTime==false)  || (GoForward==false && ZIncreasesWithTime==true) ) {
01481       if(UseGeoSwimmer) {
01482         done = GeoSwimmer::Instance()->SwimBackward(muon,SlcStripData[NewPlane][0].csh->GetZPos());
01483       } else {
01484         done = myswimmer->SwimBackward(muon,zc);
01485       }
01486     }
01487     if(done==true) {
01488       if(muon.GetDirection().Z()!=0. && muon.GetMomentumModulus()!=0.) {
01489         Output[0]=invSqrt2*(muon.GetPosition().Y()+muon.GetPosition().X());
01490         Output[1]=invSqrt2*(muon.GetPosition().Y()-muon.GetPosition().X());
01491         Output[2]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())+(muon.GetDirection().X()/muon.GetDirection().Z()));
01492         Output[3]=invSqrt2*((muon.GetDirection().Y()/muon.GetDirection().Z())-(muon.GetDirection().X()/muon.GetDirection().Z()));
01493         Output[4]=muon.GetCharge()/muon.GetMomentumModulus();
01494         // Get range and dS from the Swimmer
01495         if(dS) {*dS=muon.GetS();} if(Range) {*Range=muon.GetRange();} if(dE){*dE=muon.GetMomentumModulus()-momentum.Mag();} 
01496       }
01497       else {done=false;}
01498     }
01499     
01500   }
01501 
01502   else{
01503     // If infinite momentum, use straight line extrapolation
01504     double delz = (SlcStripData[NewPlane][0].csh->GetZPos()-SlcStripData[Plane][0].csh->GetZPos());
01505     Output[0]=StateVector[0] + StateVector[2]*delz;
01506     Output[1]=StateVector[1] + StateVector[3]*delz;
01507     Output[2]=StateVector[2];
01508     Output[3]=StateVector[3];
01509     Output[4]=StateVector[4];
01510 
01511     done=true;
01512   }    
01513   
01514   delete myswimmer;
01515   delete bf;
01516   return done;
01517 }

void AlgFitTrackCam::TimingFit CandFitTrackCamHandle cth  ) 
 

Definition at line 2435 of file AlgFitTrackCam.cxx.

References C, Chi2(), UgliStripHandle::ClearFiber(), digit(), CandDigitHandle::GetCharge(), CandStripHandle::GetCharge(), CandRecoHandle::GetCharge(), CandHandle::GetDaughterIterator(), VldContext::GetDetector(), CandTrackHandle::GetdS(), PlexSEIdAltL::GetEnd(), UgliStripHandle::GetHalfLength(), CandStripHandle::GetPlaneView(), CandDigitHandle::GetPlexSEIdAltL(), CandStripHandle::GetStripEndId(), UgliGeomHandle::GetStripHandle(), CandTrackHandle::GetT(), CandStripHandle::GetTime(), CandTrackHandle::GetU(), CandTrackHandle::GetV(), InitTrkStripData, MaxPlane, MinPlane, MSG, pow(), s(), CandRecoHandle::SetEndT(), CandTrackHandle::SetNTimeFitDigit(), CandTrackHandle::SetTimeBackwardFitNDOF(), CandTrackHandle::SetTimeBackwardFitRMS(), CandTrackHandle::SetTimeFitChi2(), CandTrackHandle::SetTimeForwardFitNDOF(), CandTrackHandle::SetTimeForwardFitRMS(), CandRecoHandle::SetTimeOffset(), CandRecoHandle::SetTimeSlope(), CandRecoHandle::SetVtxT(), StripListTime, vldc, UgliStripHandle::WlsPigtail(), and ZIncreasesWithTime.

Referenced by SetTrackProperties().

02436 {
02437   MSG("AlgFitTrackCam",Msg::kDebug) << "TimingFit" << endl;
02438 
02439   // Initialisations
02441   double s; double t; double q; int n=0; 
02442   double MinUncertainty = 0.; double MinCT=-3000.;
02443   
02444   // Time of first strip in track
02445   StripListTime=9.e30;
02446 
02447   // Create an offset such that dS=0 at the MinPlane
02448   double dSOffset=0.; double Sign=-1.; double dS[490];
02449   if(ZIncreasesWithTime==true) {dSOffset=cth.GetdS(MinPlane); Sign=1.;}
02450 
02451   // Store data needed in arrays. Charge is in PEs.
02452   double Qp[490];  double Qm[490];
02453   double CTp[490]; double CTm[490];
02454   int Skipp[490];  int Skipm[490];
02455   double C=3.e8;   
02456 
02457   double ErrorParam[3];
02458   ErrorParam[0]=0.; ErrorParam[1]=0.; ErrorParam[2]=0.;
02459 
02460   // Zero the arrays
02461   for(int i=0; i<490; ++i) { 
02462     dS[i]=0.; Qp[i]=0.; Qm[i]=0.; CTp[i]=0.; 
02463     CTm[i]=0.; Skipp[i]=0; Skipm[i]=0;
02464   }
02466 
02467 
02468 
02469   // Organise timing for the Far Detector
02471   if(vldc->GetDetector()==Detector::kFar) {  
02472     // Parameters for PE vs time fit residual
02473     MinUncertainty=0.56;
02474     ErrorParam[0]=0.56; ErrorParam[1]=0.50; ErrorParam[2]=-0.34;
02475 
02476     // Loop over all planes
02477     for(int i=MinPlane; i<=MaxPlane; ++i) {
02478         
02479       if(InitTrkStripData[i].size()>0) {
02480         dS[i]=Sign*(dSOffset-cth.GetdS(i));
02481         
02482         CTp[i]=C*cth.GetT(i,StripEnd::kPositive);
02483         CTm[i]=C*cth.GetT(i,StripEnd::kNegative);
02484         
02485         if(CTp[i]>MinCT && CTp[i]<StripListTime) {StripListTime=CTp[i];}
02486         if(CTm[i]>MinCT && CTm[i]<StripListTime) {StripListTime=CTm[i];}
02487         
02488         for(unsigned int j=0; j<InitTrkStripData[i].size(); ++j) {
02489           Qp[i]+=InitTrkStripData[i][j].csh->GetCharge(StripEnd::kPositive);
02490           Qm[i]+=InitTrkStripData[i][j].csh->GetCharge(StripEnd::kNegative);
02491         }
02492       }
02493     }
02494 
02495     // Subtract StripList time
02496     if(StripListTime<8.e30) {
02497       for(int i=MinPlane; i<=MaxPlane; ++i) {
02498         if(InitTrkStripData[i].size()>0) {
02499           CTp[i]-=StripListTime;
02500           CTm[i]-=StripListTime;
02501         }
02502       }
02503     }
02504     else {StripListTime=0.;}
02505 
02506   } // End Far Detector Section
02508 
02509 
02510 
02511   // Organise timing for the Near Detector
02513   if(vldc->GetDetector()==Detector::kNear) {
02514     // Parameters for PE vs time fit residual
02515     MinUncertainty=1.19;
02516     ErrorParam[0]=1.13; ErrorParam[1]=0.63; ErrorParam[2]=-0.21;
02517 
02518     double Index=1.77; double DistFromCentre=0.; double CTime=0.;  double FibreDist=0.;    
02519     double halfLength=0.; double DigChg=0.; double PlaneDigChg;
02520 
02521     StripEnd::StripEnd_t StpEnd = StripEnd::kUnknown;
02522     CandStripHandle* strip; CandDigitHandle* digit;
02523 
02524     UgliGeomHandle ugh = UgliGeomHandle(*vldc);
02525     UgliStripHandle striphandle;
02526 
02527 
02528     // Loop over all planes
02529     for(int i=MinPlane; i<=MaxPlane; ++i)
02530       {
02531         if(InitTrkStripData[i].size()>0) {dS[i]=Sign*(dSOffset-cth.GetdS(i));}
02532         PlaneDigChg=0.;
02533 
02534         // Loop over track strips on plane. Only +ve StripEnds should have charge.
02535         for(unsigned int j=0; j<InitTrkStripData[i].size(); ++j) {
02536           strip = InitTrkStripData[i][j].csh;
02537           CandDigitHandleItr digitItr(strip->GetDaughterIterator());
02538 
02539           Qp[i]+=strip->GetCharge(StripEnd::kPositive);
02540 
02541 
02542           // Loop over digits on strip. 
02544           while( (digit = digitItr()) ) { 
02545             StpEnd=digit->GetPlexSEIdAltL().GetEnd();
02546 
02547             if(StpEnd==StripEnd::kPositive) {
02548               FibreDist = 0.; DistFromCentre = 0.; CTime=0.; DigChg=0.;
02549               UgliStripHandle stripHandle = ugh.GetStripHandle(strip->GetStripEndId());
02550               halfLength = stripHandle.GetHalfLength(); 
02551          
02552               if(strip->GetPlaneView()==2) {DistFromCentre = cth.GetV(i);}
02553               if(strip->GetPlaneView()==3) {DistFromCentre = -cth.GetU(i);}
02554               
02555               FibreDist = (halfLength + DistFromCentre + stripHandle.ClearFiber(StpEnd) 
02556                            + stripHandle.WlsPigtail(StpEnd));
02557               
02558               CTime = C*(strip->GetTime(StpEnd)) - Index*FibreDist;
02559               DigChg=digit->GetCharge();
02560               
02561               PlaneDigChg+=DigChg; CTp[i]+=DigChg*CTime;
02562 
02563               if(CTime>MinCT && CTime<StripListTime) {StripListTime=CTime;}
02564             }
02565           }
02567         }
02568         if(PlaneDigChg>0.) CTp[i]/=PlaneDigChg;
02569       }
02570 
02571 
02572     // Subtract StripList time
02573     if(StripListTime<8.e30) {
02574       for(int i=MinPlane; i<=MaxPlane; ++i) {
02575         if(InitTrkStripData[i].size()>0) {
02576           CTp[i]-=StripListTime;
02577         }
02578       }
02579     }
02580     else {StripListTime=0.;}
02581     
02582   } // End near detector section
02584     
02585     
02586 
02587   // Carry out a simple straight line fit for T vs dS
02589   // Sqt: sum of charge*time, Sqss: sum of charge*dS*dS, etc.
02590   double Sqs=0; double Sqt=0; double Sqss=0; double Sqst=0; double Sqtt=0; double Sq=0;
02591   double TimeSlope=-999; double TimeOffset=-999; double RMS=-999;
02592   double CTCut = 0.; bool CalculateChi2=true;
02593 
02594   
02595   // On first iteration, carry out simple fit. Remove outlying points on subsequent passes.
02596   for(int itr=0; itr<3; ++itr) {
02597  
02598     for(int i=MinPlane; i<=MaxPlane; ++i) { 
02599 
02600       // Only consider planes where we found our final strips
02601       if(InitTrkStripData[i].size()>0) { 
02602         
02603         // For positive strip ends      
02604         s=dS[i]; q=Qp[i]; t=CTp[i];
02605         
02606         if(q>0. && t>MinCT && Skipp[i]==0) {
02607           if(itr==0) {Sq+=q; Sqs+=q*s; Sqt+=q*t; Sqss+=q*s*s; Sqst+=q*s*t; Sqtt+=q*t*t; n++;}
02608           
02609           else if(fabs(t-TimeOffset-(s*TimeSlope)) > CTCut) {
02610             Sqs-=q*s; Sqt-=q*t; Sqss-=q*s*s; Sqst-=q*s*t; Sqtt-=q*t*t; Sq-=q; n--; Skipp[i]=1;
02611           }
02612         }
02613 
02614 
02615         // For negative strip ends
02616         q=Qm[i]; t=CTm[i];
02617         
02618         if(q>0. && t>MinCT && Skipm[i]==0) {
02619           if(itr==0) {Sq+=q; Sqs+=q*s; Sqt+=q*t; Sqss+=q*s*s; Sqst+=q*s*t; Sqtt+=q*t*t; n++;}
02620           
02621           else if(fabs(t-TimeOffset-(s*TimeSlope)) > CTCut) {
02622             Sqs-=q*s; Sqt-=q*t; Sqss-=q*s*s; Sqst-=q*s*t; Sqtt-=q*t*t; Sq-=q; n--; Skipm[i]=1;
02623           }
02624         }
02625 
02626       }
02627     }
02628     
02629     // Calculate parameters
02630     if( (Sq*Sqss-Sqs*Sqs)!=0. && Sq!=0. ) {
02631       TimeSlope  = (Sq*Sqst-Sqs*Sqt)/(Sq*Sqss-Sqs*Sqs);
02632       TimeOffset = (Sqt*Sqss-Sqs*Sqst)/(Sq*Sqss-Sqs*Sqs);
02633       if( ((Sqtt/Sq)-((Sqt/Sq)*(Sqt/Sq)))>0. ) {
02634         RMS = pow((Sqtt/Sq)-((Sqt/Sq)*(Sqt/Sq)),0.5);
02635         CTCut = 3.+RMS;
02636       }
02637       else {CTCut = 3.5;}
02638     }
02639     else  {CalculateChi2=false; break;}
02640   }
02642 
02643 
02644 
02645   // Set timing properties for the fitted track
02647   if(n!=0 && CalculateChi2==true) {
02648 
02649     // Offset, slope and vtx/end times
02651     cth.SetTimeOffset((TimeOffset+StripListTime)/C);
02652     cth.SetTimeSlope(TimeSlope/C);
02653 
02654     if(ZIncreasesWithTime==true) {
02655       cth.SetVtxT((TimeOffset+StripListTime)/C); 
02656       cth.SetEndT((TimeOffset+StripListTime)/C+(dS[MaxPlane]*TimeSlope/C));
02657     }
02658     else {
02659       cth.SetEndT((TimeOffset+StripListTime)/C); 
02660       cth.SetVtxT((TimeOffset+StripListTime)/C+(dS[MaxPlane]*TimeSlope/C));
02661     }
02663 
02664 
02665     // Chi2
02667     double Uncertainty; double Residual2; double Chi2=0; 
02668  
02669     for(int i=MinPlane; i<=MaxPlane; ++i) { 
02670       
02671       if(InitTrkStripData[i].size()>0) { 
02672         // For positive strip ends
02673         s=dS[i]; q=Qp[i]; t=CTp[i];
02674         if(q>0. && t>MinCT && Skipp[i]==0) {
02675           Residual2=pow(t-TimeOffset-(s*TimeSlope),2);
02676 
02677           // From a rough parameterisation of uncertainty (in CT) vs number of PEs
02678           if (q<20) {Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*q);}
02679           else {Uncertainty=MinUncertainty;}
02680 
02681           if(Uncertainty!=0.) {Chi2+=Residual2/pow(Uncertainty,2);}
02682         }
02683 
02684 
02685         // For negative strip ends
02686         q=Qm[i]; t=CTm[i];
02687         if(q>0. && t>MinCT && Skipm[i]==0) {
02688           Residual2=pow(t-TimeOffset-(s*TimeSlope),2);
02689 
02690           // From a rough parameterisation of uncertainty (in CT) vs number of PEs
02691           if (q<20) {Uncertainty = ErrorParam[0]+exp(ErrorParam[1]+ErrorParam[2]*q);}
02692           else {Uncertainty=MinUncertainty;}
02693           
02694           if(Uncertainty!=0.) {Chi2+=Residual2/pow(Uncertainty,2);}
02695         }
02696       }
02697       
02698     }
02699     // Set these properties
02700     cth.SetTimeFitChi2(Chi2);
02701     cth.SetNTimeFitDigit(n);
02702   }
02704 
02705 
02706 
02707   // Now carry out fits with gradients constrained to be +/- c
02709   double CTIntercept[2]; double Csigma[2]; double Ctrunc[2]; 
02710   double ChiSqPositive=-999; double ChiSqNegative=-999; 
02711   int ChiSqNdfPos=-999; int ChiSqNdfNeg=-999;  
02712   double Swtt[2]; double Swt[2]; double Sw[2]; int npts[2]={0,0};
02713 
02714   if(Sq!=0.) {
02715     CTIntercept[0]=Sqt/Sq; Csigma[0]=-99999.9; Ctrunc[0]=-99999.9;
02716     CTIntercept[1]=Sqt/Sq; Csigma[1]=-99999.9; Ctrunc[1]=-99999.9;
02717     
02718     for(int itr=0; itr<2; ++itr)
02719       {
02720         Swtt[0]=0.; Swt[0]=0.; Sw[0]=0.; npts[0]=0;
02721         Swtt[1]=0.; Swt[1]=0.; Sw[1]=0.; npts[1]=0;
02722         
02723         for(int i=0; i<490; ++i)
02724           {
02725             // For positive strip ends
02726             if(Qp[i]>0. && CTp[i]>MinCT) {
02727               q=Qp[i]; 
02728               
02729               t=CTp[i]-dS[i]+CTIntercept[0];
02730               if(Ctrunc[0]<0. || fabs(t)<Ctrunc[0]) {Swtt[0]+=q*t*t; Swt[0]+=q*t; Sw[0]+=q; ++npts[0];}
02731               
02732               t=CTp[i]+dS[i]+CTIntercept[1];
02733               if(Ctrunc[1]<0. || fabs(t)<Ctrunc[1]) {Swtt[1]+=q*t*t; Swt[1]+=q*t; Sw[1]+=q; ++npts[1];}
02734             }
02735             
02736             // For negative strip ends
02737             if(Qm[i]>0. && CTm[i]>MinCT) {
02738               q=Qm[i]; 
02739               
02740               t=CTm[i]-dS[i]+CTIntercept[0];
02741               if(Ctrunc[0]<0. || fabs(t)<Ctrunc[0]) {Swtt[0]+=q*t*t; Swt[0]+=q*t; Sw[0]+=q; ++npts[0];}
02742               
02743               t=CTm[i]+dS[i]+CTIntercept[1];
02744               if(Ctrunc[1]<0. || fabs(t)<Ctrunc[1]) {Swtt[1]+=q*t*t; Swt[1]+=q*t; Sw[1]+=q; ++npts[1];}
02745             }
02746           }
02747         
02748         // Results for fit with gradient +C
02749         if(npts[0]>1 && Sw[0]!=0.) {
02750           CTIntercept[0]=CTIntercept[0]-Swt[0]/Sw[0]; Csigma[0]=0.; 
02751           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);}
02752           ChiSqPositive=Csigma[0]; ChiSqNdfPos=npts[0]-1; 
02753           Ctrunc[0]=Csigma[0]+3.;
02754         }
02755         
02756         // Results for fit with gradient -C
02757         if(npts[1]>1 && Sw[1]!=0.) {
02758           CTIntercept[1]=CTIntercept[1]-Swt[1]/Sw[1]; Csigma[1]=0.;
02759           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);}
02760           ChiSqNegative=Csigma[1]; ChiSqNdfNeg=npts[1]-1; 
02761           Ctrunc[1]=Csigma[1]+3.;
02762         }
02763         
02764       }
02765   }
02766   // Set these properties
02767   cth.SetTimeForwardFitRMS(ChiSqPositive);
02768   cth.SetTimeForwardFitNDOF(ChiSqNdfPos);
02769   cth.SetTimeBackwardFitRMS(ChiSqNegative);
02770   cth.SetTimeBackwardFitNDOF(ChiSqNdfNeg);
02772    
02773 }

void AlgFitTrackCam::Trace const char *  c  )  const [virtual]
 

Reimplemented from AlgBase.

Definition at line 3642 of file AlgFitTrackCam.cxx.

03643 {
03644 }

void AlgFitTrackCam::UpdateCovMatrix  ) 
 

Definition at line 2127 of file AlgFitTrackCam.cxx.

References C_k, C_k_intermediate, H_k, Identity, K_k, and MSG.

Referenced by GoBackwards(), GoForwards(), ShowerSwim(), and SpectrometerSwim().

02128 {
02129   // C_k = (Identity - (K_k * H_k) ) * C_k_intermediate
02130   MSG("AlgFitTrackCam",Msg::kDebug) << "UpdateCovMatrix" << endl;
02131 
02132   for (int i=0; i<5; ++i) {
02133     for (int j=0; j<5; ++j) {  
02134       C_k[i][j]=0;
02135       for (int m=0; m<5; ++m) {   
02136         C_k[i][j]+=(Identity[i][m] - K_k[i]*H_k[m]) * C_k_intermediate[m][j];
02137       }
02138     }
02139   }
02140 
02141 
02142   // Diagonal elements should be positive
02143   double covlim = 1.e-8;
02144 
02145   for(int i=0; i<5; ++i) {
02146     if(C_k[i][i]<covlim) {
02147       MSG("AlgFitTrackCam",Msg::kVerbose) << "Negative diagonal element in C_k" << endl;
02148       C_k[i][i]=covlim;
02149     }
02150   }
02151 
02152 
02153   // Display
02154   if(debug) {
02155     cout << "Filtered Covariance matrix" << endl;
02156     for(int i=0; i<5; ++i) {
02157       for(int j=0; j<5; ++j) {
02158         cout << C_k[i][j] << " ";
02159       }
02160       cout << endl;  
02161     }
02162   }
02163 
02164 }

void AlgFitTrackCam::UpdateStateVector const int  Plane,
const int  NewPlane,
const bool  GoForward
 

Definition at line 1996 of file AlgFitTrackCam.cxx.

References CheckValues(), K_k, MSG, PassTrack, SlcStripData, Swim(), TotalNSwimFail, TrkStripData, x_k, x_k_minus, and ZIncreasesWithTime.

Referenced by GoBackwards(), GoForwards(), ShowerSwim(), and SpectrometerSwim().

01997 {  
01998   // x_k = (F_k_minus * x_k_minus) + K_k(m_k - (H_k * F_k_minus * x_k_minus) )
01999   MSG("AlgFitTrackCam",Msg::kDebug) << "UpdateStateVector" << endl;
02000 
02001 
02002   double HFx=0;
02003   double m_k=0;
02004   double MeasurementFactor=0;
02005   int nswimfail=0;
02006 
02007 
02008   // Calculate F_k_minus * x_k_minus, using the Swimmer
02009   // Also get an accurate measure of dS and Range from the Swimmer
02011   double StateVector[5];
02012   double Prediction[5];
02013   bool GetPrediction=false;
02014 
02015   for(int i=0; i<5; ++i) {StateVector[i]=x_k_minus[i];}
02016 
02017   // Prediction could be used without GeoSwimmer calculation. Prediction is initialized with linear extrapolation.
02018   for(int i=0; i<5; i++) {
02019     double delz = (SlcStripData[NewPlane][0].csh->GetZPos()-SlcStripData[Plane][0].csh->GetZPos());
02020     Prediction[0]=StateVector[0] + StateVector[2]*delz;
02021     Prediction[1]=StateVector[1] + StateVector[3]*delz;
02022     Prediction[2]=StateVector[2];
02023     Prediction[3]=StateVector[3];
02024     Prediction[4]=StateVector[4];
02025   }
02026 
02027   // Do the swim
02029   while(GetPrediction==false && nswimfail<=10) {
02030     MSG("AlgFitTrackCam",Msg::kVerbose) << " state " << StateVector[0] << " " 
02031                                         << StateVector[1] << " " << StateVector[2] << " " 
02032                                         << StateVector[3] << " " << StateVector[4] << endl;   
02033     
02034     GetPrediction=Swim(StateVector, Prediction, Plane, NewPlane, GoForward);
02035     
02036     MSG("AlgFitTrackCam",Msg::kVerbose) << " predict state " << Prediction[0] << " " 
02037                                         << Prediction[1] << " " << Prediction[2] << " " 
02038                                         << Prediction[3] << " " << Prediction[4] << endl;
02039 
02040     if(GetPrediction==false) {
02041       StateVector[4]*=0.5; 
02042       nswimfail++; TotalNSwimFail++;
02043       MSG("AlgFitTrackCam",Msg::kVerbose) << "UpdateStateVector, Prediction failed - Double momentum and swim again" << endl;
02044     }
02045   }
02046 
02047   if(nswimfail>10) {  // Swim shouldn't fail, as it succeeded to get the propagator
02048     MSG("AlgFitTrackCam",Msg::kDebug) << "UpdateStateVector, nswimfail>10, fail track" << endl;
02049     PassTrack=false;
02050   }
02052 
02053   
02055 
02056 
02057   MSG("AlgFitTrackCam",Msg::kDebug) << "UpdateStateVector, Check predicted state " << endl;
02058   CheckValues(Prediction, NewPlane);
02059 
02060 
02061   // Calculate H_k * F_k_minus * x_k_minus
02063   if(TrkStripData[NewPlane][0].PlaneView==2) {HFx=Prediction[0];}
02064   if(TrkStripData[NewPlane][0].PlaneView==3) {HFx=Prediction[1];}
02065 
02066   MSG("AlgFitTrackCam",Msg::kVerbose) << "HFx " << HFx << endl;
02068 
02069   
02070   // Read in measurement
02072   m_k=TrkStripData[NewPlane][0].TPos;
02073   MSG("AlgFitTrackCam",Msg::kVerbose) << "m_k " << TrkStripData[NewPlane][0].TPos << endl;
02074   
02075   MeasurementFactor=(m_k-HFx);
02077 
02078   
02079   // Calculate x_k
02081   for (int i=0; i<5; ++i) {
02082     x_k[i]=0.;
02083     x_k[i]+=Prediction[i]+(K_k[i]*MeasurementFactor);
02084   }
02086 
02087 
02088   MSG("AlgFitTrackCam",Msg::kDebug) << "UpdateStateVector, Check filtered state " << endl;
02089   CheckValues(x_k, NewPlane);
02090 
02091 
02092   // Care with multiple range corrections - do not want to flip sign
02093   // (multiple corrections mean sign changes can occur even though absolute value stays same)
02095   // JAM up to 40 from 4
02096 
02097   double Maxqp = 4.;
02098   if(fabs(x_k_minus[4])==Maxqp && 
02099      ( (GoForward==true && ZIncreasesWithTime==true) 
02100        || (GoForward==false && ZIncreasesWithTime==false) ) ) 
02101     {
02102       if(!LastIteration) x_k[4] = (x_k_minus[4]>0 ? Maxqp : -Maxqp);
02103       //      cout << " resetting in UpdateStateVector " <<  endl;
02104     }
02106 
02107   //if on last plane in forward swim, disregard sign flip
02108   if(x_k_minus[4]!=0){
02109     if ( x_k[4]/x_k_minus[4]<0 && 
02110         ( (GoForward==true && ZIncreasesWithTime==true && NewPlane >= EndofRangePlane ) 
02111           || (GoForward==false && ZIncreasesWithTime==false && NewPlane <= EndofRangePlane ) )) 
02112       {
02113         x_k[4] = -x_k[4];
02114       }
02115   }
02116   
02117   // Display
02118   MSG("AlgFitTrackCam",Msg::kVerbose) << "Filtered State vector: "
02119                                       << x_k[0] << " " << x_k[1] << " " << x_k[2] << " "
02120                                       << x_k[3] << " " << x_k[4] << endl;
02121 }


Member Data Documentation

Double_t AlgFitTrackCam::bave [private]
 

Definition at line 108 of file AlgFitTrackCam.h.

Referenced by RunAlg(), SetTrackProperties(), and Swim().

double AlgFitTrackCam::C_k[5][5] [private]
 

Definition at line 116 of file AlgFitTrackCam.h.

Referenced by GoBackwards(), GoForwards(), MoveArrays(), RunAlg(), SpectrometerSwim(), and UpdateCovMatrix().

double AlgFitTrackCam::C_k_intermediate[5][5] [private]
 

Definition at line 118 of file AlgFitTrackCam.h.

Referenced by CalcKalmanGain(), ExtrapCovMatrix(), RunAlg(), and UpdateCovMatrix().

double AlgFitTrackCam::C_k_minus[5][5] [private]
 

Definition at line 117 of file AlgFitTrackCam.h.

Referenced by ExtrapCovMatrix(), GetInitialCovarianceMatrix(), MoveArrays(), and RunAlg().

bool AlgFitTrackCam::debug [private]
 

Definition at line 140 of file AlgFitTrackCam.h.

Referenced by RunAlg().

double AlgFitTrackCam::DeltaPlane [private]
 

Definition at line 135 of file AlgFitTrackCam.h.

Referenced by GetCombiPropagator(), GetNoiseMatrix(), ResetCovarianceMatrix(), and RunAlg().

double AlgFitTrackCam::DeltaZ [private]
 

Definition at line 134 of file AlgFitTrackCam.h.

Referenced by GetCombiPropagator(), GetNoiseMatrix(), ResetCovarianceMatrix(), and RunAlg().

double AlgFitTrackCam::EndCov[5] [private]
 

Definition at line 129 of file AlgFitTrackCam.h.

Referenced by GoBackwards(), GoForwards(), RunAlg(), and SetTrackProperties().

Bool_t AlgFitTrackCam::EndofRange [private]
 

Definition at line 109 of file AlgFitTrackCam.h.

Referenced by CheckValues(), GoBackwards(), and GoForwards().

Int_t AlgFitTrackCam::EndofRangePlane [private]
 

Definition at line 110 of file AlgFitTrackCam.h.

Referenced by GoBackwards(), and GoForwards().

double AlgFitTrackCam::F_k[5][5] [private]
 

Definition at line 119 of file AlgFitTrackCam.h.

Referenced by RunAlg().

double AlgFitTrackCam::F_k_minus[5][5] [private]
 

Definition at line 120 of file AlgFitTrackCam.h.

Referenced by ExtrapCovMatrix(), GetCombiPropagator(), and RunAlg().

vector<FiltDataStruct> AlgFitTrackCam::FilteredData[490] [private]
 

Definition at line 105 of file AlgFitTrackCam.h.

Referenced by FillGapsInTrack(), FindTheStrips(), RunAlg(), RunTheFitter(), SetRangeAnddS(), SetTrackProperties(), ShowerStrips(), SpectrometerSwim(), and StoreFilteredData().

PlaneOutline AlgFitTrackCam::fPL [private]
 

Definition at line 155 of file AlgFitTrackCam.h.

Referenced by NDPlaneIsActive(), and SetRangeAnddS().

int AlgFitTrackCam::H_k[5] [private]
 

Definition at line 125 of file AlgFitTrackCam.h.

Referenced by CalcKalmanGain(), GoBackwards(), GoForwards(), RunAlg(), ShowerSwim(), SpectrometerSwim(), and UpdateCovMatrix().

int AlgFitTrackCam::Identity[5][5] [private]
 

Definition at line 126 of file AlgFitTrackCam.h.

Referenced by RunAlg(), and UpdateCovMatrix().

vector<StripStruct> AlgFitTrackCam::InitTrkStripData[490] [private]
 

Definition at line 101 of file AlgFitTrackCam.h.

Referenced by FindTheStrips(), GetFitData(), InitialFramework(), RunAlg(), ShowerSwim(), SpectrometerSwim(), and TimingFit().

double AlgFitTrackCam::K_k[5] [private]
 

Definition at line 123 of file AlgFitTrackCam.h.

Referenced by CalcKalmanGain(), RunAlg(), UpdateCovMatrix(), and UpdateStateVector().

Bool_t AlgFitTrackCam::LastIteration [private]
 

Definition at line 111 of file AlgFitTrackCam.h.

Referenced by GoBackwards(), GoForwards(), and RunTheFitter().

int AlgFitTrackCam::MaxPlane [private]
 

Definition at line 131 of file AlgFitTrackCam.h.

Referenced by FillGapsInTrack(), FindTheStrips(), InitialFramework(), RemoveTrkHitsInShw(), RunAlg(), RunTheFitter(), SetTrackProperties(), ShowerSwim(), SpectrometerSwim(), and TimingFit().

double AlgFitTrackCam::MeanTrackTime [private]
 

Definition at line 154 of file AlgFitTrackCam.h.

Referenced by InitialFramework(), and SpectrometerSwim().

int AlgFitTrackCam::MinPlane [private]
 

Definition at line 132 of file AlgFitTrackCam.h.

Referenced by FillGapsInTrack(), FindTheStrips(), InitialFramework(), RemoveTrkHitsInShw(), RunAlg(), RunTheFitter(), SetTrackProperties(), ShowerStrips(), ShowerSwim(), and TimingFit().

Int_t AlgFitTrackCam::nbfield [private]
 

Definition at line 107 of file AlgFitTrackCam.h.

Referenced by RunAlg(), SetTrackProperties(), and Swim().

int AlgFitTrackCam::NIter [private]
 

Definition at line 150 of file AlgFitTrackCam.h.

Referenced by GoBackwards(), GoForwards(), RunAlg(), RunTheFitter(), and SetTrackProperties().

int AlgFitTrackCam::NumFinderStrips [private]
 

Definition at line 153 of file AlgFitTrackCam.h.

Referenced by GenerateNDSpectStrips(), InitialFramework(), and RunAlg().

bool AlgFitTrackCam::PassTrack [private]
 

Definition at line 143 of file AlgFitTrackCam.h.

Referenced by CheckValues(), GoBackwards(), GoForwards(), RunAlg(), RunTheFitter(), SpectrometerSwim(), and UpdateStateVector().

double AlgFitTrackCam::Q_k[5][5] [private]
 

Definition at line 121 of file AlgFitTrackCam.h.

Referenced by RunAlg().

double AlgFitTrackCam::Q_k_minus[5][5] [private]
 

Definition at line 122 of file AlgFitTrackCam.h.

Referenced by ExtrapCovMatrix(), GetNoiseMatrix(), and RunAlg().

bool AlgFitTrackCam::SaveData [private]
 

Definition at line 145 of file AlgFitTrackCam.h.

Referenced by RunAlg(), and RunTheFitter().

int AlgFitTrackCam::ShowerEntryPlane [private]
 

Definition at line 148 of file AlgFitTrackCam.h.

Referenced by RunAlg(), SetTrackProperties(), and ShowerStrips().

vector<StripStruct> AlgFitTrackCam::SlcStripData[490] [private]
 

Definition at line 100 of file AlgFitTrackCam.h.

Referenced by CleanNDLists(), FillGapsInTrack(), FindTheStrips(), GenerateNDSpectStrips(), GetFitData(), InitialFramework(), RunAlg(), SetRangeAnddS(), SetTrackProperties(), ShowerStrips(), ShowerSwim(), SpectrometerSwim(), Swim(), and UpdateStateVector().

double AlgFitTrackCam::StripListTime [private]
 

Definition at line 157 of file AlgFitTrackCam.h.

Referenced by TimingFit().

bool AlgFitTrackCam::SwimThroughShower [private]
 

Definition at line 146 of file AlgFitTrackCam.h.

Referenced by RemoveTrkHitsInShw(), RunAlg(), RunTheFitter(), ShowerStrips(), and ShowerSwim().

int AlgFitTrackCam::TotalNSwimFail [private]
 

Definition at line 151 of file AlgFitTrackCam.h.

Referenced by GetCombiPropagator(), RunAlg(), SetTrackProperties(), and UpdateStateVector().

const CandTrackHandle* AlgFitTrackCam::track [private]
 

Definition at line 138 of file AlgFitTrackCam.h.

Referenced by CheckValues(), GetFitData(), InitialFramework(), NDStripBegTime(), RunAlg(), RunTheFitter(), and SetPropertiesFromFinderTrack().

vector<TrkDataStruct> AlgFitTrackCam::TrkStripData[490] [private]
 

Definition at line 103 of file AlgFitTrackCam.h.

Referenced by CalcKalmanGain(), GetCombiPropagator(), GetFitData(), GetNoiseMatrix(), GoBackwards(), GoForwards(), RemoveTrkHitsInShw(), RunAlg(), RunTheFitter(), SetTrackProperties(), and UpdateStateVector().

int AlgFitTrackCam::UseGeoSwimmer [private]
 

Definition at line 113 of file AlgFitTrackCam.h.

Referenced by RunAlg().

VldContext* AlgFitTrackCam::vldc [private]
 

Definition at line 137 of file AlgFitTrackCam.h.

Referenced by GetNoiseMatrix(), InitialFramework(), NDStripBegTime(), RunAlg(), RunTheFitter(), SetPropertiesFromFinderTrack(), SetRangeAnddS(), SetTrackProperties(), Swim(), and TimingFit().

double AlgFitTrackCam::VtxCov[5] [private]
 

Definition at line 128 of file AlgFitTrackCam.h.

Referenced by GoBackwards(), GoForwards(), RunAlg(), and SetTrackProperties().

double AlgFitTrackCam::x_k[5] [private]
 

Definition at line 114 of file AlgFitTrackCam.h.

Referenced by GoBackwards(), GoForwards(), MoveArrays(), RunAlg(), RunTheFitter(), SetTrackProperties(), ShowerSwim(), StoreFilteredData(), and UpdateStateVector().

double AlgFitTrackCam::x_k4_biased [private]
 

Definition at line 112 of file AlgFitTrackCam.h.

Referenced by RunAlg(), RunTheFitter(), and SetTrackProperties().

double AlgFitTrackCam::x_k_minus[5] [private]
 

Definition at line 115 of file AlgFitTrackCam.h.

Referenced by GetCombiPropagator(), GetNoiseMatrix(), MoveArrays(), RunAlg(), ShowerSwim(), SpectrometerSwim(), and UpdateStateVector().

bool AlgFitTrackCam::ZIncreasesWithTime [private]
 

Definition at line 142 of file AlgFitTrackCam.h.

Referenced by FillGapsInTrack(), FindTheStrips(), GetInitialCovarianceMatrix(), GoBackwards(), GoForwards(), RemoveTrkHitsInShw(), RunAlg(), RunTheFitter(), SetPropertiesFromFinderTrack(), SetRangeAnddS(), SetTrackProperties(), ShowerStrips(), ShowerSwim(), Swim(), TimingFit(), and UpdateStateVector().


The documentation for this class was generated from the following files:
Generated on Fri Mar 28 15:53:16 2008 for loon by  doxygen 1.3.9.1