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 72 of file AlgFitTrackCam.cxx.

00073 {
00074 }

AlgFitTrackCam::~AlgFitTrackCam  )  [virtual]
 

Definition at line 79 of file AlgFitTrackCam.cxx.

00080 {
00081 }


Member Function Documentation

void AlgFitTrackCam::CalcKalmanGain const int  NewPlane  ) 
 

Definition at line 1955 of file AlgFitTrackCam.cxx.

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

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

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

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

Definition at line 2177 of file AlgFitTrackCam.cxx.

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

Referenced by UpdateStateVector().

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

void AlgFitTrackCam::CleanNDLists CandFitTrackHandle cth,
CandContext cx
 

Definition at line 3390 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().

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

void AlgFitTrackCam::ExtrapCovMatrix  ) 
 

Definition at line 1906 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().

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

void AlgFitTrackCam::FillGapsInTrack  ) 
 

Definition at line 788 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().

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

bool AlgFitTrackCam::FindTheStrips CandFitTrackCamHandle cth,
bool  MakeTheTrack
 

Definition at line 875 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().

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

void AlgFitTrackCam::GenerateNDSpectStrips const CandSliceHandle slice,
CandContext cx
 

Definition at line 3096 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().

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

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

Definition at line 1337 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().

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

void AlgFitTrackCam::GetFitData int  Plane1,
int  Plane2
 

Definition at line 701 of file AlgFitTrackCam.cxx.

References Plane::GetStrip(), InitTrkStripData, MSG, TrkDataStruct::PlaneView, SlcStripData, TrkDataStruct::TPos, TrkDataStruct::TPosError, TrkStripData, and TrkDataStruct::ZPos.

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

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

void AlgFitTrackCam::GetInitialCovarianceMatrix const bool  FirstIteration  ) 
 

Definition at line 1721 of file AlgFitTrackCam.cxx.

References C_k_minus, min, MSG, and ZIncreasesWithTime.

Referenced by ResetCovarianceMatrix(), and RunTheFitter().

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

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

Definition at line 1796 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().

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

void AlgFitTrackCam::GoBackwards  ) 
 

Definition at line 1258 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().

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

void AlgFitTrackCam::GoForwards  ) 
 

Definition at line 1178 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().

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

void AlgFitTrackCam::InitialFramework const CandSliceHandle slice,
CandContext cx
 

Definition at line 209 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().

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

void AlgFitTrackCam::MoveArrays  ) 
 

Definition at line 2157 of file AlgFitTrackCam.cxx.

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

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

02158 {
02159   // Move k to k-1 ready to consider next hit
02160   MSG("AlgFitTrackCam",Msg::kDebug) << "MoveArrays" << endl;
02161 
02162   for (int i=0; i<5; ++i) {
02163     for (int j=0; j<5; ++j) { 
02164       C_k_minus[i][j]=C_k[i][j];
02165     }
02166   }
02167   
02168   for (int l=0; l<5; ++l) {
02169     x_k_minus[l]=x_k[l];
02170   }
02171 }

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

Definition at line 3363 of file AlgFitTrackCam.cxx.

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

Referenced by SpectrometerSwim().

03364 { 
03365   // Method to determine whether this u/v position is active
03366 
03367   PlexPlaneId plexPlane(DetectorType::kNear,plane, 0); 
03368   if(!plexPlane.IsValid()) {return false;}
03369   if(plexPlane.GetPlaneCoverage()==PlaneCoverage::kNoActive) {return false;}
03370   if(projErr<0.3)projErr=0.3;
03371   float x = 0.707*(u-v);
03372   float y = 0.707*(u+v);
03373   float dist,xedge,yedge;
03374   fPL.DistanceToEdge(x, y,
03375                      plexPlane.GetPlaneView(),
03376                      plexPlane.GetPlaneCoverage(),
03377                      dist, xedge, yedge);
03378   bool isInside = fPL.IsInside(x, y,
03379                                plexPlane.GetPlaneView(),
03380                                plexPlane.GetPlaneCoverage());
03381   isInside &= dist>projErr;
03382 
03383   return isInside;
03384 }

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

Definition at line 3574 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().

03575 {
03576   double BegTime=999; double Time=0;
03577   double Index=1.77; double DistFromCentre=0.; 
03578   double FibreDist=0.; double halfLength=0.;
03579 
03580   // Get from track. Otherwise, will have guessed using Swimmer
03581   if(U==0) {U=track->GetU(Strip->GetPlane());}
03582   if(V==0) {V=track->GetV(Strip->GetPlane());}
03583 
03584   StripEnd::StripEnd_t StpEnd = StripEnd::kUnknown;
03585   CandDigitHandle* digit;
03586   
03587   UgliGeomHandle ugh = UgliGeomHandle(*vldc);
03588   UgliStripHandle Striphandle;
03589 
03590   CandDigitHandleItr digitItr(Strip->GetDaughterIterator());
03591 
03592 
03593   // Loop over digits on Strip. 
03595   while( (digit = digitItr()) ) { 
03596     StpEnd=digit->GetPlexSEIdAltL().GetEnd();
03597     
03598     if(StpEnd==StripEnd::kPositive) {
03599       FibreDist = 0.; DistFromCentre = 0.; Time=0.;
03600       UgliStripHandle StripHandle = ugh.GetStripHandle(Strip->GetStripEndId());
03601       halfLength = StripHandle.GetHalfLength(); 
03602       
03603       if(Strip->GetPlaneView()==2) {DistFromCentre = V;}
03604       if(Strip->GetPlaneView()==3) {DistFromCentre = -U;}
03605               
03606       FibreDist = (halfLength + DistFromCentre + StripHandle.ClearFiber(StpEnd) 
03607                    + StripHandle.WlsPigtail(StpEnd));
03608       
03609       Time = digit->GetSubtractedTime(CalTimeType::kT0) - (Index/3.e8)*FibreDist;
03610 
03611       if(Time<BegTime) {BegTime=Time;}
03612     }
03613   }
03614   
03615   return BegTime;
03616 }

void AlgFitTrackCam::RemoveTrkHitsInShw  ) 
 

Definition at line 549 of file AlgFitTrackCam.cxx.

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

Referenced by RunTheFitter().

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

void AlgFitTrackCam::ResetCovarianceMatrix  ) 
 

Definition at line 1709 of file AlgFitTrackCam.cxx.

References DeltaPlane, DeltaZ, and GetInitialCovarianceMatrix().

Referenced by RunTheFitter().

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

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

Implements AlgBase.

Definition at line 86 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.

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

void AlgFitTrackCam::RunTheFitter CandFitTrackCamHandle cth  ) 
 

Definition at line 366 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().

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

void AlgFitTrackCam::SetPropertiesFromFinderTrack CandFitTrackCamHandle cth  ) 
 

Definition at line 3031 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().

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

void AlgFitTrackCam::SetRangeAnddS CandFitTrackCamHandle cth  ) 
 

Definition at line 2766 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().

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

void AlgFitTrackCam::SetTrackProperties CandFitTrackCamHandle cth  ) 
 

Definition at line 2244 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().

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

void AlgFitTrackCam::ShowerStrips  ) 
 

Definition at line 270 of file AlgFitTrackCam.cxx.

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

Referenced by RunTheFitter().

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

void AlgFitTrackCam::ShowerSwim  ) 
 

Definition at line 599 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().

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

void AlgFitTrackCam::SpectrometerSwim CandFitTrackCamHandle cth  ) 
 

Definition at line 3172 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().

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

void AlgFitTrackCam::StoreFilteredData const int  NewPlane  ) 
 

Definition at line 2226 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().

02227 {
02228   // Store the data required for matching Kalman output data to strips
02229   MSG("AlgFitTrackCam",Msg::kDebug) << "StoreFilteredData" << endl;
02230 
02231   FiltDataStruct temp;
02232   
02233   temp.x_k0=x_k[0]; temp.x_k1=x_k[1];
02234   temp.x_k2=x_k[2]; temp.x_k3=x_k[3];
02235   temp.x_k4=x_k[4];
02236 
02237   FilteredData[NewPlane].push_back(temp);
02238 }

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 1615 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.

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

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 1520 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.

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

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 1424 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().

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

void AlgFitTrackCam::TimingFit CandFitTrackCamHandle cth  ) 
 

Definition at line 2422 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().

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

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

Reimplemented from AlgBase.

Definition at line 3622 of file AlgFitTrackCam.cxx.

03623 {
03624 }

void AlgFitTrackCam::UpdateCovMatrix  ) 
 

Definition at line 2114 of file AlgFitTrackCam.cxx.

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

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

02115 {
02116   // C_k = (Identity - (K_k * H_k) ) * C_k_intermediate
02117   MSG("AlgFitTrackCam",Msg::kDebug) << "UpdateCovMatrix" << endl;
02118 
02119   for (int i=0; i<5; ++i) {
02120     for (int j=0; j<5; ++j) {  
02121       C_k[i][j]=0;
02122       for (int m=0; m<5; ++m) {   
02123         C_k[i][j]+=(Identity[i][m] - K_k[i]*H_k[m]) * C_k_intermediate[m][j];
02124       }
02125     }
02126   }
02127 
02128 
02129   // Diagonal elements should be positive
02130   double covlim = 1.e-8;
02131 
02132   for(int i=0; i<5; ++i) {
02133     if(C_k[i][i]<covlim) {
02134       MSG("AlgFitTrackCam",Msg::kVerbose) << "Negative diagonal element in C_k" << endl;
02135       C_k[i][i]=covlim;
02136     }
02137   }
02138 
02139 
02140   // Display
02141   if(debug) {
02142     cout << "Filtered Covariance matrix" << endl;
02143     for(int i=0; i<5; ++i) {
02144       for(int j=0; j<5; ++j) {
02145         cout << C_k[i][j] << " ";
02146       }
02147       cout << endl;  
02148     }
02149   }
02150 
02151 }

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

Definition at line 1993 of file AlgFitTrackCam.cxx.

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

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

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


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(), and Swim().

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(), 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 Thu Nov 1 11:56:25 2007 for loon by  doxygen 1.3.9.1