EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4SpacalDetector.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4SpacalDetector.cc
1 
8 #include "PHG4SpacalDetector.h"
9 
12 
13 #include <g4main/PHG4Detector.h> // for PHG4Detector
14 #include <g4main/PHG4DisplayAction.h> // for PHG4DisplayAction
15 #include <g4main/PHG4Subsystem.h>
16 
17 #include <phool/PHCompositeNode.h>
18 #include <phool/PHIODataNode.h>
19 #include <phool/PHNode.h> // for PHNode
20 #include <phool/PHNodeIterator.h> // for PHNodeIterator
21 #include <phool/PHObject.h> // for PHObject
22 #include <phool/getClass.h>
23 #include <phool/recoConsts.h>
24 
25 #include <g4gdml/PHG4GDMLConfig.hh>
27 
28 #include <TSystem.h>
29 
30 #include <Geant4/G4LogicalVolume.hh>
31 #include <Geant4/G4Material.hh>
32 #include <Geant4/G4PVPlacement.hh>
33 #include <Geant4/G4PhysicalConstants.hh>
34 #include <Geant4/G4String.hh> // for G4String
35 #include <Geant4/G4SystemOfUnits.hh>
36 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
37 #include <Geant4/G4Transform3D.hh> // for G4Transform3D, G4RotateZ3D
38 #include <Geant4/G4Tubs.hh>
39 #include <Geant4/G4Types.hh> // for G4double
40 #include <Geant4/G4UserLimits.hh>
41 
42 #include <cassert>
43 #include <cstdlib> // for exit
44 #include <iostream> // for operator<<, basic_ostream
45 #include <sstream>
46 
47 class PHG4CylinderGeom;
48 
49 //_______________________________________________________________
50 //note this inactive thickness is ~1.5% of a radiation length
52  PHCompositeNode *Node,
53  const std::string &dnam,
55  const int lyr,
56  bool init_geom)
57  : PHG4Detector(subsys, Node, dnam)
58  , m_DisplayAction(dynamic_cast<PHG4SpacalDisplayAction *>(subsys->GetDisplayAction()))
59  , layer(lyr)
60 {
61  if (init_geom)
62  {
63  _geom = new SpacalGeom_t();
64  if (_geom == nullptr)
65  {
66  std::cout << "PHG4SpacalDetector::Constructor - Fatal Error - invalid geometry object!" << std::endl;
67  gSystem->Exit(1);
68  exit(1);
69  }
70  assert(parameters);
71  _geom->ImportParameters(*parameters);
72 
73  // _geom->Print();
74  }
75 
77  assert(gdml_config);
78 }
79 
81 {
82  // deleting nullptr pointers is allowed (results in NOOP)
83  // so checking for not null before deleting is not needed
85  delete _geom;
86 }
87 
88 //_______________________________________________________________
89 int PHG4SpacalDetector::IsInCylinderActive(const G4VPhysicalVolume *volume)
90 {
91  // std::cout << "checking detector" << std::endl;
92  if (active && fiber_core_vol.find(volume) != fiber_core_vol.end())
93  {
94  // return fiber_core_vol.find(volume)->second;
95  return FIBER_CORE;
96  }
97  if (absorberactive)
98  {
99  if (fiber_vol.find(volume) != fiber_vol.end())
100  {
101  return FIBER_CLADING;
102  }
103 
104  if (block_vol.find(volume) != block_vol.end())
105  {
106  return ABSORBER;
107  }
108 
109  if (calo_vol.find(volume) != calo_vol.end())
110  {
111  return SUPPORT;
112  }
113  }
114  return INACTIVE;
115 }
116 
117 //_______________________________________________________________
118 void PHG4SpacalDetector::ConstructMe(G4LogicalVolume *logicWorld)
119 {
120  assert(_geom);
121 
122  fiber_core_step_limits = new G4UserLimits(_geom->get_fiber_core_step_size() * cm);
123 
125 
126  if ((Verbosity() > 0))
127  {
128  std::cout << "PHG4SpacalDetector::Construct::" << GetName()
129  << " - Start. Print Geometry:" << std::endl;
130  Print();
131  }
132 
133  if ((_geom->get_zmin() * cm + _geom->get_zmax() * cm) / 2 != _geom->get_zpos() * cm)
134  {
135  std::cout << "PHG4SpacalDetector::Construct - ERROR - not yet support unsymmetric system. Let me know if you need it. - Jin" << std::endl;
136  _geom->Print();
137  gSystem->Exit(-1);
138  }
139  if (_geom->get_zmin() * cm >= _geom->get_zmax() * cm)
140  {
141  std::cout << "PHG4SpacalDetector::Construct - ERROR - zmin >= zmax!" << std::endl;
142  _geom->Print();
143  gSystem->Exit(-1);
144  }
145 
146  G4Tubs *cylinder_solid = new G4Tubs(G4String(GetName()),
148  _geom->get_length() * cm / 2.0, 0, twopi);
149 
151  G4Material *cylinder_mat = GetDetectorMaterial(rc->get_StringFlag("WorldMaterial"));
152  assert(cylinder_mat);
153 
154  G4LogicalVolume *cylinder_logic = new G4LogicalVolume(cylinder_solid, cylinder_mat, GetName(), 0, 0, 0);
155  GetDisplayAction()->AddVolume(cylinder_logic, "SpacalCylinder");
156  if (!m_CosmicSetupFlag)
157  {
158  new G4PVPlacement(0, G4ThreeVector(_geom->get_xpos() * cm, _geom->get_ypos() * cm, _geom->get_zpos() * cm),
159  cylinder_logic, GetName(),
160  logicWorld, false, 0, OverlapCheck());
161  }
162  // install sectors
163  if (_geom->get_sector_map().size() == 0)
164  {
166  }
167 
168  if ((Verbosity() > 0))
169  {
170  std::cout << "PHG4SpacalDetector::Construct::" << GetName()
171  << " - start constructing " << _geom->get_sector_map().size() << " sectors in total. " << std::endl;
172  Print();
173  }
174 
175  std::pair<G4LogicalVolume *, G4Transform3D> psec = Construct_AzimuthalSeg();
176  G4LogicalVolume *sec_logic = psec.first;
177  const G4Transform3D &sec_trans = psec.second;
178 
180  {
181  const int sec = val.first;
182  const double rot = val.second;
183 
184  G4Transform3D sec_place = G4RotateZ3D(rot) * sec_trans;
185 
186  std::ostringstream name;
187  name << GetName() << "_sec" << sec;
188  G4PVPlacement *calo_phys = nullptr;
189  if (m_CosmicSetupFlag)
190  {
191  calo_phys = new G4PVPlacement(0, G4ThreeVector(0, -(_geom->get_radius()) * cm, 0), sec_logic,
192  G4String(name.str()), logicWorld, false, sec,
193  OverlapCheck());
194  }
195  else
196  {
197  calo_phys = new G4PVPlacement(sec_place, sec_logic,
198  G4String(name.str()), cylinder_logic, false, sec,
199  OverlapCheck());
200  }
201  calo_vol[calo_phys] = sec;
202 
203  assert(gdml_config);
204  gdml_config->exclude_physical_vol(calo_phys);
205  }
207 
208  if (active)
209  {
210  std::ostringstream geonode;
211  if (superdetector != "NONE")
212  {
213  geonode << "CYLINDERGEOM_" << superdetector;
214  }
215  else
216  {
217  geonode << "CYLINDERGEOM_" << detector_type << "_" << layer;
218  }
219  PHG4CylinderGeomContainer *geo = findNode::getClass<PHG4CylinderGeomContainer>(topNode(), geonode.str());
220  if (!geo)
221  {
222  geo = new PHG4CylinderGeomContainer();
223  PHNodeIterator iter(topNode());
224  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
226  geonode.str(), "PHObject");
227  runNode->addNode(newNode);
228  }
229  // here in the detector class we have internal units, convert to cm
230  // before putting into the geom object
231  PHG4CylinderGeom *mygeom = clone_geom();
232  geo->AddLayerGeom(layer, mygeom);
233  // geo->identify();
234  }
235 
236  if (absorberactive)
237  {
238  std::ostringstream geonode;
239  if (superdetector != "NONE")
240  {
241  geonode << "CYLINDERGEOM_ABSORBER_" << superdetector;
242  }
243  else
244  {
245  geonode << "CYLINDERGEOM_ABSORBER_" << detector_type << "_" << layer;
246  }
247  PHG4CylinderGeomContainer *geo = findNode::getClass<PHG4CylinderGeomContainer>(topNode(), geonode.str());
248  if (!geo)
249  {
250  geo = new PHG4CylinderGeomContainer();
251  PHNodeIterator iter(topNode());
252  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
254  geonode.str(), "PHObject");
255  runNode->addNode(newNode);
256  }
257  // here in the detector class we have internal units, convert to cm
258  // before putting into the geom object
259  PHG4CylinderGeom *mygeom = clone_geom();
260  geo->AddLayerGeom(layer, mygeom);
261  // geo->identify();
262  }
263 
264  if ((Verbosity() > 0))
265  {
266  std::cout << "PHG4SpacalDetector::Construct::" << GetName()
267  << " - Completed. Print Geometry:" << std::endl;
268  Print();
269  }
270 }
271 
272 std::pair<G4LogicalVolume *, G4Transform3D>
274 {
275  G4Tubs *sec_solid = new G4Tubs(G4String(GetName() + std::string("_sec")),
277  _geom->get_length() * cm / 2.0, 0, twopi / _geom->get_azimuthal_n_sec());
278 
279  G4Material *cylinder_mat = GetDetectorMaterial(_geom->get_absorber_mat());
280  assert(cylinder_mat);
281 
282  G4LogicalVolume *sec_logic = new G4LogicalVolume(sec_solid, cylinder_mat,
283  G4String(G4String(GetName() + std::string("_sec"))), 0, 0, nullptr);
284 
285  GetDisplayAction()->AddVolume(sec_logic, "AzimuthSegment");
286 
287  const double fiber_length = _geom->get_thickness() * cm - 2 * _geom->get_fiber_outer_r() * cm;
288  G4LogicalVolume *fiber_logic = Construct_Fiber(fiber_length, std::string(""));
289 
290  int fiber_count = 0;
291  // double z_step = _geom->get_fiber_distance() * cm * sqrt(3) / 2.;
292  double z_step = _geom->get_z_distance() * cm;
293  G4double z = _geom->get_zmin() * cm - _geom->get_zpos() * cm + z_step;
294  while (z < _geom->get_zmax() * cm - _geom->get_zpos() * cm - z_step)
295  {
296  const double rot = twopi / _geom->get_azimuthal_n_sec() * ((fiber_count % 2 == 0) ? 1. / 4. : 3. / 4.);
297 
298  G4Transform3D fiber_place(G4RotateZ3D(rot) * G4TranslateZ3D(z) * G4TranslateX3D(_geom->get_half_radius() * cm) * G4RotateY3D(halfpi));
299 
300  std::ostringstream name;
301  name << GetName() << "_fiber_" << fiber_count;
302 
303  G4PVPlacement *fiber_physi = new G4PVPlacement(fiber_place, fiber_logic,
304  G4String(name.str()), sec_logic, false, fiber_count,
305  OverlapCheck());
306  fiber_vol[fiber_physi] = fiber_count;
307  assert(gdml_config);
308  gdml_config->exclude_physical_vol(fiber_physi);
309 
310  z += z_step;
311  fiber_count++;
312  }
313  _geom->set_nscint(fiber_count);
314 
315  if (Verbosity() > 0)
316  {
317  std::cout << "PHG4SpacalDetector::Construct_AzimuthalSeg::" << GetName()
318  << " - constructed " << fiber_count << " fibers" << std::endl;
319  std::cout << "\t"
320  << "_geom->get_fiber_distance() = " << _geom->get_fiber_distance()
321  << std::endl;
322  std::cout << "\t"
323  << "fiber_length = " << fiber_length / cm << std::endl;
324  std::cout << "\t"
325  << "z_step = " << z_step << std::endl;
326  std::cout << "\t"
327  << "_geom->get_azimuthal_bin() = " << _geom->get_azimuthal_n_sec()
328  << std::endl;
329  std::cout << "\t"
330  << "_geom->get_azimuthal_distance() = "
331  << _geom->get_azimuthal_distance() << std::endl;
332  std::cout << "\t"
333  << "_geom->is_virualize_fiber() = " << _geom->is_virualize_fiber()
334  << std::endl;
335  }
336 
337  return std::make_pair(sec_logic, G4Transform3D::Identity);
338 }
339 
340 G4LogicalVolume *
341 PHG4SpacalDetector::Construct_Fiber(const G4double length, const std::string &id)
342 {
343  G4Tubs *fiber_solid = new G4Tubs(G4String(GetName() + std::string("_fiber") + id),
344  0, _geom->get_fiber_outer_r() * cm, length / 2.0, 0, twopi);
345 
346  G4Material *clading_mat = GetDetectorMaterial(_geom->get_fiber_clading_mat());
347  assert(clading_mat);
348 
349  G4LogicalVolume *fiber_logic = new G4LogicalVolume(fiber_solid, clading_mat,
350  G4String(G4String(GetName() + std::string("_fiber") + id)), 0, 0,
351  nullptr);
352 
353  {
354  GetDisplayAction()->AddVolume(fiber_logic, "Fiber");
355  }
356 
357  G4Tubs *core_solid = new G4Tubs(
358  G4String(GetName() + std::string("_fiber_core") + id), 0,
359  _geom->get_fiber_core_diameter() * cm / 2, length / 2.0, 0, twopi);
360 
361  G4Material *core_mat = GetDetectorMaterial(_geom->get_fiber_core_mat());
362  assert(core_mat);
363 
364  G4LogicalVolume *core_logic = new G4LogicalVolume(core_solid, core_mat,
365  G4String(G4String(GetName() + std::string("_fiber_core") + id)), 0, 0,
367 
368  {
369  GetDisplayAction()->AddVolume(core_logic, "FiberCore");
370  }
371 
372  const bool overlapcheck_fiber = OverlapCheck() and (Verbosity() >= 3);
373  G4PVPlacement *core_physi = new G4PVPlacement(0, G4ThreeVector(), core_logic,
374  G4String(G4String(GetName() + std::string("_fiber_core") + id)), fiber_logic,
375  false, 0, overlapcheck_fiber);
376  fiber_core_vol[core_physi] = 0;
377 
378  return fiber_logic;
379 }
380 
381 void PHG4SpacalDetector::Print(const std::string & /*what*/) const
382 {
383  std::cout << "PHG4SpacalDetector::Print::" << GetName() << " - Print Geometry:" << std::endl;
384  _geom->Print();
385 
386  return;
387 }