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

#include <HGTD_DetectorFactory.h>

Inheritance diagram for HGTD_DetectorFactory:
Collaboration diagram for HGTD_DetectorFactory:

Public Member Functions

 HGTD_DetectorFactory (HGTD_GeoModelAthenaComps *athenaComps)
virtual ~HGTD_DetectorFactory ()
virtual void create (GeoPhysVol *world) override
virtual const HGTD_DetectorManagergetDetectorManager () const override
void setPrintIdentifierDict (bool)
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 Member Functions

 HGTD_DetectorFactory (HGTD_DetectorFactory &right)
HGTD_DetectorFactoryoperator= (HGTD_DetectorFactory &right)
void initializeGeoParameters ()
GeoLogVol * buildEndcapLogicalVolume (bool isPositiveSide)
GeoVPhysVol * build (const GeoLogVol *logicalEnvelope, bool bPos)
InDetDD::HGTD_ModuleDesigncreateHgtdDesign (double thickness)
std::array< PositionsInQuadrant, 4 > prepareLayersFromQuadrants (unsigned int)
PositionsInQuadrant prepareQuadrantsFromRows (int layer, unsigned int maxRow)
std::string formModuleName (int layer, int quadrant, unsigned int maxrows, int row, int mod, const ModulePosition &module, double &myx, double &myy, double &myrot, int &phi, int &eta)
PositionsInQuadrant mirrorModulesInQuadrant (const PositionsInQuadrant &)
std::vector< ModulePositionprepareModulePositionsInRowThreeRing (int row, int back=0)
int reorderRows (PositionsInQuadrant *quadrant)
std::vector< ModulePositionprepareModulePositionsInRowTwoRing (int row, bool back=false)
void mirrorPositionsAroundYaxis (std::array< PositionsInQuadrant, 4 > &arr)

Private Attributes

HGTD_DetectorManagerm_detectorManager {}
HGTD_GeoModelAthenaCompsm_athComps {}
StoredMaterialManagerm_materialMgr {}
int m_geomVersion {}
bool m_outputIdfr {}
std::map< std::string, GeoCylVolParamsm_cylVolPars
std::map< std::string, GeoBoxVolParamsm_boxVolPars
HgtdGeoParams m_hgtdPars {}
std::unique_ptr< const InDetDD::SiCommonItemsm_commonItems {}
InDetDD::AthenaCompsm_athenaComps

Detailed Description

Definition at line 74 of file HGTD_DetectorFactory.h.

Constructor & Destructor Documentation

◆ HGTD_DetectorFactory() [1/2]

HGTD_DetectorFactory::HGTD_DetectorFactory ( HGTD_GeoModelAthenaComps * athenaComps)

Definition at line 59 of file HGTD_DetectorFactory.cxx.

59 :
60 InDetDD::DetectorFactoryBase( athComps ),
61 m_athComps( athComps ),
62 m_materialMgr( nullptr ),
63 m_geomVersion( -1 ),
64 m_outputIdfr( false ) {
65 // create the detector manager
66 m_detectorManager = new HGTD_DetectorManager( detStore() );
67
68 ATH_MSG_INFO( "HGTD geometry from hard-coded definition - No Information being taken from Geometry Tag!" );
69
70
71 // Create SiCommonItems. These are items that are shared by all elements
72 m_commonItems = std::make_unique<const InDetDD::SiCommonItems>(m_athComps->getIdHelper());
73
74 // temporarily hardcode the HGTD version to build until the geo db has been updated with tables for 3-ring layout
75 // m_geomVersion = 0; // two-ring layout
76 m_geomVersion = 1; // three-ring layout
77}
#define ATH_MSG_INFO(x)
HGTD_GeoModelAthenaComps * m_athComps
HGTD_DetectorManager * m_detectorManager
std::unique_ptr< const InDetDD::SiCommonItems > m_commonItems
StoredMaterialManager * m_materialMgr

◆ ~HGTD_DetectorFactory()

HGTD_DetectorFactory::~HGTD_DetectorFactory ( )
virtual

Definition at line 79 of file HGTD_DetectorFactory.cxx.

79 {
80 // NB the detector manager (m_detectorManager) is stored in the detector store by the Tool and so we don't delete it.
81}

◆ HGTD_DetectorFactory() [2/2]

HGTD_DetectorFactory::HGTD_DetectorFactory ( HGTD_DetectorFactory & right)
private

Member Function Documentation

◆ build()

GeoVPhysVol * HGTD_DetectorFactory::build ( const GeoLogVol * logicalEnvelope,
bool bPos )
private

Definition at line 297 of file HGTD_DetectorFactory.cxx.

