ATLAS Offline Software
Loading...
Searching...
No Matches
LArG4::Barrel::Geometry Class Reference

#include <LArBarrelGeometry.h>

Inheritance diagram for LArG4::Barrel::Geometry:
Collaboration diagram for LArG4::Barrel::Geometry:

Public Member Functions

 Geometry (const std::string &name, ISvcLocator *pSvcLocator)
virtual ~Geometry ()=default
virtual StatusCode initialize () override final
virtual StatusCode finalize () override final
virtual void initializeForSDCreation () override final
virtual LArG4Identifier CalculateIdentifier (const G4Step *) const override final
virtual LArG4Identifier CalculateSuperResolutionIdentifier (const G4Step *a_step) const override final
virtual void findCell (CalcData &currentCellData, const double &x, const double &y, const double &z, const double &r, const double &eta, const double &phi, const bool detail) const override final

Protected Member Functions

 Geometry ()

Private Member Functions

LArG4Identifier CalculateECAMIdentifier (const G4Step *, const G4int indEcam, const bool inSTAC=true, int zside=1) const
bool CheckLArIdentifier (int sampling, int region, int eta, int phi) const
bool CheckDMIdentifier (int type, int sampling, int region, int eta, int phi) const
double Distance_Ele (const double &x, const double &y, const int &PhiC, int &Num_Straight, const int &Num_Coude, double &xl) const
double Distance_Abs (const double &x, const double &y, const int &nabs, const int &Num_Straight, const int &Num_Coude) const
G4int SampSeg (G4double, G4double, G4double, G4int &, G4int &, G4int &, G4int &, G4int &) const
void GetRphi ()
 phi vs r of first absorber in nominal geometry
G4double Phi0 (G4double) const
G4int PhiGap (const double &, const double &, const double &) const

Private Attributes

Gaudi::Property< std::string > m_detectorName {this, "DetectorName", "LArMgr"}
Gaudi::Property< bool > m_testbeam {this, "TestBeam", false}
Gaudi::Property< int > m_nBinsEtaSR {this, "nBinsEtaSR", 16, "Number of SR sub-cell bins in eta"}
Gaudi::Property< int > m_nBinsPhiSR {this, "nBinsPhiSR", 16, "Number of SR sub-cell bins in phi"}
Gaudi::Property< int > m_nBinsRadiusSR {this, "nBinsRadiusSR", 5, "Number of SR sub-cell bins in radius"}
G4String m_ecamName
double m_rMinAccordion {0.}
double m_rMaxAccordion {0.}
double m_zMinBarrel {0.}
double m_zMaxBarrel {0.}
double m_zMaxBarrelDMMargin {0.}
double m_etaMaxBarrel {0.}
int m_NCellTot {0}
int m_NCellMax {0}
int m_Nbrt {0}
int m_Nbrt1 {0}
double m_gam0 {0.}
double m_rint_eleFib {0.}
double * m_rc {nullptr}
double * m_phic {nullptr}
double * m_xc {nullptr}
double * m_yc {nullptr}
double * m_delta {nullptr}
int m_parity {0}
const LArCoudeElectrodesm_coudeelec {nullptr}
const LArCoudeAbsorbersm_coudeabs {nullptr}
const LArStraightElectrodesm_electrode {nullptr}
const LArStraightAbsorbersm_absorber {nullptr}
bool m_iflSAG {false}
G4int m_NRphi {0}
G4double m_Rmin {0.}
G4double m_Rmax {0.}
G4double m_Rphi [5000] = {0}
G4double m_dR {0.}

Detailed Description

Definition at line 36 of file LArBarrelGeometry.h.

Constructor & Destructor Documentation

◆ Geometry() [1/2]

LArG4::Barrel::Geometry::Geometry ( const std::string & name,
ISvcLocator * pSvcLocator )

Definition at line 43 of file LArBarrelGeometry.cxx.

44 : base_class(name, pSvcLocator)
45 {
46 }

◆ ~Geometry()

virtual LArG4::Barrel::Geometry::~Geometry ( )
virtualdefault

◆ Geometry() [2/2]

LArG4::Barrel::Geometry::Geometry ( )
protected

Member Function Documentation

◆ CalculateECAMIdentifier()

LArG4Identifier LArG4::Barrel::Geometry::CalculateECAMIdentifier ( const G4Step * a_step,
const G4int indEcam,
const bool inSTAC = true,
int zside = 1 ) const
private

Definition at line 1133 of file LArBarrelGeometry.cxx.

