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
304 double motherHalfZ = ((GeoTube*) HGTDparent->getLogVol()->getShape())->getZHalfLength();
305 double modulePackageHalfZtot = 3.5/2 + 4./2;
306
310
311
312 std::vector<std::string> hgtdVolumes;
313 hgtdVolumes.push_back("HGTD::ModeratorOut");
314 hgtdVolumes.push_back("HGTD::BackCover");
315 hgtdVolumes.push_back("HGTD::ToleranceBack");
316 hgtdVolumes.push_back("HGTD::ModeratorIn");
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
335 hgtdVolumes.push_back("HGTD::InnerRCover1");
336 hgtdVolumes.push_back("HGTD::InnerRCover2");
337 hgtdVolumes.push_back("HGTD::InnerRCover3");
338 hgtdVolumes.push_back("HGTD::OuterRCover");
339 hgtdVolumes.push_back("HGTD::PeripheralCoolingLines");
340
341
342
343
345
347
348
349
350
351 GeoCylVolParams packagePars =
m_cylVolPars[
"HGTD::FlexPackage"];
352 GeoCylVolParams flexPars =
m_cylVolPars[
"HGTD::FlexTube"];
353 std::vector<double> flexSheetInnerR;
354 double currentInnerR = 144.;
355 for (int flexSheet = 0; flexSheet < 8; flexSheet++) {
356 flexSheetInnerR.push_back(currentInnerR);
357
358 currentInnerR +=
m_boxVolPars[
"HGTDModule0"].xHalf*2 * (2 + 2 * (flexSheet < 4 ? 0.2 : 0.8) );
359 }
360
361
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());
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
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),
376 GeoPhysVol* hgtdFlexPhysical = new GeoPhysVol(hgtdFlexLogical);
377 flexPackagePhysical[flexVolume]->add(new GeoTransform(GeoTrf::TranslateZ3D(flexZoffset)));
378 flexPackagePhysical[flexVolume]->add(hgtdFlexPhysical);
379
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
389
390
391 std::vector<double> coolingTubeRadii;
392 double coolingTubeRadius = 130.;
393 coolingTubeRadii.push_back(coolingTubeRadius);
394
395
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 }
414 ATH_MSG_INFO(
"Will now calculate cooling-loop positions for the three-ring layout");
415
416 int numberOfLoops = 34;
417 float loopDistance = (674.-130.)/numberOfLoops;
418 for (
int i = 0;
i < numberOfLoops;
i++) {
419 coolingTubeRadius += loopDistance;
420 coolingTubeRadii.push_back(coolingTubeRadius);
421 }
422
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++) {
435 }
436
438
440
441
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 = {};
448
450
452
453
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
461 if (vol == 0)
463
464
465
466 else {
467 if (
v.substr(9,8) !=
"erRCover" && v !=
"HGTD::PeripheralCoolingLines") {
468 std::string vPrev = hgtdVolumes[vol-1];
470 }
471 }
472
473
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
483 GeoPhysVol* hgtdSubVolumePhysical = new GeoPhysVol(hgtdSubVolumeLogical);
484
485
486 if (v == "HGTD::CoolingPlate") {
488
489 static constexpr std::array<int,2> signArr{1,-1};
490 for (
int side = 0;
side < 2;
side++) {
491
492 HGTDparent->add(
new GeoTransform(GeoTrf::TranslateZ3D(
m_cylVolPars[v].zOffsetLocal + signArr[side]*zOffsetPeriphElec)));
493 HGTDparent->add(periphElec_phys);
494 }
495
496
497 for (
size_t i = 0;
i < coolingTubeRadii.size();
i++) {
498
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,
503 GeoPhysVol* coolingTubePhysical = new GeoPhysVol(coolingTubeLogical);
504 hgtdSubVolumePhysical->add(coolingTubePhysical);
505
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,
510 GeoPhysVol* coolingFluidPhysical = new GeoPhysVol(coolingFluidLogical);
511 hgtdSubVolumePhysical->add(coolingFluidPhysical);
512 }
513 }
514
515
516 if (
v.substr(0,17) ==
"HGTD::ModuleLayer") {
517
519
520
521 double zFlex = 0.;
522 bool Lside =
layer % 2;
523 if (Lside == 0) {
524 zFlex = -modulePackageHalfZtot +
m_cylVolPars[
"HGTD::FlexPackage"].zHalf;
525 zModuleLayerF = modulePackageHalfZtot - modulePackageHalfZ;
526 }
527 else {
528 zFlex = modulePackageHalfZtot -
m_cylVolPars[
"HGTD::FlexPackage"].zHalf;
529 zModuleLayerB = -modulePackageHalfZtot + modulePackageHalfZ;
530 }
531
532
533 hgtdSubVolumePhysical->add(new GeoTransform(GeoTrf::TranslateZ3D(zFlex)));
534 hgtdSubVolumePhysical->add(flexPackagePhysical[(Lside ? 0 : 1)]);
535
537
538 HGTDparent->add(
new GeoTransform( GeoTrf::TranslateZ3D(
m_cylVolPars[v].zOffsetLocal) *
539 GeoTrf::RotateZ3D(diskRotation*Gaudi::Units::deg)) );
540
541
542 HGTDparent->add( hgtdSubVolumePhysical );
543 moduleLayerPhysical[
layer] = hgtdSubVolumePhysical;
544
545 }
546 else {
547 HGTDparent->add(
new GeoTransform(GeoTrf::TranslateZ3D(
m_cylVolPars[v].zOffsetLocal)));
548 HGTDparent->add(hgtdSubVolumePhysical);
549 }
550
551
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 }
559
561
563
564
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");
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;
577
578
579
580
581 int totMod = 0;
582
583 unsigned int maxRows = 21;
585
587
588
590
593
594 int Lside =
layer % 2;
595
596 std::vector<std::string> volumes = moduleVolumes;
597 if ( Lside != 0 )
reverse( volumes.begin(), volumes.end() );
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
603
604
605
606 double moduleHalfWidth =
m_boxVolPars[moduleName].xHalf;
607 double moduleHalfHeight =
m_boxVolPars[moduleName].yHalf;
608
609
610
612
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
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
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
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
642 for (
size_t comp = 0;
comp < volumes.size();
comp++) {
643 if (volumes[comp] ==
"SensorPlaceHolder") volumes[
comp] = sensorName;
644
645 std::string
c = volumes[
comp];
646
647 if (comp == 0)
649 else {
650 std::string cPrev = volumes[
comp-1];
652 }
653
654
655 if (volumes[comp] == "HGTD::ModuleSpace") continue;
656
659
660
661 double xOffsetLocal = moduleHalfWidth - comp_halfx;
662
663
664 GeoBox* sensorCompSolidVol =
new GeoBox(comp_halfx, comp_halfy,
m_boxVolPars[c].zHalf);
665
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,
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
677 if ( q == 0 && ( mod == 0 || mod == ( ModsPerRow.size() - 1 ) ) && !
m_outputIdfr ) {
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());
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
701 if ( mod == 0 && q == 0 && volumes[comp] != sensorName )
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 }
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 }
719 }
721 }
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 ATH_MSG_WARNING(x)
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.
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
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.
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.