297 {
298
299 ATH_MSG_INFO( "**************************************************");
300 ATH_MSG_INFO( " Building HGTD geometry , side = " << bPos << " ");
301 ATH_MSG_INFO( "**************************************************" );
302
303 GeoFullPhysVol* HGTDparent = new GeoFullPhysVol( logicalEnvelope );
304
305 // to be calculated from parameters in db using map
306 double motherHalfZ = ((GeoTube*) HGTDparent->getLogVol()->getShape())->getZHalfLength();
307 double modulePackageHalfZtot = 3.5/2 + 4./2; // including flex - can we not get this from the db numbers? /CO
308
309 double modulePackageHalfZ = 2*m_boxVolPars["HGTD::GlueSensor"].zHalf + m_boxVolPars["HGTDSiSensor0"].zHalf
310 + m_boxVolPars["HGTD::LGADInactive"].zHalf + m_boxVolPars["HGTD::ASIC"].zHalf
311 + m_boxVolPars["HGTD::Hybrid"].zHalf + m_boxVolPars["HGTD::ModuleSpace"].zHalf;
312
313 // add volumes by key name to ordered vector, outside in (from larger z to smaller)
314 std::vector<std::string> hgtdVolumes;
315 hgtdVolumes.push_back("HGTD::ModeratorOut"); // Out as in outside the vessel
316 hgtdVolumes.push_back("HGTD::BackCover");
317 hgtdVolumes.push_back("HGTD::ToleranceBack");
318 hgtdVolumes.push_back("HGTD::ModeratorIn"); // In as in inside the vessel
319
320 hgtdVolumes.push_back("HGTD::ModuleLayer3");
321 hgtdVolumes.push_back("HGTD::SupportPlate");
322 hgtdVolumes.push_back("HGTD::CoolingPlate");
323 hgtdVolumes.push_back("HGTD::SupportPlate");
324 hgtdVolumes.push_back("HGTD::ModuleLayer2");
325
326 hgtdVolumes.push_back("HGTD::ToleranceMid");
327
328 hgtdVolumes.push_back("HGTD::ModuleLayer1");
329 hgtdVolumes.push_back("HGTD::SupportPlate");
330 hgtdVolumes.push_back("HGTD::CoolingPlate");
331 hgtdVolumes.push_back("HGTD::SupportPlate");
332 hgtdVolumes.push_back("HGTD::ModuleLayer0");
333
334 hgtdVolumes.push_back("HGTD::ToleranceFront");
335 hgtdVolumes.push_back("HGTD::FrontCover");
336 // Important - these must come last since they will otherwise shift positions of the previous volumes!
337 hgtdVolumes.push_back("HGTD::InnerRCover1"); // don't reorder!
338 hgtdVolumes.push_back("HGTD::InnerRCover2"); // don't reorder!
339 hgtdVolumes.push_back("HGTD::InnerRCover3"); // don't reorder!
340 hgtdVolumes.push_back("HGTD::OuterRCover"); // don't reorder!
341 hgtdVolumes.push_back("HGTD::PeripheralCoolingLines"); // don't reorder!
342
343 // Now build up the solid, logical and physical volumes as appropriate (starting from the outermost volume)
344 // We first start with the volumes we'll reuse several times
345
347 // FLEX PACKAGE VOLUMES //
349
350 // Flex package volume modeled as 8 concentric flex sheets with progressively larger inner radius
351 // Order of sheets depend on whether package is for front or back of a cooling plate
352 // First calculate the inner radii for the flex sheets
353 GeoCylVolParams packagePars = m_cylVolPars["HGTD::FlexPackage"];
354 GeoCylVolParams flexPars = m_cylVolPars["HGTD::FlexTube"];
355 std::vector<double> flexSheetInnerR;
356 double currentInnerR = 144.; // adding flex sheets from the second sensor (all have the hybrid already)
357 for (int flexSheet = 0; flexSheet < 8; flexSheet++) {
358 flexSheetInnerR.push_back(currentInnerR);
359 // set the inner radius for the next flex sheet, increased by two module heights and two radius-dependent spaces per sheet
360 currentInnerR += m_boxVolPars["HGTDModule0"].xHalf*2 * (2 + 2 * (flexSheet < 4 ? 0.2 : 0.8) );
361 }
362
363 // build up the two flex volumes for front (0) and back (1) sides
364 GeoPhysVol* flexPackagePhysical[2] = {};
365 for (int flexVolume = 0; flexVolume < 2; flexVolume++) {
366 std::vector<double> rInner = flexSheetInnerR;
367 if (flexVolume) reverse(rInner.begin(), rInner.end()); // reverse order for backside flex package
368
369 GeoTube* flexPackageSolid = new GeoTube(packagePars.rMin, packagePars.rMax, packagePars.zHalf);
370 GeoLogVol* flexPackageLogical = new GeoLogVol(packagePars.name, flexPackageSolid, m_materialMgr->getMaterial(packagePars.material));
371 flexPackagePhysical[flexVolume] = new GeoPhysVol(flexPackageLogical);
372 // build up a volume of flex cables, starting in z at half a flex layer from the edge of the flex package volume
373 double flexZoffset = packagePars.zHalf - flexPars.zHalf;
374 for (int flexSheet = 0; flexSheet < 8; flexSheet++) {
375 GeoTube* hgtdFlexSolid = new GeoTube(rInner[flexSheet], flexPars.rMax, flexPars.zHalf);
376 GeoLogVol* hgtdFlexLogical = new GeoLogVol("HGTD::FlexTube"+std::to_string(flexSheet),
377 hgtdFlexSolid, m_materialMgr->getMaterial(flexPars.material));
378 GeoPhysVol* hgtdFlexPhysical = new GeoPhysVol(hgtdFlexLogical);
379 flexPackagePhysical[flexVolume]->add(new GeoTransform(GeoTrf::TranslateZ3D(flexZoffset)));
380 flexPackagePhysical[flexVolume]->add(hgtdFlexPhysical);
381 // print out a line for each flex layer
382 ATH_MSG_DEBUG( "Flex layer (" << (flexSheet ? "front" : "back") << ")" << flexSheet << ", Rmin = " << std::setw(5)
383 << rInner[flexSheet] << " mm, flexZoffset = " << flexZoffset << " mm" );
384 flexZoffset = flexZoffset - m_hgtdPars.flexSheetSpacing;
385 }
386 }
387
389 // COOLING TUBES //
391
392 // make list of radii of cooling tubes
393 std::vector<double> coolingTubeRadii;
394 double coolingTubeRadius = 130.;
395 coolingTubeRadii.push_back(coolingTubeRadius);
396
397 // two-ring layout
398 if (m_geomVersion == 0) {
399 ATH_MSG_INFO("Will now calculate cooling-loop positions for the two-ring layout");
400 for (int i = 0; i < 18; i++) {
401 coolingTubeRadius += (418-130.)/18;
402 coolingTubeRadii.push_back(coolingTubeRadius);
403 }
404 for (int i = 0; i < 12; i++) {
405 coolingTubeRadius += (658-418.)/14;
406 coolingTubeRadii.push_back(coolingTubeRadius);
407 }
408 coolingTubeRadius = 710.;
409 coolingTubeRadii.push_back(coolingTubeRadius);
410 for (int i = 0; i < 7; i++) {
411 coolingTubeRadius += (890-710.)/6;
412 coolingTubeRadii.push_back(coolingTubeRadius);
413 }
414 }
415 else if (m_geomVersion == 1) {
416 ATH_MSG_INFO("Will now calculate cooling-loop positions for the three-ring layout");
417 // inner part, even spacing from 130 mm to 674 mm, 35 rings with 16 mm spacing (first one already placed above)
418 int numberOfLoops = 34;
419 float loopDistance = (674.-130.)/numberOfLoops; // in mm
420 for (int i = 0; i < numberOfLoops; i++) {
421 coolingTubeRadius += loopDistance;
422 coolingTubeRadii.push_back(coolingTubeRadius);
423 }
424 // outer part, even spacing from 720 mm to 900 mm, 7 rings with 30 mm spacing
425 coolingTubeRadius = 720;
426 coolingTubeRadii.push_back(coolingTubeRadius);
427 numberOfLoops = 6;
428 loopDistance = (900.-720.)/numberOfLoops;
429 for (int i = 0; i < numberOfLoops; i++) {
430 coolingTubeRadius += loopDistance;
431 coolingTubeRadii.push_back(coolingTubeRadius);
432 }
433 }
434 ATH_MSG_DEBUG( "Cooling tubes will be created at the following radii (" << coolingTubeRadii.size() << " in total):");
435 for (size_t i = 0; i < coolingTubeRadii.size(); i++) {
436 ATH_MSG_DEBUG( " R = " << coolingTubeRadii[i] << " mm" );
437 }
438
440 // PERIPHERAL ELECTRONICS VOLUME //
442
443 //build peripheral electronics
444 GeoCylVolParams periphElPars = m_cylVolPars["HGTD::PeriphElec"];
445 GeoTube* periphElec_solid = new GeoTube(periphElPars.rMin, periphElPars.rMax, periphElPars.zHalf);
446 GeoLogVol* periphElec_log = new GeoLogVol(periphElPars.name, periphElec_solid, m_materialMgr->getMaterial(periphElPars.material));
447 GeoPhysVol* periphElec_phys = new GeoPhysVol(periphElec_log);
448
449 std::array< GeoPhysVol*, 4 > moduleLayerPhysical = {}; // array of pointers to the physical volumes for the module layers which need special care
450
452 // BUILD UP ALL MAIN VOLUMES IN SEQUENCE //
454
455 // now build up the volumes in the order specified in the vector
456 double zModuleLayerF = 0.;
457 double zModuleLayerB = 0.;
458 for (size_t vol = 0; vol < hgtdVolumes.size(); vol++) {
459
460 std::string v = hgtdVolumes[vol];
461
462 // calculate local z offsets for each main volume sequentially
463 if (vol == 0) // special treatment for the first one
464 m_cylVolPars[v].zOffsetLocal = motherHalfZ - m_cylVolPars[v].zHalf;
465
466 // All but the InnerRCover, OuterRCover and peripheral cooling lines are placed relative to other components,
467 // but the zOffsetLocal parameter of these volumes is left as read from the db
468 else {
469 if (v.substr(9,8) != "erRCover" && v != "HGTD::PeripheralCoolingLines") {
470 std::string vPrev = hgtdVolumes[vol-1];
471 m_cylVolPars[v].zOffsetLocal = m_cylVolPars[vPrev].zOffsetLocal - m_cylVolPars[vPrev].zHalf - m_cylVolPars[v].zHalf;
472 }
473 }
474
475 // skip the tolerances - we don't actually want to create volumes for the space
476 if (v.substr(0,15) == "HGTD::Tolerance") continue;
477
478 float safety = 0.;
479 if (v.substr(0,17) == "HGTD::ModuleLayer")
480 safety = 10.;
481
482 // a disk volume to hold 4 quadrants
483 GeoTube* hgtdSubVolumeSolid = new GeoTube(m_cylVolPars[v].rMin, m_cylVolPars[v].rMax+safety, m_cylVolPars[v].zHalf);
484 GeoLogVol* hgtdSubVolumeLogical = new GeoLogVol(m_cylVolPars[v].name, hgtdSubVolumeSolid, m_materialMgr->getMaterial(m_cylVolPars[v].material));
485 GeoPhysVol* hgtdSubVolumePhysical = new GeoPhysVol(hgtdSubVolumeLogical);
486
487 // if building the cooling plate, also add peripheral electronics since position of those are relative to that of cooling plate
488 if (v == "HGTD::CoolingPlate") {
489 double zOffsetPeriphElec = m_cylVolPars[v].zHalf + periphElPars.zOffsetLocal + periphElPars.zHalf;
490 // place two, one on each side of cooling plate
491 static constexpr std::array<int,2> signArr{1,-1};
492 for (int side = 0; side < 2; side++) {
493 //0, 1 index -> 1, -1 sign
494 HGTDparent->add(new GeoTransform(GeoTrf::TranslateZ3D(m_cylVolPars[v].zOffsetLocal + signArr[side]*zOffsetPeriphElec)));
495 HGTDparent->add(periphElec_phys);
496 }
497
498 // and the CO2 cooling tubes inside the cooling plate
499 for (size_t i = 0; i < coolingTubeRadii.size(); i++) {
500 // the tube itself
501 GeoTorus* coolingTubeSolid = new GeoTorus(m_cylVolPars["HGTD::CoolingTubeFluid"].zHalf, m_cylVolPars["HGTD::CoolingTube"].zHalf,
502 coolingTubeRadii[i], 0, 2*M_PI);
503 GeoLogVol* coolingTubeLogical = new GeoLogVol("HGTD::CoolingTube", coolingTubeSolid,
504 m_materialMgr->getMaterial(m_cylVolPars["HGTD::CoolingTube"].material));
505 GeoPhysVol* coolingTubePhysical = new GeoPhysVol(coolingTubeLogical);
506 hgtdSubVolumePhysical->add(coolingTubePhysical); // no transformations needed, concentric with cooling plate and centered in z
507 // and the contents, i.e. the cooling fluid
508 GeoTorus* coolingFluidSolid = new GeoTorus(0, m_cylVolPars["HGTD::CoolingTubeFluid"].zHalf,
509 coolingTubeRadii[i], 0, 2*M_PI);
510 GeoLogVol* coolingFluidLogical = new GeoLogVol("HGTD::CoolingFluid", coolingFluidSolid,
511 m_materialMgr->getMaterial(m_cylVolPars["HGTD::CoolingTubeFluid"].material));
512 GeoPhysVol* coolingFluidPhysical = new GeoPhysVol(coolingFluidLogical);
513 hgtdSubVolumePhysical->add(coolingFluidPhysical); // no transformations needed, concentric with cooling plate and centered in z
514 }
515 }
516
517 // module layer
518 if (v.substr(0,17) == "HGTD::ModuleLayer") {
519
520 int layer = atoi(v.substr(17,1).c_str());
521
522 // front and back side layers are treated differently: z position of flex and module layers, and rotation
523 double zFlex = 0.;
524 bool Lside = layer % 2;
525 if (Lside == 0) { // layers 0 and 2
526 zFlex = -modulePackageHalfZtot + m_cylVolPars["HGTD::FlexPackage"].zHalf;
527 zModuleLayerF = modulePackageHalfZtot - modulePackageHalfZ;
528 }
529 else { // layers 1 and 3
530 zFlex = modulePackageHalfZtot - m_cylVolPars["HGTD::FlexPackage"].zHalf;
531 zModuleLayerB = -modulePackageHalfZtot + modulePackageHalfZ;
532 }
533
534 // place flex within module packages, at different positions depending on front or back or cooling plate
535 hgtdSubVolumePhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zFlex)));
536 hgtdSubVolumePhysical->add(flexPackagePhysical[(Lside ? 0 : 1)]);
537
538 float diskRotation = layer <= 1 ? m_hgtdPars.disk1Rotation : m_hgtdPars.disk2Rotation;
539
540 HGTDparent->add(new GeoTransform( GeoTrf::TranslateZ3D(m_cylVolPars[v].zOffsetLocal) *
541 GeoTrf::RotateZ3D(diskRotation*Gaudi::Units::deg)) );
542 // one needs to check this rotation against the "quadrot" will be used in the following
543
544 HGTDparent->add( hgtdSubVolumePhysical );
545 moduleLayerPhysical[layer] = hgtdSubVolumePhysical;
546
547 } // end of module package
548 else {
549 HGTDparent->add(new GeoTransform(GeoTrf::TranslateZ3D(m_cylVolPars[v].zOffsetLocal)));
550 HGTDparent->add(hgtdSubVolumePhysical);
551 }
552
553 // print out info about each main volume
554 ATH_MSG_INFO( std::setw(20) << m_cylVolPars[v].name << " ( " << std::setw(20) << m_cylVolPars[v].material
555 << " ), local z = " << std::setw(6) << m_cylVolPars[v].zOffsetLocal
556 << " mm, Rmin = " << std::setw(4) << m_cylVolPars[v].rMin
557 << " mm, Rmax = " << std::setw(4) << m_cylVolPars[v].rMax
558 << " mm, DZ = " << std::setw(5) << m_cylVolPars[v].zHalf << " mm" );
559
560 } // end loop over hgtdVolumes
561
563 // MODULE VOLUMES //
565
566 // components for the module
567 std::vector<std::string> moduleVolumes;
568 moduleVolumes.push_back("HGTD::GlueAsic");
569 moduleVolumes.push_back("HGTD::ASIC");
570 moduleVolumes.push_back("HGTD::LGADInactive");
571 moduleVolumes.push_back("SensorPlaceHolder"); // replaced below to get the numbered name right
572 moduleVolumes.push_back("HGTD::GlueSensor");
573 moduleVolumes.push_back("HGTD::Hybrid");
574 moduleVolumes.push_back("HGTD::ModuleSpace");
575
576 int endcap = bPos ? +2 : -2;
577 double thickness = 2.*m_boxVolPars["HGTDSiSensor0"].zHalf;
578 InDetDD::HGTD_ModuleDesign* moduleDesign = createHgtdDesign( thickness );
579
580 // create the module --> each for cell and with different names
581 // calculate the positions where modules should be placed in one quadrant
582
583 int totMod = 0;
584 // this should be taken from DB or XML
585 unsigned int maxRows = 21;
586 if ( m_geomVersion == 0 ) maxRows = 18;
587
588 std::array< PositionsInQuadrant, 4 > positions = prepareLayersFromQuadrants( maxRows ) ;
589 // inside m_geomVersion implicitly control 3-ring layout vs 2-ring
590
592
593 for (int layer = 0; layer < 4; layer++) {
594 if (m_outputIdfr) cout << "Layer #" << layer << std::endl;
595 // select from front vs back side of a disk
596 int Lside = layer % 2;
597
598 std::vector<std::string> volumes = moduleVolumes;
599 if ( Lside != 0 ) reverse( volumes.begin(), volumes.end() ); // reverse order of components for backside modules
600
601 std::string sensorName = std::string("HGTDSiSensor") + std::to_string(layer);
602 std::string moduleName = std::string("HGTDModule") + std::to_string(layer);
603
604 // here we assumed all 4 layers share the same dimensions.
605 // As described at HGTD_DetectorFactory::reorderRows,
606 // the short edge of 4*2 cm module in the leading row is defined as local X/Width
607 // in ReadoutGeometry, this short edge is also defined as Eta, since the row is roughly along radius.
608 double moduleHalfWidth = m_boxVolPars[moduleName].xHalf; // 11m than 10 to hold wire bond
609 double moduleHalfHeight = m_boxVolPars[moduleName].yHalf;
610
611 // loop over quadrants in the current layer
612 // take a prepared quadrant as protype
613 PositionsInQuadrant tmpQuadrant = positions[ layer ];
614 // The relative rotation between two disks is supposed to be defined/accounted within tmpQuadrant
615 for (int q = 0; q < 4; q++) {
616 float quadrot = q*90.;
617
618 for ( unsigned int row = 0; row < maxRows; row ++ ) {
619 std::vector< ModulePosition > ModsPerRow = tmpQuadrant[ row ];
620
621 // print #modules per row to fill HGTD_Identifier dictionary etc.
622 if ( m_outputIdfr && q == 0 ) std::cout << " Row #"<< row + 1 <<" :: " << ModsPerRow.size() << std::endl;
623
624 for ( unsigned int mod = 0; mod < ModsPerRow.size(); mod ++ ) {
625 ModulePosition module = ModsPerRow[ mod ];
626
627 double myx = -9999999.9 , myy = -9999999.9 , myrot = -9999999.9;
628 int myphi = -1 , myeta = - 1;
629 std::string module_string = formModuleName( layer, q, maxRows, row, mod, module, myx, myy, myrot, myphi, myeta );
630
631 if ( module_string == "" || myrot == -9999999.9 || myeta == -1 )
632 ATH_MSG_WARNING ( " Please check the module at layer "<< layer <<" quadrant " << q <<" row "<< row <<" mod " << mod <<" not well retrieved ! " );
633
634 // an hgtd module defined in the form of ( X, Y, Z )
635 GeoBox* moduleSolid = new GeoBox( moduleHalfWidth, moduleHalfHeight, modulePackageHalfZ);
636 GeoLogVol* moduleLogical = new GeoLogVol( moduleName + module_string, moduleSolid, m_materialMgr->getMaterial("std::Air"));
637 GeoFullPhysVol* modulePhysical = new GeoFullPhysVol( moduleLogical );
638
639 // print out one module per layer
640 if ( q == 0 && row == 0 && mod == 0 )
641 ATH_MSG_DEBUG( "Will now build up an individual HGTD module of layer " << layer << " and quadrant " << q << " (" << module_string << ")" );
642
643 // loop over components in module
644 for (size_t comp = 0; comp < volumes.size(); comp++) {
645 if (volumes[comp] == "SensorPlaceHolder") volumes[comp] = sensorName; // replace placeholder
646
647 std::string c = volumes[comp];
648 // calculate local z offsets for each sensor component sequentially
649 if (comp == 0) // special treatment for the first one
650 m_boxVolPars[c].zOffsetLocal = modulePackageHalfZ - m_boxVolPars[c].zHalf;
651 else {
652 std::string cPrev = volumes[comp-1];
653 m_boxVolPars[c].zOffsetLocal = m_boxVolPars[cPrev].zOffsetLocal - m_boxVolPars[cPrev].zHalf - m_boxVolPars[c].zHalf;
654 }
655
656 // skip the module space - we don't actually want to create volumes for the space
657 if (volumes[comp] == "HGTD::ModuleSpace") continue;
658
659 double comp_halfx = m_boxVolPars[c].xHalf;
660 double comp_halfy = m_boxVolPars[c].yHalf;
661
662 // and x offsets for those components that are smaller, to make room for wire bond of flex to ASIC which is larger than the sensor
663 double xOffsetLocal = moduleHalfWidth - comp_halfx;
664 // need tuning then dataBase : to make room for wire bond of flex to ASIC which is larger than the sensor
665
666 GeoBox* sensorCompSolidVol = new GeoBox(comp_halfx, comp_halfy, m_boxVolPars[c].zHalf);
667 // No attachment?
668 std::string attach = (volumes[comp] == sensorName) ? "" : "_L" + std::to_string( layer ) + module_string;
669
670 GeoLogVol* sensorCompLogicalVol = new GeoLogVol( m_boxVolPars[c].name+attach, sensorCompSolidVol,
671 m_materialMgr->getMaterial(m_boxVolPars[c].material));
672 GeoFullPhysVol* sensorCompPhysicalVol = new GeoFullPhysVol(sensorCompLogicalVol);
673
674 if (volumes[comp] == sensorName) {
675 const HGTD_ID* hgtdId = dynamic_cast<const HGTD_ID*>( m_athComps->getIdHelper() );
676 Identifier idwafer = hgtdId->wafer_id( endcap, layer, myphi, myeta );
677
678 // print only the first and last module of each row in the first quadrant
679 if ( q == 0 && ( mod == 0 || mod == ( ModsPerRow.size() - 1 ) ) && !m_outputIdfr ) {
680 ATH_MSG_DEBUG( " waferHash : " << hgtdId->wafer_hash( idwafer )
681 << " upon HGTD_ID => ec: " << endcap << ", layer: " << layer << ", quadrant: " << q
682 << ", row: " << myphi <<", module: "<< myeta );
683 ATH_MSG_DEBUG( " HGTD Module: " << m_boxVolPars[c].name+module_string << ", posX: " << myx << ", posY: " << myy << ", rot: " << quadrot + myrot );
684 }
685
686 InDetDD::HGTD_DetectorElement* detElement = new InDetDD::HGTD_DetectorElement(idwafer, moduleDesign, sensorCompPhysicalVol, m_commonItems.get());
687 m_detectorManager->addDetectorElement( detElement );
688
689 GeoTrf::Transform3D sensorTransform = GeoTrf::TranslateZ3D(m_boxVolPars[c].zOffsetLocal)*GeoTrf::TranslateX3D(xOffsetLocal);
690 GeoAlignableTransform* xform = new GeoAlignableTransform(sensorTransform);
691
692 modulePhysical->add( xform );
693 modulePhysical->add( sensorCompPhysicalVol );
694
695 totMod ++;
696 }
697 else {
698 modulePhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(m_boxVolPars[c].zOffsetLocal)*GeoTrf::TranslateX3D(xOffsetLocal)));
699 modulePhysical->add(sensorCompPhysicalVol);
700 }
701
702 // print out each module component
703 if ( mod == 0 && q == 0 && volumes[comp] != sensorName )
704 ATH_MSG_DEBUG( std::setw(20) << m_boxVolPars[c].name << " ( " << std::setw(15) << m_boxVolPars[c].material
705 << " ), in-sensor-layer local z = " << std::setw(7) << m_boxVolPars[c].zOffsetLocal << " mm"
706 << ", DX = " << std::setw(5) << m_boxVolPars[c].xHalf << " mm"
707 << ", DY = " << std::setw(5) << m_boxVolPars[c].yHalf << " mm"
708 << ", DZ = " << std::setw(5) << m_boxVolPars[c].zHalf << " mm" );
709 } // end of components loop
710
711 double zModule = ( Lside == 0 ? zModuleLayerF : zModuleLayerB );
712
713 GeoTransform* moduleTransform = new GeoTransform( GeoTrf::TranslateZ3D(zModule) *
714 GeoTrf::TranslateX3D(myx) *
715 GeoTrf::TranslateY3D(myy) *
716 GeoTrf::RotateZ3D( ( quadrot + myrot )*Gaudi::Units::deg) );
717 moduleLayerPhysical[layer]->add( moduleTransform );
718 moduleLayerPhysical[layer]->add( modulePhysical );
719 } //end of modules loop
720 ATH_MSG_DEBUG( "Done placing modules for row " << row );
721 } // end of row loop
722 ATH_MSG_DEBUG( "Done placing modules for quadrant " << q );
723 } // end of quadrants loop
724 ATH_MSG_DEBUG( "Done placing modules for layer " << layer );
725 }
726
727 ATH_MSG_INFO( "**************************************************" );
728 ATH_MSG_INFO( " Done building HGTD with " << totMod <<" modules " );
729 ATH_MSG_INFO( "**************************************************" );
730
731 return HGTDparent;
732}
#define M_PI
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static std::string to_string(const std::vector< T > &v)
std::array< std::vector< ModulePosition >, 21 > PositionsInQuadrant
InDetDD::HGTD_ModuleDesign * createHgtdDesign(double thickness)
std::map< std::string, GeoBoxVolParams > m_boxVolPars
std::string formModuleName(int layer, int quadrant, unsigned int maxrows, int row, int mod, const ModulePosition &module, double &myx, double &myy, double &myrot, int &phi, int &eta)
std::map< std::string, GeoCylVolParams > m_cylVolPars
void mirrorPositionsAroundYaxis(std::array< PositionsInQuadrant, 4 > &arr)
std::array< PositionsInQuadrant, 4 > prepareLayersFromQuadrants(unsigned int)
Identifier wafer_id(int endcap, int layer, int phi_module, int eta_module) const
For a single crystal.
Definition HGTD_ID.h:287
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition HGTD_ID.h:404
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
row
Appending html table to final .html summary file.
@ layer
Definition HitInfo.h:79
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.