1134 {
1135
1136 LArG4Identifier result = LArG4Identifier();
1137
1138 // Get all the information about the step
1139
1140 const G4StepPoint *thisStepPoint = a_step->GetPreStepPoint();
1141 const G4StepPoint *thisStepBackPoint = a_step->GetPostStepPoint();
1142 const G4ThreeVector startPoint = thisStepPoint->GetPosition();
1143 const G4ThreeVector endPoint = thisStepBackPoint->GetPosition();
1144 const G4ThreeVector p = (thisStepPoint->GetPosition() + thisStepBackPoint->GetPosition()) * 0.5;
1145
1146#ifdef DEBUGHITS
1147 ATH_MSG_VERBOSE("Position of the step in the ATLAS frame (x,y,z) --> " << p.x() << " " << p.y() << " " << p.z());
1148 ATH_MSG_VERBOSE("Eta and Phi in the ATLAS frame --> " << p.eta() << " " << p.phi());
1149#endif
1150
1151 // BACK directly into the LOCAL half_Barrel. All the variables in this LOCAL framework get the SUFFIX Zpos
1152
1153 const G4NavigationHistory* g4navigation = thisStepPoint->GetTouchable()->GetHistory();
1154 const G4AffineTransform transformation = g4navigation->GetTransform(indECAM);
1155 const G4ThreeVector startPointinLocal = transformation.TransformPoint(startPoint);
1156 const G4ThreeVector endPointinLocal = transformation.TransformPoint (endPoint);
1157 const G4ThreeVector midinLocal = (startPointinLocal+endPointinLocal)*0.5;
1158
1159#ifdef DEBUGHITS
1160 ATH_MSG_VERBOSE("Position of the step in the LOCAL frame (x,y,z) --> " << midinLocal.x() << " " << midinLocal.y() << " " << midinLocal.z());
1161 ATH_MSG_VERBOSE("Eta and Phi of the step in LOCAL frame --> " << midinLocal.eta() << " " << midinLocal.phi());
1162#endif
1163
1164 // coordinates in the local frame
1165
1166 const G4double xZpos = midinLocal.x();
1167 const G4double yZpos = midinLocal.y();
1168 const G4double zZpos = midinLocal.z();
1169 const G4double etaZpos = midinLocal.pseudoRapidity();
1170 const G4double phiZpos = (midinLocal.phi()<0.) ? midinLocal.phi() + 2.*M_PI : midinLocal.phi();
1171 const G4double radius2Zpos = xZpos*xZpos + yZpos*yZpos;
1172 const G4double radiusZpos = sqrt(radius2Zpos);
1173
1174 CalcData currentCellData;
1175 if (m_testbeam) {
1176 currentCellData.zSide = 1;
1177 }
1178 else {
1179 currentCellData.zSide = zside;
1180 }
1181
1182 // Check if the hit is in the fiducial range and in the STAC volume
1183 // if yes this is active or inactive material
1184
1185 if (inSTAC && radiusZpos >=m_rMinAccordion && radiusZpos <= m_rMaxAccordion &&
1186 zZpos <= m_zMaxBarrel && zZpos >= m_zMinBarrel && etaZpos <= m_etaMaxBarrel) {
1187
1188#ifdef DEBUGHITS
1189 ATH_MSG_VERBOSE("This hit is in the STAC volume !!!!! ");
1190#endif
1191
1192 // DETERMINATION of currentCellData.cellID,
1193 // currentCellData.zSide, currentCellData.sampling,
1194 // currentCellData.phiBin, currentCellData.etaBin,
1195 // m_stackNumID
1196 const bool MapDetail(false);
1197 this->findCell( currentCellData, xZpos, yZpos, zZpos, radiusZpos, etaZpos, phiZpos, MapDetail );
1198
1199 // adjust phi in the negative half barrel frame
1200
1201 if( currentCellData.zSide == -1 )
1202 {
1203 if( currentCellData.sampling == 1 && currentCellData.region ==0 )
1204 {
1205 currentCellData.phiBin = 31 - currentCellData.phiBin;
1206 if(currentCellData.phiBin < 0 ) currentCellData.phiBin += 64;
1207 }
1208 if( currentCellData.sampling == 1 && currentCellData.region ==1 )
1209 {
1210 currentCellData.phiBin = 127 - currentCellData.phiBin;
1211 if(currentCellData.phiBin < 0 ) currentCellData.phiBin += 256;
1212 }
1213 if( currentCellData.sampling >= 2 )
1214 {
1215 currentCellData.phiBin = 127 - currentCellData.phiBin;
1216 if(currentCellData.phiBin < 0 ) currentCellData.phiBin += 256;
1217 }
1218 }
1219
1220 // there are few hundred microns between the 4mm nominal beginning of the active region
1221 // and the real beginning of the first strip at eta=0.025/8
1222 // to avoid inactive energy with strip=0 assign this to strip=1
1223 if (currentCellData.sampling==1 && currentCellData.region==0 && currentCellData.etaBin==0) {
1224 currentCellData.etaBin=1;
1225 }
1226
1227 result << 4 // LArCalorimeter
1228 << 1 // LArEM
1229 << currentCellData.zSide
1230 << currentCellData.sampling
1231 << currentCellData.region
1232 << currentCellData.etaBin
1233 << currentCellData.phiBin;
1234
1235#ifdef DEBUGHITS
1236 ATH_MSG_VERBOSE("Here the identifier for the barrel ACTIVE ----> ");
1237 ATH_MSG_VERBOSE("eta in local frame --> " << etaZpos);
1238 ATH_MSG_VERBOSE("currentCellData.zSide ----> " << currentCellData.zSide);
1239 ATH_MSG_VERBOSE("currentCellData.sampling ----> " << currentCellData.sampling);
1240 ATH_MSG_VERBOSE("currentCellData.region ----> " << currentCellData.region);
1241 ATH_MSG_VERBOSE("currentCellData.etaBin ----> " << currentCellData.etaBin);
1242 ATH_MSG_VERBOSE("currentCellData.phiBin ----> " << currentCellData.phiBin);
1243 ATH_MSG_VERBOSE("And also etafirst ----> " << thisStepPoint->GetPosition().pseudoRapidity());
1244#endif
1245
1246 // if (!Geometry::CheckLArIdentifier(currentCellData.sampling,currentCellData.region,currentCellData.etaBin,currentCellData.phiBin)) {
1247 // ATH_MSG_ERROR(" ** Bad LAr identifier " << currentCellData.sampling << " " << currentCellData.region << " "
1248 // << currentCellData.etaBin << " " << currentCellData.phiBin);
1249 // ATH_MSG_ERROR(" x,y,z,eta,phi " << xZpos << " " << yZpos << " " << zZpos
1250 // << " " << radiusZpos << " " << etaZpos << " " << phiZpos);
1251 // }
1252
1253
1254 }
1255 // hits in dead material part
1256 else {
1257
1258 G4int sampling=0;
1259 G4int region=0;
1260 const G4int numDeadPhiBins = 64;
1261 double abs_eta = std::fabs(etaZpos);
1262 const double DM1EtaWidth = 0.1 ;
1263 const double DM1PhiWidth = 2.*M_PI / numDeadPhiBins ;
1264 currentCellData.etaBin = (G4int) ( abs_eta * (1./DM1EtaWidth) ) ;
1265 currentCellData.phiBin = (G4int) (phiZpos/ DM1PhiWidth );
1266 G4int type=1;
1267 // protect against rounding error for phi ~2pi
1268 if (currentCellData.phiBin==numDeadPhiBins) currentCellData.phiBin=currentCellData.phiBin-1;
1269
1270 // adjust phi for negative half barrel
1271
1272 if ( currentCellData.zSide == -1 ) {
1273 currentCellData.phiBin = 31 - currentCellData.phiBin;
1274 if (currentCellData.phiBin < 0 ) currentCellData.phiBin +=64 ;
1275 }
1276
1277 // material in front of the active accordion
1278 if ( radiusZpos < m_rMinAccordion ) {
1279 sampling =1 ;
1280 region = 3 ;
1281 if (currentCellData.etaBin > 14) currentCellData.etaBin=14;
1282
1283#ifdef DEBUGHITS
1284 ATH_MSG_VERBOSE("This hit is in the ECAM volume in front of the accordion (DEAD MATERIAL) !!!!! ");
1285#endif
1286
1287 } else if (radiusZpos >= m_rMaxAccordion){ // material behind the active accordion
1288 sampling = 2;
1289
1290 if (abs_eta < 1.0 ) {
1291 region = 0 ;
1292#ifdef DEBUGHITS
1293 ATH_MSG_VERBOSE("This hit is in the ECAM volume behind accordion (DEAD MATERIAL 0) !!!!! ");
1294#endif
1295 } else if ( abs_eta >= 1.0 && abs_eta < 1.5) {
1296 region = 2;
1297 currentCellData.etaBin = currentCellData.etaBin - 10; // to have etabin between 0 and 4
1298#ifdef DEBUGHITS
1299 ATH_MSG_VERBOSE("This hit is in the ECAM volume behind accordion (DEAD MATERIAL 2) !!!!! ");
1300#endif
1301 } else {
1302 ATH_MSG_ERROR(" LArBarrelGeometry: hit behind accordion at eta>1.5 !!! ");
1303 region = 2;
1304 currentCellData.etaBin = 4;
1305 }
1306
1307 } else if (zZpos <= m_zMinBarrel) { // inactive matter between two EMB halves
1308 type=2;
1309 region=0;
1310 const G4int phisave=currentCellData.phiBin;
1311 const G4bool MapDetail(false);
1312 this->findCell( currentCellData, xZpos, yZpos, zZpos, radiusZpos, etaZpos, phiZpos, MapDetail );
1313 sampling = currentCellData.sampling; // sampling as in normal definition
1314 currentCellData.etaBin=0;
1315 currentCellData.phiBin=phisave;
1316
1317 } else if (zZpos >= m_zMaxBarrel - m_zMaxBarrelDMMargin || abs_eta >= 1.40) { // inactive matter between EMB and scintillator including some margin for error
1318 if (abs_eta >1.0 && abs_eta < 1.5) {
1319 sampling=2;
1320 region=2;
1321 currentCellData.etaBin = currentCellData.etaBin - 10; // to have etabin between 0 and 4
1322 } else if (abs_eta < 1.6) {
1323 sampling=1;
1324 region=4;
1325 currentCellData.etaBin=0;
1326 } else {
1327 ATH_MSG_ERROR(" LArBarrelGeometry: hit at eta>1.6 !!! ");
1328 sampling=1;
1329 region=4;
1330 currentCellData.etaBin=0;
1331 }
1332 } else {
1333 if (!m_testbeam) {
1334 const G4double thisStepEnergyDeposit = a_step->GetTotalEnergyDeposit() * a_step->GetTrack()->GetWeight();
1335 std::ostringstream dmLog;
1336 dmLog << "LArBarrelGeometry: cannot find region for DM hit..." << std::endl;
1337 dmLog << "LArBarrelGeometry: cannot find region for DM hit..." << std::endl;
1338 dmLog << "m_zMinBarrel: " << m_zMinBarrel << std::endl;
1339 dmLog << "m_zMaxBarrel: " << m_zMaxBarrel << std::endl;
1340 dmLog << "m_rMinAccordion: " << m_rMinAccordion << std::endl;
1341 dmLog << "m_rMaxAccordion: " << m_rMaxAccordion << std::endl;
1342 dmLog << "r,z,eta,phi " << radiusZpos << " " << zZpos << " " << etaZpos << " " << phiZpos << std::endl;
1343 dmLog << "x,y,z (Atlas) " << p.x() << " " << p.y() << " " << p.z() << std::endl;
1344 dmLog << " inSTAC " << inSTAC << std::endl;
1345 dmLog << " eDeposited " << thisStepEnergyDeposit << std::endl;
1346 const G4VPhysicalVolume* vol = thisStepPoint->GetPhysicalVolume();
1347 const G4String volName = vol->GetName();
1348 dmLog << " volName " << volName << std::endl;
1349 const G4int ndep = g4navigation->GetDepth();
1350 for (G4int ii=0;ii<=ndep;ii++) {
1351 const G4VPhysicalVolume* v1 = g4navigation->GetVolume(ii);
1352 const G4String vname = v1->GetName();
1353 dmLog << "vname " << vname << std::endl;
1354 }
1355 if (thisStepEnergyDeposit > 1.*CLHEP::MeV) {
1356 ATH_MSG_ERROR(dmLog.str());
1357 } else {
1358 ATH_MSG_WARNING(dmLog.str());
1359 }
1360 }
1361 // in test beam case, we can get there for leakage on the side (in phi) of the module
1362 // in this case, we attribute an identifier like inactive material
1363 else
1364 {
1365 G4bool MapDetail=false;
1366 this->findCell( currentCellData, xZpos, yZpos, zZpos, radiusZpos, etaZpos, phiZpos, MapDetail );
1367 // ATH_MSG_ERROR(" Lateral lakage r,eta,phi " << radiusZpos << " " << etaZpos << " "
1368 // << phiZpos << " sampling/region/eta/phi " << currentCellData.sampling << " " <<
1369 // currentCellData.region << " " << currentCellData.etaBin << " " << currentCellData.phiBin);
1370 // protect against small space between z=4m and real beginning of ieta=1 in strips
1371 if (currentCellData.sampling==1 && currentCellData.region==0 && currentCellData.etaBin==0) {
1372 currentCellData.etaBin=1;
1373 // ATH_MSG_ERROR("S1R0 etabin 0 found r,z,phi local " << radiusZpos << " "
1374 // << " " << zZpos << " " << phiZpos);
1375 }
1376 result << 4 // LArCalorimeter
1377 << 1 // LArEM
1378 << currentCellData.zSide
1379 << currentCellData.sampling
1380 << currentCellData.region
1381 << currentCellData.etaBin
1382 << currentCellData.phiBin;
1383 return result;
1384 }
1385 }
1386
1387 result << 10 // LArCalorimeter
1388 << currentCellData.zSide * 4 // LArBarrel
1389 << type
1390 << sampling
1391 << region
1392 << currentCellData.etaBin
1393 << currentCellData.phiBin;
1394
1395#ifdef DEBUGHITS
1396 ATH_MSG_VERBOSE("Here the identifier for the barrel DEAD materials ---->");
1397 ATH_MSG_VERBOSE("Type ----> " << type);
1398 ATH_MSG_VERBOSE("Sampling ----> " << sampling);
1399 ATH_MSG_VERBOSE("Region ----> " << region);
1400 ATH_MSG_VERBOSE("zSide ----> " << currentCellData.zSide*4);
1401 ATH_MSG_VERBOSE("etaBin ----> " << currentCellData.etaBin);
1402 ATH_MSG_VERBOSE("phiBin ----> " << currentCellData.phiBin);
1403#endif
1404
1405 // if (!Geometry::CheckDMIdentifier(type,sampling,region,currentCellData.etaBin,currentCellData.phiBin)) {
1406 // ATH_MSG_ERROR(" ** Bad DM identifier " << type << " " << sampling << " " << region << " "
1407 // << currentCellData.etaBin << " " << currentCellData.phiBin);
1408 // ATH_MSG_ERROR("x,y,z,r,eta,phi" << xZpos << " " << yZpos << " " << zZpos <<
1409 // " " << radiusZpos << " " << etaZpos << " " << phiZpos);
1410 // }
1411
1412 }
1413
1414 return result;
1415
1416 }
#define M_PI
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Gaudi::Property< bool > m_testbeam
virtual void findCell(CalcData &currentCellData, const double &x, const double &y, const double &z, const double &r, const double &eta, const double &phi, const bool detail) const override final

◆ CalculateIdentifier()

LArG4Identifier LArG4::Barrel::Geometry::CalculateIdentifier ( const G4Step * a_step) const
finaloverridevirtual

Definition at line 936 of file LArBarrelGeometry.cxx.

937 {
938
939 // The default result is a blank identifier.
940 LArG4Identifier result = LArG4Identifier();
941
942 // Get all the required information from the current step
943 const G4NavigationHistory* g4navigation = a_step->GetPreStepPoint()->GetTouchable()->GetHistory();
944 const G4int ndep = g4navigation->GetDepth();
945 bool inSTAC = false;
946 int zside=1;
947 G4int indECAM = -999;
948
949 // Now navigate through the volumes hierarchy
950 for (G4int ii=0;ii<=ndep;ii++) {
951 const G4String& vname = g4navigation->GetVolume(ii)->GetName();
952 // FIXME Need to find a way to avoid these string-comparisons
953 if ( indECAM<0 && vname == m_ecamName ) indECAM=ii;
954 if ( !inSTAC && vname.find("STAC") !=std::string::npos) inSTAC=true;
955 if ( vname.find("NegPhysical") != std::string::npos) zside=-1;
956 }
957 if (indECAM>=0)
958 result = this->CalculateECAMIdentifier( a_step , indECAM, inSTAC, zside) ;
959 else
960 ATH_MSG_ERROR("LArBarrel::Geometry::CalculateIdentifier ECAM volume not found in hierarchy");
961
962 return result;
963 }
LArG4Identifier CalculateECAMIdentifier(const G4Step *, const G4int indEcam, const bool inSTAC=true, int zside=1) const

◆ CalculateSuperResolutionIdentifier()

LArG4Identifier LArG4::Barrel::Geometry::CalculateSuperResolutionIdentifier ( const G4Step * a_step) const
finaloverridevirtual

Definition at line 965 of file LArBarrelGeometry.cxx.

