25 #include "GeoModelKernel/GeoNameTag.h"
26 #include "GeoModelKernel/GeoIdentifierTag.h"
27 #include "GeoModelKernel/GeoMaterial.h"
28 #include "GeoModelKernel/GeoTransform.h"
29 #include "GeoModelKernel/GeoAlignableTransform.h"
30 #include "GeoModelKernel/GeoTorus.h"
31 #include "GeoModelKernel/GeoTube.h"
32 #include "GeoModelKernel/GeoBox.h"
33 #include "GeoModelKernel/GeoPhysVol.h"
34 #include "GeoModelKernel/GeoFullPhysVol.h"
40 #include "GaudiKernel/SystemOfUnits.h"
60 m_athComps( athComps ),
61 m_materialMgr( nullptr ),
63 m_outputIdfr( false ) {
67 ATH_MSG_INFO(
"HGTD geometry from hard-coded definition - No Information being taken from Geometry Tag!" );
96 float zMother = 3482.5;
103 world->add(
new GeoNameTag(
"HGTD_Pos"));
104 world->add(
new GeoIdentifierTag(9));
105 ATH_MSG_INFO(
"HGTD_Pos mother volume will be placed at z = " << zMother <<
" mm" );
106 world->add(
new GeoTransform(GeoTrf::TranslateZ3D(zMother)));
107 GeoVPhysVol* endcapPos =
build( positiveEndcapLogicalVolume,
true);
108 world->add( endcapPos );
112 world->add(
new GeoNameTag(
"HGTD_Neg"));
113 world->add(
new GeoIdentifierTag(-9));
114 ATH_MSG_INFO(
"HGTD_Neg mother volume will be placed at z = " << -zMother <<
" mm" );
115 world->add(
new GeoTransform(GeoTrf::TranslateZ3D(-zMother)));
117 GeoVPhysVol* endcapNeg =
build( negativeEndcapLogicalVolume,
false);
118 world->add( endcapNeg );
132 if (
sc != StatusCode::SUCCESS) {
133 ATH_MSG_ERROR(
"Cannot retrieve material manager from DetStore");
165 GeoMaterial* CFiberSupport =
new GeoMaterial(
"hgtd::CFiberSupport", 0.189*(
CLHEP::gram /
CLHEP::cm3));
177 GeoMaterial* BoratedPolyethelyne =
new GeoMaterial(
"hgtd::BoratedPolyethelyne", 0.99*(
CLHEP::gram /
CLHEP::cm3));
200 m_boxVolPars[
"HGTDModule0"] = {
"HGTDModule0", 11, 20, 1.75, 0,
"std::Air"};
201 m_boxVolPars[
"HGTDModule1"] = {
"HGTDModule1", 11, 20, 1.75, 0,
"std::Air"};
202 m_boxVolPars[
"HGTDModule2"] = {
"HGTDModule2", 11, 20, 1.75, 0,
"std::Air"};
203 m_boxVolPars[
"HGTDModule3"] = {
"HGTDModule3", 11, 20, 1.75, 0,
"std::Air"};
204 m_boxVolPars[
"HGTD::Hybrid"] = {
"HGTD::Hybrid", 10.25, 20, .175, 0,
"hgtd::CuKapton"};
205 m_boxVolPars[
"HGTD::GlueSensor"] = {
"HGTD::GlueSensor", 10.25, 20, .04, 0,
"hgtd::Epoxy"};
206 m_boxVolPars[
"HGTD::GlueAsic"] = {
"HGTD::GlueAsic", 11, 20, .04, 0,
"hgtd::Epoxy"};
207 m_boxVolPars[
"HGTDSiSensor0"] = {
"HGTDSiSensor0", 10.25, 20, .025, 0,
"std::Silicon"};
208 m_boxVolPars[
"HGTDSiSensor1"] = {
"HGTDSiSensor1", 10.25, 20, .025, 0,
"std::Silicon"};
209 m_boxVolPars[
"HGTDSiSensor2"] = {
"HGTDSiSensor2", 10.25, 20, .025, 0,
"std::Silicon"};
210 m_boxVolPars[
"HGTDSiSensor3"] = {
"HGTDSiSensor3", 10.25, 20, .025, 0,
"std::Silicon"};
211 m_boxVolPars[
"HGTD::LGADInactive"] = {
"HGTD::LGADInactive", 10.25, 20, .1, 0,
"std::Silicon"};
212 m_boxVolPars[
"HGTD::ASIC"] = {
"HGTD::ASIC", 11, 20, .15, 0,
"std::Silicon"};
216 double moduleSpaceHalfZ = 0.225;
217 m_boxVolPars[
"HGTD::ModuleSpace"] = {
"HGTD::ModuleSpace", 11, 20, moduleSpaceHalfZ, 0,
"std::Air"};
222 m_cylVolPars[
"HGTD_mother"] = {
"HGTD_mother", 100, 1100, 62.5, -3252,
"std::Air"};
223 m_cylVolPars[
"HGTD::FrontCover"] = {
"HGTD::FrontCover", 120, 1000, 7.5, 0,
"hgtd::CFiberSupport"};
224 m_cylVolPars[
"HGTD::FlexPackage"] = {
"HGTD::FlexPackage", 120, 660, 2, 0,
"std::Air"};
225 m_cylVolPars[
"HGTD::FlexTube"] = {
"HGTD::FlexTube", 120, 660, .175, 0,
"hgtd::CuKapton"};
226 m_cylVolPars[
"HGTD::ModuleLayer0"] = {
"HGTD::ModuleLayer0", 120, 660, 3.75, 0,
"std::Air"};
227 m_cylVolPars[
"HGTD::ModuleLayer1"] = {
"HGTD::ModuleLayer1", 120, 660, 3.75, 0,
"std::Air"};
228 m_cylVolPars[
"HGTD::ModuleLayer2"] = {
"HGTD::ModuleLayer2", 120, 660, 3.75, 0,
"std::Air"};
229 m_cylVolPars[
"HGTD::ModuleLayer3"] = {
"HGTD::ModuleLayer3", 120, 660, 3.75, 0,
"std::Air"};
230 m_cylVolPars[
"HGTD::CoolingPlate"] = {
"HGTD::CoolingPlate", 120, 920, 3, 0,
"std::Aluminium"};
231 m_cylVolPars[
"HGTD::SupportPlate"] = {
"HGTD::SupportPlate", 120, 660, .5, 0,
"std::Aluminium"};
232 m_cylVolPars[
"HGTD::ToleranceFront"] = {
"HGTD::ToleranceFront", 120, 660, 1, 0,
"std::Air"};
233 m_cylVolPars[
"HGTD::ToleranceBack"] = {
"HGTD::ToleranceBack", 120, 660, 1, 0,
"std::Air"};
234 m_cylVolPars[
"HGTD::ToleranceMid"] = {
"HGTD::ToleranceMid", 120, 660, 1, 0,
"std::Air"};
235 m_cylVolPars[
"HGTD::ModeratorIn"] = {
"HGTD::ModeratorIn", 120, 900, 15, 0,
"hgtd::BoratedPolyethelyne"};
236 m_cylVolPars[
"HGTD::ModeratorOut"] = {
"HGTD::ModeratorOut", 120, 1100, 10, 0,
"hgtd::BoratedPolyethelyne"};
237 m_cylVolPars[
"HGTD::BackCover"] = {
"HGTD::BackCover", 120, 1100, 4, 0,
"hgtd::CFiberSupport"};
238 m_cylVolPars[
"HGTD::PeriphElec"] = {
"HGTD::PeriphElec", 674, 900, 1, 2,
"hgtd::FEBoards"};
240 m_cylVolPars[
"HGTD::InnerRCover1"] = {
"HGTD::InnerRCover1", 110., 111., 105./2, -10.,
"hgtd::CFRP"};
244 GeoMaterial* innerRCoverBulkMaterial =
new GeoMaterial(
"hgtd::AerogelAndHoneycomb", 0.17*(
CLHEP::gram /
CLHEP::cm3));
248 m_cylVolPars[
"HGTD::InnerRCover2"] = {
"HGTD::InnerRCover2", 111., 119., 105./2, -10.,
"hgtd::AerogelAndHoneycomb"};
249 m_cylVolPars[
"HGTD::InnerRCover3"] = {
"HGTD::InnerRCover3", 119., 120., 105./2, -10.,
"hgtd::CFRP"};
250 m_cylVolPars[
"HGTD::OuterRCover"] = {
"HGTD::OuterRCover", 980., 1000., 82./2, -6.5,
"hgtd::Peek"};
251 m_cylVolPars[
"HGTD::PeripheralCoolingLines"] = {
"HGTD::PeripheralCoolingLines", 920., 980., 3./2, 31.,
"std::SSteel"};
254 m_cylVolPars[
"HGTD::CoolingTube"] = {
"HGTD::CoolingTubes", 0, 0, 2.0, 0,
"std::Titanium"};
256 GeoMaterial* coolantMaterial =
new GeoMaterial(
"hgtd::CO2CoolantMix", 0.55*(
CLHEP::gram /
CLHEP::cm3));
260 m_cylVolPars[
"HGTD::CoolingTubeFluid"] = {
"HGTD::CoolingTubeFluid", 0, 0, 1.5, 0,
"hgtd::CO2CoolantMix"};
288 std::string
name = isPositiveSide ?
"HGTD_PositiveEndcap" :
"HGTD_NegativeEndcap";
289 GeoLogVol* world_logical_hgtd =
new GeoLogVol(
name.c_str(), world_solid_hgtd,
292 return world_logical_hgtd;
298 ATH_MSG_INFO(
"**************************************************");
299 ATH_MSG_INFO(
" Building HGTD geometry , side = " << bPos <<
" ");
300 ATH_MSG_INFO(
"**************************************************" );
302 GeoFullPhysVol* HGTDparent =
new GeoFullPhysVol( logicalEnvelope );
305 double motherHalfZ = ((GeoTube*) HGTDparent->getLogVol()->getShape())->getZHalfLength();
306 double modulePackageHalfZtot = 3.5/2 + 4./2;
313 std::vector<std::string> hgtdVolumes;
314 hgtdVolumes.push_back(
"HGTD::ModeratorOut");
315 hgtdVolumes.push_back(
"HGTD::BackCover");
316 hgtdVolumes.push_back(
"HGTD::ToleranceBack");
317 hgtdVolumes.push_back(
"HGTD::ModeratorIn");
319 hgtdVolumes.push_back(
"HGTD::ModuleLayer3");
320 hgtdVolumes.push_back(
"HGTD::SupportPlate");
321 hgtdVolumes.push_back(
"HGTD::CoolingPlate");
322 hgtdVolumes.push_back(
"HGTD::SupportPlate");
323 hgtdVolumes.push_back(
"HGTD::ModuleLayer2");
325 hgtdVolumes.push_back(
"HGTD::ToleranceMid");
327 hgtdVolumes.push_back(
"HGTD::ModuleLayer1");
328 hgtdVolumes.push_back(
"HGTD::SupportPlate");
329 hgtdVolumes.push_back(
"HGTD::CoolingPlate");
330 hgtdVolumes.push_back(
"HGTD::SupportPlate");
331 hgtdVolumes.push_back(
"HGTD::ModuleLayer0");
333 hgtdVolumes.push_back(
"HGTD::ToleranceFront");
334 hgtdVolumes.push_back(
"HGTD::FrontCover");
336 hgtdVolumes.push_back(
"HGTD::InnerRCover1");
337 hgtdVolumes.push_back(
"HGTD::InnerRCover2");
338 hgtdVolumes.push_back(
"HGTD::InnerRCover3");
339 hgtdVolumes.push_back(
"HGTD::OuterRCover");
340 hgtdVolumes.push_back(
"HGTD::PeripheralCoolingLines");
354 std::vector<double> flexSheetInnerR;
355 double currentInnerR = 144.;
356 for (
int flexSheet = 0; flexSheet < 8; flexSheet++) {
357 flexSheetInnerR.push_back(currentInnerR);
359 currentInnerR +=
m_boxVolPars[
"HGTDModule0"].xHalf*2 * (2 + 2 * (flexSheet < 4 ? 0.2 : 0.8) );
363 GeoPhysVol* flexPackagePhysical[2] = {};
364 for (
int flexVolume = 0; flexVolume < 2; flexVolume++) {
365 std::vector<double> rInner = flexSheetInnerR;
366 if (flexVolume)
reverse(rInner.begin(), rInner.end());
368 GeoTube* flexPackageSolid =
new GeoTube(packagePars.
rMin, packagePars.
rMax, packagePars.
zHalf);
370 flexPackagePhysical[flexVolume] =
new GeoPhysVol(flexPackageLogical);
372 double flexZoffset = packagePars.
zHalf - flexPars.
zHalf;
373 for (
int flexSheet = 0; flexSheet < 8; flexSheet++) {
374 GeoTube* hgtdFlexSolid =
new GeoTube(rInner[flexSheet], flexPars.
rMax, flexPars.
zHalf);
375 GeoLogVol* hgtdFlexLogical =
new GeoLogVol(
"HGTD::FlexTube"+
std::to_string(flexSheet),
377 GeoPhysVol* hgtdFlexPhysical =
new GeoPhysVol(hgtdFlexLogical);
378 flexPackagePhysical[flexVolume]->add(
new GeoTransform(GeoTrf::TranslateZ3D(flexZoffset)));
379 flexPackagePhysical[flexVolume]->add(hgtdFlexPhysical);
381 ATH_MSG_DEBUG(
"Flex layer (" << (flexSheet ?
"front" :
"back") <<
")" << flexSheet <<
", Rmin = " << std::setw(5)
382 << rInner[flexSheet] <<
" mm, flexZoffset = " << flexZoffset <<
" mm" );
392 std::vector<double> coolingTubeRadii;
393 double coolingTubeRadius = 130.;
394 coolingTubeRadii.push_back(coolingTubeRadius);
398 ATH_MSG_INFO(
"Will now calculate cooling-loop positions for the two-ring layout");
399 for (
int i = 0;
i < 18;
i++) {
400 coolingTubeRadius += (418-130.)/18;
401 coolingTubeRadii.push_back(coolingTubeRadius);
403 for (
int i = 0;
i < 12;
i++) {
404 coolingTubeRadius += (658-418.)/14;
405 coolingTubeRadii.push_back(coolingTubeRadius);
407 coolingTubeRadius = 710.;
408 coolingTubeRadii.push_back(coolingTubeRadius);
409 for (
int i = 0;
i < 7;
i++) {
410 coolingTubeRadius += (890-710.)/6;
411 coolingTubeRadii.push_back(coolingTubeRadius);
415 ATH_MSG_INFO(
"Will now calculate cooling-loop positions for the three-ring layout");
417 int numberOfLoops = 34;
418 float loopDistance = (674.-130.)/numberOfLoops;
419 for (
int i = 0;
i < numberOfLoops;
i++) {
420 coolingTubeRadius += loopDistance;
421 coolingTubeRadii.push_back(coolingTubeRadius);
424 coolingTubeRadius = 720;
425 coolingTubeRadii.push_back(coolingTubeRadius);
427 loopDistance = (900.-720.)/numberOfLoops;
428 for (
int i = 0;
i < numberOfLoops;
i++) {
429 coolingTubeRadius += loopDistance;
430 coolingTubeRadii.push_back(coolingTubeRadius);
433 ATH_MSG_DEBUG(
"Cooling tubes will be created at the following radii (" << coolingTubeRadii.size() <<
" in total):");
434 for (
size_t i = 0;
i < coolingTubeRadii.size();
i++) {
444 GeoTube* periphElec_solid =
new GeoTube(periphElPars.
rMin, periphElPars.
rMax, periphElPars.
zHalf);
446 GeoPhysVol* periphElec_phys =
new GeoPhysVol(periphElec_log);
448 std::array< GeoPhysVol*, 4 > moduleLayerPhysical = {};
455 double zModuleLayerF = 0.;
456 double zModuleLayerB = 0.;
457 for (
size_t vol = 0; vol < hgtdVolumes.size(); vol++) {
459 std::string
v = hgtdVolumes[vol];
468 if (
v.substr(9,8) !=
"erRCover" &&
v !=
"HGTD::PeripheralCoolingLines") {
469 std::string vPrev = hgtdVolumes[vol-1];
475 if (
v.substr(0,15) ==
"HGTD::Tolerance")
continue;
478 if (
v.substr(0,17) ==
"HGTD::ModuleLayer")
484 GeoPhysVol* hgtdSubVolumePhysical =
new GeoPhysVol(hgtdSubVolumeLogical);
487 if (
v ==
"HGTD::CoolingPlate") {
491 HGTDparent->add(
new GeoTransform(GeoTrf::TranslateZ3D(
m_cylVolPars[
v].zOffsetLocal +
pow(-1,
side)*zOffsetPeriphElec)));
492 HGTDparent->add(periphElec_phys);
496 for (
size_t i = 0;
i < coolingTubeRadii.size();
i++) {
498 GeoTorus* coolingTubeSolid =
new GeoTorus(
m_cylVolPars[
"HGTD::CoolingTubeFluid"].zHalf,
m_cylVolPars[
"HGTD::CoolingTube"].zHalf,
499 coolingTubeRadii[
i], 0, 2*
M_PI);
500 GeoLogVol* coolingTubeLogical =
new GeoLogVol(
"HGTD::CoolingTube", coolingTubeSolid,
502 GeoPhysVol* coolingTubePhysical =
new GeoPhysVol(coolingTubeLogical);
503 hgtdSubVolumePhysical->add(coolingTubePhysical);
505 GeoTorus* coolingFluidSolid =
new GeoTorus(0,
m_cylVolPars[
"HGTD::CoolingTubeFluid"].zHalf,
506 coolingTubeRadii[
i], 0, 2*
M_PI);
507 GeoLogVol* coolingFluidLogical =
new GeoLogVol(
"HGTD::CoolingFluid", coolingFluidSolid,
509 GeoPhysVol* coolingFluidPhysical =
new GeoPhysVol(coolingFluidLogical);
510 hgtdSubVolumePhysical->add(coolingFluidPhysical);
515 if (
v.substr(0,17) ==
"HGTD::ModuleLayer") {
521 bool Lside =
layer % 2;
523 zFlex = -modulePackageHalfZtot +
m_cylVolPars[
"HGTD::FlexPackage"].zHalf;
524 zModuleLayerF = modulePackageHalfZtot - modulePackageHalfZ;
527 zFlex = modulePackageHalfZtot -
m_cylVolPars[
"HGTD::FlexPackage"].zHalf;
528 zModuleLayerB = -modulePackageHalfZtot + modulePackageHalfZ;
532 hgtdSubVolumePhysical->add(
new GeoTransform(GeoTrf::TranslateZ3D(zFlex)));
533 hgtdSubVolumePhysical->add(flexPackagePhysical[(Lside ? 0 : 1)]);
537 HGTDparent->add(
new GeoTransform( GeoTrf::TranslateZ3D(
m_cylVolPars[
v].zOffsetLocal) *
541 HGTDparent->add( hgtdSubVolumePhysical );
542 moduleLayerPhysical[
layer] = hgtdSubVolumePhysical;
546 HGTDparent->add(
new GeoTransform(GeoTrf::TranslateZ3D(
m_cylVolPars[
v].zOffsetLocal)));
547 HGTDparent->add(hgtdSubVolumePhysical);
552 <<
" ), local z = " << std::setw(6) <<
m_cylVolPars[
v].zOffsetLocal
555 <<
" mm, DZ = " << std::setw(5) <<
m_cylVolPars[
v].zHalf <<
" mm" );
564 std::vector<std::string> moduleVolumes;
565 moduleVolumes.push_back(
"HGTD::GlueAsic");
566 moduleVolumes.push_back(
"HGTD::ASIC");
567 moduleVolumes.push_back(
"HGTD::LGADInactive");
568 moduleVolumes.push_back(
"SensorPlaceHolder");
569 moduleVolumes.push_back(
"HGTD::GlueSensor");
570 moduleVolumes.push_back(
"HGTD::Hybrid");
571 moduleVolumes.push_back(
"HGTD::ModuleSpace");
573 int endcap = bPos ? +2 : -2;
574 double thickness = 2.*
m_boxVolPars[
"HGTDSiSensor0"].zHalf;
582 unsigned int maxRows = 21;
593 int Lside =
layer % 2;
595 std::vector<std::string> volumes = moduleVolumes;
596 if ( Lside != 0 )
reverse( volumes.begin(), volumes.end() );
605 double moduleHalfWidth =
m_boxVolPars[moduleName].xHalf;
606 double moduleHalfHeight =
m_boxVolPars[moduleName].yHalf;
612 for (
int q = 0;
q < 4;
q++) {
613 float quadrot =
q*90.;
615 for (
unsigned int row = 0;
row < maxRows;
row ++ ) {
616 std::vector< ModulePosition > ModsPerRow = tmpQuadrant[
row ];
619 if (
m_outputIdfr &&
q == 0 ) std::cout <<
" Row #"<<
row + 1 <<
" :: " << ModsPerRow.size() << std::endl;
621 for (
unsigned int mod = 0;
mod < ModsPerRow.size();
mod ++ ) {
624 double myx = -9999999.9 , myy = -9999999.9 , myrot = -9999999.9;
625 int myphi = -1 , myeta = - 1;
626 std::string module_string =
formModuleName(
layer,
q, maxRows,
row,
mod,
module, myx, myy, myrot, myphi, myeta );
628 if ( module_string ==
"" || myrot == -9999999.9 || myeta == -1 )
629 ATH_MSG_WARNING (
" Please check the module at layer "<<
layer <<
" quadrant " <<
q <<
" row "<<
row <<
" mod " <<
mod <<
" not well retrieved ! " );
632 GeoBox* moduleSolid =
new GeoBox( moduleHalfWidth, moduleHalfHeight, modulePackageHalfZ);
633 GeoLogVol* moduleLogical =
new GeoLogVol( moduleName + module_string, moduleSolid,
m_materialMgr->
getMaterial(
"std::Air"));
634 GeoFullPhysVol* modulePhysical =
new GeoFullPhysVol( moduleLogical );
637 if (
q == 0 &&
row == 0 &&
mod == 0 )
638 ATH_MSG_DEBUG(
"Will now build up an individual HGTD module of layer " <<
layer <<
" and quadrant " <<
q <<
" (" << module_string <<
")" );
642 if (volumes[
comp] ==
"SensorPlaceHolder") volumes[
comp] = sensorName;
644 std::string
c = volumes[
comp];
649 std::string cPrev = volumes[
comp-1];
654 if (volumes[
comp] ==
"HGTD::ModuleSpace")
continue;
660 double xOffsetLocal = moduleHalfWidth - comp_halfx;
663 GeoBox* sensorCompSolidVol =
new GeoBox(comp_halfx, comp_halfy,
m_boxVolPars[
c].zHalf);
667 GeoLogVol* sensorCompLogicalVol =
new GeoLogVol(
m_boxVolPars[
c].
name+attach, sensorCompSolidVol,
669 GeoFullPhysVol* sensorCompPhysicalVol =
new GeoFullPhysVol(sensorCompLogicalVol);
671 if (volumes[
comp] == sensorName) {
673 Identifier idwafer = hgtdId->
wafer_id( endcap,
layer, myphi, myeta );
678 <<
" upon HGTD_ID => ec: " << endcap <<
", layer: " <<
layer <<
", quadrant: " <<
q
679 <<
", row: " << myphi <<
", module: "<< myeta );
680 ATH_MSG_DEBUG(
" HGTD Module: " <<
m_boxVolPars[
c].
name+module_string <<
", posX: " << myx <<
", posY: " << myy <<
", rot: " << quadrot + myrot );
687 GeoAlignableTransform* xform =
new GeoAlignableTransform(sensorTransform);
689 modulePhysical->add( xform );
690 modulePhysical->add( sensorCompPhysicalVol );
695 modulePhysical->add(
new GeoTransform(GeoTrf::TranslateZ3D(
m_boxVolPars[
c].zOffsetLocal)*GeoTrf::TranslateX3D(xOffsetLocal)));
696 modulePhysical->add(sensorCompPhysicalVol);
700 if (
mod == 0 &&
q == 0 && volumes[
comp] != sensorName )
702 <<
" ), in-sensor-layer local z = " << std::setw(7) <<
m_boxVolPars[
c].zOffsetLocal <<
" mm"
703 <<
", DX = " << std::setw(5) <<
m_boxVolPars[
c].xHalf <<
" mm"
704 <<
", DY = " << std::setw(5) <<
m_boxVolPars[
c].yHalf <<
" mm"
705 <<
", DZ = " << std::setw(5) <<
m_boxVolPars[
c].zHalf <<
" mm" );
708 double zModule = ( Lside == 0 ? zModuleLayerF : zModuleLayerB );
710 GeoTransform* moduleTransform =
new GeoTransform( GeoTrf::TranslateZ3D(zModule) *
711 GeoTrf::TranslateX3D(myx) *
712 GeoTrf::TranslateY3D(myy) *
714 moduleLayerPhysical[
layer]->add( moduleTransform );
715 moduleLayerPhysical[
layer]->add( modulePhysical );
724 ATH_MSG_INFO(
"**************************************************" );
725 ATH_MSG_INFO(
" Done building HGTD with " << totMod <<
" modules " );
726 ATH_MSG_INFO(
"**************************************************" );
735 std::array< PositionsInQuadrant, 4 > positions;
749 positions[ 0 ] = d0q0front;
750 positions[ 1 ] = d0q0back;
751 positions[ 2 ] = d1q0front;
752 positions[ 3 ] = d1q0back;
767 double& myx,
double& myy,
double& myrot,
int&
phi,
int&
eta ) {
769 std::string module_string =
"";
781 myrot =
module.phiRotation;
782 phi = quadrant*21 +
row + 1;
789 double rot =
module.flipped ? 90. : 0.;
791 double moduleRotation = 0;
795 if ( quadrant%2 == 0 && myrow <= 15) moduleRotation = 180.;
796 else if (quadrant%2 == 1 && myrow > 15) moduleRotation = 180.;
798 eta = ( quadrant*maxrows ) + myrow;
800 myrot = moduleRotation + rot;
804 return module_string;
811 bool isBackside = (
layer % 2);
814 for (
size_t row = 0;
row <= maxRow;
row++) {
815 if (
row == 13 )
continue;
817 rowsInQuad[
row > 13 ?
row - 1 :
row ] = rowModulePositions;
822 for (
size_t row = 0;
row < maxRow;
row++) {
824 rowsInQuad[
row ] = rowModulePositions;
832 for (
size_t row = 0;
row < inquad.size();
row ++ ) {
833 std::vector<ModulePosition> modulePositions = inquad[
row ];
834 for (
size_t mod = 0;
mod < modulePositions.size();
mod++ ) {
840 modulePositions[
mod] = mirror;
843 rowsInQuad[ inquad.size() -
row - 1 ] = modulePositions;
852 int index_XYcoord_change = 14;
855 float halfWidth = .5*40., halfHeight = .5*21.8;
856 float midR = 230., midR2 = 470.5, maxRcut = 660., maxOuterR = 670.;
858 if (
row == 21 and back==1) {
861 float readoutRowSpace = 1.0;
862 bool extrude = ( (
row == 6 ||
row == 18 ) && !back ) ||
863 ( (
row == 2 ||
row == 11 ||
row == 12 ||
row == 17 ) && back );
867 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,
868 130., 114.7, 131.45, 164.45, 216.35, 205.45, 257.35 };
870 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,
871 122., 122.7, 123.45, 172.45, 205.45, 216.35, 246.45 };
876 if ( ( (
row == 1 ||
row == 5 ||
row == 15 ||
row == 19 ) && ! back ) ||
877 ( (
row == 0 ||
row == 8 ||
row == 16 ||
row == 18 ||
row == 21 ) && back )
879 if (
row == 17 ) useCorner = 2;
881 float backshift = 6.;
885 float tailModCorrection[ 22 ][ 19 ];
886 for (
int r = 0;
r < 22;
r ++ )
887 for (
int m = 0;
m < 19;
m ++ ) tailModCorrection[
r][
m] = 0.;
888 tailModCorrection[11][4] = tailModCorrection[12][2] = 10.;
891 float spaceSmallR = 3.7 , spaceMediumR = 6.6, spaceLargeR = 12.7;
893 float backsideSmallR = spaceSmallR;
894 float backsideMediumR = spaceMediumR;
895 float backsideLargeR = spaceLargeR;
897 float extendedWidth = readoutRowSpace + 2.*halfWidth;
899 float posRadius = 0.;
900 float posOfLastPlacedModule = 0.;
901 int moduleCounter = 0;
902 std::vector< ModulePosition > rowModulePositions;
904 float effectiveRow =
row;
906 if (
row == index_XYcoord_change ) effectiveRow = 13;
907 if (
row > index_XYcoord_change ) effectiveRow -= ( index_XYcoord_change + 1 );
910 float rowCentPos = 0.5*extendedWidth*( 2*effectiveRow + 1 );
912 if ( extrude ) maxRcut = maxOuterR;
913 while ( posRadius < maxRcut ) {
916 float modPos_row = -999.;
919 if ( moduleCounter == 0 ) {
920 modPos_row = ( back ? ModStartBack[
row] : ModStarting[
row] );
921 modPos_row += halfHeight;
925 float prevX = rowModulePositions[ moduleCounter - 1 ].x;
926 float prevY = rowModulePositions[ moduleCounter - 1 ].y;
927 float spacing = back ? backsideSmallR : spaceSmallR;
930 float ringCrossRcorner = std::sqrt( ( prevY + halfHeight)*( prevY + halfHeight) +
931 ( prevX + halfWidth )*( prevX + halfWidth ) );
932 float ringCrossRcenter = std::sqrt( prevY*prevY + prevX*prevX );
934 bool tuned_center = (
row == 3 && ( moduleCounter == 3 && !back ) ) ||
935 (
row == 20 && moduleCounter == 8 && !back ) ||
936 (
row == 21 && moduleCounter == 6 && back );
937 if ( useCorner == 2 ) {
938 if ( ( moduleCounter == 3 && ! back ) || ( ( moduleCounter == 3 || moduleCounter == 4 ) && back ) ) {
939 ringCrossRcenter -= backshift;
940 if ( ringCrossRcenter > midR && ringCrossRcenter <= midR2 ) spacing = back ? backsideMediumR : spaceMediumR;
941 if ( ringCrossRcenter > midR2 ) spacing = back ? backsideLargeR : spaceLargeR;
944 if ( ringCrossRcorner > midR && ringCrossRcorner <= midR2 ) spacing = back ? backsideMediumR : spaceMediumR;
945 if ( ringCrossRcorner > midR2 ) spacing = back ? backsideLargeR : spaceLargeR;
948 else if ( useCorner == 1 ) {
949 if ( ringCrossRcorner > midR && ringCrossRcorner <= midR2 ) spacing = back ? backsideMediumR : spaceMediumR;
950 if ( ringCrossRcorner > midR2 ) spacing = back ? backsideLargeR : spaceLargeR;
953 if ( tuned_center ) ringCrossRcenter -= backshift;
954 if ( ringCrossRcenter > midR && ringCrossRcenter <= midR2 ) spacing = back ? backsideMediumR : spaceMediumR;
955 if ( ringCrossRcenter > midR2 ) spacing = back ? backsideLargeR : spaceLargeR;
958 modPos_row = posOfLastPlacedModule + 2.*halfHeight + spacing;
960 if ( back && moduleCounter < 19) modPos_row -= tailModCorrection[
row ][ moduleCounter ];
965 posRadius = std::sqrt( ( rowCentPos + halfWidth )*( rowCentPos + halfWidth ) +
966 ( modPos_row + halfHeight)*( modPos_row + halfHeight ) );
967 if ( posRadius > maxRcut ) {
968 ATH_MSG_DEBUG(
" row " <<
row <<
" finished with " << moduleCounter <<
" modules ");
975 ModulePosition moduFlipped = { rowCentPos, modPos_row, 90.,
true,
row, moduleCounter };
978 if (
row > index_XYcoord_change ) rowModulePositions.push_back( modu );
979 else rowModulePositions.push_back( moduFlipped );
983 <<
" Module " << moduleCounter + 1 <<
" at (x,y) : "
984 << (
row > index_XYcoord_change ? rowModulePositions.back().x - halfHeight : rowModulePositions.back().x ) <<
", "
985 << (
row > index_XYcoord_change ? rowModulePositions.back().y : rowModulePositions.back().y - halfHeight ) );
987 posOfLastPlacedModule = modPos_row;
991 if (
m_outputIdfr ) std::cout <<
"Total #Module " << rowModulePositions.size() <<
" at original row " <<
row << std::endl;
993 return rowModulePositions;
1006 unsigned int numrow = quadrant->size();
1007 for (
unsigned int r = 0;
r < numrow;
r ++ ) {
1008 unsigned int idx =
r > 13 ? 13 + numrow -
r :
r;
1010 <<
" : "<< numrow );
1011 tmpQuadrant[
idx ] = quadrant->at(
r );
1012 if (
idx !=
r ) xchng++;
1015 for (
unsigned int r = 0;
r < numrow;
r++ )
1016 quadrant->at(
r ) = tmpQuadrant[ numrow - 1 -
r ];
1022 for (
auto&
layer : arr) {
1034 double phiPitch = 1.3;
1035 double etaPitch = 1.3;
1039 int circuitsPerColumn = 1;
1040 int circuitsPerRow = 2;
1043 int cellColumnsPerCircuit = 15;
1044 int cellRowsPerCircuit = 15;
1046 int diodeColumnsPerCircuit = cellColumnsPerCircuit;
1047 int diodeRowsPerCircuit = cellRowsPerCircuit;
1051 normalCell, diodeColumnsPerCircuit, 0);
1053 singleRow, 2*diodeRowsPerCircuit, 0);
1058 circuitsPerColumn, circuitsPerRow,
1059 cellColumnsPerCircuit, cellRowsPerCircuit,
1060 diodeColumnsPerCircuit, diodeRowsPerCircuit,
1075 std::vector<ModulePosition> modulePositions;
1076 double posOfLastPlacedModule = 0.;
1084 int rowForInnerRadius =
row;
1085 if (
row == 17) rowForInnerRadius = 0;
1086 if (
row == 16) rowForInnerRadius = 1;
1089 double moduleWidth =
m_boxVolPars[
"HGTDModule0"].yHalf*2;
1090 double moduleHeight =
m_boxVolPars[
"HGTDModule0"].xHalf*2;
1091 double rInner =
m_cylVolPars[
"HGTD::ModuleLayer0"].rMin;
1097 double rowCenterPos = (moduleWidth + rowSpaceSide)*(rowForInnerRadius + 0.5);
1099 double modulePosAlongRow = -99.;
1103 if (rowForInnerRadius < 3) {
1104 modulePosAlongRow = std::sqrt(
pow(rInner, 2) -
pow((moduleWidth + rowSpaceSide)*rowForInnerRadius, 2) )
1109 if (back && (rowCenterPos - moduleWidth/2 > rMid)) {
1112 modulePosAlongRow = 2*(moduleWidth + rowSpaceSide) + moduleHeight/2 + back*backSpacing;
1122 float innermostCornerR = std::sqrt(
pow(prev.
y - moduleHeight/2, 2) +
pow(prev.
x - moduleWidth/2, 2) ) + 1.;
1123 if (innermostCornerR > rMid) {
1128 double startOfSpaceAlongRow = std::sqrt(
pow(prev.
y + moduleHeight/2, 2) +
pow(prev.
x - moduleWidth/2, 2) ) - 2;
1129 if (startOfSpaceAlongRow > rMid) {
1134 if (!back && rowForInnerRadius < 8 &&
module < 3) {
1138 double maxRcut = rOuter+20;
1141 if(
row == 8 &&
module > 12) spacing -= 4;
1147 else if (
row == 12 && back) {
1152 if (!back &&
module > 6 ) spacing -= 8.5;
1153 else if (back &&
module > 5) spacing -= 2;
1159 else if (
row == 15) {
1163 modulePosAlongRow = posOfLastPlacedModule + moduleHeight + spacing;
1166 if ( std::sqrt(
pow(rowCenterPos + moduleWidth/2, 2) +
pow(modulePosAlongRow + moduleHeight/2, 2) ) > maxRcut) {
1171 modulePositions.push_back(
m);
1172 posOfLastPlacedModule = modulePosAlongRow;
1179 for (
size_t i=0;
i < modulePositions.size();
i++) {
1187 modulePositions[
i] = rotated;
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 <<
")" );
1196 return modulePositions;