◆ buildEndcapLogicalVolume()

GeoLogVol * HGTD_DetectorFactory::buildEndcapLogicalVolume ( bool isPositiveSide)
private

Definition at line 282 of file HGTD_DetectorFactory.cxx.

282 {
283
284 // build the solid volume
285 GeoTube* world_solid_hgtd = new GeoTube(m_cylVolPars["HGTD_mother"].rMin, m_cylVolPars["HGTD_mother"].rMax,
286 m_cylVolPars["HGTD_mother"].zHalf);
287
288 // build the logical volume
289 std::string name = isPositiveSide ? "HGTD_PositiveEndcap" : "HGTD_NegativeEndcap";
290 GeoLogVol* world_logical_hgtd = new GeoLogVol( name.c_str(), world_solid_hgtd,
291 m_materialMgr->getMaterial( m_cylVolPars[ "HGTD_mother"].material) );
292
293 return world_logical_hgtd;
294}

◆ create()

void HGTD_DetectorFactory::create ( GeoPhysVol * world)
overridevirtual

Definition at line 88 of file HGTD_DetectorFactory.cxx.

88 {
89
90 ATH_MSG_INFO( "Building HGTD detector");
91
92 // initialize the geometry parameters
93 // Originally taken from geometry db, but now fully hard-coded until move to GMX implementation
95
96 // for now the position of the HGTD mother volumes is hardcoded - TODO: take from db!
97 constexpr float zMother = 3482.5;
98
99 // build logical volumes for the two endcaps
100 const GeoLogVol* positiveEndcapLogicalVolume = buildEndcapLogicalVolume(true);
101 const GeoLogVol* negativeEndcapLogicalVolume = buildEndcapLogicalVolume(false);
102
103 // create and place positive endcap
104 world->add(new GeoNameTag("HGTD_Pos"));
105 world->add(new GeoIdentifierTag(9));
106 ATH_MSG_INFO( "HGTD_Pos mother volume will be placed at z = " << zMother << " mm" );
107 world->add(new GeoTransform(GeoTrf::TranslateZ3D(zMother)));
108 GeoVPhysVol* endcapPos = build( positiveEndcapLogicalVolume, true);
109 world->add( endcapPos );
110 m_detectorManager->addTreeTop( endcapPos);
111
112 // create and place negative endcap
113 world->add(new GeoNameTag("HGTD_Neg"));
114 world->add(new GeoIdentifierTag(-9));
115 ATH_MSG_INFO( "HGTD_Neg mother volume will be placed at z = " << -zMother << " mm" );
116 world->add(new GeoTransform(GeoTrf::TranslateZ3D(-zMother)));
117 world->add(new GeoTransform(GeoTrf::RotateY3D(180.0*Gaudi::Units::deg)));
118 GeoVPhysVol* endcapNeg = build( negativeEndcapLogicalVolume, false);
119 world->add( endcapNeg );
120 m_detectorManager->addTreeTop( endcapNeg );
121
122 // Add SiCommonItems to HGTD_DetectorManager to hold and delete it.
123 m_detectorManager->setCommonItems(std::move(m_commonItems));
124
125 return;
126}
GeoLogVol * buildEndcapLogicalVolume(bool isPositiveSide)
GeoVPhysVol * build(const GeoLogVol *logicalEnvelope, bool bPos)

