GEMC  2.3
Geant4 Monte-Carlo Framework
detector_factory.cc
Go to the documentation of this file.
1 // gemc headers
2 #include "detector_factory.h"
3 #include "mysql_det_factory.h"
4 #include "text_det_factory.h"
5 #include "gdml_det_factory.h"
6 #include "clara_det_factory.h"
7 
8 // c++ headers
9 #include <set>
10 using namespace std;
11 
12 // CLHEP units
13 #include "CLHEP/Units/PhysicalConstants.h"
14 using namespace CLHEP;
15 
16 detectorFactory *getDetectorFactory(map<string, detectorFactoryInMap> *detectorFactoryMap, string fname)
17 {
18 
19  if(detectorFactoryMap->find(fname) == detectorFactoryMap->end())
20  {
21  cout << " *** WARNING: " << fname << " NOT FOUND IN Detector Factory Map." << endl;
22  return NULL;
23  }
24 
25  return (*detectorFactoryMap)[fname]();
26 }
27 
28 
29 // factory registration and initialization
30 map<string, detectorFactoryInMap> registerDetectorFactory()
31 {
32  // the key of the STL map also set factoryType in initFactory
33  map<string, detectorFactoryInMap> dFactoryMap;
34 
35  // mysql factory
36  dFactoryMap["MYSQL"] = &mysql_det_factory::createFactory;
37 
38  // text factory
39  dFactoryMap["TEXT"] = &text_det_factory::createFactory;
40 
41  // gdml factory
42  dFactoryMap["GDML"] = &gdml_det_factory::createFactory;
43 
44  // clara factory
45  dFactoryMap["CLARA"] = clara_det_factory::createFactory;
46 
47  return dFactoryMap;
48 }
49 
50 
51 
52 map<string, detector> buildDetector(map<string, detectorFactoryInMap> detectorFactoryMap, goptions go, runConditions rc)
53 {
54  map<string, detector> hallMap;
55 
56  // getting detector factories one by one
57  for(map<string, detectorFactoryInMap>::iterator it = detectorFactoryMap.begin(); it != detectorFactoryMap.end(); it++)
58  {
59  // building detectors from this factory
60  detectorFactory *thisFactory = getDetectorFactory(&detectorFactoryMap, it->first);
61 
62  // initialize factory with the key of the STL map
63  thisFactory->initFactory(go, rc, it->first);
64 
65  // loading detectors
66  map<string, detector> thisDMap = thisFactory->loadDetectors();
67 
68  // merging these detectors to hallMap
69  for(map<string, detector>::iterator idet = thisDMap.begin(); idet != thisDMap.end(); idet++)
70  {
71  // big warning if detector already exist
72  // detector is NOT loaded if already existing
73  if(hallMap.find(idet->first) != hallMap.end())
74  {
75  cout << " *** WARNING! A detector >" << idet->first << "< in factory " << it->first << " exists already " << endl;
76  }
77  // loading detector if not present yet
78  // assigning member factory to it
79  else
80  {
81  hallMap[idet->first] = idet->second;
82  }
83  }
84 
85  // done with the factory, deleting factory pointer
86  delete thisFactory;
87  }
88 
89  // adding root mother volume
90  string hall_mat = go.optMap["HALL_MATERIAL"].args;
91  string hall_field = go.optMap["HALL_FIELD"].args;
92  vector<string> hall_dims = get_strings(go.optMap["HALL_DIMENSIONS"].args, ",");
93  if(hall_dims.size() != 3)
94  cout << " !!! Error: Hall dimensions is not a vector of 3 numbers. Example of dimensions: \"20*m, 20*m, 20*m\"" << endl;
95 
96  detector queen;
97  queen.name = "root";
98  queen.mother = "akasha";
99  queen.description = "mother of us all";
100  queen.pos = G4ThreeVector(0, 0, 0);
101  queen.rot = G4RotationMatrix(G4ThreeVector(1, 0, 0),
102  G4ThreeVector(0, 1, 0),
103  G4ThreeVector(0, 0, 1));
104  queen.type = "Box";
105  queen.dimensions.push_back(get_number(hall_dims[0],1));
106  queen.dimensions.push_back(get_number(hall_dims[1],1));
107  queen.dimensions.push_back(get_number(hall_dims[2],1));
108  queen.material = hall_mat;
109  queen.magfield = hall_field;
110  queen.exist = 1;
111  queen.visible = 0;
112  queen.ncopy = 0;
113  queen.scanned = 1;
114  hallMap[queen.name] = queen;
115 
116  // Transmitting the magnetic field properties along the genealogy
117  // if they have mfield set to "no" and if the option argument NO_FIELD doesn't apply
118  string nofield = go.optMap["NO_FIELD"].args;
119 
120  // Transmitting the magnetic field properties along the genealogy if they are set to "no"
121  for( map<string, detector>::iterator it = hallMap.begin(); it!=hallMap.end() && nofield != "all" ; it++)
122  {
123  // if this is tagged for no field, continue
124  if(it->first == nofield)
125  continue;
126 
127  if(it->second.magfield == "no")
128  {
129  // looking up the whole genealogy, until the first field is found
130  string mother = it->second.mother;
131  string firstAncestorFieldFound = "no";
132  while(mother != "akasha" && firstAncestorFieldFound == "no")
133  {
134  if(hallMap[mother].magfield != "no")
135  {
136  firstAncestorFieldFound = hallMap[mother].magfield;
137  it->second.magfield = hallMap[mother].magfield;
138  }
139  // moving up in genealogy
140  mother = hallMap[mother].mother;
141  }
142  }
143  }
144 
145  return hallMap;
146 }
147 
148 // returns a string that log if the factory requested are present or not
149 string check_factory_existance(map<string, detectorFactoryInMap> detectorFactoryMap, runConditions rc)
150 {
151 
152  set<string> requested;
153  set<string> present;
154 
155  string frequested;
156  string fnotfound;
157 
158  // logging requested factories
159  for(map<string, detectorCondition>::iterator it = rc.detectorConditionsMap.begin(); it != rc.detectorConditionsMap.end(); it++)
160  {
161  requested.insert(it->second.get_factory());
162  }
163 
164  // logging present factories
165  for(map<string, detectorFactoryInMap>::iterator it = detectorFactoryMap.begin(); it != detectorFactoryMap.end(); it++)
166  present.insert(it->first);
167 
168  int found_all = 1;
169  for(set<string>::iterator it = requested.begin(); it != requested.end(); it++ )
170  {
171  frequested.append(*it + " ");
172  if(present.find(*it) == present.end())
173  {
174  found_all = 0;
175  fnotfound.append(*it + " ");
176  }
177  }
178 
179 
180  if(!found_all)
181  return string(" *** WARNING: These detector factories were requested but not found: " + fnotfound);
182 
183  return string(" >> All detector factories requested are found: " + frequested);
184 
185 }
186 
188 {
189  if(gemcOpt.optMap["LOG_VERBOSITY"].arg > 0)
190  cout << " > " << ft << " Detector Factory is Initialized " << endl;
191 
192  factoryType = ft;
193  gemcOpt = go;
194  RC = rc;
195 }
196 
197 
198 
199 
200 // returns detector from a gtable
202 {
203  if(gt.data.size() < 18)
204  {
205  cout << " !!! ERROR: Detector data size should be at least 18. There are " << gt.data.size() << " items on the line for " << gt.data[0] << endl;
206  exit(0);
207  }
208  string hd_msg = " >> TEXT Factory: ";
209  double verbosity = go.optMap["GEO_VERBOSITY"].arg;
210 
211  string catch_v = go.optMap["CATCH"].args;
212 
213  detector det;
214 
215  // 0,1,2: Id, Mother, Description
216  det.name = gt.data[0];
217  det.mother = gt.data[1];
218  det.description = gt.data[2];
219 
220  // 3: Position Vector
221  det.pos = calc_position(gt.data[3]);
222 
223  // 4: Rotation Vector
224  det.rot = calc_rotation(gt.data[4], det.name);
225 
226  // Checking for displacements and rotation from nominal position
227  if(RC.detectorConditionsMap.find(det.name) != RC.detectorConditionsMap.end())
228  {
229  // Adding gcard displacement for this detector if non zero
230  G4ThreeVector shiftp = RC.detectorConditionsMap[det.name].get_position();
231 
232  if(shiftp.mag2() != 0)
233  {
234  if(verbosity > 3 || det.name.find(catch_v))
235  cout << hd_msg << " Detector " << det.name << " is displaced by: " << shiftp/cm << " cm" << endl;
236 
237  det.pos += shiftp;
238  }
239 
240  // Adding gcard rotation for this detector if if non zero
241  G4ThreeVector more_rot = RC.detectorConditionsMap[det.name].get_vrotation();
242  if(more_rot.mag2() != 0)
243  {
244  if(verbosity > 3 || det.name.find(catch_v))
245  cout << hd_msg << " Detector " << det.name << " is rotated by: " << more_rot/deg << " deg" << endl;
246 
247  det.rot.rotateX(more_rot.x());
248  det.rot.rotateY(more_rot.y());
249  det.rot.rotateZ(more_rot.z());
250  }
251  } // end of checking displacement
252 
253 
254  // 5: Color, opacity
255  if(gt.data[5].size() != 6 && gt.data[5].size() != 7)
256  {
257  cout << hd_msg << " Color Attributes for " << det.name << "<" << gt.data[5] << "> have wrong size: " << gt.data[5].size()
258  << ". It should be 6 or 7 digits rrggbb[t] (red, green, blue hexadecimals + optional transparency)." << endl;
259  exit(9);
260  }
261 
262  G4Colour thisCol = gcol(gt.data[5]);
263 
264  // 6: Solid Type
265  det.type = gt.data[6];
266 
267  // 7: Dimensions
268  stringstream vars(gt.data[7]);
269  string var;
270  while(!vars.eof())
271  {
272  vars >> var;
273  det.dimensions.push_back(get_number(var,1));
274  }
275 
276  // 8: Material
277  det.material = gt.data[8];
278 
279  // 9: Magnetic Field
280  det.magfield = gt.data[9];
281 
282  // 10: copy number
283  det.ncopy = atoi(gt.data[10].c_str());
284 
285  // 11: pMany
286  det.pMany = atoi(gt.data[11].c_str());
287 
288  // 12: Activation flag
289  det.exist = atoi(gt.data[12].c_str());
290 
291  // Overwriting existance is set in the gcard
292  if(RC.detectorConditionsMap.find(det.name) != RC.detectorConditionsMap.end())
293  {
294  det.exist = RC.detectorConditionsMap[det.name].get_existance();
295  if(verbosity > 3 || det.name.find(catch_v))
296  cout << hd_msg << " Detector " << det.name << " has existance set to: " << det.exist << endl;
297  }
298 
299  // 13: Visibility
300  det.visible = atoi(gt.data[13].c_str());
301 
302  // 14: Style
303  det.style = atoi(gt.data[14].c_str());
304 
305  // Setting the Visual Atributes Color, Visibility, Style
306  det.VAtts = G4VisAttributes(thisCol);
307  det.visible ? det.VAtts.SetVisibility(true) : det.VAtts.SetVisibility(false);
308  if(det.visible)
309  det.style ? det.VAtts.SetForceSolid(true) : det.VAtts.SetForceWireframe(true);
310 
311 
312  // 15: sensitivity
313  det.sensitivity = gt.data[15];
314 
315  if(det.sensitivity != "no")
316  {
317  // 16: hitType
318  det.hitType = gt.data[16];
319 
320  // 17: identity
321  det.identity = get_identifiers(gt.data[17]);
322  }
323 
324 
325 
326  // 18 detector system
327  det.system = gt.data[18];
328  det.factory = gt.data[19];
329 
330 
331  if(gt.data.size() > 20)
332  det.variation = gt.data[20];
333 
334  if(gt.data.size() > 21)
335  det.run = atoi(gt.data[21].c_str());
336 
337  if(verbosity>2)
338  cout << det;
339  return det;
340 }
341 
342 
343 
344 
345 
map< string, detector > buildDetector(map< string, detectorFactoryInMap > detectorFactoryMap, goptions go, runConditions rc)
vector< string > get_strings(string input)
returns a vector of strings from a stringstream, space is delimiter
string check_factory_existance(map< string, detectorFactoryInMap > detectorFactoryMap, runConditions rc)
string sensitivity
Defines the Sensitive Detector. possible choices: "no" "hits collection name".
Definition: detector.h:89
string mother
Mother Volume name.
Definition: detector.h:68
static detectorFactory * createFactory()
vector< identifier > get_identifiers(string var)
Definition: identifier.cc:110
vector< string > data
Definition: utils.h:76
Definition: utils.h:65
int run
run number that generated the detector
Definition: detector.h:98
double verbosity
STL namespace.
G4ThreeVector pos
Position relative to the mother volume, as G4ThreeVector.
Definition: detector.h:71
static detectorFactory * createFactory()
string system
detector system
Definition: detector.h:95
map< string, detectorCondition > detectorConditionsMap
G4VisAttributes VAtts
Visual Attributes: color, transparency, style (wireframe, solid), visibility.
Definition: detector.h:74
double get_number(string v, int warn_no_unit)
Returns number with dimension from string, i.e. 100*cm.
static detectorFactory * createFactory()
virtual map< string, detector > loadDetectors()=0
G4ThreeVector calc_position(string v)
Definition: utils.cc:149
bool pMany
Needed by geant4 at G4PVPlacement time.
Definition: detector.h:83
string factory
factory that generated the detector
Definition: detector.h:96
G4RotationMatrix calc_rotation(string r, string dname)
Definition: utils.cc:85
int ncopy
copy number
Definition: detector.h:82
static detectorFactory * createFactory()
string name
Name of the volume. Since this is the key of the STL map, it has to be unique.
Definition: detector.h:67
map< string, aopt > optMap
Options map.
Definition: options.h:75
string material
Volume Material name.
Definition: detector.h:79
G4Colour gcol(string cvar)
Definition: utils.cc:165
void initFactory(goptions, runConditions, string)
int visible
visibility of the detector: 0=invisible 1=visible
Definition: detector.h:86
int style
Visual style: 0=wireframe 1=solid.
Definition: detector.h:87
string hitType
Hit Process routine name. A Hit Process HitProcess derived class must exists with this name...
Definition: detector.h:90
vector< identifier > identity
Vector of identifiers. Example: superlayer manual 1 type manual 2 segment manual 3 strip manual 4...
Definition: detector.h:91
string magfield
Magnetic Field. The string "no" means that the field is inherited from the mother volume...
Definition: detector.h:80
G4RotationMatrix rot
Rotation Matrix, defined by rotations along x,y,z axis relative to the mother volume.
Definition: detector.h:72
int exist
detector ON/OFF switch
Definition: detector.h:85
string type
solid type. This follows the GEANT4 definitions
Definition: detector.h:76
vector< double > dimensions
vector of dimensions. Size, units depends on solid type
Definition: detector.h:77
int scanned
for use during construction
Definition: detector.h:93
detector get_detector(gtable gt, goptions go, runConditions RC)
string variation
variation that generated the detector
Definition: detector.h:97
detectorFactory * getDetectorFactory(map< string, detectorFactoryInMap > *detectorFactoryMap, string fname)
map< string, detectorFactoryInMap > registerDetectorFactory()
string description
Volume Description for documentation.
Definition: detector.h:69