1 package org.lcsim.geometry.field;
2
3 import hep.physics.vec.BasicHep3Vector;
4 import hep.physics.vec.Hep3Vector;
5 import java.io.BufferedReader;
6 import java.io.File;
7 import java.io.FileInputStream;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.io.InputStreamReader;
11 import static java.lang.Math.sqrt;
12 import java.net.URL;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.StringTokenizer;
16 import org.jdom.Element;
17 import org.jdom.JDOMException;
18 import org.lcsim.util.cache.FileCache;
19
20
21
22
23
24
25
26 public class FieldMap3D extends AbstractFieldMap
27 {
28 private double[][][] _xField;
29 private double[][][] _yField;
30 private double[][][] _zField;
31
32 private int _nx, _ny, _nz;
33
34 private double _minx, _maxx, _miny, _maxy, _minz, _maxz;
35
36 private double _dx, _dy, _dz;
37
38 private double _xOffset;
39 private double _yOffset;
40 private double _zOffset;
41
42 private double _bMax;
43 private double[] _Bfield = new double[3];
44 String _filename;
45
46 public FieldMap3D(Element node) throws JDOMException
47 {
48 super(node);
49 _xOffset = node.getAttribute("xoffset").getDoubleValue();
50 _yOffset = node.getAttribute("yoffset").getDoubleValue();
51 _zOffset = node.getAttribute("zoffset").getDoubleValue();
52 _filename = node.getAttributeValue("filename");
53 System.out.println("Field Map location: " + _filename);
54 try {
55 setup(_filename);
56 } catch (Exception e) {
57 throw new RuntimeException("Error reading field map from " + _filename, e);
58 }
59 }
60
61 private void setup(String filename) throws IOException
62 {
63 InputStream fis;
64 BufferedReader br;
65 String line;
66
67
68 if (filename.startsWith("http")) {
69 FileCache cache = new FileCache();
70 File file = cache.getCachedFile(new URL(filename));
71 fis = new FileInputStream(file);
72 } else {
73 fis = new FileInputStream(filename);
74 }
75
76 System.out.println("-----------------------------------------------------------");
77 System.out.println("FieldMap3D ");
78 System.out.println("-----------------------------------------------------------");
79 System.out.println("Reading the field grid from " + filename + " ... ");
80
81 br = new BufferedReader(new InputStreamReader(fis));
82
83 line = br.readLine();
84
85 line = br.readLine();
86
87 StringTokenizer st = new StringTokenizer(line, " ");
88 _nx = Integer.parseInt(st.nextToken());
89 _ny = Integer.parseInt(st.nextToken());
90 _nz = Integer.parseInt(st.nextToken());
91
92
93 _xField = new double[_nx + 1][_ny + 1][_nz + 1];
94 _yField = new double[_nx + 1][_ny + 1][_nz + 1];
95 _zField = new double[_nx + 1][_ny + 1][_nz + 1];
96
97
98
99
100 do {
101 line = br.readLine();
102 System.out.println(line);
103 st = new StringTokenizer(line, " ");
104 } while (!st.nextToken().trim().equals("0"));
105
106
107
108
109
110
111 int conversionFactor = 1000;
112 int ix, iy, iz;
113 double xval = 0.;
114 double yval = 0.;
115 double zval = 0.;
116 double bx, by, bz;
117 for (ix = 0; ix < _nx; ix++) {
118 for (iy = 0; iy < _ny; iy++) {
119 for (iz = 0; iz < _nz; iz++) {
120 line = br.readLine();
121 st = new StringTokenizer(line, " ");
122 xval = Double.parseDouble(st.nextToken());
123 yval = Double.parseDouble(st.nextToken());
124 zval = Double.parseDouble(st.nextToken());
125 bx = Double.parseDouble(st.nextToken())*conversionFactor;
126 by = Double.parseDouble(st.nextToken())*conversionFactor;
127 bz = Double.parseDouble(st.nextToken())*conversionFactor;
128 if (ix == 0 && iy == 0 && iz == 0) {
129 _minx = xval;
130 _miny = yval;
131 _minz = zval;
132 }
133 _xField[ix][iy][iz] = bx;
134 _yField[ix][iy][iz] = by;
135 _zField[ix][iy][iz] = bz;
136 double b = bx * bx + by * by + bz * bz;
137 if (b > _bMax) {
138 _bMax = b;
139 }
140 }
141 }
142 }
143 _bMax = sqrt(_bMax);
144
145 _maxx = xval;
146 _maxy = yval;
147 _maxz = zval;
148
149 System.out.println("\n ---> ... done reading ");
150 System.out.println(" ---> assumed the order: x, y, z, Bx, By, Bz "
151 + "\n ---> Min values x,y,z: "
152 + _minx + " " + _miny + " " + _minz
153 + "\n ---> Max values x,y,z: "
154 + _maxx + " " + _maxy + " " + _maxz
155 + "\n Maximum Field strength: " + _bMax + " "
156 + "\n ---> The field will be offset by " + _xOffset + " " + _yOffset + " " + _zOffset);
157
158 _dx = _maxx - _minx;
159 _dy = _maxy - _miny;
160 _dz = _maxz - _minz;
161 System.out.println("\n ---> Range of values x,y,z: "
162 + _dx + " " + _dy + " " + _dz
163 + "\n-----------------------------------------------------------");
164
165 br.close();
166 }
167
168 @Override
169 public void getField(double[] position, double[] b)
170 {
171 getField(position[0], position[1], position[2]);
172 System.arraycopy(_Bfield, 0, b, 0, 3);
173 }
174
175 @Override
176 public Hep3Vector getField(Hep3Vector position)
177 {
178 getField(position.x(), position.y(), position.z());
179 return new BasicHep3Vector(_Bfield[0], _Bfield[1], _Bfield[2]);
180 }
181
182 @Override
183 public double[] getField(double[] position)
184 {
185 getField(position[0], position[1], position[2]);
186 double[] field = {_Bfield[0], _Bfield[1], _Bfield[2]};
187 return field;
188 }
189
190 @Override
191 void getField(double x, double y, double z, BasicHep3Vector field)
192 {
193 getField(x, y, z);
194 field.setV(_Bfield[0], _Bfield[1], _Bfield[2]);
195 }
196
197 public double[] globalOffset()
198 {
199 return new double[]{_xOffset, _yOffset, _zOffset};
200 }
201
202 private void getField(double x, double y, double z)
203 {
204
205 x -= _xOffset;
206 y -= _yOffset;
207 z -= _zOffset;
208
209 if (x >= _minx && x <= _maxx
210 && y >= _miny && y <= _maxy
211 && z >= _minz && z <= _maxz) {
212
213
214
215 double xfraction = (x - _minx) / _dx;
216 double yfraction = (y - _miny) / _dy;
217 double zfraction = (z - _minz) / _dz;
218
219
220
221
222 double[] xmodf = modf(xfraction * (_nx - 1));
223 double[] ymodf = modf(yfraction * (_ny - 1));
224 double[] zmodf = modf(zfraction * (_nz - 1));
225
226
227
228 int xindex = (int) xmodf[0];
229 int yindex = (int) ymodf[0];
230 int zindex = (int) zmodf[0];
231 double xlocal = xmodf[1];
232 double ylocal = ymodf[1];
233 double zlocal = zmodf[1];
234
235 _Bfield[0]
236 = _xField[xindex][yindex][zindex] * (1 - xlocal) * (1 - ylocal) * (1 - zlocal)
237 + _xField[xindex][yindex][zindex + 1] * (1 - xlocal) * (1 - ylocal) * zlocal
238 + _xField[xindex][yindex + 1][zindex] * (1 - xlocal) * ylocal * (1 - zlocal)
239 + _xField[xindex][yindex + 1][zindex + 1] * (1 - xlocal) * ylocal * zlocal
240 + _xField[xindex + 1][yindex][zindex] * xlocal * (1 - ylocal) * (1 - zlocal)
241 + _xField[xindex + 1][yindex][zindex + 1] * xlocal * (1 - ylocal) * zlocal
242 + _xField[xindex + 1][yindex + 1][zindex] * xlocal * ylocal * (1 - zlocal)
243 + _xField[xindex + 1][yindex + 1][zindex + 1] * xlocal * ylocal * zlocal;
244 _Bfield[1]
245 = _yField[xindex][yindex][zindex] * (1 - xlocal) * (1 - ylocal) * (1 - zlocal)
246 + _yField[xindex][yindex][zindex + 1] * (1 - xlocal) * (1 - ylocal) * zlocal
247 + _yField[xindex][yindex + 1][zindex] * (1 - xlocal) * ylocal * (1 - zlocal)
248 + _yField[xindex][yindex + 1][zindex + 1] * (1 - xlocal) * ylocal * zlocal
249 + _yField[xindex + 1][yindex][zindex] * xlocal * (1 - ylocal) * (1 - zlocal)
250 + _yField[xindex + 1][yindex][zindex + 1] * xlocal * (1 - ylocal) * zlocal
251 + _yField[xindex + 1][yindex + 1][zindex] * xlocal * ylocal * (1 - zlocal)
252 + _yField[xindex + 1][yindex + 1][zindex + 1] * xlocal * ylocal * zlocal;
253 _Bfield[2]
254 = _zField[xindex][yindex][zindex] * (1 - xlocal) * (1 - ylocal) * (1 - zlocal)
255 + _zField[xindex][yindex][zindex + 1] * (1 - xlocal) * (1 - ylocal) * zlocal
256 + _zField[xindex][yindex + 1][zindex] * (1 - xlocal) * ylocal * (1 - zlocal)
257 + _zField[xindex][yindex + 1][zindex + 1] * (1 - xlocal) * ylocal * zlocal
258 + _zField[xindex + 1][yindex][zindex] * xlocal * (1 - ylocal) * (1 - zlocal)
259 + _zField[xindex + 1][yindex][zindex + 1] * xlocal * (1 - ylocal) * zlocal
260 + _zField[xindex + 1][yindex + 1][zindex] * xlocal * ylocal * (1 - zlocal)
261 + _zField[xindex + 1][yindex + 1][zindex + 1] * xlocal * ylocal * zlocal;
262
263 } else {
264 _Bfield[0] = 0.0;
265 _Bfield[1] = 0.0;
266 _Bfield[2] = 0.0;
267 }
268 }
269
270
271 private double[] modf(double fullDouble)
272 {
273 int intVal = (int) fullDouble;
274 double remainder = fullDouble - intVal;
275
276 double[] retVal = new double[2];
277 retVal[0] = intVal;
278 retVal[1] = remainder;
279
280 return retVal;
281 }
282 }