ATLAS Offline Software
Loading...
Searching...
No Matches
LArGeo::EndcapCryostatConstruction Class Reference

Description of the LAr End Cap cryostat, including MBTS description. More...

#include <EndcapCryostatConstruction.h>

Collaboration diagram for LArGeo::EndcapCryostatConstruction:

Public Member Functions

 EndcapCryostatConstruction (bool fullGeo, std::string emecVariantInner="Wheel", std::string emecVariantOuter="Wheel", bool activateFT=false, bool enableMBTS=true)
 ~EndcapCryostatConstruction ()=default
 EndcapCryostatConstruction (const EndcapCryostatConstruction &)=delete
EndcapCryostatConstructionoperator= (const EndcapCryostatConstruction &)=delete
GeoIntrusivePtr< GeoFullPhysVol > createEnvelope (bool bPos)
virtual GeoIntrusivePtr< GeoFullPhysVol > GetEnvelope ()
void setFCALVisLimit (int limit)

Static Private Member Functions

static GeoIntrusivePtr< GeoPhysVol > buildMbtsTrd (const IRDBRecord *rec, StoredMaterialManager *matmanager, GeoIntrusivePtr< GeoPhysVol > parent)

Private Attributes

int m_fcalVisLimit
EMECConstruction m_emec
HEC2WheelConstruction m_hec2
FCALConstruction m_fcal
bool m_fullGeo
std::string m_EMECVariantInner
std::string m_EMECVariantOuter
bool m_activateFT
bool m_enableMBTS

Friends

class ::LArDetectorToolNV

Detailed Description

Description of the LAr End Cap cryostat, including MBTS description.

Definition at line 31 of file EndcapCryostatConstruction.h.

Constructor & Destructor Documentation

◆ EndcapCryostatConstruction() [1/2]

LArGeo::EndcapCryostatConstruction::EndcapCryostatConstruction ( bool fullGeo,
std::string emecVariantInner = "Wheel",
std::string emecVariantOuter = "Wheel",
bool activateFT = false,
bool enableMBTS = true )

◆ ~EndcapCryostatConstruction()

LArGeo::EndcapCryostatConstruction::~EndcapCryostatConstruction ( )
default

◆ EndcapCryostatConstruction() [2/2]

LArGeo::EndcapCryostatConstruction::EndcapCryostatConstruction ( const EndcapCryostatConstruction & )
delete

Member Function Documentation

◆ buildMbtsTrd()

GeoIntrusivePtr< GeoPhysVol > LArGeo::EndcapCryostatConstruction::buildMbtsTrd ( const IRDBRecord * rec,
StoredMaterialManager * matmanager,
GeoIntrusivePtr< GeoPhysVol > parent )
staticprivate

Definition at line 1078 of file EndcapCryostatConstruction.cxx.

1081{
1082 // Construct the Trd
1083 double dx1 = rec->getDouble("DX1");
1084 double dx2 = rec->getDouble("DX2");
1085 double dy1 = rec->getDouble("DY1");
1086 double dy2 = rec->getDouble("DY2");
1087 double dz = rec->getDouble("DZ");
1088 GeoTrd* solid = new GeoTrd(dx1,dx2,dy1,dy2,dz);
1089 GeoLogVol* lv = new GeoLogVol(rec->getString("TRD")
1090 ,solid
1091 ,matmanager->getMaterial(rec->getString("MATERIAL")));
1092 GeoIntrusivePtr<GeoPhysVol> pv = new GeoPhysVol(lv);
1093 if(parent) {
1094 double xpos = rec->getDouble("XPOS");
1095 double ypos = rec->getDouble("YPOS");
1096 double zpos = rec->getDouble("ZPOS");
1097 parent->add(new GeoTransform(GeoTrf::TranslateZ3D(zpos)*GeoTrf::TranslateY3D(ypos)*GeoTrf::TranslateX3D(xpos)));
1098 parent->add(pv);
1099 }
1100 return pv;
1101}
static std::map< double, LArWheelSliceSolid * > solid
virtual const std::string & getString(const std::string &fieldName) const =0
Get string field value.
virtual double getDouble(const std::string &fieldName) const =0
Get double field value.
virtual const GeoMaterial * getMaterial(const std::string &name)=0

◆ createEnvelope()

GeoIntrusivePtr< GeoFullPhysVol > LArGeo::EndcapCryostatConstruction::createEnvelope ( bool bPos)

Definition at line 89 of file EndcapCryostatConstruction.cxx.

