10 #include "GaudiKernel/ISvcLocator.h"
11 #include "GaudiKernel/MsgStream.h"
12 #include "GaudiKernel/IMessageSvc.h"
13 #include "GaudiKernel/SystemOfUnits.h"
16 #include "GeoModelKernel/GeoMaterial.h"
17 #include "GeoModelKernel/GeoFullPhysVol.h"
18 #include "GeoModelKernel/GeoPhysVol.h"
19 #include "GeoModelKernel/GeoLogVol.h"
20 #include "GeoModelKernel/GeoTransform.h"
21 #include "GeoModelKernel/GeoSerialTransformer.h"
22 #include "GeoModelKernel/GeoTube.h"
23 #include "GeoModelKernel/GeoBox.h"
24 #include "GeoModelKernel/GeoPcon.h"
25 #include "GeoModelKernel/GeoTrd.h"
26 #include "GeoModelKernel/GeoShape.h"
27 #include "GeoModelKernel/GeoShapeUnion.h"
28 #include "GeoModelKernel/GeoShapeShift.h"
29 #include "GeoModelKernel/GeoShapeSubtraction.h"
30 #include "GeoModelKernel/GeoDefinitions.h"
39 #include "GeoGenericFunctions/Variable.h"
50 ISvcLocator* svcLocator = Gaudi::svcLocator();
51 IMessageSvc*
msgSvc(
nullptr);
52 if(svcLocator->service(
"MessageSvc",
msgSvc,
true)==StatusCode::FAILURE)
53 throw std::runtime_error(
"Error in EndcapDMConstruction, cannot access MessageSvc");
54 MsgStream
log(
msgSvc,
"EndcapDMConstruction");
55 log << MSG::INFO <<
"Start building EC electronics geometry" <<
endmsg;
58 if(svcLocator->service(
"DetectorStore",
detStore,
false)==StatusCode::FAILURE)
59 throw std::runtime_error(
"Error in EndcapDMConstruction, cannot access DetectorStore");
62 if(svcLocator->service(
"GeoModelSvc",geoModel) == StatusCode::FAILURE)
63 throw std::runtime_error(
"Error in EndcapDMConstruction, cannot access GeoModelSvc");
66 if(svcLocator->service(
"RDBAccessSvc",rdbAccess) == StatusCode::FAILURE)
67 throw std::runtime_error(
"Error in EndcapDMConstruction, cannot access RDBAccessSvc");
71 if(StatusCode::SUCCESS !=
detStore->retrieve(materialManager, std::string(
"MATERIALS")))
72 throw std::runtime_error(
"Error in EndcapDMConstruction, stored MaterialManager is not found");
75 if(LArEndcapCrate->size()==0) {
76 log << MSG::INFO <<
"Skip building EC electronics. Database flag not set" <<
endmsg;
85 std::map<std::string, unsigned int> boxMap;
86 for(
unsigned int j=0; j<BarrelDMBoxes->size(); j++) {
87 const std::string&
key = (*BarrelDMBoxes)[j]->getString(
"BOXNAME");
90 std::map<std::string, unsigned int> tubeMap;
91 for(
unsigned int i=0;
i<BarrelDMTubes->size();
i++) {
92 const std::string&
key = (*BarrelDMTubes)[
i]->getString(
"TUBENAME");
95 std::map<std::string, unsigned int> ecCrateMap;
96 for(
unsigned int i=0;
i<LArEndcapCrate->size();
i++) {
97 const std::string&
key = (*LArEndcapCrate)[
i]->getString(
"BOXNAME");
101 unsigned int recordIndex;
104 const GeoMaterial *alu = materialManager->
getMaterial(
"std::Aluminium");
105 const GeoMaterial* matBoardsEnvelope = materialManager->
getMaterial(
"LAr::BoardsEnvelope");
108 recordIndex = tubeMap[
"Ped2"];
109 double ped2zhlen = (*BarrelDMTubes)[recordIndex]->getDouble(
"ZHLEN");
110 double ped2minr = (*BarrelDMTubes)[recordIndex]->getDouble(
"MINR");
111 double ped2maxr = (*BarrelDMTubes)[recordIndex]->getDouble(
"MAXR");
112 double ped2ytr = (*BarrelDMTubes)[recordIndex]->getDouble(
"YTR");
113 recordIndex = tubeMap[
"Ped3"];
114 double ped3zhlen = (*BarrelDMTubes)[recordIndex]->getDouble(
"ZHLEN");
115 double ped3minr = (*BarrelDMTubes)[recordIndex]->getDouble(
"MINR");
116 double ped3maxr = (*BarrelDMTubes)[recordIndex]->getDouble(
"MAXR");
117 double ped3xtr = (*BarrelDMTubes)[recordIndex]->getDouble(
"XTR");
119 recordIndex = boxMap[
"Pedest"];
120 double pedesthlen = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HLEN");
121 double pedesthwdt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HWDT");
122 double pedesthhgt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HHGT");
123 double pedestxtr = (*BarrelDMBoxes)[recordIndex]->getDouble(
"XTR");
124 double pedestztr = (*BarrelDMBoxes)[recordIndex]->getDouble(
"ZTR");
125 recordIndex = boxMap[
"Ped1"];
126 double ped1hlen = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HLEN");
127 double ped1hwdt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HWDT");
128 double ped1hhgt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HHGT");
129 recordIndex = boxMap[
"Crate1"];
130 double crate1hlen = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HLEN");
131 double crate1hwdt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HWDT");
132 double crate1hhgt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HHGT");
133 double crate1xtr = (*BarrelDMBoxes)[recordIndex]->getDouble(
"XTR");
134 double crate1ztr = (*BarrelDMBoxes)[recordIndex]->getDouble(
"ZTR");
135 recordIndex = boxMap[
"Crate2"];
136 double crate2hlen = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HLEN");
137 double crate2hwdt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HWDT");
138 double crate2hhgt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HHGT");
139 recordIndex = boxMap[
"Crate3"];
140 double crate3hlen = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HLEN");
141 double crate3hwdt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HWDT");
142 double crate3hhgt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HHGT");
143 double crate3xtr = (*BarrelDMBoxes)[recordIndex]->getDouble(
"XTR");
144 recordIndex = boxMap[
"BoardE"];
145 double BoardEhlen = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HLEN");
146 double BoardEhwdt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HWDT");
147 double BoardEhhgt = (*BarrelDMBoxes)[recordIndex]->getDouble(
"HHGT");
148 double BoardExtr = (*BarrelDMBoxes)[recordIndex]->getDouble(
"XTR");
149 double BoardEytr = (*BarrelDMBoxes)[recordIndex]->getDouble(
"YTR");
150 double BoardEztr = (*BarrelDMBoxes)[recordIndex]->getDouble(
"ZTR");
153 std::map<std::string, unsigned int>::const_iterator
it = ecCrateMap.find(
"Crate1");
154 if(
it != ecCrateMap.end()) {
155 recordIndex = ecCrateMap[
"Crate1"];
156 double ztrEC = (*LArEndcapCrate)[recordIndex]->getDouble(
"ZTR");
158 if(m_activateFT && ztrEC == -249.05){
161 <<
" to fit mother volume" <<
endmsg;
170 double xtrEC = (*LArEndcapCrate)[recordIndex]->getDouble(
"XTR");
175 it = ecCrateMap.find(
"Pedest");
176 if(
it!=ecCrateMap.end()) {
177 recordIndex = ecCrateMap[
"Pedest"];
178 pedestxtr = (*LArEndcapCrate)[recordIndex]->getDouble(
"XTR");
180 it = ecCrateMap.find(
"BoardE");
181 if(
it!=ecCrateMap.end()) {
182 recordIndex = ecCrateMap[
"BoardE"];
183 BoardExtr = (*LArEndcapCrate)[recordIndex]->getDouble(
"XTR");
187 const double epsilon = m_activateFT? 0.: 6.;
190 GeoBox *Pedestal =
new GeoBox(pedesthlen, pedesthwdt, pedesthhgt - epsilon);
191 GeoBox *Ped1 =
new GeoBox(ped1hlen, ped1hwdt, ped1hhgt - epsilon);
192 GeoTube *Ped2 =
new GeoTube(ped2minr, ped2maxr, ped2zhlen);
193 GeoTube *Ped3 =
new GeoTube(ped3minr,ped3maxr , ped3zhlen);
194 const GeoShape & CratePed=((*Pedestal).subtract(*Ped1).
195 subtract((*Ped2) <<GeoTrf::TranslateY3D(-ped2ytr)*GeoTrf::RotateY3D(90*
Gaudi::Units::deg)).
196 subtract((*Ped3) <<GeoTrf::TranslateX3D(-ped3xtr)).
197 subtract((*Ped2) <<GeoTrf::TranslateY3D(ped2ytr)*GeoTrf::RotateY3D(90*
Gaudi::Units::deg)));
199 GeoLogVol *lvped =
new GeoLogVol(
"LAr::DM::Ped",&CratePed,alu);
200 GeoIntrusivePtr<GeoPhysVol>pedestal =
new GeoPhysVol(lvped);
203 GeoBox *Crate1 =
new GeoBox(crate1hlen, crate1hwdt, crate1hhgt - epsilon);
204 GeoBox *Crate2 =
new GeoBox(crate2hlen, crate2hwdt, crate2hhgt - epsilon);
205 GeoBox *Crate3 =
new GeoBox(crate3hlen, crate3hwdt, crate3hhgt - epsilon);
206 const GeoShape & FEBCrate=(*Crate1).subtract(*Crate2).add((*Crate3) <<GeoTrf::TranslateX3D(-crate3xtr));
208 GeoLogVol *lvcrate =
new GeoLogVol(
"LAr::DM::Crate",&FEBCrate,alu);
209 GeoIntrusivePtr<GeoPhysVol>crate =
new GeoPhysVol(lvcrate);
212 GeoBox *BoardEnvelope =
new GeoBox(BoardEhlen, BoardEhwdt, BoardEhhgt - epsilon);
213 GeoLogVol *lvbenv =
new GeoLogVol(
"LAr::DM::FEBoard",BoardEnvelope,matBoardsEnvelope);
214 GeoIntrusivePtr<GeoPhysVol>boardenvelope =
new GeoPhysVol(lvbenv);
217 GeoTransform* xfCrateBase(
new GeoTransform(GeoTrf::TranslateX3D(crate1xtr)*GeoTrf::TranslateZ3D(crate1ztr)));
218 GeoTransform* xfPedestBase(
new GeoTransform(GeoTrf::TranslateX3D(pedestxtr)*GeoTrf::TranslateZ3D(pedestztr)));
219 GeoTransform* xfBoardEBase1(
new GeoTransform(GeoTrf::TranslateY3D(BoardEytr)*GeoTrf::TranslateX3D(BoardExtr)*GeoTrf::TranslateZ3D(BoardEztr)));
220 GeoTransform* xfBoardEBase2(
new GeoTransform(GeoTrf::TranslateY3D(-BoardEytr)*GeoTrf::TranslateX3D(BoardExtr)*GeoTrf::TranslateZ3D(BoardEztr)));
222 for(
unsigned i(0);
i<LArEndcapCratePhiPos->size(); ++
i) {
224 GeoTransform* xfPhiPos(
new GeoTransform(GeoTrf::RotateZ3D(phiPos)));
226 envelope->add(xfPhiPos);
227 envelope->add(xfCrateBase);
228 envelope->add(crate);
230 envelope->add(xfPhiPos);
231 envelope->add(xfPedestBase);
232 envelope->add(pedestal);
234 envelope->add(xfPhiPos);
235 envelope->add(xfBoardEBase1);
236 envelope->add(boardenvelope);
238 envelope->add(xfPhiPos);
239 envelope->add(xfBoardEBase2);
240 envelope->add(boardenvelope);
244 std::string
name =
"LAr::Endcap::SignalFT::";
247 const GeoMaterial* iron = materialManager->
getMaterial(
"std::Iron");
251 const GeoMaterial* wflange_mat = materialManager->
getMaterial(
"LAr::FT::WarmFlange");
253 GeoShape* wflange =
new GeoTube(0., wflange_R, wflange_height/2);
254 GeoLogVol* wflangeLV =
new GeoLogVol(
name +
"WarmFlange", wflange, wflange_mat);
255 GeoIntrusivePtr<GeoPhysVol> wflangePV =
new GeoPhysVol(wflangeLV);
260 const GeoMaterial* bellow_mat = materialManager->
getMaterial(
"LAr::FT::Bellow");
262 const double bellow_Rinner = bellow_Router - bellow_wall;
263 GeoShape* bellow =
new GeoTube(bellow_Rinner, bellow_Router, bellow_height/2);
264 GeoLogVol* bellowLV =
new GeoLogVol(
name +
"Bellow", bellow, bellow_mat);
265 GeoIntrusivePtr<GeoPhysVol> bellowPV =
new GeoPhysVol(bellowLV);
267 const GeoMaterial* vcables_mat = materialManager->
getMaterial(
"LAr::FT::VacuumCables");
269 GeoShape* vcables =
new GeoTube(0., bellow_Rinner, bellow_height/2);
270 GeoLogVol* vcablesLV =
new GeoLogVol(
name +
"VacuumCables", vcables, vcables_mat);
271 GeoIntrusivePtr<GeoPhysVol> vcablesPV =
new GeoPhysVol(vcablesLV);
275 const GeoMaterial* cflange_mat = materialManager->
getMaterial(
"LAr::FT::ColdFlange");
276 GeoShape* cflange =
new GeoTube(0., cflange_Router, cflange_height/2);
277 GeoLogVol* cflangeLV =
new GeoLogVol(
name +
"ColdFlange", cflange, cflange_mat);
278 GeoIntrusivePtr<GeoPhysVol> cflangePV =
new GeoPhysVol(cflangeLV);
280 const double coldbox1_Router = cflange_Router;
288 const GeoMaterial* coldbox_mat = iron;
289 GeoShape* coldbox1 =
new GeoTube(coldbox1_Router - coldbox1_wall, coldbox1_Router, coldbox1_height/2);
290 GeoShape* coldbox11 =
new GeoTube(0., coldbox1_Router, coldbox1_height/2);
291 GeoLogVol* coldbox1LV =
new GeoLogVol(
name +
"ColdBox1", coldbox1, coldbox_mat);
292 GeoIntrusivePtr<GeoPhysVol> coldbox1PV =
new GeoPhysVol(coldbox1LV);
293 GeoShape* coldbox21 =
new GeoTube(0., coldbox1_Router, coldbox2_height/2);
294 GeoShape* coldbox22 =
new GeoTube(0., hole_r, coldbox2_height);
295 const GeoShape& coldbox2 = coldbox21->subtract((*coldbox22) << GeoTrf::TranslateY3D(hole_shift));
296 GeoLogVol* coldbox2LV =
new GeoLogVol(
name +
"ColdBox2", &coldbox2, coldbox_mat);
297 GeoIntrusivePtr<GeoPhysVol> coldbox2PV =
new GeoPhysVol(coldbox2LV);
298 GeoShape* coldbox3 =
new GeoTube(hole_r, coldbox3_Router, coldbox3_height/2);
299 GeoShape* coldbox31 =
new GeoTube(0., coldbox3_Router, coldbox3_height/2);
300 GeoLogVol* coldbox3LV =
new GeoLogVol(
name +
"ColdBox3", coldbox3, coldbox_mat);
301 GeoIntrusivePtr<GeoPhysVol> coldbox3PV =
new GeoPhysVol(coldbox3LV);
303 GeoTrf::TranslateZ3D bellow_pos(-wflange_height/2 - bellow_height/2);
304 GeoTrf::TranslateZ3D cflange_pos(-wflange_height/2 - bellow_height - cflange_height/2);
305 GeoTrf::TranslateZ3D coldbox1_pos(-wflange_height/2 - bellow_height - cflange_height - coldbox1_height/2);
306 GeoTrf::TranslateZ3D coldbox2_pos(-wflange_height/2 - bellow_height - cflange_height - coldbox1_height - coldbox2_height/2);
307 GeoTrf::Translate3D coldbox2hole_pos(
309 -wflange_height/2 - bellow_height - cflange_height - coldbox1_height - coldbox2_height/2
311 GeoTrf::Translate3D coldbox3_pos(
313 -wflange_height/2 - bellow_height - cflange_height - coldbox1_height - coldbox2_height - coldbox3_height/2
316 const GeoShape& FTenvelope = wflange->add(
317 (*bellow) << bellow_pos
319 (*cflange) << cflange_pos
321 (*coldbox11) << coldbox1_pos
323 (*coldbox21) << coldbox2_pos
325 (*coldbox31) << coldbox3_pos
328 GeoLogVol* FTLV =
new GeoLogVol(
name +
"Envelope",
332 GeoIntrusivePtr<GeoPhysVol> FTPV =
new GeoPhysVol(FTLV);
334 FTPV->add(wflangePV);
335 GeoTransform *bellow_trf =
new GeoTransform(bellow_pos);
336 FTPV->add(bellow_trf);
338 FTPV->add(bellow_trf);
339 FTPV->add(vcablesPV);
340 GeoTransform *cflange_trf =
new GeoTransform(cflange_pos);
341 FTPV->add(cflange_trf);
342 FTPV->add(cflangePV);
343 GeoTransform *coldbox1_trf =
new GeoTransform(coldbox1_pos);
344 FTPV->add(coldbox1_trf);
345 FTPV->add(coldbox1PV);
346 GeoTransform *coldbox2_trf =
new GeoTransform(coldbox2_pos);
347 FTPV->add(coldbox2_trf);
348 FTPV->add(coldbox2PV);
349 GeoTransform *coldbox3_trf =
new GeoTransform(coldbox3_pos);
350 FTPV->add(coldbox3_trf);
351 FTPV->add(coldbox3PV);
353 const GeoMaterial* lar_mat = materialManager->
getMaterial(
"std::LiquidArgon");
354 GeoShape* lar1 =
new GeoTube(0., coldbox1_Router - coldbox1_wall, coldbox1_height/2);
355 GeoShape* lar2 =
new GeoTube(0., hole_r, coldbox1_height);
356 const GeoShape& lar = lar1->subtract((*lar2) << GeoTrf::TranslateY3D(hole_shift));
357 GeoLogVol* larLV =
new GeoLogVol(
name +
"LAr", &lar, lar_mat);
358 GeoIntrusivePtr<GeoPhysVol> larPV =
new GeoPhysVol(larLV);
359 FTPV->add(coldbox1_trf);
362 const GeoMaterial *pigtail_mat = materialManager->
getMaterial(
"LAr::FT::Pigtail");
364 const double pth = (coldbox1_height + coldbox2_height + coldbox3_height) / 2;
365 GeoTransform *pigtail_trf =
new GeoTransform(
366 GeoTrf::Translate3D(0, hole_shift,
367 -wflange_height/2 - bellow_height - cflange_height - pth
369 GeoShape* pigtail =
new GeoTube(0., hole_r, pth);
370 GeoLogVol* pigtailLV =
new GeoLogVol(
name +
"Pigtails", pigtail, pigtail_mat);
371 GeoIntrusivePtr<GeoPhysVol> pigtailPV =
new GeoPhysVol(pigtailLV);
372 FTPV->add(pigtail_trf);
373 FTPV->add(pigtailPV);
378 const GeoMaterial* ocable_mat = materialManager->
getMaterial(
"LAr::FT::Cable");
379 GeoShape* ocable =
new GeoTube(0., ocable_R, ocable_len / 2);
380 GeoLogVol* ocableLV =
new GeoLogVol(
"LAr::Endcap::FTCables", ocable, ocable_mat);
381 GeoIntrusivePtr<GeoPhysVol> ocablePV =
new GeoPhysVol(ocableLV);
386 const GeoMaterial* chimney_mat = iron;
387 GeoShape* chimney1 =
new GeoTube(chimney_Router - chimney_wall, chimney_Router, chimney_height/2);
390 GeoShape* chimney2 =
new GeoTube(chimney_Router, chimney_Router + ch_lowring_r, ch_lowring_h/2);
393 GeoShape* chimney3 =
new GeoTube(bellow_Router, chimney_Router + ch_upring_r, ch_upring_h/2);
394 const GeoShape& chimney = chimney1->add(
395 (*chimney2) << GeoTrf::TranslateZ3D(-chimney_height/2 + ch_lowring_h/2)
397 (*chimney3) << GeoTrf::TranslateZ3D(chimney_height/2 - ch_upring_h/2)
399 GeoLogVol* chimneyLV =
new GeoLogVol(
"LAr::Endcap::FTChimney", &chimney, chimney_mat);
400 GeoIntrusivePtr<GeoPhysVol> chimneyPV =
new GeoPhysVol(chimneyLV);
405 const double r0 = cryo_Router + chimney_height + wflange_height/2;
406 const double r1 = cryo_Router + chimney_height/2;
407 const double r2 = cryo_Router + chimney_height + wflange_height + ocable_len/2;
408 auto put1 = [&envelope, z_pos](GeoIntrusivePtr<GeoPhysVol>
object,
double r,
double phi)
410 envelope->add(
new GeoTransform(
415 envelope->add(
object);
418 auto put = [&put1, &FTPV, &chimneyPV, &ocablePV, r0, r1, r2](
double phi)
421 put1(chimneyPV, r1,
phi);
422 put1(ocablePV, r2,
phi);
426 for(
unsigned int i{0};
i < LArEndcapCratePhiPos->size(); ++
i){
427 const int num = (*LArEndcapCratePhiPos)[
i]->getInt(
"CRATENUM");
443 if(EndcapDMTubes->size()) {
444 const GeoMaterial* matECServices = materialManager->
getMaterial(
"LAr::LArECServices");
445 for(
unsigned i(0);
i<EndcapDMTubes->size(); ++
i) {
446 GeoTube* endcapTube =
new GeoTube((*EndcapDMTubes)[
i]->getDouble(
"RMIN"),(*EndcapDMTubes)[
i]->getDouble(
"RMAX"),(*EndcapDMTubes)[
i]->getDouble(
"DZ"));
447 GeoLogVol* endcapTubeLv =
new GeoLogVol((*EndcapDMTubes)[
i]->getString(
"TUBENAME"),endcapTube,matECServices);
448 GeoIntrusivePtr<GeoPhysVol> endcapTubePv =
new GeoPhysVol(endcapTubeLv);
449 envelope->add(
new GeoTransform(GeoTrf::TranslateZ3D((*EndcapDMTubes)[
i]->getDouble(
"ZPOS"))));
450 envelope->add(endcapTubePv);