5 #include <phparameter/PHParameters.h>
13 #include <Geant4/G4AssemblyVolume.hh>
14 #include <Geant4/G4Box.hh>
15 #include <Geant4/G4ExtrudedSolid.hh>
16 #include <Geant4/G4LogicalVolume.hh>
17 #include <Geant4/G4Material.hh>
18 #include <Geant4/G4RotationMatrix.hh>
19 #include <Geant4/G4String.hh>
20 #include <Geant4/G4SystemOfUnits.hh>
21 #include <Geant4/G4ThreeVector.hh>
22 #include <Geant4/G4Transform3D.hh>
23 #include <Geant4/G4Tubs.hh>
24 #include <Geant4/G4TwoVector.hh>
25 #include <Geant4/G4Types.hh>
26 #include <Geant4/G4VPhysicalVolume.hh>
30 #include <boost/format.hpp>
45 const std::string &dnam)
47 , m_Params(parameters)
62 std::cout << __PRETTY_FUNCTION__ <<
" delete m_EndCapAssembly" << std::endl;
105 G4Transform3D transform_side1 = transform_center * g4vec_front_z;
108 G4Transform3D transform_side2 = transform_center * rotm_otherside * g4vec_front_z;
132 material.push_back(
"G4_Cu");
133 thickness.push_back(0.0005 * 2. *
cm);
134 material.push_back(
"G4_KAPTON");
135 thickness.push_back(0.005 *
cm);
136 material.push_back(
"sPHENIX_TPC_Gas");
137 thickness.push_back(0.2 *
cm);
143 double totalThickness = 0;
144 for (std::vector<double>::size_type i = 0; i < thickness.size(); i++)
146 totalThickness += thickness[i];
152 totalThickness *= n_GEM_layers;
153 AddLayer(assemblyvol, starting_z,
G4String(
"GEMAllParts"),
"GEMeffective", totalThickness, 64);
157 const int n_PCB_layers(16);
159 AddLayer(assemblyvol, starting_z,
G4String(
"PCBCu"),
"G4_Cu", 0.0035 *
cm * n_PCB_layers, 80);
161 AddLayer(assemblyvol, starting_z,
"PCBBase",
"FR4", 0.00254 *
cm * 7 * n_PCB_layers, 100);
170 std::string compositeName,
171 std::vector<std::string> materialName,
178 std::cout << __PRETTY_FUNCTION__ <<
" NOTICE: Checking if material " << compositeName <<
" exists. This will return a warning if it doesn't, but that is okay." << std::endl;
181 if (tempmat !=
nullptr)
183 std::cout << __PRETTY_FUNCTION__ <<
" Fatal Error: composite material " << compositeName <<
" already exists" << std::endl;
188 assert(materialName.size() == thickness.size());
191 double totalArealDensity = 0, totalThickness = 0;
192 for (std::vector<double>::size_type i = 0; i < thickness.size(); i++)
195 if (tempmat ==
nullptr)
197 std::cout << __PRETTY_FUNCTION__ <<
" Fatal Error: component material " << materialName[i] <<
" does not exist." << std::endl;
201 totalArealDensity += tempmat->
GetDensity() * thickness[i];
202 totalThickness += thickness[i];
206 double compositeDensity = totalArealDensity / totalThickness;
210 for (std::vector<double>::size_type i = 0; i < thickness.size(); i++)
224 std::string _material,
226 double _percentage_filled
229 z_start += _depth / 2.;
231 z_start += _depth / 2.;
233 std::string name_base = boost::str(boost::format(
"%1%_Layer_%2%") %
GetName() % _name);
239 _depth * _percentage_filled / 100. / 2.,
243 if (material ==
nullptr)
245 std::cout << __PRETTY_FUNCTION__ <<
" Fatal Error: missing material " << _material << std::endl;
264 assert(n_sectors >= 1);
266 assert(n_radial_modules >= 1);
270 if (material ==
nullptr)
272 std::cout << __PRETTY_FUNCTION__ <<
" Fatal Error: missing material " <<
m_Params->
get_string_param(
"wagon_wheel_material") << std::endl;
282 std::cout << __PRETTY_FUNCTION__ <<
" - wagon_wheel_front_frame z_start = " << z_start << std::endl;
288 z_start += wagon_wheel_front_frame_thickness / 2.;
290 z_start += wagon_wheel_front_frame_thickness / 2.;
295 for (
int ring_id = 0; ring_id <= n_radial_modules; ++ring_id)
297 G4double Rin = wagon_wheel_front_frame_R_inner;
298 G4double Rout = wagon_wheel_front_frame_R_outer;
303 boost::str(boost::format(
"wagon_wheel_front_frame_R_R%1%_outer") % (ring_id))) *
306 if (ring_id < n_radial_modules)
309 boost::str(boost::format(
"wagon_wheel_front_frame_R_R%1%_inner") % (ring_id + 1))) *
313 std::string name_base = boost::str(boost::format(
"%1%_%2%_Ring%3%") %
GetName() %
"wagon_wheel_front_frame" % ring_id);
319 wagon_wheel_front_frame_thickness / 2.,
326 g4vec_wagon_wheel_front_frame,
336 for (
int ring_id = 1; ring_id <= n_radial_modules; ++ring_id)
340 boost::str(boost::format(
"wagon_wheel_front_frame_R_R%1%_outer") % (ring_id))) *
344 boost::str(boost::format(
"wagon_wheel_front_frame_R_R%1%_inner") % (ring_id))) *
347 const G4double reduced_height = sqrt(Rout * Rout - wagon_wheel_front_frame_spoke_width / 2 * wagon_wheel_front_frame_spoke_width / 2);
349 std::vector<G4TwoVector> vertexes;
350 vertexes.push_back(
G4TwoVector(-wagon_wheel_front_frame_spoke_width / 2, Rin));
351 vertexes.push_back(
G4TwoVector(+wagon_wheel_front_frame_spoke_width / 2, Rin));
352 vertexes.push_back(
G4TwoVector(+wagon_wheel_front_frame_spoke_width / 2, reduced_height));
353 vertexes.push_back(
G4TwoVector(-wagon_wheel_front_frame_spoke_width / 2, reduced_height));
357 std::string name_base_spoke = boost::str(boost::format(
"%1%_%2%_Ring%3%_spoke") %
GetName() %
"wagon_wheel_front_frame" % ring_id);
361 wagon_wheel_front_frame_thickness / 2.,
368 for (
int sector_id = 0; sector_id < n_sectors; ++sector_id)
386 std::cout << __PRETTY_FUNCTION__ <<
" - wagon_wheel_rim_outer z_start = " << z_start << std::endl;
394 G4ThreeVector g4vec_wagon_wheel_rim_outer(0, 0, z_start + wagon_wheel_rim_outer_thickness / 2.);
396 std::string name_base = boost::str(boost::format(
"%1%_wagon_wheel_rim_outer") %
GetName());
400 wagon_wheel_rim_outer_Rin,
401 wagon_wheel_rim_outer_Rout,
402 wagon_wheel_rim_outer_thickness / 2.,
409 g4vec_wagon_wheel_rim_outer,
426 std::string name_base = boost::str(boost::format(
"%1%_wagon_wheel_spoke") %
GetName());
428 std::vector<G4TwoVector> vertexes;
429 vertexes.push_back(
G4TwoVector(0, wagon_wheel_spoke_R_inner));
430 vertexes.push_back(
G4TwoVector(0, wagon_wheel_spoke_R_outer));
431 vertexes.push_back(
G4TwoVector(wagon_wheel_spoke_height_outer, wagon_wheel_spoke_R_outer));
432 vertexes.push_back(
G4TwoVector(wagon_wheel_spoke_height_inner, wagon_wheel_spoke_R_inner));
437 wagon_wheel_spoke_width / 2.,
443 G4ThreeVector g4vec_wagon_wheel_spoke(0, 0, z_start + wagon_wheel_spoke_width / 2.);
446 for (
int sector_id = 0; sector_id < n_sectors; ++sector_id)
450 g4vec_wagon_wheel_spoke);
467 assert(n_sectors >= 1);
472 assert(n_radial_modules >= 1);
480 if (electronics_cooling_block_thickness > 0)
484 std::cout << __PRETTY_FUNCTION__ <<
" - electronics_cooling_block_material z_start = " << z_start << std::endl;
487 const std::string electronics_cooling_block_material_name(
m_Params->
get_string_param(
"electronics_cooling_block_material"));
489 if (material ==
nullptr)
491 std::cout << __PRETTY_FUNCTION__ <<
" Fatal Error: missing material " <<
m_Params->
get_string_param(
"electronics_cooling_block_material_name") << std::endl;
496 G4ThreeVector g4vec_electronics_cooling_block(0, 0, z_start + electronics_cooling_block_thickness / 2.);
501 for (
int ring_id = 0; ring_id <= n_radial_modules; ++ring_id)
503 G4double Rin = electronics_cooling_block_R_inner;
504 G4double Rout = electronics_cooling_block_R_outer;
509 boost::str(boost::format(
"electronics_cooling_block_R_R%1%_outer") % (ring_id))) *
512 if (ring_id < n_radial_modules)
515 boost::str(boost::format(
"electronics_cooling_block_R_R%1%_inner") % (ring_id + 1))) *
519 std::string name_base = boost::str(boost::format(
"%1%_%2%_Ring%3%") %
GetName() %
"electronics_cooling_block" % ring_id);
521 const G4double spoke_phi = atan2(wagon_wheel_spoke_width, Rin);
529 electronics_cooling_block_thickness / 2.,
530 spoke_phi, sector_dphi - 2 * spoke_phi);
534 std::cout << __PRETTY_FUNCTION__ <<
" - electronics_cooling_block " << name_base
535 <<
" Rin = " << Rin <<
" Rout = " << Rout
536 <<
" phi = " << spoke_phi <<
" to " << (sector_dphi - spoke_phi) << std::endl;
543 for (
int sector_id = 0; sector_id < n_sectors; ++sector_id)
547 g4vec_electronics_cooling_block);
564 const G4double electronics_assemly_thickness = electronics_FEE_Cu_thickness + electronics_FEE_PCB_thickness + electronics_FEE_Al_thickness;
568 for (
int ring_id = 1; ring_id <= n_radial_modules; ++ring_id)
571 boost::str(boost::format(
"electronics_cooling_block_R_R%1%_outer") % (ring_id))) *
573 electronics_assemly_thickness;
575 boost::str(boost::format(
"electronics_cooling_block_R_R%1%_inner") % (ring_id))) *
577 electronics_assemly_thickness;
578 const int nFEE =
m_Params->
get_int_param(boost::str(boost::format(
"electronics_nFEE_R%1%") % (ring_id)));
582 std::cout << __PRETTY_FUNCTION__ <<
" warning : ignore FEE construction for module " << ring_id <<
" as "
583 << boost::str(boost::format(
"electronics_nFEE_R2%1%") % (ring_id)) <<
" = " << nFEE << std::endl;
590 std::string name_base = boost::str(boost::format(
"%1%_%2%_Ring%3%") %
GetName() %
"electronics" % ring_id);
594 std::cout << __PRETTY_FUNCTION__ <<
" - electronics G4_PCB z_start = " << z_start
595 <<
" starting_electronics = " << starting_electronics << std::endl;
597 starting_electronics -= electronics_FEE_PCB_thickness / 2.;
599 g4vec_electronics.
set(starting_electronics, (Rout + Rin) * .5, z_start + electronics_FEE_depth / 2.);
600 starting_electronics -= electronics_FEE_PCB_thickness / 2.;
601 G4VSolid *solid_electronics =
nullptr;
602 solid_electronics =
new G4Box(name_base +
"_PCB",
603 electronics_FEE_PCB_thickness / 2.,
605 electronics_FEE_depth / 2.);
612 g4vec_electronics,
nullptr);
616 std::cout << __PRETTY_FUNCTION__ <<
" - electronics G4_Cu z_start = " << z_start
617 <<
" starting_electronics = " << starting_electronics << std::endl;
619 starting_electronics -= electronics_FEE_Cu_thickness / 2.;
620 g4vec_electronics.
set(starting_electronics, (Rout + Rin) * .5, z_start + electronics_FEE_depth / 2.);
621 starting_electronics -= electronics_FEE_Cu_thickness / 2.;
623 solid_electronics =
new G4Box(name_base +
"_Cu",
624 electronics_FEE_Cu_thickness / 2.,
626 electronics_FEE_depth / 2.);
632 g4vec_electronics,
nullptr);
636 std::cout << __PRETTY_FUNCTION__ <<
" - electronics Al z_start = " << z_start
637 <<
" starting_electronics = " << starting_electronics << std::endl;
639 starting_electronics -= electronics_FEE_Al_thickness / 2.;
640 g4vec_electronics.
set(starting_electronics, (Rout + Rin) * .5, z_start + electronics_FEE_depth / 2.);
641 starting_electronics -= electronics_FEE_Al_thickness / 2.;
643 solid_electronics =
new G4Box(name_base +
"_Al",
644 electronics_FEE_Al_thickness / 2.,
646 electronics_FEE_depth / 2.);
654 g4vec_electronics,
nullptr);
657 for (
int sector_id = 0; sector_id < n_sectors; ++sector_id)
659 const G4double sector_phi_shift = wagon_wheel_sector_phi_offset + sector_dphi * sector_id;
660 const G4double spoke_phi = atan2(wagon_wheel_spoke_width, Rin);
661 const G4double board_dphi = (sector_dphi - 2 * spoke_phi) / (nFEE + 1);
662 const G4double board_phi_start = sector_phi_shift + spoke_phi + board_dphi;
664 for (
int board_id = 0; board_id < nFEE; ++board_id)
679 std::cout <<
"PHG4TpcEndCap Detector:" << std::endl;
680 if (what ==
"ALL" || what ==
"VOLUME")
682 std::cout <<
"Version 0.1" << std::endl;
683 std::cout <<
"Parameters:" << std::endl;