90{
91 // Get access to the material manager:
92 MsgStream log(Athena::getMessageSvc(), "LArGeo::EndcapCryostatConstruction");
93 log << MSG::DEBUG << "started" << endmsg;
94
95
96 SmartIF<StoreGateSvc> detStore{Gaudi::svcLocator()->service("DetectorStore")};
97 if(!detStore.isValid()) {
98 throw std::runtime_error("Error in EndcapCryostatConstruction, cannot access DetectorStore");
99 }
100
101 // Get the materials from the material manager:-----------------------------------------------------//
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
143 std::string AtlasVersion = geoModelSvc->atlasVersion();
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 // Deal with Pcons
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 // Define geometry
203
204 // Set up strings for volume names.
205 std::string baseName = "LAr::Endcap::Cryostat";
206
207 // Define the mother volume for the endcap cryostat. Everything
208 // else in the endcap (cryostat walls, detectors, etc.) should be
209 // placed inside here.
210
211 // The position of this volume may change if the thickness of the
212 // cabling in front of the endcaps changes. Therefore, we must get
213 // the z-shift from the database and adjust the volume geometry
214 // accordingly.
215
216 std::string cryoMotherName = baseName + "::MotherVolume";
217 GeoPcon* cryoMotherShape = new GeoPcon(0.,2.*M_PI);
218
219 double zStartCryoMother = 0.; // This variable is needed to calculate local transform of the MBTS mother
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 /* This sould be corrected in the DB, but we have no time */
233 if(m_activateFT){
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 //JT. 04.2013
254 // insert extra material in form of Tubes
255 // between warm and cold wall in front of Emec Presampler
256 // ( walls : warm(cylNumber=3), cold(cylNumber=14)
257 // in case of negative value of the thickness, no volume will be created
258 //
259
260 // Extra cylinders
261
262 IRDBRecordset_ptr cryoExtraCyl = rdbAccessSvc->getRecordsetPtr("LArCones",detectorKey, detectorNode);
263
264 if(m_fullGeo && cryoCylinders->size()>0){
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"); //PS rmin
273 double rmax=(*cryoExtraCyl)[i]->getDouble("RMAX1"); //PS rmax
274 double dz = (*cryoExtraCyl)[i]->getDouble("DZ"); //leadthickness
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"); //lead
317 const GeoMaterial *mat = materialManager->getMaterial(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 } // warm cold walls found
344 } // dz>0. , extra cyl. thickness is positive
345 } //CylBeforePS ; extracyl is defined in the db record
346 if(finloop) break;
347 } // loop for extra cyls in the db record
348 } // number of items in the db record >0
349 else {
350 log << MSG::DEBUG << "no extra material in front of PS" << endmsg;
351 }
352 } // fullgeo is required and cryocyl reciord is not empty
353
354 // end of inserting extra lead plate before PS
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 // 100 - is the piece of Shielding. We need to build it for minimal geo too
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
371 if(!currentRecord->isFieldNull("QUALIFIER")){
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
392 if(m_activateFT){ // need to cut holes in cryostat walls for FT
393 if(cylNumber == 13){ // warm wall
394 log << MSG::DEBUG << "Cut holes for feedthroughs in warm wall "
395 << cylName
396 << endmsg;
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){
408 const double x = r*cos(pos), y = r*sin(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){ // topmost crate has one FT
418 put(phi + dphi); // asymmetric, see DMConstruction
419 } else {
420 put(phi - dphi);
421 put(phi + dphi);
422 }
423 }
424 solidCyl = warmwall;
425 } else if(cylNumber == 20){ // cold wall
426 log << MSG::DEBUG << "Cut holes for feedthroughs in cold wall "
427 << cylName
428 << endmsg;
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){
439 const double x = r*cos(pos), 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 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){ // topmost crate has one FT
449 put(phi + dphi); // asymmetric, see DMConstruction
450 } else {
451 put(phi - dphi);
452 put(phi + dphi);
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 // Don't move the pump even if the rest of the cryostat moves.
465
466 //if ( cylNumber == 33 ) zInCryostat -= zEmec;
467
468 // Place each cylinder.
469
470 cryoMotherPhysical->add(new GeoIdentifierTag(cylNumber));
471 cryoMotherPhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zInCryostat)));
472
473 // Front cold wall of Cryostat is a mother for Endcap Presampler
474 if ( cylNumber == 14 ) {
475 // its PhysicalVolume has a special name
476 cryoMotherPhysical->add( new GeoNameTag(cylName + "::PresamplerMother") );
477
478 EndcapPresamplerConstruction endcapPresamplerConstruction;
479
480 GeoIntrusivePtr<GeoFullPhysVol> emecPSEnvelope = endcapPresamplerConstruction.Envelope();
481 if (emecPSEnvelope) {
482 // Get the position of the presampler from the geometry helper.
483 double Zpos = 30.5*Gaudi::Units::mm;
484
485 // It is highly debateable whether the endcap presampler is
486 // alignable, but in any case we shall not align it here because
487 // we need to completely redo it, anyway, since it does not
488 // even live "in" this volume, not in real life anyway.
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);
498 status=detStore->record(sPhysVol,tag);
499 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
500 }
501 }
502
503 // After we've added any additional sub-volumes, add the cylinder.
504 cryoMotherPhysical->add(physCyl);
505 }
506 }
507 }
508
509 // g.p., 3-Apr-2006
510 // placing Pcones for FCAL nose, instead of cylinders 34,28,29
511 if(m_fullGeo)
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"),
522 currentRecord->getDouble("RMIN"),
523 currentRecord->getDouble("RMAX"));
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 // There are two LAr regions within the endcap cryostat. The first
535 // is the region that contains the EMEC and HEC (the electromagnetic
536 // and hadronic endcap calorimeters, respectively). The second is
537 // the region that contains the forward calorimeter.
538
539 // This volumes will be sub-divided into sensitive-detector regions
540 // in the detector.
541
542 // EMEC + HEC:
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"),
556 currentRecord->getDouble("RMIN"),
557 currentRecord->getDouble("RMAX"));
558 }
559 }
560
561 const GeoLogVol* totalEMHLArLogical =
562 new GeoLogVol(totalEMHLArName, totalEMHLArShape, LAr);
563
564 GeoIntrusivePtr<GeoFullPhysVol> totalEMHLArPhysical = new GeoFullPhysVol(totalEMHLArLogical);
565
566 // Add brass plugs
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"),
584 currentRecord->getDouble("RMIN"),
585 currentRecord->getDouble("RMAX"));
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
595 if(m_activateFT){
596 // this ring emulates signal cables concentration area
597 // nearby the theedtrougs inside the cryostat
598 const double rcoldwall = 2155.*Gaudi::Units::mm;
599 const double coldhole_radius = 0.5*150.*Gaudi::Units::mm; // copied from above
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 {
619 m_emec.setFullGeo(m_fullGeo);
620 m_emec.setInnerVariant(m_EMECVariantInner);
621 m_emec.setOuterVariant(m_EMECVariantOuter);
622 GeoIntrusivePtr<GeoFullPhysVol>envelope = m_emec.GetEnvelope(bPos);
623
624 //=>
625 const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(larPosition, bPos ? "EMEC_POS":"EMEC_NEG");
626 if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
627 GeoTrf::Transform3D xfPos = GeoDBUtils::getTransform(posRec);
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);
634 status=detStore->record(sPhysVol,tag);
635 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag).c_str());
636
637 StoredAlignX *sAlignX = new StoredAlignX(xfEmec);
638 status=detStore->record(sAlignX,tag);
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 //--- Make the Front Wheel alignable:
658
659 const IRDBRecord *posHec1 = GeoDBUtils::getTransformRecord(larPosition, bPos ? "HEC1_POS":"HEC1_NEG");
660 GeoTrf::Transform3D xfPosHec1 = posHec1 ? GeoDBUtils::getTransform(posHec1) : GeoTrf::Translate3D(0.,0.,-2423.0);
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);
666 status=detStore->record(sPhysVol1,tag1);
667 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag1).c_str());
668
669 StoredAlignX *sAlignX1 = new StoredAlignX(xfHec1);
670 status=detStore->record(sAlignX1,tag1);
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
684 const IRDBRecord *posHec2 = GeoDBUtils::getTransformRecord(larPosition, bPos ? "HEC2_POS":"HEC2_NEG");
685 GeoTrf::Transform3D xfPosHec2 = posHec2 ? GeoDBUtils::getTransform(posHec2) : GeoTrf::Translate3D(0.,0.,-1566.0);
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);
691 status=detStore->record(sPhysVol2,tag2);
692 if(!status.isSuccess()) throw std::runtime_error ((std::string("Cannot store")+tag2).c_str());
693
694 StoredAlignX *sAlignX2 = new StoredAlignX(xfHec2);
695 status=detStore->record(sAlignX2,tag2);
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 // 13-Mar-2002 WGS: Place the FCAL detector inside the cryostat.
708 m_fcal.setFCALVisLimit(m_fcalVisLimit);
709 m_fcal.setFullGeo(m_fullGeo);
710 {
711
712 // The "envelope" determined by the EMB should be a GeoFullPhysVol.
713 GeoIntrusivePtr<GeoVFullPhysVol> fcalEnvelope = m_fcal.GetEnvelope(bPos);
714
715 /* For now, comment out the FCAL placement, for two reasons:
716 1) The FCAL geometry helper class has been written yet;
717 2) Reconstruction needs each FCAL module to have a
718 separate alignable envelope. We'll work out t hese
719 issues later. */
720
721
722 // From FCALConstruction.cxx: */
723 //
724
725 std::string tag = bPos ? "FCAL_POS" : "FCAL_NEG";
726 // Get default values for alignable transform deltas from SubdetPosHelper
727 const IRDBRecord *posRec = GeoDBUtils::getTransformRecord(std::move(larPosition), tag);
728 if (!posRec) throw std::runtime_error("Error, no lar position record in the database") ;
729 GeoTrf::Transform3D xfPos = GeoDBUtils::getTransform(posRec);
730 GeoAlignableTransform *fcalXF = new GeoAlignableTransform(xfPos);
731
733 StoredAlignX *sAlignX = new StoredAlignX(fcalXF);
734 status=detStore->record(sAlignX,tag);
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 // Place the FCAL modules.
747 cryoMotherPhysical->add(fcalXF);
748 cryoMotherPhysical->add( new GeoTransform( GeoTrf::TranslateZ3D(tubs->getZHalfLength()) ) );
749 cryoMotherPhysical->add( fcalEnvelope );
750
751
752 }
753
754 //__________________________ MBTS+moderator+JM tube _____________________________________
755 if(m_enableMBTS && !rdbAccessSvc->getChildTag("MBTS",detectorKey, detectorNode).empty()) {
756 // DB related stuff first
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; // Used in the new description only
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 // Build material geometry only if the FullGeo flag has been set
771 if(m_fullGeo) {
772 // Define iterators
773 IRDBRecordset::const_iterator itMother = mbtsTubs->end();
774 IRDBRecordset::const_iterator itModerator = mbtsTubs->end();
775 IRDBRecordset::const_iterator itTube=mbtsTubs->end();
776
778 IRDBRecordset::const_iterator last = mbtsTubs->end();
779
780 // Mother volume
781 GeoIntrusivePtr<GeoPhysVol> pvMM = nullptr;
782
783 if(mbtsPcons->size()==0) {
784 // ****
785 // In this description the Moderator and the JM tube are constructed as separate volumes (both of them are tubes)
786 // ****
787
788 for(; first!=last; ++first) {
789 const std::string& strTubeName = (*first)->getString("TUBE");
790 if(strTubeName == "MBTS_mother") {
791 itMother = first;
792 }
793 else if(strTubeName == "Moderator") {
794 itModerator = first;
795 }
796 else if(strTubeName == "JMTUBE") {
797 itTube = first;
798 }
799 }
800
801 // Build mother volume
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 // Moderator cylinder
835 //double rminMod = (*itModerator)->getDouble("RMIN")*Gaudi::Units::mm;
836 //double rmaxMod = (*itModerator)->getDouble("RMAX")*Gaudi::Units::mm;
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 // In this description the Moderator and the JM tube are constructed one polycone + one extra part for the moderator
859 // ****
860
861 planeIndMap mbtsMotherPlanes, jmTubePlanes;
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 // construct shapes for the MBTS mother and Moderator+JM
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"),
886 currentRecord->getDouble("RMIN"),
887 currentRecord->getDouble("RMAX"));
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"),
902 currentRecord->getDouble("RMIN"),
903 currentRecord->getDouble("RMAX"));
904 }
905 }
906
907 // Construct volumes:
908
909 // Mother
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 // Extra tube for the moderator:
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 // Moderator+JM polycone
931 GeoLogVol* lvMod = new GeoLogVol("ModeratorJMPcon",solidMod, matJM);
932 GeoIntrusivePtr<GeoPhysVol> pvMod = new GeoPhysVol(lvMod);
933
934 pvMM->add(pvMod);
935 }
936
937 // Scintillators
938 if(mbtsGen->size()==0) {
939 // The "old" description: just scintillators, no aluminum envelopes
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 {
954 if(!curScin->isFieldNull("STARTPHI"))
955 startPhi = curScin->getDouble("STARTPHI");
956 }
957 catch(std::runtime_error&) {}
958
959 const GeoMaterial *matScin = materialManager->getMaterial(curScin->getString("MATERIAL"));
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 // parameterizations
970 double deltaPhi = 360./nScin;
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 // The "new" description: scintillators + aluminum envelopes + plastic plugs + aluminum press bars (only for RUN1)
990
991 // General parameters
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 // Build the air envelope first
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];
1004 pvAirEnv = buildMbtsTrd(rec,materialManager,nullptr);
1005
1006 // Build direct children of the air envelope
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 // Build direct children of the aluminum envelope
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 // Build direct children of the 'air-in-aluminum'
1029 for(itTrdMap=trdMap.begin();itTrdMap!=trdMap.end();++itTrdMap) {
1030 rec = (*mbtsTrds)[itTrdMap->second];
1031 if(rec->getString("PARENT")=="MBTSAirInAlu")
1032 buildMbtsTrd(rec,materialManager,pvAirInAlu);
1033 }
1034
1035 // parameterizations
1036 double deltaPhi = 360./nAirEnv;
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 } // if(m_fullGeo)
1054
1055 // Build readout for MBTS
1056 // Do it only once for both A and C sides
1057 if(bPos) {
1058 if(LArGeo::buildMbtsReadout(detStore
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 // Build endcap dead matter around the cryostat
1072 EndcapDMConstruction crateBuilder(m_activateFT);
1073 crateBuilder.create(cryoMotherPhysical);
1074
1075 return cryoMotherPhysical;
1076}
#define M_PI
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar phi() const
phi method
#define endmsg
std::map< int, unsigned int, std::less< int > > planeIndMap
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
#define y
#define x
GeoIntrusivePtr< GeoFullPhysVol > Envelope()
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
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)
int r
Definition globals.cxx:22
IMessageSvc * getMessageSvc(bool quiet=false)
bool first
Definition DeMoScan.py:534
::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)
@ layer
Definition HitInfo.h:79
status
Definition merge.py:16

