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 57 of file HGTD_DetectorFactory.cxx.

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

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

◆ 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 295 of file HGTD_DetectorFactory.cxx.

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

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

◆ create()

void HGTD_DetectorFactory::create ( GeoPhysVol * world)
overridevirtual

Definition at line 86 of file HGTD_DetectorFactory.cxx.

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

◆ createHgtdDesign()

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

Definition at line 1033 of file HGTD_DetectorFactory.cxx.

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

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

1068 {
1069 return m_detectorManager;
1070}

◆ initializeGeoParameters()

void HGTD_DetectorFactory::initializeGeoParameters ( )
private

Definition at line 127 of file HGTD_DetectorFactory.cxx.

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

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

◆ mirrorPositionsAroundYaxis()

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

Definition at line 1022 of file HGTD_DetectorFactory.cxx.

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

◆ 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 734 of file HGTD_DetectorFactory.cxx.

734 {
735
736 std::array< PositionsInQuadrant, 4 > positions;
737
738 // three-ring layout
739 if ( m_geomVersion == 1 ) {
740 // the 1st disk
741 PositionsInQuadrant d0q0front = prepareQuadrantsFromRows( 0, nRows );
742 reorderRows( &d0q0front );
743 PositionsInQuadrant d0q0back = prepareQuadrantsFromRows( 1, nRows );
744 reorderRows( &d0q0back );
745
746 // the 2nd disk is the same as the 1st, but mirrored
747 PositionsInQuadrant d1q0front = mirrorModulesInQuadrant( d0q0back );
748 PositionsInQuadrant d1q0back = mirrorModulesInQuadrant( d0q0front );
749
750 positions[ 0 ] = std::move(d0q0front); // front-side module positions
751 positions[ 1 ] = std::move(d0q0back); // back-side module positions
752 positions[ 2 ] = std::move(d1q0front); // front-side module positions
753 positions[ 3 ] = std::move(d1q0back); // back-side module positions
754
755 } else {
756 nRows = 18; // note 21-18 = 3 elements with positions of modules in rows are left empty
757 positions[0] = positions[2] = prepareQuadrantsFromRows(0, nRows ); // front-side module positions
758 positions[1] = positions[3] = prepareQuadrantsFromRows(1, nRows ); // back-side module positions
759 }
760 return positions;
761}
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 850 of file HGTD_DetectorFactory.cxx.

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

◆ prepareModulePositionsInRowTwoRing()

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

Definition at line 1073 of file HGTD_DetectorFactory.cxx.

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

◆ prepareQuadrantsFromRows()

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

Definition at line 809 of file HGTD_DetectorFactory.cxx.

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

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

◆ setPrintIdentifierDict()

void HGTD_DetectorFactory::setPrintIdentifierDict ( bool print)

Definition at line 81 of file HGTD_DetectorFactory.cxx.

81 {
83 return;
84}
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: