/
EicHtcTask.h
320 lines (234 loc) · 10.4 KB
/
EicHtcTask.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
//
// AYK (ayk@bnl.gov), 2014/02/03
//
// An attempt to port HERMES & OLYMPUS forward tracking KF code to EicRoot;
//
//#include <3d.h>
//#include <htclib.h>
#ifndef _EIC_HTC_TASK_
#define _EIC_HTC_TASK_
class TGeoNode;
// FIXME: save on typing?; really?;
#define _EIC_HTC_TREE_ "htc"
#define _EIC_HTC_BRANCH_ "EicHtcTrack"
#define _EIC_HTC_TRACK_ "track"
#include <TGeoMatrix.h>
#include <FairTask.h>
#include <TrKalmanFilter.h>
#include <FairTrackParP.h>
class EicTrackingDigiHit;
#include <EicIdealTrackingCode.h>
#include <EicTrackingDigiHitProducer.h>
class EicHtcHitComponent: public TObject {
// No reason to overcomplicate access here;
friend class EicHtcHit;
friend class EicHtcTask;
public:
EicHtcHitComponent() {
mLocalCoord1D = mXsResidual = mXmResidual = mSigmaRS = mSigmaRM = mResolution = 0.0;
};
~EicHtcHitComponent() {};
private:
Double_t mLocalCoord1D; // local coordinate
Double_t mXsResidual; // smoothed residual (~inclusive in Aiwu's notation)
Double_t mXmResidual; // smoothed-subtracted one (~exclusive in Aiwu's notation)
Double_t mResolution; // 1D sigma used for track fitting (and smearing in case of MC data)
// This is in node-projected space (H*M*H^T); assume only diagonal terms of respective
// cov.matrix are of interest; otherwise will have to put full matrix right into
// the EicHtcHit class;
Double_t mSigmaRS; // sqrt(diagonal term) of H-projected smoother cov.matrix
Double_t mSigmaRM; // same as above, without information from this KF node
ClassDef(EicHtcHitComponent,4);
};
class EicHtcHit: public TObject {
friend class EicHtcTask;
public:
EicHtcHit(unsigned dim = 0): mDim(dim) {
mSmootherChiSquare = mSmootherProbability = 0.0;
//memset(mSigmaCS, 0x00, sizeof(mSigmaCS));
mGlobalCoordXY[0] = mGlobalCoordXY[1] = 0.0;
mComponents = dim ? new EicHtcHitComponent[dim] : 0;
};
~EicHtcHit() {};
double ChiSq() const { return mSmootherChiSquare; };
double Prob() const { return mSmootherProbability; };
// Hit resolution (sqrt of diagonal term);
double GetResolution(unsigned what = 0) const {
return what < mDim ? mComponents[what].mResolution : 0.0;
};
// Local coordinate(s);
double GetLc(unsigned what = 0) const {
return what < mDim ? mComponents[what].mLocalCoord1D : 0.0;
};
// Global XY-coordinates;
double GetGc(unsigned what = 0) const {
return what < 2 ? mGlobalCoordXY[what] : 0.0;
};
// Smoother residuals and estimated error (component onto detector
// plane coordinate system); aka "inclusive residual";
double GetRs(unsigned what = 0) const {
return what < mDim ? mComponents[what].mXsResidual : 0.0;
};
double GetEs(unsigned what = 0) const {
return what < mDim ? mComponents[what].mSigmaRS : 0.0;
};
// Same as above, but with the present KF node measurement excluded;
// aka "exclusive residual";
double GetRm(unsigned what = 0) const {
return what < mDim ? mComponents[what].mXmResidual : 0.0;
};
double GetEm(unsigned what = 0) const {
return what < mDim ? mComponents[what].mSigmaRM : 0.0;
};
private:
UInt_t mDim;
EicHtcHitComponent *mComponents; //[mDim] up to 2 components for now
Double_t mSmootherChiSquare; // chi^2 after Kalman smoother pass for this node
Double_t mSmootherProbability; // "probability" of this chi^2 value
Double_t mGlobalCoordXY[2]; // global XY-coordinates at this node
// FIXME: may later want to add both state vector, as well as the full smoother
// covariance matrix; not really needed for FLYSUB business right now;
//
// This is the "global" 3D space, {x,y,sx,sy} or {x,y,sx,sy,1/p} track parameterization;
//Double_t mSigmaCS[5]; // sqrt(diagonal terms) of smoother cov.matrix in 3D
ClassDef(EicHtcHit,12);
};
// NB: "tuple" is available in C++ 11 only, sorry;
typedef std::pair<const char*, std::pair<unsigned, unsigned> > kEntry;
typedef std::map<kEntry, EicHtcHit*, bool(*)(kEntry, kEntry)> hEntry;
bool HitKeyCompare(kEntry, kEntry);
class EicHtcTrack: public TObject {
friend class EicHtcTask;
public:
EicHtcTrack(): mMomentum(0.0), mNdf(0), mFilterChiSquare(0.0), mFilterChiSquareCCDF(0.0) {
mHits = new hEntry(HitKeyCompare);
memset(mBeamCoordXY, 0x00, sizeof(mBeamCoordXY));
memset(mBeamCoordSigmaXY, 0x00, sizeof(mBeamCoordSigmaXY));
memset(mBeamSlopeXY, 0x00, sizeof(mBeamSlopeXY));
memset(mBeamSlopeSigmaXY, 0x00, sizeof(mBeamSlopeSigmaXY));
};
~EicHtcTrack() { if (mHits) delete mHits; };
// Simplify access method names (typing issues);
int Ndf() const { return mNdf; };
double ChiSquare() const { return mFilterChiSquare; };
double ChiSquareCCDF() const { return mFilterChiSquareCCDF; };
double BeamX() const { return mBeamCoordXY [0]; };
double BeamEX() const { return mBeamCoordSigmaXY[0]; };
double BeamY() const { return mBeamCoordXY [1]; };
double BeamEY() const { return mBeamCoordSigmaXY[1]; };
double BeamSX() const { return mBeamSlopeXY [0]; };
double BeamESX() const { return mBeamSlopeSigmaXY[0]; };
double BeamSY() const { return mBeamSlopeXY [1]; };
double BeamESY() const { return mBeamSlopeSigmaXY[1]; };
const EicHtcHit* GetHit(const char *detName, unsigned group, unsigned node = 0) const;
Double_t mMomentum;
private:
// General parameters;
Int_t mNdf; // number of degrees of freedom
Double_t mFilterChiSquare; // chi^2 after Kalman filter pass for the whole track
Double_t mFilterChiSquareCCDF;// respective complement of the cumulative distribution function
Double_t mBeamCoordXY[2]; // beam coordinate estimate at the KF head node
Double_t mBeamCoordSigmaXY[2];// respective diagonal errors
Double_t mBeamSlopeXY[2]; // beam slope estimate at the KF head node
Double_t mBeamSlopeSigmaXY[2];// respective diagonal errors
// Track/hit info at registering plane locations;
hEntry *mHits;
ClassDef(EicHtcTrack,9);
};
class HtcKalmanFilter: public TrKalmanFilter {
public:
HtcKalmanFilter(): TrKalmanFilter() {};
HtcKalmanFilter(MfieldMode mode): TrKalmanFilter(mode), mMgslices(0) {};
~HtcKalmanFilter() {};
int KalmanFilterMagneticField(TVector3 &xx, TVector3 &B);
private:
MgridSlice *mMgslices;
MgridSlice *InitializeMgridSlice(double z0);
};
class EicHtcTask: public FairTask {
public:
EicHtcTask(): FairTask("EIC HTC Task") { ResetVars(); };
EicHtcTask(EicIdealTrackingCode *ideal, MfieldMode fieldMode = WithField);
void ResetVars() {
mMediaBank = 0; mFitTrackArray = 0;
mHtcBranch = 0; mHtcTrack = 0; mPersistency = true;
mParticleMomentumSeed = 30.0;
mCoordinateScaleXY = mSlopeScale = mResidualScaleXY = 1.0;
mKalmanFilter = 0;
mMediaScanDirection = TVector3(0.0, 0.0, 1.0);
};
~EicHtcTask() {};
// Want to propagate detector group names to the Kalman filter initialization;
InitStatus Init();
void Exec(Option_t* opt);
void Print(Option_t* option = "") const;
void FinishTask();
void SetTrackOutBranchName(const TString& name) { mTrackOutBranchName = name; }
// Basically "proton" or "pion"; THINK: momentum = 0.0 means: take
// simulated one as a seed; or perhaps the one from EicIdealTrack?;
int SetParticleHypothesis(const char *name, double momentumSeed = 0.0) {
if (name) mParticleHypothesis = TString(name);
mParticleMomentumSeed = momentumSeed;
return 0;
};
// 'virtual': well, let user code an opportunity to explicitely specify both axis
// and scan 3D lines in space explicitely;
virtual MediaBank *ConfigureMediaBank();
void SetMediaScanThetaPhi(double theta, double phi);
TVector3 GetMediaScanDirection() const { return mMediaScanDirection; };
// May want to change coordinate and residual scale in the encoded hits to
// something like [mm] and [um] (default is 1:1, so [cm]);
void SetHitOutputCoordinateScaleXY(double scale) { mCoordinateScaleXY = scale; };
void SetHitOutputSlopeScale(double scale) { mSlopeScale = scale; };
void SetHitOutputResidualScaleXY(double scale) { mResidualScaleXY = scale; };
void SetResolutionByHand(const char *plName, double value) {
if (plName) mResolutionsByHand[TString(plName)] = value;
};
double GetResolutionByHand(const char *plName) {
//printf("%d\n", mResolutionsByHand.size());
if (plName && mResolutionsByHand.find(TString(plName)) != mResolutionsByHand.end())
return mResolutionsByHand[TString(plName)];
else
return 0.0;
};
HtcKalmanFilter *GetKalmanFilter() const { return mKalmanFilter; };
virtual unsigned GetMissingHitCounterMax() const { return 0; };
protected:
EicIdealTrackingCode *mIdealTrCode;//!
HtcKalmanFilter *mKalmanFilter; //! Kalman filter pointer
//void SetMaxPossibleHitCount(unsigned max) { mMaxPossibleHitCount = max; };
unsigned GetMaxPossibleHitCount() const;// {
//return mMaxPossibleHitCount;
//};
private:
MediaBank *mMediaBank; //!
TClonesArray* mFitTrackArray; //! Output TCA for track
TString mTrackOutBranchName; //! Name of the output TCA
TBranch *mHtcBranch; //! HTC track branch
EicHtcTrack *mHtcTrack; //! track buffer to be fed to tree->Fill()
Bool_t mPersistency; //!
TVector3 mMediaScanDirection;
public:
TString mParticleHypothesis; // particle hypothesis used for fitting
// NB: this will remain constant for magnet-off mode;
Double_t mParticleMomentumSeed; // particle momentum seed used for fitting
//
// FIXME: not radians in fact; need atan() somewhere -> check!;
//
private:
// Local 1D spatial detector coordinates (say XY) and beam profile XY-coordinates;
Double_t mCoordinateScaleXY; // [cm] may be rescaled to say [mm]
// Beam profile XY-slopes;
Double_t mSlopeScale; // [rad] may be rescaled to say [urad]
// Local 1D spatial detector residuals (say XY);
Double_t mResidualScaleXY; // [cm] may be rescaled to say [um]
std::map<TString, double> mResolutionsByHand; // resolutions set by hand in reconstruction.C
//unsigned mMaxPossibleHitCount;
int PerformMediaScan();
int DeclareSensitiveVolumes();
int ConfigureKalmanFilter();
int ConstructLinearTrackApproximation(KfMatrix *A, KfMatrix *b);
FairTrackParP GetFairTrackParP(TrKalmanNode *node);
ClassDef(EicHtcTask,22);
};
#endif