◆ GetEnvelope()

virtual GeoIntrusivePtr< GeoFullPhysVol > LArGeo::EndcapCryostatConstruction::GetEnvelope ( )
inlinevirtual

Definition at line 50 of file EndcapCryostatConstruction.h.

50{ return GeoIntrusivePtr<GeoFullPhysVol>{};}

◆ operator=()

EndcapCryostatConstruction & LArGeo::EndcapCryostatConstruction::operator= ( const EndcapCryostatConstruction & )
delete

◆ setFCALVisLimit()

void LArGeo::EndcapCryostatConstruction::setFCALVisLimit ( int limit)
inline

◆ ::LArDetectorToolNV

friend class ::LArDetectorToolNV
friend

Definition at line 71 of file EndcapCryostatConstruction.h.

Member Data Documentation

◆ m_activateFT

bool LArGeo::EndcapCryostatConstruction::m_activateFT
private

Definition at line 68 of file EndcapCryostatConstruction.h.

◆ m_emec

EMECConstruction LArGeo::EndcapCryostatConstruction::m_emec
private

Definition at line 60 of file EndcapCryostatConstruction.h.

◆ m_EMECVariantInner

std::string LArGeo::EndcapCryostatConstruction::m_EMECVariantInner
private

Definition at line 65 of file EndcapCryostatConstruction.h.

◆ m_EMECVariantOuter

std::string LArGeo::EndcapCryostatConstruction::m_EMECVariantOuter
private

Definition at line 66 of file EndcapCryostatConstruction.h.

◆ m_enableMBTS

bool LArGeo::EndcapCryostatConstruction::m_enableMBTS
private

Definition at line 69 of file EndcapCryostatConstruction.h.

◆ m_fcal

FCALConstruction LArGeo::EndcapCryostatConstruction::m_fcal
private

Definition at line 62 of file EndcapCryostatConstruction.h.

◆ m_fcalVisLimit

int LArGeo::EndcapCryostatConstruction::m_fcalVisLimit
private

Definition at line 58 of file EndcapCryostatConstruction.h.

◆ m_fullGeo

bool LArGeo::EndcapCryostatConstruction::m_fullGeo
private

Definition at line 64 of file EndcapCryostatConstruction.h.

◆ m_hec2

HEC2WheelConstruction LArGeo::EndcapCryostatConstruction::m_hec2
private

Definition at line 61 of file EndcapCryostatConstruction.h.


The documentation for this class was generated from the following files: