GEMC  2.2
Geant4 Monte-Carlo Framework
phi-segmented.cc
Go to the documentation of this file.
1 // gemc headers
2 #include "asciiField.h"
3 #include "utils.h"
4 
5 
6 // phi-segmented 3D field in cylindrical coordinates. Field itself is in cartesian coordinates.
7 // Dependent on 3 cartesian coordinates (transverse, azimuthal, longitudinal) expressed in cylindrical coordinate
8 // The values can be loaded from the map in any order as long as their speed is ordered.
9 // The values are indexed as B1_3D[transverse][longi]
10 // The field is two dimensional, ordered in the class as B1=BT, B2=BL
11 
12 // from fieldFactory: load field map
14 {
15  int np_1 = map->getCoordinateWithSpeed(0).np;
16  int np_2 = map->getCoordinateWithSpeed(1).np;
17  int np_3 = map->getCoordinateWithSpeed(2).np;
18  double min1 = map->getCoordinateWithSpeed(0).min;
19  double min2 = map->getCoordinateWithSpeed(1).min;
20  double min3 = map->getCoordinateWithSpeed(2).min;
21  double cell1 = (map->getCoordinateWithSpeed(0).max - min1)/(np_1 - 1);
22  double cell2 = (map->getCoordinateWithSpeed(1).max - min2)/(np_2 - 1);
23  double cell3 = (map->getCoordinateWithSpeed(2).max - min3)/(np_3 - 1);
24 
25  // Allocate memory. [AZI][TRANSVERSE][LONGI]
26  // as initialized in the map
27  map->B1_3D = new double**[map->np[0]];
28  map->B2_3D = new double**[map->np[0]];
29  map->B3_3D = new double**[map->np[0]];
30  for (unsigned i = 0; i < map->np[0]; ++i)
31  {
32  map->B1_3D[i] = new double*[map->np[1]];
33  map->B2_3D[i] = new double*[map->np[1]];
34  map->B3_3D[i] = new double*[map->np[1]];
35  for (unsigned j = 0; j < map->np[1]; ++j)
36  {
37  map->B1_3D[i][j] = new double[map->np[2]];
38  map->B2_3D[i][j] = new double[map->np[2]];
39  map->B3_3D[i][j] = new double[map->np[2]];
40 
41  }
42  }
43 
44  double unit1 = get_number("1*" + map->getCoordinateWithSpeed(0).unit);
45  double unit2 = get_number("1*" + map->getCoordinateWithSpeed(1).unit);
46  double unit3 = get_number("1*" + map->getCoordinateWithSpeed(2).unit);
47 
48  double scale = map->scaleFactor*get_number("1*" + map->unit);
49 
50  double d1, d2, d3, b1, b2, b3;
51 
52  // progress bar
53  int barWidth = 50;
54 
55  // using fscanf instead of c++ to read file, this is a lot faster
56  char ctmp[100];
57  string tmp;
58  FILE *fp = fopen (map->identifier.c_str(), "r");
59 
60  // ignoring header
61  while(tmp != "</mfield>")
62  {
63  fscanf(fp, "%s", ctmp);
64  tmp = string(ctmp);
65  }
66 
67  // now reading map
68  // values as read from map
69  for(int i1 = 0; i1<np_1 ; i1++)
70  {
71  for(int i2 = 0; i2<np_2 ; i2++)
72  {
73  for(int i3 = 0; i3<np_3 ; i3++)
74  {
75  fscanf(fp, "%lg %lg %lg %lg %lg %lg", &d1, &d2, &d3, &b1, &b2, &b3);
76 
77  d1 *= unit1;
78  d2 *= unit2;
79  d3 *= unit3;
80  b1 *= scale;
81  b2 *= scale;
82  b3 *= scale;
83 
84  // checking map consistency for first coordinate
85  if( (min1 + i1*cell1 - d1)/d1 > 0.001)
86  {
87  cout << " !! Error: coordinate index wrong. Map point should be " << min1 + i1*cell1
88  << " but it's " << d1 << " instead." << endl;
89  }
90  // checking map consistency for second coordinate
91  if( (min2 + i2*cell2 - d2)/d2 > 0.001)
92  {
93  cout << " !! Error: coordinate index wrong. Map point should be " << min2 + i2*cell2
94  << " but it's " << d2 << " instead." << endl;
95  }
96 
97  // checking map consistency for third coordinate
98  if( (min3 + i3*cell3 - d3)/d3 > 0.001)
99  {
100  cout << " !! Error: coordinate index wrong. Map point should be " << min2 + i2*cell2
101  << " but it's " << d2 << " instead." << endl;
102  }
103 
104 
105  // calculating index
106  unsigned t1 = (unsigned) floor( ( d1 - min1 + cell1/2 ) / ( cell1 ) ) ;
107  unsigned t2 = (unsigned) floor( ( d2 - min2 + cell2/2 ) / ( cell2 ) ) ;
108  unsigned t3 = (unsigned) floor( ( d3 - min3 + cell3/2 ) / ( cell3 ) ) ;
109 
110  // The values are indexed as B1_3D[AZI][TRANSVERSE][LONGI]
111  if( map->getCoordinateWithSpeed(0).name == "azimuthal"
112  && map->getCoordinateWithSpeed(1).name == "transverse"
113  && map->getCoordinateWithSpeed(2).name == "longitudinal" )
114  {
115  map->B1_3D[t1][t2][t3] = b1;
116  map->B2_3D[t1][t2][t3] = b2;
117  map->B3_3D[t1][t2][t3] = b3;
118  }
119  if( map->getCoordinateWithSpeed(0).name == "azimuthal"
120  && map->getCoordinateWithSpeed(1).name == "longitudinal"
121  && map->getCoordinateWithSpeed(2).name == "transverse" )
122  {
123  map->B1_3D[t1][t3][t2] = b1;
124  map->B2_3D[t1][t3][t2] = b2;
125  map->B3_3D[t1][t3][t2] = b3;
126  }
127  if( map->getCoordinateWithSpeed(0).name == "longitudinal"
128  && map->getCoordinateWithSpeed(1).name == "azimuthal"
129  && map->getCoordinateWithSpeed(2).name == "transverse" )
130  {
131  map->B1_3D[t3][t1][t2] = b1;
132  map->B2_3D[t3][t1][t2] = b2;
133  map->B3_3D[t3][t1][t2] = b3;
134  }
135  if( map->getCoordinateWithSpeed(0).name == "longitudinal"
136  && map->getCoordinateWithSpeed(1).name == "transverse"
137  && map->getCoordinateWithSpeed(2).name == "azimuthal" )
138  {
139  map->B1_3D[t3][t2][t1] = b1;
140  map->B2_3D[t3][t2][t1] = b2;
141  map->B3_3D[t3][t2][t1] = b3;
142  }
143  if( map->getCoordinateWithSpeed(0).name == "transverse"
144  && map->getCoordinateWithSpeed(1).name == "longitudinal"
145  && map->getCoordinateWithSpeed(2).name == "azimuthal" )
146  {
147  map->B1_3D[t2][t3][t1] = b1;
148  map->B2_3D[t2][t3][t1] = b2;
149  map->B3_3D[t2][t3][t1] = b3;
150  }
151  if( map->getCoordinateWithSpeed(0).name == "transverse"
152  && map->getCoordinateWithSpeed(1).name == "azimuthal"
153  && map->getCoordinateWithSpeed(2).name == "longitudinal" )
154  {
155  map->B1_3D[t2][t1][t3] = b1;
156  map->B2_3D[t2][t1][t3] = b2;
157  map->B3_3D[t2][t1][t3] = b3;
158  }
159 
160  }
161  }
162 
163  cout << " [";
164  double progress = (double)i1/(double)np_1;
165  int pos = progress*barWidth;
166  for (int i = 0; i < barWidth; ++i)
167  {
168  if (i < pos) cout << "=";
169  else if (i == pos) cout << ">";
170  else cout << " ";
171  }
172  cout << "] " << int(progress * 100.0) << " %\r";
173  cout.flush();
174  }
175  fclose(fp);
176 
177  cout << endl;
178 }
179 
180 // from mappedField: GetFieldValue
181 void gMappedField::GetFieldValue_phiSegmented( const double x[3], double *Bfield, int FIRST_ONLY) const
182 {
183 
184  // this routine will rotate the coordinate to segment local
185  // coordinates to find the map indexes.
186  // Then it will rotate the field back to the original position
187 
188  double mfield[3] = {0,0,0};
189 
190  double aC = 0; // azimuthal
191  double tC = 0; // transverse
192  double lC = 0; // longitudinal
193 
194  double aLC;
195  unsigned aI, tI, lI;
196 
197 
198  aC = atan2( x[1], x[0] )*rad;
199  if( aC < 0 ) aC += 360*deg;
200 
201  tC = sqrt(x[0]*x[0] + x[1]*x[1]);
202  lC = x[2];
203 
204  // Rotating the point to within the map limit
205  int segment = 1;
206  aLC = aC;
207  while (aLC/deg > 30)
208  {
209  aLC -= 60*deg;
210  segment++;
211  }
212 
213  // need the delta phi from the local coordinate, so we can rotate the field back to the original point
214  double dphi = aC - aLC;
215 
216  // for the map index we need the absolute value
217  double aaLC = fabs(aLC);
218 
219  // map indexes, bottom of the cell
220  aI = floor( ( aaLC - startMap[0] ) / cellSize[0] );
221  tI = floor( ( tC - startMap[1] ) / cellSize[1] );
222  lI = floor( ( lC - startMap[2] ) / cellSize[2] );
223 
224  // checking if the point is closer to the top of the cell
225  if( fabs( startMap[0] + aI*cellSize[0] - aaLC) > fabs( startMap[0] + (aI + 1)*cellSize[0] - aaLC) ) aI++;
226  if( fabs( startMap[1] + tI*cellSize[1] - tC) > fabs( startMap[1] + (tI + 1)*cellSize[1] - tC) ) tI++;
227  if( fabs( startMap[2] + lI*cellSize[2] - lC) > fabs( startMap[2] + (lI + 1)*cellSize[2] - lC) ) lI++;
228 
229  // outside map, returning no field
230  if(aI >= np[0] || tI >= np[1] || lI >= np[2]) return;
231 
232 
233  // positive on the right side of the segment
234  int sign = (aLC >= 0 ? 1 : -1);
235 
236 
237  // no interpolation
238  if(interpolation == "none")
239  {
240  // Field at local point
241  mfield[0] = B1_3D[aI][tI][lI];
242  mfield[1] = B2_3D[aI][tI][lI];
243  mfield[2] = B3_3D[aI][tI][lI];
244 
245 
246  // Rotating the field back to original point
247  Bfield[0] = sign*mfield[0] * cos(dphi/rad) - mfield[1] * sin(dphi/rad);
248  Bfield[1] = sign*mfield[0] * sin(dphi/rad) + mfield[1] * cos(dphi/rad);
249  Bfield[2] = sign*mfield[2];
250 
251  if(verbosity>3 && FIRST_ONLY != 99)
252  {
253 
254  cout << " > Track position in magnetic field: "
255  << "(" << (x[0] + mapOrigin[0])/cm << ", "
256  << (x[1] + mapOrigin[1])/cm << ", "
257  << (x[2] + mapOrigin[2])/cm << ") cm, " << endl;
258 
259  cout << " > Track position in magnetic field (phi, r, z): "
260  << "(" << aC/deg << " deg, "
261  << tC/cm << " cm, "
262  << lC/cm << " cm) " << endl;
263 
264  cout << " > Local coordinates (phi, segment, delta phi) "
265  << "(" << aaLC/deg << " deg, "
266  << segment << ", "
267  << dphi/deg << " deg) " << endl;
268 
269  cout << " > Map Indexes (phi, r, z) "
270  << "(" << aI << ", "
271  << tI << ", "
272  << lI << ") " << endl;
273 
274  cout << " > Field Values (local) (Bx, By, Bz) "
275  << "(" << mfield[0]/tesla << ", "
276  << mfield[1]/tesla << ", "
277  << mfield[2]/tesla << ") tesla " << endl;
278 
279  cout << " > Field Values (absolute) (Bx, By, Bz) "
280  << "(" << Bfield[0]/tesla << ", "
281  << Bfield[1]/tesla << ", "
282  << Bfield[2]/tesla << ") tesla " << endl;
283 
284  cout << endl;
285  }
286  }
287 }
288 
289 
290 
291 
292 
293 
unsigned int np
Definition: mappedField.h:40
string unit
field unit in the map
Definition: mappedField.h:97
double verbosity
string name
Definition: mappedField.h:39
unsigned int * np
Definition: mappedField.h:116
double *** B2_3D
Definition: mappedField.h:103
double scaleFactor
copy of the gfield scaleFactor
Definition: mappedField.h:96
double min
Definition: mappedField.h:41
double get_number(string v, int warn_no_unit)
Returns number with dimension from string, i.e. 100*cm.
double *** B3_3D
Definition: mappedField.h:104
double max
Definition: mappedField.h:42
void loadFieldMap_phiSegmented(gMappedField *, double)
gcoord getCoordinateWithSpeed(int speed)
return coordinate based on speed
Definition: mappedField.cc:38
string unit
Definition: mappedField.h:43
void GetFieldValue_phiSegmented(const double x[3], double *Bfield, int FIRST_ONLY) const
double *** B1_3D
Definition: mappedField.h:102
string identifier
Pointer to map in factory (for example, hostname / filename with path / date)
Definition: mappedField.h:92