ATLAS Offline Software
Loading...
Searching...
No Matches
TRTDetectorFactory_Full Class Reference

This class creates the TRT Geometry. More...

#include <TRTDetectorFactory_Full.h>

Inheritance diagram for TRTDetectorFactory_Full:
Collaboration diagram for TRTDetectorFactory_Full:

Public Member Functions

 TRTDetectorFactory_Full (InDetDD::AthenaComps *athenaComps, const ITRT_StrawStatusSummaryTool *sumTool, std::unique_ptr< const TRTStrawStatusAccessor > statusAccessor, bool useOldActiveGasMixture, bool DC2CompatibleBarrelCoordinates, bool alignable, bool doArgon, bool doKrypton, bool useDynamicAlignmentFolders)
 ~TRTDetectorFactory_Full ()=default
virtual void create (GeoPhysVol *world) override
virtual const InDetDD::TRT_DetectorManagergetDetectorManager () const override
const TRTDetectorFactory_Fulloperator= (const TRTDetectorFactory_Full &right)=delete
 TRTDetectorFactory_Full (const TRTDetectorFactory_Full &right)=delete
StoreGateSvcdetStore ()
const StoreGateSvcdetStore () const
const IGeoDbTagSvcgeoDbTagSvc () const
IRDBAccessSvcrdbAccessSvc ()
const IGeometryDBSvcgeomDB () const
MsgStream & msg (MSG::Level lvl) const
bool msgLvl (MSG::Level lvl)
InDetDD::AthenaCompsgetAthenaComps ()

Private Types

enum  ActiveGasMixture { GM_XENON , GM_KRYPTON , GM_ARGON }

Private Member Functions

ActiveGasMixture DecideGasMixture (int strawStatusHT)
const GeoShape * makeModule (double length, const GeoTrf::Vector2D &corner1, const GeoTrf::Vector2D &corner2, const GeoTrf::Vector2D &corner3, const GeoTrf::Vector2D &corner4, GeoTrf::Transform3D &absolutePosition, double shrinkDist=0) const
GeoPhysVol * makeStraw (bool hasLargeDeadRegion=false, ActiveGasMixture gasMixture=GM_XENON)
GeoFullPhysVol * makeStrawPlane (size_t w, ActiveGasMixture gasMixture=GM_XENON)

Private Attributes

InDetDD::TRT_DetectorManagerm_detectorManager = nullptr
std::unique_ptr< InDetMaterialManagerm_materialManager
std::unique_ptr< TRTParameterInterfacem_data
std::unique_ptr< const TRTStrawStatusAccessorm_statusAccessor
const ITRT_StrawStatusSummaryToolm_sumTool {nullptr}
bool m_useOldActiveGasMixture
bool m_DC2CompatibleBarrelCoordinates
bool m_alignable
bool m_strawsvcavailable
bool m_doArgon
bool m_doKrypton
bool m_useDynamicAlignFolders
GeoFullPhysVol * m_type1Planes [3] = {nullptr, nullptr, nullptr}
GeoFullPhysVol * m_type2Planes [3] = {nullptr, nullptr, nullptr}
InDetDD::AthenaCompsm_athenaComps

Detailed Description

This class creates the TRT Geometry.

Author
Joe Boudreau, Andrei and Iouris Zalite, Thomas Kittelmann

Definition at line 33 of file TRTDetectorFactory_Full.h.

Member Enumeration Documentation

◆ ActiveGasMixture

Constructor & Destructor Documentation

◆ TRTDetectorFactory_Full() [1/2]

TRTDetectorFactory_Full::TRTDetectorFactory_Full ( InDetDD::AthenaComps * athenaComps,
const ITRT_StrawStatusSummaryTool * sumTool,
std::unique_ptr< const TRTStrawStatusAccessor > statusAccessor,
bool useOldActiveGasMixture,
bool DC2CompatibleBarrelCoordinates,
bool alignable,
bool doArgon,
bool doKrypton,
bool useDynamicAlignmentFolders )

Definition at line 83 of file TRTDetectorFactory_Full.cxx.

92 : InDetDD::DetectorFactoryBase(athenaComps),
93 m_statusAccessor(std::move(statusAccessor)),
94 m_sumTool(sumTool),
95 m_useOldActiveGasMixture(useOldActiveGasMixture),
96 m_DC2CompatibleBarrelCoordinates(DC2CompatibleBarrelCoordinates),
97 m_alignable(alignable),
99 m_doArgon(doArgon),
100 m_doKrypton(doKrypton),
101 m_useDynamicAlignFolders(useDynamicAlignmentFolders)
102{
103}
const ITRT_StrawStatusSummaryTool * m_sumTool
std::unique_ptr< const TRTStrawStatusAccessor > m_statusAccessor

◆ ~TRTDetectorFactory_Full()

TRTDetectorFactory_Full::~TRTDetectorFactory_Full ( )
default

◆ TRTDetectorFactory_Full() [2/2]

TRTDetectorFactory_Full::TRTDetectorFactory_Full ( const TRTDetectorFactory_Full & right)
delete

Member Function Documentation

◆ create()

void TRTDetectorFactory_Full::create ( GeoPhysVol * world)
overridevirtual

Definition at line 131 of file TRTDetectorFactory_Full.cxx.

