90{
91
94
95
96 SmartIF<StoreGateSvc>
detStore{Gaudi::svcLocator()->service(
"DetectorStore")};
98 throw std::runtime_error("Error in EndcapCryostatConstruction, cannot access DetectorStore");
99 }
100
101
102
103 StoredMaterialManager* materialManager = nullptr;
104 if (StatusCode::SUCCESS !=
detStore->retrieve(materialManager, std::string(
"MATERIALS")))
return nullptr;
105
106 const GeoMaterial *Lead = materialManager->
getMaterial(
"std::Lead");
107 if (!Lead) {
108 throw std::runtime_error("Error in EndcapCryostatConstruction, std::Lead is not found.");
109 }
110
111 const GeoMaterial *Air = materialManager->
getMaterial(
"std::Air");
112 if (!Air) {
113 throw std::runtime_error("Error in EndcapCryostatConstruction, std::Air is not found.");
114 }
115
116 const GeoMaterial *Al = materialManager->
getMaterial(
"std::Aluminium");
117 if (!Al) {
118 throw std::runtime_error("Error in EndcapCryostatConstruction, std::Aluminium is not found.");
119 }
120
121 const GeoMaterial *LAr = materialManager->
getMaterial(
"std::LiquidArgon");
122 if (!LAr) {
123 throw std::runtime_error("Error in EndcapCryostatConstruction, std::LiquidArgon is not found.");
124 }
125
126 const GeoMaterial *G10 = materialManager->
getMaterial(
"LAr::G10");
127 if (!G10) throw std::runtime_error("Error in EndcapCryostatConstruction, LAr::G10 is not found.");
128
129 const GeoMaterial *Copper = materialManager->
getMaterial(
"std::Copper");
130 if (!Copper) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Copper is not found.");
131
132 const GeoMaterial *Iron = materialManager->
getMaterial(
"std::Iron");
133 if (!Iron) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Iron is not found.");
134
135 const GeoMaterial *Polystyrene = materialManager->
getMaterial(
"std::Polystyrene");
136 if (!Polystyrene) throw std::runtime_error("Error in EndcapCryostatConstruction, std::Polystyrene is not found.");
137
138
139
140 SmartIF<IGeoModelSvc> geoModelSvc{Gaudi::svcLocator()->service("GeoModelSvc")};
141 if(!geoModelSvc.isValid()) throw std::runtime_error("Cannot locate GeoModelSvc!");
142
144 std::string LArVersion = geoModelSvc->LAr_VersionOverride();
145
146 std::string detectorKey = LArVersion.empty() ?
AtlasVersion : LArVersion;
147 std::string detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
148
149 SmartIF<IRDBAccessSvc> rdbAccessSvc{Gaudi::svcLocator()->service("RDBAccessSvc")};
150 if(!rdbAccessSvc.isValid()) {
151 throw std::runtime_error ("Cannot locate RDBAccessSvc!!");
152 }
153
154 IRDBRecordset_ptr cryoCylinders = rdbAccessSvc->getRecordsetPtr(
"CryoCylinders",detectorKey, detectorNode);
155 IRDBRecordset_ptr larPosition = rdbAccessSvc->getRecordsetPtr(
"LArPosition",detectorKey, detectorNode);
156 if (larPosition->
size()==0 ) {
157 larPosition = rdbAccessSvc->getRecordsetPtr("LArPosition", "LArPosition-00");
158 if (larPosition->
size()==0 ) {
159 throw std::runtime_error("Error, no lar position table in database!");
160 }
161 }
162
163
164
165
166 if(cryoCylinders->
size()==0) cryoCylinders = rdbAccessSvc->getRecordsetPtr(
"CryoCylinders",
"CryoCylinders-00");
167
168
169 IRDBRecordset_ptr cryoPcons = rdbAccessSvc->getRecordsetPtr(
"CryoPcons",detectorKey, detectorNode);
170 if(cryoPcons->
size()==0) cryoPcons = rdbAccessSvc->getRecordsetPtr(
"CryoPcons",
"CryoPcons-00");
171
172 planeIndMap cryoMotherPlanes, emhPlanes, fcalNosePlanes;
173 std::vector<planeIndMap> brassPlugPlanesVect;
174 brassPlugPlanesVect.emplace_back();
175 brassPlugPlanesVect.emplace_back();
176 planeIndMap::const_iterator
iter;
177
178 for (
unsigned int ind=0; ind<cryoPcons->
size(); ind++)
179 {
180 int key = (*cryoPcons)[ind]->getInt(
"PLANE_ID");
181 const std::string& pconName = (*cryoPcons)[ind]->getString("PCON");
182 if(pconName=="Endcap::CryoMother") {
183 cryoMotherPlanes[
key] = ind;
184 }
185 else if(pconName=="Endcap::EMH") {
186 emhPlanes[
key] = ind;
187 }
188 else if(pconName=="Endcap::FcalNose") {
189 fcalNosePlanes[
key] = ind;
190 }
191 else if(pconName=="Endcap::BrassPlug1") {
192 brassPlugPlanesVect[0][
key] = ind;
193 }
194 else if(pconName=="Endcap::BrassPlug2") {
195 brassPlugPlanesVect[1][
key] = ind;
196 }
197 }
198
199
201
203
204
205 std::string baseName = "LAr::Endcap::Cryostat";
206
207
208
209
210
211
212
213
214
215
216 std::string cryoMotherName = baseName + "::MotherVolume";
217 GeoPcon* cryoMotherShape =
new GeoPcon(0.,2.*
M_PI);
218
219 double zStartCryoMother = 0.;
220
221 for(unsigned int ind = 0; ind < cryoMotherPlanes.size(); ++ ind){
222 iter = cryoMotherPlanes.find(ind);
223 if(iter == cryoMotherPlanes.end()){
224 throw std::runtime_error(
225 "Error in EndcapCryostatConstruction, missing plane in Endcap Cryo Mother"
226 );
227 } else {
228 const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
229 double zplane = currentRecord->
getDouble(
"ZPLANE");
230 double rmin = currentRecord->
getDouble(
"RMIN");
231 double rmax = currentRecord->
getDouble(
"RMAX");
232
234 if(zplane == 0.){
235 zplane = 12.;
236 log << MSG::DEBUG <<
"Put cryoMother zplane " << ind
237 <<
" at " << zplane <<
" to accomodate FEC" <<
endmsg;
238 }
239 if(rmax == 2476.){
240 rmax = 2506.;
241 log << MSG::DEBUG <<
"Put cryoMother rmax " << ind
242 <<
" at " << rmax <<
" to accomodate FT Chimney" <<
endmsg;
243 }
244 }
245 cryoMotherShape->addPlane(zplane, rmin, rmax);
246 if(ind == 0) zStartCryoMother = zplane;
247 }
248 }
249
250 const GeoLogVol* cryoMotherLogical = new GeoLogVol(cryoMotherName, cryoMotherShape, Air);
251 GeoIntrusivePtr<GeoFullPhysVol> cryoMotherPhysical{new GeoFullPhysVol(cryoMotherLogical)};
252
253
254
255
256
257
258
259
260
261
262 IRDBRecordset_ptr cryoExtraCyl = rdbAccessSvc->getRecordsetPtr(
"LArCones",detectorKey, detectorNode);
263
265 unsigned int nextra=cryoExtraCyl->
size();
266 if(nextra>0){
267 log << MSG::DEBUG <<
"activate extra material in front of PS" <<
endmsg;
268 bool finloop=false;
269 for(
unsigned int i=0;
i<nextra;
i++){
270 const std::string&
name=(*cryoExtraCyl)[
i]->getString(
"CONE");
271 if(
name.find(
"EmecCylBeforePS") != std::string::npos){
272 double rmin=(*cryoExtraCyl)[
i]->getDouble(
"RMIN1");
273 double rmax=(*cryoExtraCyl)[
i]->getDouble(
"RMAX1");
274 double dz = (*cryoExtraCyl)[
i]->getDouble(
"DZ");
275 if(dz>0.){
276
277 double rmin_warm=0.,rmax_warm=0.,dz_warm=0.,zInCryostat_warm=0.;
278 double rmin_cold=0.,rmax_cold=0.,dz_cold=0.,zInCryostat_cold=0.;
279 int wallfind=0;
280
281 for (
unsigned int layer = 0;
layer < cryoCylinders->
size();
layer++) {
282 const IRDBRecord *currentRecord = (*cryoCylinders)[
layer];
283 int cylNumber = currentRecord->
getInt(
"CYL_NUMBER");
284 if(currentRecord->
getString(
"CYL_LOCATION")==
"Endcap"){
285 if(cylNumber == 3 )
286 {
287 rmin_warm=currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm;
288 rmax_warm=currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm;
289 dz_warm=currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
290 zInCryostat_warm = currentRecord->
getDouble(
"ZMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
291 wallfind=wallfind+1;
292 }
293 if(cylNumber == 14 )
294 {
295 rmin_cold=currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm;
296 rmax_cold=currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm;
297 dz_cold=currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
298 zInCryostat_cold = currentRecord->
getDouble(
"ZMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
299 wallfind=wallfind+1;
300 }
301 }
302 }
303 if(wallfind==2){
304 double maxdz=(zInCryostat_cold-dz_cold)-(zInCryostat_warm+dz_warm);
305 if(dz>maxdz) dz=maxdz;
306 double zpos=((zInCryostat_cold-dz_cold)+(zInCryostat_warm+dz_warm))/2.;
307
308 std::ostringstream cylStream;
309 cylStream << baseName << "::ExtraCyl";
310 std::string cylName = cylStream.str();
311 cylName = cylName + "_beforePS";
312
313 double phi0=(*cryoExtraCyl)[
i]->getDouble(
"PHI0");
314 double dphi=(*cryoExtraCyl)[
i]->getDouble(
"DPHI");
315 if(dphi>6.28) dphi=2.*
M_PI;
316 const std::string& material=(*cryoExtraCyl)[
i]->getString(
"MATERIAL");
318 if (!mat) {
319 throw std::runtime_error("Error in EndcapCryostatConstruction,material for CylBeforePS is not found.");
320 }
321
322 GeoTubs *solidCyl = new GeoTubs(rmin,rmax,dz/2.,phi0,dphi);
323 const GeoLogVol *logicCyl = new GeoLogVol(cylName,solidCyl,mat);
324 GeoPhysVol *physCyl = new GeoPhysVol(logicCyl);
325
326 cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zpos)));
327 cryoMotherPhysical->add(physCyl);
328
329 std::cout<<"**************************************************"<<std::endl;
330 std::cout<<"EndcapCryostatConstruction insert extra material between warm and cold wall of cryo at front of PS::"<<std::endl;
331 std::cout<<
" ExtraCyl params: name,mat= "<<cylName<<
" "<<
mat->getName()
332 <<" rmin,rmax,dzthick,zpos="<<rmin<<" "<<rmax<<" "<<dz<<" "<<zpos
333 <<
" PhiStart,PhiSize="<<
phi0<<
" "<<dphi
334 <<std::endl;
335
336 std::cout<<" warm cyl params: rmin,rmax,dzthick,zpos="<<rmin_warm<<" "<<rmax_warm<<" "<<2.*dz_warm<<" "
337 <<zInCryostat_warm<<std::endl;
338 std::cout<<" cold cyl params: rmin,rmax,dzthick,zpos="<<rmin_cold<<" "<<rmax_cold<<" "<<2.*dz_cold<<" "
339 <<zInCryostat_cold<<std::endl;
340 std::cout<<"**************************************************"<<std::endl;
341
342 finloop=true;
343 }
344 }
345 }
346 if(finloop) break;
347 }
348 }
349 else {
350 log << MSG::DEBUG <<
"no extra material in front of PS" <<
endmsg;
351 }
352 }
353
354
355
356
357 IRDBRecordset_ptr LArEndcapCratePhiPos = rdbAccessSvc->getRecordsetPtr(
"LArEndcapCratePhiPos",detectorKey, detectorNode);
358
359
360 for(
unsigned int layer = 0;
layer < cryoCylinders->
size();
layer++){
361 const IRDBRecord *currentRecord = (*cryoCylinders)[
layer];
362 int cylNumber = currentRecord->
getInt(
"CYL_NUMBER");
363 if(
m_fullGeo || cylNumber == 14 || cylNumber == 100) {
364
365
366 if(currentRecord->
getString(
"CYL_LOCATION")==
"Endcap") {
367 std::ostringstream cylStream;
368 cylStream << baseName << "::Cylinder";
369 std::string cylName = (cylNumber == 100?"JDSH_AddShield_Inner":cylStream.str());
370
372 const std::string& qualifier = currentRecord->
getString(
"QUALIFIER");
373 if (!qualifier.empty()) cylName = cylName + "::" + qualifier;
374 }
375
376 const GeoShape* solidCyl = new GeoTubs(
377 currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm,
378 currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm,
379 currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.,
380 (double) 0.,
381 (
double) 2.*
M_PI*Gaudi::Units::rad
382 );
383 const GeoMaterial *material = materialManager->
getMaterial(currentRecord->
getString(
"MATERIAL"));
384
385 if(!material){
386 std::ostringstream errorMessage;
387 errorMessage << "Error in EndcapCrysostat Construction" << std::endl;
388 errorMessage <<
"Material " << currentRecord->
getString(
"MATERIAL") <<
" is not found" << std::endl;
389 throw std::runtime_error(errorMessage.str().c_str());
390 }
391
393 if(cylNumber == 13){
394 log << MSG::DEBUG <<
"Cut holes for feedthroughs in warm wall "
395 << cylName
397 const double rmin = currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm;
398 const double rmax = currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm;
399 const double dz = currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
400 const double warmhole_radius = 0.5*340.*Gaudi::Units::mm;
401 const double warmhole_pos = dz - 247.*Gaudi::Units::mm;
402 GeoTube *warmhole = new GeoTube(0., warmhole_radius, (rmax - rmin) * 4);
403 const GeoShapeShift &
h1 = (*warmhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
404 const double r = (rmin + rmax) * 0.5;
405 const GeoShape* warmwall = solidCyl;
406 const double dphi = 5.*Gaudi::Units::deg;
407 auto put = [&warmwall, &warmhole_pos, &
r, &
h1](
double pos){
409 warmwall = &(warmwall->subtract(
410 h1 << GeoTrf::Translate3D(
x,
y, warmhole_pos)
411 *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
412 ));
413 };
414 for(
unsigned int i{0};
i < LArEndcapCratePhiPos->
size(); ++
i){
415 const int num = (*LArEndcapCratePhiPos)[
i]->getInt(
"CRATENUM");
416 const double phi = (*LArEndcapCratePhiPos)[
i]->getDouble(
"PHIPOS")*Gaudi::Units::deg;
417 if(num == 10){
419 } else {
422 }
423 }
424 solidCyl = warmwall;
425 } else if(cylNumber == 20){
426 log << MSG::DEBUG <<
"Cut holes for feedthroughs in cold wall "
427 << cylName
429 const double rmin = currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm;
430 const double rmax = currentRecord->
getDouble(
"RMIN")*Gaudi::Units::cm + currentRecord->
getDouble(
"DR")*Gaudi::Units::cm;
431 const double coldhole_radius = 0.5*150.*Gaudi::Units::mm;
432 const double coldhole_pos = 21.5*Gaudi::Units::mm;
433 GeoTube *coldhole = new GeoTube(0., coldhole_radius, (rmax - rmin) * 4);
434 const GeoShapeShift &
h1 = (*coldhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
435 const double r = (rmin + rmax) * 0.5;
436 const GeoShape *coldwall = solidCyl;
437 const double dphi = 5.*Gaudi::Units::deg;
438 auto put = [&coldwall, &coldhole_pos, &
r, &
h1](
double pos){
440 coldwall = &(coldwall->subtract(
441 h1 << GeoTrf::Translate3D(
x,
y, coldhole_pos)
442 *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
443 ));
444 };
445 for(
unsigned int i{0};
i < LArEndcapCratePhiPos->
size(); ++
i){
446 const int num = (*LArEndcapCratePhiPos)[
i]->getInt(
"CRATENUM");
447 const double phi = (*LArEndcapCratePhiPos)[
i]->getDouble(
"PHIPOS")*Gaudi::Units::deg;
448 if(num == 10){
450 } else {
453 }
454 }
455 solidCyl = coldwall;
456 }
457 }
458
459 const GeoLogVol* logicCyl = new GeoLogVol(cylName,solidCyl,material);
460 GeoIntrusivePtr<GeoPhysVol> physCyl = new GeoPhysVol(logicCyl);
461
462 double zInCryostat = currentRecord->
getDouble(
"ZMIN")*Gaudi::Units::cm
463 + currentRecord->
getDouble(
"DZ")*Gaudi::Units::cm / 2.;
464
465
466
467
468
469
470 cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
471 cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
472
473
474 if ( cylNumber == 14 ) {
475
476 cryoMotherPhysical->add( new GeoNameTag(cylName + "::PresamplerMother") );
477
478 EndcapPresamplerConstruction endcapPresamplerConstruction;
479
480 GeoIntrusivePtr<GeoFullPhysVol> emecPSEnvelope = endcapPresamplerConstruction.
Envelope();
481 if (emecPSEnvelope) {
482
483 double Zpos = 30.5*Gaudi::Units::mm;
484
485
486
487
488
489 GeoTransform *xfPs = new GeoTransform(GeoTrf::TranslateZ3D(Zpos));
490
491 physCyl->add(xfPs);
492 physCyl->add( emecPSEnvelope );
493
494 std::string
tag = bPos? std::string(
"PRESAMPLER_EC_POS") : std::string(
"PRESAMPLER_EC_NEG");
496
497 StoredPhysVol *sPhysVol = new StoredPhysVol(emecPSEnvelope);
499 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag).c_str());
500 }
501 }
502
503
504 cryoMotherPhysical->add(physCyl);
505 }
506 }
507 }
508
509
510
512 if (!fcalNosePlanes.empty()) {
513 GeoPcon *fcalNosePcon =
new GeoPcon(0,2*
M_PI);
514 for(unsigned int ind=0; ind<fcalNosePlanes.size(); ind++) {
515 iter = fcalNosePlanes.find(ind);
516
517 if(iter==fcalNosePlanes.end()) {
518 throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in InnerWall");
519 } else {
520 const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
521 fcalNosePcon->addPlane(currentRecord->
getDouble(
"ZPLANE"),
524 }
525 }
526 int coneNumber = 1;
527 const GeoLogVol *fcalNoseLog = new GeoLogVol("LAr::Endcap::Cryostat::Cone::Mixed", fcalNosePcon, Al);
528 cryoMotherPhysical->add(new GeoIdentifierTag(coneNumber));
529 GeoIntrusivePtr<GeoPhysVol>fcalNosePhys = new GeoPhysVol(fcalNoseLog);
530 cryoMotherPhysical->add(fcalNosePhys);
531 }
532
533
534
535
536
537
538
539
540
541
542
543 std::string totalEMHLArName = baseName + "::EmecHecLAr";
544 GeoPcon* totalEMHLArShape =
new GeoPcon(0.,2.*
M_PI);
545
546 for(unsigned int ind=0; ind<emhPlanes.size(); ind++)
547 {
548 iter = emhPlanes.find(ind);
549
550 if(iter==emhPlanes.end())
551 throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in EMH");
552 else
553 {
554 const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
555 totalEMHLArShape->addPlane(currentRecord->
getDouble(
"ZPLANE"),
558 }
559 }
560
561 const GeoLogVol* totalEMHLArLogical =
562 new GeoLogVol(totalEMHLArName, totalEMHLArShape, LAr);
563
564 GeoIntrusivePtr<GeoFullPhysVol> totalEMHLArPhysical = new GeoFullPhysVol(totalEMHLArLogical);
565
566
567 const GeoMaterial *PlugBrass(nullptr);
568 for(
size_t i(0);
i<2;++
i) {
569 const planeIndMap& brassPlugPlanes = brassPlugPlanesVect[
i];
570 if (!brassPlugPlanes.empty()) {
571 if(!PlugBrass) {
572 PlugBrass = materialManager->
getMaterial(
"LAr::PlugBrass");
573 if (!PlugBrass) throw std::runtime_error("Error in EndcapCryostatConstruction, LAr::PlugBrass is not found.");
574 }
575 GeoPcon *brassPlugPcon =
new GeoPcon(0,2*
M_PI);
576 for(unsigned int ind=0; ind<brassPlugPlanes.size(); ind++) {
577 iter = brassPlugPlanes.find(ind);
578
579 if(iter==brassPlugPlanes.end()) {
580 throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in BrassPlug");
581 } else {
582 const IRDBRecord *currentRecord = (*cryoPcons)[(*iter).second];
583 brassPlugPcon->addPlane(currentRecord->
getDouble(
"ZPLANE"),
586 }
587 }
588 const GeoLogVol *brassPlugLog = new GeoLogVol("LAr::Endcap::Cryostat::BrassPlug", brassPlugPcon, PlugBrass);
589 GeoIntrusivePtr<GeoPhysVol>brassPlugPhys = new GeoPhysVol(brassPlugLog);
590 totalEMHLArPhysical->add(new GeoIdentifierTag(i+1));
591 totalEMHLArPhysical->add(brassPlugPhys);
592 }
593 }
594
596
597
598 const double rcoldwall = 2155.*Gaudi::Units::mm;
599 const double coldhole_radius = 0.5*150.*Gaudi::Units::mm;
600 const double icable_dz = coldhole_radius;
601 const double icable_dr =
602 (1920./LArEndcapCratePhiPos->
size()) *
603 M_PI * 1.1*1.1/4. * Gaudi::Units::mm2
604 / (icable_dz*2);
605 log << MSG::DEBUG <<
"adding " << icable_dr/Gaudi::Units::mm <<
" mm"
606 <<
" of cables inside EC cryostat in front of FT" <<
endmsg;
607 const double z_pos = -249.*Gaudi::Units::mm - icable_dz;
608 const GeoMaterial* icable_mat = materialManager->
getMaterial(
"LAr::FT::Cable");
609 GeoShape* icable = new GeoTube(rcoldwall - icable_dr, rcoldwall, icable_dz);
610 GeoLogVol* icableLV = new GeoLogVol("LAr::Endcap::InnerFTCables", icable, icable_mat);
611 GeoIntrusivePtr<GeoPhysVol> icablePV = new GeoPhysVol(icableLV);
612 totalEMHLArPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(z_pos)));
613 totalEMHLArPhysical->add(icablePV);
614 }
615
616 cryoMotherPhysical->add( totalEMHLArPhysical );
617
618 {
622 GeoIntrusivePtr<GeoFullPhysVol>envelope =
m_emec.GetEnvelope(bPos);
623
624
626 if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
628 GeoAlignableTransform *xfEmec = new GeoAlignableTransform(xfPos);
629
630 std::string
tag = bPos? std::string(
"EMEC_POS") : std::string(
"EMEC_NEG");
632
633 StoredPhysVol *sPhysVol = new StoredPhysVol(envelope);
635 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag).c_str());
636
637 StoredAlignX *sAlignX = new StoredAlignX(xfEmec);
639 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag).c_str());
640
641
642
643 totalEMHLArPhysical->add(xfEmec);
644 totalEMHLArPhysical->add( envelope );
645 }
646
647 {
648
649 std::string wheelType="front";
650 bool threeBoards= false;
651 HECWheelConstruction frontHEC(
m_fullGeo,wheelType,threeBoards,bPos) ;
652 GeoIntrusivePtr<GeoFullPhysVol> EnvelopeF = frontHEC.GetEnvelope();
653
655
656
657
658
661 GeoAlignableTransform *xfHec1 = new GeoAlignableTransform(xfPosHec1);
662
663 std::string
tag1 = bPos? std::string(
"HEC1_POS") : std::string(
"HEC1_NEG");
664
665 StoredPhysVol *sPhysVol1 = new StoredPhysVol(EnvelopeF);
667 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag1).c_str());
668
669 StoredAlignX *sAlignX1 = new StoredAlignX(xfHec1);
671 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag1).c_str());
672
673 totalEMHLArPhysical->add( xfHec1);
674 totalEMHLArPhysical->add(new GeoIdentifierTag(0));
675 totalEMHLArPhysical->add( EnvelopeF );
676
677
678
679 wheelType="rear";
680 threeBoards= false;
681 HECWheelConstruction rearHEC(
m_fullGeo,wheelType,threeBoards,bPos) ;
682 GeoIntrusivePtr<GeoFullPhysVol> EnvelopeR = rearHEC.GetEnvelope();
683
686 GeoAlignableTransform *xfHec2 = new GeoAlignableTransform(xfPosHec2);
687
688 std::string
tag2 = bPos? std::string(
"HEC2_POS") : std::string(
"HEC2_NEG");
689
690 StoredPhysVol *sPhysVol2 = new StoredPhysVol(EnvelopeR);
692 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag2).c_str());
693
694 StoredAlignX *sAlignX2 = new StoredAlignX(xfHec2);
696 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag2).c_str());
697
698 totalEMHLArPhysical->add( xfHec2);
699 totalEMHLArPhysical->add(new GeoIdentifierTag(1));
700 totalEMHLArPhysical->add( EnvelopeR );
701
702
703 }
704
705
706
707
710 {
711
712
713 GeoIntrusivePtr<GeoVFullPhysVol> fcalEnvelope =
m_fcal.GetEnvelope(bPos);
714
715
716
717
718
719
720
721
722
723
724
725 std::string
tag = bPos ?
"FCAL_POS" :
"FCAL_NEG";
726
728 if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
730 GeoAlignableTransform *fcalXF = new GeoAlignableTransform(xfPos);
731
733 StoredAlignX *sAlignX = new StoredAlignX(fcalXF);
735 if(!
status.isSuccess())
throw std::runtime_error ((std::string(
"Cannot store")+tag).c_str());
736
737
738 const GeoLogVol *envVol = fcalEnvelope->getLogVol();
739 const GeoShape *envShape = envVol->getShape();
740 if (envShape->typeID()!=GeoTubs::getClassTypeID()) {
741 throw std::runtime_error("Cannot recognize FCAL container shape");
742 }
743
744 const GeoTubs * tubs = static_cast<const GeoTubs*>(envShape);
745
746
747 cryoMotherPhysical->add(fcalXF);
748 cryoMotherPhysical->add( new GeoTransform( GeoTrf::TranslateZ3D(tubs->getZHalfLength()) ) );
749 cryoMotherPhysical->add( fcalEnvelope );
750
751
752 }
753
754
755 if(
m_enableMBTS && !rdbAccessSvc->getChildTag(
"MBTS",detectorKey, detectorNode).empty()) {
756
757 IRDBRecordset_ptr mbtsTubs = rdbAccessSvc->getRecordsetPtr(
"MBTSTubs", detectorKey, detectorNode);
758 IRDBRecordset_ptr mbtsScin = rdbAccessSvc->getRecordsetPtr(
"MBTSScin", detectorKey, detectorNode);
759 IRDBRecordset_ptr mbtsPcons = rdbAccessSvc->getRecordsetPtr(
"MBTSPcons",detectorKey, detectorNode);
760 IRDBRecordset_ptr mbtsGen = rdbAccessSvc->getRecordsetPtr(
"MBTSGen", detectorKey, detectorNode);
761 IRDBRecordset_ptr mbtsTrds = rdbAccessSvc->getRecordsetPtr(
"MBTSTrds", detectorKey, detectorNode);
762
763 double zposMM = 0.;
764 std::map<std::string,unsigned> trdMap;
765 for(
unsigned indTrd(0);indTrd<mbtsTrds->
size();++indTrd) {
766 const std::string& keyTrd = (*mbtsTrds)[indTrd]->getString("TRD");
767 trdMap[keyTrd]=indTrd;
768 }
769
770
772
776
779
780
781 GeoIntrusivePtr<GeoPhysVol> pvMM = nullptr;
782
783 if(mbtsPcons->
size()==0) {
784
785
786
787
789 const std::string& strTubeName = (*first)->getString("TUBE");
790 if(strTubeName == "MBTS_mother") {
792 }
793 else if(strTubeName == "Moderator") {
795 }
796 else if(strTubeName == "JMTUBE") {
798 }
799 }
800
801
802 double rminMM = (*itMother)->getDouble("RMIN")*Gaudi::Units::mm;
803 double rmaxMM = (*itMother)->getDouble("RMAX")*Gaudi::Units::mm;
804 double dzMM = (*itMother)->getDouble("DZ")*Gaudi::Units::mm;
805 zposMM = (*itMother)->getDouble("ZPOS")*Gaudi::Units::mm;
806
807 const GeoMaterial *matMM = materialManager->
getMaterial((*itMother)->getString(
"MATERIAL"));
808
809 GeoIntrusivePtr<GeoTube> tubeMM{new GeoTube(rminMM,rmaxMM,dzMM)};
810
811 GeoTube *tubeJM=nullptr;
812 const GeoShape *solidMM=nullptr;
813 if (itTube!=mbtsTubs->
end()) {
814 double dzMod = (*itTube)->getDouble("DZ")*Gaudi::Units::mm;
815 double rMaxMod = (*itTube)->getDouble("RMAX")*Gaudi::Units::mm;
816
817 GeoPcon *pcon =
new GeoPcon(0,2*
M_PI);
818 pcon->addPlane(-dzMM,rminMM,rmaxMM);
819 pcon->addPlane( dzMM,rminMM,rmaxMM);
820 pcon->addPlane( dzMM,rminMM,rMaxMod);
821 pcon->addPlane( dzMM+2*dzMod, rminMM,rMaxMod);
822 tubeJM = new GeoTube(rminMM,rMaxMod,dzMod);
823 solidMM=pcon;
824 }
825
826 if (!solidMM) solidMM = new GeoTube(rminMM,rmaxMM,dzMM);
827
828 GeoLogVol* lvMM = new GeoLogVol("MBTS_mother",solidMM,matMM);
829 pvMM = new GeoPhysVol(lvMM);
830
831 cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMM)));
832 cryoMotherPhysical->add(pvMM);
833
834
835
836
837 double dzMod = (*itModerator)->getDouble("DZ")*Gaudi::Units::mm;
838 double zposMod = (*itModerator)->getDouble("ZPOS")*Gaudi::Units::mm;
839
840 const GeoMaterial *matMod = materialManager->
getMaterial((*itModerator)->getString(
"MATERIAL"));
841
842 GeoTube* solidMod = new GeoTube(rminMM,rmaxMM,dzMod);
843 GeoLogVol* lvMod = new GeoLogVol("Moderator",solidMod, matMod);
844 GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
845
846 pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMod)));
847 pvMM->add(pvMod);
848
849 if (tubeJM) {
850 GeoLogVol* lvMod = new GeoLogVol("ModeratorTube",tubeJM, matMod);
851 GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
852
853 pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D(tubeMM->getZHalfLength()+tubeJM->getZHalfLength())));
854 pvMM->add(pvMod);
855 }
856 } else {
857
858
859
860
862 planeIndMap::const_iterator
iter;
863
864 for (
unsigned int ind=0; ind<mbtsPcons->
size(); ind++) {
865 int key = (*mbtsPcons)[ind]->getInt(
"PLANE_ID");
866 const std::string& pconName = (*mbtsPcons)[ind]->getString("PCON");
867 if(pconName=="MBTS::Mother") {
868 mbtsMotherPlanes[
key] = ind;
869 }
870 else if(pconName=="MBTS::JM") {
871 jmTubePlanes[
key] = ind;
872 }
873 }
874
875 double zStartMM = 0.;
876
877
878 GeoPcon* solidMM =
new GeoPcon(0.,2.*
M_PI);
879 for(unsigned int ind=0; ind<mbtsMotherPlanes.size(); ind++) {
880 iter = mbtsMotherPlanes.find(ind);
881 if(iter==mbtsMotherPlanes.end())
882 throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in MBTS Mother");
883 else {
884 const IRDBRecord *currentRecord = (*mbtsPcons)[(*iter).second];
885 solidMM->addPlane(currentRecord->
getDouble(
"ZPLANE"),
888 if(ind==0)
889 zStartMM = currentRecord->
getDouble(
"ZPLANE");
890 }
891 }
892
893
894 GeoPcon* solidMod =
new GeoPcon(0.,2.*
M_PI);
895 for(unsigned int ind=0; ind<jmTubePlanes.size(); ind++) {
896 iter = jmTubePlanes.find(ind);
897 if(iter==jmTubePlanes.end())
898 throw std::runtime_error("Error in EndcapCryostatConstruction, missing plane in Moderator+JM tube volume");
899 else {
900 const IRDBRecord *currentRecord = (*mbtsPcons)[(*iter).second];
901 solidMod->addPlane(currentRecord->
getDouble(
"ZPLANE"),
904 }
905 }
906
907
908
909
910 GeoLogVol* lvMM = new GeoLogVol("MBTS_mother",solidMM,Air);
911 pvMM = new GeoPhysVol(lvMM);
912
913 zposMM = zStartCryoMother - zStartMM;
914 cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zposMM)));
915 cryoMotherPhysical->add(pvMM);
916
917
918 if((mbtsTubs->
size()!=1) || ((*mbtsTubs)[0]->getString(
"TUBE")!=
"MBTS::JM"))
919 throw std::runtime_error("Error in EndcapCryostatConstruction, unexpected number of tubes or wrong name for the JM tube");
920 GeoTube* tubeJM = new GeoTube((*mbtsTubs)[0]->getDouble("RMIN"),
921 (*mbtsTubs)[0]->getDouble("RMAX"),
922 (*mbtsTubs)[0]->getDouble("DZ"));
923 const GeoMaterial* matJM = materialManager->
getMaterial((*mbtsTubs)[0]->getString(
"MATERIAL"));
924 GeoLogVol* lvJM = new GeoLogVol("ModeratorJMTube",tubeJM, matJM);
925 GeoIntrusivePtr<GeoPhysVol> pvJM = new GeoPhysVol(lvJM);
926
927 pvMM->add(new GeoTransform(GeoTrf::TranslateZ3D((*mbtsTubs)[0]->getDouble("ZPOS"))));
928 pvMM->add(pvJM);
929
930
931 GeoLogVol* lvMod = new GeoLogVol("ModeratorJMPcon",solidMod, matJM);
932 GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
933
934 pvMM->add(pvMod);
935 }
936
937
938 if(mbtsGen->
size()==0) {
939
940 for(
unsigned int scinId=0; scinId<mbtsScin->
size(); scinId++) {
941 const IRDBRecord* curScin = (*mbtsScin)[scinId];
942
943 int nScin = curScin->
getInt(
"SCINNUM");
944 double dx1Scin = curScin->
getDouble(
"DX1")*Gaudi::Units::mm;
945 double dx2Scin = curScin->
getDouble(
"DX2")*Gaudi::Units::mm;
946 double dy1Scin = curScin->
getDouble(
"DY1")*Gaudi::Units::mm;
947 double dy2Scin = curScin->
getDouble(
"DY2")*Gaudi::Units::mm;
948 double dzScin = curScin->
getDouble(
"DZ")*Gaudi::Units::mm;
949 double zposScin = curScin->
getDouble(
"ZPOS")*Gaudi::Units::mm;
950 double rposScin = curScin->
getDouble(
"RPOS")*Gaudi::Units::mm;
951
952 double startPhi = 0.;
953 try {
955 startPhi = curScin->
getDouble(
"STARTPHI");
956 }
957 catch(std::runtime_error&) {}
958
960
961 std::ostringstream ostr;
962 ostr << curScin->
getInt(
"SCIN_ID");
963 std::string scinName = std::string("MBTS")+ostr.str();
964
965 GeoTrd* solidScin = new GeoTrd(dx1Scin,dx2Scin,dy1Scin,dy2Scin,dzScin);
966 GeoLogVol* lvScin = new GeoLogVol(scinName,solidScin,matScin);
967 GeoIntrusivePtr<GeoPhysVol> pvScin = new GeoPhysVol(lvScin);
968
969
971 Variable varInd;
972 GeoSerialTransformer* stScin = nullptr;
973
974 if(bPos) {
975 GENFUNCTION phiInd =
deltaPhi*(varInd + startPhi)*Gaudi::Units::deg;
976 TRANSFUNCTION xfScin = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposScin)*GeoTrf::TranslateX3D(rposScin)*GeoTrf::RotateY3D(90*Gaudi::Units::deg);
977 stScin = new GeoSerialTransformer(pvScin,&xfScin,nScin);
978 } else {
979 GENFUNCTION phiInd = (180 -
deltaPhi*(varInd + startPhi))*Gaudi::Units::deg;
980 TRANSFUNCTION xfScin = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposScin)*GeoTrf::TranslateX3D(rposScin)*GeoTrf::RotateY3D(90*Gaudi::Units::deg);
981 stScin = new GeoSerialTransformer(pvScin,&xfScin,nScin);
982 }
983
984 pvMM->add(new GeoSerialIdentifier(0));
985 pvMM->add(stScin);
986 }
987 }
988 else {
989
990
991
992 int nAirEnv = (*mbtsGen)[0]->getInt("NSCIN");
993 double startPhi = (*mbtsGen)[0]->getDouble("STARTPHI");
994 double zposAirEnv = (*mbtsGen)[0]->getDouble("ZPOSENV");
995 double rposAirEnv = (*mbtsGen)[0]->getDouble("RPOSENV");
996
997 GeoIntrusivePtr<GeoPhysVol>pvAirEnv{}, pvAluEnv{} , pvAirInAlu{};
998
999
1000 std::map<std::string,unsigned>::const_iterator itTrdMap = trdMap.find("MBTSAirEnv");
1001 if(itTrdMap==trdMap.end())
1002 throw std::runtime_error("Error in EndcapCryostatConstruction, unable to get MBTS air envelope parameters from the database!");
1003 const IRDBRecord* rec = (*mbtsTrds)[itTrdMap->second];
1005
1006
1007 for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1008 rec = (*mbtsTrds)[itTrdMap->second];
1009 const std::string& trd = rec->
getString(
"TRD");
1010 if(rec->
getString(
"PARENT")==
"MBTSAirEnv") {
1011 GeoIntrusivePtr<GeoPhysVol> nevVol =
buildMbtsTrd(rec,materialManager,pvAirEnv);
1012 if(trd.compare("MBTSAluEnv")==0)
1013 pvAluEnv = nevVol;
1014 }
1015 }
1016
1017
1018 for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1019 rec = (*mbtsTrds)[itTrdMap->second];
1020 const std::string& trd = rec->
getString(
"TRD");
1021 if(rec->
getString(
"PARENT")==
"MBTSAluEnv") {
1022 GeoIntrusivePtr<GeoPhysVol> nevVol =
buildMbtsTrd(rec,materialManager,pvAluEnv);
1023 if(trd.compare("MBTSAirInAlu")==0)
1024 pvAirInAlu = nevVol;
1025 }
1026 }
1027
1028
1029 for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1030 rec = (*mbtsTrds)[itTrdMap->second];
1031 if(rec->
getString(
"PARENT")==
"MBTSAirInAlu")
1033 }
1034
1035
1037 Variable varInd;
1038 GeoSerialTransformer* stAirEnv = nullptr;
1039 if(bPos) {
1040 GENFUNCTION phiInd =
deltaPhi*(varInd + startPhi)*Gaudi::Units::deg;
1041 TRANSFUNCTION xfAirEnv = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposAirEnv)*GeoTrf::TranslateX3D(rposAirEnv)*GeoTrf::RotateY3D(90*Gaudi::Units::deg);
1042 stAirEnv = new GeoSerialTransformer(pvAirEnv,&xfAirEnv,nAirEnv);
1043 } else {
1044 GENFUNCTION phiInd = (180 -
deltaPhi*(varInd + startPhi))*Gaudi::Units::deg;
1045 TRANSFUNCTION xfAirEnv = Pow(GeoTrf::RotateZ3D(1.0),phiInd)*GeoTrf::TranslateZ3D(zposAirEnv)*GeoTrf::TranslateX3D(rposAirEnv)*GeoTrf::RotateY3D(90*Gaudi::Units::deg);
1046 stAirEnv = new GeoSerialTransformer(pvAirEnv,&xfAirEnv,nAirEnv);
1047 }
1048
1049 pvMM->add(new GeoSerialIdentifier(0));
1050 pvMM->add(stAirEnv);
1051
1052 }
1053 }
1054
1055
1056
1057 if(bPos) {
1059 , rdbAccessSvc.get()
1061 , zposMM
1062 , trdMap
1063 , detectorKey
1064 , detectorNode).isFailure()) {
1065 throw std::runtime_error("Failed to build MBTS readout geometry");
1066 }
1067 }
1068
1069 }
1070
1071
1073 crateBuilder.create(cryoMotherPhysical);
1074
1075 return cryoMotherPhysical;
1076}
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar phi() const
phi method
std::map< int, unsigned int, std::less< int > > planeIndMap
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
GeoIntrusivePtr< GeoFullPhysVol > Envelope()
static const IRDBRecord * getTransformRecord(IRDBRecordset_ptr positionRecSet, const std::string &key)
static GeoTrf::Transform3D getTransform(const IRDBRecord *currentRec)
virtual bool isFieldNull(const std::string &fieldName) const =0
Check if the field value is NULL.
virtual int getInt(const std::string &fieldName) const =0
Get int field value.
RecordsVector::const_iterator const_iterator
virtual const_iterator begin() const =0
virtual const_iterator end() const =0
virtual unsigned int size() const =0
static GeoIntrusivePtr< GeoPhysVol > buildMbtsTrd(const IRDBRecord *rec, StoredMaterialManager *matmanager, GeoIntrusivePtr< GeoPhysVol > parent)
IMessageSvc * getMessageSvc(bool quiet=false)
::StatusCode StatusCode
StatusCode definition for legacy code.
StatusCode buildMbtsReadout(StoreGateSvc *detStore, IRDBAccessSvc *paramSvc, IMessageSvc *msgSvc, double zposMM, const std::map< std::string, unsigned > &trdMap, const std::string &detKey, const std::string &detNode)