965 {
966
967 LArG4Identifier result;
968
969 // Convert step to local half-barrel coordinates
970 const G4StepPoint *preStep = a_step->GetPreStepPoint();
971 const G4StepPoint *postStep = a_step->GetPostStepPoint();
972 G4ThreeVector midGlobal = (preStep->GetPosition() + postStep->GetPosition()) * 0.5;
973
974 const G4NavigationHistory* g4nav = preStep->GetTouchable()->GetHistory();
975
976 G4int indECAM = -1;
977 const G4int ndep = g4nav->GetDepth();
978
979 for (G4int ii = 0; ii <= ndep; ++ii) {
980 if (g4nav->GetVolume(ii)->GetName() == m_ecamName) {
981 indECAM = ii;
982 break;
983 }
984 }
985
986 if (indECAM == -1) {
987 ATH_MSG_ERROR("ECAM volume not found!");
988 return result;
989 }
990
991 G4AffineTransform localTrans = g4nav->GetTransform(indECAM);
992 G4ThreeVector midLocal = localTrans.TransformPoint(midGlobal);
993
994 double x = midLocal.x(), y = midLocal.y(), z = midLocal.z();
995 double radius = sqrt(x*x + y*y);
996 double eta = midLocal.pseudoRapidity();
997 double phi = midLocal.phi() < 0 ? midLocal.phi() + 2*M_PI : midLocal.phi();
998
999 // --- Find the standard (low-resolution) cell ---
1000 CalcData currentCellData;
1001 bool MapDetail = false;
1002 findCell(currentCellData, x, y, z, radius, eta, phi, MapDetail);
1003
1004 int etaBin = currentCellData.etaBin;
1005 int phiBin = currentCellData.phiBin;
1006 int sampling = currentCellData.sampling;
1007 int region = currentCellData.region;
1008
1009 // --- Compute minimum boundaries (low resolution cell) ---
1010 double eta_min = 0.0;
1011 double delta_eta = 0.025; // default
1012 if (sampling == 1) {
1013 if (region == 0) {
1014 delta_eta = 0.003125;
1015 eta_min = etaBin * delta_eta;
1016 } else {
1017 delta_eta = 0.025;
1018 eta_min = 1.4 + etaBin * delta_eta;
1019 }
1020 } else if (sampling == 2) {
1021 delta_eta = 0.025;
1022 eta_min = etaBin * delta_eta;
1023 } else if (sampling == 3) {
1024 delta_eta = 0.05;
1025 eta_min = etaBin * delta_eta;
1026 }
1027
1028 double phiGranularity = (sampling == 1 && region == 0) ? (2*M_PI/64) : (2*M_PI/256);
1029 double phi_min = phiBin * phiGranularity;
1030
1031 double radius_min = 0.0;
1032 double radius_max = 0.0;
1033
1034 if (sampling == 1) {
1035 radius_min = (etaBin == 0) ? m_rMinAccordion : Rmax1[etaBin - 1];
1036 radius_max = Rmax1[etaBin];
1037 } else if (sampling == 2) {
1038 radius_min = Rmax1[etaBin];
1039 radius_max = Rmax2[etaBin];
1040 } else if (sampling == 3) {
1041 radius_min = Rmax2[etaBin];
1042 radius_max = m_rMaxAccordion;
1043 }
1044
1045 // --- Super-Resolution granularity (bins within cell) ---
1046 const int nBinsEtaSR = m_nBinsEtaSR;
1047 const int nBinsPhiSR = m_nBinsPhiSR;
1048 const int nBinsRadiusSR = m_nBinsRadiusSR;
1049
1050 double delta_eta_SR = delta_eta / nBinsEtaSR;
1051 double delta_phi_SR = phiGranularity / nBinsPhiSR;
1052 double delta_r_SR = (radius_max - radius_min) / nBinsRadiusSR;
1053
1054 auto computeBin = [](double val, double min_lr, double delta_sr, int maxBins) {
1055 const int overflow = maxBins - 1;
1056 if (delta_sr == 0.0) return overflow;
1057 int bin = int((val - min_lr) / delta_sr);
1058 return std::clamp(bin, 0, overflow);;
1059 };
1060
1061 // --- Compute SR bin numbers (local within the cell) ---
1062 int etaBinSR = computeBin(eta, eta_min, delta_eta_SR, nBinsEtaSR);
1063 int phiBinSR = computeBin(phi, phi_min, delta_phi_SR, nBinsPhiSR);
1064 int rBinSR = computeBin(radius, radius_min, delta_r_SR, nBinsRadiusSR);
1065
1066 // Packing (16 bits):
1067 // Bit 15: Marker bit (always 1)
1068 // Bits 9-14 (6 bits): etaBinSR (shifted by 1)
1069 // Bits 3-8 (6 bits): phiBinSR (shifted by 1)
1070 // Bits 0-2 (3 bits): rBinSR (reduced by 1 bit)
1071
1072 unsigned short int packedID = ( 0x8000 ) // Marker bit always set (bit 15)
1073 | ( (etaBinSR & 0x3F) << 9 ) // 6 bits for eta (bits 9-14)
1074 | ( (phiBinSR & 0x3F) << 3 ) // 6 bits for phi (bits 3-8)
1075 | ( rBinSR & 0x07 ); // 3 bits for r (bits 0-2)
1076
1077 // --- Store packedID into LArG4Identifier ---
1078 result << packedID;
1079
1080 return result;
1081 }
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define y
#define x
#define z
Gaudi::Property< int > m_nBinsEtaSR
Gaudi::Property< int > m_nBinsPhiSR
Gaudi::Property< int > m_nBinsRadiusSR
static const G4double Rmax2[56]
maximum values of active S2 region from electrode drawing
static const G4double Rmax1[448]
maximum values of active S1 region from electrode drawing (first eta value checked by D....
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setPhiMap phiBin
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap etaBin

◆ CheckDMIdentifier()

bool LArG4::Barrel::Geometry::CheckDMIdentifier ( int type,
int sampling,
int region,
int eta,
int phi ) const
private

Definition at line 1418 of file LArBarrelGeometry.cxx.

1419 {
1420
1421 if (type <1 || type > 2) return false;
1422 if (type==1) {
1423 if (sampling<1 || sampling>2) return false;
1424 if (sampling==1) {
1425 if (region!=3 && region !=4) return false;
1426 if (phi<0 || phi>63) return false;
1427 if (region==3) {
1428 if (eta<0 || eta>14) return false;
1429 }
1430 if (region==4) {
1431 if (eta !=0) return false;
1432 }
1433 }
1434 if (sampling==2) {
1435 if (region !=0 && region !=2) return false;
1436 if (phi<0 || phi>63) return false;
1437 if (region==0){
1438 if (eta<0 || eta>9) return false;
1439 }
1440 if (region==2) {
1441 if (eta<0 || eta>4) return false;
1442 }
1443 }
1444 }
1445 if (type==2) {
1446 if (sampling<1 || sampling >3) return false;
1447 if (region !=0) return false;
1448 if (eta!=0) return false;
1449 if (phi<0 || phi>63) return false;
1450 }
1451 return true;
1452 }

◆ CheckLArIdentifier()

bool LArG4::Barrel::Geometry::CheckLArIdentifier ( int sampling,
int region,
int eta,
int phi ) const
private

Definition at line 1455 of file LArBarrelGeometry.cxx.

1456 {
1457 if (sampling<0 || sampling >3) return false;
1458 if (sampling==0) {
1459 if (region!=0) return false;
1460 if (eta<0 || eta>60) return false;
1461 if (phi<0 || phi>63) return false;
1462 }
1463 if (sampling==1) {
1464 if (region<0 || region >1) return false;
1465 if (region==0) {
1466 if (eta<1 || eta>447) return false;
1467 if (phi<0 || phi>63) return false;
1468 }
1469 if (region==1) {
1470 if (eta<0 || eta>2) return false;
1471 if (phi<0 || phi>255) return false;
1472 }
1473 }
1474 if (sampling==2) {
1475 if (region<0 || region >1) return false;
1476 if (region==0) {
1477 if (eta<0 || eta>55) return false;
1478 if (phi<0 || phi>255) return false;
1479 }
1480 if (region==1) {
1481 if (eta!=0) return false;
1482 if (phi<0 || phi>255) return false;
1483 }
1484 }
1485 if (sampling==3) {
1486 if (region !=0) return false;
1487 if (eta<0 || eta>26) return false;
1488 if (phi<0 || phi>255) return false;
1489 }
1490 return true;
1491 }

◆ Distance_Abs()

double LArG4::Barrel::Geometry::Distance_Abs ( const double & x,
const double & y,
const int & nabs,
const int & Num_Straight,
const int & Num_Coude ) const
private

Definition at line 240 of file LArBarrelGeometry.cxx.

243 {
244 //
245 // FrameWork is consistent with the one used to PhiCell determination
246 // e.g. it assumes HERE to be the LOCAL one of "stac_phys1",
247 // (mother of ACCordion volumes) from which Z> 0. and Z < 0. half_barrel
248 // parts are then defined.
249 //
250 // One needs POINTERS to Electrode neutral fibers
251 // either for straight parts or for folds
252 //
253 // u unit 2D_Vector along straight part of the electrode neutral fiber
254 const G4double u[2] = { m_absorber->Cosu(Num_Straight, PhiCell), m_absorber->Sinu(Num_Straight, PhiCell) };
255 // Middle m_coordinates of this straight part of the electrode neutral fiber
256 const G4double Xm[2] = { m_absorber->XCentAbs(Num_Straight, PhiCell), m_absorber->YCentAbs(Num_Straight, PhiCell) };
257 // m_Hit Vector components
258 double dx = xhit - Xm[0]; double dy = yhit - Xm[1];
259
260 // First compute algebric distance hit (2D) the 2D_projection of the
261 // m_Hit Vector on this electrode neutral fiber.
262 const double hit = dx*u[0] + dy*u[1];
263
264 //
265 // Flat of Fold Region ?
266 //
267 if(std::fabs(hit) < m_absorber->HalfLength(Num_Straight,PhiCell)) {
268 // Flat Region
269 return u[0]*dy - u[1]*dx;
270 }
271 else {
272 // Fold Center c_coordinates
273 const G4double Xc[2] = { m_coudeabs->XCentCoude(Num_Coude, PhiCell), m_coudeabs->YCentCoude(Num_Coude, PhiCell) };
274 // c_Hit Vector components and its length
275 dx = xhit - Xc[0];
276 dy = yhit - Xc[1];
277 const double dr = sqrt( dx*dx + dy*dy);
278 return (Num_Coude%2 == m_parity) ? (m_rint_eleFib-dr) : (dr - m_rint_eleFib);
279 } // end of Fold Regions
280 } // end of the function Distance_Abs
const LArCoudeAbsorbers * m_coudeabs
const LArStraightAbsorbers * m_absorber
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77

◆ Distance_Ele()

double LArG4::Barrel::Geometry::Distance_Ele ( const double & x,
const double & y,
const int & PhiC,
int & Num_Straight,
const int & Num_Coude,
double & xl ) const
private

Definition at line 166 of file LArBarrelGeometry.cxx.

169 {
170 //
171 // FrameWork is consistent with the one used to PhiCell determination
172 // e.g. it assumes HERE to be the LOCAL one of "stac_phys1",
173 // (mother of ACCordion volumes) from which Z> 0. and Z < 0. half_barrel
174 // parts are then defined.
175 //
176 // One needs POINTERS to Electrode neutral fibers
177 // either for straight parts or for folds
178 //
179 // Fold Center ccoordinates
180 const G4double Xc[2] = { m_coudeelec->XCentCoude(Num_Coude, PhiCell), m_coudeelec->YCentCoude(Num_Coude, PhiCell) };
181 const G4double radfold = sqrt(Xc[0]*Xc[0]+Xc[1]*Xc[1]);
182 const G4double radhit = sqrt(xhit*xhit+yhit*yhit);
183
184 // check if the assumed straight number is the correct one
185 // (this can be wrong when we are close to a fold and there is sagging)
186 if (Num_Coude == Num_Straight && radhit <radfold) {
187 if (Num_Straight>0) { Num_Straight = Num_Straight-1; }
188 // ATH_MSG_VERBOSE("radhit,radfold " << radhit << " " << radfold << " change straight by +1");
189 }
190 if (Num_Coude == (Num_Straight+1) && radhit > radfold) {
191 if (Num_Straight<12) { Num_Straight = Num_Straight+1; }
192 // ATH_MSG_VERBOSE("radhit,radfold " << radhit << " " << radfold << " change straight by -1");
193 }
194
195 // u unit 2D_Vector along straight part of the electrode neutral fiber
196 const double u[2] = { m_electrode->Cosu(Num_Straight, PhiCell), m_electrode->Sinu(Num_Straight, PhiCell) };
197 // Middle m_coordinates of this straight part of the electrode neutral fiber
198 const double Xm[2] = { m_electrode->XCentEle(Num_Straight, PhiCell), m_electrode->YCentEle(Num_Straight, PhiCell) };
199 // m_Hit Vector components
200 double dx = xhit - Xm[0];
201 double dy = yhit - Xm[1];
202
203 // First compute algebric distance m_hit (2D) the 2D_projection of the
204 // m_Hit Vector on this electrode neutral fiber.
205 const double hit = dx*u[0] + dy*u[1];
206
207 //
208 // Flat of Fold Region ?
209 //
210 const G4double Half_Elec(m_electrode->HalfLength(Num_Straight,PhiCell));
211
212 if(std::fabs(hit) < Half_Elec) {
213 // Flat Region
214 xl=hit/Half_Elec;
215 return u[0]*dy - u[1]*dx;
216 }
217 else {
218 // Fold region
219 // c_Hit Vector components and its length
220 dx = xhit - Xc[0];
221 dy = yhit - Xc[1];
222 const double dr = sqrt( dx*dx + dy*dy);
223 if (Num_Coude==Num_Straight) { xl=-1.; }
224 else xl=+1;
225 return (Num_Coude%2 == m_parity) ? (m_rint_eleFib-dr) : (dr - m_rint_eleFib);
226 } // end of Fold Regions
227 } // end of the function Distance_Ele
const LArCoudeElectrodes * m_coudeelec
const LArStraightElectrodes * m_electrode

◆ finalize()

StatusCode LArG4::Barrel::Geometry::finalize ( )
finaloverridevirtual

Definition at line 137 of file LArBarrelGeometry.cxx.

138 {
139 if (m_rc) delete [] m_rc;
140 if (m_phic) delete [] m_phic;
141 if (m_delta) delete [] m_delta;
142 if (m_xc) delete [] m_xc;
143 if (m_yc) delete [] m_yc;
144
145 return StatusCode::SUCCESS;
146 }

◆ findCell()

void LArG4::Barrel::Geometry::findCell ( CalcData & currentCellData,
const double & x,
const double & y,
const double & z,
const double & r,
const double & eta,
const double & phi,
const bool detail ) const
finaloverridevirtual

Definition at line 593 of file LArBarrelGeometry.cxx.

601 {
602
603 currentCellData.cellID = 0;
604
605 if (aRadius < m_rc[0] || aRadius >= m_rc[m_Nbrt1-1]) {
606#ifdef DEBUGHITS
607 ATH_MSG_VERBOSE(" Outside Accordion " << aRadius << " " << m_rc[0] << " " << m_rc[m_Nbrt1-1]);
608#endif
609 return; // outside accordion
610 }
611
612 // set the straight section number
613 currentCellData.nstraight=0;
614 for (int i=1;i<m_Nbrt1;i++) {
615 if (m_rc[i] > aRadius) { break; }
616 currentCellData.nstraight++;
617 }
618 if (currentCellData.nstraight <0 || currentCellData.nstraight >= m_Nbrt) {
619 ATH_MSG_ERROR("Invalid straight number " << currentCellData.nstraight << " " << aRadius);
620 return;
621 }
622
623 // get the closest fold number
624 currentCellData.nfold=currentCellData.nstraight;
625 if (std::fabs(aRadius-m_rc[currentCellData.nfold]) > std::fabs(aRadius-m_rc[currentCellData.nfold+1]) ) {
626 currentCellData.nfold +=1;
627 }
628 if (currentCellData.nfold <0 || currentCellData.nfold >= m_Nbrt1) {
629 ATH_MSG_ERROR("Invalid fold number " << currentCellData.nfold);
630 return;
631 }
632
633
634#ifdef DEBUGHITS
635 ATH_MSG_VERBOSE(" BarrelGeometry: radius,eta,phi " << aRadius << " " << anEta << " ");
636 ATH_MSG_VERBOSE(" Straight/Fold numbers " << currentCellData.nstraight << " " << currentCellData.nfold);
637#endif
638
639 // eta and longitudinal segmentations
640 G4int ireg,isamp,ieta,isamp2,ieta2;
641 currentCellData.cellID = this->SampSeg(anEta,aRadius,zPosition,ireg,isamp,ieta,isamp2,ieta2);
642
643 currentCellData.etaBin = ieta;
644 currentCellData.sampling = isamp;
645 currentCellData.region = ireg;
646 currentCellData.etaMap = ieta2;
647 currentCellData.sampMap = isamp2;
648
649 // compute electrode number in phi
650 int phicell = this->PhiGap(aRadius,xPosition,yPosition);
651 if (phicell<0) phicell=0;
652 // for test beam, some protection
653 if (m_NCellTot !=1024) {
654 if (phicell>=m_NCellTot) {
655 if (phicell<512) { phicell=m_NCellTot-1; }
656 else { phicell=0; }
657 currentCellData.cellID=0;
658 }
659 }
660
661#ifdef DEBUGHITS
662 ATH_MSG_VERBOSE(" phigap " << phicell);
663#endif
664
665 // compute readout cell number
666 int sampling_phi_nGaps=4;
667 if (currentCellData.region==0 && currentCellData.sampling==1) { sampling_phi_nGaps=16; }
668
669 if (currentCellData.cellID==0) {
670 currentCellData.phiBin = (G4int) ( phicell/sampling_phi_nGaps );
671 currentCellData.distElec=9999.;
672 return;
673 }
674
675 // compute distance to electrode
676 G4double xl;
677 G4int nstr = currentCellData.nstraight;
678 const G4double distElec = this->Distance_Ele(xPosition,yPosition,phicell,nstr,currentCellData.nfold,xl);
679
680#ifdef DEBUGHITS
681 ATH_MSG_VERBOSE(" distElec " << distElec);
682#endif
683
684 // if distance is < 2.5mm we are sure to be in the correct gap
685 if (std::fabs(distElec) > 2.5) {
686 // try +-2 electrode in phi to get minimum distance
687 double dElecMin=distElec;
688 double xlmin=xl;
689 int phicellmin=phicell;
690 for (int ii=-2;ii<3;ii++) {
691 if (ii==0) { continue; }
692 int phicellnew = phicell+ii;
693 // for test beam no phi wrapping
694 if (m_NCellTot != 1024 && ( phicellnew<0 || phicellnew >= m_NCellTot)) { continue; }
695 if (phicellnew < 0) { phicellnew += m_NCellTot; }
696 if (phicellnew >= m_NCellTot) { phicellnew -= m_NCellTot; }
697 double xln;
698 int nstr2=currentCellData.nstraight;
699 double dElec = Distance_Ele(xPosition,yPosition,phicellnew,nstr2,currentCellData.nfold,xln);
700 if (std::fabs(dElec)<std::fabs(dElecMin)) {
701 phicellmin=phicellnew;
702 xlmin=xln;
703 dElecMin = dElec;
704 nstr=nstr2;
705 }
706 }
707 currentCellData.phiGap = phicellmin;
708 currentCellData.distElec = dElecMin;
709 currentCellData.xl = xlmin;
710 currentCellData.nstraight = nstr;
711 } // end distance >2.5mm
712 else {
713 currentCellData.phiGap=phicell;
714 currentCellData.distElec=distElec;
715 currentCellData.xl=xl;
716 currentCellData.nstraight=nstr;
717 }
718
719#ifdef DEBUGHITS
720 ATH_MSG_VERBOSE(" final phiGap,distElec,xl " << currentCellData.phiGap << " " << currentCellData.distElec << " "
721 << currentCellData.xl);
722#endif
723
724 // compute distance to absorber
725
726 G4int nabs;
727 if (currentCellData.distElec<0) nabs=currentCellData.phiGap;
728 else nabs=currentCellData.phiGap+1;
729 if (nabs >= m_NCellMax) nabs -= m_NCellMax;
730 currentCellData.distAbs = Distance_Abs(xPosition,yPosition,nabs,currentCellData.nstraight,currentCellData.nfold);
731#ifdef DEBUGHITS
732 ATH_MSG_VERBOSE(" nabs,distAbs " << nabs << " " << currentCellData.distAbs);
733#endif
734
735 // in some rare cases near fold, the closest distance could give the wrong gap
736 // in such case, the signs of distAbs and distElec are not opposite as they should
737 if ((currentCellData.distAbs>0. && currentCellData.distElec>0) ||
738 (currentCellData.distAbs<0. && currentCellData.distElec<0) ) {
739 // ATH_MSG_VERBOSE("distElec and distAbs same sign " << currentCellData.distElec << " " << currentCellData.distAbs);
740 // ATH_MSG_VERBOSE(" currentCellData.phiGap " << currentCellData.phiGap);
741 if (std::fabs(currentCellData.distElec)>std::fabs(currentCellData.distAbs)) {
742 if (currentCellData.distAbs>0) { currentCellData.phiGap += 1; }
743 if (currentCellData.distAbs<0) { currentCellData.phiGap -= 1; }
744 if (m_NCellTot != 1024) {
745 if (currentCellData.phiGap <0) { currentCellData.phiGap=0; }
746 if (currentCellData.phiGap >= m_NCellTot) { currentCellData.phiGap = m_NCellTot-1; }
747 }
748 else {
749 if (currentCellData.phiGap < 0) { currentCellData.phiGap += m_NCellTot; }
750 if (currentCellData.phiGap >= m_NCellTot) { currentCellData.phiGap -= m_NCellTot; }
751 }
752 currentCellData.distElec = Distance_Ele(xPosition,yPosition,currentCellData.phiGap,currentCellData.nstraight,currentCellData.nfold,currentCellData.xl);
753 // ATH_MSG_VERBOSE(" new phiGap,distElec " << currentCellData.phiGap << " " << currentCellData.distElec);
754 }
755 }
756
757 currentCellData.phiBin = (G4int) ( currentCellData.phiGap/sampling_phi_nGaps );
758
759 if (MapDetail) {
760 // compute x0,y0 coordinates in local electrode frame, using closest fold
761 // as reference
762 const G4double alpha = m_coudeelec->PhiRot(currentCellData.nfold,currentCellData.phiGap);
763 const G4double dx=xPosition-m_coudeelec->XCentCoude(currentCellData.nfold,currentCellData.phiGap);
764 const G4double dy=yPosition-m_coudeelec->YCentCoude(currentCellData.nfold,currentCellData.phiGap);
765 const G4double dx1=dx*cos(alpha)-dy*sin(alpha);
766 const G4double dy1=dx*sin(alpha)+dy*cos(alpha);
767 currentCellData.x0 = dx1 + m_xc[currentCellData.nfold];
768 currentCellData.y0 = dy1 + m_yc[currentCellData.nfold];
769 if (m_parity==1) { currentCellData.y0 = -1*currentCellData.y0; }
770 }
771
772
773 } // end of findCell method
double Distance_Ele(const double &x, const double &y, const int &PhiC, int &Num_Straight, const int &Num_Coude, double &xl) const
G4int PhiGap(const double &, const double &, const double &) const
G4int SampSeg(G4double, G4double, G4double, G4int &, G4int &, G4int &, G4int &, G4int &) const
double Distance_Abs(const double &x, const double &y, const int &nabs, const int &Num_Straight, const int &Num_Coude) const

◆ GetRphi()

void LArG4::Barrel::Geometry::GetRphi ( )
private

phi vs r of first absorber in nominal geometry

Initialize r-phi reference map (called from constructor)

Definition at line 777 of file LArBarrelGeometry.cxx.

778 {
779 const G4double dl=0.001;
780 const G4double inv_dl = 1. / dl;
781 G4double cenx[15],ceny[15];
782 //G4double xl,xl2;
783 std::vector<G4double> sum1(5000);
784 std::vector<G4double> sumx(5000);
785 //xl=0;
786 //xl2=0.;
787 m_NRphi=5000;
788 m_Rmin=1500.;
789 m_dR=0.10;
790 m_Rmax=0.;
791
792 const G4double rint= m_rint_eleFib;
793 const G4double inv_rint = 1. / rint;
794 const G4double dt=dl * inv_rint;
795 const G4double inv_dt = 1. / dt;
796
797 for (G4int i=0;i<m_NRphi;i++) {
798 sum1[i]=0.;
799 sumx[i]=0.;
800 }
801 for (G4int i=0;i<15;i++) {
802 cenx[i]=m_rc[i]*cos(m_phic[i]);
803 ceny[i]=m_rc[i]*sin(m_phic[i]);
804 }
805
806 for (G4int i=0; i<15; i++) {
807
808 // fold
809 G4double phi0,phi1;
810 if (i==0) {
811 // first fold goes up
812 if (m_parity==0) {
813 phi0=-CLHEP::pi/2.;
814 phi1=-m_delta[0];
815 }
816 // first fold goes down
817 else {
818 phi0=m_delta[0];
819 phi1=CLHEP::pi/2;
820 }
821 }
822 else if (i==14) {
823 if (m_parity==0) {
824 phi0=-CLHEP::pi+m_delta[13];
825 phi1=-CLHEP::pi/2.;
826 }
827 else {
828 phi0=CLHEP::pi/2;
829 phi1=CLHEP::pi - m_delta[13];
830 }
831 }
832 else {
833 if (i%2==(1-m_parity)) {
834 phi0=m_delta[i];
835 phi1=CLHEP::pi-m_delta[i-1];
836 }
837 else {
838 phi0=-CLHEP::pi+m_delta[i-1];
839 phi1=-m_delta[i];
840 }
841 }
842 //xl2+=rint*std::fabs(phi1-phi0);
843 const G4int nstep=int((phi1-phi0)*inv_dt)+1;
844 for (int ii=0;ii<nstep;ii++) {
845 //xl+=dl;
846 const G4double phi=phi0+dt*((G4double)ii);
847 const G4double x=cenx[i]+rint*cos(phi);
848 const G4double y=ceny[i]+rint*sin(phi);
849 const G4double radius=sqrt(x*x+y*y);
850 if (radius>m_Rmax) { m_Rmax=radius; }
851 const G4double phid=atan(y/x);
852 const G4int ir=((int) ((radius-m_Rmin)/m_dR) );
853 if (ir>=0 && ir < m_NRphi) {
854 sum1[ir]+=1.;
855 sumx[ir]+=phid;
856 }
857 }
858
859 // straight section
860 if (i<14) {
861 const G4double dx=cenx[i+1]-cenx[i];
862 const G4double dy=ceny[i+1]-ceny[i];
863 const G4double along=std::sqrt(dx*dx+dy*dy-4.*rint*rint);
864 const G4double x0=0.5*(cenx[i+1]+cenx[i]);
865 const G4double y0=0.5*(ceny[i+1]+ceny[i]);
866 const G4double phi = (i%2==m_parity) ? CLHEP::pi/2-m_delta[i] : -CLHEP::pi/2.+m_delta[i];
867 const G4double x1=x0-0.5*along*cos(phi);
868 const G4double y1=y0-0.5*along*sin(phi);
869 //xl2+=along;
870 const int nstep=int(along*inv_dl)+1;
871 for (int ii=0;ii<nstep;ii++) {
872 //xl+=dl;
873 const G4double x=x1+dl*((G4double)ii)*cos(phi);
874 const G4double y=y1+dl*((G4double)ii)*sin(phi);
875 const G4double radius=sqrt(x*x+y*y);
876 if (radius>m_Rmax) { m_Rmax=radius; }
877 const G4double phid=atan(y/x);
878 const G4int ir=((int) ((radius-m_Rmin)/m_dR) );
879 if (ir>=0 && ir < m_NRphi) {
880 sum1[ir]+=1.;
881 sumx[ir]+=phid;
882 }
883 }
884 }
885 }
886 // ATH_MSG_VERBOSE("total electrode length " << xl << " " << xl2);
887 // ATH_MSG_VERBOSE("rmax in accordion " << m_Rmax);
888 for (int i=0; i<m_NRphi; i++) {
889 if (sum1[i]>0) {
890 m_Rphi[i]=sumx[i]/sum1[i];
891 // Not used:
892 //G4double radius = m_Rmin + ((G4double(i))+0.5)*m_dR;
893 //ATH_MSG_VERBOSE(" GUTEST r,phi0 " << radius << " " << m_Rphi[i]);
894 }
895 else { m_Rphi[i]=0.; }
896 }
897 }
#define pi
int ir
counter of the current depth
Definition fastadd.cxx:49

◆ initialize()

StatusCode LArG4::Barrel::Geometry::initialize ( )
finaloverridevirtual

Definition at line 50 of file LArBarrelGeometry.cxx.

51 {
52 // initialize the geometry.
53 // Access source of detector parameters.
54
56
57 // number of straight sections (should be 14)
58 m_Nbrt = (int) (parameters->GetValue("LArEMBnoOFAccZigs"));
59 // Number of ZIGs + 1 i.e. 15 = number of folds
60 m_Nbrt1 = m_Nbrt + 1;
61 // phi of first absorber
62 m_gam0 = parameters->GetValue("LArEMBAbsPhiFirst");
63 // radius of curvature of neutral fiber in the folds
64 m_rint_eleFib = parameters->GetValue("LArEMBNeutFiberRadius");
65
66 m_rc = new double[m_Nbrt1];
67 m_phic = new double[m_Nbrt1];
68 m_delta = new double[m_Nbrt1];
69 m_xc = new double[m_Nbrt1];
70 m_yc = new double[m_Nbrt1];
71
72 // r,phi positions of the centre of the folds (nominal geometry)
73 for (G4int idat = 0; idat < m_Nbrt1 ; idat++) {
74 m_rc[idat] = (double) parameters->GetValue("LArEMBRadiusAtCurvature",idat);
75 m_phic[idat] = (double) parameters->GetValue("LArEMBPhiAtCurvature",idat);
76 m_delta[idat] = (double) parameters->GetValue("LArEMBDeltaZigAngle",idat);
77 m_xc[idat] = m_rc[idat]*cos(m_phic[idat]);
78 m_yc[idat] = m_rc[idat]*sin(m_phic[idat]);
79 }
80 // define parity of accordion waves: =0 if first wave goes up, 1 if first wave goes down in the local frame
81 m_parity=0;
82 if (m_phic[0]<0.) { m_parity=1; }
83 //
84 m_rMinAccordion = parameters->GetValue("LArEMBRadiusInnerAccordion");
85 m_rMaxAccordion = parameters->GetValue("LArEMBFiducialRmax");
86 m_etaMaxBarrel = parameters->GetValue("LArEMBMaxEtaAcceptance");
87 m_zMinBarrel = parameters->GetValue("LArEMBfiducialMothZmin");
88 m_zMaxBarrel = parameters->GetValue("LArEMBfiducialMothZmax");
89 m_zMaxBarrelDMMargin = 10.0; // 10 mm margin
90 // === GU 11/06/2003 total number of cells in phi
91 // to distinguish 1 module (testbeam case) from full Atlas
92 m_NCellTot = (int) (parameters->GetValue("LArEMBnoOFPhysPhiCell"));
93 // total number of cells in phi to distinguish 1 module (testbeam case) from full Atlas
94 m_testbeam=false;
95 if (m_NCellTot != 1024) {
96 m_testbeam=true;
97 }
98 m_NCellMax=1024;
99 // ===
100
101 // Initialize r-phi reference map
102 this->GetRphi();
103
104 if (m_detectorName.empty()) m_ecamName = "LAr::EMB::ECAM";
105 else m_ecamName = m_detectorName+"::LAr::EMB::ECAM";
106
107 // Validate SR granularity properties against bit-packing constraints
109 ATH_MSG_ERROR("nBinsEtaSR must be in range [1, 64], got " << m_nBinsEtaSR);
110 return StatusCode::FAILURE;
111 }
113 ATH_MSG_ERROR("nBinsPhiSR must be in range [1, 64], got " << m_nBinsPhiSR);
114 return StatusCode::FAILURE;
115 }
117 ATH_MSG_ERROR("nBinsRadiusSR must be in range [1, 8], got " << m_nBinsRadiusSR);
118 return StatusCode::FAILURE;
119 }
120
121 return StatusCode::SUCCESS;
122 }
LArGeo::VDetectorParameters LArVG4DetectorParameters
Gaudi::Property< std::string > m_detectorName
void GetRphi()
phi vs r of first absorber in nominal geometry
static const VDetectorParameters * GetInstance()

