GEMC  2.3
Geant4 Monte-Carlo Framework
dipole.cc
Go to the documentation of this file.
1 // gemc headers
2 #include "asciiField.h"
3 #include "utils.h"
4 
5 // 1D-dipole field
6 // Dependent on 2 cartesian coordinates (longitudinal, transverse)
7 // uniform in the other coordinate
8 // The values can be loaded from the map in any order
9 // as long as their speed is ordered.
10 // The values are indexed as B1_2D[longi][transverse]
11 
12 // from fieldFactory: load field map
14 {
15  setlocale(LC_NUMERIC, "en_US");
16 
17  int np_1 = map->getCoordinateWithSpeed(0).np;
18  int np_2 = map->getCoordinateWithSpeed(1).np;
19  double min1 = map->getCoordinateWithSpeed(0).min;
20  double min2 = map->getCoordinateWithSpeed(1).min;
21  double max1 = map->getCoordinateWithSpeed(0).max;
22  double max2 = map->getCoordinateWithSpeed(1).max;
23  double cell1 = (max1 - min1)/(np_1 - 1);
24  double cell2 = (max2 - min2)/(np_2 - 1);
25 
26  // Allocate memory. [LONGI][TRANSVERSE]
27  // as initialized in the map
28  map->B1_2D = new double*[map->np[0]];
29  for (unsigned int i = 0; i < map->np[0]; ++i)
30  map->B1_2D[i] = new double[map->np[1]];
31 
32 
33  double unit1 = get_number("1*" + map->getCoordinateWithSpeed(0).unit);
34  double unit2 = get_number("1*" + map->getCoordinateWithSpeed(1).unit);
35 
36  double scale = map->scaleFactor*get_number("1*" + map->unit);
37 
38  double d1, d2, b;
39 
40  // progress bar
41  int barWidth = 50;
42 
43  // using fscanf instead of c++ to read file, this is a lot faster
44  char ctmp[100];
45  string tmp;
46  FILE *fp = fopen (map->identifier.c_str(), "r");
47 
48  // ignoring header
49  while(tmp != "</mfield>")
50  {
51  fscanf(fp, "%s", ctmp);
52  tmp = string(ctmp);
53  }
54 
55  // now reading map
56  // values as read from map
57  for(int i1 = 0; i1<np_1 ; i1++)
58  {
59  for(int i2 = 0; i2<np_2 ; i2++)
60  {
61  fscanf(fp, "%lg %lg %lg", &d1, &d2, &b);
62 
63  d1 *= unit1;
64  d2 *= unit2;
65 
66  b *= scale;
67 
68  if(verbosity>4)
69  cout << " Loading Map: coordinates (" << d1 << ", " << d2 << ") value: " << b << endl;
70 
71 
72  // checking map consistency for first coordinate
73  if( (min1 + i1*cell1 - d1)/d1 > 0.001)
74  {
75  cout << " !! Error: coordinate index wrong. Map first point should be " << min1 + i1*cell1
76  << " but it's " << d1 << " instead. Cell size: " << cell1 << " min: " << min1 << " max : " << max1 << " index: " << i1 << endl;
77  }
78  // checking map consistency for second coordinate
79  if( (min2 + i2*cell2 - d2)/d2 > 0.001)
80  {
81  cout << " !! Error: coordinate index wrong. Map second point should be " << min2 + i2*cell2
82  << " but it's " << d2 << " instead. Cell size: " << cell2 << " min: " << min2 << " max : " << max2 << " index: " << i2 << endl;
83  }
84 
85  // calculating index
86  unsigned t1 = (unsigned) floor( ( d1 - min1 + cell1/2 ) / ( cell1 ) ) ;
87  unsigned t2 = (unsigned) floor( ( d2 - min2 + cell2/2 ) / ( cell2 ) ) ;
88 
89  // The values are indexed as B1_2D[longi][transverse]
90  if( map->getCoordinateWithSpeed(0).name == "longitudinal"
91  && map->getCoordinateWithSpeed(1).name == "transverse")
92  map->B1_2D[t1][t2] = b;
93 
94  if( map->getCoordinateWithSpeed(0).name == "transverse"
95  && map->getCoordinateWithSpeed(1).name == "longitudinal")
96  map->B1_2D[t2][t1] = b;
97 
98  }
99 
100  cout << " [";
101  double progress = (double)i1/(double)np_1;
102  int pos = progress*barWidth;
103  for (int i = 0; i < barWidth; ++i)
104  {
105  if (i < pos) cout << "=";
106  else if (i == pos) cout << ">";
107  else cout << " ";
108  }
109  cout << "] " << int(progress * 100.0) << " %\r";
110  cout.flush();
111  }
112  fclose(fp);
113 
114  cout << endl;
115 }
116 
117 // from mappedField: GetFieldValue
118 void gMappedField::GetFieldValue_Dipole( const double x[3], double *Bfield, int FIRST_ONLY) const
119 {
120  double LC = 0; // longitudinal
121  double TC = 0; // transverse
122 
123  if(symmetry == "dipole-x")
124  {
125  TC = x[1];
126  LC = x[2];
127  }
128  if(symmetry == "dipole-y")
129  {
130  TC = x[0];
131  LC = x[2];
132  }
133  if(symmetry == "dipole-z")
134  {
135  TC = x[0];
136  LC = x[1];
137  }
138 
139  // map indexes, bottom of the cell
140  unsigned int IL = floor( ( LC - startMap[0] ) / cellSize[0] );
141  unsigned int IT = floor( ( TC - startMap[1] ) / cellSize[1] );
142 
143  // checking if the point is closer to the top of the cell
144  if( fabs( startMap[0] + IL*cellSize[0] - LC) > fabs( startMap[0] + (IL+1)*cellSize[0] - LC) ) IL++;
145  if( fabs( startMap[1] + IT*cellSize[1] - TC) > fabs( startMap[1] + (IT+1)*cellSize[1] - TC) ) IT++;
146 
147  // outside map, returning no field
148  if(IL>=np[0] || IT>=np[1]) return;
149 
150  // no interpolation
151  if(interpolation == "none")
152  {
153  if(symmetry == "dipole-x") Bfield[0] = B1_2D[IL][IT];
154  if(symmetry == "dipole-y") Bfield[1] = B1_2D[IL][IT];
155  if(symmetry == "dipole-z") Bfield[2] = B1_2D[IL][IT];
156  }
157 
158  // we don't worry about computer speed
159  // if verbosity is set this high
160  // so we can output units as well
161  if(verbosity>3 && FIRST_ONLY != 99)
162  {
163  cout << " > Track position in magnetic field: "
164  << "(" << (x[0] + mapOrigin[0])/cm << ", "
165  << (x[1] + mapOrigin[1])/cm << ", "
166  << (x[2] + mapOrigin[2])/cm << ") cm, " << endl;
167  cout << " Dipole: ";
168  cout << "loc. pos. = (" << x[0]/cm << ", " << x[1]/cm << ", " << x[2]/cm << ") cm, ";
169  cout << "IT=" << IT << " ";
170  cout << "IL=" << IL << ", ";
171  cout << "B = (" << Bfield[0]/gauss << ", " << Bfield[1]/gauss << ", " << Bfield[2]/gauss << ") gauss " << endl;
172 
173  }
174 }
175 
176 
177 
178 
179 
180 
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 scaleFactor
copy of the gfield scaleFactor
Definition: mappedField.h:96
double min
Definition: mappedField.h:41
double ** B1_2D
Definition: mappedField.h:107
void GetFieldValue_Dipole(const double x[3], double *Bfield, int FIRST_ONLY) const
Definition: dipole.cc:118
double get_number(string v, int warn_no_unit)
Returns number with dimension from string, i.e. 100*cm.
double max
Definition: mappedField.h:42
gcoord getCoordinateWithSpeed(int speed)
return coordinate based on speed
Definition: mappedField.cc:38
string unit
Definition: mappedField.h:43
void loadFieldMap_Dipole(gMappedField *, double)
Definition: dipole.cc:13
string identifier
Pointer to map in factory (for example, hostname / filename with path / date)
Definition: mappedField.h:92