◆ createHgtdDesign()

InDetDD::HGTD_ModuleDesign * HGTD_DetectorFactory::createHgtdDesign ( double thickness)
private

Definition at line 1035 of file HGTD_DetectorFactory.cxx.

1035 {
1036
1037 double phiPitch = 1.3; // mm
1038 double etaPitch = 1.3; // mm
1039
1040 // for each module there are two ASICs connected, need further confirmation for below specifications
1041 // the "collumns" along module short edge align to a direction just following the EndOfCollumn(EoC) of each ASIC.
1042 int circuitsPerColumn = 1;
1043 int circuitsPerRow = 2; // along the long edge of module, tentatively following IBL descriptin
1044
1045 // each ASIC just cover half ( 15*15 pixels ) of a module
1046 int cellColumnsPerCircuit = 15;
1047 int cellRowsPerCircuit = 15; // along module FULL length there are 2*15 rows
1048
1049 int diodeColumnsPerCircuit = cellColumnsPerCircuit;
1050 int diodeRowsPerCircuit = cellRowsPerCircuit;
1051
1052 std::shared_ptr<const PixelDiodeMatrix> normalCell = InDetDD::PixelDiodeMatrix::construct(phiPitch, etaPitch);
1053 std::shared_ptr<const PixelDiodeMatrix> singleRow = InDetDD::PixelDiodeMatrix::construct(InDetDD::PixelDiodeMatrix::phiDir, 0,
1054 std::move(normalCell), diodeColumnsPerCircuit, 0);
1055 std::shared_ptr<const PixelDiodeMatrix> fullMatrix = InDetDD::PixelDiodeMatrix::construct(InDetDD::PixelDiodeMatrix::etaDir, 0,
1056 std::move(singleRow), 2*diodeRowsPerCircuit, 0); // note 30 = 2*15 rows adopted
1057
1059
1060 InDetDD::HGTD_ModuleDesign* design = new InDetDD::HGTD_ModuleDesign(thickness,
1061 circuitsPerColumn, circuitsPerRow,
1062 cellColumnsPerCircuit, cellRowsPerCircuit,
1063 diodeColumnsPerCircuit, diodeRowsPerCircuit,
1064 std::move(fullMatrix),
1065 InDetDD::CarrierType::electrons, 1, yDirection );
1066
1067 return design;
1068}
static std::shared_ptr< const PixelDiodeMatrix > construct(double phiWidth, double etaWidth)
Construct method for just a single cell.

◆ 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();}

◆ formModuleName()

std::string HGTD_DetectorFactory::formModuleName ( int layer,
int quadrant,
unsigned int maxrows,
int row,
int mod,
const ModulePosition & module,
double & myx,
double & myy,
double & myrot,
int & phi,
int & eta )
private

Definition at line 768 of file HGTD_DetectorFactory.cxx.

770 {
771
772 std::string module_string = "";
773
774 double x = module.x;
775 double y = module.y;
776 double myphi = atan(y/x);
777 double radius = std::sqrt(x*x+y*y);
778
779 myx = radius*cos( quadrant*M_PI*0.5 + myphi );
780 myy = radius*sin( quadrant*M_PI*0.5 + myphi );
781
782 // three-ring layout
783 if ( m_geomVersion == 1 ) {
784 myrot = module.phiRotation;
785 phi = quadrant*21 + row + 1; // quadrant is absent ( hidden into row ) in HGTD-Identifier
786 eta = mod + 1;
787 //module_string = "_R" + std::to_string(phi) + "_M" + std::to_string(eta); //This was the previous string, but doesn't match expectations of HGTDSensorSD
788 module_string = "_layer_" + std::to_string(layer) + "_" + std::to_string(phi) + "_" + std::to_string(eta);
789 }
790 // two-ring layout
791 else {
792 double rot = module.flipped ? 90. : 0.;
793 int myrow = module.row;
794 double moduleRotation = 0;
795 if ( layer > 1 ) {
796 myx = -myx;
797 // need to rotate 180 degrees some modules in q0 and q2
798 if ( quadrant%2 == 0 && myrow <= 15) moduleRotation = 180.;
799 else if (quadrant%2 == 1 && myrow > 15) moduleRotation = 180.;
800 }
801 eta = ( quadrant*maxrows ) + myrow;
802 phi = module.el_in_row;
803 myrot = moduleRotation + rot;
804 module_string = "_layer_" + std::to_string(layer) + "_" + std::to_string(phi) + "_" + std::to_string(eta);
805 }
806
807 return module_string;
808}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define y
#define x

