ATLAS Offline Software
Loading...
Searching...
No Matches
BarrelFastSimDedicatedSD.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
14#include "CLHEP/Geometry/Point3D.h"
15#include "CLHEP/Geometry/Transform3D.h"
17
18using HepGeom::Point3D;
19using HepGeom::Transform3D;
20using CLHEP::Hep3Vector;
21
22// Constructor:
24 : IFastSimDedicatedSD("BarrelFastSimDedicatedSD", detStore)
25 , m_embManager(nullptr)
26 , m_accordionDetails(nullptr)
27 , m_absorberSections(nullptr)
28{
29 if (verbose) { G4cout << GetName() << "::initialize()" << G4endl; }
30 if ( detStore->retrieve( m_embManager ).isFailure() ){
31 throw std::runtime_error("Could not retrieve EMB manager");
32 }
33 m_accordionDetails=m_embManager->getAccordionDetails();
34 m_absorberSections=m_accordionDetails->getAbsorberSections();
35}
36
37// ProcessHitsMethod
38void BarrelFastSimDedicatedSD::ProcessSpot(const EnergySpot & spot, double weight){
39
40 // Fill the identifier.
41 Point3D<double> globalPosition=spot.GetPosition();
42
43 static const Transform3D xfNeg = Amg::EigenTransformToCLHEP(m_embManager->getDetectorRegion(0,0,0)->getAbsoluteTransform().inverse());
44 static const Transform3D xfPos = Amg::EigenTransformToCLHEP(m_embManager->getDetectorRegion(1,0,0)->getAbsoluteTransform().inverse());
45
46 Point3D<double> localPosition = globalPosition.z()<0 ? xfNeg*globalPosition : xfPos*globalPosition;
47 int zIndex = globalPosition.z() <0 ? 0:1;
48 double eta = localPosition.getEta();
49 double phi = localPosition.getPhi();
50 double r = localPosition.perp();
51
52 bool implementWaves=true;
53
55 for (e=m_embManager->beginDetectorRegion();e!=m_embManager->endDetectorRegion(); ++e) {
56 const EMBDetectorRegion *region = *e;
57 if (region->getEndcapIndex()!=zIndex) continue;
58 const EMBDetDescr *regionDescriptor=region->getDescriptor();
59 const CellBinning & etaBinning=regionDescriptor->getEtaBinning();
60 if (eta>etaBinning.getStart() && eta<etaBinning.getEnd()) {
61 unsigned int etaIndex = int((eta - etaBinning.getStart())/etaBinning.getDelta()) + etaBinning.getFirstDivisionNumber();
62 unsigned int phiIndex = 0;
63 EMBCellConstLink cellPtr = region->getEMBCell(etaIndex,phiIndex);
64 double rmax = cellPtr->getRLocal(EMBCell::BACK);
65 double rmin = cellPtr->getRLocal(EMBCell::FRONT);
66 if (r>rmin && r<rmax) {
67 const CellBinning & phiBinning=regionDescriptor->getPhiBinning();
68 double minPhi=std::min(phiBinning.getStart(), phiBinning.getEnd());
69 double maxPhi=std::max(phiBinning.getStart(), phiBinning.getEnd());
70
71 while (phi<minPhi) phi += 2*M_PI;
72 while (phi>maxPhi) phi -= 2*M_PI;
73 unsigned int regionIndex = region->getRegionIndex();
74 unsigned int samplingIndex = region->getSamplingIndex();
75 unsigned int phiIndex = int((phi - phiBinning.getStart())/phiBinning.getDelta()) + phiBinning.getFirstDivisionNumber();
76
77 // Now get the nominal cell and see if the indices need to be corrected for the accordion waves:
78 if (samplingIndex!=0) {
79 EMBCellConstLink cellPtr=region->getEMBCell(etaIndex,phiIndex);
80
81 double delta=-2.0*M_PI/1024/2;
82
83 double phiLocalUpper=cellPtr->getPhiLocalUpper()-delta;
84 double phiLocalLower=cellPtr->getPhiLocalLower()-delta;
85
86 while (phiLocalLower<0) phiLocalLower += 2.0*M_PI;
87 while (phiLocalUpper<0) phiLocalUpper += 2.0*M_PI;
88 while (phiLocalLower>2*M_PI) phiLocalLower -= 2.0*M_PI;
89 while (phiLocalUpper>2*M_PI) phiLocalUpper -= 2.0*M_PI;
90
91 int accordionIndexUpper=int(phiLocalUpper/(2*M_PI)*1024+0.25); if (accordionIndexUpper==1024) accordionIndexUpper=0;
92 int accordionIndexLower=int(phiLocalLower/(2*M_PI)*1024+0.25); if (accordionIndexLower==1024) accordionIndexLower=0;
93
94 Point3D<double> A0 =
95 ( Point3D<double>(m_absorberSections->XCent(accordionIndexLower,1),m_absorberSections->YCent(accordionIndexLower,1),0)+
96 Point3D<double>(m_absorberSections->XCent(accordionIndexUpper,1),m_absorberSections->YCent(accordionIndexUpper,1),0))/2.0;
97
98 Point3D<double> A1=
99 (Point3D<double>(m_absorberSections->XCent(accordionIndexLower,12),m_absorberSections->YCent(accordionIndexLower,12),0)+
100 Point3D<double>(m_absorberSections->XCent(accordionIndexUpper,12),m_absorberSections->YCent(accordionIndexUpper,12),0))/2.0-A0;
101
102 Point3D<double> P0=Point3D<double>(localPosition.x(), localPosition.y(),0)-A0;
103 int stackIndex=int(A1.dot(P0)/A1.mag2()*22.0 + 3.0)/2 ;
104
105 if (stackIndex<0 || stackIndex>13) {
106 G4cout << "Warning, bad stack index " << stackIndex << ' ' << rmin << ' ' << r << ' ' << A0.perp() << ' ' << A0 << ' ' << A1 << ' ' << P0 << G4endl;
107 if (implementWaves) return;
108 } else {
109 double xcent = m_absorberSections->XCent (accordionIndexLower,stackIndex);
110 double ycent = m_absorberSections->YCent (accordionIndexLower,stackIndex);
111 double cosU = m_absorberSections->Cosu (accordionIndexLower,stackIndex);
112 double sinU = m_absorberSections->Sinu (accordionIndexLower,stackIndex);
113 double halfLength = m_absorberSections->HalfLength(accordionIndexLower,stackIndex);
114
115 Point3D<double> u(xcent-halfLength*cosU, ycent-halfLength*sinU,0);
116 Point3D<double> v(xcent+halfLength*cosU, ycent+halfLength*sinU,0);
117 Point3D<double> x=v-u,y=Hep3Vector(localPosition.x(),localPosition.y(),0)-u;
118 if ((zIndex==0 && x.cross(y).z()>0) || (zIndex==1&& x.cross(y).z()<0)) {
119 if (implementWaves) {
120 if (phiIndex==0) phiIndex=phiBinning.getNumDivisions()-1;
121 else phiIndex--;
122 }
123 } else {
124 double xcent = m_absorberSections->XCent (accordionIndexUpper,stackIndex);
125 double ycent = m_absorberSections->YCent (accordionIndexUpper,stackIndex);
126 double cosU = m_absorberSections->Cosu (accordionIndexUpper,stackIndex);
127 double sinU = m_absorberSections->Sinu (accordionIndexUpper,stackIndex);
128 double halfLength = m_absorberSections->HalfLength(accordionIndexUpper,stackIndex);
129
130 Point3D<double> u(xcent-halfLength*cosU, ycent-halfLength*sinU,0);
131 Point3D<double> v(xcent+halfLength*cosU, ycent+halfLength*sinU,0);
132 Point3D<double> x=v-u,y=Hep3Vector(localPosition.x(),localPosition.y(),0)-u;
133 if ((zIndex==0 && x.cross(y).z()<0) || (zIndex==1 && x.cross(y).z()>0)) {
134 if (implementWaves) {
135 if (phiIndex==phiBinning.getNumDivisions()-1) phiIndex=0;
136 else phiIndex++;
137 }
138 }
139 }
140 }
141 }
142
143 //static LArG4Identifier id;
144 m_larID.clear();
145 m_larID << 4 // LArCalorimeter
146 << 1 // LArEM
147 << ((zIndex==0) ? -1:1)
148 << samplingIndex
149 << regionIndex
150 << etaIndex
151 << phiIndex;
152 // call process to add this to the collection
153 SimpleHit(m_larID, spot.GetTime(), spot.GetEnergy()*weight);
154
155 return;
156 }
157 }
158 }
159
160}
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
Eigen::Affine3d Transform3D
#define y
#define x
const EMBDetectorManager * m_embManager
void ProcessSpot(const EnergySpot &spot, double weight) override final
ProcessHitsMethod.
const GeoStraightAccSection * m_absorberSections
BarrelFastSimDedicatedSD(StoreGateSvc *, bool verbose)
LArG4Identifier m_larID
My LAr identifier.
const EMBAccordionDetails * m_accordionDetails
@ BACK
Definition EMBCell.h:33
@ FRONT
Definition EMBCell.h:33
Descriptor for regions of the electromagnetic barrel calorimeter.
Definition EMBDetDescr.h:27
const CellBinning & getPhiBinning() const
The Binning in Phi.
const CellBinning & getEtaBinning() const
The Binning in Eta.
std::vector< constEMBDetectorRegion * >::const_iterator DetectorRegionConstIterator
const EMBDetDescr * getDescriptor() const
Returns the Descriptor for this region.
EMBCellConstLink getEMBCell(unsigned int ieta, unsigned int iphi) const
Access to Cells.
unsigned int getSamplingIndex() const
Returns the Sampling Layer Index.
EMBDetectorRegion::DetectorSide getEndcapIndex() const
The endcap index.
unsigned int getRegionIndex() const
Returns the Region Index.
G4ThreeVector GetPosition() const
Definition EnergySpot.h:40
G4double GetEnergy() const
Definition EnergySpot.h:37
G4double GetTime() const
Definition EnergySpot.h:43
IFastSimDedicatedSD(const std::string &name, StoreGateSvc *detStore)
Simple constructor and destructor.
G4bool SimpleHit(const LArG4Identifier &lar_id, G4double time, G4double energy)
First method translates to this - also for fast sims.
The Athena Transient Store API.
int r
Definition globals.cxx:22
bool verbose
Definition hcg.cxx:73
HepGeom::Transform3D EigenTransformToCLHEP(const Amg::Transform3D &eigenTransf)
Converts an Eigen-based Amg::Transform3D into a CLHEP-based HepGeom::Transform3D.