◆ initializeForSDCreation()

void LArG4::Barrel::Geometry::initializeForSDCreation ( )
finaloverridevirtual

Definition at line 126 of file LArBarrelGeometry.cxx.

127 {
128 // get pointers to access G4 geometry
133 }
static const LArCoudeAbsorbers * GetInstance(const std::string &strDetector="")
static const LArCoudeElectrodes * GetInstance(const std::string &strDetector="")
static const LArStraightAbsorbers * GetInstance(const std::string &strDetector="")
static const LArStraightElectrodes * GetInstance(const std::string &strDetector="")

◆ Phi0()

G4double LArG4::Barrel::Geometry::Phi0 ( G4double radius) const
private

Definition at line 902 of file LArBarrelGeometry.cxx.

903 {
904 // TODO This function could be simplified.
905 G4int ir;
906 if (radius < m_Rmin) { ir=0; }
907 else {
908 if (radius > m_Rmax) radius=m_Rmax-0.0001;
909 ir=((int) ((radius-m_Rmin)/m_dR) );
910 }
911 return m_Rphi[ir];
912 }

◆ PhiGap()

G4int LArG4::Barrel::Geometry::PhiGap ( const double & radius,
const double & xhit,
const double & yhit ) const
private

Definition at line 917 of file LArBarrelGeometry.cxx.