◆ 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 HGTD_DetectorManager * HGTD_DetectorFactory::getDetectorManager ( ) const
overridevirtual

Definition at line 1070 of file HGTD_DetectorFactory.cxx.

1070 {
1071 return m_detectorManager;
1072}

◆ initializeGeoParameters()

void HGTD_DetectorFactory::initializeGeoParameters ( )
private

Definition at line 129 of file HGTD_DetectorFactory.cxx.

129 {
130
131 // retrieve the material manager (can't use ATH_CHECK macros within create(), it seems..)
132 StatusCode sc = detStore()->retrieve(m_materialMgr, std::string("MATERIALS"));
133 if (sc != StatusCode::SUCCESS) {
134 ATH_MSG_ERROR("Cannot retrieve material manager from DetStore");
135 }
136
137 // temporarily hard-code custom materials - eventually will be defined in xml once HGTD migrates to GeoModelXML detector description
138
139 GeoMaterial* CFRP = new GeoMaterial("hgtd::CFRP", 1.78*(CLHEP::gram / CLHEP::cm3)); // copy of sct::CFRP used in 21.9
140 CFRP->add(m_materialMgr->getElement("Carbon"), 0.92);
141 CFRP->add(m_materialMgr->getElement("Hydrogen"), 0.02);
142 CFRP->add(m_materialMgr->getElement("Oxygen"), 0.05);
143 m_materialMgr->addMaterial("hgtd", CFRP);
144
145 GeoMaterial* Honeycomb = new GeoMaterial("hgtd::Honeycomb", 0.042*(CLHEP::gram / CLHEP::cm3)); // copy of muo::Honeycomb used in 21.9
146 Honeycomb->add(m_materialMgr->getElement("Carbon"), 0.88);
147 Honeycomb->add(m_materialMgr->getElement("Hydrogen"), 0.11);
148 m_materialMgr->addMaterial("hgtd", Honeycomb);
149
150 GeoMaterial* Peek = new GeoMaterial("hgtd::Peek", 1.3*(CLHEP::gram / CLHEP::cm3)); // copy of pix::Peek used in 21.9
151 Peek->add(m_materialMgr->getElement("Hydrogen"), 0.04);
152 Peek->add(m_materialMgr->getElement("Carbon"), 0.79);
153 Peek->add(m_materialMgr->getElement("Oxygen"), 0.16);
154 m_materialMgr->addMaterial("hgtd", Peek);
155
156 GeoMaterial* CO2_Liquid = new GeoMaterial("hgtd::CO2_Liquid", 1.032*(CLHEP::gram / CLHEP::cm3)); // copy of pix::CO2_Liquid used in 21.9
157 CO2_Liquid->add(m_materialMgr->getElement("Carbon"), 0.27);
158 CO2_Liquid->add(m_materialMgr->getElement("Oxygen"), 0.72);
159 m_materialMgr->addMaterial("hgtd", CO2_Liquid);
160
161 GeoMaterial* CO2 = new GeoMaterial("hgtd::CO2", 0.001842*(CLHEP::gram / CLHEP::cm3)); // copy of trt::CO2 used in 21.9
162 CO2->add(m_materialMgr->getElement("Carbon"), 0.27);
163 CO2->add(m_materialMgr->getElement("Oxygen"), 0.72);
164 m_materialMgr->addMaterial("hgtd", CO2);
165
166 GeoMaterial* CFiberSupport = new GeoMaterial("hgtd::CFiberSupport", 0.189*(CLHEP::gram / CLHEP::cm3)); // copy of sct::CFiberSupport used in 21.9
167 CFiberSupport->add(m_materialMgr->getElement("Carbon"), 1.0);
168 m_materialMgr->addMaterial("hgtd", CFiberSupport);
169
170 GeoMaterial* CuKapton = new GeoMaterial("hgtd::CuKapton", 2.94*(CLHEP::gram / CLHEP::cm3)); // copy of sct::CuKapton used in 21.9
171 CuKapton->add(m_materialMgr->getElement("Copper"), 0.61);
172 CuKapton->add(m_materialMgr->getElement("Carbon"), 0.26);
173 CuKapton->add(m_materialMgr->getElement("Hydrogen"), 0.01);
174 CuKapton->add(m_materialMgr->getElement("Oxygen"), 0.08);
175 CuKapton->add(m_materialMgr->getElement("Nitrogen"), 0.02);
176 m_materialMgr->addMaterial("hgtd", CuKapton);
177
178 GeoMaterial* BoratedPolyethelyne = new GeoMaterial("hgtd::BoratedPolyethelyne", 0.99*(CLHEP::gram / CLHEP::cm3)); // copy of LAr::BoratedPolyethelyne used in 21.9
179 BoratedPolyethelyne->add(m_materialMgr->getElement("Hydrogen"), 0.13);
180 BoratedPolyethelyne->add(m_materialMgr->getElement("Carbon"), 0.81);
181 BoratedPolyethelyne->add(m_materialMgr->getElement("Boron"), 0.05);
182 m_materialMgr->addMaterial("hgtd", BoratedPolyethelyne);
183
184 GeoMaterial* FEBoards = new GeoMaterial("hgtd::FEBoards", 0.99*(CLHEP::gram / CLHEP::cm3)); // copy of LAr::FEBoards used in 21.9
185 FEBoards->add(m_materialMgr->getElement("Silicon"), 0.27);
186 FEBoards->add(m_materialMgr->getElement("Oxygen"), 0.34);
187 FEBoards->add(m_materialMgr->getElement("Copper"), 0.28);
188 FEBoards->add(m_materialMgr->getElement("Hydrogen"), 0.01);
189 FEBoards->add(m_materialMgr->getElement("Carbon"), 0.09);
190 m_materialMgr->addMaterial("hgtd", FEBoards);
191
192 GeoMaterial* Epoxy = new GeoMaterial("hgtd::Epoxy", 1*(CLHEP::gram / CLHEP::cm3)); // copy of sct::Epoxy used in 21.9
193 Epoxy->add(m_materialMgr->getElement("Carbon"), 0.76);
194 Epoxy->add(m_materialMgr->getElement("Hydrogen"), 0.07);
195 Epoxy->add(m_materialMgr->getElement("Oxygen"), 0.16);
196 m_materialMgr->addMaterial("hgtd", Epoxy);
197
198 // Hardcoded box parameters taken from geometry db:
199
200 // Node: HGTDBox BOX DX DY DZ ZPOS MATERIAL
201 m_boxVolPars["HGTDModule0"] = {"HGTDModule0", 11, 20, 1.75, 0, "std::Air"};
202 m_boxVolPars["HGTDModule1"] = {"HGTDModule1", 11, 20, 1.75, 0, "std::Air"};
203 m_boxVolPars["HGTDModule2"] = {"HGTDModule2", 11, 20, 1.75, 0, "std::Air"};
204 m_boxVolPars["HGTDModule3"] = {"HGTDModule3", 11, 20, 1.75, 0, "std::Air"};
205 m_boxVolPars["HGTD::Hybrid"] = {"HGTD::Hybrid", 10.25, 20, .175, 0, "hgtd::CuKapton"};
206 m_boxVolPars["HGTD::GlueSensor"] = {"HGTD::GlueSensor", 10.25, 20, .04, 0, "hgtd::Epoxy"};
207 m_boxVolPars["HGTD::GlueAsic"] = {"HGTD::GlueAsic", 11, 20, .04, 0, "hgtd::Epoxy"};
208 m_boxVolPars["HGTDSiSensor0"] = {"HGTDSiSensor0", 10.25, 20, .025, 0, "std::Silicon"};
209 m_boxVolPars["HGTDSiSensor1"] = {"HGTDSiSensor1", 10.25, 20, .025, 0, "std::Silicon"};
210 m_boxVolPars["HGTDSiSensor2"] = {"HGTDSiSensor2", 10.25, 20, .025, 0, "std::Silicon"};
211 m_boxVolPars["HGTDSiSensor3"] = {"HGTDSiSensor3", 10.25, 20, .025, 0, "std::Silicon"};
212 m_boxVolPars["HGTD::LGADInactive"] = {"HGTD::LGADInactive", 10.25, 20, .1, 0, "std::Silicon"};
213 m_boxVolPars["HGTD::ASIC"] = {"HGTD::ASIC", 11, 20, .15, 0, "std::Silicon"};
214
215 // Add a dummy entry that will be used to leave some space - no volume will actually be created for this
216 // needed after fix of ASIC thickness (and material) in HGTD-TDR-01 tag (ATLAS-P2-ITK-17-04-02 and later), compared to HGTD-TDR-00
217 double moduleSpaceHalfZ = 0.225;
218 m_boxVolPars["HGTD::ModuleSpace"] = {"HGTD::ModuleSpace", 11, 20, moduleSpaceHalfZ, 0, "std::Air"};
219
220
221
222 // Node: HGTDTubs TUBE RMIN RMAX DZ ZPOS MATERIAL
223 m_cylVolPars["HGTD_mother"] = {"HGTD_mother", 100, 1100, 62.5, -3252, "std::Air"};
224 m_cylVolPars["HGTD::FrontCover"] = {"HGTD::FrontCover", 120, 1000, 7.5, 0, "hgtd::CFiberSupport"};
225 m_cylVolPars["HGTD::FlexPackage"] = {"HGTD::FlexPackage", 120, 660, 2, 0, "std::Air"};
226 m_cylVolPars["HGTD::FlexTube"] = {"HGTD::FlexTube", 120, 660, .175, 0, "hgtd::CuKapton"};
227 m_cylVolPars["HGTD::ModuleLayer0"] = {"HGTD::ModuleLayer0", 120, 660, 3.75, 0, "std::Air"};
228 m_cylVolPars["HGTD::ModuleLayer1"] = {"HGTD::ModuleLayer1", 120, 660, 3.75, 0, "std::Air"};
229 m_cylVolPars["HGTD::ModuleLayer2"] = {"HGTD::ModuleLayer2", 120, 660, 3.75, 0, "std::Air"};
230 m_cylVolPars["HGTD::ModuleLayer3"] = {"HGTD::ModuleLayer3", 120, 660, 3.75, 0, "std::Air"};
231 m_cylVolPars["HGTD::CoolingPlate"] = {"HGTD::CoolingPlate", 120, 920, 3, 0, "std::Aluminium"};
232 m_cylVolPars["HGTD::SupportPlate"] = {"HGTD::SupportPlate", 120, 660, .5, 0, "std::Aluminium"};
233 m_cylVolPars["HGTD::ToleranceFront"] = {"HGTD::ToleranceFront", 120, 660, 1, 0, "std::Air"};
234 m_cylVolPars["HGTD::ToleranceBack"] = {"HGTD::ToleranceBack", 120, 660, 1, 0, "std::Air"};
235 m_cylVolPars["HGTD::ToleranceMid"] = {"HGTD::ToleranceMid", 120, 660, 1, 0, "std::Air"};
236 m_cylVolPars["HGTD::ModeratorIn"] = {"HGTD::ModeratorIn", 120, 900, 15, 0, "hgtd::BoratedPolyethelyne"};
237 m_cylVolPars["HGTD::ModeratorOut"] = {"HGTD::ModeratorOut", 120, 1100, 10, 0, "hgtd::BoratedPolyethelyne"};
238 m_cylVolPars["HGTD::BackCover"] = {"HGTD::BackCover", 120, 1100, 4, 0, "hgtd::CFiberSupport"};
239 m_cylVolPars["HGTD::PeriphElec"] = {"HGTD::PeriphElec", 674, 900, 1, 2, "hgtd::FEBoards"};
240
241 m_cylVolPars["HGTD::InnerRCover1"] = {"HGTD::InnerRCover1", 110., 111., 105./2, -10., "hgtd::CFRP"};
242 // the InnerRCover bulk should be 70% aerogel and 30% honeycomb made from "aradime" (not defined - using "hgtd::Honeycomb" for now)
243 // proportions should be 50/50 by weight, which is used for GeoMaterial fractions
244 // TODO: these should be double-checked, or at least that the density/weight matches engineering drawings
245 GeoMaterial* innerRCoverBulkMaterial = new GeoMaterial("hgtd::AerogelAndHoneycomb", 0.17*(CLHEP::gram / CLHEP::cm3));
246 innerRCoverBulkMaterial->add(m_materialMgr->getMaterial("std::Aerogel"), 0.5);
247 innerRCoverBulkMaterial->add(m_materialMgr->getMaterial("hgtd::Honeycomb"), 0.5);
248 m_materialMgr->addMaterial("hgtd", innerRCoverBulkMaterial);
249 m_cylVolPars["HGTD::InnerRCover2"] = {"HGTD::InnerRCover2", 111., 119., 105./2, -10., "hgtd::AerogelAndHoneycomb"};
250 m_cylVolPars["HGTD::InnerRCover3"] = {"HGTD::InnerRCover3", 119., 120., 105./2, -10., "hgtd::CFRP"};
251 m_cylVolPars["HGTD::OuterRCover"] = {"HGTD::OuterRCover", 980., 1000., 82./2, -6.5, "hgtd::Peek"};
252 m_cylVolPars["HGTD::PeripheralCoolingLines"] = {"HGTD::PeripheralCoolingLines", 920., 980., 3./2, 31., "std::SSteel"};
253 // TODO: outer cover should be 40% "hgtd::Peek" and 60% electrical connectors (unclear material)
254
255 m_cylVolPars["HGTD::CoolingTube"] = {"HGTD::CoolingTubes", 0, 0, 2.0, 0, "std::Titanium"};
256 // Coolant should be 50% liquid and 50% gas CO2 ("hgtd::CO2")
257 GeoMaterial* coolantMaterial = new GeoMaterial("hgtd::CO2CoolantMix", 0.55*(CLHEP::gram / CLHEP::cm3));
258 coolantMaterial->add(m_materialMgr->getMaterial("hgtd::CO2_Liquid"), 0.5);
259 coolantMaterial->add(m_materialMgr->getMaterial("hgtd::CO2"), 0.5);
260 m_materialMgr->addMaterial("hgtd", coolantMaterial);
261 m_cylVolPars["HGTD::CoolingTubeFluid"] = {"HGTD::CoolingTubeFluid", 0, 0, 1.5, 0, "hgtd::CO2CoolantMix"};
262
263
264
265 // These parameters were not in the db (they don't fit into the cylinder or box structures used above)
266 m_hgtdPars = { 320., // rMid
267 640., // rOuter - only used in one place, and there 20 mm is added to it...
268 0., // disk1Rotation (in degrees)
269 15., // disk2Rotation (in degrees)
270 1., // rowSpaceSide
271 4., // rowBacksideInnerShift
272 17., // rowBacksideOuterShift
273 1.5, // moduleSpaceInner
274 12.5, // moduleSpaceOuter
275 0.456 // flexSheetSpacing
276 };
277
278 return;
279}
#define ATH_MSG_ERROR(x)
static Double_t sc
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
::StatusCode StatusCode
StatusCode definition for legacy code.

