9#include <structure/geometry/GeoServiceMaterialCreator.h>
10#include <geometry/CreatorFactory.h>
11#include <geometry/Materials.h>
12#include <simulation/background/BkgSensitiveDetector.h>
13#include <framework/gearbox/GearDir.h>
14#include <framework/logging/Logger.h>
15#include <G4Transform3D.hh>
16#include <G4LogicalVolume.hh>
17#include <G4PVPlacement.hh>
18#include "G4Polycone.hh"
34 using namespace geometry;
46 GearDir content0(content,
"GapMomVolTopBack");
50 const double rmin = GapVol.getLength(
"Rmin") /
Unit::mm;
51 const double rmax = GapVol.getLength(
"Rmax") /
Unit::mm;
52 const double z = GapVol.getLength(
"Z") /
Unit::mm;
57 GearDir content1(content,
"GapMomVolEclCoilBarrel");
61 const double rmin = GapVol.getLength(
"Rmin") /
Unit::mm;
62 const double rmax = GapVol.getLength(
"Rmax") /
Unit::mm;
63 const double z = GapVol.getLength(
"Z") /
Unit::mm;
64 MomVolEclCoilBarrelPar.
appendNode(rmin, rmax, z);
68 GearDir content2(content,
"GapMomVolBack");
72 const double rmin = GapVol.getLength(
"Rmin") /
Unit::mm;
73 const double rmax = GapVol.getLength(
"Rmax") /
Unit::mm;
74 const double z = GapVol.getLength(
"Z") /
Unit::mm;
79 GearDir content3(content,
"GapMomVolFor");
83 const double rmin = GapVol.getLength(
"Rmin") /
Unit::mm;
84 const double rmax = GapVol.getLength(
"Rmax") /
Unit::mm;
85 const double z = GapVol.getLength(
"Z") /
Unit::mm;
88 ServiceMaterialGeometryPar.
getMomVolFor() = MomVolForPar;
90 GearDir content4(content,
"ServiceGapsMaterials");
92 for (
const GearDir& material : content4.
getNodes(
"ServiceGapsMaterial")) {
94 material.getString(
"Name"),
95 material.getString(
"material"),
96 material.getInt(
"@id", 0),
97 material.getLength(
"InnerR"),
98 material.getLength(
"OuterR"),
99 material.getLength(
"BackwardZ"),
100 material.getLength(
"ForwardZ")
105 GearDir content5(content,
"ServiceGapsEclMaterials");
107 for (
const GearDir& material : content5.
getNodes(
"ServiceGapsMaterial")) {
109 material.getString(
"Name"),
110 material.getString(
"material"),
111 material.getInt(
"@id", 0),
112 material.getLength(
"InnerR1"),
113 material.getLength(
"OuterR1"),
114 material.getLength(
"InnerR2"),
115 material.getLength(
"OuterR2"),
116 material.getLength(
"BackwardZ"),
117 material.getLength(
"ForwardZ")
122 GearDir content6(content,
"TicknessDensity");
125 content6.
getInt(
"IRCDCBack"),
126 content6.
getInt(
"IPhiCDCBack"),
127 content6.
getInt(
"IRCDCFor"),
128 content6.
getInt(
"IPhiCDCFor"),
129 content6.
getInt(
"IRECLBack"),
130 content6.
getInt(
"IZECLBack"),
131 content6.
getInt(
"IPhiECLBack"),
132 content6.
getInt(
"IRECLFor"),
133 content6.
getInt(
"IZECLFor"),
134 content6.
getInt(
"IPhiECLFor"),
135 content6.
getInt(
"IZARICHFor"),
136 content6.
getInt(
"IPhiARICHFor"),
137 content6.
getInt(
"IPhiTOPBack"),
138 content6.
getInt(
"IPhiTOPFor"),
139 content6.
getInt(
"IZECLCOILBar"),
140 content6.
getInt(
"IPhiECLCOILBar"),
143 ServiceMaterialGeometryPar.
getthick() = ThickPar;
146 return ServiceMaterialGeometryPar;
154 const auto& MomVolFor = parameters.getMomVolFor();
155 std::vector<double> motherforRmin = MomVolFor.getRmin();
156 std::vector<double> motherforRmax = MomVolFor.getRmax();
157 std::vector<double> motherforZ = MomVolFor.getZ() ;
159 G4Polycone* solid_gap_for =
new G4Polycone(
"ServiceMaterial.GAPFor", 0 * CLHEP::deg, 360.* CLHEP::deg, MomVolFor.getNNodes(),
160 motherforZ.data(), motherforRmin.data(), motherforRmax.data());
161 G4LogicalVolume* logical_gap_for =
new G4LogicalVolume(solid_gap_for, medAir,
"ServiceMaterial.GAPFor", 0, 0, 0);
162 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), logical_gap_for,
"ServiceMaterial.GAPFor", &topVolume,
false, 1);
164 const auto& MomVolBack = parameters.getMomVolBack();
165 std::vector<double> motherbackRmin = MomVolBack.getRmin();
166 std::vector<double> motherbackRmax = MomVolBack.getRmax();
167 std::vector<double> motherbackZ = MomVolBack.getZ();
169 G4Polycone* solid_gap_back =
new G4Polycone(
"ServiceMaterial.GAPBack", 0 * CLHEP::deg, 360.* CLHEP::deg, MomVolBack.getNNodes(),
170 motherbackZ.data(), motherbackRmin.data(), motherbackRmax.data());
171 G4LogicalVolume* logical_gap_back =
new G4LogicalVolume(solid_gap_back, medAir,
"ServiceMaterial.GAPBack", 0, 0, 0);
172 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), logical_gap_back,
"ServiceMaterial.GAPBack", &topVolume,
false, 1);
174 const auto& MomVolTopBack = parameters.getMomVolTopBack();
175 std::vector<double> mothertopbackRmin = MomVolTopBack.getRmin();
176 std::vector<double> mothertopbackRmax = MomVolTopBack.getRmax();
177 std::vector<double> mothertopbackZ = MomVolTopBack.getZ();
179 G4Polycone* solid_gap_topback =
new G4Polycone(
"ServiceMaterial.GAPTopBack", 0 * CLHEP::deg, 360.* CLHEP::deg,
180 MomVolTopBack.getNNodes(),
181 mothertopbackZ.data(), mothertopbackRmin.data(), mothertopbackRmax.data());
182 G4LogicalVolume* logical_gap_topback =
new G4LogicalVolume(solid_gap_topback, medAir,
"ServiceMaterial.GAPTopBack", 0, 0, 0);
183 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), logical_gap_topback,
"ServiceMaterial.GAPTopBack", &topVolume,
false, 1);
185 const auto& MomVolEclCoilBarrel = parameters.getMomVolEclCoilBarrel();
186 std::vector<double> mothereclcoilbarrelRmin = MomVolEclCoilBarrel.getRmin();
187 std::vector<double> mothereclcoilbarrelRmax = MomVolEclCoilBarrel.getRmax();
188 std::vector<double> mothereclcoilbarrelZ = MomVolEclCoilBarrel.getZ();
190 G4Polycone* solid_gap_eclcoilbarrel =
new G4Polycone(
"ServiceMaterial.GAPEclCoilBarrel", 0 * CLHEP::deg, 360.* CLHEP::deg,
191 MomVolEclCoilBarrel.getNNodes(),
192 mothereclcoilbarrelZ.data(), mothereclcoilbarrelRmin.data(), mothereclcoilbarrelRmax.data());
193 G4LogicalVolume* logical_gap_eclcoilbarrel =
new G4LogicalVolume(solid_gap_eclcoilbarrel, medAir,
194 "ServiceMaterial.GAPEclCoilBarrel", 0, 0, 0);
195 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, 0.0), logical_gap_eclcoilbarrel,
"ServiceMaterial.GAPEclCoilBarrel", &topVolume,
false,
198 const auto& Thick = parameters.getthick();
199 std::vector<double> Thickness = Thick.getthickness();
200 int IRCDCB = Thick.getIRCDCB();
201 int IPhiCDCB = Thick.getIPhiCDCB();
202 int IRCDCF = Thick.getIRCDCF();
203 int IPhiCDCF = Thick.getIPhiCDCF();
204 int IRECLB = Thick.getIRECLB();
205 int IZECLB = Thick.getIZECLB();
206 int IPhiECLB = Thick.getIPhiECLB();
207 int IRECLF = Thick.getIRECLF();
208 int IZECLF = Thick.getIZECLF();
209 int IPhiECLF = Thick.getIPhiECLF();
210 int IZARICHF = Thick.getIZARICHF();
211 int IPhiARICHF = Thick.getIPhiARICHF();
212 int IPhiTOPB = Thick.getIPhiTOPB();
213 int IPhiTOPF = Thick.getIPhiTOPF();
214 int IPhiECLCOILB = Thick.getIPhiECLCOILB();
215 int IZECLCOILB = Thick.getIZECLCOILB();
218 const int materialID = material.getIdentifier();
219 const double materialInnerR = material.getInnerR() /
Unit::mm;
220 const double materialOuterR = material.getOuterR() /
Unit::mm;
221 const double materialBackwardZ = material.getBackwardZ() /
Unit::mm;
222 const double materialForwardZ = material.getForwardZ() /
Unit::mm;
224 if (materialID < 2) {
226 double IR = 0, IPhi = 0;
227 if (materialID < 1) {IR = IRCDCB; IPhi = IPhiCDCB;}
228 else {IR = IRCDCF; IPhi = IPhiCDCF;}
229 const double cellR = (materialOuterR - materialInnerR) / IRCDCB;
230 for (
int iR = 0; iR < IR; iR++) {
231 const double rmin = materialInnerR + iR * cellR;
232 const double rmax = materialInnerR + (iR + 1) * cellR;
233 for (
int iPhi = 0; iPhi < IPhi; iPhi++) {
234 const double SPhi = 360. / IPhi * iPhi;
235 const double DPhi = 360. / IPhi;
236 if (materialID < 1) {
237 const string storageName =
"Service_CDC_ECL_Bwd_" + to_string(iR) +
"_" + to_string(iPhi);
238 const double materialThick = Thickness[blockid] /
Unit::mm;
239 const double materialPosZ = materialForwardZ - materialThick;
241 createTube(rmin, rmax, SPhi, DPhi, materialThick, materialPosZ, mCDCGapback, storageName, logical_gap_back);
243 if (materialID >= 1) {
244 const string storageName =
"Service_CDC_ARICH_Fwd_" + to_string(iR) +
"_" + to_string(iPhi);
245 const double materialThick = Thickness[blockid + IRCDCB * IPhiCDCB] /
Unit::mm;
246 const double materialPosZ = materialBackwardZ;
248 createTube(rmin, rmax, SPhi, DPhi, materialThick, materialPosZ, mCDCGapfor, storageName, logical_gap_for);
255 if (materialID == 2) {
257 const double materialThick = fabs(materialForwardZ - materialBackwardZ) / IZARICHF;
258 for (
int iZ = 0; iZ < IZARICHF; iZ++) {
259 const double rmax = materialOuterR;
260 const double materialPosZ = materialBackwardZ + iZ * materialThick;
261 for (
int iPhi = 0; iPhi < IPhiARICHF; iPhi++) {
262 const double SPhi = 360. / IPhiARICHF * iPhi;
263 const double DPhi = 360. / IPhiARICHF;
264 const double materialRThick = Thickness[blockid + IRCDCB * IPhiCDCB + IRCDCF * IPhiCDCF] /
Unit::mm;
265 const double rmin = rmax - materialRThick;
267 const string storageName =
"Service_ARICH_TOP_Fwd_" + to_string(iZ) +
"_" + to_string(iPhi);
268 createTube(rmin, rmax, SPhi, DPhi, materialThick, materialPosZ, ArichAir, storageName, logical_gap_for);
274 if (materialID >= 3 && materialID < 5) {
277 if (materialID == 3) {IPhiTOP = IPhiTOPB;}
278 else {IPhiTOP = IPhiTOPF;}
279 const double rmin = materialInnerR;
280 const double rmax = materialOuterR;
281 for (
int iPhi = 0; iPhi < IPhiTOP; iPhi++) {
282 const double SPhi = 360. / IPhiTOP * iPhi;
283 const double DPhi = 360. / IPhiTOP;
284 if (materialID == 3) {
285 const double materialThick = Thickness[blockid + IRCDCB * IPhiCDCB + IRCDCF * IPhiCDCF + IZARICHF * IPhiARICHF] /
Unit::mm;
286 const double materialPosZ = materialForwardZ - materialThick;
288 const string storageName =
"Service_TOP_ECL_Bwd_" + to_string(iPhi);
289 createTube(rmin, rmax, SPhi, DPhi, materialThick, materialPosZ, TopbackAir, storageName, logical_gap_topback);
291 if (materialID == 4) {
292 const double materialThick = Thickness[blockid + IRCDCB * IPhiCDCB + IRCDCF * IPhiCDCF + IZARICHF * IPhiARICHF + IPhiTOPB] /
294 const double materialPosZ = materialBackwardZ;
296 const string storageName =
"Service_TOP_ECL_Fwd_" + to_string(iPhi);
297 createTube(rmin, rmax, SPhi, DPhi, materialThick, materialPosZ, TopforAir, storageName, logical_gap_for);
303 if (materialID == 5) {
305 const double materialThick = fabs(materialForwardZ - materialBackwardZ) / IZECLCOILB;
306 for (
int iZ = 0; iZ < IZECLCOILB; iZ++) {
307 const double rmin = materialInnerR;
308 const double materialPosZ = materialBackwardZ + iZ * materialThick;
309 for (
int iPhi = 0; iPhi < IPhiECLCOILB; iPhi++) {
310 const double SPhi = 360. / IPhiECLCOILB * iPhi;
311 const double DPhi = 360. / IPhiECLCOILB;
312 const double materialRThick = Thickness[blockid + IRCDCB * IPhiCDCB + IRCDCF * IPhiCDCF + IZARICHF * IPhiARICHF + IPhiTOPB +
314 const double rmax = rmin + materialRThick;
316 const string storageName =
"Service_ECL_COIL_Barrel_" + to_string(iZ) +
"_" + to_string(iPhi);
317 createTube(rmin, rmax, SPhi, DPhi, materialThick, materialPosZ, EclCoilAir, storageName, logical_gap_eclcoilbarrel);
327 int IRECL = 0, IZECL = 0, IPhiECL = 0;
328 const int materialID = material.getIdentifier();
329 if (materialID < 1) {IRECL = IRECLB; IZECL = IZECLB; IPhiECL = IPhiECLB;}
330 else {IRECL = IRECLF; IZECL = IZECLF; IPhiECL = IPhiECLF;}
331 const double materialInnerR1 = material.getInnerR1() /
Unit::mm;
332 const double materialOuterR1 = material.getOuterR1() /
Unit::mm;
333 const double materialInnerR2 = material.getInnerR2() /
Unit::mm;
334 const double materialOuterR2 = material.getOuterR2() /
Unit::mm;
335 const double materialBackwardZ = material.getBackwardZ() /
Unit::mm;
336 const double materialForwardZ = material.getForwardZ() /
Unit::mm;
337 const double interval = (materialForwardZ - materialBackwardZ) / IZECL ;
338 const double Hf1 = (materialOuterR1 - materialInnerR1) / IRECL;
339 const double Hf2 = (materialOuterR2 - materialInnerR2) / IRECL;
340 for (
int iR = 0; iR < IRECL; iR++) {
341 const double Rmin1 = materialInnerR1 + Hf1 * iR;
342 const double Rmax1 = materialInnerR1 + Hf1 * (iR + 1);
343 const double Rmin2 = materialInnerR2 + Hf2 * iR;
344 const double Rmax2 = materialInnerR2 + Hf2 * (iR + 1);
345 const double Hrmax = (Rmax2 - Rmax1) / IZECL;
346 const double Hrmin = (Rmin2 - Rmin1) / IZECL;
347 for (
int iZ = 0; iZ < IZECL; iZ++) {
348 const double BackwardposZ = materialBackwardZ + interval * iZ;
349 const double ForwardposZ = materialBackwardZ + interval * (iZ + 1);
350 for (
int iPhi = 0; iPhi < IPhiECL; iPhi++) {
351 const double SPhi = (360. / IPhiECL) * iPhi;
352 const double DPhi = 360. / IPhiECL;
353 if (materialID == 0) {
354 const double thick = Thickness[blockid + IRCDCB * IPhiCDCB + IRCDCF * IPhiCDCF + IZARICHF * IPhiARICHF + IPhiTOPB + IPhiTOPF +
355 IPhiECLCOILB * IZECLCOILB] /
Unit::mm;
356 const double rmin2 = Rmin1 + Hrmin * (iZ + 1);
357 const double rmax2 = Rmax1 + Hrmax * (iZ + 1);
358 const double rmin1 = rmin2 - Hrmin * thick / interval ;
359 const double rmax1 = rmax2 - Hrmax * thick / interval ;
360 const double posZ = ForwardposZ - thick;
362 const string storageName =
"Service_ECLGAPS_Bwd_" + to_string(iR) +
"_" + to_string(iZ) +
"_" + to_string(iPhi);
363 createCone(rmin1, rmax1, rmin2, rmax2, thick, SPhi, DPhi, posZ, ECLbackAir, storageName, logical_gap_back);
365 if (materialID == 1) {
366 const double thick = Thickness[blockid + IRCDCB * IPhiCDCB + IRCDCF * IPhiCDCF + IZARICHF * IPhiARICHF + IPhiTOPB + IPhiTOPF +
367 IPhiECLCOILB * IZECLCOILB + IZECLB * IRECLB * IPhiECLB ] /
Unit::mm;
368 const double rmin1 = Rmin1 + Hrmin * iZ;
369 const double rmax1 = Rmax1 + Hrmax * iZ;
370 const double rmin2 = rmin1 + Hrmin * thick / interval;
371 const double rmax2 = rmax1 + Hrmax * thick / interval;
372 const double posZ = BackwardposZ;
374 const string storageName =
"Service_ECLGAPS_Fwd_" + to_string(iR) +
"_" + to_string(iZ) +
"_" + to_string(iPhi);
375 createCone(rmin1, rmax1, rmin2, rmax2, thick, SPhi, DPhi, posZ, ECLforAir, storageName, logical_gap_for);
385 const double thick,
const double posZ, G4Material* med,
const string& name, G4LogicalVolume*& logical_gap)
387 const string solidName =
"solid_" + name;
388 const string logicalName =
"logical_" + name;
389 const string physicalName =
"physical_" + name;
390 G4Tubs* solidV =
new G4Tubs(solidName.c_str(), rmin * CLHEP::mm, rmax * CLHEP::mm,
391 thick * CLHEP::mm / 2.0, SPhi * CLHEP::deg, DPhi * CLHEP::deg);
392 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med, logicalName.c_str(), 0, 0, 0);
393 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::mm + thick * CLHEP::mm / 2.0), logicalV,
394 physicalName.c_str(), logical_gap,
false, 0);
399 const double thick,
const double SPhi,
const double DPhi,
const double posZ, G4Material* med,
400 const string& name, G4LogicalVolume*& top)
402 const string solidName =
"solid" + name;
403 const string logicalName =
"logical" + name;
404 const string physicalName =
"physical" + name;
405 G4Cons* storageConeShape =
new G4Cons(solidName.c_str(), rmin1 * CLHEP::mm, rmax1 * CLHEP::mm, rmin2 * CLHEP::mm,
406 rmax2 * CLHEP::mm, thick * CLHEP::mm / 2.0, SPhi * CLHEP::deg, DPhi * CLHEP::deg);
407 G4LogicalVolume* storageCone =
new G4LogicalVolume(storageConeShape, med, logicalName.c_str(), 0, 0, 0);
408 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::mm + thick * CLHEP::mm / 2.0), storageCone, physicalName.c_str(), top,
GearDir is the basic class used for accessing the parameter store.
The Class for Service Materials between CDC and ECL, ARICH and TOP, TOP and ECL.
The Class for Service Materials between barrel and endcap of ECL.
The Class for services materials geometry.
const std::vector< ServiceGapsMaterialsEclPar > & getServiceGapsEclMaterials(void) const
Get Service Materials at ECL.
const ServiceGapsMomVolPar & getMomVolBack(void) const
Get Backward Gap MomVolume.
const ThicknessDensityPar & getthick(void) const
Get Gap element cell Thickness.
const ServiceGapsMomVolPar & getMomVolFor(void) const
Get Forward Gap MomVolume.
const std::vector< ServiceGapsMaterialsCdcArichTopPar > & getServiceGapsMaterials(void) const
Get Service Materials.
const ServiceGapsMomVolPar & getMomVolEclCoilBarrel(void) const
Get Barrel ECL and Coil Gap MomVolume.
const ServiceGapsMomVolPar & getMomVolTopBack(void) const
Get Backward Top Gap MomVolume.
The class for the mother volume of the Service Materials.
void appendNode(double rmin, double rmax, double z)
Append a new node.
The class for the thicknesses and the density of gap element cell.
static const double mm
[millimeters]
std::vector< double > getArray(const std::string &path) const noexcept(false)
Get the parameter path as a list of double values converted to the standard unit.
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
int getInt(const std::string &path="") const noexcept(false)
Get the parameter path as a int.
static G4Material * get(const std::string &name)
Find given material.
ServiceGapsMaterialsPar createConfiguration(const GearDir ¶m)
Create a parameter object from the Gearbox XML parameters.
void createTube(const double rmin, const double rmax, const double SPhi, const double DPhi, const double thick, const double posZ, G4Material *med, const std::string &name, G4LogicalVolume *&top)
Create G4Tube.
void createGeometry(const ServiceGapsMaterialsPar ¶meters, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Create the geometry from a parameter object.
void createCone(const double rmin1, const double rmax1, const double rmin2, const double rmax2, const double thick, const double SPhi, const double DPhi, const double posz, G4Material *med, const std::string &name, G4LogicalVolume *&top)
Create G4Cone.
GeometryTypes
Flag indiciating the type of geometry to be used.
geometry::CreatorFactory< GeoServiceMaterialCreator > GeoServiceMaterialFactory("ServiceMaterialCreator")
Create factory instance so that the framework can instantiate the ServiceMaterialCreator.
Abstract base class for different kinds of events.
Very simple class to provide an easy way to register creators with the CreatorManager.