918 {
919 const G4double phi0=Phi0(radius)+m_gam0; // from -pi to pi
920 const G4double phi_hit=atan2(yhit,xhit); // from -pi to pi
921 G4double dphi=phi_hit-phi0;
922 // bring back to 0-2pi
923 if (dphi<0) dphi=dphi+2*M_PI;
924 if (dphi>=2*M_PI) dphi=dphi-2*M_PI;
925 dphi=dphi/(2*M_PI)*1024;
926 const G4int ngap=((int) dphi);
927#ifdef DEBUGHITS
928 ATH_MSG_VERBOSE(" phi0 " << phi0 << " dphi, ngap " << dphi << " " << ngap);
929#endif
930 return ngap;
931 }
G4double Phi0(G4double) const

◆ SampSeg()

G4int LArG4::Barrel::Geometry::SampSeg ( G4double eta,
G4double radius,
G4double z,
G4int & iregion,
G4int & isampling,
G4int & ieta,
G4int & isamp2,
G4int & ieta2 ) const
private

Definition at line 307 of file LArBarrelGeometry.cxx.

310 {
311 // Helper struct to hold pre-calculated geometry information
312 struct Geo {
313 G4double Eta_max,R_max_acc,Z_max_acc,R_min_acc,Z_max_lowr,dzdr;
314 G4double zmax1,zmax2,zmax3,zmax4,zmax5,zmax6,zmax7,rmax1,rmax2,rmax3,rmax4;
315 };
316
317 // Fill it once
318 static const Geo g = []() {
320 Geo g{};
321
322 // maximum eta barrel 1.475 (at r=1500.024)
323 g.Eta_max = parameters->GetValue("LArEMBMaxEtaAcceptance");
324 // minimum active radius 1500.024
325 g.R_min_acc= parameters->GetValue("LArEMBRadiusInnerAccordion");
326 // maximum active radius 1960.
327 g.R_max_acc = parameters->GetValue("LArEMBFiducialRmax");
328 // maximum active z (before subtracting edge for signal readout)
329 // currently 3150, should be changed in database to become 3164
330 g.Z_max_acc = parameters->GetValue("LArEMBfiducialMothZmax");
331 // minimum radius at z max for active region
332 const G4double R_min_highz=1548.; //FIXME should be taken from database
333
334 // compute z edge taken by readout strips on the edge
335 const G4double deltaz=7.; // this include copper 6mm + 2*0.5mm empty space on each side
336 g.zmax1=g.Z_max_acc-deltaz;
337 g.zmax2=g.Z_max_acc-2.*deltaz;
338 g.zmax3=g.Z_max_acc-3.*deltaz;
339 g.zmax4=g.Z_max_acc-4.*deltaz;
340 g.zmax5=g.Z_max_acc-5.*deltaz;
341 g.zmax6=g.Z_max_acc-6.*deltaz;
342 g.zmax7=g.Z_max_acc-7.*deltaz;
343 g.rmax1=g.R_max_acc-deltaz;
344 g.rmax2=g.R_max_acc-2.*deltaz;
345 g.rmax3=g.R_max_acc-3.*deltaz;
346 g.rmax4=g.R_max_acc-4.*deltaz;
347
348 // maximum z at r=1500.024
349 g.Z_max_lowr = sinh(g.Eta_max)*g.R_min_acc;
350 // slope of z vs r edge (which is not projective in eta...)
351 g.dzdr = (g.Z_max_acc-g.Z_max_lowr)/(R_min_highz-g.R_min_acc);
352
353 // ATH_MSG_VERBOSE("Initialization of SampSet ");
354 // ATH_MSG_VERBOSE(" Rmin/Rmax " << g.R_min_acc << " " << g.R_max_acc);
355 // ATH_MSG_VERBOSE(" Zmax/Zmax_lowR " << g.Z_max_acc << " " << g.Z_max_lowr);
356 // ATH_MSG_VERBOSE(" Rmin_highz " << R_min_highz);
357 // ATH_MSG_VERBOSE(" dzdr " << g.dzdr);
358 return g;
359 }();
360
361 // inactive thickness between S1 and S2 FIXME should be taken from database
362 const G4double Dr_s12=1.1;
363 const G4double Eta_max_s1=1.4; // maximum eta region 0
364 const G4double Eta_max_s3=1.325; // maximum eta for S3 in region 0
365 const G4double deta=0.025; // basic granularity
366
367
368 // iactive = 1 if active region, 0 if region considered as inactive
369 G4int iactive = 1;
370
371 const G4double aeta=std::fabs(eta);
372
373 G4double r12=-1.;
374 G4double r23=-1.;
375
376 // Not used: G4double rmax=Z_max_acc/sinh(aeta);
377
378 G4int istrip,imid;
379
380 // eta < 1.4
381
382 if (aeta<Eta_max_s1) {
383
384 // get radius for end of strips
385 istrip=(int) (aeta/deta*8.);
386 if (istrip<0 || istrip >=448) {
387 ATH_MSG_ERROR(" Problem aeta,istrip " << aeta << " " << istrip);
388 return 0;
389 }
390 r12=Rmax1[istrip];
391
392 // get radius for end of middle
393 imid = (int) (aeta/deta);
394 if (imid <0 || imid >=56) {
395 ATH_MSG_ERROR(" Problem aeta,imid " << aeta << " " << imid);
396 return 0;
397 }
398 r23=Rmax2[imid];
399
400 iregion=0;
401
402 // strips
403 if (radius <= r12) {
404 isampling=1;
405 ieta=istrip;
406 if (ieta==0) iactive=0;
407 isamp2=1;
408 ieta2=istrip;
409 }
410
411 // region between strips and middle => not active, same identifier as strips
412 else if (radius < (r12+Dr_s12)) {
413 isampling=1;
414 ieta=istrip;
415 iactive=0;
416 isamp2=1;
417 ieta2=istrip;
418 }
419
420 else {
421
422 // eta<1.325, we can be in the back
423 if (aeta<Eta_max_s3) {
424 // radius<r23 we are in the middle
425 if (radius <= r23) {
426 isampling=2;
427 ieta=imid;
428 isamp2=2;
429 ieta2=imid;
430 }
431 // for radius >r23 we have to take care of the readout strips at high z
432 // and attribute some of the energy to other cells
433 else { // radius>r23
434 if (z>g.zmax1) {
435 isampling=2;
436 ieta=55;
437 }
438 else if (z>g.zmax2) {
439 isampling=2;
440 ieta=54;
441 }
442 else if (z>g.zmax3) {
443 isampling=2;
444 ieta=53;
445 }
446 else if (z>g.zmax4) {
447 isampling=3;
448 ieta=26;
449 }
450 else if (aeta<1.3 && z>g.zmax5) {
451 isampling=2;
452 ieta=52;
453 }
454 else if (aeta<1.3 && z>g.zmax6) {
455 isampling=2;
456 ieta=51;
457 }
458 else if (radius>g.rmax4 && z<g.zmax5 && aeta>1.2) {
459 if (radius>g.rmax1) {
460 isampling=2;
461 ieta=51;
462 }
463 else if(radius>g.rmax2) {
464 isampling=3;
465 ieta=25;
466 }
467 else if (radius>g.rmax3) {
468 if (z<g.zmax7) {
469 isampling=2;
470 ieta=50;
471 }
472 else {
473 isampling=3;
474 ieta=25;
475 }
476 }
477 else {
478 if (aeta<1.25) {
479 isampling=2;
480 ieta=49;
481 }
482 else {
483 isampling=3;
484 ieta=25;
485 }
486 }
487 }
488 // normal back cell
489 else {
490 isampling=3;
491 ieta=imid/2;
492 isamp2=3;
493 ieta2=ieta;
494 }
495 isamp2=3;
496 ieta2=imid/2;
497 } // end radius>r23
498 // put into middle energy deposited along readout strips across the back
499 if (isampling==3 && z<g.zmax4 && (radius<g.rmax4 || aeta<1.2) ) {
500 const double etastr = (imid%2==0) ? 0.025*imid : 0.025*(imid+1);
501 const double delta=radius*(sinh(etastr)-sinh(aeta))/cosh(etastr);
502 double deltastr;
503 if (aeta<0.475) { deltastr=1.5;}
504 else if (aeta<0.80) { deltastr=2.75;}
505 else if (aeta<0.85) { deltastr=1.5;}
506 else if (aeta<1.1) { deltastr=2.75;}
507 else { deltastr=3.25;}
508
509 if (std::fabs(delta)<deltastr) {
510 isampling=2;
511 ieta=imid;
512 }
513 } // end if sampling==3
514 } // end if eta<1.325
515 else {
516 isampling=2;
517 ieta=imid;
518 if (z>g.zmax1) {
519 ieta=55;
520 }
521 else if (z>g.zmax2 && aeta<1.375) {
522 ieta=54;
523 }
524 isamp2=2;
525 ieta2=imid;
526 } // end eta>1.352
527 } // end radius selection
528 } // end eta1.4
529
530 // eta between 1.4 and 1.475
531
532 if (aeta>=Eta_max_s1 && aeta<g.Eta_max) {
533 r12 = Rmax1[447]; // radius for end of sampling 1
534 r23=g.Z_max_acc/sinh(aeta); // radius of end of sampling 2, bounded by high z end
535
536 const double zmax = g.Z_max_lowr + g.dzdr*(radius-g.R_min_acc);
537
538 iregion=1;
539 if (radius <=r12) {
540 isampling=1;
541 ieta=int((aeta-Eta_max_s1)/deta);
542 if (z>zmax) { iactive=0; }
543 }
544 else if (radius < (r12+Dr_s12)) {
545 isampling=1;
546 ieta=int((aeta-Eta_max_s1)/deta);
547 iactive=0;
548 }
549 else if (radius <= r23) {
550 isampling=2;
551 ieta=0;
552 if (z>zmax) { iactive=0; }
553 }
554 else {
555 isampling=2;
556 ieta=0;
557 iactive=0;
558 }
559 isamp2=isampling;
560 ieta2=ieta;
561 }
562 // eta above 1.475, not fiducial region, but still returns something
563 // for calibration hits
564 if (aeta>g.Eta_max) {
565 iregion=1;
566 r12 = Rmax1[447];
567 if (radius <=r12) {
568 isampling=1;
569 ieta=2;
570 }
571 else {
572 isampling=2;
573 ieta=0;
574 }
575 isamp2=isampling;
576 ieta2=ieta;
577 iactive=0;
578 }
579
580 // cross-check of active region
581 if (z>g.Z_max_acc || radius>g.R_max_acc || radius<g.R_min_acc || aeta > g.Eta_max) iactive=0;
582
583 return iactive;
584 }

