GEMC  1.8
Geant4 Monte-Carlo Framework
detector.cc
Go to the documentation of this file.
1 // %%%%%%%%%%
2 // G4 headers
3 // %%%%%%%%%%
4 #include "G4Box.hh"
5 #include "G4Cons.hh"
6 #include "G4Ellipsoid.hh"
7 #include "G4IntersectionSolid.hh"
8 #include "G4NistManager.hh"
9 #include "G4Para.hh"
10 #include "G4Polycone.hh"
11 #include "G4Polyhedra.hh"
12 #include "G4Torus.hh"
13 #include "G4Trd.hh"
14 #include "G4Trap.hh"
15 #include "G4Tubs.hh"
16 #include "G4EllipticalTube.hh"
17 #include "G4Paraboloid.hh"
18 #include "G4Hype.hh"
19 #include "G4Sphere.hh"
20 #include "G4SubtractionSolid.hh"
21 #include "G4UnionSolid.hh"
22 #include "G4IntersectionSolid.hh"
23 #include "G4UnitsTable.hh"
24 #include "G4RotationMatrix.hh"
25 
26 
27 // %%%%%%%%%%%%
28 // gemc headers
29 // %%%%%%%%%%%%
30 #include "detector.h"
31 
32 // %%%%%%%%%%%
33 // C++ headers
34 // %%%%%%%%%%%
35 #include <string>
36 #include <vector>
37 using namespace std;
38 
40 {
41  SolidV = NULL;
42  LogicV = NULL;
43  PhysicalV = NULL;
44 }
45 
46 int detector::create_solid(gemc_opts gemcOpt, map<string, detector> *Map)
47 {
48  int built = 0;
49  if(SolidV) delete SolidV;
50 
51  string hd_msg = gemcOpt.args["LOG_MSG"].args + " Solid: >> ";
52  double VERB = gemcOpt.args["G4P_VERBOSITY"].arg ;
53  string catch_v = gemcOpt.args["CATCH"].args;
54 
55  // ####
56  // Box
57  // ####
58  if(type == "Box")
59  {
60  if(dimensions.size() != 3)
61  {
62  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
63  << " is " << dimensions.size() << ":" << endl;
64  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
65  cout << " This does not match a G4Box. Exiting" << endl << endl;
66  exit(0);
67  }
68 
69  SolidV = new G4Box(name,
70  dimensions[0],
71  dimensions[1],
72  dimensions[2]);
73 
74  built = 1;
75  }
76 
77  // ##############
78  // Parallelepiped
79  // ##############
80  if(type == "Parallelepiped")
81  {
82  if(dimensions.size() != 6)
83  {
84  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
85  << " is " << dimensions.size() << ":" << endl;
86  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
87  cout << " This does not match a G4Para. Exiting" << endl << endl;
88  exit(0);
89  }
90 
91  SolidV = new G4Para(name,
92  dimensions[0],
93  dimensions[1],
94  dimensions[2],
95  dimensions[3],
96  dimensions[4],
97  dimensions[5]);
98 
99  built = 1;
100  }
101 
102 
103  // ######
104  // Sphere
105  // ######
106  if(type == "Sphere")
107  {
108  if(dimensions.size() != 6)
109  {
110  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
111  << " is " << dimensions.size() << ":" << endl;
112  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
113  cout << " This does not match a G4Sphere. Exiting." << endl << endl;
114  exit(0);
115  }
116 
117  SolidV = new G4Sphere(name,
118  dimensions[0],
119  dimensions[1],
120  dimensions[2],
121  dimensions[3],
122  dimensions[4],
123  dimensions[5]);
124 
125  built = 1;
126  }
127 
128 
129  // #########
130  // Ellipsoid
131  // #########
132  if(type == "Ellipsoid")
133  {
134  if(dimensions.size() != 5)
135  {
136  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
137  << " is " << dimensions.size() << ":" << endl;
138  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
139  cout << " This does not match a G4Ellipsoid. Exiting." << endl << endl;
140  exit(0);
141  }
142 
143  SolidV = new G4Ellipsoid(name,
144  dimensions[0],
145  dimensions[1],
146  dimensions[2],
147  dimensions[3],
148  dimensions[4]);
149 
150  built = 1;
151  }
152 
153  // ##########
154  // Paraboloid
155  // ##########
156  if(type == "Paraboloid")
157  {
158  if(dimensions.size() != 3)
159  {
160  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
161  << " is " << dimensions.size() << ":" << endl;
162  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
163  cout << " This does not match a G4Paraboloid. Exiting." << endl << endl;
164  exit(0);
165  }
166 
167  SolidV = new G4Paraboloid(name,
168  dimensions[0],
169  dimensions[1],
170  dimensions[2]);
171 
172  built = 1;
173  }
174 
175 
176  // ##################
177  // Hyperbolic Profile
178  // ##################
179  if(type == "Hype")
180  {
181  if(dimensions.size() != 5)
182  {
183  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
184  << " is " << dimensions.size() << ":" << endl;
185  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
186  cout << " This does not match a G4Hype. Exiting." << endl << endl;
187  exit(0);
188  }
189 
190  SolidV = new G4Hype(name,
191  dimensions[0],
192  dimensions[1],
193  dimensions[2],
194  dimensions[3],
195  dimensions[4]);
196 
197  built = 1;
198  }
199 
200 
201 
202  // ####
203  // Tube
204  // ####
205  if(type == "Tube")
206  {
207  if(dimensions.size() != 5)
208  {
209  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
210  << " is " << dimensions.size() << ":" << endl;
211  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
212  cout << " This does not match a G4Tubs. Exiting" << endl << endl;
213  exit(0);
214  }
215 
216  SolidV = new G4Tubs(name,
217  dimensions[0],
218  dimensions[1],
219  dimensions[2],
220  dimensions[3],
221  dimensions[4]);
222 
223  built = 1;
224  }
225 
226  // ###############
227  // G4ElipticalTube
228  // ###############
229  if(type == "EllipticalTube" || type == "Eltu")
230  {
231  if(dimensions.size() != 3)
232  {
233  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
234  << " is " << dimensions.size() << ":" << endl;
235  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
236  cout << " This does not match a G4ElipticalTube. Exiting" << endl << endl;
237  exit(0);
238  }
239 
240  SolidV = new G4EllipticalTube(name,
241  dimensions[0], // dx: The equation of the surface in x/y is 1.0 = (x/dx)**2 +(y/dy)**2
242  dimensions[1], // dy
243  dimensions[2]); // dz = half length in z
244  built = 1;
245 
246  }
247 
248 
249 
250  // ####
251  // Cone
252  // ####
253  if(type == "Cons")
254  {
255  if(dimensions.size() != 7)
256  {
257  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
258  << " is " << dimensions.size() << ":" << endl;
259  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
260  cout << " This does not match a G4Cons. Exiting" << endl << endl;
261  exit(0);
262  }
263 
264  SolidV = new G4Cons(name,
265  dimensions[0],
266  dimensions[1],
267  dimensions[2],
268  dimensions[3],
269  dimensions[4],
270  dimensions[5],
271  dimensions[6]);
272 
273  built = 1;
274  }
275 
276  // #####
277  // Torus
278  // #####
279  if(type == "Torus")
280  {
281  if(dimensions.size() != 5)
282  {
283  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
284  << " is " << dimensions.size() << ":" << endl;
285  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
286  cout << " This does not match a G4Torus. Exiting" << endl << endl;
287  exit(0);
288  }
289  SolidV = new G4Torus(name,
290  dimensions[0],
291  dimensions[1],
292  dimensions[2],
293  dimensions[3],
294  dimensions[4]);
295 
296  built = 1;
297  }
298 
299 
300 
301  // #########
302  // Trapezoid
303  // #########
304  if(type == "Trd")
305  {
306  if(dimensions.size() != 5)
307  {
308  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
309  << " is " << dimensions.size() << ":" << endl;
310  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
311  cout << " This does not match a G4Trd. Exiting" << endl << endl;
312  exit(0);
313  }
314  SolidV = new G4Trd(name,
315  dimensions[0],
316  dimensions[1],
317  dimensions[2],
318  dimensions[3],
319  dimensions[4]);
320  built = 1;
321  }
322 
323 
324  // ##################
325  // Inclined Trapezoid
326  // ##################
327  if(type == "ITrd")
328  {
329  if(dimensions.size() != 7)
330  {
331  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
332  << " is " << dimensions.size() << ":" << endl;
333  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
334  cout << " This does not match a ITrd. Exiting" << endl << endl;
335  exit(0);
336  }
337 
338  double alph_xz = dimensions[5];
339  double alph_yz = dimensions[6];
340  double x = tan(alph_xz);
341  double y = tan(alph_yz);
342  double r = sqrt(x*x + y*y);
343 
344  // Calculating the 11 G4Trap parameters
345  double pDz = dimensions[4];
346  double pTheta = atan2(r, 1);
347  double pPhi = atan2(y, x);
348  double pDy1 = dimensions[2];
349  double pDx1 = dimensions[0];
350  double pDx2 = pDx1;
351  double pAlp1 = 0;
352  double pDy2 = dimensions[3];
353  double pDx3 = dimensions[1];
354  double pDx4 = pDx3;
355  double pAlp2 = 0;
356 
357  SolidV = new G4Trap(name,
358  pDz,
359  pTheta,
360  pPhi,
361  pDy1,
362  pDx1,
363  pDx2,
364  pAlp1,
365  pDy2,
366  pDx3,
367  pDx4,
368  pAlp2);
369 
370  built = 1;
371  }
372 
373 
374  // ########################
375  // Geant4 Generic Trapezoid
376  // ########################
377  if(type == "G4Trap")
378  {
379  if(dimensions.size() != 11)
380  {
381  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
382  << " is " << dimensions.size() << ":" << endl;
383  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
384  cout << " This does not match a G4Trd. Exiting" << endl << endl;
385  exit(0);
386  }
387  SolidV = new G4Trap(name,
388  dimensions[0],
389  dimensions[1],
390  dimensions[2],
391  dimensions[3],
392  dimensions[4],
393  dimensions[5],
394  dimensions[6],
395  dimensions[7],
396  dimensions[8],
397  dimensions[9],
398  dimensions[10]);
399  built = 1;
400  }
401 
402 
403  // #######################################
404  // G4Trap Constructor with 4+4 coordinates
405  // #######################################
406  if(type == "G4TrapC")
407  {
408  if(dimensions.size() != 24)
409  {
410  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
411  << " is " << dimensions.size() << ":" << endl;
412  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
413  cout << " This does not match a G4Trd. Exiting" << endl << endl;
414  exit(0);
415  }
416 
417  G4ThreeVector points[8];
418  for(int v=0; v<8; v++)
419  {
420  points[v].setX(dimensions[v*3+0]/cm * cm);
421  points[v].setY(dimensions[v*3+1]/cm * cm);
422  points[v].setZ(dimensions[v*3+2]/cm * cm);
423  }
424 
425  SolidV = new G4Trap(name, // name
426  points); // coordinates
427 
428  built = 1;
429  }
430 
431 
432 
433  // ####################
434  // Polyhedra (PGON)
435  // First G4 constructor
436  // ####################
437  if(type == "Pgon")
438  {
439  if(dimensions.size() < 8)
440  {
441  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
442  << " is " << dimensions.size() << ":" << endl;
443  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
444  cout << " This does not match a G4Polyhedra. Exiting" << endl << endl;
445  exit(0);
446  }
447  int nsides = (int) dimensions[2];
448  int zplanes = (int) dimensions[3];
449  if(nsides < 1)
450  {
451  cout << hd_msg << " Fatal Error: no sides for " << name
452  << "... should be a G4Polyhedra. Exiting" << endl << endl;
453  exit(0);
454  }
455  double* zPlane = new double[zplanes];
456  double* rInner = new double[zplanes];
457  double* rOuter = new double[zplanes];
458 
459  for(int zpl=0; zpl<zplanes; zpl++)
460  {
461  rInner[zpl] = dimensions[4 + 0*zplanes + zpl] ;
462  rOuter[zpl] = dimensions[4 + 1*zplanes + zpl] ;
463  zPlane[zpl] = dimensions[4 + 2*zplanes + zpl] ;
464  }
465  SolidV = new G4Polyhedra(name,
466  dimensions[0],
467  dimensions[1],
468  nsides,
469  zplanes,
470  zPlane,
471  rInner,
472  rOuter);
473  built = 1;
474  }
475 
476 
477  // ####################
478  // Polyhedra (PCON)
479  // First G4 constructor
480  // ####################
481  if(type == "Polycone")
482  {
483  if(dimensions.size() < 7)
484  {
485  cout << hd_msg << " Fatal Error: the number of dimensions for " << name
486  << " is " << dimensions.size() << ":" << endl;
487  for(unsigned int i=0; i<dimensions.size(); i++) cout << " dimension " << i + 1 << ": " << dimensions[i] << endl;
488  cout << " This does not match a G4Polycone. Exiting" << endl << endl;
489  exit(0);
490  }
491  int zplanes = (int) dimensions[2];
492 
493  double* zPlane = new double[zplanes];
494  double* rInner = new double[zplanes];
495  double* rOuter = new double[zplanes];
496 
497  for(int zpl=0; zpl<zplanes; zpl++)
498  {
499  // notice that the order should be different
500  // why didn't I put z first in the constructor as in geant4?
501  // might have to change it later
502  rInner[zpl] = dimensions[3 + 0*zplanes + zpl] ;
503  rOuter[zpl] = dimensions[3 + 1*zplanes + zpl] ;
504  zPlane[zpl] = dimensions[3 + 2*zplanes + zpl] ;
505  }
506  SolidV = new G4Polycone(name,
507  dimensions[0],
508  dimensions[1],
509  zplanes,
510  zPlane,
511  rInner,
512  rOuter);
513  built = 1;
514  }
515 
516 
517  // ############################
518  // CopyPlacement:
519  // Point LogicV to the original
520  // ############################
521  if(type.find("CopyOf") != string::npos && type.find("CopyOf") == 0)
522  {
523  hd_msg = gemcOpt.args["LOG_MSG"].args + " Copy: >> ";
524  string original(type, 6, 190);
525 
526  // Look for original
527  map<string, detector>::iterator it = (*Map).find(TrimSpaces(original));
528  if(it == (*Map).end())
529  {
530  cout << hd_msg << " <" << original << "> not found. Exiting." << endl << endl;
531  exit(0);
532  }
533  else
534  {
535  if(VERB>4 || name.find(catch_v) != string::npos)
536  {
537  cout << hd_msg << " " << name << " is a copy of <" << TrimSpaces(original) << ">. Pointing to its logical volume." << endl;
538  }
539  SetLogical(it->second.GetLogical());
540  }
541  built = 1;
542  }
543 
544 
545  // ################
546  // Solid Operations
547  // ################
548  if(type.find("Operation:") != string::npos && type.find("Operation:") == 0)
549  {
550  hd_msg = gemcOpt.args["LOG_MSG"].args + " Operation: >> ";
551 
552  bool translationFirst = false;
553 
554  // If Operation:~ it will perform the translation first
555  size_t posTld = type.find("~");
556  if( posTld != string::npos )
557  {
558  translationFirst = true;
559  type.replace( posTld, 1, " " );
560  }
561 
563  bool absolutecoordinates = false;
564 
565  // If Operation:@ it will assume that position of second object is given in the common mother volume of both objects
566 
567  size_t pos_at = type.find("@");
568  if( pos_at != string::npos )
569  {
570  absolutecoordinates = true;
571  type.replace( pos_at, 1, " " );
572  }
574 
575 
576  size_t posp = 0;
577  size_t posm = 0;
578  size_t post = 0;
579  size_t pos = 0;
580  // harcoded max size of 200 here
581  string operation(type, 10, 190);
582  posp = operation.find("+");
583  posm = operation.find("-");
584  post = operation.find("*");
585  if (posp != string::npos) pos = posp;
586  else if(posm != string::npos) pos = posm;
587  else if(post != string::npos) pos = post;
588  if(!posp && !posm && !post)
589  {
590  cout << hd_msg << " Operation " << operation << " for " << name << " not recognized. Exiting." << endl;
591  exit(0);
592  }
593 
594  // Locating solids
595  string solid1, solid2;
596  string tsolid1, tsolid2;
597  solid1.assign(operation, 0, pos);
598  solid2.assign(operation, pos+1, operation.size());
599  tsolid1 = TrimSpaces(solid1);
600  tsolid2 = TrimSpaces(solid2);
601 
602  // Locating second solid transformation
603  map<string, detector>::iterator it1 = (*Map).find(tsolid1);
604  map<string, detector>::iterator it2 = (*Map).find(tsolid2);
605  if(it1 == (*Map).end())
606  {
607  cout << hd_msg << " " << tsolid1 << " Not found. Exiting." << endl << endl;
608  exit(0);
609  }
610  if(it2 == (*Map).end())
611  {
612  cout << hd_msg << " " << tsolid2 << " Not found. Exiting." << endl << endl;
613  exit(0);
614  }
615 
616  // Define rotational and translational transformations then combine them
617  G4RotationMatrix rotate = it2->second.rot ;
618  G4ThreeVector translate = it2->second.pos;
619  G4RotationMatrix invRot = rotate.invert() ;
620  G4Transform3D transf1( invRot, G4ThreeVector( 0, 0, 0 ) );
621  G4Transform3D transf2( G4RotationMatrix(), translate );
622  G4Transform3D transform = transf2 * transf1 ;
623 
624  if( absolutecoordinates && TrimSpaces(it1->second.mother) == TrimSpaces(it2->second.mother) ) { //assume that second object position and rotation are given in absolute (mother) coordinates:
625 
626 
627  G4RotationMatrix invrot1 = (it1->second.rot).inverse();
628  G4RotationMatrix rotate2 = it2->second.rot;
629 
630  G4ThreeVector net_translation = it2->second.pos - it1->second.pos;
631 
632  // The net rotation should be the INVERSE of the rotation of object 2 relative to object 1.
633  // rotate1/2 is the rotation of object 1/2 relative to their common mother.
634  // If R is the rotation of 2 relative to 1, then R2 = R * R1 --> R = R2 R1^-1
635  G4RotationMatrix invnet_rotation = (rotate2 * invrot1).invert();
636 
637  // In order to express the relative position of object 2 in the coordinate system of object one, we must rotate it
638  // applying the same rotation as that used to position object 1, according to the GEANT4 framework:
639  // I do not quite understand WHY this works, but through trial and error, I have
640  // discovered that the combination of operations below is what works:
641  net_translation *= it1->second.rot;
642  transform = G4Transform3D( invnet_rotation, net_translation );
643  //We don't want there to be any possibility to overwrite "transform" in this special case, so we force translationFirst to false here:
644  translationFirst = false;
645  }
646 
647 
648  // If there was tilda in the operation string then the rotation and translation are switched
649  // with respect to the default behaviour of G4UnionSolid with separate rotational matrix
650  // and translatin vector
651  if( translationFirst )
652  {
653  transform = transf1 * transf2 ;
654  }
655 
656  if(posp != string::npos)
657  {
658  SolidV = new G4UnionSolid( name, it1->second.GetSolid(), it2->second.GetSolid(), transform );
659  }
660  if(posm != string::npos)
661  {
662  SolidV = new G4SubtractionSolid( name, it1->second.GetSolid(), it2->second.GetSolid(), transform );
663  }
664  if(post != string::npos)
665  {
666  SolidV = new G4IntersectionSolid(name, it1->second.GetSolid(), it2->second.GetSolid(), transform );
667  }
668 
669  if(VERB>4 || name.find(catch_v) != string::npos)
670  {
671  cout << hd_msg << " " << name << " is the " << (pos==posp ? " sum " : " difference ") << " of " << tsolid1 << " and " << tsolid2 << endl;;
672  }
673  built = 1;
674  }
675 
676  if(VERB>4 || name.find(catch_v) != string::npos)
677  {
678  cout << hd_msg << " " << name << " solid " << type << " built." << endl;
679  }
680 
681 
682  if(built==0)
683  {
684  cout << hd_msg << " " << name << " solid " << type << " not recognized. Exiting." << endl;
685  exit(0);
686  }
687  return 1;
688 }
689 
690 
691 
692 
693 
694 
695 int detector::create_logical_volume(map<string, G4Material*> *MMats, gemc_opts gemcOpt)
696 {
697  string hd_msg = gemcOpt.args["LOG_MSG"].args + " Logical: >> ";
698  double VERB = gemcOpt.args["G4P_VERBOSITY"].arg ;
699  string catch_v = gemcOpt.args["CATCH"].args;
700  string defmat = gemcOpt.args["DEFAULT_MATERIAL"].args;
701  if(material=="Component")
702  {
703  if(VERB>4 || name.find(catch_v) != string::npos)
704  cout << hd_msg << " " << name << " is a Solid Component. Logical Volume will not be built." << endl;
705  return 0;
706  }
707 
708  // Check if Material Exists
709  map<string, G4Material*>::iterator i = MMats->find(material);
710 
711  // if material is not defined, look in G4 table.
712  if(i == MMats->end() && LogicV == 0)
713  {
714  G4NistManager* matman = G4NistManager::Instance();
715  if(matman->FindOrBuildMaterial(material)) (*MMats)[material] = matman->FindOrBuildMaterial(material);
716  }
717  i = MMats->find(material);
718 
719  // if material is still not defined, use air
720  if(i == MMats->end() && LogicV == 0)
721  {
722  if(defmat == "none")
723  {
724  cout << hd_msg << " Warning: " << material << " is not defined. Exiting" << endl;
725  cout << hd_msg << " You can set the DEFAULT_MATERIAL flag to replace an undefined material. " << endl;
726  exit(0);
727  }
728  else
729  {
730  material = defmat;
731  if(MMats->find(material)== MMats->end())
732  {
733  cout << hd_msg << " Warning: " << defmat << " set with DEFAULT_MATERIAL is not found. Exiting" << endl;
734  exit(0);
735 
736  }
737  }
738  }
739 
740 
741  // Logical Volume Basic Constructor
742  // If LogicV exists already, this is a copy
743  if(LogicV == 0)
744  LogicV = new G4LogicalVolume(SolidV, (*MMats)[material], name);
745  if(name == "root") LogicV->SetVisAttributes(G4VisAttributes::GetInvisible());
746  else LogicV->SetVisAttributes(VAtts);
747 
748  if(VERB>4 || name.find(catch_v) != string::npos)
749  {
750  cout << hd_msg << " " << name << " Logical Volume built." << endl;
751  }
752 
753  return 1;
754 }
755 
756 
757 int detector::create_physical_volumes(gemc_opts gemcOpt, G4LogicalVolume *mamma)
758 {
759  string hd_msg = gemcOpt.args["LOG_MSG"].args + " Physical: >> ";
760  double VERB = gemcOpt.args["G4P_VERBOSITY"].arg ;
761  bool OVERL = gemcOpt.args["CHECK_OVERLAPS"].arg > 0 ;
762  string catch_v = gemcOpt.args["CATCH"].args;
763  if(PhysicalV) delete PhysicalV;
764  if(material=="Component")
765  {
766  if(VERB>4 || name.find(catch_v) != string::npos)
767  cout << hd_msg << " " << name << " is a Solid Component. Physical Volume will not be built." << endl;
768  return 1;
769  }
770 
771  if(name == "root")
772  PhysicalV = new G4PVPlacement(0,
773  G4ThreeVector(),
774  LogicV,
775  name.c_str(),
776  0,
777  false,
778  0);
779 
780  else
781  PhysicalV = new G4PVPlacement(&rot,
782  pos,
783  LogicV,
784  name.c_str(),
785  mamma,
786  false,
787  ncopy,
788  OVERL);
789 
790  if(VERB>4 || name.find(catch_v) != string::npos)
791  {
792  if(mamma)
793  cout << hd_msg << " " << name << " Physical Volume(s) built inside " << mamma->GetName() << "." << endl;
794  }
795 
796  return 1;
797 }
798 
799 
800 
801 
802 // Returns dimensions nomenclature for different solid type
803 vector< vector<string> > dimensionstype(string solidtype)
804 {
805  vector< vector<string> > dtypes;
806  vector<string> dt;
807  dt.resize(2);
808 
809  if(solidtype == "Box")
810  {
811  dt[0] = "half length in X";
812  dt[1] = "Length";
813  dtypes.push_back(dt);
814  dt[0] = "half length in Y";
815  dtypes.push_back(dt);
816  dt[0] = "half length in Z";
817  dtypes.push_back(dt);
818  }
819 
820  if(solidtype == "Sphere")
821  {
822  dt[1] = "Length";
823  dt[0] = "Inner radius";
824  dtypes.push_back(dt);
825  dt[0] = "Outer radius";
826  dtypes.push_back(dt);
827  dt[1] = "Angle";
828  dt[0] = "Starting Phi angle of the segment";
829  dtypes.push_back(dt);
830  dt[0] = "Delta Phi angle of the segment";
831  dtypes.push_back(dt);
832  dt[0] = "Starting Theta angle of the segment";
833  dtypes.push_back(dt);
834  dt[0] = "Delta Theta angle of the segment";
835  dtypes.push_back(dt);
836  }
837  if(solidtype == "Tube")
838  {
839  dt[1] = "Length";
840  dt[0] = "Inner radius";
841  dtypes.push_back(dt);
842  dt[0] = "Outer radius";
843  dtypes.push_back(dt);
844  dt[0] = "Half length in z";
845  dtypes.push_back(dt);
846  dt[1] = "Angle";
847  dt[0] = "Starting Phi angle";
848  dtypes.push_back(dt);
849  dt[0] = "Delta Phi angle";
850  dtypes.push_back(dt);
851  }
852  if(solidtype == "Trd")
853  {
854  dt[1] = "Length";
855  dt[0] = "Half-length along x at the surface at -dz";
856  dtypes.push_back(dt);
857  dt[0] = "Half-length along x at the surface at +dz";
858  dtypes.push_back(dt);
859  dt[0] = "Half-length along y at the surface at -dz";
860  dtypes.push_back(dt);
861  dt[0] = "Half-length along y at the surface at +dz";
862  dtypes.push_back(dt);
863  dt[0] = "dz: Half-length along z axis";
864  dtypes.push_back(dt);
865  }
866  if(solidtype == "Cons")
867  {
868  dt[1] = "Length";
869  dt[0] = "Inner radius at start";
870  dtypes.push_back(dt);
871  dt[0] = "Outer radius at start";
872  dtypes.push_back(dt);
873  dt[0] = "Inner radius at end";
874  dtypes.push_back(dt);
875  dt[0] = "Outer radius at end";
876  dtypes.push_back(dt);
877  dt[0] = "Half length in z";
878  dtypes.push_back(dt);
879  dt[1] = "Angle";
880  dt[0] = "Starting Phi angle";
881  dtypes.push_back(dt);
882  dt[0] = "Delta Phi angle";
883  dtypes.push_back(dt);
884  }
885  if(solidtype == "G4Trap")
886  {
887  dt[1] = "Length";
888  dt[0] = "Half z length ";
889  dtypes.push_back(dt);
890  dt[1] = "Angle";
891  dt[0] = "Polar angle of the line joining the centres of the faces";
892  dtypes.push_back(dt);
893  dt[0] = "Azimuthal angle of the line joining the centre of the face";
894  dtypes.push_back(dt);
895  dt[1] = "Length";
896  dt[0] = "Half y length at -pDz";
897  dtypes.push_back(dt);
898  dt[0] = "Half x length of the side at y=-pDy1, -pDz";
899  dtypes.push_back(dt);
900  dt[0] = "Half x length of the side at y=+pDy1, -pDz";
901  dtypes.push_back(dt);
902  dt[1] = "Angle";
903  dt[0] = "Angle to the y axis from the centre (lower endcap) ";
904  dtypes.push_back(dt);
905  dt[1] = "Length";
906  dt[0] = "Half y length at +pDz";
907  dtypes.push_back(dt);
908  dt[0] = "Half x length of the side at y=-pDy2, +pDz";
909  dtypes.push_back(dt);
910  dt[0] = "Half x length of the side at y=+pDy2, +pDz";
911  dtypes.push_back(dt);
912  dt[1] = "Angle";
913  dt[0] = "Angle to the y axis from the centre (upper endcap) ";
914  dtypes.push_back(dt);
915  }
916 
917  if(solidtype == "G4EllipticalTube")
918  {
919  dt[1]="Lenght";
920  dt[0]="Half length x";
921  dtypes.push_back(dt);
922  dt[1]="Lenght";
923  dt[0]="Half length y";
924  dtypes.push_back(dt);
925  dt[1]="Lenght";
926  dt[0]="Half length z";
927  dtypes.push_back(dt);
928  }
929 
930  return dtypes;
931 }
932 
933 
934 ostream &operator<<(ostream &stream, detector Detector)
935 {
936  cout << endl;
937  cout << " Detector name: " << Detector.name << " - " << Detector.description << endl;
938  cout << " Mother: " << Detector.mother << endl;
939  cout << " Position (cm): " << Detector.pos/cm << endl;
940  cout << " Rotation: " << Detector.rot << endl;
941  cout << " Color: " << Detector.VAtts.GetColour() << endl;
942  cout << " Type: " << Detector.type << endl;
943  vector< vector<string> > dtypes = dimensionstype( Detector.type.c_str() );
944 
945  if(dtypes.size() != Detector.dimensions.size() && Detector.type.find("CopyOf") != 0)
946  {
947  for(unsigned int i=0; i<Detector.dimensions.size(); i++)
948  cout << " Size " << i + 1 << ": " << Detector.dimensions[i] << endl;
949  }
950  if(dtypes.size() == Detector.dimensions.size() && Detector.type.find("CopyOf") != 0)
951  for(unsigned int i=0; i<dtypes.size(); i++)
952  cout << " " << dtypes[i][0] << ": " << G4BestUnit(Detector.dimensions[i], dtypes[i][1]) << endl;
953 
954  cout << " Material: " << Detector.material << endl;
955  cout << " Magnetic Field: " << Detector.magfield << endl;
956  cout << " Copy Number: " << Detector.ncopy << endl;
957  cout << " Activated: " << ( Detector.exist==1 ? "yes" : "no" ) << endl;
958  cout << " Visible: " << ( Detector.visible==1 ? "yes" : "no" ) << endl;
959  cout << " Style: " << ( Detector.style==1 ? "solid" : "wireframe" ) << endl;
960  cout << " Sensitivity: " << Detector.sensitivity << endl;
961  if(Detector.sensitivity != "no")
962  cout << " hitType: " << Detector.hitType << endl;
963 
964  if(Detector.identity.size())
965  {
966  if(Detector.identity[0].name != "Mirror")
967  cout << Detector.identity ;
968  }
969  cout << endl;
970 
971  return stream;
972 }
973 
974 bool detector::operator == (const detector& D) const
975 {
976  // Name uniquely identifies a volume
977  if(D.name == this->name)
978  return true;
979  else return false;
980 }
981 
982 
983 
984 
985 
986 
987 
988 
989 
990 
991 
992 
993 
994 
995 
996 
997 
998 
999 
1000 
1001 
1002 
1003 
1004 
1005 
1006 
int create_logical_volume(map< string, G4Material * > *, gemc_opts)
Creates the Logical Volume.
Definition: detector.cc:695
string sensitivity
Defines the Sensitive Detector. possible choices: "no" "hits collection name".
Definition: detector.h:75
string mother
Mother Volume name.
Definition: detector.h:54
ostream & operator<<(ostream &stream, detector Detector)
Definition: detector.cc:934
STL namespace.
G4ThreeVector pos
Position relative to the mother volume, as G4ThreeVector.
Definition: detector.h:57
bool operator==(const detector &D) const
Overloaded "==" operator for detector class.
Definition: detector.cc:974
int create_solid(gemc_opts, map< string, detector > *)
Creates the Solid. If it&#39;s a Copy Placement, retrieve and assigns LogicV.
Definition: detector.cc:46
G4VisAttributes VAtts
Visual Attributes: color, transparency, style (wireframe, solid), visibility.
Definition: detector.h:60
vector< vector< string > > dimensionstype(string solidtype)
Returns dimensions nomenclature for different solid type.
Definition: detector.cc:803
int ncopy
copy number
Definition: detector.h:68
string name
Name of the volume. Since this is the key of the STL map, it has to be unique.
Definition: detector.h:53
string material
Volume Material name.
Definition: detector.h:65
detector()
Definition: detector.cc:39
int visible
visibility of the detector: 0=invisible 1=visible
Definition: detector.h:72
int style
Visual style: 0=wireframe 1=solid.
Definition: detector.h:73
string hitType
Hit Process routine name. A Hit Process MPHBaseClass derived class must exists with this name...
Definition: detector.h:76
vector< identifier > identity
Vector of identifiers. Example: superlayer manual 1 type manual 2 segment manual 3 strip manual 4...
Definition: detector.h:77
string magfield
Magnetic Field. The string "no" means that the field is inherited from the mother volume...
Definition: detector.h:66
map< string, opts > args
Options map.
Definition: usage.h:68
G4RotationMatrix rot
Rotation Matrix, defined by rotations along x,y,z axis relative to the mother volume.
Definition: detector.h:58
int exist
detector ON/OFF switch
Definition: detector.h:71
int create_physical_volumes(gemc_opts, G4LogicalVolume *)
Creates the Physical Volume.
Definition: detector.cc:757
string type
solid type. This follows the GEANT4 definitions
Definition: detector.h:62
vector< double > dimensions
vector of dimensions. Size, units depends on solid type
Definition: detector.h:63
string TrimSpaces(string in)
Removes leading and trailing spaces.
double r
Definition: dc12geom.h:54
string description
Volume Description for documentation.
Definition: detector.h:55