GEMC  2.3
Geant4 Monte-Carlo Framework
asciiField.cc
Go to the documentation of this file.
1 // gemc headers
2 #include "fieldFactory.h"
3 #include "asciiField.h"
4 #include "string_utilities.h"
5 #include "utils.h"
6 
7 // CLHEP units
8 #include "CLHEP/Units/PhysicalConstants.h"
9 using namespace CLHEP;
10 
11 bool asciiField::isEligible(string file)
12 {
13  ifstream IN(file.c_str());
14 
15  if(!IN.is_open())
16  return 0;
17 
18  string first;
19  IN >> first;
20  IN.close();
21 
22  if(strcmp (first.c_str(), "<mfield>") != 0)
23  return 0;
24 
25  return 1;
26 }
27 
28 // load field definitions
30 {
31  gfield gf(opts);
32 
33  ifstream IN(file.c_str());
34  string content = "";
35  string stop = "";
36 
37  while(IN.good() && stop != "</mfield>")
38  {
39  IN >> stop;
40  content += stop + " " ;
41  }
42  IN.close();
43 
44  // sucking up all that string into a domdocument
45  QDomDocument domDocument;
46  domDocument.setContent(QString(content.c_str()));
47 
48 
49  QDomElement docElem = domDocument.documentElement();
50  QDomNode n = docElem.firstChild();
51  while(!n.isNull())
52  {
53  QDomElement e = n.toElement(); // converts the node to an element.
54  if(!e.isNull()) // check that the node really is an element.
55  {
56  if(e.tagName().toStdString() == "description")
57  {
58  gf.name = assignAttribute(e, "name", "na");
59  gf.factory = assignAttribute(e, "factory", "na");
60  gf.description = assignAttribute(e, "comment", "no comment");
61  }
62 
63  if(e.tagName().toStdString() == "symmetry")
64  {
65  gf.symmetry = assignAttribute(e, "type", "na");
66  gf.format = assignAttribute(e, "format", "na");
67  gf.integration = assignAttribute(e, "integration", "na");
68  gf.minStep = assignAttribute(e, "minStep", 0.01);
69  }
70 
71  // simple symmetry, looking for uniform field definition
72  if(gf.format == "simple" && gf.symmetry == "uniform")
73  {
74  if(e.tagName().toStdString() == "dimension")
75  {
76  string units = "*" + assignAttribute(e, "units", "gauss");
77  gf.dimensions = assignAttribute(e, "bx", "0") + units + " ";
78  gf.dimensions += assignAttribute(e, "by", "0") + units + " " ;
79  gf.dimensions += assignAttribute(e, "bz", "0") + units ;
80  }
81  }
82 
83 
84  // simple symmetry, looking for multipole field definition
85  if(gf.format == "simple" && gf.symmetry == "multipole")
86  {
87  if(e.tagName().toStdString() == "dimension")
88  {
89  gf.dimensions = assignAttribute(e, "Npole", "0") + " ";
90  gf.dimensions += assignAttribute(e, "scale", "0") + "*" + assignAttribute(e, "Bunit", "gauss") + " ";
91  gf.dimensions += assignAttribute(e, "x", "0") + "*" + assignAttribute(e, "XYZunit", "cm") + " ";
92  gf.dimensions += assignAttribute(e, "y", "0") + "*" + assignAttribute(e, "XYZunit", "cm") + " ";
93  gf.dimensions += assignAttribute(e, "z", "0") + "*" + assignAttribute(e, "XYZunit", "cm") + " ";
94  gf.dimensions += assignAttribute(e, "rot", "0") + "*" + assignAttribute(e, "ROTunit", "deg") + " ";
95  gf.dimensions += assignAttribute(e, "ROTaxis", "Y");
96  }
97  }
98 
99  // map symmetry, looking for map field definition
100  if(gf.format == "map")
101  {
102  if(!gf.map) gf.map = new gMappedField(file, gf.symmetry);
103 
104  // selecting "map" nodes
105  // selecting "coordinate" nodes
106  if(e.tagName().toStdString() == "map")
107  {
108  QDomNode nn= e.firstChild();
109  while(!nn.isNull())
110  {
111  QDomElement ee = nn.toElement();
112  if(ee.tagName().toStdString() == "coordinate")
113  {
114  QDomNode nnn= ee.firstChild();
115  while(!nnn.isNull())
116  {
117  QDomElement eee = nnn.toElement();
118 
119  if(eee.tagName().toStdString() == "first" || eee.tagName().toStdString() == "second" || eee.tagName().toStdString() == "third")
120  {
121 
122  string name = assignAttribute(eee, "name", "na");
123  int np = (int) assignAttribute(eee, "npoints", 0);
124  string unit = assignAttribute(eee, "units", "mm");
125  // loading min and max with their unit
126  double min = assignAttribute(eee, "min", 0.0)*get_number("1*" + unit);
127  double max = assignAttribute(eee, "max", 0.0)*get_number("1*" + unit);
128  int speed = 0;
129  if(eee.tagName().toStdString() == "second") speed = 1;
130  if(eee.tagName().toStdString() == "third") speed = 2;
131  gf.map->coordinates.push_back(gcoord(name, np, min, max, unit, speed));
132  }
133  nnn=nnn.nextSibling();
134  }
135  }
137  if(ee.tagName().toStdString() == "shift")
138  {
139  string unit = assignAttribute(ee, "units", "mm");
140  gf.map->mapOrigin[0] = assignAttribute(ee, "x", 0.0)*get_number("1*" + unit);
141  gf.map->mapOrigin[1] = assignAttribute(ee, "y", 0.0)*get_number("1*" + unit);
142  gf.map->mapOrigin[2] = assignAttribute(ee, "z", 0.0)*get_number("1*" + unit);
143  }
145  if(ee.tagName().toStdString() == "field")
146  {
147  gf.map->unit = assignAttribute(ee, "unit", "gauss");
148  }
150  if(ee.tagName().toStdString() == "interpolation")
151  {
152  gf.map->interpolation = assignAttribute(ee, "type", "none");
153  }
154  nn = nn.nextSibling();
155  }
156  }
157  }
158 
159  }
160  n = n.nextSibling();
161  }
162  // initialize field and field map
163  gf.initialize(opts);
164 
165  // rescaling dimensions for uniform field
166  if(gf.scaleFactor != 1 && gf.format == "simple" && gf.symmetry == "uniform")
167  {
168  vector<string> olddim = get_strings(gf.dimensions);
169  string newdim;
170  for(unsigned int d=0; d<olddim.size(); d++)
171  {
172  // default unit is "megatesla" since for volts is megavolt
173  newdim += stringify(get_number(olddim[d])*1000*gf.scaleFactor) + "*T " ;
174  }
175  gf.dimensions = TrimSpaces(newdim);
176  }
177 
178  // rescaling dimensions for multipole field
179  if(gf.scaleFactor != 1 && gf.format == "simple" && gf.symmetry == "multipole")
180  {
181  vector<string> olddim = get_strings(gf.dimensions);
182  string newdim;
183  for(unsigned int d=0; d<olddim.size(); d++)
184  {
185  if (d==1) newdim += stringify(gf.scaleFactor*atof(olddim[d].substr(0, olddim[d].find("*")).c_str()))
186  + "*" + TrimSpaces(olddim[d].substr(olddim[d].find("*")+1, olddim[d].find("*") + 20)) + " ";
187  else newdim += olddim[d]+" ";
188  }
189  gf.dimensions = TrimSpaces(newdim);
190  }
191 
192  return gf;
193 }
194 
195 
196 
197 // load field map
199 {
200  cout << " > Loading field map from " << map->identifier << " with symmetry: " << map->symmetry << endl;
201 
202  // dipole field
203  if(map->symmetry == "dipole-x" || map->symmetry == "dipole-y" || map->symmetry == "dipole-z")
204  loadFieldMap_Dipole(map, v);
205 
206  // cylindrical field
207  if(map->symmetry == "cylindrical-x" || map->symmetry == "cylindrical-y" || map->symmetry == "cylindrical-z")
208  loadFieldMap_Cylindrical(map, v);
209 
210  // phi-segmented field
211 
212  if(map->symmetry == "phi-segmented")
213  loadFieldMap_phiSegmented(map, v);
214 }
215 
216 
217 
218 
219 
220 
221 //
222 //for clas12 solenoid:
223 //
224 //<mfield>
225 //<description name="clas12-solenoid" factory="ASCII" comment="clas12 superconducting solenoid"/>
226 //<symmetry type="cylindrical-z" format="map" integration="RungeKutta" minStep="0.01*mm"/>
227 //<map>
228 //<coordinate>
229 //<first name="transverse" npoints="601" min="0" max="3" units="m"/>
230 //<second name="longitudinal" npoints="1201" min="-3" max="3" units="m"/>
231 //</coordinate>
232 //<field unit="T"/>
233 //<interpolation type="none"/>
234 //</map>
235 //</mfield>
236 //
237 
238 
239 
240 
241 // for clas12 torus:
242 //
243 //<mfield>
244 //<description name="clas12-torus" factory="ASCII" comment="clas12 superconducting torus"/>
245 //<symmetry type="phi-segmented" format="map" integration="RungeKutta" minStep="1*mm"/>
246 //<map>
247 //<coordinate>
248 //<first name="azimuthal" npoints="61" min="0" max="30" units="deg"/>
249 //<second name="transverse" npoints="126" min="0" max="500" units="cm"/>
250 //<third name="longitudinal" npoints="126" min="100" max="600" units="cm"/>
251 //</coordinate>
252 //<field unit="kilogauss"/>
253 //<interpolation type="none"/>
254 //</map>
255 //</mfield>
256 
257 
258 
259 
260 
261 // Example of uniform field:
262 // <mfield>
263 // <description name="uniform" factory="ASCII" comment="Uniform 10 T Magnetic Field along x-axis"/>
264 // <symmetry type="uniform" format="simple"/>
265 // <dimension bx="10" by="0" bz="0" units="T"/>
266 // </mfield>
267 //
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
double mapOrigin[3]
Displacement of map. This is used in GetFieldValue.
Definition: mappedField.h:95
string description
Field Description.
Definition: field.h:76
gMappedField * map
Mapped Field.
Definition: field.h:92
void loadFieldMap(gMappedField *, double)
Definition: asciiField.cc:198
vector< string > get_strings(string input)
returns a vector of strings from a stringstream, space is delimiter
string unit
field unit in the map
Definition: mappedField.h:97
string integration
Integration Method.
Definition: field.h:78
string format
Field format (available: simple (for uniform) and map)
Definition: field.h:74
string symmetry
Field symmetry.
Definition: field.h:73
double get_number(string v, int warn_no_unit)
Returns number with dimension from string, i.e. 100*cm.
string name
Field name - used as key in the map<string, gfield>
Definition: field.h:72
string assignAttribute(QDomElement e, string attribute, string defaultValue)
Definition: utils.cc:294
string stringify(double x)
bool isEligible(string)
Definition: asciiField.cc:11
string dimensions
Field dimensions (with units), for non-mapped fields.
Definition: field.h:77
gfield loadField(string, goptions)
Definition: asciiField.cc:29
string factory
Field factory (format of magnetic field)
Definition: field.h:75
vector< gcoord > coordinates
Vector size depend on the symmetry.
Definition: mappedField.h:93
void initialize(goptions)
Overloaded "<<" for gfield class. Dumps infos on screen.
Definition: field.cc:116
Definition: field.h:52
string interpolation
map interpolation technique. Choices are "none", "linear", "quadratic"
Definition: mappedField.h:98
double minStep
Minimum Step for the G4ChordFinder.
Definition: field.h:80
string TrimSpaces(string in)
Removes leading and trailing spaces.
string symmetry
map symmetry
Definition: mappedField.h:91
double scaleFactor
Definition: field.h:84
string identifier
Pointer to map in factory (for example, hostname / filename with path / date)
Definition: mappedField.h:92