EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KalmanNode.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file KalmanNode.h
1 //
2 // AYK (ayk@bnl.gov)
3 //
4 // Kalman filter node and associated structures; ported from
5 // HERMES/OLYMPUS sources; cleaned up 2014/10/13;
6 //
7 
8 #include <cstring>
9 //#include <stdio.h>
10 
11 #include <KfMatrix.h>
12 
13 #ifndef _KALMAN_NODE_
14 #define _KALMAN_NODE_
15 
16 class Mgrid;
17 class KalmanNode;
18 
19 class StringList {
20  public:
22  // FIXME: has never been checked;
23  ~StringList() { /*if (mString) free(mString);*/ };
24 
25  char *mString;
26 
28 };
29 
30 class NodeList {
31  friend class KalmanFilter;
32 
33 public:
34  NodeList(): mNode(0), mNextNode(0) {};
35  ~NodeList() {};
36 
37  private:
39 
41 };
42 
43 class NodeGroup {
44  friend class KalmanNode;
45  friend class KalmanFilter;
46 
47 public:
48  // Constructor should clean up "next" pointer; just reset everything;
51  ~NodeGroup() {};
52 
53  private:
54  // Min number of fired registering planes during outlier removal;
55  int mFiredNodeNumMin;
56 
57  // Linked list with node name prefices;
59 
60  // Linked list of nodes belonging to this group;
63 
64  // Presently fired number of nodes (KF working variable); FIXME: multi-threading;
66 
67  // If 'true', minimum fired node control is enabled;
69 
71 };
72 
73 class MgridSlice {
74  public:
75  // Constructor should clean up "next" pointer; just reset everything;
77 
78  // Z coordinate;
79  double mZ0;
80 
81  // XY-mgrid at a given z0; can be NULL (Z out of magnetic field area);
83 
84  // It is convenient to have a flag indicating whether last
85  // call to mgrid interpolation routine with repetition_flag=0
86  // succeeded or not; indeed for derivative calculations makes
87  // no sense to call the routine with repetition_flag=1 at an offset
88  // with respect to one of the [0..4] parameters if a call at
89  // nominal parameter set failed;
91 
92  // Will exist as a linked list;
94 };
95 
96 class KalmanNode {
97  friend class KalmanFilter;
98 
99  public:
100  // Constructor: just reset everything; FIXME: what a crap!;
102  memset((void*)this, 0x00, sizeof(KalmanNode));
103  };
104 
105  void SetFiredFlag();
106  void ResetFiredFlag();
107 
108  virtual bool IsActive() const { return true; };
109  bool IsFired() const { return mFired; };
110  void SetZ(double z) { mZ = z; };
111  virtual double GetZ() const { return mZ; };
112  unsigned GetMdim() const { return mDim; };
113 
114  // Would need a range check here?; hmm;
115  double GetV(unsigned ip, unsigned iq) const { return V->KFM(ip,iq); };
116  double GetX0(unsigned ip) const { return x0->KFV(ip); };
117  double GetXf(unsigned ip) const { return xf->KFV(ip); };
118  double GetXs(unsigned ip) const { return xs->KFV(ip); };
119  double GetXm(unsigned ip) const { return xm->KFV(ip); };
120  double GetRs(unsigned ip) const { return rs->KFV(ip); };
121  double GetRm(unsigned ip) const { return rm->KFV(ip); };
122  double Getm (unsigned ip) const { return m->KFV (ip); };
123  double GetSmootherChiSquare() const { return mSmootherChiSquare; };
125  double GetCP(unsigned ip, unsigned iq) const { return CP->KFM(ip,iq); };
126  double GetCF(unsigned ip, unsigned iq) const { return CF->KFM(ip,iq); };
127  double GetCS(unsigned ip, unsigned iq) const { return CS->KFM(ip,iq); };
128  double GetRS(unsigned ip, unsigned iq) const { return RS->KFM(ip,iq); };
129  double GetRM(unsigned ip, unsigned iq) const { return RM->KFM(ip,iq); };
130 
131  KfVector *GetX0() const { return x0; };
132  KfVector *GetXf() const { return xf; };
133  KfVector *GetXp() const { return xp; };
134  KfVector *GetXs() const { return xs; };
135  KfMatrix *GetCP() const { return CP; };
136  KfMatrix *GetCS() const { return CS; };
137 
138  const char *GetName() const { return mName; };
139 
140  KalmanNode *GetNext(unsigned fb) const { return (fb ? mPrev : mNext); };
141  KalmanNode *GetPrev(unsigned fb) const { return (fb ? mNext : mPrev); };
142 
143  void SetPrev(KalmanNode *node) { mPrev = node; };
144  void SetNext(KalmanNode *node) { mNext = node; };
145 
147  // FIXME: well, this breaks mNodeGroups ownership model I guess;
148  mNodeGroupNum = sample->mNodeGroupNum;
149  mNodeGroups = sample->mNodeGroups;
150  };
151 
152  protected:
153  // Node ordering parameter; Z-coordinate for application to charged particle
154  // tracking in forward spectometers; then just call it 'mZ';
155  double mZ;
156 
157  // Measurement vector dimension;
158  int mDim;
159 
160  // User back-door pointer;
161  //void *mBackDoorPointer;
162 
163  //
164  // Prefer not to prepend 'm' prefix (would really spoil readability);
165  //
166 
167  // Non-stochastic part of the system equation matrix;
168  // assume that linear transport (magnet-free in case of tracking)
169  // matrices never change => precalculate them and store for
170  // forward and backward filters separately; if this situation ever
171  // changes, will have to create these FF's thread-specific;
172  KfMatrix *FF[2]; //[SDIM][SDIM]
173 
174  // Keep 'usual' Kalman notation; 'measured' coordinate;
175  KfVector *m; //[MDIM]
176 
177  // Measurement noise covariance (matrix);
178  KfMatrix *V; //[MDIM][MDIM]
179 
180  // Non-stochastic part of the measurement matrix;
181  KfMatrix *H; //[MDIM][SDIM]
182 
183  // Expansion point; used for the pure linear case as well, but makes
184  // real sense for (nonlinear) tracking in magnetic field;
185  KfVector *x0; //[SDIM]
186 
187  // Process noise covariance matrix;
188  KfMatrix *Q; //[SDIM][SDIM]
189 
190  // 'FR' will point to either FF or FM depending on what is actually wanted;
191  KfMatrix *FM; //[SDIM][SDIM]
193 
194  // Buffer matrices;
195  KfMatrix *MMTX; //[MDIM][MDIM]
196  KfVector *MVEC; //[MDIM]
197 
198  // Predicted state vector based on the previous (k-1) nodes;
199  // in case of tracing in the magnetic field it will stay 0.;
200  KfVector *xp; //[SDIM]
201  // Filtered state vector based on all (k) nodes up to this one;
202  // in case of tracing in the magnetic field it is a deviation
203  // from x0[];
204  KfVector *xf; //[SDIM]
205 
206  // Smoothed state vector with this node measurement excluded;
207  KfVector *xm; //[SDIM]
208  // Respective residuals
209  KfVector *rm; //[MDIM]
210 
211  // Predicted covariance matrix based on the previous (k-1) nodes;
212  KfMatrix *CP; //[SDIM][SDIM]
213  // Updated (filtered) covariance matrix based on all (k) nodes;
214  KfMatrix *CF; //[SDIM][SDIM]
215 
216  // Kalman gain matrix;
217  KfMatrix *K; //[SDIM][MDIM]
218 
219  // Smoothed state vector based on all (n) nodes;
220  KfVector *xs; //[SDIM]
221  // Intermediate vector for xs[] calculation (see De Jong);
222  KfVector *qq; //[SDIM]
223 
224  // Prediction error, filtered residuals and their covariance matrix;
225  KfVector *ep, *rf; //[MDIM]
226  KfMatrix *RPI, *RF; //[MDIM][MDIM]
227 
228  // Updated (smoothed) covariance matrix;
229  KfMatrix *CS; //[SDIM][SDIM]
230  // Smoothed residuals and their covariance matrix;
231  KfVector *rs; //[MDIM]
232  KfMatrix *RS; //[MDIM][MDIM]
233 
234  // Smoother dovariance matrix with current node measurement subtracted;
235  KfMatrix *CM; //[SDIM][SDIM]
236  // Respective matrix projected onto the node space (H*CM*H^T);
237  KfMatrix *RM; //[MDIM][MDIM]
238 
239  // LB=(I-KH) for this node; L=F*LF - true node->L needed
240  // for CS[][] calculation (De Jong); QQ[] is an intermediate
241  // matrix for the same purposes;
242  KfMatrix *LB, *L; //[SDIM][SDIM]
243  KfMatrix *QQ; //[SDIM][SDIM]
244 
245  private:
246  // Well, it turns out that name helps; can be NULL though;
247  char *mName;
248 
249  // Previous/next in "natural" direction of ascending Z;
251 
252  // Well, not really tracking-specific parameter; NB: even if
253  // root->non_linear_transport_flag is 1 few nodes may require
254  // a pure linear transport (like BC3/4 in HTC case --> no
255  // magnetic field); as of 2010/08/17 this flag is direction-specific
256  // for any given node (which actually makes sense only for complicated
257  // cases like bridging);
259 
260  // Node groups this node belongs to;
263 
264  // If '1', this node actually has a measurement;
265  bool mFired;
266 
267  // chi^2 increment (filtering);
269 
270  // chi^2 for the smoothed residuals (one value per node);
272 
273  void AllocateKfMatrices(unsigned sdim);
274 } ;
275 
276 #endif