View Javadoc

1   package org.lcsim.geometry.field;
2   
3   import hep.physics.vec.BasicHep3Vector;
4   import java.io.BufferedReader;
5   import java.io.File;
6   import java.io.FileReader;
7   import java.io.IOException;
8   import org.jdom.Element;
9   import org.jdom.JDOMException;
10  import java.net.URL;
11  import org.lcsim.util.cache.FileCache;
12  import static java.lang.Math.abs;
13  import static java.lang.Math.sqrt;
14  import static java.lang.Math.atan2;
15  import static java.lang.Math.sin;
16  import static java.lang.Math.cos;
17  
18  /**
19   *
20   * @author jeremym
21   */
22  public class RZFieldMap extends AbstractFieldMap
23  {
24      private int numBinsR;
25      private int numBinsZ;
26      
27      private double gridSizeR;
28      private double gridSizeZ;
29      
30      private double maxZ;
31      private double maxR;
32      private double maxRSquared;
33      
34      private String location;
35      
36      private double[][] BrArray;
37      private double[][] BzArray;
38      
39      public RZFieldMap(Element node) throws JDOMException
40      {
41          super(node);       
42          
43          numBinsR = node.getAttribute("numBinsR").getIntValue();
44          
45          if (numBinsR < 2)
46          {
47              throw new JDOMException("numBinsR is invalid: " + numBinsR);
48          }
49          
50          numBinsZ = node.getAttribute("numBinsZ").getIntValue();
51          
52          if (numBinsZ < 2)
53          {
54              throw new JDOMException("numBinsZ is invalid: " + numBinsZ);
55          }
56         
57          /* FIXME: Hard-coded conversion of cm to mm. */
58          gridSizeR = node.getAttribute("gridSizeR").getDoubleValue() * 10;
59          gridSizeZ = node.getAttribute("gridSizeZ").getDoubleValue() * 10;
60          
61          maxR = ( numBinsR - 1 ) * gridSizeR;
62          maxZ = ( numBinsZ - 1 ) * gridSizeZ;
63          maxRSquared = maxR*maxR;
64          
65          BrArray = new double[numBinsZ][numBinsR];
66          BzArray = new double[numBinsZ][numBinsR];
67                 
68          location = node.getAttribute("url").getValue();
69          
70          try
71          {
72              readFieldMap();
73          }
74          catch (Exception e)
75          {
76              throw new RuntimeException("Error reading field map from " + location, e);
77          }
78      }
79      
80      private void readFieldMap() throws IOException
81      {
82          readFieldMap(this.location);
83      }
84      
85      private void readFieldMap(String location) throws IOException
86      {
87          FileCache cache = new FileCache();
88          File file = cache.getCachedFile(new URL(location));
89          
90          BufferedReader reader = new BufferedReader(new FileReader(file));
91          
92          for (;;)
93          {
94              String line = reader.readLine();
95              if (line == null) break;
96              String[] chunks = line.trim().split(" +");
97              
98              if ( chunks.length > 0 )
99              {
100                 if ( chunks.length != 4 )
101                 {
102                     throw new IOException("Invalid RZ field map line: " + line);
103                 }
104                 
105                 /* FIXME: Hard-coded unit conversion of cm to mm. */
106                 double z = Double.parseDouble(chunks[0]) * 10;
107                 double r = Double.parseDouble(chunks[1]) * 10;
108                 
109                 /* FIXME: Hard-coded unit conversion of kilogauss to tesla. */
110                 double Bz = Double.parseDouble(chunks[2]) / 10;
111                 double Br = Double.parseDouble(chunks[3]) / 10;
112                 
113                 int iz= (int) ((z + 0.0001)/gridSizeZ);
114                 int ir=(int) ((r + 0.0001)/gridSizeR);
115                 
116                 if ( iz > ( numBinsZ - 1) )
117                 {
118                     throw new IOException("z bin out of range: " + iz);
119                 }
120                 
121                 if ( ir > ( numBinsR - 1) )
122                 {
123                     throw new IOException("r bin out of range:" + ir);
124                 }
125                 
126                 BzArray[iz][ir] = Bz;
127                 BrArray[iz][ir] = Br;
128             }
129         }
130     }
131     
132     void getField(double x, double y, double z, BasicHep3Vector field)
133     {
134         double rSquared = x*x + y*y;
135         
136         double hz = 0;
137         double hr = 0;
138         
139         if(abs(z)>maxZ || rSquared>maxRSquared)
140         {
141             field.setV(0,0,0);
142             return;
143         }
144         double r = sqrt(rSquared);
145         // FIXME: .001?
146         int iz = (int) ((abs(z)+0.001)/gridSizeZ);
147         int ir = (int) ((r+0.001)/gridSizeR);
148         
149         // outside
150         if(iz<0 || ir>numBinsR)
151         {
152             field.setV(0,0,0);
153             return;
154         }
155         
156         int izfar = 0;
157         if(iz>=numBinsZ)
158         {
159             izfar = 1;
160             iz = numBinsZ;
161         }
162         
163         double bz0 = BzArray[iz][ir];
164         double br0 = BrArray[iz][ir];
165         
166         double delz = 0.;
167         double delr = 0.;
168         
169         double brdz = 0.;
170         double brdr = 0.;
171         
172         if(r>0.0)
173         {
174             delr = r - ((float)ir) * gridSizeR;
175             brdz = (BrArray[iz+1][ir]-br0)/gridSizeZ;
176             brdr = (BrArray[iz][ir+1]-br0)/gridSizeR;
177         }
178         
179         delz = abs(z) - ((float)iz) * gridSizeZ;
180         
181         double bzdz = (BzArray[iz+1][ir]-bz0)/gridSizeZ;
182         double bzdr = (BzArray[iz][ir+1]-bz0)/gridSizeR;
183         
184         if(izfar==1)
185         {
186             hz = bz0+bzdr*delr;
187             hr = br0+brdr*delr;
188         }
189         else
190         {
191             hz = bz0+bzdz*delz+bzdr*delr;
192             hr = br0+brdz*delz+brdr*delr;
193         }
194         
195         if(z<0.0) hr = -hr;
196         
197         double theta = atan2(y, x);
198         double hx = hr * cos(theta);
199         double hy = hr * sin(theta);
200         
201         field.setV(hx,hy,hz);
202     }
203         
204     public final int getNumBinsR()
205     {
206         return numBinsR;
207     }
208     
209     public final int getNumBinsZ()
210     {
211         return numBinsZ;
212     }
213     
214     public final double getGridSizeR()
215     {
216         return gridSizeR;
217     }
218     
219     public final double getGridSizeZ()
220     {
221         return gridSizeZ;
222     }
223     
224     public final double getMaxZ()
225     {
226         return maxZ;
227     }
228     
229     public final double getMaxR()
230     {
231         return maxR;
232     }
233 }