EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MgridInterpolation.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MgridInterpolation.h
1 /* -------------------------------------------------------------------------- */
2 /* MgridInterpolation.h */
3 /* */
4 /* A.Kisselev, PNPI, St.Petersburg, Russia. */
5 /* e-mail: kisselev@hermes.desy.de */
6 /* -------------------------------------------------------------------------- */
7 
8 #include <ThreeDeePolySpace.h>
9 
10 #ifndef _MGRID_INTERPOLATION_H
11 #define _MGRID_INTERPOLATION_H
12 
13 typedef double (*interfun)(double xx, double coord[], double value[]);
14 
15 // No interpolation at all (take nearest node value);
16 #define _NO_INTERPOLATION_ 0
17 // Sequential interpolation in XYZ direction in some order;
18 // dimensions are 2..4; '2' is linear interpolation,
19 // '3' - quadratic, '4' - weighted quadratic (the latter
20 // two are after WWC);
21 #define _SEQUENTIAL_FAST_INTERPOLATION_ 1
22 // The same, but at any dimension, orthogonal polynomials used;
23 // moderately CPU intensive;
24 #define _SEQUENTIAL_HIGH_INTERPOLATION_ 2
25 // Well, this mode is mathematically incorrect, because it does not
26 // take into account possible spread of fitting errors after first 1-2
27 // directions; on the other hand taking them into account may lead
28 // to a complete screw up, because one either have to rely on the
29 // 'weight' field, or renormalize by sqrt(chi^2/ndf) and it is not
30 // clear would not it be better to ignore errors all together;
31 // besides this CPU usage will blow up since basis needs to be redone
32 // for every new xx[];
33 // for practical reasons this mode is left in (it is indeed more
34 // reasonable that interpolation with big adim[] since it gives
35 // more smooth fit); if one wants fit instead of interpolation
36 // and cares about mathematical correctness, _MGRID_MULTI_DIM_FITTING_
37 // is the way to go;
38 #define _SEQUENTIAL_HIGH_FITTING_ 3
39 // A global 3dim polynomial interpolation (very CPU intensive);
40 #define _MULTI_DIM_INTERPOLATION_ 4
41 // The same, but number of cells may be more than overall
42 // degree of polynomial; NB: basis is built only ONCE, assuming
43 // that weight=1. in all points; attempt to change weights for
44 // individual xx[] points afterwards will result in wrong fitting;
45 // in principle one can of course introduce a 'professional' mode
46 // when basis is calculated every time new (and it is in fact very
47 // easy to do), but for now assume that all points have always
48 // equal errors;
49 #define _MULTI_DIM_FITTING_ 5
50 
51 
52 // For now do not see need for more than 6 doubles (3 field
53 // components + 3 estimated errors); do not want 'double *B'
54 // because the beginning of this structure will go directly
55 // into a data file; NB: the code will be backward compatible
56 // with older versions even if one day this DIM will be
57 // increased, because the actual length is written in file
58 // header upon creation;
59 #define _CELL_DATA_DIM_MAX_ 10
60 
61 // This format header lines (property&B[]) should never change!;
62 struct MgridCell {
63  // N field components; perhaps anything else dazu;
65 
66  //
67  // !!! Do not touch fields above this line (apart from changing
68  // _CELL_DATA_DIM_MAX_); well, in fact B[] to be the first element
69  // in this structure is the only requirement;
70  //
71 
72  // The rest will not be stored in data files, but it is
73  // convenient to have this stuff in right here;
74  void *ptr;
75 
77 } ;
78 
79 // Possible bits in mgrid->object_contents_bits;
80 // cell->B[] stuff (field + errors + ...);
81 #define _CELL_DATA_ 0x01
82 // Cell properties (since they are of char type it is
83 // more economic to keep them in a separate array);
84 #define _CELL_PROPERTIES_ 0x02
85 
86 // Possible bits of mgrid->cell_contents_bits; do not forget to
87 // change max known bit #define below;
88 #define _FIELD_COMPONENT_VALUES_ 0x01
89 #define _FIELD_COMPONENT_ERRORS_ 0x02
90 #define _FIT_CHI_SQUARE_ 0x04
91 #define _CELL_COORDINATES_ 0x08
92 #define _FIELD_GRADIENTS_ 0x10
93 #define _1D_FIELD_ERRORS_ 0x20
94 #define _3D_FIELD_ERRORS_ 0x40
95 // Some sanity; does not help much; ok;
96 #define _MAX_KNOWN_CELL_CONTENTS_BIT_ 7
97 
98 
99 //
100 // Possible cell status; should fit in 4 bits; the more the number
101 // the worse this cell was;
102 //
103 
104 // After the ASCII input all cells will be SAFE; after regriding cell
105 // remains SAFE if 1) self-cell was SAFE, 2) ideal cube was used
106 // for interpolation/fitting without repositioning, 3) all neighbour
107 // cells used were SAFE;
108 #define _SAFE_CELL_ 0x01
109 // Basically means that regriding procedure for this cell either had
110 // to reposition the cube, or to use EDGE self/neighbour cells;
111 // in other words this cell is on the edge of the grid;
112 #define _EDGE_CELL_ 0x02
113 // This cell was either extrapolated from the other (known) cells
114 // or during it's creation EXTRA cells were used (means they were at
115 // least allowed to be used - see self/neighbour allowed masks);
116 // creation of such cells is in principle straighforward, but not
117 // implemented yet;
118 #define _EXTRA_CELL_ 0x04
119 // No info for this cell available;
120 #define _DEAD_CELL_ 0x08
121 
122 // When creating a grid out of cell list either to put all components
123 // into separate grids and arrange mgrid heap (ON) or create a (2-3)-dim
124 // mgrid right away (OFF); the former may be of interest if component
125 // grids are not guaranteed to be perfectly sitting on top of each other
126 // for instance there are relative shifts which need to be found - it is
127 // much easier to do moving around daughter grids inside a heap;
128 #define _SPLIT_OFF_ 0
129 #define _SPLIT_ON_ 1
130 
131 class Mgrid;
132 
134  unsigned char property;
136 } ;
137 
139  friend class Mgrid;
140 
141  private:
142  // Yes, convert old allocate_interpolation_frame() to a constructor;
143  MgridInterpolation(Mgrid *mgrid);
144 
145  // There are few different types (see definitions below); they
146  // all give different accuracy and have a very different CPU consumption;
147  unsigned char mode;
148 
149  // For safety (cross-check) purposes store address of a grid
150  // for which this interpolation was cooked;
152 
153  // Algorithm is expected to be fast and straightforward;
154  // therefore KxMxN cube with adim[] sizes is chosen really as a
155  // cube around xx[] point in a local grid coordinate sequence,
156  // without any attempt to move it in order to have all
157  // cells defined; if 'big' cubes wanted, it is advisable
158  // to add *extrapolated* 'galo' cells outside of the measured area
159  // when producing mfile; NB: this may change in the future;
160  // natural XYZ (RFZ) sequence;
161  int adim[3];
162 
163  // Interpoaltion sequence -> XYZ (RFZ) coordinates mapping;
164  // sequence[0]=_Y_ means that interpolation is first done along
165  // Y (F) direction of XYZ (RFZ) coordinate system; used
166  // in case of SEQUENTIAL modes only;
167  int sequence[3], reversed[3];
168 
169 
170  // -------------- The rest are working variables; ---------------
171 
172 
173  // Bitwise mask of which types of cells may be considered
174  // _EDGE_/_EXTRA_/_DEAD_; _DEAD_ for 'self_cell' may make
175  // sense during extrapolation of original grig for exapmple;
177  // Whether or not cube finder may shift cube with respect to 'best'
178  // position; is allowed per default; no need to change?;
180 
181  // KxMxN cell area; allocated linearly for simplicity;
183 
184  // This is needed for the 'FAST' mode; NB: interpolation index sequence!;
186 
187  // This is a polynomial degree used for fitting (may differ from adim[]);
188  // natural XYZ (RFZ) sequence, of course;
189  int pdim[3];
190  // If cubic area fails, few of the dimensions may be prohibited
191  // for non-cubic extension; say may want to have a true 1-dim
192  // fitting for double entries in recoil detector magnet map;
194 
195  // If cell points have different weights regular cube case makes not too
196  // much sense since polynomial basis has to be rebuilt every time anyway;
197  // since point weights can be changed by user any time (protect later, please!)
198  // it is also expected that user is responsible for setting this flag;
200 
201  // Gradient calculation takes CPU time => disabled per default;
202  // in fact this works in 3D XYZ case only --> need to check;
204 
205  // KxMxN cell area; allocated linearly for simplicity;
208 
209  // N-dim position of the leftmost cell in case of a cubic positioning;
210  // natural XYZ (RFZ) sequence;
211  int left[3];
212 
213  // This is needed for the 'FAST' mode; NB: interpolation index sequence!;
214  double *v[3];
215 
216  // This is needed for the '1DIM POLY' mode; interpolation sequence!;
219 
220  // This is needed for the 'GLOBAL' mode; in fact it would probably make
221  // sense to equip polynomial structures with local thread buffers?;
223  // grad[] is the gradient;
225  // Gradient value in the last xx[] point where field value
226  // was calculated; do it better later;
227  double gvalue[3], ferr;
228 
229  // Cell, cube, etc handling routines;
230  int setAllowedCells(unsigned char _allowed_self_cells_mask,
231  unsigned char _allowed_neighbour_cells_mask);
232  int prepairIrregularCase(int cmp);
234  int checkNeighbouringCubicArea(TVector3 &xx, int cmp);
235  void fillOutputCubeArray(int gdim[3], MgridCombiCell *ok_arr, int shift[3]);
236  int checkSmallCube(int gdim[3], MgridCombiCell *ok_arr, int shift[3]);
237  int fillOkArray(int left[3], int adim[3], int cmp, MgridCombiCell *ok_arr);
238 
239  // Interpolation creation routines;
242  int assignBestSequence();
243  int assignSuggestedSequence(char _sequence[]);
244  int precookSequentialHighCommon(int _adim[], char _sequence[]);
246  int preCookMultiDimCommon(int _adim[]);
248 } ;
249 
250 // Possible bits in 'status' word; can not use 8 lower bits;
251 #define _BAD_MGRID_POINTER_ 0x00000100
252 #define _ZERO_INTERPOLATION_POINTER_ 0x00000200
253 #define _CELL_OUT_OF_GRID_ 0x00000400
254 // This type of self cells is not allowed;
255 #define _ILLEGAL_SELF_CELL_ 0x00000800
256 // Cube may not be positioned properly;
257 #define _CUBE_SHIFT_ 0x00001000
258 // Was not able to position cube of requested size at all;
259 #define _CUBE_FAILURE_ 0x00002000
260 // Cube movement was off and not allowed neighbour cell encountered;
261 #define _ILLEGAL_NEIGHBOUR_CELL_ 0x00004000
262 
263 #define _FAILURE_(mgrid, bit) {(mgrid)->last_field_status |= (bit); return -1; }
264 
265 #endif