33 template <
typename T,
typename... Args>
34 auto TGeoManagerCreate(Args&&... args) -> T*
36 return std::make_unique<T>(std::forward<Args>(args)...).release();
39 auto create_cone_displacement(
const std::string& name,
double rotate_y_degree) -> TGeoCombiTrans*
41 auto rotation = TGeoRotation{};
42 rotation.RotateY(rotate_y_degree);
43 auto* transition = TGeoManagerCreate<TGeoCombiTrans>(
45 transition->SetName(name.c_str());
46 transition->RegisterYourself();
50 auto build_bar_shape(std::string_view name,
const BarDimension& bar_dimension) -> TGeoShape*
52 auto* displace1 = create_cone_displacement(
"trc1",
DEGREE_90);
53 auto* displace2 = create_cone_displacement(
"trc2", -
DEGREE_90);
55 auto* main_bar_shape = TGeoManagerCreate<TGeoBBox>(
56 fmt::format(
"{}Box", name).c_str(), bar_dimension.
length, bar_dimension.
width, bar_dimension.
width);
57 auto* cone_shape = TGeoManagerCreate<TGeoCone>(fmt::format(
"{}Cone", name).c_str(),
62 bar_dimension.
width * std::sqrt(2.));
63 auto* bar_tail_shape = TGeoManagerCreate<TGeoBBox>(fmt::format(
"{}ConeBox", name).c_str(),
67 return TGeoManagerCreate<TGeoCompositeShape>(name.data(),
68 fmt::format(
"{}+(({}*{}):{})+(({}*{}):{})",
69 main_bar_shape->GetName(),
70 bar_tail_shape->GetName(),
71 cone_shape->GetName(),
73 bar_tail_shape->GetName(),
74 cone_shape->GetName(),
83 read_material_from_file(geo_loader);
84 construct_all_material();
85 construct_all_shapes();
86 construct_all_volumes();
87 return build_detector(num_of_planes);
90 auto Creator::build_detector(
int num_of_planes) -> TGeoVolume*
92 auto* neuland = TGeoManagerCreate<TGeoVolumeAssembly>(
"volNeuland");
95 const auto first_plane_front_z = -num_of_planes *
BarSize_Z / 2.;
97 auto rot_zero = TGeoRotation{};
98 auto rot_90 = TGeoRotation{};
101 for (
int module_id{}; module_id < total_module_size; ++module_id)
105 const auto z_pos =
PlaneID2ZPos(plane_id) + first_plane_front_z;
107 auto* translation_rotation = TGeoManagerCreate<TGeoCombiTrans>();
110 translation_rotation->SetTranslation(0, vertical_displacement, z_pos);
111 translation_rotation->SetRotation(rot_zero);
115 translation_rotation->SetTranslation(vertical_displacement, 0, z_pos);
116 translation_rotation->SetRotation(rot_90);
118 neuland->AddNode(bar_, module_id + 1, translation_rotation);
124 void Creator::construct_all_volumes()
126 scintillator_ = build_scintillator();
127 Al_wrapping_ = build_Al_wrapping();
128 tape_wrapping_ = build_tape_wrapping();
129 bar_ = build_bar_volume();
132 void Creator::construct_all_material()
134 material_BC408_ = build_material(
"BC408");
135 material_poly_ = build_material(
"polyethylene");
136 material_Al_ = build_material(
"aluminium");
139 void Creator::construct_all_shapes()
141 auto dimension = BarDimension{};
147 shape_scintillator_ = build_bar_shape(
"shapeBC408", dimension);
151 auto* shape_Al_solid = build_bar_shape(
"shapeAlWrappingSolid", dimension);
152 shape_Al_wrapping_ = TGeoManagerCreate<TGeoCompositeShape>(
154 fmt::format(
"{} - {}", shape_Al_solid->GetName(), shape_scintillator_->GetName()).c_str());
158 auto* shape_tape_solid = build_bar_shape(
"shapeTapeWrappingSolid", dimension);
159 shape_tape_wrapping_ = TGeoManagerCreate<TGeoCompositeShape>(
161 fmt::format(
"{} - {}", shape_tape_solid->GetName(), shape_Al_solid->GetName()).c_str());
164 auto Creator::build_bar_volume() -> TGeoVolume*
166 auto* bar = TGeoManagerCreate<TGeoVolumeAssembly>(
"volPaddle");
167 bar->AddNode(scintillator_, 1);
168 bar->AddNode(Al_wrapping_, 1);
169 bar->AddNode(tape_wrapping_, 1);
173 auto Creator::build_scintillator() -> TGeoVolume*
175 auto* scintillator = TGeoManagerCreate<TGeoVolume>(
"volBC408", shape_scintillator_, material_BC408_);
176 static constexpr auto greyish_blue = 33;
177 static constexpr auto transparency = 30;
178 scintillator->SetLineColor(greyish_blue);
179 scintillator->SetTransparency(transparency);
183 auto Creator::build_Al_wrapping() -> TGeoVolume*
185 auto* Al_wrapping = TGeoManagerCreate<TGeoVolume>(
"volAlWrapping", shape_Al_wrapping_, material_Al_);
186 static constexpr auto greyish_silver = 17;
187 Al_wrapping->SetLineColor(greyish_silver);
191 auto Creator::build_tape_wrapping() -> TGeoVolume*
193 auto* tape_wrapping = TGeoManagerCreate<TGeoVolume>(
"volTapeWrapping", shape_tape_wrapping_, material_poly_);
194 static constexpr auto black = 1;
195 tape_wrapping->SetLineColor(black);
196 return tape_wrapping;
199 auto Creator::build_material(
const std::string& material_name) -> TGeoMedium*
201 auto* fair_medium = geo_media_->getMedium(material_name.c_str());
202 if (fair_medium ==
nullptr)
204 R3BLOG(error, fmt::format(
"FairGeoMedium {} not found!", material_name));
207 if (geo_builder_ ==
nullptr)
209 throw R3B::runtime_error(
"geo_builder is nullptr!");
211 geo_builder_->createMedium(fair_medium);
212 if (gGeoManager ==
nullptr)
214 throw R3B::runtime_error(
"gGeoManager is nullptr!");
216 auto* material = gGeoManager->GetMedium(material_name.c_str());
217 if (material ==
nullptr)
219 R3BLOG(error, fmt::format(
"TGeoMedium {} not found!", material_name));
224 void Creator::read_material_from_file(FairGeoLoader* geo_loader)
226 auto* geo_interface = geo_loader->getGeoInterface();
227 const auto working_dir = std::string{ std::getenv(
"VMCWORKDIR") };
228 if (working_dir.empty())
230 throw R3B::logic_error(
"Environment variable \"VMCWORKDIR\" is not defined!");
232 geo_interface->setMediaFile(fmt::format(
"{}/geometry/media_r3b.geo", working_dir).c_str());
233 geo_interface->readMedia();
235 geo_builder_ = geo_loader->getGeoBuilder();
236 geo_media_ = geo_interface->getMedia();