◆ mirrorModulesInQuadrant()

PositionsInQuadrant HGTD_DetectorFactory::mirrorModulesInQuadrant ( const PositionsInQuadrant & inquad)
private

Definition at line 833 of file HGTD_DetectorFactory.cxx.

833 {
834 PositionsInQuadrant rowsInQuad;
835 for (size_t row = 0; row < inquad.size(); row ++ ) {
836 std::vector<ModulePosition> modulePositions = inquad[ row ];
837 for ( size_t mod = 0; mod < modulePositions.size(); mod++ ) {
838 ModulePosition old = modulePositions[mod];
839 ModulePosition mirror = old;
840 mirror.x = old.y;
841 mirror.y = old.x;
842 mirror.phiRotation = ( old.phiRotation == 0. ? 90. : 0. );
843 modulePositions[mod] = mirror;
844 }
845 // keeping the order defined in HGTD_DetectorFactory::reorderRows
846 rowsInQuad[ inquad.size() - row - 1 ] = std::move(modulePositions);
847 }
848 return rowsInQuad;
849}

◆ mirrorPositionsAroundYaxis()

void HGTD_DetectorFactory::mirrorPositionsAroundYaxis ( std::array< PositionsInQuadrant, 4 > & arr)
private

Definition at line 1024 of file HGTD_DetectorFactory.cxx.

1024 {
1025 for (auto& layer : arr) {
1026 for (auto& row : layer) {
1027 for (auto& module : row) {
1028 module.x = -module.x;
1029 }
1030 }
1031 }
1032}

◆ 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=()

HGTD_DetectorFactory & HGTD_DetectorFactory::operator= ( HGTD_DetectorFactory & right)
private

◆ prepareLayersFromQuadrants()

std::array< PositionsInQuadrant, 4 > HGTD_DetectorFactory::prepareLayersFromQuadrants ( unsigned int nRows)
private

Definition at line 736 of file HGTD_DetectorFactory.cxx.

736 {
737
738 std::array< PositionsInQuadrant, 4 > positions;
739
740 // three-ring layout
741 if ( m_geomVersion == 1 ) {
742 // the 1st disk
743 PositionsInQuadrant d0q0front = prepareQuadrantsFromRows( 0, nRows );
744 reorderRows( &d0q0front );
745 PositionsInQuadrant d0q0back = prepareQuadrantsFromRows( 1, nRows );
746 reorderRows( &d0q0back );
747
748 // the 2nd disk is the same as the 1st, but mirrored
749 PositionsInQuadrant d1q0front = mirrorModulesInQuadrant( d0q0back );
750 PositionsInQuadrant d1q0back = mirrorModulesInQuadrant( d0q0front );
751
752 positions[ 0 ] = std::move(d0q0front); // front-side module positions
753 positions[ 1 ] = std::move(d0q0back); // back-side module positions
754 positions[ 2 ] = std::move(d1q0front); // front-side module positions
755 positions[ 3 ] = std::move(d1q0back); // back-side module positions
756
757 } else {
758 nRows = 18; // note 21-18 = 3 elements with positions of modules in rows are left empty
759 positions[0] = positions[2] = prepareQuadrantsFromRows(0, nRows ); // front-side module positions
760 positions[1] = positions[3] = prepareQuadrantsFromRows(1, nRows ); // back-side module positions
761 }
762 return positions;
763}
PositionsInQuadrant prepareQuadrantsFromRows(int layer, unsigned int maxRow)
int reorderRows(PositionsInQuadrant *quadrant)
PositionsInQuadrant mirrorModulesInQuadrant(const PositionsInQuadrant &)
unsigned int constexpr nRows
Definition RPDUtils.h:24

◆ prepareModulePositionsInRowThreeRing()

std::vector< ModulePosition > HGTD_DetectorFactory::prepareModulePositionsInRowThreeRing ( int row,
int back = 0 )
private

Definition at line 852 of file HGTD_DetectorFactory.cxx.

