ATLAS Offline Software
Loading...
Searching...
No Matches
BarrelCryostatConstruction.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// BarrelCryostatConstruction
6
7// 28-Nov-2001 WGS: Revise to create cryostat mother volume, and to
8// place all components of the barrel within this volume.
9
14
15#include "GeoModelKernel/GeoElement.h"
16#include "GeoModelKernel/GeoMaterial.h"
17#include "GeoModelKernel/GeoFullPhysVol.h"
18#include "GeoModelKernel/GeoPhysVol.h"
19#include "GeoModelKernel/GeoVPhysVol.h"
20#include "GeoModelKernel/GeoLogVol.h"
21#include "GeoModelKernel/GeoPcon.h"
22#include "GeoModelKernel/GeoTubs.h"
23#include "GeoModelKernel/GeoTube.h"
24#include "GeoModelKernel/GeoBox.h"
25#include "GeoModelKernel/GeoCons.h"
26#include "GeoModelKernel/GeoTransform.h"
27#include "GeoModelKernel/GeoNameTag.h"
28#include "GeoModelKernel/GeoAlignableTransform.h"
29#include "GeoModelKernel/GeoIdentifierTag.h"
30#include "GeoModelKernel/GeoVolumeTagCatalog.h"
31#include "GeoModelKernel/GeoShapeIntersection.h"
32#include "GeoModelKernel/GeoShapeSubtraction.h"
33#include "GeoModelKernel/GeoShapeShift.h"
34#include "GeoModelKernel/GeoShapeUnion.h"
35#include "GeoModelKernel/GeoSerialTransformer.h"
43#include "GaudiKernel/MsgStream.h"
44#include "GaudiKernel/Bootstrap.h"
45
49
50// For transforms:
51#include "CLHEP/Geometry/Transform3D.h"
52// For units:
53#include "GaudiKernel/PhysicalConstants.h"
54// For Transformation Fields:
55#include "GeoGenericFunctions/Abs.h"
56#include "GeoGenericFunctions/Mod.h"
57#include "GeoGenericFunctions/Rectangular.h"
58#include "GeoGenericFunctions/Variable.h"
59#include "GeoGenericFunctions/FixedConstant.h"
60#include "GeoGenericFunctions/Sin.h"
61#include "GeoGenericFunctions/Cos.h"
62
63#include <string>
64#include <cmath>
65#include <map>
66#include <climits>
67#include <stdexcept>
68using namespace GeoXF;
69using namespace GeoGenfun;
70
71// The objects for mapping plane indexes in Pcon to the record index
72// in RDBRecordset
73using planeIndMap = std::map<int, unsigned int, std::less<int>>;
74
76 : AthMessaging("LAr::BarrelCryostatConstruction")
79 , m_cryoMotherPhysical(nullptr)
80 , m_fullGeo(fullGeo)
81 , m_activateFT(ft)
82{}
83
85
86
87GeoIntrusivePtr<GeoFullPhysVol> LArGeo::BarrelCryostatConstruction::GetEnvelope(const VDetectorParameters* params)
88{
90
91 // Get access to the material manager:
92 ATH_MSG_DEBUG("started");
93
94 SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
95 if (!detStore.isValid()) {
96 throw std::runtime_error("Error in LArDetectorFactory, cannot access DetectorStore");
97 }
98
99 // Get the materials from the material manager:-----------------------------------------------------//
100 // //
101 StoredMaterialManager* materialManager = nullptr;
102 if (StatusCode::SUCCESS != detStore->retrieve(materialManager, std::string("MATERIALS"))) return nullptr;
103
104 const GeoMaterial *Air = materialManager->getMaterial("std::Air");
105 if (!Air) {
106 throw std::runtime_error("Error in BarrelCryostatConstruction, std::Air is not found.");
107 }
108
109 const GeoMaterial *Aluminium = materialManager->getMaterial("std::Aluminium");
110 if (!Aluminium) {
111 throw std::runtime_error("Error in BarrelCryostatConstruction, std::Aluminium is not found.");
112 }
113
114 const GeoMaterial *Titanium = materialManager->getMaterial("std::Titanium");
115 if (!Titanium) {
116 Titanium = Aluminium;
117 // No need to throw an error. Some configurations do not build anything out of titanium.
118 // throw std::runtime_error("Error in BarrelCryostatConstruction, std::Titanium is not found.");
119 }
120
121 const GeoMaterial *LAr = materialManager->getMaterial("std::LiquidArgon");
122 if (!LAr) {
123 throw std::runtime_error("Error in BarrelCryostatConstruction, std::LiquidArgon is not found.");
124 }
125
126
127 // ----- ----- ------ Get primary numbers from the GeomDB ----- ----- -----
128 SmartIF<IGeoModelSvc> geoModel{Gaudi::svcLocator()->service("GeoModelSvc")};
129 if(!geoModel.isValid())
130 throw std::runtime_error("Error in BarrelCryostatConstruction, cannot access GeoModelSvc");
131 SmartIF<IRDBAccessSvc> rdbAccess{Gaudi::svcLocator()->service("RDBAccessSvc")};
132 if(!rdbAccess.isValid())
133 throw std::runtime_error("Error in BarrelCryostatConstruction, cannot access RDBAccessSvc");
134
135 planeIndMap innerWallPlanes, innerEndWallPlanes, outerWallPlanes, cryoMotherPlanes, totalLarPlanes, halfLarPlanes, sctEcCoolingPlanes;
136 planeIndMap::const_iterator iter;
137 const IRDBRecord* currentRecord{nullptr};
138
139 DecodeVersionKey larVersionKey(geoModel, "LAr");
140 ATH_MSG_DEBUG("Getting primary numbers for " << larVersionKey.node() << ", " << larVersionKey.tag());
141
142 // ---- Alignable transforms for the barrel:
143 // 1. HalfLar + Presampler (pos/neg)
144 // 2. Coil
145 std::string names[]={"EMB_POS","EMB_NEG","SOLENOID"};
146 GeoAlignableTransform *xf[]={nullptr,nullptr,nullptr};
147 for (int n=0;n<3;n++) {
148
149 IRDBRecordset_ptr larPosition = rdbAccess->getRecordsetPtr("LArPosition",larVersionKey.tag(), larVersionKey.node());
150
151 if (larPosition->size()==0 ) {
152 larPosition = rdbAccess->getRecordsetPtr("LArPosition", "LArPosition-00");
153 if (larPosition->size()==0 ) {
154 throw std::runtime_error("Error, no lar position table in database!");
155 }
156 }
157
158 const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(std::move(larPosition), names[n]);
159 if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
160 GeoTrf::Transform3D xfPos = GeoDBUtils::getTransform(posRec);
161 xf[n] = new GeoAlignableTransform(xfPos);
162
163 StoredAlignX *sAlignX = new StoredAlignX(xf[n]);
164 StatusCode status=detStore->record(sAlignX,names[n]);
165 if(!status.isSuccess()) throw std::runtime_error (("Cannot store " + names[n]).c_str() );
166 }
167
168 GeoAlignableTransform *xfHalfLArPos=xf[0], *xfHalfLArNeg=xf[1], *xfSolenoid=xf[2];
169
170
171
172
173 IRDBRecordset_ptr cryoEars = rdbAccess->getRecordsetPtr("CryoEars", larVersionKey.tag(),larVersionKey.node());
174 IRDBRecordset_ptr idSupportRails = rdbAccess->getRecordsetPtr("IdSupportRail", larVersionKey.tag(), larVersionKey.node());
175 IRDBRecordset_ptr cryoCylinders = rdbAccess->getRecordsetPtr("CryoCylinders",
176 larVersionKey.tag(),
177 larVersionKey.node());
178 if(cryoCylinders->size()==0)
179 cryoCylinders = rdbAccess->getRecordsetPtr("CryoCylinders","CryoCylinders-00");
180
181
182 IRDBRecordset_ptr cryoPcons = rdbAccess->getRecordsetPtr("CryoPcons",
183 larVersionKey.tag(),
184 larVersionKey.node());
185 if(cryoPcons->size()==0)
186 cryoPcons = rdbAccess->getRecordsetPtr("CryoPcons","CryoPcons-00");
187
188
189 for (unsigned int ind=0; ind<cryoPcons->size(); ind++)
190 {
191 int key = (*cryoPcons)[ind]->getInt("PLANE_ID");
192 const std::string& pconName = (*cryoPcons)[ind]->getString("PCON");
193 if(pconName=="Barrel::InnerWall")
194 innerWallPlanes[key] = ind;
195 if (pconName=="Barrel::InnerEndWall")
196 innerEndWallPlanes[key] = ind;
197 else if(pconName=="Barrel::OuterWall")
198 outerWallPlanes[key] = ind;
199 else if(pconName=="Barrel::CryoMother")
200 cryoMotherPlanes[key] = ind;
201 else if(pconName=="Barrel::TotalLAr")
202 totalLarPlanes[key] = ind;
203 else if(pconName=="Barrel::HalfLAr")
204 halfLarPlanes[key] = ind;
205 else if(pconName=="Barrel::SctEcCooling")
206 sctEcCoolingPlanes[key] = ind;
207 }
208 // ----- ----- ------ Get primary numbers from the GeomDB ----- ----- -----
209
211 // Define geometry
213
214 // 1) There is mother volume.
215 // 2) There are ~ 60 cylindrical layers in the mother
216 // Also ~ 12 conical layers in the mother.
217 // Also the liquid argon volume.
218 // 3) There are 3 half barrels in the liquid argon volume.
219
220 // 1) The mother volume. ---------------------------------------------------------------------------//
221 // //
222 std::string cryoMotherName = "LAr::Barrel::Cryostat::MotherVolume"; //
223
224 // Define the mother volume for the entire barrel cryostat.
225 // Everything else in the barrel (cryostat walls, detector,
226 // presampler) should be placed inside here.
227
228 // The size of this volume may change if the thickness of the
229 // cabling in front of the endcaps changes. Therefore, we must get
230 // the z-shift from the LAr information database
231 // (LArVDetectorParameters) and adjust the volume geometry
232 // accordingly.
233
234 // double cryoMotherRin[] = {1149.8*Gaudi::Units::mm, 1149.8*Gaudi::Units::mm,1149.8*Gaudi::Units::mm,1149.8*Gaudi::Units::mm,1149.8*Gaudi::Units::mm,1149.8*Gaudi::Units::mm};
235 // double cryoMotherRout[] = {2890. *Gaudi::Units::mm, 2890. *Gaudi::Units::mm,2250. *Gaudi::Units::mm,2250. *Gaudi::Units::mm,2890. *Gaudi::Units::mm,2890. *Gaudi::Units::mm};
236 // double cryoMotherZplan[] = {-3490.*Gaudi::Units::mm,-2850.*Gaudi::Units::mm,-2849.*Gaudi::Units::mm, 2849.*Gaudi::Units::mm, 2850.*Gaudi::Units::mm, 3490.*Gaudi::Units::mm};
237
238 // Access source of detector parameters.
239 // VDetectorParameters* parameters = VDetectorParameters::GetInstance();
240
241 // Get the z-Shift from the detector parameters routine.
242 // double zShift = parameters->GetValue("LArEMECZshift");
243
244 // Adjust mother volume size.
245 // int lastPlaneCryo = ( sizeof(cryoMotherZplan) / sizeof(double) );
246 // cryoMotherZplan[lastPlaneCryo-1] += zShift;
247 // cryoMotherZplan[0] -= zShift;
248
249 double dphi_all = 2.*M_PI;
250
251 GeoPcon* cryoMotherShape =
252 new GeoPcon(0., // starting phi
253 dphi_all ); // total phi
254
255 for(unsigned int ind=0; ind<cryoMotherPlanes.size(); ind++)
256 {
257 iter = cryoMotherPlanes.find(ind);
258
259 if(iter==cryoMotherPlanes.end()) {
260 throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in CryoMother");
261 }
262 else {
263 currentRecord = (*cryoPcons)[(*iter).second];
264
265 cryoMotherShape->addPlane(currentRecord->getDouble("ZPLANE"),
266 currentRecord->getDouble("RMIN"),
267 currentRecord->getDouble("RMAX"));
268 }
269 }
270
271 // for ( int i = 0; i != lastPlaneCryo; ++i )
272 // {
273 // cryoMotherShape->addPlane(
274 // cryoMotherZplan[i], // position of z planes
275 // cryoMotherRin[i], // tangent distance to inner surface
276 // cryoMotherRout[i]); // tangent distance to outer surface
277 // }
278
279 const GeoLogVol* cryoMotherLogical =
280 new GeoLogVol(cryoMotherName, cryoMotherShape, Air);
281
282 m_cryoMotherPhysical = new GeoFullPhysVol(cryoMotherLogical);
283 //tag this volume as one that can be used as an envelope volume to add other volumes inside later
284 //(e.g. ITk and HGTD services built by other tools)
285 GeoVolumeTagCatalog::VolumeTagCatalog()->addTaggedVolume("Envelope","LArBarrel",m_cryoMotherPhysical);
286
287 // //
288 //--------------------------------------------------------------------------------------------------//
289
290 //--------------------------------------------------------------------------------------------------//
291 // Cylindrical layers for the cryo mother: //
292 //
293 for (unsigned int ind=0; ind < cryoCylinders->size(); ind++)
294 {
295 currentRecord = (*cryoCylinders)[ind];
296
297 if(currentRecord->getString("CYL_LOCATION")=="Barrel::CryoMother")
298 {
299
300 const GeoMaterial *material = materialManager->getMaterial(currentRecord->getString("MATERIAL"));
301
302 if (!material)
303 {
304 std::ostringstream errorMessage;
305 errorMessage << "Error in BarrelCrysostat Construction" << std::endl;
306 errorMessage << "Material " << currentRecord->getString("MATERIAL") << " is not found" << std::endl;
307 throw std::runtime_error(errorMessage.str().c_str());
308 }
309
310
311 std::ostringstream cylStream;
312 int cylID = currentRecord->getInt("CYL_ID");
313 cylStream << "LAr::Barrel::Cryostat::Cylinder::#" << cylID;
314 std::string cylName= cylStream.str();
315
316 int cylNumber = currentRecord->getInt("CYL_NUMBER");
317 double zMin = currentRecord->getDouble("ZMIN")*Gaudi::Units::cm;
318 double dZ = currentRecord->getDouble("DZ")*Gaudi::Units::cm;
319 double zInCryostat = zMin + dZ / 2.;
320
321 if(m_fullGeo){
322 if ((*cryoEars).size()>0 && cylID==1) {
323 const IRDBRecord * record = (*cryoEars)[0];
324 double rmin = record->getDouble("EARRMIN");
325 double rmax = record->getDouble("EARRMAX");
326 double zthick = record->getDouble("EARZTHICKNESS");
327 double yvert = record->getDouble("EARVERTICALEXTENT");
328 GeoTubs *tubs = new GeoTubs(rmin,
329 rmax,
330 zthick/ 2.,
331 (double) 0.,
332 dphi_all);
333
334 GeoBox *box = new GeoBox( rmax, yvert/2, rmax);
335
336 const GeoShape & shape = tubs->intersect(*box);
337 const GeoLogVol *logVol = new GeoLogVol ("LAr::Barrel::Cryostat::Sector::Ear",&shape, material);
338 GeoIntrusivePtr<GeoPhysVol>earPhysVol = new GeoPhysVol(logVol);
339
340 m_cryoMotherPhysical->add(new GeoNameTag(std::string("CryostatEarForward")));
341 m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
342 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
343 m_cryoMotherPhysical->add(earPhysVol);
344
345 m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("CryostatEarBackward")));
346 m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
347 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(-zInCryostat)));
348 m_cryoMotherPhysical->add(earPhysVol);
349 }
350
351 if ((*cryoEars).size() > 0 && cylID==6) {
352 const IRDBRecord * record = (*cryoEars)[0];
353 double rmin = record->getDouble("LEGRMIN");
354 double rmax = record->getDouble("LEGRMAX");
355 double zthick = record->getDouble("LEGZTHICKNESS");
356 double yvert = record->getDouble("LEGYMAX");
357 double angle = record->getDouble("LEGANGLE");
358
359 GeoTubs *tubs = new GeoTubs(rmin,
360 rmax,
361 zthick/ 2.,
362 -angle*(M_PI/180.0),
363 M_PI + 2*angle*(M_PI/180));
364
365 GeoTrf::TranslateY3D offset(rmax-yvert);
366 GeoBox * box = new GeoBox(rmax,rmax, rmax);
367 const GeoShape & shape = tubs->subtract((*box)<<offset);
368
369 const GeoLogVol *logVol = new GeoLogVol ("LAr::Barrel::Cryostat::Sector::Leg",&shape, material);
370 GeoIntrusivePtr<GeoPhysVol>legPhysVol = new GeoPhysVol(logVol);
371
372 m_cryoMotherPhysical->add(new GeoNameTag(std::string("CryostatLegForward")));
373 m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
374 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat+zthick)));
375 m_cryoMotherPhysical->add(legPhysVol);
376
377 m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("CryostatLegBackward")));
378 m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
379 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(-zInCryostat-zthick)));
380 m_cryoMotherPhysical->add(legPhysVol);
381 }
382 }
383
384 const GeoShape* solidBarrelCylinder = nullptr;
385 const GeoLogVol* logicBarrelCylinder = nullptr;
386
387 // For Reco Geometry construct only solenoid cylinders
388 if(m_fullGeo || (10<=cylID && cylID<=14)) {
389 solidBarrelCylinder
390 = new GeoTubs(currentRecord->getDouble("RMIN")*Gaudi::Units::cm,
391 currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm,
392 currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.,
393 (double) 0.,
394 dphi_all);
395 if(m_activateFT){
396 if(cylID == 7){ // Cut holes for feedthroughs in warm wall
397 ATH_MSG_DEBUG("Cut holes for feedthroughs in warm wall " << cylName);
398 const double rmin = currentRecord->getDouble("RMIN")*Gaudi::Units::cm;
399 const double rmax = currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm;
400 const double bellow_Router = 0.5*299.*Gaudi::Units::mm; // from DMconstruction
401 const double warmhole_radius = bellow_Router;
402 const double warmhole_pos = 4.*Gaudi::Units::cm;
403 GeoTube *warmhole = new GeoTube(0., warmhole_radius, (rmax - rmin) * 2);
404 const GeoShapeShift &h1 = (*warmhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
405 const double r = (rmin + rmax) * 0.5;
406 const GeoShape *warmwall = solidBarrelCylinder;
407 const double dphi = 4.*Gaudi::Units::deg;
408 const int NCrates = 16;
409 auto put = [&warmwall, &warmhole_pos, &r, &h1](double pos){
410 const double x = r*cos(pos);
411 const double y = r*sin(pos);
412 warmwall = &(warmwall->subtract(
413 h1 << GeoTrf::Translate3D(x, y, warmhole_pos)
414 *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
415 ));
416 };
417 for(int i = 0; i < NCrates; ++ i){
418 const double phi = 360.*Gaudi::Units::deg * i / NCrates;
419 put(phi - dphi);
420 put(phi + dphi);
421 }
422 solidBarrelCylinder = warmwall;
423 } else if(cylID == 2){ // Cut holes for feedthroughs in cold wall
424 ATH_MSG_DEBUG("Cut holes for feedthroughs in cold wall " << cylName);
425 const double rmin = currentRecord->getDouble("RMIN")*Gaudi::Units::cm;
426 const double rmax = currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm;
427 const double coldhole_radius = 0.5*150.*Gaudi::Units::mm; // see DMconstruction
428 const double coldhole_pos = 27.5*Gaudi::Units::mm;
429 GeoTube *coldhole = new GeoTube(0., coldhole_radius, (rmax - rmin) * 2);
430 const GeoShapeShift &h1 = (*coldhole) << GeoTrf::RotateX3D(90*Gaudi::Units::deg);
431 const double r = (rmin + rmax) * 0.5;
432 const GeoShape *coldwall = solidBarrelCylinder;
433 const double dphi = 4.*Gaudi::Units::deg;
434 const int NCrates = 16;
435 for(int i = 0; i < NCrates; ++ i){
436 const double phi = 360.*Gaudi::Units::deg * i / NCrates;
437 auto put = [&coldwall, &coldhole_pos, &r, &h1](double pos){
438 const double x = r*cos(pos);
439 const double y = r*sin(pos);
440 coldwall = &(coldwall->subtract(
441 h1 << GeoTrf::Translate3D(x, y, coldhole_pos)
442 *GeoTrf::RotateZ3D(pos + 90*Gaudi::Units::deg)
443 ));
444 };
445 put(phi - dphi);
446 put(phi + dphi);
447 }
448 solidBarrelCylinder = coldwall;
449 }
450 }
451
452 logicBarrelCylinder = new GeoLogVol(cylName,solidBarrelCylinder,material);
453 }
454
455 if(logicBarrelCylinder) {
456 // If ZMIN < 0 place the cylinder onse
457 // If ZMIN >=0 place each cylinder twice, at +z and -z.
458 if(zMin<0) {
459 GeoIntrusivePtr<GeoFullPhysVol> physBarrelCylinder = new GeoFullPhysVol(logicBarrelCylinder);
460
461 m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("Phys")));
462 m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
463
464 // put alignamble transform for cryostat cylinders 10<=cylID<=14
465 if(10<=cylID && cylID<=14)
466 m_cryoMotherPhysical->add(xfSolenoid);
467
468 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
469 m_cryoMotherPhysical->add(physBarrelCylinder);
470
471
472 // NOTE: there are 5 volumes for solenoid with NO common direct parent
473 // I'm storing the first one #10. (FIXME)
474 // NOTE: Pretty soon there will
475 // be no need at all to store physical volumes in the manager or in storegate!
476 if(cylID==10) {
477 StoredPhysVol *sPhysVol = new StoredPhysVol(physBarrelCylinder);
478 StatusCode status=detStore->record(sPhysVol,"SOLENOID");
479 if(!status.isSuccess()) throw std::runtime_error ("Cannot store SOLENOID");
480 }
481
482 }else{
483 GeoIntrusivePtr<GeoPhysVol> physBarrelCylinder = new GeoPhysVol(logicBarrelCylinder);
484
485 m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("PhysForward")));
486 m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
487 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
488 m_cryoMotherPhysical->add(physBarrelCylinder);
489
490 m_cryoMotherPhysical->add(new GeoNameTag(cylName+std::string("PhysBackward")));
491 m_cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
492 if(m_activateFT && (cylID == 2 || cylID == 7)){
493 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::RotateY3D(180.*Gaudi::Units::deg)));
494 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
495 } else {
496 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(-zInCryostat)));
497 }
498 m_cryoMotherPhysical->add(physBarrelCylinder);
499 }
500 }
501 }
502 } //
503 //--------------------------------------------------------------------------------------------------//
504
505 if(m_fullGeo) {
506 // Make a Polycon for the outer wall:
507 GeoPcon *outerWallPcon = new GeoPcon(0,dphi_all);
508
509 for(unsigned int ind=0; ind<outerWallPlanes.size(); ind++) {
510 iter = outerWallPlanes.find(ind);
511
512 if(iter==outerWallPlanes.end())
513 throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in OuterWall");
514 else {
515 currentRecord = (*cryoPcons)[(*iter).second];
516 outerWallPcon->addPlane(currentRecord->getDouble("ZPLANE"),
517 currentRecord->getDouble("RMIN"),
518 currentRecord->getDouble("RMAX"));
519 }
520 }
521
522 const GeoLogVol *outerWallLog = new GeoLogVol("LAr::Barrel::Cryostat::OuterWall", outerWallPcon, Aluminium);
523 m_cryoMotherPhysical->add(new GeoNameTag(std::string("Barrel Cryo OuterWall Phys")));
524 GeoIntrusivePtr<GeoPhysVol>outerWallPhys = new GeoPhysVol(outerWallLog);
525 m_cryoMotherPhysical->add(outerWallPhys);
526
527 // Make a Polycon for the inner wall:
528 GeoPcon *innerWallPcon = new GeoPcon(0,dphi_all);
529
530 for(unsigned int ind=0; ind<innerWallPlanes.size(); ind++) {
531 iter = innerWallPlanes.find(ind);
532
533 if(iter==innerWallPlanes.end())
534 throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in InnerWall");
535 else {
536 currentRecord = (*cryoPcons)[(*iter).second];
537 innerWallPcon->addPlane(currentRecord->getDouble("ZPLANE"),
538 currentRecord->getDouble("RMIN"),
539 currentRecord->getDouble("RMAX"));
540 }
541 }
542
543 const GeoLogVol *innerWallLog = new GeoLogVol("LAr::Barrel::Cryostat::InnerWall", innerWallPcon, Aluminium);
544 m_cryoMotherPhysical->add(new GeoNameTag(std::string("Barrel Cryo InnerWall Phys")));
545 GeoIntrusivePtr<GeoPhysVol>innerWallPhys = new GeoPhysVol(innerWallLog);
546 m_cryoMotherPhysical->add(innerWallPhys);
547
548 // Vis a la fin du cryostat
549
550 IRDBRecordset_ptr cryoBolts = rdbAccess->getRecordsetPtr("LArBarrelCryoBolts",
551 larVersionKey.tag(),
552 larVersionKey.node());
553 if (cryoBolts->size() >0) {
554 ATH_MSG_INFO(" new description with barrel croystat bolts");
555 const IRDBRecord * cryoBoltsRecord = (*cryoBolts) [0];
556 double rmax_vis = cryoBoltsRecord->getDouble("RBOLT");
557 int Nvis = cryoBoltsRecord->getInt("NBOLT");
558 double PhiPos0 = cryoBoltsRecord->getDouble("PHI0");
559 double RhoPosB = cryoBoltsRecord->getDouble("RADIUS");
560 int index1 = cryoBoltsRecord->getInt("INDEXWALL1");
561 int index2 = cryoBoltsRecord->getInt("INDEXWALL2");
562 const GeoMaterial *bolt_material = materialManager->getMaterial(cryoBoltsRecord->getString("MATERIAL"));
563 if (!bolt_material) {
564 throw std::runtime_error("Error in BarrelCryostatConstruction, material for bolt not found");
565 }
566
567
568 double z1=-1.;
569 double z2=-1.;
570 if ((iter = innerWallPlanes.find(index1))!= innerWallPlanes.end()) {
571 const IRDBRecord * pconsRecord = (*cryoPcons) [(*iter).second];
572 z1 = pconsRecord->getDouble("ZPLANE");
573 }
574 if ((iter = innerWallPlanes.find(index2))!= innerWallPlanes.end()) {
575 const IRDBRecord * pconsRecord = (*cryoPcons) [(*iter).second];
576 z2 = pconsRecord->getDouble("ZPLANE");
577 }
578 if (z1>0. && z2>0.) {
579 double zthick_vis=(z2-z1)-0.1;
580
581 GeoTubs *tub_vis = new GeoTubs(0.,rmax_vis,zthick_vis/2., (double) 0., dphi_all);
582 const GeoLogVol * log_vis = new GeoLogVol("LAr::Barrel::Cryostat::InnerWall::Vis",tub_vis,bolt_material);
583 GeoIntrusivePtr<GeoPhysVol> phys_vis = new GeoPhysVol(log_vis);
584
585 double xxVis=((double)(Nvis));
586 double ZposB=0.5*(z1+z2);
587 double twopi128 = 2.*M_PI/xxVis;
588 GeoGenfun::Variable i;
589 GeoGenfun::Mod Mod1(1.0),Mod128(xxVis),Mod2(2.0);
590 GeoGenfun::GENFUNCTION PhiPos = PhiPos0 + twopi128*Mod128(i);
591 GeoGenfun::GENFUNCTION Int = i - Mod1;
592 GeoGenfun::Cos Cos;
593 GeoGenfun::Sin Sin;
594 GeoXF::TRANSFUNCTION TX =
595 GeoXF::Pow(GeoTrf::TranslateX3D(1.0),RhoPosB*Cos(PhiPos))*
596 GeoXF::Pow(GeoTrf::TranslateY3D(1.0),RhoPosB*Sin(PhiPos))*
597 GeoXF::Pow(GeoTrf::TranslateZ3D(2*ZposB),Int(i/128))*
598 GeoTrf::TranslateZ3D(-ZposB);
599 GeoSerialTransformer *st = new GeoSerialTransformer(phys_vis, &TX, 2*Nvis);
600 innerWallPhys->add(st);
601 }
602 } // bolts found in the geometry database
603 else {
604 ATH_MSG_INFO(" old description withut bold in the geometry database ");
605 }
606
607
608 // extra Cone for systematics in upstream matter
609 IRDBRecordset_ptr extraCones = rdbAccess->getRecordsetPtr("LArCones",
610 larVersionKey.tag(),
611 larVersionKey.node());
612 if (extraCones->size() > 0 ) {
613 int nextra=0;
614 for(const IRDBRecord_ptr& cone : *extraCones) {
615 const std::string& conName = cone->getString("CONE");
616 if (conName.find("ExtraInCryo") != std::string::npos) {
617 nextra++;
618 double extra_dz = 0.5*( cone->getDouble("DZ") );
619 double extra_rmin1 = cone->getDouble("RMIN1");
620 double extra_rmin2 = cone->getDouble("RMIN2");
621 double extra_rmax1 = cone->getDouble("RMAX1");
622 double extra_rmax2 = cone->getDouble("RMAX2");
623 double extra_phi0 = cone->getDouble("PHI0");
624 double extra_dphi = cone->getDouble("DPHI");
625 double extra_zpos = cone->getDouble("ZPOS");
626 // GU 20-feb-06
627 // if extra_dphi is close to 2pi (6.283185) it seems safer for G4 navigation
628 // to impose exactly same dphi as mother volume instead of a sligthly smaller dphi
629 if (extra_dphi>6.2831) extra_dphi = dphi_all;
630 // std::cout << " rmin1,rmin2,rmax1,rmax2,dz,phi0,dphi,zpos " << extra_rmin1 << " " << extra_rmin2 << " "
631 // << extra_rmax1 << " " << extra_rmax2 << " " << extra_dz << " " << extra_phi0 << " "
632 // << extra_dphi << " " << extra_zpos << std::endl;
633 GeoCons* extraCons
634 = new GeoCons(extra_rmin1,extra_rmin2,extra_rmax1,extra_rmax2,extra_dz,extra_phi0,extra_dphi);
635
636 std::ostringstream extraStream;
637 extraStream << "LAr::Barrel::Cryostat::ExtraMat" << nextra;
638 std::string extraName= extraStream.str();
639 // std::cout << " extraName " << extraName << std::endl;
640
641 GeoLogVol* extraLog = new GeoLogVol(extraName,extraCons,Aluminium);
642 GeoIntrusivePtr<GeoPhysVol> extraPhys = new GeoPhysVol(extraLog);
643 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(extra_zpos)));
644 m_cryoMotherPhysical->add(extraPhys);
645 }
646 }
647 }
648
649 // Throw in coil support block
650 {
651 const GeoMaterial* myMaterial;
652 double length,height,width,pairSeparation,distFromRidge;
653 int nPairTot,indexWall;
654 IRDBRecordset_ptr newBlocks = rdbAccess->getRecordsetPtr("LArBarBumperBlocks", larVersionKey.tag(),larVersionKey.node());
655 if (newBlocks->size() >0 ) {
656 ATH_MSG_INFO(" new coil bumper description ");
657 const IRDBRecord * newBlocksRecord = (*newBlocks) [0];
658 length = newBlocksRecord->getDouble("LENGTH"); // deltaX
659 height = newBlocksRecord->getDouble("HEIGHT"); // delta Y
660 width = newBlocksRecord->getDouble("WIDTH"); // lenght in Z
661 pairSeparation = newBlocksRecord->getDouble("PAIRSEP");
662 distFromRidge = newBlocksRecord->getDouble("DISTANCEFROMRIDGE");
663 nPairTot = newBlocksRecord->getInt("NPAIRTOT");
664 indexWall = newBlocksRecord->getInt("INDEXWALL");
665 myMaterial = materialManager->getMaterial(newBlocksRecord->getString("MATERIAL"));
666 if (!myMaterial) {
667 throw std::runtime_error("Error in BarrelCryostatConstruction, material for coil bumpber not found");
668 }
669 }
670 else {
671 ATH_MSG_INFO(" old coil bumper description ");
672 IRDBRecordset_ptr tiBlocks = rdbAccess->getRecordsetPtr("TiBlocks", larVersionKey.tag(),larVersionKey.node());
673 const IRDBRecord * tiBlocksRecord = (*tiBlocks) [0];
674 length = tiBlocksRecord->getDouble("LENGTH"); // delta X
675 height = tiBlocksRecord->getDouble("HEIGHT"); // delta Y
676 width = tiBlocksRecord->getDouble("WIDTH"); // lenght in Z
677 pairSeparation = tiBlocksRecord->getDouble("PAIRSEP");
678 distFromRidge = tiBlocksRecord->getDouble("DISTANCEFROMRIDGE");
679 nPairTot = tiBlocksRecord->getInt("NPAIRTOT");
680 indexWall=8;
681 myMaterial=Titanium;
682 }
683
684 double r=-1.;
685 double z=-1.;
686 if ((iter = innerWallPlanes.find(indexWall))!= innerWallPlanes.end()) {
687 const IRDBRecord * pconsRecord = (*cryoPcons) [(*iter).second];
688 r = pconsRecord->getDouble("RMAX");
689 z = pconsRecord->getDouble("ZPLANE");
690 }
691
692 if (r>0.) {
693
694
695 // Make one block:
696 GeoBox *box = new GeoBox(length/2.0, height/2.0, width/2.0);
697 GeoLogVol *logVol = new GeoLogVol("LAr::Barrel::Cryostat::Sector::TitaniumBlock", box,myMaterial);
698 GeoIntrusivePtr<GeoPhysVol>physVol = new GeoPhysVol(logVol);
699
700 double angle=pairSeparation/r;
701 double pos = -z+width/2 + distFromRidge;
702// position of bumpers in new description
703 if (newBlocks->size() >0) {
704 GeoGenfun::Variable i; //
705 GeoGenfun::Mod Mod1(1.0),Mod2(2.0); //
706 GeoGenfun::GENFUNCTION Truncate = i - Mod1(i); //
707 GeoGenfun::GENFUNCTION AngleZ = -angle/2.+angle*Truncate(Mod2(i/2))+ 2.*M_PI/(1.0*nPairTot)*Truncate(i/4) + 2*M_PI/(2.*nPairTot);
708 GeoGenfun::GENFUNCTION TransZ = -pos + 2.*pos*Mod2(i);
709
710 TRANSFUNCTION tx =
711 GeoXF::Pow(GeoTrf::TranslateZ3D(1.0),TransZ)*
712 GeoXF::Pow(GeoTrf::RotateZ3D(1.0),AngleZ)*
713 GeoTrf::Translate3D(0.,r+height/2,0.);
714 GeoSerialTransformer *t = new GeoSerialTransformer(physVol, &tx, nPairTot*4);
715 m_cryoMotherPhysical->add(t);
716 }
717// position of bumper in old description
718 else {
719 GeoGenfun::Variable i; //
720 GeoGenfun::Mod Mod1(1.0),Mod2(2.0); //
721 GeoGenfun::GENFUNCTION Truncate = i - Mod1(i); //
722
723 TRANSFUNCTION tx =
724 Pow(GeoTrf::RotateZ3D(2*M_PI/nPairTot),Truncate(i/4))*
725 Pow(GeoTrf::RotateZ3D(angle),Mod2(i/2))*
726 GeoTrf::RotateZ3D(-angle/2)*
727 Pow(GeoTrf::TranslateZ3D(2*pos),Mod2(i))*
728 GeoTrf::Translate3D(0,r+height/2, -pos);
729 GeoSerialTransformer *t = new GeoSerialTransformer(physVol, &tx, nPairTot*4);
730 m_cryoMotherPhysical->add(t);
731 }
732
733 } // r>0.
734 else {
735 ATH_MSG_WARNING(" could not find wall index plane => no coil bumper description ");
736 }
737
738 } // end of coil supports
739
740
741 // Make a Polycon for the inner endwall:
742 if(!innerEndWallPlanes.empty()) {
743 GeoPcon *innerEndWallPcon = new GeoPcon(0,dphi_all);
744
745 for(unsigned int ind=0; ind<innerEndWallPlanes.size(); ind++) {
746 iter = innerEndWallPlanes.find(ind);
747
748 if(iter==innerEndWallPlanes.end())
749 throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in InnerEndWall");
750 else {
751 currentRecord = (*cryoPcons)[(*iter).second];
752 innerEndWallPcon->addPlane(currentRecord->getDouble("ZPLANE"),
753 currentRecord->getDouble("RMIN"),
754 currentRecord->getDouble("RMAX"));
755 }
756 }
757
758 const GeoLogVol *innerEndWallLog = new GeoLogVol("LAr::Barrel::Cryostat::InnerEndWall", innerEndWallPcon, Aluminium);
759 m_cryoMotherPhysical->add(new GeoNameTag(std::string("Barrel Cryo InnerEndWall Phys")));
760 GeoIntrusivePtr<GeoPhysVol>innerEndWallPhys = new GeoPhysVol(innerEndWallLog);
761 m_cryoMotherPhysical->add(innerEndWallPhys);
762 m_cryoMotherPhysical->add(new GeoTransform(GeoTrf::RotateY3D(M_PI)));
763 m_cryoMotherPhysical->add(innerEndWallPhys);
764 }
765
766 //------------------------------------------------------------------------------------------------//
767 /*if ((*idSupportRails).size()>0 && railrec->size() >0) {
768 } this part of code is moved into SupportRailFactory.cxx (InDetServMatGeoModel package) --- Adam Agocs */
769 } // if(m_fullGeo)
770 //--------------------------------------------------------------------------------------------------//
771
772 //--------------------------------------------------------------------------------------------------//
773 // The total liquid argon volume inside the cryostat. This will be
774 // sub-divided into sensitive-detector regions in the detector
775 // routine.
776
777 // double totalLArRin[] = { 1565.5*Gaudi::Units::mm, 1385.*Gaudi::Units::mm, 1385.*Gaudi::Units::mm, 1565.5*Gaudi::Units::mm };
778 // double totalLArRout[] = { 2140. *Gaudi::Units::mm, 2140.*Gaudi::Units::mm, 2140.*Gaudi::Units::mm, 2140. *Gaudi::Units::mm };
779 // double totalLArZplan[] = {-3267. *Gaudi::Units::mm,-3101.*Gaudi::Units::mm, 3101.*Gaudi::Units::mm, 3267. *Gaudi::Units::mm };
780
781 GeoPcon* totalLArShape =
782 new GeoPcon(0., // starting phi
783 dphi_all); // total phi
784
785 for(unsigned int ind=0; ind<totalLarPlanes.size(); ind++)
786 {
787 iter = totalLarPlanes.find(ind);
788
789 if(iter==totalLarPlanes.end())
790 throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in CryoMother");
791 else
792 {
793 currentRecord = (*cryoPcons)[(*iter).second];
794 totalLArShape->addPlane(currentRecord->getDouble("ZPLANE"),
795 currentRecord->getDouble("RMIN"),
796 currentRecord->getDouble("RMAX"));
797 }
798 }
799
800 std::string totalLArName = "LAr::Barrel::Cryostat::TotalLAr";
801 const GeoLogVol* totalLArLogical = new GeoLogVol(totalLArName, totalLArShape, LAr);
802
803 // When you place a polycone inside another polycone, the z=0
804 // co-ordinates will be the same. (Let's hope this is still true
805 // in GeoModel.)
806 m_cryoMotherPhysical->add(new GeoNameTag("Total LAR Volume"));
807 GeoIntrusivePtr<GeoPhysVol> totalLArPhysical = new GeoPhysVol(totalLArLogical);
808 m_cryoMotherPhysical->add(totalLArPhysical);
809 // //
810
811 // 19-Feb-2003 ML: mother volumes for halfBarrels
812
813 // To allow for mis-alignments, provide a 3mm gap at low z. (This
814 // is just a first pass; we may want to introduce other adjustments
815 // to this shape to allow for mis-alignments in other dimensions.)
816
817 // increase internal radius to allow misalignments
818 // ----------------------------------------------- double rInShift = 0.*Gaudi::Units::mm;
819
820 // double halfLArZplan[] = { 3.0 *Gaudi::Units::mm, 3101.*Gaudi::Units::mm, 3267. *Gaudi::Units::mm };
821 // double halfLArRin[] = {1385.*Gaudi::Units::mm + rInShift, 1385.*Gaudi::Units::mm + rInShift, 1565.5*Gaudi::Units::mm + rInShift};
822 // double halfLArRout[] = {2140.*Gaudi::Units::mm, 2140.*Gaudi::Units::mm, 2140. *Gaudi::Units::mm };
823
824 std::string halfLArName = "LAr::Barrel::Cryostat::HalfLAr";
825 GeoPcon* halfLArShape =
826 new GeoPcon(
827 0., // starting phi
828 dphi_all // total phi
829 );
830
831 for(unsigned int ind=0; ind<halfLarPlanes.size(); ind++)
832 {
833 iter = halfLarPlanes.find(ind);
834
835 if(iter==halfLarPlanes.end())
836 throw std::runtime_error("Error in BarrelCryostatConstruction, missing plane in CryoMother");
837 else
838 {
839 currentRecord = (*cryoPcons)[(*iter).second];
840 halfLArShape->addPlane(currentRecord->getDouble("ZPLANE"),
841 currentRecord->getDouble("RMIN"),
842 currentRecord->getDouble("RMAX"));
843 }
844 }
845
846 // Define logical volumes for both halves of the barrel.
847 const GeoLogVol* halfLArLogicalPos =
848 new GeoLogVol(halfLArName + "::Pos", halfLArShape, LAr);
849 GeoIntrusivePtr<GeoPhysVol> halfLArPhysicalPos = new GeoPhysVol(halfLArLogicalPos);
850
851 const GeoLogVol* halfLArLogicalNeg =
852 new GeoLogVol(halfLArName + "::Neg", halfLArShape, LAr);
853 GeoIntrusivePtr<GeoPhysVol> halfLArPhysicalNeg = new GeoPhysVol(halfLArLogicalNeg);
854
855 totalLArPhysical->add(new GeoNameTag(halfLArName + "::PosPhysical"));
856
857 // add alignable transform
858 totalLArPhysical->add(xfHalfLArPos);
859 totalLArPhysical->add(halfLArPhysicalPos);
860
861 totalLArPhysical->add(new GeoNameTag(halfLArName + "::NegPhysical"));
862
863 // add alignable transform
864 totalLArPhysical->add(xfHalfLArNeg);
865 totalLArPhysical->add( new GeoTransform(GeoTrf::RotateY3D(180.*Gaudi::Units::deg)) );
866 totalLArPhysical->add(halfLArPhysicalNeg);
867
868 {
869
870 // 27-Nov-2001 WGS: Place the barrel LAr and detector inside the cryostat.
871 // There are two placements: one for the z>0 section, one for the z<0 section.
872
873
874 BarrelConstruction barrelConstruction(m_fullGeo, params);
875 barrelConstruction.setBarrelSagging(m_barrelSagging);
876 barrelConstruction.setBarrelCellVisLimit(m_barrelVisLimit);
877
878
879 // The "envelope" determined by the EMB should be a GeoFullPhysVol.
880 GeoIntrusivePtr<GeoFullPhysVol> barrelPosEnvelope = barrelConstruction.GetPositiveEnvelope();
881 if ( barrelPosEnvelope)
882 halfLArPhysicalPos->add(barrelPosEnvelope);
883
884 // The "envelope" determined by the EMB should be a GeoFullPhysVol.
885 GeoIntrusivePtr<GeoFullPhysVol> barrelNegEnvelope = barrelConstruction.GetNegativeEnvelope();
886 if ( barrelNegEnvelope)
887 halfLArPhysicalNeg->add(barrelNegEnvelope);
888
889 if(m_fullGeo) {
890 //--------------------------------------------------------------------------------------------------//
891 // Cylindrical layers for half LAr
892 //
893 for (unsigned int ind=0; ind < cryoCylinders->size(); ind++) {
894 currentRecord = (*cryoCylinders)[ind];
895
896 if(currentRecord->getString("CYL_LOCATION")=="Barrel::HalfLAr"||
897 currentRecord->getString("CYL_LOCATION")=="Barrel::TotalLAr") {
898 bool isHalfLar = currentRecord->getString("CYL_LOCATION")=="Barrel::HalfLAr";
899
900 const GeoMaterial *material = materialManager->getMaterial(currentRecord->getString("MATERIAL"));
901
902 if (!material) {
903 std::ostringstream errorMessage;
904 errorMessage << "Error in BarrelCrysostat Construction" << std::endl;
905 errorMessage << "Material " << currentRecord->getString("MATERIAL") << " is not found" << std::endl;
906 throw std::runtime_error(errorMessage.str().c_str());
907 }
908
909 std::ostringstream cylStream;
910 cylStream << "LAr::Barrel::Cryostat::";
911
912 if (!currentRecord->isFieldNull("QUALIFIER")) {
913 const std::string& qualifier = currentRecord->getString("QUALIFIER");
914 if (!qualifier.empty()) cylStream << qualifier << "::";
915 }
916 cylStream << "Cylinder::#" << currentRecord->getInt("CYL_ID");
917 std::string cylName= cylStream.str();
918
919 GeoTubs* solidBarrelCylinder
920 = new GeoTubs(currentRecord->getDouble("RMIN")*Gaudi::Units::cm,
921 currentRecord->getDouble("RMIN")*Gaudi::Units::cm + currentRecord->getDouble("DR")*Gaudi::Units::cm,
922 currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.,
923 (double) 0.,
924 dphi_all);
925
926 const GeoLogVol* logicBarrelCylinder
927 = new GeoLogVol(cylName,solidBarrelCylinder,material);
928
929 GeoIntrusivePtr<GeoPhysVol> physBarrelCylinder = new GeoPhysVol(logicBarrelCylinder);
930
931 double zInCryostat = currentRecord->getDouble("ZMIN")*Gaudi::Units::cm + currentRecord->getDouble("DZ")*Gaudi::Units::cm / 2.;
932
933 int cylNumber = currentRecord->getInt("CYL_NUMBER");
934
935
936 if(isHalfLar) {
937 // Place each cylinder twice, once in each half-barrel:
938 halfLArPhysicalPos->add(new GeoNameTag(cylName+std::string("PhysForward")));
939 halfLArPhysicalPos->add(new GeoIdentifierTag(cylNumber));
940 // halfLArPhysicalPos->add(xfPos);
941 halfLArPhysicalPos->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
942 halfLArPhysicalPos->add(physBarrelCylinder);
943
944 halfLArPhysicalNeg->add(new GeoNameTag(cylName+std::string("PhysBackward")));
945 halfLArPhysicalNeg->add(new GeoIdentifierTag(cylNumber));
946 // halfLArPhysicalNeg->add(xfNeg);
947 halfLArPhysicalNeg->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
948 halfLArPhysicalNeg->add(physBarrelCylinder);
949 } else {
950 totalLArPhysical->add(new GeoNameTag(cylName+std::string("PhysForward")));
951 totalLArPhysical->add(new GeoIdentifierTag(cylNumber));
952 totalLArPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
953 totalLArPhysical->add(physBarrelCylinder);
954
955 totalLArPhysical->add(new GeoNameTag(cylName+std::string("PhysBackward")));
956 totalLArPhysical->add(new GeoIdentifierTag(cylNumber));
957 totalLArPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(-zInCryostat)));
958 totalLArPhysical->add(physBarrelCylinder);
959 }
960 }
961 } //
962 //--------------------------------------------------------------------------------------------------//
963 }
964
965 }
966 {
967 // ----- Presampler ------
968 double PresamplerMother_length = 1549.0*Gaudi::Units::mm; // Copied from PresParameterDef.icc
969 double presamplerShift = 3.*Gaudi::Units::mm;
970 BarrelPresamplerConstruction barrelPSConstruction(m_fullGeo, params);
971
972 // The "envelope" determined by the EMB should be a GeoFullPhysVol.
973 GeoIntrusivePtr<GeoFullPhysVol> barrelPSPosEnvelope = barrelPSConstruction.GetPositiveEnvelope();
974 GeoTransform *xfPos = new GeoTransform(GeoTrf::Transform3D(GeoTrf::TranslateZ3D(PresamplerMother_length+presamplerShift)));
975 {
976 halfLArPhysicalPos->add(xfPos);
977 //halfLArPhysicalPos->add(new GeoNameTag("PositivePSBarrel"));
978 halfLArPhysicalPos->add(barrelPSPosEnvelope);
979
980 StoredPhysVol *sPhysVol = new StoredPhysVol(barrelPSPosEnvelope);
981 StatusCode status=detStore->record(sPhysVol,"PRESAMPLER_B_POS");
982 if(!status.isSuccess()) throw std::runtime_error ("Cannot store PRESAMPLER_B_POS");
983 }
984 // The "envelope" determined by the EMB should be a GeoFullPhysVol.
985 GeoIntrusivePtr<GeoFullPhysVol> barrelPSNegEnvelope = barrelPSConstruction.GetNegativeEnvelope();
986 GeoTransform *xfNeg = new GeoTransform(GeoTrf::Transform3D(GeoTrf::TranslateZ3D(PresamplerMother_length+presamplerShift)));
987 {
988 halfLArPhysicalNeg->add(xfNeg);
989 //halfLArPhysicalPos->add(new GeoNameTag("NegativePSBarrel"));
990 halfLArPhysicalNeg->add(barrelPSNegEnvelope);
991
992 StoredPhysVol *sPhysVol = new StoredPhysVol(barrelPSNegEnvelope);
993 StatusCode status=detStore->record(sPhysVol,"PRESAMPLER_B_NEG");
994 if(!status.isSuccess()) throw std::runtime_error ("Cannot store PRESAMPLER_B_NEG");
995 }
996
997 }
998
999 // SCT-EC Cooling
1000 IRDBRecordset_ptr cryoPconPhiSect = rdbAccess->getRecordsetPtr("CryoPconPhiSect", larVersionKey.tag(),larVersionKey.node());
1001 if ((*cryoPconPhiSect).size()!=0){
1002 for(unsigned i=0; i<cryoPconPhiSect->size(); ++i) {
1003 double startPhi = (*cryoPconPhiSect)[i]->getDouble("STARTPHI");
1004 double dPhi = (*cryoPconPhiSect)[i]->getDouble("DPHI");
1005 double centerPhi = startPhi + 0.5*dPhi;
1006
1007 const GeoMaterial* material = materialManager->getMaterial((*cryoPconPhiSect)[i]->getString("MATERIAL"));
1008 if (!material) {
1009 std::string message = std::string("Error in BarrelCryostatConstruction! ") + (*cryoPconPhiSect)[i]->getString("MATERIAL") + std::string(" is not found.");
1010 throw std::runtime_error(message.c_str());
1011 }
1012
1013 GeoPcon* pcon = new GeoPcon(startPhi*Gaudi::Units::deg,dPhi*Gaudi::Units::deg);
1014
1015 for(unsigned int ii=0; ii<sctEcCoolingPlanes.size(); ii++) {
1016 iter = sctEcCoolingPlanes.find(ii);
1017
1018 if(iter==sctEcCoolingPlanes.end()) {
1019 std::ostringstream stream;
1020 stream << "Error in BarrelCryostatConstruction, missing plane " << ii <<" in SCT-EC cooling";
1021 throw std::runtime_error(stream.str().c_str());
1022 }
1023 else {
1024 currentRecord = (*cryoPcons)[(*iter).second];
1025 pcon->addPlane(currentRecord->getDouble("ZPLANE"),
1026 currentRecord->getDouble("RMIN"),
1027 currentRecord->getDouble("RMAX"));
1028 }
1029 } // iterate over planes
1030
1031 const GeoLogVol* sctCiCoolingLog = new GeoLogVol("LAr::Barrel::Cryostat::SctCiCooling",pcon,material);
1032 GeoIntrusivePtr<GeoPhysVol> sctCiCoolingPhys = new GeoPhysVol(sctCiCoolingLog);
1033
1034 GeoTransform* xfPos1 = new GeoTransform(GeoTrf::Transform3D::Identity());
1035 GeoTransform* xfPos2 = new GeoTransform(GeoTrf::RotateZ3D(180*Gaudi::Units::deg));
1036 GeoTransform* xfNeg1 = new GeoTransform(GeoTrf::RotateZ3D((180+2*centerPhi)*Gaudi::Units::deg)*GeoTrf::RotateY3D(180*Gaudi::Units::deg));
1037 GeoTransform* xfNeg2 = new GeoTransform(GeoTrf::RotateZ3D(2*centerPhi*Gaudi::Units::deg)*GeoTrf::RotateY3D(180*Gaudi::Units::deg));
1038
1039 m_cryoMotherPhysical->add(xfPos1);
1040 m_cryoMotherPhysical->add(sctCiCoolingPhys);
1041 m_cryoMotherPhysical->add(xfPos2);
1042 m_cryoMotherPhysical->add(sctCiCoolingPhys);
1043 m_cryoMotherPhysical->add(xfNeg1);
1044 m_cryoMotherPhysical->add(sctCiCoolingPhys);
1045 m_cryoMotherPhysical->add(xfNeg2);
1046 m_cryoMotherPhysical->add(sctCiCoolingPhys);
1047 } // iterate over Phi Sections
1048 }
1049 else {
1050 ATH_MSG_DEBUG("CryoPconPhiSect table not found - not building SCT cooling ");
1051 }
1052
1053
1054 if(!rdbAccess->getChildTag("LArBarrelDM",larVersionKey.tag(),larVersionKey.node()).empty() && m_fullGeo) {
1055 // Dead material in barrel
1056 CrackDMConstruction crackDMConstruction(rdbAccess,geoModel,materialManager,m_activateFT);
1057 crackDMConstruction.create(m_cryoMotherPhysical);
1058 }
1059
1060 return m_cryoMotherPhysical;
1061}
#define M_PI
Scalar phi() const
phi method
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::map< int, unsigned int, std::less< int > > planeIndMap
Declaration of BarrelCryostatConstruction class.
Declaration of BarrelPresamplerConstruction class.
static const unsigned int NCrates
double length(const pvec &v)
Definition of the abstract IRDBAccessSvc interface.
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition of the abstract IRDBRecord interface.
Definition of the abstract IRDBRecordset interface.
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
const double width
#define y
#define x
#define z
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
void create(GeoFullPhysVol *envelope)
This is a helper class to query the version tags from GeoModelSvc and determine the appropriate tag a...
const std::string & tag() const
Return version tag.
const std::string & node() const
Return the version node.
static const IRDBRecord * getTransformRecord(IRDBRecordset_ptr positionRecSet, const std::string &key)
Definition GeoDBUtils.h:23
static GeoTrf::Transform3D getTransform(const IRDBRecord *currentRec)
Definition GeoDBUtils.h:33
IRDBRecord is one record in the IRDBRecordset object.
Definition IRDBRecord.h:27
virtual const std::string & getString(const std::string &fieldName) const =0
Get string field value.
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.
virtual double getDouble(const std::string &fieldName) const =0
Get double field value.
virtual unsigned int size() const =0
GeoIntrusivePtr< GeoFullPhysVol > GetPositiveEnvelope()
void setBarrelCellVisLimit(int maxCell)
GeoIntrusivePtr< GeoFullPhysVol > GetNegativeEnvelope()
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope(const VDetectorParameters *params)
BarrelCryostatConstruction(bool fullGeo, bool activateFT=false)
GeoModel description of the LAr Barrel Presampler.
GeoIntrusivePtr< GeoFullPhysVol > GetNegativeEnvelope()
GeoIntrusivePtr< GeoFullPhysVol > GetPositiveEnvelope()
This class holds one or more material managers and makes them storeable, under StoreGate.
virtual const GeoMaterial * getMaterial(const std::string &name)=0
int r
Definition globals.cxx:22