1 package org.lcsim.recon.tracking.magfield;
2
3 import java.io.*;
4 import java.util.ArrayList;
5 import java.util.StringTokenizer;
6 import org.lcsim.recon.tracking.spacegeom.CartesianPointVector;
7 import org.lcsim.recon.tracking.spacegeom.SpacePoint;
8 import org.lcsim.recon.tracking.spacegeom.SpacePointTensor;
9 import org.lcsim.recon.tracking.spacegeom.SpacePointVector;
10
11
12
13
14
15
16
17 public class Cartesian3DMagneticFieldMap extends AbstractMagneticField
18 {
19
20
21 private double[][][] _xField;
22 private double[][][] _yField;
23 private double[][][] _zField;
24
25 private int _nx, _ny, _nz;
26
27 private double _minx, _maxx, _miny, _maxy, _minz, _maxz;
28
29 private double _dx, _dy, _dz;
30
31 private double _xOffset;
32 private double _yOffset;
33 private double _zOffset;
34
35 public Cartesian3DMagneticFieldMap(InputStream is, double xOffset, double yOffset, double zOffset)
36 {
37 _xOffset = xOffset;
38 _yOffset = yOffset;
39 _zOffset = zOffset;
40
41 System.out.println("\n-----------------------------------------------------------"
42 + "\n Reading Magnetic Field map"
43 + "\n-----------------------------------------------------------");
44
45 try {
46 BufferedReader myInput = new BufferedReader(new InputStreamReader(new BufferedInputStream(is)));
47
48 String thisLine;
49
50 thisLine = myInput.readLine();
51
52 thisLine = myInput.readLine();
53
54 StringTokenizer st = new StringTokenizer(thisLine, " ");
55 _nx = Integer.parseInt(st.nextToken());
56 _ny = Integer.parseInt(st.nextToken());
57 _nz = Integer.parseInt(st.nextToken());
58
59
60
61 _xField = new double[_nx + 1][_ny + 1][_nz + 1];
62 _yField = new double[_nx + 1][_ny + 1][_nz + 1];
63 _zField = new double[_nx + 1][_ny + 1][_nz + 1];
64
65
66
67
68 do {
69 thisLine = myInput.readLine();
70 st = new StringTokenizer(thisLine, " ");
71 } while (!st.nextToken().trim().equals("0"));
72
73
74
75
76
77 int ix, iy, iz;
78 double xval = 0.;
79 double yval = 0.;
80 double zval = 0.;
81 double bx, by, bz;
82 for (ix = 0; ix < _nx; ix++) {
83 for (iy = 0; iy < _ny; iy++) {
84 for (iz = 0; iz < _nz; iz++) {
85 thisLine = myInput.readLine();
86 st = new StringTokenizer(thisLine, " ");
87 xval = Double.parseDouble(st.nextToken());
88 yval = Double.parseDouble(st.nextToken());
89 zval = Double.parseDouble(st.nextToken());
90 bx = Double.parseDouble(st.nextToken());
91 by = Double.parseDouble(st.nextToken());
92 bz = Double.parseDouble(st.nextToken());
93 if (ix == 0 && iy == 0 && iz == 0) {
94 _minx = xval;
95 _miny = yval;
96 _minz = zval;
97 }
98 _xField[ix][iy][iz] = bx;
99 _yField[ix][iy][iz] = by;
100 _zField[ix][iy][iz] = bz;
101 }
102 }
103 }
104
105 _maxx = xval;
106 _maxy = yval;
107 _maxz = zval;
108
109 System.out.println("\n ---> ... done reading ");
110 System.out.println(" ---> assumed the order: x, y, z, Bx, By, Bz "
111 + "\n ---> Min values x,y,z: "
112 + _minx + " " + _miny + " " + _minz + " cm "
113 + "\n ---> Max values x,y,z: "
114 + _maxx + " " + _maxy + " " + _maxz + " cm "
115 + "\n ---> The field will be offset by " + _xOffset + " " + _yOffset + " " + _zOffset + " cm ");
116
117 _dx = _maxx - _minx;
118 _dy = _maxy - _miny;
119 _dz = _maxz - _minz;
120 System.out.println("\n ---> Range of values x,y,z: "
121 + _dx + " " + _dy + " " + _dz + " cm in z "
122 + "\n-----------------------------------------------------------");
123
124 myInput.close();
125 } catch (Exception e) {
126 e.printStackTrace();
127 }
128
129 }
130
131 @Override
132 public SpacePointVector field(SpacePoint p)
133 {
134 double x = p.x() + _xOffset;
135 double y = p.y() + _yOffset;
136 double z = p.z() + _zOffset;
137 double[] Bfield = new double[3];
138
139 if (x >= _minx && x <= _maxx
140 && y >= _miny && y <= _maxy
141 && z >= _minz && z <= _maxz) {
142
143
144
145 double xfraction = (x - _minx) / _dx;
146 double yfraction = (y - _miny) / _dy;
147 double zfraction = (z - _minz) / _dz;
148
149 double xdindex, ydindex, zdindex;
150
151
152
153 double[] xmodf = modf(xfraction * (_nx - 1));
154 double[] ymodf = modf(yfraction * (_ny - 1));
155 double[] zmodf = modf(zfraction * (_nz - 1));
156
157
158
159
160 int xindex = (int) xmodf[0];
161 int yindex = (int) ymodf[0];
162 int zindex = (int) zmodf[0];
163 double xlocal = xmodf[1];
164 double ylocal = ymodf[1];
165 double zlocal = zmodf[1];
166
167 Bfield[0] =
168 _xField[xindex][yindex][zindex] * (1 - xlocal) * (1 - ylocal) * (1 - zlocal)
169 + _xField[xindex][yindex][zindex + 1] * (1 - xlocal) * (1 - ylocal) * zlocal
170 + _xField[xindex][yindex + 1][zindex] * (1 - xlocal) * ylocal * (1 - zlocal)
171 + _xField[xindex][yindex + 1][zindex + 1] * (1 - xlocal) * ylocal * zlocal
172 + _xField[xindex + 1][yindex][zindex] * xlocal * (1 - ylocal) * (1 - zlocal)
173 + _xField[xindex + 1][yindex][zindex + 1] * xlocal * (1 - ylocal) * zlocal
174 + _xField[xindex + 1][yindex + 1][zindex] * xlocal * ylocal * (1 - zlocal)
175 + _xField[xindex + 1][yindex + 1][zindex + 1] * xlocal * ylocal * zlocal;
176 Bfield[1] =
177 _yField[xindex][yindex][zindex] * (1 - xlocal) * (1 - ylocal) * (1 - zlocal)
178 + _yField[xindex][yindex][zindex + 1] * (1 - xlocal) * (1 - ylocal) * zlocal
179 + _yField[xindex][yindex + 1][zindex] * (1 - xlocal) * ylocal * (1 - zlocal)
180 + _yField[xindex][yindex + 1][zindex + 1] * (1 - xlocal) * ylocal * zlocal
181 + _yField[xindex + 1][yindex][zindex] * xlocal * (1 - ylocal) * (1 - zlocal)
182 + _yField[xindex + 1][yindex][zindex + 1] * xlocal * (1 - ylocal) * zlocal
183 + _yField[xindex + 1][yindex + 1][zindex] * xlocal * ylocal * (1 - zlocal)
184 + _yField[xindex + 1][yindex + 1][zindex + 1] * xlocal * ylocal * zlocal;
185 Bfield[2] =
186 _zField[xindex][yindex][zindex] * (1 - xlocal) * (1 - ylocal) * (1 - zlocal)
187 + _zField[xindex][yindex][zindex + 1] * (1 - xlocal) * (1 - ylocal) * zlocal
188 + _zField[xindex][yindex + 1][zindex] * (1 - xlocal) * ylocal * (1 - zlocal)
189 + _zField[xindex][yindex + 1][zindex + 1] * (1 - xlocal) * ylocal * zlocal
190 + _zField[xindex + 1][yindex][zindex] * xlocal * (1 - ylocal) * (1 - zlocal)
191 + _zField[xindex + 1][yindex][zindex + 1] * xlocal * (1 - ylocal) * zlocal
192 + _zField[xindex + 1][yindex + 1][zindex] * xlocal * ylocal * (1 - zlocal)
193 + _zField[xindex + 1][yindex + 1][zindex + 1] * xlocal * ylocal * zlocal;
194
195 } else {
196 Bfield[0] = 0.0;
197 Bfield[1] = 0.0;
198 Bfield[2] = 0.0;
199 }
200
201 return new CartesianPointVector(p, Bfield[0], Bfield[1], Bfield[2]);
202 }
203
204 @Override
205 public SpacePointVector field(SpacePoint p, SpacePointTensor g)
206 {
207 throw new UnsupportedOperationException("Not supported yet.");
208 }
209
210 public double minX()
211 {
212 return _minx + _xOffset;
213 }
214
215 public double minY()
216 {
217 return _miny + _yOffset;
218 }
219
220 public double minZ()
221 {
222 return _minz + _zOffset;
223 }
224
225 public double maxX()
226 {
227 return _maxx + _xOffset;
228 }
229
230 public double maxY()
231 {
232 return _maxy + _yOffset;
233 }
234
235 public double maxZ()
236 {
237 return _maxz + _zOffset;
238 }
239
240
241 private double[] modf(double fullDouble)
242 {
243 int intVal = (int) fullDouble;
244 double remainder = fullDouble - intVal;
245
246 double[] retVal = new double[2];
247 retVal[0] = intVal;
248 retVal[1] = remainder;
249
250 return retVal;
251 }
252 }