852 {
853
854 // below parameters should be collected into xml or RDB
855 int index_XYcoord_change = 14;
856
857 // height is the short edge of module, width is the longer edge
858 float halfWidth = .5*40., halfHeight = .5*21.8; // bare module
859 float midR = 230., midR2 = 470.5, maxRcut = 660., maxOuterR = 670.;
860 // special tweak needed to avoid overlapping holes on front and back
861 if (row == 21 and back==1) {
862 midR2 = 510.;
863 }
864 float readoutRowSpace = 1.0;
865 bool extrude = ( ( row == 6 || row == 18 ) && !back ) || // front side
866 ( ( row == 2 || row == 11 || row == 12 || row == 17 ) && back ); // back side
867
868 // instead of attempting to re-calculate the leading module per row, just pick up from dataBase,
869 // numbers here taken from spreadsheet at https://cernbox.cern.ch/index.php/s/PPXEWSBnBjwI7UU
870 std::array< float, 22 > ModStarting = { 122., 122.7, 89.85, 123.5, 175.4, 257.4, 287.5, 298.4, 287.5, 304.5, 287.5, 304.5, 287.5, 0.0, 299.7,
871 130., 114.7, 131.45, 164.45, 216.35, 205.45, 257.35 };
872
873 std::array< float, 22 > ModStartBack = { 130., 114.7, 97.85, 131.5, 164.5, 246.5, 298.4, 287.5, 298.4, 287.5, 304.5, 287.5, 304.5, 0.0, 287.5,
874 122., 122.7, 123.45, 172.45, 205.45, 216.35, 246.45 };
875 /* row == 13 will be skipped from outside, and, since row == 15 XY flip take place. */
876
877 // this is a bit hacky for this layout, a db-based solution will help in the future
878 int useCorner = 0;
879 if ( ( ( row == 1 || row == 5 || row == 15 || row == 19 ) && ! back ) || // front side
880 ( ( row == 0 || row == 8 || row == 16 || row == 18 || row == 21 ) && back ) // back side
881 ) useCorner = 1;
882 if ( row == 17 ) useCorner = 2;
883 // in some exceptional cases the spacing will be smaller even though the module crossed the ring boundary
884 float backshift = 6.;
885
886 // the new layout tune makes small adjustments (usually 2~3 mm) for the last modules of some rows.
887 // even though most of element is zero for most of modules, we store these adjustments in a 2D array for now
888 float tailModCorrection[ 22 ][ 19 ];
889 for ( int r = 0; r < 22; r ++ )
890 for ( int m = 0; m < 19; m ++ ) tailModCorrection[r][m] = 0.;
891 tailModCorrection[11][4] = tailModCorrection[12][2] = 10.;
892
893 // TDR layout: spaceSmallR = 5.5 , spaceMediumR = 8.4 , spaceLargeR = 14.5
894 float spaceSmallR = 3.7 , spaceMediumR = 6.6, spaceLargeR = 12.7; // updated spacings from post-TDR developments
895
896 float backsideSmallR = spaceSmallR;
897 float backsideMediumR = spaceMediumR;
898 float backsideLargeR = spaceLargeR;
899
900 float extendedWidth = readoutRowSpace + 2.*halfWidth;
901
902 float posRadius = 0.;
903 float posOfLastPlacedModule = 0.; // start with dummy position
904 int moduleCounter = 0;
905 std::vector< ModulePosition > rowModulePositions;
906
907 float effectiveRow = row;
908 // note the flipping of effectiveRow, it is the cause of XY flipping in later occurrance
909 if ( row == index_XYcoord_change ) effectiveRow = 13;
910 if ( row > index_XYcoord_change ) effectiveRow -= ( index_XYcoord_change + 1 );
911
912 // x coordinate for vertical rows
913 float rowCentPos = 0.5*extendedWidth*( 2*effectiveRow + 1 );
914
915 if ( extrude ) maxRcut = maxOuterR;
916 while ( posRadius < maxRcut ) {
917 // horizontal rows need care (restart from other edge of quadrant), this variable helps get the inner radius right
918 // y coordinate for vertical rows, then x coordinate for modules
919 float modPos_row = -999.;
920
921 // for the first module in each row, take the starting position from the arrays created earlier from the spreadsheet
922 if ( moduleCounter == 0 ) { // leading module per row
923 modPos_row = ( back ? ModStartBack[row] : ModStarting[row] );
924 modPos_row += halfHeight;
925 }
926 // the rest of the modules follow sequential, radius-dependent placement rules
927 else {
928 float prevX = rowModulePositions[ moduleCounter - 1 ].x;
929 float prevY = rowModulePositions[ moduleCounter - 1 ].y;
930 float spacing = back ? backsideSmallR : spaceSmallR;
931
932 // increase the spacing by the ring it will fallin
933 float ringCrossRcorner = std::sqrt( ( prevY + halfHeight)*( prevY + halfHeight) +
934 ( prevX + halfWidth )*( prevX + halfWidth ) );
935 float ringCrossRcenter = std::sqrt( prevY*prevY + prevX*prevX );
936
937 bool tuned_center = ( row == 3 && ( moduleCounter == 3 && !back ) ) || // front, row 3
938 ( row == 20 && moduleCounter == 8 && !back ) || // front, row 20
939 ( row == 21 && moduleCounter == 6 && back ); // back, row 21
940 if ( useCorner == 2 ) {
941 if ( ( moduleCounter == 3 && ! back ) || ( ( moduleCounter == 3 || moduleCounter == 4 ) && back ) ) {
942 ringCrossRcenter -= backshift;
943 if ( ringCrossRcenter > midR && ringCrossRcenter <= midR2 ) spacing = back ? backsideMediumR : spaceMediumR;
944 if ( ringCrossRcenter > midR2 ) spacing = back ? backsideLargeR : spaceLargeR;
945 }
946 else {
947 if ( ringCrossRcorner > midR && ringCrossRcorner <= midR2 ) spacing = back ? backsideMediumR : spaceMediumR;
948 if ( ringCrossRcorner > midR2 ) spacing = back ? backsideLargeR : spaceLargeR;
949 }
950 }
951 else if ( useCorner == 1 ) {
952 if ( ringCrossRcorner > midR && ringCrossRcorner <= midR2 ) spacing = back ? backsideMediumR : spaceMediumR;
953 if ( ringCrossRcorner > midR2 ) spacing = back ? backsideLargeR : spaceLargeR;
954 }
955 else {
956 if ( tuned_center ) ringCrossRcenter -= backshift;
957 if ( ringCrossRcenter > midR && ringCrossRcenter <= midR2 ) spacing = back ? backsideMediumR : spaceMediumR;
958 if ( ringCrossRcenter > midR2 ) spacing = back ? backsideLargeR : spaceLargeR;
959 }
960
961 modPos_row = posOfLastPlacedModule + 2.*halfHeight + spacing;
962
963 if ( back && moduleCounter < 19) modPos_row -= tailModCorrection[ row ][ moduleCounter ];
964
965 } // endif non-leading module
966
967 // check and limit the length of the row
968 posRadius = std::sqrt( ( rowCentPos + halfWidth )*( rowCentPos + halfWidth ) +
969 ( modPos_row + halfHeight)*( modPos_row + halfHeight ) );
970 if ( posRadius > maxRcut ) {
971 ATH_MSG_DEBUG(" row " << row <<" finished with " << moduleCounter <<" modules ");
972 break;
973 }
974
975 // the X and Y coordinates need to be flipped if this row is horizontal,
976 // needed only for backwards compatibility for two-ring layout
977 ModulePosition modu = { modPos_row, rowCentPos, 0., false, row, moduleCounter };
978 ModulePosition moduFlipped = { rowCentPos, modPos_row, 90., true, row, moduleCounter };
979
980 // eventually arrived at a module to append into this row
981 if ( row > index_XYcoord_change ) rowModulePositions.push_back( modu );
982 else rowModulePositions.push_back( moduFlipped );
983
984 // the spreadsheet gave the center of bottom edge of a module, so an adjustment by halfHeight is needed
985 if ( m_outputIdfr ) ATH_MSG_DEBUG( " Row " << ( row <= index_XYcoord_change ? effectiveRow + 1 : 36 - row )
986 << " Module " << moduleCounter + 1 <<" at (x,y) : "
987 << ( row > index_XYcoord_change ? rowModulePositions.back().x - halfHeight : rowModulePositions.back().x ) << ", "
988 << ( row > index_XYcoord_change ? rowModulePositions.back().y : rowModulePositions.back().y - halfHeight ) );
989
990 posOfLastPlacedModule = modPos_row;
991 moduleCounter ++;
992 } // endof while loop
993
994 if ( m_outputIdfr ) std::cout << "Total #Module " << rowModulePositions.size() <<" at original row " << row << std::endl;
995
996 return rowModulePositions;
997}
int r
Definition globals.cxx:22

◆ prepareModulePositionsInRowTwoRing()

std::vector< ModulePosition > HGTD_DetectorFactory::prepareModulePositionsInRowTwoRing ( int row,
bool back = false )
private

Definition at line 1075 of file HGTD_DetectorFactory.cxx.

