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>
28 #include <CLHEP/Vector/RotationZ.h>
30 #include <boost/format.hpp>
45 const std::string &dnam)
47 , m_Params(parameters)
62 std::cout << __PRETTY_FUNCTION__ <<
" delete m_EndCapAssembly" << std::endl;
72 G4LogicalVolume *logvol = volume->GetLogicalVolume();
92 G4RotateY3D rotm_otherside(180 * deg);
97 G4RotationMatrix rotm_center;
101 G4Transform3D transform_center(rotm_center, g4vec_center);
105 G4Transform3D transform_side1 = transform_center * g4vec_front_z;
108 G4Transform3D transform_side2 = transform_center * rotm_otherside * g4vec_front_z;
116 G4AssemblyVolume *assemblyvol =
new G4AssemblyVolume();
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;
207 G4Material *composite =
new G4Material(compositeName, compositeDensity, thickness.size());
210 for (std::vector<double>::size_type i = 0; i < thickness.size(); i++)
213 composite->AddMaterial(tempmat, thickness[i] * tempmat->GetDensity() / totalArealDensity);
221 G4AssemblyVolume *assemblyvol,
224 std::string _material,
226 double _percentage_filled
229 z_start += _depth / 2.;
230 G4ThreeVector g4vec(0, 0, z_start);
231 z_start += _depth / 2.;
233 std::string name_base = boost::str(boost::format(
"%1%_Layer_%2%") %
GetName() % _name);
235 G4VSolid *solid_layer =
new G4Tubs(
239 _depth * _percentage_filled / 100. / 2.,
243 if (material ==
nullptr)
245 std::cout << __PRETTY_FUNCTION__ <<
" Fatal Error: missing material " << _material << std::endl;
249 G4LogicalVolume *logical_layer =
new G4LogicalVolume(solid_layer, material, name_base);
252 assemblyvol->AddPlacedVolume(logical_layer, g4vec,
nullptr);
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.;
289 G4ThreeVector g4vec_wagon_wheel_front_frame(0, 0, z_start);
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);
315 G4VSolid *solid_wagon_wheel_front_frame =
new G4Tubs(
319 wagon_wheel_front_frame_thickness / 2.,
322 G4LogicalVolume *log_solid_wagon_wheel_front_frame =
new G4LogicalVolume(solid_wagon_wheel_front_frame, material, name_base);
325 assmeblyvol->AddPlacedVolume(log_solid_wagon_wheel_front_frame,
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));
355 G4TwoVector
zero(0, 0);
357 std::string name_base_spoke = boost::str(boost::format(
"%1%_%2%_Ring%3%_spoke") %
GetName() %
"wagon_wheel_front_frame" % ring_id);
359 G4VSolid *solid_wagon_wheel_front_frame_spoke =
new G4ExtrudedSolid(name_base_spoke,
361 wagon_wheel_front_frame_thickness / 2.,
364 G4LogicalVolume *log_solid_wagon_wheel_front_frame_spoke =
new G4LogicalVolume(solid_wagon_wheel_front_frame_spoke, material, name_base_spoke);
368 for (
int sector_id = 0; sector_id < n_sectors; ++sector_id)
370 G4Transform3D trans_spoke(CLHEP::HepRotationZ(wagon_wheel_sector_phi_offset + sector_dphi * sector_id), g4vec_wagon_wheel_front_frame);
372 assmeblyvol->AddPlacedVolume(log_solid_wagon_wheel_front_frame_spoke,
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());
398 G4VSolid *solid_wagon_wheel =
new G4Tubs(
400 wagon_wheel_rim_outer_Rin,
401 wagon_wheel_rim_outer_Rout,
402 wagon_wheel_rim_outer_thickness / 2.,
405 G4LogicalVolume *log_solid_wagon_wheel =
new G4LogicalVolume(solid_wagon_wheel, material, name_base);
408 assmeblyvol->AddPlacedVolume(log_solid_wagon_wheel,
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));
433 G4TwoVector
zero(0, 0);
435 G4VSolid *solid_wagon_wheel_spoke =
new G4ExtrudedSolid(name_base,
437 wagon_wheel_spoke_width / 2.,
440 G4LogicalVolume *log_solid_wagon_wheel_spoke =
new G4LogicalVolume(solid_wagon_wheel_spoke, material, name_base);
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)
448 G4RotateY3D rotm_spoke(-90 * deg);
449 G4Transform3D trans_spoke(CLHEP::HepRotationZ(wagon_wheel_sector_phi_offset + sector_dphi * sector_id),
450 g4vec_wagon_wheel_spoke);
451 G4Transform3D trans_spoke_final = trans_spoke * rotm_spoke;
453 assmeblyvol->AddPlacedVolume(log_solid_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);
525 G4VSolid *
solid =
new G4Tubs(
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;
540 G4LogicalVolume *log_vol =
new G4LogicalVolume(solid, material, name_base);
543 for (
int sector_id = 0; sector_id < n_sectors; ++sector_id)
546 CLHEP::HepRotationZ(wagon_wheel_sector_phi_offset + sector_dphi * sector_id),
547 g4vec_electronics_cooling_block);
549 assmeblyvol->AddPlacedVolume(log_vol, trans);
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;
588 G4AssemblyVolume *assmeblyvol_electronics =
new G4AssemblyVolume();
589 G4double starting_electronics(0);
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.;
598 G4ThreeVector g4vec_electronics;
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.);
607 G4LogicalVolume *log_electronics =
nullptr;
608 log_electronics =
new G4LogicalVolume(solid_electronics,
GetDetectorMaterial(
"FR4"), name_base +
"_PCB");
611 assmeblyvol_electronics->AddPlacedVolume(log_electronics,
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.);
628 log_electronics =
new G4LogicalVolume(solid_electronics,
GetDetectorMaterial(
"G4_Cu"), name_base +
"_Cu");
631 assmeblyvol_electronics->AddPlacedVolume(log_electronics,
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.);
648 log_electronics =
new G4LogicalVolume(solid_electronics,
653 assmeblyvol_electronics->AddPlacedVolume(log_electronics,
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)
666 G4Transform3D trans_electronic = G4RotateZ3D(board_phi_start + board_dphi * board_id);
668 assmeblyvol->AddPlacedAssembly(assmeblyvol_electronics, trans_electronic);
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;