132{
133 // Create a new detectormanager.
134 m_detectorManager = new InDetDD::TRT_DetectorManager(detStore());
135
136 std::ofstream strawStatusFile;
137 if(m_sumTool) {
138 strawStatusFile.open("StrawStatus.txt");
139 }
140
141 //---------------------- Initialize the parameter interface ------------------------//
142
143 ATH_MSG_DEBUG( " Getting primary numbers from the Detector Description Database " );
144 TRT_DetDescrDB_ParameterInterface * parameterInterface = new TRT_DetDescrDB_ParameterInterface(getAthenaComps());
145 m_data.reset(parameterInterface);
146
147 //---------------------- Initialize the InnerDetector material manager ------------------------//
148
149 m_materialManager = std::make_unique<InDetMaterialManager>("TRT_MaterialManager", getAthenaComps());
150 m_materialManager->addScalingTable(parameterInterface->scalingTable());
151
152 //---------------------- Check if the folder TRT/Cond/StatusHT is in place ------------------------//
154
155 // --------------------- In a normal reconstruction or digitization job, the folder will not be available at this point. No reason for warnings here.
156 if (!m_strawsvcavailable) ATH_MSG_DEBUG("WHOLE TRT RUNNING XENON" );
157 if (!m_doArgon ) ATH_MSG_DEBUG("Tool setup will force to NOT to use ARGON. Ignore this warning if you are running RECONSTRUCTION or DIGI, but cross-check if you are running SIMULATION");
158 if (!m_doKrypton) ATH_MSG_DEBUG( "Tool setup will force to NOT to use KRYPTON. Ignore this warning if you are running RECONSTRUCTION or DIGI, but cross-check if you are running SIMULATION");
159
160
161 //---------------------- Initialize ID Helper ------------------------------------//
162
163 // Initialize the ID helper:
164// bool idHelperInitialized=false;
165
166 const TRT_ID *idHelper = nullptr;
167
168 if (detStore()->retrieve(idHelper, "TRT_ID").isFailure()) {
169 ATH_MSG_ERROR( "Could not retrieve TRT ID Helper");
170 }
171
172 m_detectorManager->setIdHelper(idHelper,false);
173
174 //---------------------- Set and Print Version Information ------------------------------------//
175
176 //Set active gas type information.
179
180 // Set Version information
181 // Some of these get overwritten for new configurations.
182 std::string versionTag = m_data->versionTag;
183 std::string versionName = "DC2";
184 std::string layout = "Final";
185 std::string description = "DC2 Geometry";
186 int versionMajorNumber = 2;
187 int versionMinorNumber = 1;
188 int versionPatchNumber = 0;
189
190 if (m_data->initialLayout) layout = "Initial";
191 //In principle we dont need to let the minor number reflect the
192 //gastype anymore, but it doesn't hurt:
193 if (m_useOldActiveGasMixture) versionMinorNumber = 0;
195 versionMajorNumber = 3;
196 versionName = "Rome";
197 description = "Geometry for Rome 2005";
198 }
199
200 if (m_data->isCosmicRun) {
201 layout = "SR1";
202 description = "Geometry for SR1";
203 }
204
205
206 // If new configuration we get the version information from the database.
207 // The version numbers can be incremented as one sees fit.
208 // In principle they should be changed whenever there are any code changes.
209 if (!m_data->oldConfiguration) {
210 versionName = m_data->versionName;
211 layout = m_data->layout;
212 description = m_data->versionDescription;
213 versionMajorNumber = 4;
214 versionMinorNumber = 1;
215 versionPatchNumber = 1;
216 }
217
218 InDetDD::Version version(versionTag,
219 versionName,
220 layout,
222 versionMajorNumber,
223 versionMinorNumber,
224 versionPatchNumber);
225
226 m_detectorManager->setVersion(version);
227
228
229 // Print version information.
230 ATH_MSG_INFO( "In TRT Detector Factory (For DC2 and later geometries)" );
231 ATH_MSG_INFO( " " << version.fullDescription() );
232
233
234 //---------- Set flags for which parts of the detector are built -----------//
235
236 std::string barrelLabel = "Barrel";
237 std::string endcapA_WheelAB_Label = "EndcapA_WheelAB";
238 std::string endcapC_WheelAB_Label = "EndcapC_WheelAB";
239 std::string endcapA_WheelC_Label = "EndcapA_WheelC";
240 std::string endcapC_WheelC_Label = "EndcapC_WheelC";
241
242 // Check if old naming scheme (which was a bit confusing with endcap C label)
243 if (m_data->partPresent("EndcapAB_Plus")) {
244 barrelLabel = "Barrel";
245 endcapA_WheelAB_Label = "EndcapAB_Plus";
246 endcapC_WheelAB_Label = "EndcapAB_Minus";
247 endcapA_WheelC_Label = "EndcapC_Plus";
248 endcapC_WheelC_Label = "EndcapC_Minus";
249 }
250
251
252 bool barrelPresent = m_data->partPresent(barrelLabel);
253 bool endcapABPlusPresent = m_data->partPresent(endcapA_WheelAB_Label);
254 bool endcapABMinusPresent = m_data->partPresent(endcapC_WheelAB_Label);
255 bool endcapCPlusPresent = m_data->partPresent(endcapA_WheelC_Label);
256 bool endcapCMinusPresent = m_data->partPresent(endcapC_WheelC_Label);
257 // Overall transform (probably will always be identifty - but just in case)
258 GeoTrf::Transform3D trtTransform = m_data->partTransform("TRT");
259
260 // For old configurations we need to set which parts are present.
261 //
262 if (m_data->oldConfiguration) {
263 if (m_data->isCosmicRun) {
264 endcapABPlusPresent = false;
265 endcapABMinusPresent = false;
266 endcapCPlusPresent = false;
267 endcapCMinusPresent = false;
268 }
269 if (m_data->initialLayout) {
270 endcapCPlusPresent = false;
271 endcapCMinusPresent = false;
272 }
273 }
274
275
276 //---------- Alignmnent and Conditions -----------//
277
278
279 // Register the channels for alignment constants
280 // and the level corresponding to the channel.
281 // Not the levels are an internal definition . They are not the same as
282 // the usual alignment levels
283 const int AlignmentLevelSubWheel = 1; // Level 2 in endcap. Not used in barrel
284 const int AlignmentLevelModule = 2; // Level 2 in barrel. Deprecated (wheel level) in endcap.
285 const int AlignmentLevelTop = 3; // Level 1
286
287 if (m_alignable) {
288
290 m_detectorManager->addAlignFolderType(InDetDD::static_run1);
291 m_detectorManager->addFolder("/TRT/Align");
292 m_detectorManager->addChannel("/TRT/Align/TRT", AlignmentLevelTop, InDetDD::global);
293
294 if (barrelPresent) {
295 m_detectorManager->addChannel("/TRT/Align/B0", AlignmentLevelModule, InDetDD::global);
296 m_detectorManager->addChannel("/TRT/Align/B1", AlignmentLevelModule, InDetDD::global);
297 m_detectorManager->addChannel("/TRT/Align/B2", AlignmentLevelModule, InDetDD::global);
298 }
299 if (endcapABPlusPresent) { // EndcapA
300 m_detectorManager->addChannel("/TRT/Align/L2A", AlignmentLevelSubWheel, InDetDD::global);
301 }
302 if (endcapABMinusPresent) {// EndcapC
303 m_detectorManager->addChannel("/TRT/Align/L2C", AlignmentLevelSubWheel, InDetDD::global);
304 }
305 }
306
307 else {
309
310 m_detectorManager->addGlobalFolder("/TRT/AlignL1/TRT");
311 m_detectorManager->addChannel("/TRT/AlignL1/TRT", AlignmentLevelTop, InDetDD::global);
312 m_detectorManager->addFolder("/TRT/AlignL2");
313
314 if (barrelPresent) {
315 m_detectorManager->addChannel("/TRT/AlignL2/B0", AlignmentLevelModule, InDetDD::global);
316 m_detectorManager->addChannel("/TRT/AlignL2/B1", AlignmentLevelModule, InDetDD::global);
317 m_detectorManager->addChannel("/TRT/AlignL2/B2", AlignmentLevelModule, InDetDD::global);
318 }
319
320 if (endcapABPlusPresent) { // EndcapA
321 m_detectorManager->addChannel("/TRT/AlignL2/L2A", AlignmentLevelSubWheel, InDetDD::global);
322 }
323 if (endcapABMinusPresent) {// EndcapC
324 m_detectorManager->addChannel("/TRT/AlignL2/L2C", AlignmentLevelSubWheel, InDetDD::global);
325 }
326 }
327
328 // Unchanged in Run1 and new Run2 schema
329 m_detectorManager->addSpecialFolder("/TRT/Calib/DX");
330 }
331
332
333
334 //Uncomment for testing:
335 // m_data->ShowValues();
336
337 //----------------------Initialize the numerology------------------------//
338
339 for (unsigned int m=0;m<m_data->nBarrelRings;m++) {
340 m_detectorManager->getNumerology()->setNBarrelLayers(m, m_data->barrelNumberOfStrawLayersInModule[m]);
341 }
342
343 m_detectorManager->getNumerology()->setNBarrelRings(m_data->nBarrelRings);
344 //Note: This next line is now consistent with TRT_TestBeamDetDescr.
345 m_detectorManager->getNumerology()->setNBarrelPhi(m_data->nBarrelModulesUsed);
346
347 unsigned int nEndcapWheels = 0;
348 if (endcapABPlusPresent||endcapABMinusPresent) nEndcapWheels += m_data->endcapNumberOfAWheels + m_data->endcapNumberOfBWheels;
349 if (endcapCPlusPresent||endcapCMinusPresent) nEndcapWheels += m_data->endcapNumberOfCWheels;
350
351 m_detectorManager->getNumerology()->setNEndcapWheels(nEndcapWheels);
352 m_detectorManager->getNumerology()->setNEndcapPhi(m_data->nEndcapPhi);
353
354 for (unsigned int w=0;w<m_detectorManager->getNumerology()->getNEndcapWheels();w++) {
355 unsigned int nlayers;
356 if ( w < m_data->endcapNumberOfAWheels )
357 nlayers = m_data->endCapNumberOfStrawLayersPerWheelA;
358 else if ( w < ( m_data->endcapNumberOfAWheels + m_data->endcapNumberOfBWheels ) )
359 nlayers = m_data->endCapNumberOfStrawLayersPerWheelB;
360 else
361 nlayers = m_data->endCapNumberOfStrawLayersPerWheelC;
362 m_detectorManager->getNumerology()->setNEndcapLayers(w, nlayers ) ;
363 }
364
365 //---------------------- Top level volumes ------------------------//
366
367 GeoNodePtr<GeoNameTag> topLevelNameTag(new GeoNameTag("TRT"));
368 // The top level volumes
369 GeoFullPhysVol *pBarrelVol = nullptr;
370 GeoFullPhysVol *pEndCapABPlus = nullptr;
371 GeoFullPhysVol *pEndCapCPlus = nullptr;
372 GeoFullPhysVol *pEndCapABMinus = nullptr;
373 GeoFullPhysVol *pEndCapCMinus = nullptr;
374
375
376
377 //
378 // Barrel volume:
379 //
380
381 if (barrelPresent) {
382 GeoTube* sBarrelVol = new GeoTube( m_data->virtualBarrelInnerRadius,
383 m_data->virtualBarrelOuterRadius,
384 m_data->virtualBarrelVolumeLength );
385
386
387 GeoLogVol *lBarrelVol = new GeoLogVol("TRTBarrel", sBarrelVol, m_materialManager->getMaterial("trt::CO2"));
388 pBarrelVol = new GeoFullPhysVol(lBarrelVol);
389
390 ATH_MSG_DEBUG( "Virtual TRT Barrel volume defined by RMin = "<<m_data->virtualBarrelInnerRadius
391 <<", Rmax = "<<m_data->virtualBarrelOuterRadius<<" Zmax = "<<m_data->virtualBarrelVolumeLength );
392
393 // Common Endcap volumes (one for forward, one for backward):
394 //GeoPhysVol *pCommonEndcapVolume[2];
395
396 GeoAlignableTransform * barrelTransform =
397 new GeoAlignableTransform(trtTransform * m_data->partTransform(barrelLabel));
398
399 world->add(topLevelNameTag);
400 world->add(barrelTransform);
401 world->add(pBarrelVol);
402 m_detectorManager->addTreeTop(pBarrelVol);
403 // Use barrel_ec_id = -1 (+ve and -ve barrel is treated as one alignable object)
404 Identifier id = idHelper->barrel_ec_id(-1);
405 m_detectorManager->addAlignableTransform(AlignmentLevelTop, id, barrelTransform, pBarrelVol); // global if other selected
406
407 }
408
409 //
410 // End-cap volume AB:
411 //
412 GeoLogVol * lEndCapVolumeAB = nullptr;
413 if (endcapABPlusPresent || endcapABMinusPresent) {
414 GeoTube * sEndCapVolumeAB_unshifted = new GeoTube (m_data->innerRadiusOfEndCapVolumeAB,
415 m_data->outerRadiusOfEndCapVolumeAB,
416 m_data->lengthOfEndCapVolumeAB/2.);
417 const GeoShape & sEndCapVolumeAB
418 = ( *sEndCapVolumeAB_unshifted << GeoTrf::TranslateZ3D(m_data->positionOfEndCapVolumeAB));
419
420 lEndCapVolumeAB = new GeoLogVol("TRTEndcapWheelAB", &sEndCapVolumeAB, m_materialManager->getMaterial("trt::CO2"));
421 }
422
423 if (endcapABPlusPresent) {
424 pEndCapABPlus = new GeoFullPhysVol(lEndCapVolumeAB);
425
426 GeoAlignableTransform * transform =
427 new GeoAlignableTransform(trtTransform * m_data->partTransform(endcapA_WheelAB_Label));
428
429 world->add(topLevelNameTag);
430 world->add(transform);
431 world->add(new GeoIdentifierTag(0));
432 world->add(pEndCapABPlus);
433 m_detectorManager->addTreeTop(pEndCapABPlus);
434 Identifier id = idHelper->barrel_ec_id(2);
435 m_detectorManager->addAlignableTransform(AlignmentLevelTop, id, transform, pEndCapABPlus); // global if other selected
436 }
437
438 if (endcapABMinusPresent) {
439 pEndCapABMinus = new GeoFullPhysVol(lEndCapVolumeAB);
440
441 GeoAlignableTransform * transform =
442 new GeoAlignableTransform(trtTransform * m_data->partTransform(endcapC_WheelAB_Label) * GeoTrf::RotateY3D(180*GeoModelKernelUnits::deg));
443
444 world->add(topLevelNameTag);
445 world->add(transform);
446 world->add(new GeoIdentifierTag(1));
447 world->add(pEndCapABMinus);
448 m_detectorManager->addTreeTop(pEndCapABMinus);
449 Identifier id = idHelper->barrel_ec_id(-2);
450 m_detectorManager->addAlignableTransform(AlignmentLevelTop, id, transform, pEndCapABMinus); // global if other selected
451 }
452
453 //
454 // End-cap volume C:
455 //
456 GeoLogVol * lEndCapVolumeC = nullptr;
457 if (endcapCPlusPresent || endcapCMinusPresent) {
458 GeoTube * sEndCapVolumeC_unshifted = new GeoTube (m_data->innerRadiusOfEndCapVolumeC,
459 m_data->outerRadiusOfEndCapVolumeC,
460 m_data->lengthOfEndCapVolumeC/2.);
461 const GeoShape & sEndCapVolumeC
462 = ( *sEndCapVolumeC_unshifted << GeoTrf::TranslateZ3D(m_data->positionOfEndCapVolumeC));
463
464 lEndCapVolumeC = new GeoLogVol("TRTEndcapWheelC", &sEndCapVolumeC, m_materialManager->getMaterial("trt::CO2"));
465 }
466
467 if (endcapCPlusPresent) {
468 pEndCapCPlus = new GeoFullPhysVol(lEndCapVolumeC);
469
470 GeoAlignableTransform * transform =
471 new GeoAlignableTransform(trtTransform * m_data->partTransform(endcapA_WheelC_Label));
472
473 world->add(topLevelNameTag);
474 world->add(transform);
475 world->add(new GeoIdentifierTag(0));
476 world->add(pEndCapCPlus);
477 m_detectorManager->addTreeTop(pEndCapCPlus);
478 }
479
480 if (endcapCMinusPresent) {
481 pEndCapCMinus = new GeoFullPhysVol(lEndCapVolumeC);
482
483 GeoAlignableTransform * transform =
484 new GeoAlignableTransform(trtTransform * m_data->partTransform(endcapC_WheelC_Label) * GeoTrf::RotateY3D(180*GeoModelKernelUnits::deg));
485
486 world->add(topLevelNameTag);
487 world->add(transform);
488 world->add(new GeoIdentifierTag(0));
489 world->add(pEndCapCMinus);
490 m_detectorManager->addTreeTop(pEndCapCMinus);
491 }
492
493 // Pointers to the Endcap volumes (index 0: for forward, index 1: for backward):
494 GeoFullPhysVol *pCommonEndcapAB[2];
495 GeoFullPhysVol *pCommonEndcapC[2];
496
497 pCommonEndcapAB[0] = pEndCapABPlus;
498 pCommonEndcapAB[1] = pEndCapABMinus;
499 pCommonEndcapC[0] = pEndCapCPlus;
500 pCommonEndcapC[1] = pEndCapCMinus;
501
502
503 //-----------------------------------------------------------------------//
504 // //
505 // Extra Material //
506 // //
507 //-----------------------------------------------------------------------//
508 if (pBarrelVol) {
509 InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
510 xMat.add(pBarrelVol, "TRTBarrel");
511 }
512 if (pEndCapABPlus) {
513 InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
514 xMat.add(pEndCapABPlus, "TRTEndcap");
515 xMat.add(pEndCapABPlus, "TRTEndcapA");
516 }
517 if (pEndCapABMinus) {
518 InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
519 xMat.add(pEndCapABMinus, "TRTEndcap");
520 xMat.add(pEndCapABMinus, "TRTEndcapC");
521 }
522
523 // Just for completeness
524 if (pEndCapCPlus) {
525 InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
526 xMat.add(pEndCapCPlus, "TRTEndcap_WheelC");
527 xMat.add(pEndCapCPlus, "TRTEndcapA_WheelC");
528 }
529 if (pEndCapCMinus) {
530 InDetDD::ExtraMaterial xMat(m_data->distortedMatManager());
531 xMat.add(pEndCapCMinus, "TRTEndcap_WheelC");
532 xMat.add(pEndCapCMinus, "TRTEndcapC_WheelC");
533 }
534
535
536
537 //-----------------------------------------------------------------------//
538 // //
539 // Barrel //
540 // //
541 //-----------------------------------------------------------------------//
542
543
544 if (pBarrelVol) {
545 //-----------------------------------------------------------------------//
546 // //
547 // Barrel Outer and Inner Supports //
548 // //
549 //-----------------------------------------------------------------------//
550 // Barrel inner support:
551 GeoTube *sBarrelInnerSupport = new GeoTube(m_data->innerRadiusOfBarrelVolume,
552 m_data->innerRadiusOfBarrelVolume + m_data->thicknessOfBarrelInnerSupport,
553 m_data->lengthOfBarrelVolume/2);
554
555 //ugly, but necessary check due to changes in database.
556 GeoLogVol *lBarrelInnerSupport = new GeoLogVol("BarrelInnerSupport", sBarrelInnerSupport,
557 m_materialManager->getMaterial("trt::BarrelInnerSupport") ?
558 m_materialManager->getMaterial("trt::BarrelInnerSupport") :
559 m_materialManager->getMaterial("trt::BarrelSupport") );
560
561
562 GeoPhysVol *pBarrelInnerSupport = new GeoPhysVol(lBarrelInnerSupport);
563 pBarrelVol->add(pBarrelInnerSupport);
564
565 // Barrel outer support:
566 GeoTube *sBarrelOuterSupport = new GeoTube(m_data->outerRadiusOfBarrelVolume - m_data->thicknessOfBarrelOuterSupport,
567 m_data->outerRadiusOfBarrelVolume, m_data->lengthOfBarrelVolume/2);
568
569 GeoLogVol *lBarrelOuterSupport = new GeoLogVol("BarrelOuterSupport", sBarrelOuterSupport,
570 m_materialManager->getMaterial("trt::BarrelOuterSupport") ?
571 m_materialManager->getMaterial("trt::BarrelOuterSupport") :
572 m_materialManager->getMaterial("trt::BarrelSupport") );
573
574
575 GeoPhysVol *pBarrelOuterSupport = new GeoPhysVol(lBarrelOuterSupport);
576 pBarrelVol->add(pBarrelOuterSupport);
577
578
579
580 if (m_data->includeBarServiceAndFlange) {
581
582 //-----------------------------------------------------------------------//
583 // //
584 // Barrel End Flange region //
585 // //
586 //-----------------------------------------------------------------------//
587
588
589 GeoTube *sEndFlangeRegion = new GeoTube(m_data->barFlangeRMin, m_data->barFlangeRMax,
590 (m_data->barFlangeZMax - m_data->barFlangeZMin)/2);
591 GeoLogVol *lEndFlangeRegion = new GeoLogVol("EndFlangeRegion", sEndFlangeRegion,
592 m_materialManager->getMaterial("trt::EndFlangeRegion") );
593
594 GeoPhysVol *pEndFlangeRegion = new GeoPhysVol(lEndFlangeRegion);
595
596 double zPosEndFlange = (m_data->barFlangeZMin+m_data->barFlangeZMax)/2;
597 GeoTransform *xfEndFlangeRegionPlus = new GeoTransform(GeoTrf::TranslateZ3D(zPosEndFlange));
598 GeoTransform *xfEndFlangeRegionMinus = new GeoTransform(GeoTrf::TranslateZ3D(-zPosEndFlange));
599
600 pBarrelVol->add(xfEndFlangeRegionPlus);
601 pBarrelVol->add(pEndFlangeRegion);
602 pBarrelVol->add(xfEndFlangeRegionMinus);
603 pBarrelVol->add(pEndFlangeRegion);
604
605
606 //-----------------------------------------------------------------------//
607 // //
608 // Barrel service region //
609 // //
610 //-----------------------------------------------------------------------//
611
612 GeoTube *sServices = new GeoTube(m_data->barServicesRMin, m_data->barServicesRMax,
613 (m_data->barServicesZMax - m_data->barServicesZMin)/2);
614 GeoLogVol *lServices = new GeoLogVol("Services", sServices,
615 m_materialManager->getMaterial("trt::Services") );
616
617 GeoPhysVol *pServices = new GeoPhysVol(lServices);
618
619 double zPosServices = (m_data->barServicesZMin+m_data->barServicesZMax)/2;
620 GeoTransform *xfServicesPlus = new GeoTransform(GeoTrf::TranslateZ3D(zPosServices));
621 GeoTransform *xfServicesMinus = new GeoTransform(GeoTrf::TranslateZ3D(-zPosServices));
622
623 pBarrelVol->add(xfServicesPlus);
624 pBarrelVol->add(pServices);
625 pBarrelVol->add(xfServicesMinus);
626 pBarrelVol->add(pServices);
627
628 }
629
630
631
632 //-----------------------------------------------------------------------//
633 // //
634 // Barrel Modules //
635 // //
636 //-----------------------------------------------------------------------//
637
638 std::vector<InDetDD::TRT_BarrelDescriptor *> bDescriptor;
639
640 // Create some shared stuff to stick into each module.
641
642 // The cooling tube:
643 GeoTube *sCoolingTube = new GeoTube(0, m_data->barrelOuterRadiusOfCoolingTube, m_data->lengthOfBarrelVolume/2.0);
644 GeoLogVol *lCoolingTube = new GeoLogVol("CoolingTube",sCoolingTube,m_materialManager->getMaterial("trt::CoolingTube"));
645 GeoPhysVol *pCoolingTube = new GeoPhysVol(lCoolingTube);
646
647 GeoTube *sCoolingFluid = new GeoTube(0, m_data->barrelInnerRadiusOfCoolingTube, m_data->lengthOfBarrelVolume/2.0);
648 GeoLogVol *lCoolingFluid = new GeoLogVol("CoolingFluid",sCoolingFluid,m_materialManager->getMaterial("trt::CoolingFluid"));
649 GeoPhysVol*pCoolingFluid = new GeoPhysVol(lCoolingFluid);
650
651 pCoolingTube->add(pCoolingFluid);
652
653 double lengthOfInnerDeadRegion= m_data->lengthOfDeadRegion;
654 double lengthOfActiveGas = (m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - m_data->lengthOfDeadRegion - lengthOfInnerDeadRegion;
655 double activeGasZPositionNormalStraws = (lengthOfActiveGas + m_data->barrelLengthOfTwister) / 2. + lengthOfInnerDeadRegion;
656
657 lengthOfInnerDeadRegion = m_data->barrelLengthOfLargeDeadRegion;
658 lengthOfActiveGas = (m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - m_data->lengthOfDeadRegion - lengthOfInnerDeadRegion;
659 double activeGasZPositionStrawsWithLargeDeadRegion = (lengthOfActiveGas + m_data->barrelLengthOfTwister) / 2. + lengthOfInnerDeadRegion;
660
661 // The modules themselves.
662 for (size_t iABC=0;iABC<m_data->nBarrelRings;iABC++) {
663
664 // Create a shape for the modules of each layer (shell)
665 // STS: Initialize raditator and shell LogVol
666 GeoLogVol *lRad = nullptr;
667 GeoLogVol *lShell = nullptr;
668
669 // The shell volume:
670 std::ostringstream shellstream;
671 shellstream << "Shell" << iABC;
672 GeoTrf::Vector2D shellCorner1(m_data->shellCornerXPosition[iABC][0],m_data->shellCornerYPosition[iABC][0]);
673 GeoTrf::Vector2D shellCorner2(m_data->shellCornerXPosition[iABC][1],m_data->shellCornerYPosition[iABC][1]);
674 GeoTrf::Vector2D shellCorner3(m_data->shellCornerXPosition[iABC][2],m_data->shellCornerYPosition[iABC][2]);
675 GeoTrf::Vector2D shellCorner4(m_data->shellCornerXPosition[iABC][3],m_data->shellCornerYPosition[iABC][3]);
676 GeoTrf::Transform3D shellPosition(GeoTrf::Transform3D::Identity());
677 if ( shellCorner1.y() <= 0 ) { ATH_MSG_DEBUG( "shellCorner1 is <= 0 (" << shellCorner1 << ")"); }
678 if ( shellCorner2.y() <= 0 ) { ATH_MSG_DEBUG( "shellCorner2 is <= 0 (" << shellCorner2 << ")"); }
679 if ( shellCorner3.y() <= 0 ) { ATH_MSG_DEBUG( "shellCorner3 is <= 0 (" << shellCorner3 << ")" ); }
680 if ( shellCorner4.y() <= 0 ) { ATH_MSG_DEBUG( "shellCorner4 is <= 0 (" << shellCorner4 << ")"); }
681 const GeoShape * sShell = makeModule(m_data->lengthOfBarrelVolume,
682 shellCorner1,shellCorner2,shellCorner3,shellCorner4,shellPosition);
683
684 // STS: We have three different shellmodules and radiators densities.
685 std::ostringstream layerstr;
686 layerstr << iABC;
687
688 std::string shellMatName = "trt::ModuleShell"+layerstr.str();
689 std::string shellName = "ModuleShell"+layerstr.str();
690
691 const GeoMaterial * shellMat = m_materialManager->getMaterial(shellMatName);
692 if (!shellMat) shellMat = m_materialManager->getMaterial("trt::ModuleShell");
693 lShell = new GeoLogVol(shellName, sShell, shellMat);
694
695 //---------------------------------------------------------------------------------------------------------------
696 // Some shared stuff for all of the modules within a layer:
697
698 // Make a Radiator
699 GeoTrf::Transform3D radAbsolutePosition(GeoTrf::Transform3D::Identity());
700 const GeoShape * sRad = makeModule(m_data->lengthOfBarrelVolume,
701 shellCorner1,shellCorner2,shellCorner3,shellCorner4,
702 radAbsolutePosition,m_data->barrelThicknessOfModuleWalls);
703
704 // FibreRadiator will have three different densities for each type of module
705 std::string radMatName = "trt::FibreRadiator"+layerstr.str();
706 std::string radName = "FibreRadiator"+layerstr.str();
707
708 const GeoMaterial * radMat = m_materialManager->getMaterial(radMatName);
709 if (!radMat) radMat = m_materialManager->getMaterial("trt::FibreRadiator");
710
711 lRad = new GeoLogVol(radName, sRad, radMat);
712
713 //---------------------------------------------------------------------------------------------------------------
714 // Place the cooling tubes in the Radiator
715 GeoTransform *xCool1 = new GeoTransform(shellPosition.inverse()
716 *GeoTrf::Translate3D(m_data->barrelXOfCoolingTube[iABC][0],m_data->barrelYOfCoolingTube[iABC][0],0));
717 GeoTransform *xCool2 = new GeoTransform(shellPosition.inverse()
718 *GeoTrf::Translate3D(m_data->barrelXOfCoolingTube[iABC][1],m_data->barrelYOfCoolingTube[iABC][1],0));
719
720 //----------------------------------------------------------------------------------------------------------------
721 // Parameterize all of the straws and put them within the radiator.
722
723 // Figure out how many straws have a large dead region
724 size_t nStrawsWithLargeDeadRegion = 0;
725 if (iABC==0) {
726 for (size_t iLayer = 0; iLayer<m_data->barrelNumberOfLayersWithLargeDeadRegion; iLayer++) {
727 nStrawsWithLargeDeadRegion += m_data->barrelNumberOfStrawsInStrawLayer[iABC][iLayer];
728 }
729 }
730
731 // Generators:
732 GeoTrf::TranslateX3D Xx(1.0);
733 GeoTrf::TranslateY3D Xy(1.0);
734
735 GENFUNCTION fx = ArrayFunction(&m_data->strawXPosition[iABC][0+nStrawsWithLargeDeadRegion],
736 &m_data->strawXPosition[iABC][0]+m_data->barrelNumberOfStrawsInModule[iABC]);
737 //TK: why ..[0]+n and not ..[n] ?
738 GENFUNCTION fy = ArrayFunction(&m_data->strawYPosition[iABC][0+nStrawsWithLargeDeadRegion],
739 &m_data->strawYPosition[iABC][0]+m_data->barrelNumberOfStrawsInModule[iABC]);
740 TRANSFUNCTION tx1 = Pow(Xx,fx)*Pow(Xy,fy);
741
742 //Functions for straw with large dead regions
743 GENFUNCTION fxDead = ArrayFunction(&m_data->strawXPosition[iABC][0], &m_data->strawXPosition[iABC][0+nStrawsWithLargeDeadRegion]);
744 GENFUNCTION fyDead = ArrayFunction(&m_data->strawYPosition[iABC][0], &m_data->strawYPosition[iABC][0+nStrawsWithLargeDeadRegion]);
745 TRANSFUNCTION tx1Dead = Pow(Xx,fxDead)*Pow(Xy,fyDead);
746
747 //TK: Quick fix, might waste a few KB of memory.
748 //TK: only use when iABC==0
749 GENFUNCTION fxAll = ArrayFunction(&m_data->strawXPosition[iABC][0], &m_data->strawXPosition[iABC][0]+m_data->barrelNumberOfStrawsInModule[iABC]);
750 GENFUNCTION fyAll = ArrayFunction(&m_data->strawYPosition[iABC][0], &m_data->strawYPosition[iABC][0]+m_data->barrelNumberOfStrawsInModule[iABC]);
751 TRANSFUNCTION tx1All = Pow(Xx,fxAll)*Pow(Xy,fyAll);
752
753
755 //Calculation of needed transforms
756 //First get the global and local positions of the two alignment straws:
757 //USE HEP2VECTORS!!!
758
759 GeoTrf::Vector3D Align1Global(m_data->barrelXOfFirstGlobalAlignmentStraw[iABC], m_data->barrelYOfFirstGlobalAlignmentStraw[iABC], 0);
760 GeoTrf::Vector3D Align2Global(m_data->barrelXOfSecondGlobalAlignmentStraw[iABC], m_data->barrelYOfSecondGlobalAlignmentStraw[iABC],0);
761 GeoTrf::Vector3D Align1Local(m_data->strawXPosition[iABC][0],m_data->strawYPosition[iABC][0],0);
762 GeoTrf::Vector3D Align2Local(m_data->strawXPosition[iABC][m_data->barrelIndexOfSecondGlobalAlignmentStraw[iABC]],
763 m_data->strawYPosition[iABC][m_data->barrelIndexOfSecondGlobalAlignmentStraw[iABC]],0);
764
765 //We need to make first a translation which puts the first alignment straw into place:
766
767 //And we need to make a rotation which puts the second one on its position:
768
769 GeoTrf::Vector2D local12((Align2Local - Align1Local).x(),(Align2Local - Align1Local).y());
770 GeoTrf::Vector2D global12((Align2Global - Align1Global).x(),(Align2Global - Align1Global).y());
771 double zrotang = global12.phi()-local12.phi();
772
773 //Here we combine these two into a GeoTrf::Transform3D:
774
775 GeoTrf::Transform3D absStrawXForm = GeoTrf::Translate3D(Align1Global.x(),Align1Global.y(),Align1Global.z())
776 *GeoTrf::RotateZ3D( zrotang )
777 *GeoTrf::Translate3D(-Align1Local.x(),-Align1Local.y(),-Align1Local.z());
778
779 //
781
782 //Why not use radiator instead of shell?
783 TRANSFUNCTION tx2=shellPosition.inverse()*absStrawXForm*tx1;
784 TRANSFUNCTION tx2Dead=shellPosition.inverse()*absStrawXForm*tx1Dead;
785 TRANSFUNCTION tx2All=shellPosition.inverse()*absStrawXForm*tx1All;
786 if (iABC==0) {
787 //TK: move rest of ...All stuff here?
788 m_detectorManager->setBarrelTransformField(iABC,tx2All.clone());
789 } else {
790 m_detectorManager->setBarrelTransformField(iABC,tx2.clone());
791 }
792
793 // Adds one straw from each layer (reformulate..) (should be done via m_data from database)
794 double oldx=-999*GeoModelKernelUnits::cm, oldz=-999*GeoModelKernelUnits::cm;
795 unsigned int c=0;
796 size_t iLayer=0;
797 while (c< m_data->barrelNumberOfStrawsInModule[iABC] ) {
798
799 GeoTrf::Vector3D p(0,0,0);
800 if (iABC==0)
801 p = tx2All(c)*p;
802 else
803 p = tx2(c)*p;
804
805 double x = p.x();
806 double z = p.z();
807
808 //TK: use arrays!! update this...
809 if (sqrt((x-oldx)*(x-oldx)+ (z-oldz)*(z-oldz))> 5*GeoModelKernelUnits::cm) {
810 iLayer++;
811 bDescriptor.push_back(new InDetDD::TRT_BarrelDescriptor());
812 m_detectorManager->setBarrelDescriptor(bDescriptor.back());
813 bDescriptor.back()->setStrawTransformField(m_detectorManager->barrelTransformField(iABC),c);
814
815 //TK: Next, we are providing information about the Z
816 //dimensions of the active gas, to be used for reconstruction
817 //purposes. Personally I find "strawZDead" to be a slightly
818 //confusing choice of name for that method.
819
820 if((iABC==0)&&(iLayer<=m_data->barrelNumberOfLayersWithLargeDeadRegion )) {
821 //TK: these things should come back from makestraw...
822 double lengthOfActiveGas=
823 (m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - m_data->lengthOfDeadRegion-m_data->barrelLengthOfLargeDeadRegion;
824 double startZOfActiveGas=activeGasZPositionStrawsWithLargeDeadRegion-lengthOfActiveGas/2.0;
825 bDescriptor.back()->strawZPos(activeGasZPositionStrawsWithLargeDeadRegion);
826 bDescriptor.back()->strawZDead(startZOfActiveGas);
827 bDescriptor.back()->strawLength(lengthOfActiveGas);
828 } else {
829 double lengthOfActiveGas=(m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - 2*m_data->lengthOfDeadRegion;
830 double startZOfActiveGas=activeGasZPositionNormalStraws-lengthOfActiveGas/2.0;
831 bDescriptor.back()->strawZPos(activeGasZPositionNormalStraws);
832 bDescriptor.back()->strawZDead(startZOfActiveGas);
833 bDescriptor.back()->strawLength(lengthOfActiveGas);
834 }
835
836 }
837 bDescriptor.back()->addStraw(z,x);
838 oldx=x; oldz=z;
839 c++;
840
841 }
842
843
844
845 // Now create m_data->nBarrelModulesUsed unique modules within each layer.
846 pBarrelVol->add(new GeoSerialIdentifier(0));
847 for (size_t iMod = 0; iMod<m_data->nBarrelModulesUsed;iMod++) {
848 double delta = iMod*360*GeoModelKernelUnits::deg/m_data->nBarrelModules;
849
850
851
852
853 GeoFullPhysVol * pShell = new GeoFullPhysVol(lShell);
854
855 // This is where the shell is pushed out to its place
856 //GeoTransform * xfx1 = new GeoTransform(GeoTrf::RotateZ3D(delta)*shellPosition);
857 GeoAlignableTransform * xfx1 = new GeoAlignableTransform(GeoTrf::RotateZ3D(delta)*shellPosition);
858 pBarrelVol->add(xfx1);
859 pBarrelVol->add(pShell);
860
861 // Register the alignable transfrom to the manager
862 // +ve and -ve are part of the same barrel. We use barrel_ec = -1.
863 Identifier idModule = idHelper->module_id(-1, iMod, iABC);
864 // In barrel frame (generally the same as the global frame)
865 m_detectorManager->addAlignableTransform(AlignmentLevelModule, idModule, xfx1, pShell, pBarrelVol);
866
867 // Add the substructure here:
868 pShell->add(new GeoIdentifierTag(iABC));
869 Identifier TRT_Identifier = idHelper->straw_id(1, iMod, iABC, 1, 1);
870 int strawStatusHT = TRTCond::StrawStatus::Good;
872 if(m_sumTool) {
873 strawStatusHT = m_sumTool->getStatusHT(TRT_Identifier, Gaudi::Hive::currentContext());
874 strawStatusFile << TRT_Identifier.get_compact() << std::format("{:5}",strawStatusHT) << std::endl;
875 }
876 else {
877 strawStatusHT = m_statusAccessor->status(TRT_Identifier);
878 }
879 }
880 ActiveGasMixture agm = DecideGasMixture(strawStatusHT);
881
882 // Make a radiator
883 GeoNodePtr<GeoPhysVol> pRad(new GeoPhysVol(lRad));
884 pRad->add(xCool1);
885 pRad->add(pCoolingTube);
886 pRad->add(xCool2);
887 pRad->add(pCoolingTube);
888 pRad->add(new GeoSerialIdentifier(0));
889
890 GeoNodePtr<GeoPhysVol> pHoleForMixedStraw;
891 GeoNodePtr<GeoPhysVol> pHoleForMixedStrawWithLargeDeadRegion;
892
893 switch (agm)
894 {
895 case GM_ARGON:
896 ATH_MSG_DEBUG( "Marking Argon straws from /TRT/Cond/StatusHT:\t"
897 << idHelper->print_to_string(TRT_Identifier));
898 pHoleForMixedStraw = makeStraw(false, GM_ARGON);
899 pHoleForMixedStrawWithLargeDeadRegion = makeStraw(true, GM_ARGON);
900 break;
901 case GM_KRYPTON:
902 ATH_MSG_DEBUG( "Marking Krypton straws from /TRT/Cond/StatusHT:\t"
903 << idHelper->print_to_string(TRT_Identifier));
904 pHoleForMixedStraw = makeStraw(false, GM_KRYPTON);
905 pHoleForMixedStrawWithLargeDeadRegion = makeStraw(true, GM_KRYPTON);
906 break;
907 case GM_XENON:
908 ATH_MSG_DEBUG( "Marking Xenon straws from /TRT/Cond/StatusHT:\t"
909 << idHelper->print_to_string(TRT_Identifier) );
910 pHoleForMixedStraw = makeStraw();
911 pHoleForMixedStrawWithLargeDeadRegion = makeStraw(true);
912 break;
913 default:
914 ATH_MSG_FATAL( "Unexpected gas mixture: " << agm );
915 throw std::runtime_error("Unexpected gas mixture");
916 return;
917 }
918
919 GeoNodePtr<GeoSerialTransformer> serialTransformer = new GeoSerialTransformer(pHoleForMixedStraw
920 , &tx2
921 , m_data->barrelNumberOfStrawsInModule[iABC]-nStrawsWithLargeDeadRegion);
922
923 if (iABC==0) {
924 GeoNodePtr<GeoSerialTransformer> serialTransformerDead = new GeoSerialTransformer(pHoleForMixedStrawWithLargeDeadRegion
925 , &tx2Dead
926 , nStrawsWithLargeDeadRegion);
927 pRad->add(serialTransformerDead);
928 }
929 pRad->add(serialTransformer);
930
931 pShell->add(pRad);
932
933 //-------------------------------------------------------------------//
934 // //
935 // Barrel readout: //
936 // //
937 //-------------------------------------------------------------------//
938
939 //
940 // Get the number of straw layers in each module:
941 //
942
943 unsigned int nStrawLayers = m_detectorManager->getNumerology()->getNBarrelLayers(iABC);
944 for (unsigned int iStrawLayer=0;iStrawLayer<nStrawLayers; iStrawLayer++) { // limit stored as float!
945
946 unsigned int jStrawLayer=iStrawLayer;
947 if (iABC>0) jStrawLayer += m_detectorManager->getNumerology()->getNBarrelLayers(0);
948 if (iABC>1) jStrawLayer += m_detectorManager->getNumerology()->getNBarrelLayers(1);
949 //TK: just go from jStrawLayer=layerstart;jStrawLayer<layerend ?
950
951 InDetDD::TRT_BarrelDescriptor *bD=bDescriptor[jStrawLayer];
952
953 InDetDD::TRT_BarrelElement *element0 = new InDetDD::TRT_BarrelElement(pShell, bD, 0 , iABC, iMod, iStrawLayer, idHelper, m_detectorManager->conditions());
954 InDetDD::TRT_BarrelElement *element1 = new InDetDD::TRT_BarrelElement(pShell, bD, 1 , iABC, iMod, iStrawLayer, idHelper, m_detectorManager->conditions());
955
956 m_detectorManager->manageBarrelElement(element0);
957 m_detectorManager->manageBarrelElement(element1);
958 }
959
960 }//End "for (size_t iMod = ..." loop.
961
962 }
963
964 // Set up the nearest neighbor pointers: in R.
965 for (unsigned int e=0;e<2;e++) {
966 for (unsigned int iMod=0;iMod<m_data->nBarrelModulesUsed; iMod++) {
967 InDetDD::TRT_BarrelElement *prev=nullptr;
968 for (unsigned int iABC=0;iABC<m_data->nBarrelRings;iABC++) {
969 for (unsigned int s=0;s<m_detectorManager->getNumerology()->getNBarrelLayers(iABC); s++) {
970 InDetDD::TRT_BarrelElement *current = m_detectorManager->getBarrelElement(e,iABC, iMod, s);
971 if (prev && current) {
972 prev->setNextInR(current);
973 current->setPreviousInR(prev);
974 }
975 prev=current;
976 }
977 }
978 }
979 }
980
981 // Set up the nearest neighbor pointers: in Phi.
982 for (unsigned int e=0;e<2;e++) {
983 for (unsigned int iABC=0;iABC<m_data->nBarrelRings;iABC++) {
984 for (unsigned int s=0;s<m_detectorManager->getNumerology()->getNBarrelLayers(iABC); s++) {
985 InDetDD::TRT_BarrelElement *prev=nullptr;
986 for (unsigned int iMod=0;iMod<m_data->nBarrelModulesUsed; iMod++) {
987 InDetDD::TRT_BarrelElement *current = m_detectorManager->getBarrelElement(e,iABC, iMod, s);
988 if (prev && current) {
989 prev->setNextInPhi(current);
990 current->setPreviousInPhi(prev);
991 }
992 prev=current;
993 }
994 if (m_data->nBarrelModulesUsed==m_data->nBarrelModules) { // Full complement; then, we wrap!:
995 InDetDD::TRT_BarrelElement *first=m_detectorManager->getBarrelElement(e,iABC,0,s);
996 InDetDD::TRT_BarrelElement *last =m_detectorManager->getBarrelElement(e,iABC,m_data->nBarrelModules-1,s);
997 if (first && last) {
998 first->setPreviousInPhi(last);
999 last->setNextInPhi(first);
1000 }
1001 }
1002 }
1003 }
1004 }
1005 }//end of if (pBarrelVol)
1006
1007
1008
1009 //-----------------------------------------------------------------------//
1010 // //
1011 // Endcap Modules //
1012 // //
1013 //-----------------------------------------------------------------------//
1014
1015 // TK: This part could really use some cleanup and reordering.
1016 // There is no need to repeat the same code for A, B & C endcaps.
1017
1018
1019 // if none of the endcaps is being built we can return.
1020 if (!(endcapABPlusPresent || endcapABMinusPresent || endcapCPlusPresent || endcapCMinusPresent)){
1021 return;
1022 }
1023 unsigned int firstIndexOfA = 0;
1024 unsigned int firstIndexOfB = m_data->endcapNumberOfAWheels;
1025 unsigned int firstIndexOfC = m_data->endcapNumberOfAWheels + m_data->endcapNumberOfBWheels;
1026
1027 unsigned int indexUpperBound = firstIndexOfA + m_detectorManager->getNumerology()->getNEndcapWheels();
1028
1029 if (m_data->initialLayout) indexUpperBound = firstIndexOfC; // No wheel C.
1030
1031 const unsigned int nSides = 2;
1032 const unsigned int nStrawLayMaxEc = 8;//hardcoded...
1033
1034 unsigned int iiSide, iiWheel, iiPlane, iiPhi, counter; //set of counters
1035 int sign;
1036 double zdelta = 0.024; // try to make smaller gaps for Endcap Inner/OuterSupportGapper
1037 GeoTransform *xfRadiator, *xfPlane, *xfHeatExchanger, *xfFaradayFoilFront, *xfFaradayFoilBack;
1038 GeoTransform *xfInnerSupportGapperA,*xfOuterSupportGapperA, *xfInnerSupportGapperB, *xfOuterSupportGapperB;
1039 GeoFullPhysVol *childPlane = nullptr;
1040
1041
1042 double RotationsOfStrawPlanes[nStrawLayMaxEc]; //8 is hardcoded
1043 double shiftForEachRotation = m_data->endCapShiftForEachRotation; // in units of deltaPhi
1044 RotationsOfStrawPlanes[0] = 0.;
1045
1046 bool oldGeometry = true;
1047 // Temporary way to determine old from new
1048 if (shiftForEachRotation < 0) oldGeometry = false;
1049
1050 if (oldGeometry) {
1051 // For old geometry
1052 for (counter = 1; counter < nStrawLayMaxEc; counter++)
1053 {
1054 RotationsOfStrawPlanes[counter] = RotationsOfStrawPlanes[counter-1] + shiftForEachRotation;
1055 if (RotationsOfStrawPlanes[counter] >= 1.)
1056 RotationsOfStrawPlanes[counter] -= 1.;
1057 }
1058 } else {
1059 // New geometry
1060 double RotationsOfStrawPlanesTmp[nStrawLayMaxEc] = {0,0,0,0,2,2,2,2};
1061 for (counter = 0; counter < nStrawLayMaxEc; counter++)
1062 {
1063 RotationsOfStrawPlanes[counter] = (counter * shiftForEachRotation) + RotationsOfStrawPlanesTmp[counter];
1064 }
1065 }
1066
1067 // Create and initialize by 0 arrays of descriptors
1068 std::vector<InDetDD::TRT_EndcapDescriptor*> descriptorsAB[nSides][nStrawLayMaxEc];
1069 std::vector<InDetDD::TRT_EndcapDescriptor*> descriptorsC[nSides][nStrawLayMaxEc];
1070 InDetDD::TRT_EndcapDescriptor* pDescriptor = nullptr;
1071 InDetDD::TRT_EndcapElement* element = nullptr;
1072
1073 for(iiSide = 0; iiSide<nSides; iiSide++) {
1074 for(iiPlane = 0; iiPlane < nStrawLayMaxEc; iiPlane++) {
1075 descriptorsAB[iiSide][iiPlane].resize (m_data->nEndcapPhi);
1076 descriptorsC[iiSide][iiPlane].resize (m_data->nEndcapPhi);
1077 }
1078 }
1079
1080
1081
1082 // Do Wheels A and B if one of them is present
1083 if (endcapABPlusPresent || endcapABMinusPresent) {
1084 // -------------- Wheel A -----------------------
1085
1086 // Inner/Outer supports
1087 GeoTube* sInnerSupportA = new GeoTube(m_data->endCapInnerRadiusOfSupportA,
1088 m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1089 m_data->endCapLengthOfWheelsA/2);
1090 GeoLogVol* lInnerSupportA = new GeoLogVol("InnerSupportA", sInnerSupportA, m_materialManager->getMaterial("trt::InnerSupportA"));
1091 GeoPhysVol* pInnerSupportA = new GeoPhysVol(lInnerSupportA);
1092
1093 GeoTube* sOuterSupportA = new GeoTube(m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA,
1094 m_data->endCapOuterRadiusOfSupportA, m_data->endCapLengthOfWheelsA/2);
1095 GeoLogVol* lOuterSupportA = new GeoLogVol("OuterSupportA", sOuterSupportA, m_materialManager->getMaterial("trt::OuterSupportA"));
1096 GeoPhysVol* pOuterSupportA = new GeoPhysVol(lOuterSupportA);
1097
1098 // Straw plane
1099 GeoNodePtr<GeoFullPhysVol> pStrawPlaneA_Kr;
1100 GeoNodePtr<GeoFullPhysVol> pStrawPlaneA_Ar;
1101 if (m_doKrypton)
1102 pStrawPlaneA_Kr = makeStrawPlane(firstIndexOfA, GM_KRYPTON);
1103 if (m_doArgon)
1104 pStrawPlaneA_Ar = makeStrawPlane(firstIndexOfA, GM_ARGON);
1105 GeoIntrusivePtr<GeoFullPhysVol> pStrawPlaneA = makeStrawPlane(firstIndexOfA);
1106
1107
1108 //TK:
1109 // Instead of this confusing stuf (main, thin, middle??), make:
1110 // 1) An array which gives the exact thicknesses of the various radiators
1111 // 2) A "makeradiator" method like makestrawplane which checks
1112 // internally whether it already has created a radiator of a
1113 // given thickness.
1114 //
1115 // Then just loop over the radiators
1116 //
1117
1118 // Radiators
1119 GeoTube* sMainRadiatorA = new GeoTube(m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1120 m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA
1121 - m_data->endCapRadialDistFromRadToOuterSupportA, m_data->endCapMainRadiatorThicknessA/2);
1122 GeoLogVol* lMainRadiatorA = new GeoLogVol("MainRadiatorA",sMainRadiatorA, m_materialManager->getMaterial("trt::FoilRadiatorAC"));
1123 GeoPhysVol* pMainRadiatorA = new GeoPhysVol(lMainRadiatorA);
1124
1125 GeoTube* sThinRadiatorA = new GeoTube(m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1126 m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA
1127 - m_data->endCapRadialDistFromRadToOuterSupportA, m_data->endCapThinRadiatorThicknessA/2);
1128 GeoLogVol* lThinRadiatorA = new GeoLogVol("ThinRadiatorA",sThinRadiatorA, m_materialManager->getMaterial("trt::FoilRadiatorAC"));
1129 GeoPhysVol* pThinRadiatorA = new GeoPhysVol(lThinRadiatorA);
1130
1131 // Wheel
1132 GeoTube* sWheelA = new GeoTube( m_data->endCapInnerRadiusOfSupportA,m_data->endCapOuterRadiusOfSupportA, m_data->endCapLengthOfWheelsA/2);
1133 GeoLogVol* lWheelA = new GeoLogVol("WheelA", sWheelA, m_materialManager->getMaterial("trt::CO2"));
1134
1135 // This is the straw pitch.
1136 double deltaPhiForStrawsA = 360.*GeoModelKernelUnits::deg/m_data->endcapNumberOfStrawsInStrawLayer_AWheels;
1137
1138
1139 // In reality the positive and negative endcaps are built identical, both in
1140 // geometry and readout. The offline numbering however keeps phi numbering going
1141 // in the same direction as global phi (righthanded direction).
1142
1143 // For the latest version we build +ve and negative endcaps identical.
1144 // We also build the descriptors identical apart from the setting of startphi.
1145 //
1146 // The mapping is fixed (this must be reproduced in the sensitive
1147 // detector and readout geometry) The mapping is 1-1 for the
1148 // +ve endcap, for the -ve endcap it is as follows:
1149 //
1150 // ***************************************************************
1151 // * Negative endcap (Endcap C) mapping. *
1152 // * *
1153 // * nSectors = 32 *
1154 // * nStraws = num straws in sector *
1155 // * sector -> (nSectors + nSectors/2 - sector - 1) % nSectors *
1156 // * straw -> nStraws - 1 - straw *
1157 // ***************************************************************
1158 //
1159 // For compatibility with old (wrong geometry) we rotate the strawlayers
1160 // differently for the negative endcap than we do for the positive endcap.
1161 // This is to allow the sensitive detector and readout geometry to have
1162 // the same code for both layouts.
1163 //
1164 // Below we refere to online as the physical readout and offline as the offline
1165 // identifier convetions.
1166 // iiPhi corresponds to the "online" readout phi sector. This goes
1167 // right handed in positive endcap and left handed in negative, where handedness
1168 // is wrt to global frame.
1169 // iiPhiOffline is the offline numbering which is always right handed.
1170
1171 for(iiSide=0; iiSide<nSides; iiSide++) {
1172 // Wheel A
1173 if (pCommonEndcapAB[iiSide]) {
1174
1175 double WheelPlacerA = m_data->endCapPositionOfFirstWheelA[iiSide];
1176
1177 for(iiWheel=firstIndexOfA; iiWheel < firstIndexOfB; iiWheel++)
1178 {
1179 //prepair to place wheel
1180 WheelPlacerA += m_data->endCapDistanceBetweenWheelCentersA[iiSide][iiWheel] ;
1181
1182 GeoFullPhysVol* pWheelA = new GeoFullPhysVol(lWheelA);
1183
1184 GeoAlignableTransform * xfAlignableModule = nullptr;
1185
1186 // Place planes in the wheel
1187 for (iiPlane = 0; iiPlane < m_data->endCapNumberOfStrawLayersPerWheelA; iiPlane++)
1188 {
1189
1190
1191
1192 // WheelA is subdivided into 4 alignable objects. (Every 4th straw layer)
1193 // We create an alignable transform for each alignable module
1194 // and multiply this by the transform for every straw layer in the "alignable module"
1195 // The tranform is by default Identity.
1196 if (iiPlane % 4 == 0) {
1197 // Register alignable node
1198 int barrel_ec = (iiSide) ? -2 : +2;
1199 xfAlignableModule = new GeoAlignableTransform(GeoTrf::Transform3D::Identity());
1200 Identifier idSubModule = idHelper->layer_id(barrel_ec, 0, iiWheel, iiPlane);
1201 // We pass the parent volume as the local delta for this correction is the same as a local delta
1202 // on the transformation of the wheel.
1203 m_detectorManager->addAlignableTransform(AlignmentLevelSubWheel, idSubModule, xfAlignableModule, pWheelA);
1204 }
1205
1206 // phiPlane is phi of straw 0, sector 0 (online numbering)
1207 double phiPlane = m_data->endCapPhiOfFirstStraw + RotationsOfStrawPlanes[iiPlane%nStrawLayMaxEc]*deltaPhiForStrawsA;
1208
1209 // For compatibility with old geometry we have to shift every eighth wheel by 1 straw pitch.
1210 if(iiSide && oldGeometry && (iiPlane%8 == 0)) {
1211 phiPlane += deltaPhiForStrawsA;
1212 }
1213
1214 int bar_ec = (iiSide) ? -2 : +2;
1215 Identifier TRT_Identifier = idHelper->straw_id(bar_ec, 1, iiWheel, 1, 1);
1216 int strawStatusHT = TRTCond::StrawStatus::Good;
1217 if (m_strawsvcavailable) {
1218 if(m_sumTool) {
1219 strawStatusHT = m_sumTool->getStatusHT(TRT_Identifier, Gaudi::Hive::currentContext());
1220 strawStatusFile << TRT_Identifier.get_compact() << std::format("{:5}",strawStatusHT) << std::endl;
1221 }
1222 else {
1223 strawStatusHT = m_statusAccessor->status(TRT_Identifier);
1224 }
1225 }
1226 ActiveGasMixture agm = DecideGasMixture(strawStatusHT);
1227
1228 // Ruslan: insert plane with Ar-straws
1229 // Artem: same for Kr
1230 switch (agm)
1231 {
1232 case GM_ARGON:
1233 ATH_MSG_DEBUG( "Marking Argon straws from /TRT/Cond/StatusHT:\t"
1234 << idHelper->print_to_string(TRT_Identifier) );
1235 childPlane = pStrawPlaneA_Ar->clone();
1236 break;
1237 case GM_KRYPTON:
1238 ATH_MSG_DEBUG( "Marking Krypton straws from /TRT/Cond/StatusHT:\t"
1239 << idHelper->print_to_string(TRT_Identifier) );
1240 childPlane = pStrawPlaneA_Kr->clone();
1241 break;
1242 case GM_XENON:
1243 ATH_MSG_DEBUG( "Marking Xenon straws from /TRT/Cond/StatusHT:\t"
1244 << idHelper->print_to_string(TRT_Identifier) );
1245 childPlane = pStrawPlaneA->clone();
1246 break;
1247 default:
1248 ATH_MSG_FATAL( "Unexpected gas mixture: " << agm );
1249 throw std::runtime_error("Unexpected gas mixture");
1250 return;
1251 }
1252
1253
1254 xfPlane = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionA[iiPlane] - m_data->endCapLengthOfWheelsA/2)*GeoTrf::RotateZ3D(phiPlane));
1255
1256 if (xfAlignableModule) pWheelA->add(xfAlignableModule);
1257 pWheelA->add(xfPlane);
1258 pWheelA->add(new GeoIdentifierTag(iiPlane));
1259 pWheelA->add(childPlane);
1260
1261 // Create descriptors
1262 // Just do it for the first wheel
1263 if(iiWheel==firstIndexOfA && iiPlane < nStrawLayMaxEc)
1264 for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1265 {
1266
1267 pDescriptor = new InDetDD::TRT_EndcapDescriptor();
1268 m_detectorManager->setEndcapDescriptor(pDescriptor);
1269
1270 pDescriptor->nStraws() = m_data->endcapNumberOfStrawsInStrawLayer_AWheels/m_data->nEndcapPhi;
1271 pDescriptor->strawPitch() = deltaPhiForStrawsA;
1272
1273 double startPhi = phiPlane + iiPhi * pDescriptor->strawPitch() * pDescriptor->nStraws();
1274
1275 // For negative endcap the startPhi is the last straw in the physical sector
1276 // phi -> phi + strawPitch*(n-1)
1277 // it then gets rotated 180 around y axis
1278 // phi -> pi - phi
1279 if (iiSide) {
1280 startPhi = GeoModelKernelUnits::pi - (startPhi + pDescriptor->strawPitch() * (pDescriptor->nStraws() - 1));
1281 }
1282
1283 // Make sure its between -pi and pi.
1284 if (startPhi <= -GeoModelKernelUnits::pi) startPhi += 2*GeoModelKernelUnits::pi;
1285 if (startPhi > GeoModelKernelUnits::pi) startPhi -= 2*GeoModelKernelUnits::pi;
1286
1287 pDescriptor->startPhi() = startPhi;
1288
1289 pDescriptor->strawLength() = m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA
1290 - 2*m_data->lengthOfDeadRegion - m_data->endCapRadialThicknessOfInnerSupportA - m_data->endCapInnerRadiusOfSupportA;
1291 pDescriptor->innerRadius() = m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA
1292 + m_data->lengthOfDeadRegion;
1293 pDescriptor->setStrawTransformField(m_detectorManager->endcapTransformField(0),iiPhi*pDescriptor->nStraws());
1294
1295 descriptorsAB[iiSide][iiPlane%nStrawLayMaxEc][iiPhi] = pDescriptor;
1296 }
1297 // Create elements
1298 for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1299 {
1300 // m_data->nEndcapPhi assumed to be even.
1301 // For positive endcap online == offline. For negative endcap we rotate 180 deg about y axis so
1302 // sector 0 -> 15, 15 -> 0, 16 -> 31, 31 -> 16, etc. This is achieved with
1303 // sector -> (nSectors + nSectors/2 - sector - 1) % nSectors
1304 int iiPhiOffline = (iiSide==0) ? iiPhi : (3*m_data->nEndcapPhi/2 - iiPhi - 1)% m_data->nEndcapPhi;
1305 element = new InDetDD::TRT_EndcapElement(childPlane,
1306 descriptorsAB[iiSide][iiPlane%nStrawLayMaxEc][iiPhi],
1307 iiSide==0,
1308 iiWheel,
1309 iiPlane,
1310 iiPhiOffline,
1311 idHelper,
1312 m_detectorManager->conditions());
1313 m_detectorManager->manageEndcapElement(element);
1314 }
1315 }
1316 // Place radiators in the wheel
1317 for (counter = 1; counter <= m_data->endCapNumberOfStrawLayersPerWheelA; counter++)
1318 {
1319 if (counter % 4 == 1)
1320 {
1321 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionA[counter-1] - m_data->endCapLengthOfWheelsA/2
1322 - m_data->outerRadiusOfStraw - m_data->endCapThinRadiatorThicknessA/2));
1323 pWheelA->add(xfRadiator);
1324 pWheelA->add(pThinRadiatorA);
1325 }
1326
1327 if (counter % 4 == 0)
1328 {
1329 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionA[counter-1] - m_data->endCapLengthOfWheelsA/2
1330 + m_data->outerRadiusOfStraw + m_data->endCapThinRadiatorThicknessA/2));
1331 pWheelA->add(xfRadiator);
1332 pWheelA->add(pThinRadiatorA);
1333 continue;
1334 }
1335
1336 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionA[counter-1] - m_data->endCapLengthOfWheelsA/2
1337 + m_data->outerRadiusOfStraw + m_data->endCapMainRadiatorThicknessA/2));
1338 pWheelA->add(xfRadiator);
1339 pWheelA->add(pMainRadiatorA);
1340 }
1341 // Place Inner/Outer supports in the wheel
1342 pWheelA->add(pInnerSupportA);
1343 pWheelA->add(pOuterSupportA);
1344
1345 // Place wheel in the Endcap Volume
1346 GeoAlignableTransform * xfWheel = new GeoAlignableTransform( GeoTrf::TranslateZ3D(WheelPlacerA) );
1347
1348 pCommonEndcapAB[iiSide]->add(xfWheel);
1349 pCommonEndcapAB[iiSide]->add(new GeoIdentifierTag(iiWheel));
1350 pCommonEndcapAB[iiSide]->add(pWheelA);
1351
1352 // Register alignable node
1353 int barrel_ec = (iiSide) ? -2 : +2;
1354 Identifier idModule = idHelper->module_id(barrel_ec, 0, iiWheel);
1355 m_detectorManager->addAlignableTransform(AlignmentLevelModule, idModule, xfWheel, pWheelA);
1356
1357 if (m_data->includeECFoilHeatExchangerAndMembranes) {
1358
1359 // Faraday Foils added
1360 // same Faraday foils for both wheel A and B
1361 // KaptonFoil radius is between R_max of InnerSupport and R_min of OuterSupport....STS
1362 GeoTube* sFaradayFoilWheelAB = new GeoTube(m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1363 m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA,
1364 m_data->endCapFaradayFoilThickness/2);
1365 GeoLogVol* lFaradayFoilWheelAB = new GeoLogVol("FaradayKaptonFoil",sFaradayFoilWheelAB, m_materialManager->getMaterial("trt::FaradayFoilMaterial"));
1366 GeoIntrusivePtr<GeoPhysVol> pFaradayFoilWheelAB{new GeoPhysVol(lFaradayFoilWheelAB)};
1367
1368 // Heat Exchanger added
1369 GeoTube* sHeatExchangerA = new GeoTube(m_data->endCapRMinOfHeatExchanger,m_data->endCapRMaxOfHeatExchanger,m_data->endCapHeatExchangerThicknessA/2);
1370 GeoLogVol* lHeatExchangerA = new GeoLogVol("HeatExchangerA",sHeatExchangerA, m_materialManager->getMaterial("trt::HeatExchangerAMat"));
1371 GeoIntrusivePtr<GeoPhysVol> pHeatExchangerA{new GeoPhysVol(lHeatExchangerA)};
1372
1373 // Inner/Outer Support Gapper added
1374 GeoTube* sInnerSupportGapperA = new GeoTube(m_data->endCapInnerRadiusOfSupportA,
1375 m_data->endCapInnerRadiusOfSupportA + m_data->endCapRadialThicknessOfInnerSupportA,
1376 m_data->endCapHeatExchangerThicknessA/2 + m_data->endCapFaradayFoilThickness/2 + zdelta);
1377 GeoLogVol* lInnerSupportGapperA = new GeoLogVol("InnerSupportGapperA", sInnerSupportGapperA, m_materialManager->getMaterial("trt::InnerSupportA"));
1378 GeoIntrusivePtr<GeoPhysVol> pInnerSupportGapperA{new GeoPhysVol(lInnerSupportGapperA)};
1379
1380 GeoTube* sOuterSupportGapperA = new GeoTube(m_data->endCapOuterRadiusOfSupportA - m_data->endCapRadialThicknessOfOuterSupportA,
1381 m_data->endCapOuterRadiusOfSupportA,
1382 m_data->endCapHeatExchangerThicknessA/2 + m_data->endCapFaradayFoilThickness/2 + zdelta);
1383 GeoLogVol* lOuterSupportGapperA = new GeoLogVol("OuterSupportGapperA", sOuterSupportGapperA, m_materialManager->getMaterial("trt::OuterSupportA"));
1384 GeoIntrusivePtr<GeoPhysVol> pOuterSupportGapperA{new GeoPhysVol(lOuterSupportGapperA)};
1385
1386 if(iiWheel<=firstIndexOfB-1)
1387 {
1388 xfFaradayFoilFront = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerA
1389 - m_data->endCapLengthOfWheelsA/2
1390 - m_data->endCapFaradayFoilThickness/2.0));
1391 xfFaradayFoilBack = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerA
1392 + m_data->endCapLengthOfWheelsA/2
1393 + m_data->endCapFaradayFoilThickness/2.0));
1394 pCommonEndcapAB[iiSide]->add(xfFaradayFoilFront);
1395 pCommonEndcapAB[iiSide]->add(pFaradayFoilWheelAB);
1396 pCommonEndcapAB[iiSide]->add(xfFaradayFoilBack);
1397 pCommonEndcapAB[iiSide]->add(pFaradayFoilWheelAB);
1398 }
1399 // Place HeatExchanger after putiing wheel only. No heat exchanger after the last wheel.
1400
1401 // Ditto for Inner/OuterSupportGapper
1402 if(iiWheel<firstIndexOfB-1)
1403 {
1404 xfHeatExchanger = new GeoTransform(GeoTrf::TranslateZ3D( WheelPlacerA
1405 + m_data->endCapLengthOfWheelsA/2
1406 + m_data->endCapFaradayFoilThickness
1407 + m_data->endCapHeatExchangerThicknessA/2));
1408 pCommonEndcapAB[iiSide]->add(xfHeatExchanger);
1409 pCommonEndcapAB[iiSide]->add(pHeatExchangerA);
1410
1411 xfInnerSupportGapperA = new GeoTransform(GeoTrf::TranslateZ3D( WheelPlacerA
1412 + m_data->endCapLengthOfWheelsA/2
1413 + m_data->endCapFaradayFoilThickness
1414 + m_data->endCapHeatExchangerThicknessA/2));
1415 xfOuterSupportGapperA = new GeoTransform(GeoTrf::TranslateZ3D( WheelPlacerA
1416 + m_data->endCapLengthOfWheelsA/2
1417 + m_data->endCapFaradayFoilThickness
1418 + m_data->endCapHeatExchangerThicknessA/2));
1419 pCommonEndcapAB[iiSide]->add(xfInnerSupportGapperA);
1420 pCommonEndcapAB[iiSide]->add(pInnerSupportGapperA);
1421 pCommonEndcapAB[iiSide]->add(xfOuterSupportGapperA);
1422 pCommonEndcapAB[iiSide]->add(pOuterSupportGapperA);
1423 }
1424
1425 } //include membrane, heat exchanger and foil
1426 } // iiWheel loop for Wheel A
1427 } // if (pCommonEndcapAB[iiSide]) block for Wheel A
1428 } // iiSide loop for Wheel A
1429
1430
1431
1432 // --------------- Wheel B ----------------------------
1433
1434 //Check here that (m_data->endcapNumberOfStrawsInStrawLayer_AWheels == m_data->endcapNumberOfStrawsInStrawLayer_BWheels) !!
1435 //We assume this in several places!
1436
1437 // Inner/Outer supports
1438
1439 GeoTube* sInnerSupportB = new GeoTube(m_data->endCapInnerRadiusOfSupportB,
1440 m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1441 m_data->endCapLengthOfWheelsB/2);
1442 GeoLogVol* lInnerSupportB = new GeoLogVol("InnerSupportB", sInnerSupportB, m_materialManager->getMaterial("trt::InnerSupportB"));
1443 GeoPhysVol* pInnerSupportB = new GeoPhysVol(lInnerSupportB);
1444
1445 GeoTube* sOuterSupportB = new GeoTube(m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB,
1446 m_data->endCapOuterRadiusOfSupportB, m_data->endCapLengthOfWheelsB/2);
1447 GeoLogVol* lOuterSupportB = new GeoLogVol("OuterSupportB", sOuterSupportB, m_materialManager->getMaterial("trt::OuterSupportB"));
1448 GeoPhysVol* pOuterSupportB = new GeoPhysVol(lOuterSupportB);
1449
1450 // Straw plane
1451 GeoFullPhysVol* pStrawPlaneB_Kr = nullptr;
1452 GeoFullPhysVol* pStrawPlaneB_Ar = nullptr;
1453 if (m_doKrypton)
1454 pStrawPlaneB_Kr = makeStrawPlane(firstIndexOfB,GM_KRYPTON);
1455 if (m_doArgon)
1456 pStrawPlaneB_Ar = makeStrawPlane(firstIndexOfB,GM_ARGON);
1457 GeoIntrusivePtr<GeoFullPhysVol> pStrawPlaneB {makeStrawPlane(firstIndexOfB)};
1458
1459 // Radiators
1460
1461 GeoTube* sMainRadiatorB = new GeoTube(m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB, //TK: no dist between rad&support at inner??????????????????????????????????????
1462 m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB
1463 - m_data->endCapRadialDistFromRadToOuterSupportB, m_data->endCapMainRadiatorThicknessB/2);
1464 GeoLogVol* lMainRadiatorB = new GeoLogVol("MainRadiatorB",sMainRadiatorB, m_materialManager->getMaterial("trt::FoilRadiatorB"));
1465 GeoPhysVol* pMainRadiatorB = new GeoPhysVol(lMainRadiatorB);
1466
1467 GeoTube* sThinRadiatorB = new GeoTube(m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1468 m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB
1469 - m_data->endCapRadialDistFromRadToOuterSupportB,
1470 m_data->endCapThinRadiatorThicknessB/2);
1471 GeoLogVol* lThinRadiatorB = new GeoLogVol("ThinRadiatorB",sThinRadiatorB, m_materialManager->getMaterial("trt::FoilRadiatorB"));
1472 GeoPhysVol* pThinRadiatorB = new GeoPhysVol(lThinRadiatorB);
1473
1474 GeoTube* sMiddleRadiatorB = new GeoTube(m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1475 m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB
1476 - m_data->endCapRadialDistFromRadToOuterSupportB, m_data->endCapMiddleRadiatorThicknessB/2);
1477 GeoLogVol* lMiddleRadiatorB = new GeoLogVol("MiddleRadiatorB",sMiddleRadiatorB, m_materialManager->getMaterial("trt::FoilRadiatorB"));
1478 GeoPhysVol* pMiddleRadiatorB = new GeoPhysVol(lMiddleRadiatorB);
1479
1480 // Wheel
1481 //TK: endCapAmountWheelLengthExceedsSumOfLayer = ...................
1482 GeoTube* sWheelB = new GeoTube( m_data->endCapInnerRadiusOfSupportB,m_data->endCapOuterRadiusOfSupportB, m_data->endCapLengthOfWheelsB/2);
1483 GeoLogVol* lWheelB = new GeoLogVol("WheelB", sWheelB, m_materialManager->getMaterial("trt::CO2"));
1484
1485 // This is the straw pitch.
1486 double deltaPhiForStrawsB = 360.*GeoModelKernelUnits::deg/m_data->endcapNumberOfStrawsInStrawLayer_BWheels;
1487
1488 for(iiSide=0; iiSide<nSides; iiSide++) {
1489
1490 double WheelPlacerB = m_data->endCapPositionOfFirstWheelB[iiSide];
1491
1492 // Wheel B
1493 if (pCommonEndcapAB[iiSide]) {
1494 for(iiWheel=firstIndexOfB; iiWheel < firstIndexOfC; iiWheel++)
1495 {
1496 //prepair to place wheel
1497 WheelPlacerB += m_data->endCapDistanceBetweenWheelCentersB[iiSide][iiWheel];
1498
1499 GeoFullPhysVol* pWheelB = new GeoFullPhysVol(lWheelB);
1500
1501 GeoAlignableTransform * xfAlignableModule = nullptr;
1502
1503 // Place planes in the wheel
1504 for (iiPlane = 0; iiPlane < m_data->endCapNumberOfStrawLayersPerWheelB; iiPlane++)
1505 {
1506
1507 // Each wheel in WheelB is subdivided into 2 alignable objects (every 4th straw layer)
1508 // We create an alignable transform for each alignable module
1509 // and multiply this by the transform for every straw layer in the "alignable module"
1510 // The tranform is by default Identity.
1511 if (iiPlane % 4 == 0) {
1512 // Register alignable node
1513 int barrel_ec = (iiSide) ? -2 : +2;
1514 xfAlignableModule = new GeoAlignableTransform(GeoTrf::Transform3D::Identity());
1515 Identifier idSubModule = idHelper->layer_id(barrel_ec, 0, iiWheel, iiPlane);
1516 // We pass the parent volume as the local delta for this correction is the same as a local delta
1517 // on the transformation of the wheel.
1518 m_detectorManager->addAlignableTransform(AlignmentLevelSubWheel, idSubModule, xfAlignableModule, pWheelB);
1519 }
1520
1521 int bar_ec = (iiSide) ? -2 : +2;
1522 Identifier TRT_Identifier = idHelper->straw_id(bar_ec, 1, iiWheel, 1, 1);
1523 int strawStatusHT = TRTCond::StrawStatus::Good;
1524 if (m_strawsvcavailable) {
1525 if(m_sumTool) {
1526 strawStatusHT = m_sumTool->getStatusHT(TRT_Identifier, Gaudi::Hive::currentContext());
1527 strawStatusFile << TRT_Identifier.get_compact() << std::format("{:5}",strawStatusHT) << std::endl;
1528 }
1529 else {
1530 strawStatusHT = m_statusAccessor->status(TRT_Identifier);
1531 }
1532 }
1533 ActiveGasMixture agm = DecideGasMixture(strawStatusHT);
1534
1535 //Ruslan: insert plane with Ar-straws
1536 //Artem: same for Kr
1537 switch (agm)
1538 {
1539 case GM_ARGON:
1540 ATH_MSG_DEBUG( "Marking Argon straws from /TRT/Cond/StatusHT:\t"
1541 << idHelper->print_to_string(TRT_Identifier) );
1542 childPlane = pStrawPlaneB_Ar->clone();
1543 break;
1544 case GM_KRYPTON:
1545 ATH_MSG_DEBUG( "Marking Krypton straws from /TRT/Cond/StatusHT:\t"
1546 << idHelper->print_to_string(TRT_Identifier));
1547 childPlane = pStrawPlaneB_Kr->clone();
1548 break;
1549 case GM_XENON:
1550 ATH_MSG_DEBUG( "Marking Xenon straws from /TRT/Cond/StatusHT:\t"
1551 << idHelper->print_to_string(TRT_Identifier));
1552 childPlane = pStrawPlaneB->clone();
1553 break;
1554 default:
1555 ATH_MSG_FATAL( "Unexpected gas mixture: " << agm);
1556 throw std::runtime_error("Unexpected gas mixture");
1557 return;
1558 }
1559
1560 // phiPlane is phi of straw 0, sector 0 (online numbering)
1561 double phiPlane = m_data->endCapPhiOfFirstStraw + RotationsOfStrawPlanes[iiPlane%nStrawLayMaxEc]*deltaPhiForStrawsB;
1562
1563 // For compatibility with old geometry we have to shift every eighth wheel by 1 straw pitch.
1564 if(iiSide && oldGeometry && (iiPlane%8 == 0)) {
1565 phiPlane += deltaPhiForStrawsB;
1566 }
1567
1568 xfPlane = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionB[iiPlane]
1569 - m_data->endCapLengthOfWheelsB/2)*GeoTrf::RotateZ3D(phiPlane));
1570
1571 if (xfAlignableModule) pWheelB->add(xfAlignableModule);
1572 pWheelB->add(xfPlane);
1573 pWheelB->add(new GeoIdentifierTag(iiPlane));
1574 pWheelB->add(childPlane);
1575
1576 // Create elements
1577 for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1578 {
1579 // m_data->nEndcapPhi assumed to be even.
1580 // For positive endcap online == offline. For negative endcap we rotate 180 deg about y axis so
1581 // sector 0 -> 15, 15 -> 0, 16 -> 31, 31 -> 16, etc. This is achieved with
1582 // sector -> (nSectors + nSectors/2 - sector - 1) % nSectors
1583 int iiPhiOffline = (iiSide==0) ? iiPhi : (3*m_data->nEndcapPhi/2 - iiPhi - 1)% m_data->nEndcapPhi;
1584 element = new InDetDD::TRT_EndcapElement(childPlane,
1585 descriptorsAB[iiSide][iiPlane%nStrawLayMaxEc][iiPhi],
1586 iiSide==0,
1587 iiWheel,
1588 iiPlane,
1589 iiPhiOffline,
1590 idHelper,
1591 m_detectorManager->conditions());
1592 m_detectorManager->manageEndcapElement(element);
1593 }
1594 }
1595
1596 // Place radiators in the wheel
1597 for (counter = 1; counter <= m_data->endCapNumberOfStrawLayersPerWheelB; counter++)
1598 {
1599 // Main radiators
1600 if (counter % 4 != 0)
1601 {
1602 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionB[counter-1] - m_data->endCapLengthOfWheelsB/2
1603 + m_data->outerRadiusOfStraw + m_data->endCapMainRadiatorThicknessB/2));
1604 pWheelB->add(xfRadiator);
1605 pWheelB->add(pMainRadiatorB);
1606 }
1607
1608 // Thin radiators
1609 if (counter == 1 || counter == 8)
1610 {
1611 sign = counter == 1? -1 : 1;
1612 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionB[counter-1] - m_data->endCapLengthOfWheelsB/2 + sign*(m_data->outerRadiusOfStraw + m_data->endCapThinRadiatorThicknessB/2)));
1613 pWheelB->add(xfRadiator);
1614 pWheelB->add(pThinRadiatorB);
1615 }
1616
1617 // Middle radiators
1618 if (counter == 4 || counter == 5)
1619 {
1620 sign = counter == 4 ? 1 : -1;
1621 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionB[counter-1] - m_data->endCapLengthOfWheelsB/2 + sign*(m_data->outerRadiusOfStraw + m_data->endCapMiddleRadiatorThicknessB/2)));
1622 pWheelB->add(xfRadiator);
1623 pWheelB->add(pMiddleRadiatorB);
1624 }
1625 }
1626
1627 // Place Inner/Outer supports in the wheel
1628 pWheelB->add(pInnerSupportB);
1629 pWheelB->add(pOuterSupportB);
1630
1631 // Place wheel in the Endcap Volume
1632 GeoAlignableTransform * xfWheel = new GeoAlignableTransform(GeoTrf::TranslateZ3D( WheelPlacerB ));
1633
1634
1635 pCommonEndcapAB[iiSide]->add(xfWheel);
1636 pCommonEndcapAB[iiSide]->add(new GeoIdentifierTag(iiWheel));
1637 pCommonEndcapAB[iiSide]->add(pWheelB);
1638
1639 // Register alignable node
1640 int barrel_ec = (iiSide) ? -2 : +2;
1641 Identifier idModule = idHelper->module_id(barrel_ec, 0, iiWheel);
1642 m_detectorManager->addAlignableTransform(AlignmentLevelModule, idModule, xfWheel, pWheelB);
1643
1644
1645 if (m_data->includeECFoilHeatExchangerAndMembranes) {
1646
1647 // Faraday Foils added
1648 // same Faraday foils for both wheel A and B
1649 // KaptonFoil radius is between R_max of InnerSupport and R_min of OuterSupport.....STS
1650 GeoTube* sFaradayFoilWheelAB = new GeoTube(m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1651 m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB,
1652 m_data->endCapFaradayFoilThickness/2);
1653 GeoLogVol* lFaradayFoilWheelAB = new GeoLogVol("FaradayKaptonFoil",sFaradayFoilWheelAB, m_materialManager->getMaterial("trt::FaradayFoilMaterial"));
1654 GeoIntrusivePtr<GeoPhysVol> pFaradayFoilWheelAB{new GeoPhysVol(lFaradayFoilWheelAB)};
1655
1656 // Heat Exchanger
1657 GeoTube* sHeatExchangerB = new GeoTube(m_data->endCapRMinOfHeatExchanger,m_data->endCapRMaxOfHeatExchanger,m_data->endCapHeatExchangerThicknessB/2);
1658
1659 GeoLogVol* lHeatExchangerB = new GeoLogVol("HeatExchangerB", sHeatExchangerB, m_materialManager->getMaterial("trt::HeatExchangerBMat"));
1660 GeoIntrusivePtr<GeoPhysVol> pHeatExchangerB{new GeoPhysVol(lHeatExchangerB)};
1661
1662 // Inner/Outer Support Gapper added
1663 GeoTube* sInnerSupportGapperB = new GeoTube(m_data->endCapInnerRadiusOfSupportB,
1664 m_data->endCapInnerRadiusOfSupportB + m_data->endCapRadialThicknessOfInnerSupportB,
1665 m_data->endCapHeatExchangerThicknessB/2 + m_data->endCapFaradayFoilThickness/2 + zdelta);
1666 GeoLogVol* lInnerSupportGapperB = new GeoLogVol("InnerSupportGapperB", sInnerSupportGapperB, m_materialManager->getMaterial("trt::InnerSupportB"));
1667 GeoIntrusivePtr<GeoPhysVol> pInnerSupportGapperB{new GeoPhysVol(lInnerSupportGapperB)};
1668
1669 GeoTube* sOuterSupportGapperB = new GeoTube(m_data->endCapOuterRadiusOfSupportB - m_data->endCapRadialThicknessOfOuterSupportB,
1670 m_data->endCapOuterRadiusOfSupportB,
1671 m_data->endCapHeatExchangerThicknessB/2 + m_data->endCapFaradayFoilThickness/2 + zdelta);
1672 GeoLogVol* lOuterSupportGapperB = new GeoLogVol("OuterSupportGapperB", sOuterSupportGapperB, m_materialManager->getMaterial("trt::OuterSupportB"));
1673 GeoIntrusivePtr<GeoPhysVol> pOuterSupportGapperB{new GeoPhysVol(lOuterSupportGapperB)};
1674
1675 // Place kapton foils on a wheel just like a sandwitch
1676 if(iiWheel-firstIndexOfB<firstIndexOfC-firstIndexOfB)
1677 {
1678 xfFaradayFoilFront = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerB
1679 - m_data->endCapLengthOfWheelsB/2
1680 - m_data->endCapFaradayFoilThickness/2.0));
1681 xfFaradayFoilBack = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerB
1682 + m_data->endCapLengthOfWheelsB/2
1683 + m_data->endCapFaradayFoilThickness/2.0));
1684
1685 pCommonEndcapAB[iiSide]->add(xfFaradayFoilFront);
1686 pCommonEndcapAB[iiSide]->add(pFaradayFoilWheelAB);
1687 pCommonEndcapAB[iiSide]->add(xfFaradayFoilBack);
1688 pCommonEndcapAB[iiSide]->add(pFaradayFoilWheelAB);
1689 }
1690
1691 // Place HeatExchanger after putiing wheel only. No heat exchanger after the last wheel
1692 // Ditto for Inner/OuterSupportGapper
1693 if(iiWheel-firstIndexOfB<firstIndexOfC-firstIndexOfB-1)
1694 {
1695 xfHeatExchanger = new GeoTransform(GeoTrf::TranslateZ3D( WheelPlacerB
1696 + m_data->endCapLengthOfWheelsB/2
1697 + m_data->endCapFaradayFoilThickness
1698 + m_data->endCapHeatExchangerThicknessB/2));
1699 pCommonEndcapAB[iiSide]->add(xfHeatExchanger);
1700 pCommonEndcapAB[iiSide]->add(pHeatExchangerB);
1701
1702 xfInnerSupportGapperB = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerB
1703 + m_data->endCapLengthOfWheelsB/2
1704 + m_data->endCapFaradayFoilThickness
1705 + m_data->endCapHeatExchangerThicknessB/2));
1706
1707 xfOuterSupportGapperB = new GeoTransform(GeoTrf::TranslateZ3D(WheelPlacerB
1708 + m_data->endCapLengthOfWheelsB/2
1709 + m_data->endCapFaradayFoilThickness
1710 + m_data->endCapHeatExchangerThicknessB/2));
1711 pCommonEndcapAB[iiSide]->add(xfInnerSupportGapperB);
1712 pCommonEndcapAB[iiSide]->add(pInnerSupportGapperB);
1713 pCommonEndcapAB[iiSide]->add(xfOuterSupportGapperB);
1714 pCommonEndcapAB[iiSide]->add(pOuterSupportGapperB);
1715 }
1716 } // include foil, heat exchanger and membrane
1717 }// iiWheel loop for Wheel B
1718 } // if (pCommonEndcapAB[iiSide]) block for Wheel B
1719 } // iiSide loop for Wheel B
1720
1721 } // end AB
1722
1723
1724 if(m_sumTool) {
1725 strawStatusFile.close();
1726 }
1727
1728 if (m_data->includeECFoilHeatExchangerAndMembranes) {
1729 // Membranes
1730
1731 GeoTube* sMbrane = new GeoTube(m_data->endCapRMinOfMbrane, m_data->endCapRMaxOfMbrane, m_data->endCapThicknessOfMbrane/2.0);
1732 GeoLogVol* lMbrane = new GeoLogVol("Membrane", sMbrane, m_materialManager->getMaterial("trt::EndCapMbrane"));
1733 GeoPhysVol* pMbrane = new GeoPhysVol(lMbrane);
1734
1735 GeoTransform *xfMbraneWheelA1 = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapZMinOfMbraneWheelA1 + m_data->endCapThicknessOfMbrane/2.0));
1736 GeoTransform *xfMbraneWheelA2 = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapZMinOfMbraneWheelA2 + m_data->endCapThicknessOfMbrane/2.0));
1737 GeoTransform *xfMbraneWheelB1 = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapZMinOfMbraneWheelB1 + m_data->endCapThicknessOfMbrane/2.0));
1738 GeoTransform *xfMbraneWheelB2 = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapZMinOfMbraneWheelB2 + m_data->endCapThicknessOfMbrane/2.0));
1739
1740 for(iiSide=0; iiSide<nSides; iiSide++) {
1741 pCommonEndcapAB[iiSide]->add(xfMbraneWheelA1);
1742 pCommonEndcapAB[iiSide]->add(pMbrane);
1743 pCommonEndcapAB[iiSide]->add(xfMbraneWheelA2);
1744 pCommonEndcapAB[iiSide]->add(pMbrane);
1745 pCommonEndcapAB[iiSide]->add(xfMbraneWheelB1);
1746 pCommonEndcapAB[iiSide]->add(pMbrane);
1747 pCommonEndcapAB[iiSide]->add(xfMbraneWheelB2);
1748 pCommonEndcapAB[iiSide]->add(pMbrane);
1749 }
1750 }
1751
1752
1753
1754 // ---------------- Wheel C ---------------------------
1755 // Not present in initial layout
1756 if (endcapCPlusPresent || endcapCMinusPresent) {
1757 // Inner/Outer supports
1758 GeoTube* sInnerSupportC = new GeoTube(m_data->endCapInnerRadiusOfSupportC, m_data->endCapInnerRadiusOfSupportC
1759 + m_data->endCapRadialThicknessOfInnerSupportC, m_data->endCapLengthOfWheelsC/2);
1760 GeoLogVol* lInnerSupportC = new GeoLogVol("InnerSupportC", sInnerSupportC, m_materialManager->getMaterial("trt::InnerSupportC"));
1761 GeoPhysVol* pInnerSupportC = new GeoPhysVol(lInnerSupportC);
1762
1763 GeoTube* sOuterSupportC = new GeoTube(m_data->endCapOuterRadiusOfSupportC - m_data->endCapRadialThicknessOfOuterSupportC,
1764 m_data->endCapOuterRadiusOfSupportC, m_data->endCapLengthOfWheelsC/2);
1765 GeoLogVol* lOuterSupportC = new GeoLogVol("OuterSupportC", sOuterSupportC, m_materialManager->getMaterial("trt::OuterSupportC"));
1766 GeoPhysVol* pOuterSupportC = new GeoPhysVol(lOuterSupportC);
1767
1768 // Straw plane
1769 GeoIntrusivePtr<GeoFullPhysVol> pStrawPlaneC = makeStrawPlane(firstIndexOfC);
1770
1771 // Radiators
1772 GeoTube* sMainRadiatorC = new GeoTube(m_data->endCapInnerRadiusOfSupportC + m_data->endCapRadialThicknessOfInnerSupportC,
1773 m_data->endCapOuterRadiusOfSupportC - m_data->endCapRadialThicknessOfOuterSupportC
1774 - m_data->endCapRadialDistFromRadToOuterSupportC, m_data->endCapMainRadiatorThicknessC/2);
1775 GeoLogVol* lMainRadiatorC = new GeoLogVol("MainRadiatorC",sMainRadiatorC, m_materialManager->getMaterial("trt::FoilRadiatorAC"));
1776 GeoPhysVol* pMainRadiatorC = new GeoPhysVol(lMainRadiatorC);
1777
1778 GeoTube* sThinRadiatorC = new GeoTube(m_data->endCapInnerRadiusOfSupportC + m_data->endCapRadialThicknessOfInnerSupportC,
1779 m_data->endCapOuterRadiusOfSupportC - m_data->endCapRadialThicknessOfOuterSupportC
1780 - m_data->endCapRadialDistFromRadToOuterSupportC, m_data->endCapThinRadiatorThicknessC/2);
1781 GeoLogVol* lThinRadiatorC = new GeoLogVol("ThinRadiatorC",sThinRadiatorC, m_materialManager->getMaterial("trt::FoilRadiatorAC"));
1782 GeoPhysVol* pThinRadiatorC = new GeoPhysVol(lThinRadiatorC);
1783
1784 // Wheel
1785 GeoTube* sWheelC = new GeoTube( m_data->endCapInnerRadiusOfSupportC,m_data->endCapOuterRadiusOfSupportC, m_data->endCapLengthOfWheelsC/2);
1786 GeoLogVol* lWheelC = new GeoLogVol("WheelC", sWheelC, m_materialManager->getMaterial("trt::CO2"));
1787
1788 // This is the straw pitch.
1789 double deltaPhiForStrawsC = 360.*GeoModelKernelUnits::deg/m_data->endcapNumberOfStrawsInStrawLayer_CWheels;
1790
1791 for(iiSide=0; iiSide<nSides; iiSide++) {
1792 // Wheel C
1793 if (pCommonEndcapC[iiSide]) {
1794 for(iiWheel=firstIndexOfC; iiWheel < indexUpperBound; iiWheel++)
1795 {
1796 GeoFullPhysVol* pWheelC = new GeoFullPhysVol(lWheelC);
1797
1798 // Place planes in the wheel
1799 for (iiPlane = 0; iiPlane < m_data->endCapNumberOfStrawLayersPerWheelC; iiPlane++)
1800 {
1801 // phiPlane is phi of straw 0, sector 0 (online numbering)
1802 double phiPlane = m_data->endCapPhiOfFirstStraw + RotationsOfStrawPlanes[iiPlane%nStrawLayMaxEc]*deltaPhiForStrawsC;
1803
1804 // For compatibility with old geometry we have to shift every eighth wheel by 1 straw pitch.
1805 if(iiSide && oldGeometry && (iiPlane%8 == 0)) {
1806 phiPlane += deltaPhiForStrawsC;
1807 }
1808
1809
1810 childPlane = pStrawPlaneC->clone();
1811
1812 xfPlane = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionC[iiPlane]
1813 - m_data->endCapLengthOfWheelsC/2)*GeoTrf::RotateZ3D(phiPlane));
1814 pWheelC->add(xfPlane);
1815 pWheelC->add(new GeoIdentifierTag(iiPlane));
1816 pWheelC->add(childPlane);
1817
1818 // Create descriptors
1819 // Just do it for the first wheel
1820 if(iiWheel==firstIndexOfC && iiPlane < nStrawLayMaxEc)
1821 for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1822 {
1823 pDescriptor = new InDetDD::TRT_EndcapDescriptor();
1824 m_detectorManager->setEndcapDescriptor(pDescriptor);
1825
1826 pDescriptor->nStraws() = m_data->endcapNumberOfStrawsInStrawLayer_CWheels/m_data->nEndcapPhi;
1827 pDescriptor->strawPitch() = deltaPhiForStrawsC;
1828
1829
1830 double startPhi = phiPlane + iiPhi * pDescriptor->strawPitch() * pDescriptor->nStraws();
1831
1832 // For negative endcap the startPhi is the last straw in the physical sector, it then gets
1833 // rotated 180 around y axis (phi -> pi - phi)
1834 if (iiSide) {
1835 startPhi = GeoModelKernelUnits::pi - (startPhi + pDescriptor->strawPitch() * (pDescriptor->nStraws() - 1));
1836 }
1837
1838 // Make sure its between -pi and pi.
1839 if (startPhi <= -GeoModelKernelUnits::pi) startPhi += 2*GeoModelKernelUnits::pi;
1840 if (startPhi > GeoModelKernelUnits::pi) startPhi -= 2*GeoModelKernelUnits::pi;
1841
1842
1843 pDescriptor->startPhi() = startPhi;
1844
1845 pDescriptor->strawLength() = m_data->endCapOuterRadiusOfSupportC - m_data->endCapRadialThicknessOfOuterSupportC
1846 - 2*m_data->lengthOfDeadRegion - m_data->endCapRadialThicknessOfInnerSupportC - m_data->endCapInnerRadiusOfSupportC;
1847 pDescriptor->innerRadius() = m_data->endCapInnerRadiusOfSupportC + m_data->endCapRadialThicknessOfInnerSupportC + m_data->lengthOfDeadRegion;
1848 pDescriptor->setStrawTransformField(m_detectorManager->endcapTransformField(2),iiPhi*pDescriptor->nStraws());
1849
1850
1851 descriptorsC[iiSide][iiPlane%nStrawLayMaxEc][iiPhi] = pDescriptor;
1852 }
1853
1854 // Create elements
1855 for(iiPhi = 0; iiPhi < m_data->nEndcapPhi; iiPhi++)
1856 {
1857 // m_data->nEndcapPhi assumed to be even.
1858 // For positive endcap online == offline. For negative endcap we rotate 180 deg about y axis so
1859 // sector 0 -> 15, 15 -> 0, 16 -> 31, 31 -> 16, etc. This is achieved with
1860 // sector -> (nSectors + nSectors/2 - sector - 1) % nSectors
1861 int iiPhiOffline = (iiSide==0) ? iiPhi : (3*m_data->nEndcapPhi/2 - iiPhi - 1)% m_data->nEndcapPhi;
1862 element = new InDetDD::TRT_EndcapElement(childPlane,
1863 descriptorsC[iiSide][iiPlane%nStrawLayMaxEc][iiPhi],
1864 iiSide==0,
1865 iiWheel,
1866 iiPlane,
1867 iiPhiOffline,
1868 idHelper,
1869 m_detectorManager->conditions());
1870 m_detectorManager->manageEndcapElement(element);
1871 }
1872 }
1873
1874 // Place radiators in the wheel
1875 for (counter = 1; counter <= m_data->endCapNumberOfStrawLayersPerWheelC; counter++)
1876 {
1877 if (counter % 4 == 1)
1878 {
1879 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionC[counter-1] - m_data->endCapLengthOfWheelsC/2
1880 - m_data->lengthOfDeadRegion - m_data->endCapThinRadiatorThicknessC/2));
1881 pWheelC->add(xfRadiator);
1882 pWheelC->add(pThinRadiatorC);
1883 }
1884
1885 if (counter % 4 == 0)
1886 {
1887 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionC[counter-1] - m_data->endCapLengthOfWheelsC/2
1888 + m_data->outerRadiusOfStraw + m_data->endCapThinRadiatorThicknessC/2));
1889 pWheelC->add(xfRadiator);
1890 pWheelC->add(pThinRadiatorC);
1891 continue;
1892 }
1893
1894 xfRadiator = new GeoTransform(GeoTrf::TranslateZ3D(m_data->endCapLayerZPositionC[counter-1] - m_data->endCapLengthOfWheelsC/2
1895 + m_data->outerRadiusOfStraw + m_data->endCapMainRadiatorThicknessC/2));
1896 pWheelC->add(xfRadiator);
1897 pWheelC->add(pMainRadiatorC);
1898 }
1899
1900 // Place Inner/Outer supports in the wheel
1901 pWheelC->add(pInnerSupportC);
1902 pWheelC->add(pOuterSupportC);
1903
1904 // Place wheel in the Endcap Volume
1905 GeoAlignableTransform * xfWheel
1906 = new GeoAlignableTransform(GeoTrf::TranslateZ3D(m_data->endCapPositionOfFirstWheelC
1907 + (iiWheel - firstIndexOfC)*m_data->endCapDistanceBetweenWheelCentersC));
1908
1909 pCommonEndcapC[iiSide]->add(xfWheel);
1910 pCommonEndcapC[iiSide]->add(new GeoIdentifierTag(iiWheel));
1911 pCommonEndcapC[iiSide]->add(pWheelC);
1912
1913 // Register alignable node
1914 int barrel_ec = (iiSide) ? -2 : +2;
1915 Identifier idModule = idHelper->module_id(barrel_ec, 0, iiWheel);
1916 m_detectorManager->addAlignableTransform(AlignmentLevelModule, idModule, xfWheel, pWheelC);
1917
1918
1919 } // iiWheel loop for Wheel C
1920 } // if (pCommonEndcapC[iiSide]) block for Wheel C
1921 } // iiSide loop for Wheel C
1922
1923 } // End Wheel C
1924
1925
1926 // Set up the nearest neighbor pointers: in Z
1927 for (iiSide=0; iiSide<2; iiSide++)
1928 for(iiPhi=0; iiPhi<m_data->nEndcapPhi; iiPhi++)
1929 {
1930 InDetDD::TRT_EndcapElement *prev = nullptr;
1931 for (iiWheel=0; iiWheel<indexUpperBound; iiWheel++)
1932 for (iiPlane=0; iiPlane<m_detectorManager->getNumerology()->getNEndcapLayers(iiWheel); iiPlane++)
1933 {
1934 InDetDD::TRT_EndcapElement *current = m_detectorManager->getEndcapElement(iiSide, iiWheel, iiPlane, iiPhi);
1935 if (prev && current)
1936 {
1937 prev->setNextInZ(current);
1938 current->setPreviousInZ(prev);
1939 }
1940 prev=current;
1941 }
1942 }
1943}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
GeoIntrusivePtr< T > GeoNodePtr
Definition GeoNodePtr.h:12
int sign(int a)
#define y
#define x
#define z
std::string print_to_string(Identifier id, const IdContext *context=0) const
or provide the printout in string form
value_type get_compact() const
Get the compact id.
InDetDD::AthenaComps * getAthenaComps()
void setNextInPhi(const TRT_BarrelElement *element)
Sets the next-in-phi detector.
void setNextInR(const TRT_BarrelElement *element)
Sets the next-in-r detector.
double & strawPitch()
The straw pitch (angular!
void setStrawTransformField(const GeoXF::Function *xf, size_t offsetInto)
Sets the transform field for straws and offset.
double & startPhi()
The starting phi (angular!
unsigned int & nStraws()
The number of straws in a module:
double & innerRadius()
The inner radius:
void setNextInZ(const TRT_EndcapElement *element)
Set Next in Z.
GeoFullPhysVol * makeStrawPlane(size_t w, ActiveGasMixture gasMixture=GM_XENON)
InDetDD::TRT_DetectorManager * m_detectorManager
const GeoShape * makeModule(double length, const GeoTrf::Vector2D &corner1, const GeoTrf::Vector2D &corner2, const GeoTrf::Vector2D &corner3, const GeoTrf::Vector2D &corner4, GeoTrf::Transform3D &absolutePosition, double shrinkDist=0) const
std::unique_ptr< InDetMaterialManager > m_materialManager
std::unique_ptr< TRTParameterInterface > m_data
GeoPhysVol * makeStraw(bool hasLargeDeadRegion=false, ActiveGasMixture gasMixture=GM_XENON)
ActiveGasMixture DecideGasMixture(int strawStatusHT)
Identifier layer_id(int barrel_ec, int phi_module, int layer_or_wheel, int straw_layer) const
For an individual straw layer.
Definition TRT_ID.h:494
Identifier straw_id(int barrel_ec, int phi_module, int layer_or_wheel, int straw_layer, int straw) const
Three ways of getting id for a single straw:
Definition TRT_ID.h:575
Identifier module_id(int barrel_ec, int phi_module, int layer_or_wheel) const
For an individual module phi sector.
Definition TRT_ID.h:442
Identifier barrel_ec_id(int barrel_ec) const
For +/-barrel or +/-endcap id.
Definition TRT_ID.h:411
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
bool first
Definition DeMoScan.py:534
@ timedependent_run2
str layout
Definition TileTB.py:76
retrieve(aClass, aKey=None)
Definition PyKernel.py:110

◆ DecideGasMixture()

TRTDetectorFactory_Full::ActiveGasMixture TRTDetectorFactory_Full::DecideGasMixture ( int strawStatusHT)
private

Definition at line 2340 of file TRTDetectorFactory_Full.cxx.

2341 {
2342 ActiveGasMixture return_agm = GM_XENON;
2343 if (m_strawsvcavailable && m_doArgon && (strawStatusHT == TRTCond::StrawStatus::Dead ||
2344 strawStatusHT == TRTCond::StrawStatus::Argon))
2345 return_agm = GM_ARGON;
2346 else if (m_strawsvcavailable && m_doKrypton && (strawStatusHT == TRTCond::StrawStatus::Krypton))
2347 return_agm = GM_KRYPTON;
2348 else if (m_strawsvcavailable && strawStatusHT != TRTCond::StrawStatus::Xenon &&
2349 strawStatusHT != TRTCond::StrawStatus::Good &&
2350 strawStatusHT != TRTCond::StrawStatus::Dead &&
2351 strawStatusHT != TRTCond::StrawStatus::Argon &&
2352 strawStatusHT != TRTCond::StrawStatus::Krypton &&
2353 strawStatusHT != TRTCond::StrawStatus::EmulateArgon &&
2354 strawStatusHT != TRTCond::StrawStatus::EmulateKrypton)
2355 {
2356 msg(MSG::FATAL) << "Unexpected StatusHT value: " << strawStatusHT << endmsg;
2357 throw std::runtime_error("Unexpected StatusHT value");
2358 }
2359 return return_agm;
2360 }
#define endmsg
MsgStream & msg
Definition testRead.cxx:32

◆ detStore() [1/2]

StoreGateSvc * InDetDD::DetectorFactoryBase::detStore ( )
inlineinherited

Definition at line 27 of file InDetDetectorFactoryBase.h.

27{return m_athenaComps->detStore();}

◆ detStore() [2/2]

const StoreGateSvc * InDetDD::DetectorFactoryBase::detStore ( ) const
inlineinherited

Definition at line 28 of file InDetDetectorFactoryBase.h.

28{return std::as_const(*m_athenaComps).detStore();}

◆ geoDbTagSvc()

const IGeoDbTagSvc * InDetDD::DetectorFactoryBase::geoDbTagSvc ( ) const
inlineinherited

Definition at line 30 of file InDetDetectorFactoryBase.h.

30{return std::as_const(*m_athenaComps).geoDbTagSvc();}

◆ geomDB()

const IGeometryDBSvc * InDetDD::DetectorFactoryBase::geomDB ( ) const
inlineinherited

Definition at line 34 of file InDetDetectorFactoryBase.h.

34{return m_athenaComps->geomDB();}

◆ getAthenaComps()

InDetDD::AthenaComps * InDetDD::DetectorFactoryBase::getAthenaComps ( )
inlineinherited

Definition at line 42 of file InDetDetectorFactoryBase.h.

42{return m_athenaComps;}

◆ getDetectorManager()

const InDetDD::TRT_DetectorManager * TRTDetectorFactory_Full::getDetectorManager ( ) const
overridevirtual

Definition at line 112 of file TRTDetectorFactory_Full.cxx.

113{
114 //TK: Maybe check that m_detectorManager!=0 ?
115 return m_detectorManager;
116}

◆ makeModule()

const GeoShape * TRTDetectorFactory_Full::makeModule ( double length,
const GeoTrf::Vector2D & corner1,
const GeoTrf::Vector2D & corner2,
const GeoTrf::Vector2D & corner3,
const GeoTrf::Vector2D & corner4,
GeoTrf::Transform3D & absolutePosition,
double shrinkDist = 0 ) const
private

Definition at line 1961 of file TRTDetectorFactory_Full.cxx.

1962 {
1963
1964
1965 // This method takes the absolute coordinates of the four corners,
1966 // constructs the relevant shape, centered around the intersections
1967 // of its diagonals, and returns it along with the absolute
1968 // coordinates of that center (modulePosition).
1969 //
1970 // We know that the four corners _approximately_ can be described as
1971 // the union of two isosceles triangles with same side-lengths and
1972 // different bases.
1973 //
1974 // shrinkDist is for the radiator, which must be similar to the
1975 // shell, but shrunken by some distance.
1976
1977 // First we calculate the relative vectors of the edges:
1978
1979 GeoTrf::Vector2D delta12 = corner1 - corner2; GeoTrf::Vector2D delta23 = corner2 - corner3;
1980 GeoTrf::Vector2D delta34 = corner3 - corner4; GeoTrf::Vector2D delta14 = corner1 - corner4;
1981
1982 // We also need the diagonals.
1983 GeoTrf::Vector2D delta24 = corner2 - corner4;
1984 GeoTrf::Vector2D delta13 = corner1 - corner3;
1985
1986 // Then we find out which way the module bends (NB: .angle returns the UNSIGNED angle!).
1987 double openingAngleOfFirstCorner= angle(delta12,delta14);
1988 int sign = ( openingAngleOfFirstCorner < 90*GeoModelKernelUnits::deg ? 1 : -1);
1989
1990 // If our approximation with triangles were correct, three of the
1991 // lengths (of edges and diagonals) would be equal. We force this
1992 // instead.
1993 //
1994 // (Whether the involved diagonal is 2-4 or 1-3 depends on the sign).
1995 double commonSide = (magn(delta14) + magn(delta23) + (sign==1?magn(delta24):magn(delta13)) ) / 3.;
1996 double base1 = magn(delta12); // Inner base
1997 double base2 = magn(delta34); // Outer base
1998
1999 if (shrinkDist!=0) {
2000 // Since the moving corners bit above doesnt work, we do this instead:
2001 double cosAlpha= sqrt(commonSide*commonSide-0.25*base1*base1)/commonSide;
2002 commonSide -= (1+1/cosAlpha)*shrinkDist;
2003 base1 -= 2*shrinkDist;
2004 base2 -= 2*shrinkDist;
2005 }
2006
2007 double height1 = sqrt (commonSide*commonSide-0.25*base1*base1);
2008 double height2 = sqrt (commonSide*commonSide-0.25*base2*base2);
2009 double rot = atan(base2/height2/2)-atan(base1/height1/2);
2010 double epsilon = 1*GeoModelKernelUnits::micrometer; // needed to ensure perfect overlaps.
2011 GeoTrd *trd1 = new GeoTrd(base1/2+epsilon, epsilon, length/2, length/2, height1/2);
2012 GeoTrd *trd2 = new GeoTrd(epsilon, base2/2+epsilon, length/2, length/2, height2/2);
2013
2014 double gamma = atan((base2/2+epsilon)*2/height2);
2015 double r = sqrt((base2/2+epsilon)*(base2/2+epsilon) + height2*height2/4);
2016 GeoTrf::Transform3D xForm=GeoTrf::Translate3D(r*sin(sign*(gamma-rot)),0,height1/2-r*cos(gamma-rot))*GeoTrf::RotateY3D(sign*rot);
2017 const GeoShape & sShell = (*trd1).add((*trd2)<<xForm);
2018
2019 // We now have the shape we want. We only have left to transform
2020 // its position to where we want it.
2021 //
2022 // First, the actual positions of the four corners of
2023 // the constructed shape.
2024 GeoTrf::Vector2D actualCorner1, actualCorner2, actualCorner3, actualCorner4;
2025 actualCorner1 = corner1;
2026 actualCorner2 = corner1 + GeoTrf::Vector2D(0,base1);
2027 if (sign==1) {
2028 actualCorner4 = corner1 + GeoTrf::Vector2D(height1,base1/2);
2029 actualCorner3 = actualCorner4 + GeoTrf::Vector2D(-base2*sin(rot),base2*cos(rot));
2030 } else {
2031 actualCorner3 = corner1 + GeoTrf::Vector2D(height1,base1/2);
2032 actualCorner4 = actualCorner3 + GeoTrf::Vector2D(-base2*sin(rot),-base2*cos(rot));
2033 }
2034 // The center of our shape is at
2035 GeoTrf::Vector2D center= corner1 + GeoTrf::Vector2D(height1/2,base1/2);
2036
2037 // Let us turn the whole module
2038 double modRot = (-delta12).phi()-GeoTrf::Vector2D(0,1).phi();
2039
2040 // std::cout << "TK: modRot : "<< modRot/GeoModelKernelUnits::degree<<" degrees"<<std::endl;
2041 rotate(modRot,actualCorner1);
2042 rotate(modRot,actualCorner2);
2043 rotate(modRot,actualCorner3);
2044 rotate(modRot,actualCorner4);
2045 rotate(modRot,center);
2046
2047 // Finally, the shape is moved where it fits best with the original corner coordinates.
2048
2049 GeoTrf::Vector2D displacement = 0.25*( (corner1+corner2+corner3+corner4) - (actualCorner1+actualCorner2+actualCorner3+actualCorner4) );
2050 // .. << ::DEBUG << std::cout << "TK: makeModule : moving a total of (micrometer) " << displacement.mag()/GeoModelKernelUnits::micrometer<< std::endl;
2051 // std::cout << "TK: makeModule : moving due to 1 (micrometer) " << 0.25*(corner1-actualCorner1).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2052 // std::cout << "TK: makeModule : moving due to 2 (micrometer) " << 0.25*(corner2-actualCorner2).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2053 // std::cout << "TK: makeModule : moving due to 3 (micrometer) " << 0.25*(corner3-actualCorner3).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2054 // std::cout << "TK: makeModule : moving due to 4 (micrometer) " << 0.25*(corner4-actualCorner4).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2055 center += displacement;
2056 actualCorner1 += displacement;
2057 actualCorner2 += displacement;
2058 actualCorner3 += displacement;
2059 actualCorner4 += displacement;
2060
2061 // GeoTrf::Vector2D remainingOffset = -0.25*( (corner1+corner2+corner3+corner4) - (actualCorner1+actualCorner2+actualCorner3+actualCorner4) );
2062 // std::cout << "TK: makeModule : remaining total offset (should be zero) (micrometer) " << remainingOffset.mag()/GeoModelKernelUnits::micrometer<< std::endl;
2063 // std::cout << "TK: makeModule : 1 remaining offset (micrometer) " << (corner1-actualCorner1).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2064 // std::cout << "TK: makeModule : 2 remaining offset (micrometer) " << (corner2-actualCorner2).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2065 // std::cout << "TK: makeModule : 3 remaining offset (micrometer) " << (corner3-actualCorner3).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2066 // std::cout << "TK: makeModule : 4 remaining offset (micrometer) " << (corner4-actualCorner4).mag()/GeoModelKernelUnits::micrometer<< std::endl;
2067
2068 // The final positioning includes a few 90deg rotations because the axis's in the GeoTrd's are different from the actual axis's.
2069 modulePosition = GeoTrf::TranslateY3D(center.y())*GeoTrf::TranslateX3D(center.x())*GeoTrf::RotateZ3D(90.0*GeoModelKernelUnits::deg)*GeoTrf::RotateX3D(90.0*GeoModelKernelUnits::deg)*GeoTrf::RotateY3D(modRot);
2070
2071 return &sShell;
2072}
Scalar phi() const
phi method
double length(const pvec &v)
void rotate(double angler, GeoTrf::Vector2D &vector)
double magn(GeoTrf::Vector2D &vector)
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
int r
Definition globals.cxx:22

◆ makeStraw()

GeoPhysVol * TRTDetectorFactory_Full::makeStraw ( bool hasLargeDeadRegion = false,
ActiveGasMixture gasMixture = GM_XENON )
private

Definition at line 2080 of file TRTDetectorFactory_Full.cxx.

2080 {
2081
2082 double lengthOfInnerDeadRegion= hasLargeDeadRegion ? m_data->barrelLengthOfLargeDeadRegion : m_data->lengthOfDeadRegion ;
2083 double lengthOfActiveGas = (m_data->barrelLengthOfStraw-m_data->barrelLengthOfTwister)/2.0 - m_data->lengthOfDeadRegion - lengthOfInnerDeadRegion;
2084 double posA = (lengthOfActiveGas + m_data->barrelLengthOfTwister) / 2. + lengthOfInnerDeadRegion; // middle of lengthOfActiveGas
2085 double posInnerDeadRegion = ( m_data->barrelLengthOfTwister + lengthOfInnerDeadRegion ) / 2;
2086
2087 // Straws:
2088 GeoTube *sHole = new GeoTube(0,m_data->barrelOuterRadiusOfStrawHole, m_data->barrelLengthOfStraw/2.0);
2089 GeoLogVol *lHole = new GeoLogVol("Hole", sHole, m_materialManager->getMaterial("trt::CO2"));
2090 GeoPhysVol *pHole = new GeoPhysVol(lHole);
2091
2092 // Straws:
2093 GeoTube *sStraw = new GeoTube(0,m_data->outerRadiusOfStraw, m_data->barrelLengthOfStraw/2.0);
2094 GeoLogVol *lStrawMixed = new GeoLogVol("StrawM", sStraw, m_materialManager->getMaterial("trt::Straw"));
2095 GeoPhysVol *pStrawMixed = new GeoPhysVol(lStrawMixed);
2096
2097 // Dead regions:
2098 GeoShape *sDeadRegion = new GeoTube(m_data->outerRadiusOfWire , m_data->innerRadiusOfStraw , m_data->lengthOfDeadRegion/2 );
2099 GeoLogVol *lDeadRegion = nullptr;
2100 if (gasMixture == GM_ARGON)
2101 lDeadRegion = new GeoLogVol("DeadRegion_Ar", sDeadRegion, m_materialManager->getMaterial("trt::ArCO2O2"));
2102 else if (gasMixture == GM_KRYPTON)
2103 lDeadRegion = new GeoLogVol("DeadRegion_Kr", sDeadRegion, m_materialManager->getMaterial("trt::KrCO2O2"));
2104 else
2105 lDeadRegion = new GeoLogVol("DeadRegion", sDeadRegion, m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt:XeCO2CF4" : "trt::XeCO2O2")));
2106 GeoPhysVol *pDeadRegion = new GeoPhysVol(lDeadRegion);
2107
2108 // InnerDeadRegions, part II:
2109 GeoShape * sInnerDeadRegion = new GeoTube(m_data->outerRadiusOfWire , m_data->innerRadiusOfStraw, lengthOfInnerDeadRegion/2 );
2110 GeoLogVol * lInnerDeadRegion = nullptr;
2111 if (gasMixture == GM_ARGON)
2112 lInnerDeadRegion = new GeoLogVol("InnerDeadRegion_Ar", sInnerDeadRegion, m_materialManager->getMaterial("trt::ArCO2O2"));
2113 else if(gasMixture == GM_KRYPTON)
2114 lInnerDeadRegion = new GeoLogVol("InnerDeadRegion_Kr", sInnerDeadRegion, m_materialManager->getMaterial("trt::KrCO2O2"));
2115 else
2116 lInnerDeadRegion = new GeoLogVol("InnerDeadRegion", sInnerDeadRegion, m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt:XeCO2CF4" : "trt::XeCO2O2")));
2117 GeoPhysVol* pInnerDeadRegion = new GeoPhysVol(lInnerDeadRegion);
2118
2119 // Twisters:
2120 GeoShape *sTwister = new GeoTube(m_data->outerRadiusOfWire , m_data->innerRadiusOfStraw, m_data->barrelLengthOfTwister/2);
2121 GeoLogVol *lTwister = new GeoLogVol("Twister", sTwister, m_materialManager->getMaterial("trt::Twister"));
2122 GeoPhysVol *pTwister = new GeoPhysVol(lTwister);
2123
2124 // Wires:
2125 GeoShape *sWire = new GeoTube( 0,m_data->outerRadiusOfWire,m_data->barrelLengthOfStraw/2.0);
2126 GeoLogVol *lWire = new GeoLogVol("Wire", sWire, m_materialManager->getMaterial("trt::Wire"));
2127 GeoPhysVol *pWire = new GeoPhysVol(lWire);
2128
2129 // NB please see comments in TRT_BarrelElement::getAbsoluteTransform before re-organizing
2130 // the next few paragraphs!!.
2131
2132 // Gas for mixed straws, part I:
2133 GeoTube *sGasMA = new GeoTube(m_data->outerRadiusOfWire , m_data->innerRadiusOfStraw,lengthOfActiveGas/2.0);
2134 GeoLogVol * lGasMA = nullptr;
2135 if (gasMixture == GM_ARGON)
2136 lGasMA = new GeoLogVol("GasMA_Ar", sGasMA, m_materialManager->getMaterial("trt::ArCO2O2"));
2137 else if (gasMixture == GM_KRYPTON)
2138 lGasMA = new GeoLogVol("GasMA_Kr", sGasMA, m_materialManager->getMaterial("trt::KrCO2O2"));
2139 else
2140 lGasMA = new GeoLogVol("GasMA", sGasMA, m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt:XeCO2CF4" : "trt::XeCO2O2")));
2141 GeoNameTag *nGasMAPos = new GeoNameTag("GasMAPos");
2142 GeoTransform *xGasMAPos = new GeoTransform(GeoTrf::RotateY3D(M_PI)*GeoTrf::TranslateZ3D(-posA));//the rotation of pi is to... digitization (TK)
2143 GeoNameTag *nGasMANeg = new GeoNameTag("GasMANeg");
2144 GeoTransform *xGasMANeg = new GeoTransform(GeoTrf::TranslateZ3D(-posA));
2145 GeoPhysVol *pGasMA = new GeoPhysVol(lGasMA);
2146
2147 // Assemble gas within straws
2148 GeoSerialIdentifier *id = new GeoSerialIdentifier(0);
2149 pStrawMixed->add(id);
2150 pStrawMixed->add(nGasMANeg);
2151 pStrawMixed->add(xGasMANeg);
2152 pStrawMixed->add(pGasMA);
2153 pStrawMixed->add(nGasMAPos);
2154 pStrawMixed->add(xGasMAPos);
2155 pStrawMixed->add(pGasMA);
2156
2157 // Outer Dead region for mixed straws, part II:
2158 GeoSerialDenominator *nDeadMA = new GeoSerialDenominator("DeadRegionL");
2159 GeoTransform *xDeadPosMA = new GeoTransform(GeoTrf::TranslateZ3D(+(m_data->barrelLengthOfStraw-m_data->lengthOfDeadRegion)/2.0));
2160 GeoTransform *xDeadNegMA = new GeoTransform(GeoTrf::TranslateZ3D(-(m_data->barrelLengthOfStraw-m_data->lengthOfDeadRegion)/2.0));
2161
2162 // Assemble dead regions within straws:
2163 pStrawMixed->add(nDeadMA);
2164 pStrawMixed->add(xDeadPosMA);
2165 pStrawMixed->add(pDeadRegion);
2166 pStrawMixed->add(xDeadNegMA);
2167 pStrawMixed->add(pDeadRegion);
2168
2169 // InnerDeadRegions, part III:
2170 GeoSerialDenominator *nInnerDeadMA = new GeoSerialDenominator("InnerDeadRegionL");
2171 GeoTransform *xInnerDeadPosMA = new GeoTransform(GeoTrf::TranslateZ3D(+posInnerDeadRegion));
2172 GeoTransform *xInnerDeadNegMA = new GeoTransform(GeoTrf::TranslateZ3D(-posInnerDeadRegion));
2173 // add to mixedStraw:
2174 pStrawMixed->add(nInnerDeadMA);
2175 pStrawMixed->add(xInnerDeadPosMA);
2176 pStrawMixed->add(pInnerDeadRegion);
2177 pStrawMixed->add(xInnerDeadNegMA);
2178 pStrawMixed->add(pInnerDeadRegion);
2179
2180 // Assemble twisters within straws.
2181 GeoNameTag *nTwister = new GeoNameTag("TwisterM");
2182 pStrawMixed->add(nTwister);
2183 pStrawMixed->add(pTwister);
2184
2185 // Assemble wires within straws.
2186 GeoNameTag *nWire = new GeoNameTag("WireM");
2187 pStrawMixed->add(nWire);
2188 pStrawMixed->add(pWire);
2189
2190 pHole->add(pStrawMixed);
2191
2192 return pHole;
2193}
#define M_PI

◆ makeStrawPlane()

GeoFullPhysVol * TRTDetectorFactory_Full::makeStrawPlane ( size_t w,
ActiveGasMixture gasMixture = GM_XENON )
private

Definition at line 2201 of file TRTDetectorFactory_Full.cxx.

2201 {
2202 // -----------------------------------------------------------------------------------//
2203 // //
2204 // There are twelve straw planes; however there are only two kinds, one for sector //
2205 // A & B, and one for sector C. We call the first "type 1" and the second "type 2" //
2206 // In order to economize, we shall only create two planes. //
2207 // -----------------------------------------------------------------------------------//
2208
2209 size_t nstraws=0;
2210
2211 //A and B wheels have similar straw planes, but the C wheels are different.
2212 // const size_t firstIndexOfC = 15; //hardcoded
2213 const size_t firstIndexOfC = 14; //hardcoded
2214
2215 unsigned iplane = 0;
2216 if (gasMixture == GM_ARGON) {
2217 iplane = 1;
2218 }
2219 else if (gasMixture == GM_KRYPTON) {
2220 iplane = 2;
2221 }
2222
2223 if (w>=firstIndexOfC) {
2224 if (m_type2Planes[iplane] != nullptr) {
2225 return m_type2Planes[iplane];
2226 }
2227 nstraws=m_data->endcapNumberOfStrawsInStrawLayer_CWheels;
2228 }
2229 else {
2230 if (m_type1Planes[iplane] != nullptr) {
2231 return m_type1Planes[iplane];
2232 }
2233 nstraws=m_data->endcapNumberOfStrawsInStrawLayer_AWheels;
2234 //Check here that (m_data->endcapNumberOfStrawsInStrawLayer_AWheels == m_data->endcapNumberOfStrawsInStrawLayer_BWheels) !!
2235 }
2236
2237 double MultiplierForStrawLength = 0.999;//TK: update... to avoid conflicts? should be 0.9999??
2238
2239 double ldead = m_data->lengthOfDeadRegion;
2240 double r0 = m_data->outerRadiusOfWire;
2241 double r1 = m_data->innerRadiusOfStraw;
2242 double r2 = m_data->outerRadiusOfStraw;
2243
2244 double R0, R1;
2245 if (w >= firstIndexOfC) {
2246 //C wheels:
2247 R0 = m_data->endcapOuterRadiusOfInnerSupport_wheelC;
2248 R1 = m_data->endcapInnerRadiusOfOuterSupport_wheelC;
2249 } else {
2250 //A and B wheels:
2251 R0 = m_data->endcapOuterRadiusOfInnerSupport_wheelAB;
2252 R1 = m_data->endcapInnerRadiusOfOuterSupport_wheelAB;
2253 }
2254
2255 double Length = (R1-R0)*MultiplierForStrawLength;//TK update
2256 double pos = 0.5*(R0+R1);
2257
2258
2259 GeoFullPhysVol *pStrawPlane=nullptr;//TK update
2260 GeoTube *sStrawPlane = new GeoTube(R0,R1,r2);
2261 GeoLogVol *lStrawPlane = new GeoLogVol("StrawPlane", sStrawPlane, m_materialManager->getMaterial("trt::CO2"));
2262 pStrawPlane = new GeoFullPhysVol(lStrawPlane); //TK update
2263
2264
2265 GeoTube *sStraw = new GeoTube( 0, r2, Length/2.0);
2266 GeoLogVol *lStraw = new GeoLogVol("Straw",sStraw, m_materialManager->getMaterial("trt::Straw"));
2267 GeoPhysVol *pStraw = new GeoPhysVol(lStraw);
2268
2269 // Positioning of straws :
2270 double dphi = 2*M_PI/ nstraws;
2271 GeoTrf::RotateZ3D Rz(1.0);// Radians!
2272 GeoTrf::TranslateX3D Tx(1.0);// MM! TK: actually this doesnt need to be interpreted as mm? Just as a dimensionless 1. (i guess)
2273 GeoTrf::TranslateY3D Ty(1.0);// MM!
2274 Variable i;
2275 Sin sin;
2276 Cos cos;
2277 TRANSFUNCTION tx = Pow(Tx,pos*cos(dphi*i))*Pow(Ty,pos*sin(dphi*i))*Pow(Rz,dphi*i)*GeoTrf::RotateY3D(-90*GeoModelKernelUnits::deg);
2278 GeoSerialTransformer *serialTransformer=new GeoSerialTransformer(pStraw, &tx, nstraws);
2279 pStrawPlane->add(new GeoSerialIdentifier(0));
2280 pStrawPlane->add(serialTransformer);
2281
2282 // Give this parameterization also to the readout geometry:
2283 if (w<firstIndexOfC) {
2284 m_detectorManager->setEndcapTransformField(0,tx.clone());
2285 m_detectorManager->setEndcapTransformField(1,tx.clone());
2286 }
2287 else {
2288 m_detectorManager->setEndcapTransformField(2,tx.clone());
2289 }
2290
2291 // Gas :
2292 // (Function TRTConstructionOfTube::ConstructAndPosition #2)
2293 GeoTube *sGas = new GeoTube (r0,r1,(Length-2*ldead)/2);
2294 GeoLogVol *lGas = nullptr;
2295 if (gasMixture == GM_ARGON)
2296 lGas = new GeoLogVol("Gas_Ar", sGas, m_materialManager->getMaterial("trt::ArCO2O2"));
2297 else if (gasMixture == GM_KRYPTON)
2298 lGas = new GeoLogVol("Gas_Kr", sGas, m_materialManager->getMaterial("trt::KrCO2O2"));
2299 else
2300 lGas = new GeoLogVol("Gas", sGas, m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt::XeCO2CF4" : "trt::XeCO2O2")));
2301 GeoPhysVol *pGas = new GeoPhysVol(lGas);
2302 pStraw->add(pGas);
2303
2304 // Dead region :
2305 GeoTube *sDeadRegion = new GeoTube(r0,r1,ldead/2);
2306 GeoLogVol *lDeadRegion = nullptr;
2307 if (gasMixture == GM_ARGON)
2308 lDeadRegion = new GeoLogVol("DeadRegion_Ar",sDeadRegion,m_materialManager->getMaterial("trt::ArCO2O2"));
2309 else if (gasMixture == GM_KRYPTON)
2310 lDeadRegion = new GeoLogVol("DeadRegion_Kr",sDeadRegion,m_materialManager->getMaterial("trt::KrCO2O2"));
2311 else
2312 lDeadRegion = new GeoLogVol("DeadRegion",sDeadRegion,m_materialManager->getMaterial((m_useOldActiveGasMixture ? "trt::XeCO2CF4" : "trt::XeCO2O2")));
2313 GeoPhysVol *pDeadRegion = new GeoPhysVol(lDeadRegion);
2314
2315 GeoTransform *xDeadPos = new GeoTransform(GeoTrf::TranslateZ3D(+(Length/2-ldead/2)));
2316 GeoTransform *xDeadNeg = new GeoTransform(GeoTrf::TranslateZ3D(-(Length/2-ldead/2)));
2317 pStraw->add(xDeadPos);
2318 pStraw->add(pDeadRegion);
2319 pStraw->add(xDeadNeg);
2320 pStraw->add(pDeadRegion);
2321
2322
2323 // Wire :
2324 GeoTube *sWire = new GeoTube( 0, r0, Length/2);
2325 GeoLogVol *lWire = new GeoLogVol("Wire", sWire, m_materialManager->getMaterial("trt::Wire"));
2326 GeoPhysVol *pWire = new GeoPhysVol(lWire);
2327 pStraw->add(pWire);
2328
2329 if (w>=firstIndexOfC) {
2330 m_type2Planes[iplane] = pStrawPlane;
2331 }
2332 else {
2333 m_type1Planes[iplane] = pStrawPlane;
2334 }
2335 return pStrawPlane;
2336
2337}
const double r0
electron radius{cm}

◆ msg()

MsgStream & InDetDD::DetectorFactoryBase::msg ( MSG::Level lvl) const
inlineinherited

Definition at line 37 of file InDetDetectorFactoryBase.h.

37{ return m_athenaComps->msg(lvl); }

◆ msgLvl()

bool InDetDD::DetectorFactoryBase::msgLvl ( MSG::Level lvl)
inlineinherited

Definition at line 40 of file InDetDetectorFactoryBase.h.

40{ return m_athenaComps->msgLvl(lvl); }

◆ operator=()

const TRTDetectorFactory_Full & TRTDetectorFactory_Full::operator= ( const TRTDetectorFactory_Full & right)
delete

◆ rdbAccessSvc()

IRDBAccessSvc * InDetDD::DetectorFactoryBase::rdbAccessSvc ( )
inlineinherited

Definition at line 32 of file InDetDetectorFactoryBase.h.

32{return m_athenaComps->rdbAccessSvc();}

Member Data Documentation

◆ m_alignable

bool TRTDetectorFactory_Full::m_alignable
private

Definition at line 101 of file TRTDetectorFactory_Full.h.

◆ m_athenaComps

InDetDD::AthenaComps* InDetDD::DetectorFactoryBase::m_athenaComps
privateinherited

Definition at line 46 of file InDetDetectorFactoryBase.h.

◆ m_data

std::unique_ptr<TRTParameterInterface> TRTDetectorFactory_Full::m_data
private

Definition at line 95 of file TRTDetectorFactory_Full.h.

◆ m_DC2CompatibleBarrelCoordinates

bool TRTDetectorFactory_Full::m_DC2CompatibleBarrelCoordinates
private

Definition at line 100 of file TRTDetectorFactory_Full.h.

◆ m_detectorManager

InDetDD::TRT_DetectorManager* TRTDetectorFactory_Full::m_detectorManager = nullptr
private

Definition at line 93 of file TRTDetectorFactory_Full.h.

◆ m_doArgon

bool TRTDetectorFactory_Full::m_doArgon
private

Definition at line 103 of file TRTDetectorFactory_Full.h.

◆ m_doKrypton

bool TRTDetectorFactory_Full::m_doKrypton
private

Definition at line 104 of file TRTDetectorFactory_Full.h.

◆ m_materialManager

std::unique_ptr<InDetMaterialManager> TRTDetectorFactory_Full::m_materialManager
private

Definition at line 94 of file TRTDetectorFactory_Full.h.

◆ m_statusAccessor

std::unique_ptr<const TRTStrawStatusAccessor> TRTDetectorFactory_Full::m_statusAccessor
private

Definition at line 96 of file TRTDetectorFactory_Full.h.

◆ m_strawsvcavailable

bool TRTDetectorFactory_Full::m_strawsvcavailable
private

Definition at line 102 of file TRTDetectorFactory_Full.h.

◆ m_sumTool

const ITRT_StrawStatusSummaryTool* TRTDetectorFactory_Full::m_sumTool {nullptr}
private

Definition at line 97 of file TRTDetectorFactory_Full.h.

97{nullptr};

◆ m_type1Planes

GeoFullPhysVol* TRTDetectorFactory_Full::m_type1Planes[3] = {nullptr, nullptr, nullptr}
private

Definition at line 107 of file TRTDetectorFactory_Full.h.

107{nullptr, nullptr, nullptr};

◆ m_type2Planes

GeoFullPhysVol* TRTDetectorFactory_Full::m_type2Planes[3] = {nullptr, nullptr, nullptr}
private

Definition at line 108 of file TRTDetectorFactory_Full.h.

108{nullptr, nullptr, nullptr};

◆ m_useDynamicAlignFolders

bool TRTDetectorFactory_Full::m_useDynamicAlignFolders
private

Definition at line 105 of file TRTDetectorFactory_Full.h.

◆ m_useOldActiveGasMixture

bool TRTDetectorFactory_Full::m_useOldActiveGasMixture
private

Definition at line 99 of file TRTDetectorFactory_Full.h.


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