1075 {
1076
1077 unsigned int module = 0;
1078 std::vector<ModulePosition> modulePositions;
1079 double posOfLastPlacedModule = 0.;
1080
1081 while (true) {
1082 //ATH_MSG_INFO) << "Will now place module " << module );
1083 // horizontal rows need care (restart from other edge of quadrant), this variable helps get the inner radius right
1084 // in quadrant 0 - ie top right quadrant
1085 // row 0 = bottom horizontal row. numbering grows upwards and counterclockwise; row 17=leftmost vertical row
1086 // rowForInnerRadius = 0-1 for vertical rows too
1087 int rowForInnerRadius = row; // because row 16-17 are equivalent to 0-1 regarding module placement
1088 if (row == 17) rowForInnerRadius = 0;
1089 if (row == 16) rowForInnerRadius = 1;
1090
1091 // params needed frequently below
1092 double moduleWidth = m_boxVolPars["HGTDModule0"].yHalf*2;
1093 double moduleHeight = m_boxVolPars["HGTDModule0"].xHalf*2;
1094 double rInner = m_cylVolPars["HGTD::ModuleLayer0"].rMin;
1095 double rMid = m_hgtdPars.rMid;
1096 double rOuter = m_hgtdPars.rOuter;
1097 double rowSpaceSide = m_hgtdPars.rowSpaceSide;
1098
1099 // x coordinate for vertical rows
1100 double rowCenterPos = (moduleWidth + rowSpaceSide)*(rowForInnerRadius + 0.5);
1101 // y coordinate for vertical rows
1102 double modulePosAlongRow = -99.; // mock value for now
1103 // for the first module, pick the right starting point
1104 if (modulePositions.empty()) {
1105 // start at inner radius and include any offset for backside.
1106 if (rowForInnerRadius < 3) {
1107 modulePosAlongRow = std::sqrt( pow(rInner, 2) - pow((moduleWidth + rowSpaceSide)*rowForInnerRadius, 2) )
1108 + back*m_hgtdPars.rowBacksideInnerShift + moduleHeight/2;
1109 }
1110 else { // later modules start at 2*moduleWidth, with offset for the backside
1111 double backSpacing = m_hgtdPars.rowBacksideInnerShift;
1112 if (back && (rowCenterPos - moduleWidth/2 > rMid)) {
1113 backSpacing = m_hgtdPars.rowBacksideOuterShift;
1114 }
1115 modulePosAlongRow = 2*(moduleWidth + rowSpaceSide) + moduleHeight/2 + back*backSpacing;
1116 }
1117 }
1118 // the rest of the modules follow sequential, radius-dependent placement rules
1119 else {
1120 ModulePosition prev = modulePositions.back();
1121 double spacing = m_hgtdPars.moduleSpaceInner;
1122 // if the previous module was completely outside rMid, increase the spacing
1123 // (+1 mm is a needed shift for full coverage - could need tweaking if layout parameters change!)
1124 float innermostCornerR = std::sqrt( pow(prev.y - moduleHeight/2, 2) + pow(prev.x - moduleWidth/2, 2) ) + 1.;
1125 if (innermostCornerR > rMid) {
1126 spacing = m_hgtdPars.moduleSpaceOuter;
1127 }
1128 // for the back the large spacing starts as soon as the space would entirely be outside R = 320 mm
1129 if (back) {
1130 double startOfSpaceAlongRow = std::sqrt( pow(prev.y + moduleHeight/2, 2) + pow(prev.x - moduleWidth/2, 2) ) - 2;
1131 if (startOfSpaceAlongRow > rMid) {
1132 spacing = m_hgtdPars.moduleSpaceOuter;
1133 }
1134 }
1135 // correction to the first two spaces on the front side, compensating for the 2 mm introduced at beginning of a row
1136 if (!back && rowForInnerRadius < 8 && module < 3) {
1137 spacing -= 1.; // should result in 3 mm instead of 4 mm for innermost spaces on rows starting at R = 120
1138 }
1139 // squeeze in a few more modules at the end of some rows
1140 double maxRcut = rOuter+20;
1141 if(row == 8 || row == 9 || row == 10) {
1142 maxRcut = 661;
1143 if(row == 8 && module > 12) spacing -= 4;
1144 }
1145 else if ( row == 11 && module > 9) {
1146 maxRcut = 662;
1147 spacing -= 6;
1148 }
1149 else if (row == 12 && back) {
1150 maxRcut = 665;
1151 }
1152 else if(row == 13 && module > 5) {
1153 maxRcut = 666;
1154 if (!back && module > 6 ) spacing -= 8.5;
1155 else if (back && module > 5) spacing -= 2;
1156 }
1157 else if (row == 14 && module > 3) {
1158 maxRcut = 665;
1159 spacing -= 5;
1160 }
1161 else if (row == 15) {
1162 maxRcut = 669;
1163 spacing -= 5.5;
1164 }
1165 modulePosAlongRow = posOfLastPlacedModule + moduleHeight + spacing;
1166 // stop if the next module will extend outside the max allowed radius
1167 // HC max radius is 665
1168 if ( std::sqrt( pow(rowCenterPos + moduleWidth/2, 2) + pow(modulePosAlongRow + moduleHeight/2, 2) ) > maxRcut) {
1169 break;
1170 }
1171 }
1172 ModulePosition m = {rowCenterPos, modulePosAlongRow, 0, true, row, (int)module};
1173 modulePositions.push_back(m);
1174 posOfLastPlacedModule = modulePosAlongRow;
1175 module += 1;
1176 } // end of loop over modules
1177
1178 // finally, flip x and y for all modules if this row is horizontal
1179 if (row < 16) {
1180 // ATH_MSG_INFO) << "Flipping x and y for modules in row " << row );
1181 for (size_t i=0; i < modulePositions.size(); i++) {
1182 ModulePosition old = modulePositions[i];
1183 ModulePosition rotated = old;
1184 rotated.x = old.y;
1185 rotated.y = old.x;
1186 rotated.flipped = !old.flipped;
1187 rotated.row = old.row;
1188 rotated.el_in_row = old.el_in_row;
1189 modulePositions[i] = rotated;
1190 }
1191 }
1192
1193 ATH_MSG_DEBUG( "row = " << row );
1194 for(size_t i=0; i < modulePositions.size(); i++) {
1195 ATH_MSG_DEBUG( "Module " << i << " at (x,y) = (" << modulePositions[i].x << "," << modulePositions[i].y << ")" );
1196 }
1197
1198 return modulePositions;
1199}
constexpr int pow(int base, int exp) noexcept

◆ prepareQuadrantsFromRows()

PositionsInQuadrant HGTD_DetectorFactory::prepareQuadrantsFromRows ( int layer,
unsigned int maxRow )
private

Definition at line 811 of file HGTD_DetectorFactory.cxx.

811 {
812
813 PositionsInQuadrant rowsInQuad;
814 bool isBackside = (layer % 2);
815 // three-ring layout
816 if ( m_geomVersion == 1 ) {
817 for (size_t row = 0; row <= maxRow; row++) {
818 if ( row == 13 ) continue; // element #21 is tried since one row is skipped
819 std::vector<ModulePosition> rowModulePositions = prepareModulePositionsInRowThreeRing( row, isBackside );
820 rowsInQuad[ row > 13 ? row - 1 : row ] = std::move(rowModulePositions);
821 }
822 }
823 // two-ring layout
824 else {
825 for (size_t row = 0; row < maxRow; row++) {
826 std::vector<ModulePosition> rowModulePositions = prepareModulePositionsInRowTwoRing(row, isBackside);
827 rowsInQuad[ row ] = std::move(rowModulePositions);
828 }
829 }
830 return rowsInQuad;
831}
std::vector< ModulePosition > prepareModulePositionsInRowTwoRing(int row, bool back=false)
std::vector< ModulePosition > prepareModulePositionsInRowThreeRing(int row, int back=0)

◆ rdbAccessSvc()

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

Definition at line 32 of file InDetDetectorFactoryBase.h.

32{return m_athenaComps->rdbAccessSvc();}

◆ reorderRows()

int HGTD_DetectorFactory::reorderRows ( PositionsInQuadrant * quadrant)
private

Definition at line 1005 of file HGTD_DetectorFactory.cxx.

1005 {
1006
1007 PositionsInQuadrant tmpQuadrant;
1008 int xchng = 0;
1009 unsigned int numrow = quadrant->size();
1010 for ( unsigned int r = 0; r < numrow; r ++ ) {
1011 unsigned int idx = r > 13 ? 13 + numrow - r : r;
1012 ATH_MSG_DEBUG( " original row " << ( r <= 12 ? r : r + 1 ) <<" new row " << idx + 1
1013 << " : "<< numrow );
1014 tmpQuadrant[ idx ] = quadrant->at( r );
1015 if ( idx != r ) xchng++;
1016 }
1017 // refill the quadrant
1018 for ( unsigned int r = 0; r < numrow; r++ )
1019 quadrant->at( r ) = tmpQuadrant[ numrow - 1 - r ];
1020
1021 return xchng;
1022}

◆ setPrintIdentifierDict()

void HGTD_DetectorFactory::setPrintIdentifierDict ( bool print)

Definition at line 83 of file HGTD_DetectorFactory.cxx.

83 {
85 return;
86}
void print(char *figname, TCanvas *c1)

Member Data Documentation

◆ m_athComps

HGTD_GeoModelAthenaComps* HGTD_DetectorFactory::m_athComps {}
private

Definition at line 116 of file HGTD_DetectorFactory.h.

116{};

◆ m_athenaComps

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

Definition at line 46 of file InDetDetectorFactoryBase.h.

◆ m_boxVolPars

std::map<std::string,GeoBoxVolParams> HGTD_DetectorFactory::m_boxVolPars
private

Definition at line 125 of file HGTD_DetectorFactory.h.

◆ m_commonItems

std::unique_ptr<const InDetDD::SiCommonItems> HGTD_DetectorFactory::m_commonItems {}
private

Definition at line 128 of file HGTD_DetectorFactory.h.

128{};

◆ m_cylVolPars

std::map<std::string,GeoCylVolParams> HGTD_DetectorFactory::m_cylVolPars
private

Definition at line 124 of file HGTD_DetectorFactory.h.

◆ m_detectorManager

HGTD_DetectorManager* HGTD_DetectorFactory::m_detectorManager {}
private

Definition at line 115 of file HGTD_DetectorFactory.h.

115{};

◆ m_geomVersion

int HGTD_DetectorFactory::m_geomVersion {}
private

Definition at line 119 of file HGTD_DetectorFactory.h.

119{};

◆ m_hgtdPars

HgtdGeoParams HGTD_DetectorFactory::m_hgtdPars {}
private

Definition at line 126 of file HGTD_DetectorFactory.h.

126{};

◆ m_materialMgr

StoredMaterialManager* HGTD_DetectorFactory::m_materialMgr {}
private

Definition at line 117 of file HGTD_DetectorFactory.h.

117{};

◆ m_outputIdfr

bool HGTD_DetectorFactory::m_outputIdfr {}
private

Definition at line 122 of file HGTD_DetectorFactory.h.

122{};

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