SND@LHC Software
Loading...
Searching...
No Matches
sndRecoTrack.cxx
Go to the documentation of this file.
1#include "sndRecoTrack.h"
2#include "Scifi.h"
3#include "MuFilter.h"
4#include "ShipUnit.h"
5#include "TROOT.h"
6#include "TMatrixD.h"
7#include "TMath.h"
8#include "TGraph.h"
9#include "TF1.h"
10#include "StateOnPlane.h" /* genfit */
11#include "FitStatus.h"
12#include "RKTrackRep.h"
13#include "ConstField.h"
14#include "FieldManager.h"
15#include "TGeoMaterialInterface.h"
16#include "MaterialEffects.h"
17
18using namespace genfit;
19using namespace std;
20
21//tests
22#include <iostream>
23
24/* Constructor from genfit::Track object */
26{
27 FitStatus* fitStatus = track->getFitStatus();
28 chi2 = fitStatus->getChi2();
29 Ndf = fitStatus->getNdf();
30 fFlag = fitStatus->isFitConverged();
31
32 if (fFlag)
33 {
34 for ( auto i = 0; i < track->getNumPoints(); i++ )
35 {
36 auto state = track->getFittedState(i);
37 fTrackPoints.push_back(state.getPos());
38 fRawMeasDetID.push_back(track->getPointWithMeasurement(i)->getRawMeasurement()->getDetId());
39 if (i ==0)
40 {
41 fTrackMom = state.getMom();
42 start = state.getPos();
43 }
44 if (i == track->getNumPoints()-1)
45 stop = state.getPos();
46 }
47 }
48 // defaults
49 fTrackType = 0;
50 fRawMeasTimes = {};
51}
52
54{
55 /* Don't use this function for now. It works ok with MC,
56 not the case for data.. Work in progress.
57 Provide track direction with a probability level
58 based on timing measurements of hits/clusters.
59 What follows is based on a note by C.Vilela.
60 Reference T0 is 1st meas in z
61 1st item in the returned pair is:
62 1 = along Z axis; -1 = reverse Z direction
63 */
64
65 // Account for signal propagation in detectors
66 vector<float> corr_times = getCorrTimes();
67
68 MuFilter *MuFilterDet = dynamic_cast<MuFilter*> (gROOT->GetListOfGlobals()->FindObject("MuFilter") );
69 Scifi *ScifiDet = dynamic_cast<Scifi*> (gROOT->GetListOfGlobals()->FindObject("Scifi") );
70 double resol{}, resol_0{};
71 int size = fTrackPoints.size();
72 TMatrixD Tres1(size-1,1), Tres2(size-1,1);
73 TMatrixD Sigma(size-1, size-1);
74 // Extract time meas. resolution of the reference T0 measurement
75 if (fRawMeasDetID[0] >= 100000) {
76 resol_0 = ScifiDet->GetConfParF("Scifi/timeResol");
77 }
78 else resol_0 = MuFilterDet->GetConfParF("MuFilter/timeResol");
79 // Set time residual vectors and covariance matrix
80 for ( int i = 0; i < size-1; i++){
81 Tres1[i][0] = corr_times[i+1] - corr_times[0]
82 -(fTrackPoints[i+1]-fTrackPoints[0]).Mag()/ShipUnit::c_light;
83 Tres2[i][0] = corr_times[0] - corr_times[i+1]
84 -(fTrackPoints[i+1]-fTrackPoints[0]).Mag()/ShipUnit::c_light;
85 //tests
86 /*cout<<i<<" deltaT "<<corr_times[i+1] - corr_times[0]<<" dL "
87 << (fTrackPoints[i+1]-fTrackPoints[0]).Mag()
88 <<" dL/c "<< (fTrackPoints[i+1]-fTrackPoints[0]).Mag()/ShipUnit::c_light<<endl;*/
89 for ( int j = 0; j < size-1; j++){
90 if (i == j) {
91 if (fRawMeasDetID[i+1] >= 100000) {
92 resol = ScifiDet->GetConfParF("Scifi/timeResol");
93 }
94 else resol = MuFilterDet->GetConfParF("MuFilter/timeResol");
95 Sigma[i][j] = pow(resol_0,2)+pow(resol,2);
96 }
97 else Sigma[i][j] = pow(resol_0,2);
98 }
99 }
100 TMatrixD SigmaInv(TMatrixD::kInverted,Sigma);
101 TMatrixD Tres1_T(TMatrixD::kTransposed,Tres1);
102 //tests
103 //Tres1_T.Print();
104 TMatrixD Tres2_T(TMatrixD::kTransposed,Tres2);
105 TMatrixT<double> LambdaB1 = Tres1_T*SigmaInv*Tres1;
106 TMatrixT<double> LambdaB2 = Tres2_T*SigmaInv*Tres2;
107 // tests
108 /*cout<<LambdaB1[0][0]<<" "<<LambdaB2[0][0]
109 <<" "<<LambdaB2[0][0]-LambdaB1[0][0]
110 <<" "<<TMath::Prob(LambdaB1[0][0], size-1)
111 <<" "<<TMath::Prob(LambdaB2[0][0], size-1)<<endl;*/
112 if (LambdaB2[0][0]-LambdaB1[0][0] >= 0)
113 return make_pair(1, TMath::Prob(LambdaB1[0][0], size-1));
114 else return make_pair(-1, TMath::Prob(LambdaB2[0][0], size-1));
115}
116
117pair<float, float> sndRecoTrack::Velocity()
118{
119 /* Extract particle velocity based on timing
120 measurements as slope of linear fit of (dL,dT)
121 Reference T0 is 1st measurement in z */
122
123 // Account for signal propagation in detectors
124 vector<float> corr_times = getCorrTimes();
125
126 MuFilter *MuFilterDet = dynamic_cast<MuFilter*> (gROOT->GetListOfGlobals()->FindObject("MuFilter") );
127 Scifi *ScifiDet = dynamic_cast<Scifi*> (gROOT->GetListOfGlobals()->FindObject("Scifi") );
128 TGraph gr;
129 double resol{}, delta_T{};
130 for (int i = 1; i < fTrackPoints.size(); i++){
131 if (fRawMeasDetID[i] >= 100000) {
132 resol = ScifiDet->GetConfParF("Scifi/timeResol");
133 }
134 else resol = MuFilterDet->GetConfParF("MuFilter/timeResol");
135 delta_T = corr_times[i]-corr_times[0];
136 // Use current track point measurement only if time difference is above resolution
137 if (fabs(delta_T) < resol*sqrt(2)) continue;
138 gr.AddPoint((fTrackPoints[i]-fTrackPoints[0]).Mag(), delta_T);
139 }
140 TF1 line("line", "pol1");
141 // A single entry in the graph - no fit
142 if (gr.GetN() < 2)
143 return make_pair(9999.,999.);
144 else
145 gr.Fit("line", "SQ");
146 // slope of fit is 1/v
147 return make_pair(1./line.GetParameter(1),line.GetParError(1)/pow(line.GetParameter(1),2));
148}
149
150tuple<float, float, float> sndRecoTrack::trackDir()
151{
152 /* Based on the same function in SndlhcTracking.py!
153 Extract direction based on timing
154 measurements as slope of linear fit of (dL,dT'),
155 where dT' features time of flight estimation.
156 Use a nominal first position in z */
157
158 // Account for signal propagation in detectors
159 vector<float> corr_times = getCorrTimes();
160
161 TGraph gr;
162 double dist{}, delta_T{};
163
164 double firstScifi_z = 300*ShipUnit::cm;
165 TVector3 pos(start);
166 TVector3 mom(fTrackMom);
167 double lam = (firstScifi_z - pos.z())/mom.z();
168 // nominal first position
169 TVector3 pos1(pos.x()+lam*mom.x(), pos.y()+lam*mom.y(), firstScifi_z);
170
171 for (int i = 0; i < fTrackPoints.size(); i++){
172 dist= (fTrackPoints[i]-pos1).Mag();
173 gr.AddPoint(dist, corr_times[i] - dist/ShipUnit::c_light);
174 }
175 TF1 line("line", "pol1");
176 gr.Fit("line", "SQ");
177 return make_tuple(line.GetParameter(1),
178 line.GetParameter(1)/(line.GetParError(1)+1E-13), line.GetParameter(0));
179}
180
182{
183 TVector3 NewPosition = TVector3(0., 0., z);
184 /* line below assumes that plane in global coordinates
185 is perpendicular to z-axis, which is not true for TI18 geometry. */
186 TVector3 parallelToZ = TVector3(0., 0., 1.);
187 RKTrackRep rep = RKTrackRep(13);
188 StateOnPlane state = StateOnPlane(&rep);
189 // find index(!) of track point closest in z
190 float zMin = 9999;
191 int index;
192 for ( int i =0; i < fTrackPoints.size(); i++ ){
193 if ( fabs(zMin - fTrackPoints[i].Z()) < zMin ) index = i;
194 }
195 TVector3 Closest_pos = fTrackPoints[index];
196 rep.setPosMom(state, Closest_pos, fTrackMom);
197 rep.extrapolateToPlane(state, NewPosition, parallelToZ);
198
199 return state.getPos();
200}
201
203{
204 /* Account for signal propagation in detectors */
205 vector<float> corr_times{};
206 MuFilter *MuFilterDet = dynamic_cast<MuFilter*> (gROOT->GetListOfGlobals()->FindObject("MuFilter") );
207 Scifi *ScifiDet = dynamic_cast<Scifi*> (gROOT->GetListOfGlobals()->FindObject("Scifi") );
208 TVector3 A, B, X{};
209 float scintVel, L;
210 float mean{}, fastest=999.;
211 for ( int i = 0; i < fTrackPoints.size(); i++ ){
212 // First get readout coordinates and parameters
213 if (fRawMeasDetID[i] >= 100000){
214 ScifiDet->GetSiPMPosition(fRawMeasDetID[i],A,B);
215 scintVel = ScifiDet->GetConfParF("Scifi/signalSpeed");
216 }
217 else {
218 MuFilterDet->GetPosition(fRawMeasDetID[i],A,B);
219 // DS
220 if (floor(fRawMeasDetID[i]/10000) == 3){
221 L = MuFilterDet->GetConfParF("MuFilter/DownstreamBarX");
222 scintVel = MuFilterDet->GetConfParF("MuFilter/DsPropSpeed");
223 }
224 // US and Veto
225 else scintVel = MuFilterDet->GetConfParF("MuFilter/VandUpPropSpeed");
226 }
227 // calculate distance btw track point and SiPM
228 // vertical detector elements
229 if ( (fRawMeasDetID[i] >= 100000 && int(fRawMeasDetID[i]/100000)%10 == 1) or
230 (fRawMeasDetID[i] < 100000 && floor(fRawMeasDetID[i]/10000) == 3
231 && fRawMeasDetID[i]%1000 > 59) ) X = B-fTrackPoints[i];
232 else X = A - fTrackPoints[i];
233 // Then, get calibrated hit times
234 if (fRawMeasDetID[i] >= 100000) {
235 corr_times.push_back(ScifiDet->GetCorrectedTime(fRawMeasDetID[i], fRawMeasTimes[i][0], 0) - X.Mag()/scintVel);
236 }
237 else {
238 mean = 0;
239 fastest=999.;
240 for (int ch = 0, N_channels = fRawMeasTimes[i].size(); ch <N_channels; ch++ ){
241 // For the moment only DS is time calibrated
242 if (floor(fRawMeasDetID[i]/10000) == 3){
243 // vertical bars or DS clusters
244 if ( N_channels==1 ){
245 corr_times.push_back(MuFilterDet->GetCorrectedTime(fRawMeasDetID[i], ch, fRawMeasTimes[i][ch], 0) - X.Mag()/scintVel);
246 }
247 // horizontal bar - take mean of the L/R hit times
248 else{
249 mean += MuFilterDet->GetCorrectedTime(fRawMeasDetID[i], ch, fRawMeasTimes[i][ch], 0);
250 if (ch == N_channels-1) corr_times.push_back(mean/N_channels- L/scintVel/2.);
251 }
252 }
253 // US and Veto - no time calibration yet, just use fastest hit time for now
254 else{
255 fastest = min(fastest, fRawMeasTimes[i][ch]);
256 if (ch == N_channels-1) corr_times.push_back(fastest - X.Mag()/scintVel);
257 }
258 }
259 }
260 //cout<<"i "<<i<<" raw tdc "<<fRawMeasTimes[i]<<" corr t "<<corr_times.back()<<" "<< X.Mag()<<endl;
261 }
262
263 return corr_times;
264}
265
void GetPosition(Int_t id, TVector3 &vLeft, TVector3 &vRight)
Definition MuFilter.cxx:639
Float_t GetCorrectedTime(Int_t id, Int_t c, Double_t t, Double_t L)
Definition MuFilter.cxx:579
Float_t GetConfParF(TString name)
Definition MuFilter.h:46
Definition Scifi.h:20
void GetSiPMPosition(Int_t SiPMChan, TVector3 &A, TVector3 &B)
Definition Scifi.cxx:625
Float_t GetConfParF(TString name)
Definition Scifi.h:49
Double_t GetCorrectedTime(Int_t fDetectorID, Double_t rawTime, Double_t L)
Definition Scifi.cxx:517
Class where important numbers and properties of a fit can be stored.
Definition FitStatus.h:36
double getNdf() const
Get the degrees of freedom of the fit.
Definition FitStatus.h:76
bool isFitConverged(bool inAllPoints=true) const
Did the fit converge (in all Points or only partially)?
Definition FitStatus.h:61
double getChi2() const
Get chi^2 of the fit.
Definition FitStatus.h:74
AbsTrackRep with 5D track parameterization in plane coordinates: (q/p, u', v', u, v)
Definition RKTrackRep.h:70
virtual void setPosMom(StateOnPlane &state, const TVector3 &pos, const TVector3 &mom) const
Set position and momentum of state.
virtual double extrapolateToPlane(StateOnPlane &state, const SharedPlanePtr &plane, bool stopAtBoundary=false, bool calcJacobianNoise=false) const
Extrapolates the state to plane, and returns the extrapolation length and, via reference,...
Definition RKTrackRep.cc:97
A state with arbitrary dimension defined in a DetPlane.
TVector3 getPos() const
Collection of TrackPoint objects, AbsTrackRep objects and FitStatus objects.
Definition Track.h:71
std::vector< TVector3 > fTrackPoints
TVector3 start
std::vector< float > getCorrTimes()
std::vector< int > fRawMeasDetID
TVector3 extrapolateToPlaneAtZ(float z)
TVector3 stop
std::vector< std::vector< float > > fRawMeasTimes
TVector3 fTrackMom
std::tuple< float, float, float > trackDir()
std::pair< int, float > TrackDirection()
std::pair< float, float > Velocity()
Matrix inversion tools.
Definition AbsBField.h:29