Member Data Documentation

◆ m_absorber

const LArStraightAbsorbers* LArG4::Barrel::Geometry::m_absorber {nullptr}
private

Definition at line 111 of file LArBarrelGeometry.h.

111{nullptr};

◆ m_coudeabs

const LArCoudeAbsorbers* LArG4::Barrel::Geometry::m_coudeabs {nullptr}
private

Definition at line 109 of file LArBarrelGeometry.h.

109{nullptr};

◆ m_coudeelec

const LArCoudeElectrodes* LArG4::Barrel::Geometry::m_coudeelec {nullptr}
private

Definition at line 108 of file LArBarrelGeometry.h.

108{nullptr};

◆ m_delta

double* LArG4::Barrel::Geometry::m_delta {nullptr}
private

Definition at line 104 of file LArBarrelGeometry.h.

104{nullptr};

◆ m_detectorName

Gaudi::Property<std::string> LArG4::Barrel::Geometry::m_detectorName {this, "DetectorName", "LArMgr"}
private

Definition at line 68 of file LArBarrelGeometry.h.

68{this, "DetectorName", "LArMgr"};

◆ m_dR

G4double LArG4::Barrel::Geometry::m_dR {0.}
private

Definition at line 120 of file LArBarrelGeometry.h.

120{0.};

