17 #include <Geant4/G4Box.hh>
18 #include <Geant4/G4Exception.hh>
19 #include <Geant4/G4ExceptionSeverity.hh>
20 #include <Geant4/G4LogicalVolume.hh>
21 #include <Geant4/G4PVPlacement.hh>
22 #include <Geant4/G4PhysicalConstants.hh>
23 #include <Geant4/G4String.hh>
24 #include <Geant4/G4SystemOfUnits.hh>
25 #include <Geant4/G4Transform3D.hh>
26 #include <Geant4/G4Trap.hh>
27 #include <Geant4/G4Tubs.hh>
28 #include <Geant4/G4Types.hh>
29 #include <Geant4/G4Vector3D.hh>
58 <<
"PHG4FullProjSpacalDetector::Constructor - Fatal Error - invalid geometry object!"
79 std::cout <<
"PHG4FullProjSpacalDetector::Construct::" <<
GetName()
80 <<
" - start with PHG4SpacalDetector::Construct()." << std::endl;
87 std::cout <<
"PHG4FullProjSpacalDetector::Construct::" <<
GetName()
88 <<
" - Completed." << std::endl;
92 std::pair<G4LogicalVolume*, G4Transform3D>
111 G4LogicalVolume* sec_logic =
new G4LogicalVolume(sec_solid, cylinder_mat,
124 if (
get_geom_v3()->get_construction_verbose() >= 1)
126 std::cout <<
"PHG4FullProjSpacalDetector::Construct_AzimuthalSeg::" <<
GetName()
127 <<
" - construct end walls." << std::endl;
136 G4LogicalVolume* wall_logic =
new G4LogicalVolume(wall_solid, wall_mat,
141 using z_locations_t = std::map<int, double>;
142 z_locations_t z_locations;
151 std::cout <<
"PHG4FullProjSpacalDetector::Construct_AzimuthalSeg::"
152 <<
GetName() <<
" - constructed End Wall ID " << val.first
153 <<
" @ Z = " << val.second << std::endl;
155 G4Transform3D wall_trans = G4TranslateZ3D(val.second);
157 G4PVPlacement* wall_phys =
new G4PVPlacement(wall_trans, wall_logic,
158 G4String(
GetName()) + G4String(
"_EndWall"), sec_logic,
170 if (
get_geom_v3()->get_construction_verbose() >= 1)
172 std::cout <<
"PHG4FullProjSpacalDetector::Construct_AzimuthalSeg::" <<
GetName()
173 <<
" - construct side walls." << std::endl;
180 G4LogicalVolume* wall_logic =
new G4LogicalVolume(wall_solid, wall_mat,
185 using sign_t = std::map<int, std::pair<int, int>>;
187 signs[2000] = std::make_pair(+1, +1);
188 signs[2001] = std::make_pair(+1, -1);
189 signs[2100] = std::make_pair(-1, +1);
190 signs[2101] = std::make_pair(-1, -1);
194 const int sign_z = val.second.first;
195 const int sign_azimuth = val.second.second;
197 if (
get_geom_v3()->get_construction_verbose() >= 2)
198 std::cout <<
"PHG4FullProjSpacalDetector::Construct_AzimuthalSeg::"
199 <<
GetName() <<
" - constructed Side Wall ID " << val.first
208 G4Transform3D wall_trans = G4RotateZ3D(
212 G4PVPlacement* wall_phys =
new G4PVPlacement(wall_trans, wall_logic,
213 G4String(
GetName()) + G4String(
"_EndWall"), sec_logic,
234 G4PVPlacement* block_phys =
new G4PVPlacement(block_trans, LV_tower,
235 G4String(
GetName()) + G4String(
"_Tower"), sec_logic,
false,
236 g_tower.
id, overlapcheck_block);
243 std::cout <<
"PHG4FullProjSpacalDetector::Construct_AzimuthalSeg::" <<
GetName()
245 <<
" unique towers" << std::endl;
247 return std::make_pair(sec_logic, G4Transform3D::Identity);
253 G4LogicalVolume* LV_tower)
259 using fiber_par_map = std::map<int, std::pair<G4Vector3D, G4Vector3D>>;
260 fiber_par_map fiber_par;
261 G4double min_fiber_length = g_tower.
pDz *
cm * 4;
263 G4Vector3D v_zshift = G4Vector3D(tan(g_tower.
pTheta) * cos(g_tower.
pPhi),
267 for (
int ix = 0; ix < g_tower.
NFiberX; ix++)
270 const double weighted_ix =
static_cast<double>(ix) / (g_tower.
NFiberX - 1.);
278 for (
int iy = 0; iy < g_tower.
NFiberY; iy++)
281 if ((ix + iy) % 2 == 1)
284 const double weighted_iy =
static_cast<double>(iy) / (g_tower.
NFiberY - 1.);
289 const double weighted_pDx12 = weighted_pDx1 * (1 - weighted_iy) + weighted_pDx2 * (weighted_iy) + weighted_pDy1 * tan(g_tower.
pAlp1);
290 const double weighted_pDx34 = weighted_pDx3 * (1 - weighted_iy) + weighted_pDx4 * (weighted_iy) + weighted_pDy1 * tan(g_tower.
pAlp2);
292 G4Vector3D
v1 = G4Vector3D(weighted_pDx12, weighted_pDy1, 0) - v_zshift;
293 G4Vector3D
v2 = G4Vector3D(weighted_pDx34, weighted_pDy2, 0) + v_zshift;
295 G4Vector3D vector_fiber = (v2 -
v1);
297 G4Vector3D center_fiber = (v2 +
v1) / 2;
304 fiber_par[fiber_ID] = std::make_pair(vector_fiber,
307 const G4double fiber_length = vector_fiber.mag();
309 min_fiber_length =
std::min(fiber_length, min_fiber_length);
317 const G4double fiber_length = min_fiber_length;
318 std::vector<G4double> fiber_cut;
320 std::stringstream ss;
322 G4LogicalVolume* fiber_logic =
Construct_Fiber(fiber_length, ss.str());
326 const int fiber_ID = val.first;
327 G4Vector3D vector_fiber = val.second.first;
328 G4Vector3D center_fiber = val.second.second;
329 const G4double optimal_fiber_length = vector_fiber.mag();
331 const G4Vector3D
v1 = center_fiber - 0.5 * vector_fiber;
334 assert(optimal_fiber_length - fiber_length >= 0);
335 fiber_cut.push_back(optimal_fiber_length - fiber_length);
337 center_fiber += (fiber_length / optimal_fiber_length - 1) * 0.5 * vector_fiber;
338 vector_fiber *= fiber_length / optimal_fiber_length;
343 std::cout <<
"PHG4FullProjSpacalDetector::Construct_Fibers_SameLengthFiberPerTower::" <<
GetName()
344 <<
" - constructed fiber " << fiber_ID << ss.str()
345 <<
", Length = " << optimal_fiber_length <<
"-"
346 << (optimal_fiber_length - fiber_length) <<
"mm, "
347 <<
"x = " << center_fiber.x() <<
"mm, "
348 <<
"y = " << center_fiber.y() <<
"mm, "
349 <<
"z = " << center_fiber.z() <<
"mm, "
350 <<
"vx = " << vector_fiber.x() <<
"mm, "
351 <<
"vy = " << vector_fiber.y() <<
"mm, "
352 <<
"vz = " << vector_fiber.z() <<
"mm, "
355 const G4double rotation_angle = G4Vector3D(0, 0, 1).angle(vector_fiber);
356 const G4Vector3D rotation_axis =
357 rotation_angle == 0 ? G4Vector3D(1, 0, 0) : G4Vector3D(0, 0, 1).cross(vector_fiber);
359 G4Transform3D fiber_place(
360 G4Translate3D(center_fiber.x(), center_fiber.y(), center_fiber.z()) * G4Rotate3D(rotation_angle, rotation_axis));
362 std::stringstream
name;
367 G4PVPlacement* fiber_physi =
new G4PVPlacement(fiber_place, fiber_logic,
368 G4String(name.str()), LV_tower,
false, fiber_ID,
378 if (
get_geom_v3()->get_construction_verbose() >= 2)
380 <<
"PHG4FullProjSpacalDetector::Construct_Fibers_SameLengthFiberPerTower::"
381 <<
GetName() <<
" - constructed tower ID " << g_tower.
id <<
" with "
382 << fiber_count <<
" fibers. Average fiber length cut = "
383 << accumulate(fiber_cut.begin(), fiber_cut.end(), 0.0) / fiber_cut.size() <<
" mm" << std::endl;
391 G4LogicalVolume* LV_tower)
393 G4Vector3D v_zshift = G4Vector3D(tan(g_tower.
pTheta) * cos(g_tower.
pPhi),
397 for (
int ix = 0; ix < g_tower.
NFiberX; ix++)
399 const double weighted_ix =
static_cast<double>(ix) / (g_tower.
NFiberX - 1.);
407 for (
int iy = 0; iy < g_tower.
NFiberY; iy++)
409 if ((ix + iy) % 2 == 1)
413 const double weighted_iy =
static_cast<double>(iy) / (g_tower.
NFiberY - 1.);
418 const double weighted_pDx12 = weighted_pDx1 * (1 - weighted_iy) + weighted_pDx2 * (weighted_iy) + weighted_pDy1 * tan(g_tower.
pAlp1);
419 const double weighted_pDx34 = weighted_pDx3 * (1 - weighted_iy) + weighted_pDx4 * (weighted_iy) + weighted_pDy1 * tan(g_tower.
pAlp2);
421 G4Vector3D
v1 = G4Vector3D(weighted_pDx12, weighted_pDy1, 0) - v_zshift;
422 G4Vector3D
v2 = G4Vector3D(weighted_pDx34, weighted_pDy2, 0) + v_zshift;
424 G4Vector3D vector_fiber = (v2 -
v1);
426 G4Vector3D center_fiber = (v2 +
v1) / 2;
432 const G4double fiber_length = vector_fiber.mag();
434 std::stringstream ss;
442 std::cout <<
"PHG4FullProjSpacalDetector::Construct_Fibers::" <<
GetName()
443 <<
" - constructed fiber " << fiber_ID << ss.str()
444 <<
", Length = " << fiber_length <<
"mm, "
445 <<
"x = " << center_fiber.x() <<
"mm, "
446 <<
"y = " << center_fiber.y() <<
"mm, "
447 <<
"z = " << center_fiber.z() <<
"mm, "
448 <<
"vx = " << vector_fiber.x() <<
"mm, "
449 <<
"vy = " << vector_fiber.y() <<
"mm, "
450 <<
"vz = " << vector_fiber.z() <<
"mm, "
453 const G4double rotation_angle = G4Vector3D(0, 0, 1).angle(
455 const G4Vector3D rotation_axis =
456 rotation_angle == 0 ? G4Vector3D(1, 0, 0) : G4Vector3D(0, 0, 1).cross(vector_fiber);
458 G4Transform3D fiber_place(
459 G4Translate3D(center_fiber.x(), center_fiber.y(),
461 G4Rotate3D(rotation_angle, rotation_axis));
463 std::stringstream
name;
468 G4PVPlacement* fiber_physi =
new G4PVPlacement(fiber_place,
469 fiber_logic, G4String(name.str()), LV_tower,
false,
470 fiber_ID, overlapcheck_fiber);
480 if (
get_geom_v3()->get_construction_verbose() >= 3)
481 std::cout <<
"PHG4FullProjSpacalDetector::Construct_Fibers::" <<
GetName()
482 <<
" - constructed tower ID " << g_tower.
id <<
" with " << fiber_cnt
483 <<
" fibers" << std::endl;
493 std::stringstream sout;
494 sout <<
"_" << g_tower.
id;
495 const G4String sTowerID(sout.str());
499 G4Trap* block_solid =
new G4Trap(
500 G4String(
GetName()) + sTowerID,
512 G4LogicalVolume* block_logic =
new G4LogicalVolume(block_solid, cylinder_mat,
524 if (
get_geom_v3()->get_construction_verbose() >= 2)
525 std::cout <<
"PHG4FullProjSpacalDetector::Construct_Tower::" <<
GetName()
526 <<
" - constructed tower ID " << g_tower.
id <<
" with "
527 << fiber_count <<
" fibers using Construct_Fibers" << std::endl;
534 if (
get_geom_v3()->get_construction_verbose() >= 2)
535 std::cout <<
"PHG4FullProjSpacalDetector::Construct_Tower::" <<
GetName()
536 <<
" - constructed tower ID " << g_tower.
id <<
" with "
538 <<
" fibers using Construct_Fibers_SameLengthFiberPerTower" << std::endl;
542 G4ExceptionDescription
message;
545 G4Exception(
"PHG4FullProjSpacalDetector::Construct_Tower",
"Wrong",
546 FatalException, message,
"");
554 std::cout <<
"PHG4FullProjSpacalDetector::Print::" <<
GetName()
555 <<
" - Print Geometry:" << std::endl;