◆ m_ecamName

G4String LArG4::Barrel::Geometry::m_ecamName
private

Definition at line 78 of file LArBarrelGeometry.h.

◆ m_electrode

const LArStraightElectrodes* LArG4::Barrel::Geometry::m_electrode {nullptr}
private

Definition at line 110 of file LArBarrelGeometry.h.

110{nullptr};

◆ m_etaMaxBarrel

double LArG4::Barrel::Geometry::m_etaMaxBarrel {0.}
private

Definition at line 86 of file LArBarrelGeometry.h.

86{0.};

◆ m_gam0

double LArG4::Barrel::Geometry::m_gam0 {0.}
private

Definition at line 97 of file LArBarrelGeometry.h.

97{0.}; //phi position for the first absorber neutral fiber

◆ m_iflSAG

bool LArG4::Barrel::Geometry::m_iflSAG {false}
private

Definition at line 113 of file LArBarrelGeometry.h.

113{false};

◆ m_nBinsEtaSR

Gaudi::Property<int> LArG4::Barrel::Geometry::m_nBinsEtaSR {this, "nBinsEtaSR", 16, "Number of SR sub-cell bins in eta"}
private

Definition at line 74 of file LArBarrelGeometry.h.

74{this, "nBinsEtaSR", 16, "Number of SR sub-cell bins in eta"};

◆ m_nBinsPhiSR

Gaudi::Property<int> LArG4::Barrel::Geometry::m_nBinsPhiSR {this, "nBinsPhiSR", 16, "Number of SR sub-cell bins in phi"}
private

Definition at line 75 of file LArBarrelGeometry.h.

75{this, "nBinsPhiSR", 16, "Number of SR sub-cell bins in phi"};

◆ m_nBinsRadiusSR

Gaudi::Property<int> LArG4::Barrel::Geometry::m_nBinsRadiusSR {this, "nBinsRadiusSR", 5, "Number of SR sub-cell bins in radius"}
private

Definition at line 76 of file LArBarrelGeometry.h.

76{this, "nBinsRadiusSR", 5, "Number of SR sub-cell bins in radius"};

◆ m_Nbrt

int LArG4::Barrel::Geometry::m_Nbrt {0}
private

Definition at line 93 of file LArBarrelGeometry.h.

93{0}; // number of straight sections (=14)

◆ m_Nbrt1

int LArG4::Barrel::Geometry::m_Nbrt1 {0}
private

Definition at line 94 of file LArBarrelGeometry.h.

94{0}; // number of folds (=15)

◆ m_NCellMax

int LArG4::Barrel::Geometry::m_NCellMax {0}
private

Definition at line 90 of file LArBarrelGeometry.h.

90{0}; // 1024

◆ m_NCellTot

int LArG4::Barrel::Geometry::m_NCellTot {0}
private

Definition at line 89 of file LArBarrelGeometry.h.

89{0}; // either 64 or 1024 for TestBeam or Atlas

◆ m_NRphi

G4int LArG4::Barrel::Geometry::m_NRphi {0}
private

Definition at line 116 of file LArBarrelGeometry.h.

116{0};

◆ m_parity

int LArG4::Barrel::Geometry::m_parity {0}
private

Definition at line 105 of file LArBarrelGeometry.h.

105{0};

◆ m_phic

double* LArG4::Barrel::Geometry::m_phic {nullptr}
private

Definition at line 101 of file LArBarrelGeometry.h.

101{nullptr};

◆ m_rc

double* LArG4::Barrel::Geometry::m_rc {nullptr}
private

Definition at line 100 of file LArBarrelGeometry.h.

100{nullptr};

◆ m_rint_eleFib

double LArG4::Barrel::Geometry::m_rint_eleFib {0.}
private

Definition at line 98 of file LArBarrelGeometry.h.

98{0.}; //2.78

◆ m_Rmax

G4double LArG4::Barrel::Geometry::m_Rmax {0.}
private

Definition at line 118 of file LArBarrelGeometry.h.

118{0.};

◆ m_rMaxAccordion

double LArG4::Barrel::Geometry::m_rMaxAccordion {0.}
private

Definition at line 82 of file LArBarrelGeometry.h.

82{0.};

◆ m_Rmin

G4double LArG4::Barrel::Geometry::m_Rmin {0.}
private

Definition at line 117 of file LArBarrelGeometry.h.

117{0.};

◆ m_rMinAccordion

double LArG4::Barrel::Geometry::m_rMinAccordion {0.}
private

Definition at line 81 of file LArBarrelGeometry.h.

81{0.};

◆ m_Rphi

G4double LArG4::Barrel::Geometry::m_Rphi[5000] = {0}
private

Definition at line 119 of file LArBarrelGeometry.h.

119{0};

◆ m_testbeam

Gaudi::Property<bool> LArG4::Barrel::Geometry::m_testbeam {this, "TestBeam", false}
private

Definition at line 71 of file LArBarrelGeometry.h.

71{this, "TestBeam", false};

◆ m_xc

double* LArG4::Barrel::Geometry::m_xc {nullptr}
private

Definition at line 102 of file LArBarrelGeometry.h.

102{nullptr};

◆ m_yc

double* LArG4::Barrel::Geometry::m_yc {nullptr}
private

Definition at line 103 of file LArBarrelGeometry.h.

103{nullptr};

◆ m_zMaxBarrel

double LArG4::Barrel::Geometry::m_zMaxBarrel {0.}
private

Definition at line 84 of file LArBarrelGeometry.h.

84{0.};

◆ m_zMaxBarrelDMMargin

double LArG4::Barrel::Geometry::m_zMaxBarrelDMMargin {0.}
private

Definition at line 85 of file LArBarrelGeometry.h.

85{0.};

◆ m_zMinBarrel

double LArG4::Barrel::Geometry::m_zMinBarrel {0.}
private

Definition at line 83 of file LArBarrelGeometry.h.

83{0.};

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