ATLAS Offline Software
EMBAccordionDetails.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
12 #include "GaudiKernel/ISvcLocator.h"
13 #include "GaudiKernel/Bootstrap.h"
14 #include "GaudiKernel/PhysicalConstants.h"
15 #include "GaudiKernel/ServiceHandle.h"
16 #include "StoreGate/StoreGateSvc.h"
17 #include <cmath>
18 
20 
21 public:
25  int phiGap(double radius, double xhit, double yhit) const;
26 
30  void getRPhi();
31 
35  double phi0(double radius) const;
36 
40  double Distance_Ele(const double &x, const double &y,
41  const int &PhiC, int &Num_Straight, const int &Num_Coude,
42  double &xl);
46  double Distance_Abs(const double &x, const double &y,
47  const int &nabs, const int &Num_Straight, const int &Num_Coude);
48 
49  double gam0;
50  double Rmin;
51  double Rmax;
52  double dR;
53  double Rphi[5000];
54  int NRphi;
55  int Nbrt;
56  int Nbrt1;
57  double rint_eleFib ; //2.78
58  double delta[15]; // zig-zag angles
59  double rc[15] ; // R and
60  double phic[15] ; // phi positions of center of fold for first absorber
61  double xc[15]; // corresponding x,y values
62  double yc[15];
63  double rMinAccordion;
64  double rMaxAccordion;
65  double zMinBarrel;
66  double zMaxBarrel;
67  double etaMaxBarrel;
68  int NCellTot; // either 64 or 1024 for TestBeam or Atlas
69  int NCellMax; // 1024
70 
73 
74  ServiceHandle<StoreGateSvc> detStore{"DetectorStore","DetectorStore"};
75 };
76 
78 {
79  const double dl=0.001;
80  const double inv_dl = 1 / dl;
81  double cenx[15],ceny[15];
82  double sum1[5000],sumx[5000];
83  NRphi=5000;
84  Rmin=1500.;
85  dR=0.10;
86  Rmax=0.;
87 
88  const double rint= rint_eleFib;
89  const double inv_rint = 1. / rint;
90  const double dt=dl * inv_rint;
91  const double inv_dt = 1. / dt;
92 
93  for (int i=0;i<NRphi;i++) {
94  sum1[i]=0.;
95  sumx[i]=0.;
96  }
97  for (int i=0;i<15;i++) {
98  cenx[i]=rc[i]*cos(phic[i]);
99  ceny[i]=rc[i]*sin(phic[i]);
100  }
101 
102  for (int i=0; i<15; i++) {
103 
104 // fold
105  double phi0,phi1;
106  if (i==0) {
107  phi0=-M_PI/2.;
108  phi1=-M_PI/2.+delta[0];
109  }
110  else if (i==14) {
111  phi0=-M_PI+delta[13];
112  phi1=-M_PI/2.;
113  }
114  else {
115  if (i%2==1) {
116  phi0=delta[i];
117  phi1=M_PI-delta[i-1];
118  }
119  else {
120  phi0=-M_PI+delta[i-1];
121  phi1=-delta[i];
122  }
123  }
124  int nstep=int((phi1-phi0) * inv_dt)+1;
125  for (int ii=0;ii<nstep;ii++) {
126  double phi=phi0+dt*((double)ii);
127  double x=cenx[i]+rint*cos(phi);
128  double y=ceny[i]+rint*sin(phi);
129  double radius=sqrt(x*x+y*y);
130  if (radius>Rmax) Rmax=radius;
131  double phid=atan(y/x);
132  int ir=((int) ((radius-Rmin)/dR) );
133  if (ir>=0 && ir < NRphi) {
134  sum1[ir]+=1.;
135  sumx[ir]+=phid;
136  }
137  }
138 
139 // straight section
140  if (i<14) {
141  double dx=cenx[i+1]-cenx[i];
142  double dy=ceny[i+1]-ceny[i];
143  double along=dx*dx+dy*dy-4.*rint*rint;
144  along=sqrt(along);
145  double x0=0.5*(cenx[i+1]+cenx[i]);
146  double y0=0.5*(ceny[i+1]+ceny[i]);
147  double phi;
148  if (i%2==0) phi=M_PI/2-delta[i];
149  else phi=-M_PI/2.+delta[i];
150  double x1=x0-0.5*along*cos(phi);
151  double y1=y0-0.5*along*sin(phi);
152  int nstep=int(along * inv_dl)+1;
153  for (int ii=0;ii<nstep;ii++) {
154  double x=x1+dl*((double)ii)*cos(phi);
155  double y=y1+dl*((double)ii)*sin(phi);
156  double radius=sqrt(x*x+y*y);
157  if (radius>Rmax) Rmax=radius;
158  double phid=atan(y/x);
159  int ir=((int) ((radius-Rmin)/dR) );
160  if (ir>=0 && ir < NRphi) {
161  sum1[ir]+=1.;
162  sumx[ir]+=phid;
163  }
164  }
165  }
166  }
167  for (int i=0; i<NRphi; i++) {
168  if (sum1[i]>0) {
169  Rphi[i]=sumx[i]/sum1[i];
170  }
171  else Rphi[i]=0.;
172  }
173 }
174 
175 
176 // ======================================================================================
177 // compute number (0 to 1023) of closest electrode according to nominal
178 // accordion geometry
179 int EMBAccordionDetails::Clockwork::phiGap(double radius, double xhit, const double yhit) const
180 {
181  const double m2pi = 2.0*Gaudi::Units::pi;
182  double phi_0=phi0(radius)+gam0; // from -M_PI to M_PI
183  double phi_hit=atan2(yhit,xhit); // from -M_PI to M_PI
184  double dphi=phi_hit-phi_0;
185 // bring back to 0-2pi
186  if (dphi<0) dphi=dphi+m2pi;
187  if (dphi>=m2pi) dphi=dphi-m2pi;
188  dphi=dphi*(1024/m2pi);
189  int ngap=((int) dphi);
190  return ngap;
191 }
192 
193 
194 
196  : m_c(new Clockwork())
197 {
198  ISvcLocator *svcLocator = Gaudi::svcLocator();
199 
200  SmartIF<IGeoModelSvc> geoModel{svcLocator->service("GeoModelSvc")};
201  if(!geoModel.isValid())
202  throw std::runtime_error("Error in HECDetectorManager, cannot access GeoModelSvc");
203 
204  SmartIF<IGeoDbTagSvc> geoDbTagSvc{svcLocator->service("GeoDbTagSvc")};
205  if(!geoDbTagSvc.isValid())
206  throw std::runtime_error("Error in HECDetectorManager, cannot access GeoDbTagSvc");
207 
208  SmartIF<IRDBAccessSvc> rdbAccess{svcLocator->service(geoDbTagSvc->getParamSvcName())};
209  if(!rdbAccess.isValid())
210  throw std::runtime_error("Error in HECDetectorManager, cannot access RDBAccessSvc");
211 
212  if(m_c->detStore.retrieve().isFailure())
213  throw std::runtime_error("Error in HECDetectorManager, cannot access DetectorStore");
214 
215  std::string detectorKey, detectorNode;
216 
217  if(geoDbTagSvc->getSqliteReader()==nullptr) {
218  std::string AtlasVersion = geoModel->atlasVersion();
219  std::string LArVersion = geoModel->LAr_VersionOverride();
220 
221  detectorKey = LArVersion.empty() ? AtlasVersion : LArVersion;
222  detectorNode = LArVersion.empty() ? "ATLAS" : "LAr";
223  }
224 
225  IRDBRecordset_ptr barrelGeometry = rdbAccess->getRecordsetPtr("BarrelGeometry",detectorKey,detectorNode);
226  if (barrelGeometry->size()==0) {
227  throw std::runtime_error("Cannot find the BarrelGeometry Table");
228  }
229 
230  IRDBRecordset_ptr barrelLongDiv = rdbAccess->getRecordsetPtr("BarrelLongDiv",detectorKey,detectorNode);
231  if (barrelLongDiv->size()==0) {
232  throw std::runtime_error("Cannot find the BarrelLongDiv Table");
233  }
234 
235  // number of straight sections (should be 14)
236  m_c->Nbrt = (*barrelGeometry)[0]->getInt("NBRT");
237  // Number of ZIGs + 1 i.e. 15 = number of folds
238  m_c->Nbrt1 = m_c->Nbrt + 1;
239  // phi of first absorber
240  m_c->gam0 = (*barrelGeometry)[0]->getDouble("PHIFIRST");
241  // radius of curvature of neutral fiber in the folds
242  m_c->rint_eleFib = (*barrelGeometry)[0]->getDouble("RINT")*Gaudi::Units::cm;
243 
244  // r,phi positions of the centre of the folds (nominal geometry)
245  for (int idat = 0; idat < m_c->Nbrt1 ; idat++)
246  {
247  m_c->rc[idat] = (*barrelGeometry)[0]->getDouble("RHOCEN",idat)*Gaudi::Units::cm;
248  m_c->phic[idat] = (*barrelGeometry)[0]->getDouble("PHICEN",idat)*Gaudi::Units::deg;
249  m_c->delta[idat] = (*barrelGeometry)[0]->getDouble("DELTA",idat)*Gaudi::Units::deg;
250  m_c->xc[idat] = m_c->rc[idat]*cos(m_c->phic[idat]);
251  m_c->yc[idat] = m_c->rc[idat]*sin(m_c->phic[idat]);
252  }
253  //
254  m_c->rMinAccordion = (*barrelGeometry)[0]->getDouble("RIN_AC")*Gaudi::Units::cm;
255  m_c->rMaxAccordion = (*barrelGeometry)[0]->getDouble("ROUT_AC")*Gaudi::Units::cm;
256  m_c->etaMaxBarrel = (*barrelGeometry)[0]->getDouble("ETACUT");
257  m_c->zMinBarrel = (*barrelLongDiv)[0]->getDouble("ZMAXACT")*Gaudi::Units::cm;
258  m_c->zMaxBarrel = (*barrelLongDiv)[0]->getDouble("ZMINACT")*Gaudi::Units::cm;
259  // === GU 11/06/2003 total number of cells in phi
260  // to distinguish 1 module (testbeam case) from full Atlas
261  m_c->NCellTot = (*barrelGeometry)[0]->getInt("NCELMX");
262  m_c->NCellMax=1024;
263 
264  //====================================================
265 
266  m_c->getRPhi();
267 
268 }
269 
271  delete m_c;
272 }
273 
275  return m_c->gam0;
276 }
277 
278 
280 {
281  int ir;
282  if (radius < Rmin) ir=0;
283  else {
284  if (radius > Rmax) radius=Rmax-0.0001;
285  ir=((int) ((radius-Rmin)/dR) );
286  }
287  return Rphi[ir];
288 }
289 
290 
292  if (m_c->absorberStraightSection==nullptr) {
293  const GeoStraightAccSection* sa = nullptr;
294 
295  StatusCode status = m_c->detStore->retrieve(sa,"STRAIGHTABSORBERS");
296  if (status != StatusCode::SUCCESS) throw std::runtime_error ("Cannot locate Straight Absorbers");
297 
299 
300  }
302 
303 }
304 
305 
307  if (m_c->electrodeStraightSection==nullptr) {
308  const GeoStraightAccSection* sa = nullptr;
309 
310  StatusCode status = m_c->detStore->retrieve(sa,"STRAIGHTELECTRODES");
311  if (status != StatusCode::SUCCESS) throw std::runtime_error ("Cannot locate Straight Electrodes");
312 
314 
315  }
317 
318 }
319 
320 
321 
322 //======================================================================================
323 //
324 // Here INTRINSIC Distance_to_electrode determination (G.P.)
325 //
326 // This retuns an ALGEBRICDistEle value, the distance from electrode
327 //neutral fiber TOWARDS the Sub_Step in LAr (measured on a local perpendicular
328 //vector unit oriented upwards i.e. following increasing Phi values).
329 //
330 // This is done in THE INTRINSIC LOCAL Z > 0. half_barrel part ("stac_phys1")
331 //
332 // inputs: xhit,yhit = x,y positions in local half barrel
333 // PhiCell = electrode number in phi (0 to 1023 for Atlas case)
334 // Num_Straight = number (0 to 13) of the straight section
335 // Num_Coude = number (0 to 14) of closest fold
336 //
337 // output: Function value = algebric distance to electrode
338 // xl = normalized lenght along electrode straight section (between +-1)
339 
340 #ifdef READY
341 double EMBAccordionDetails::Clockwork::Distance_Ele(const double & xhit,
342  const double &yhit, const int &PhiCell, int &Num_Straight,
343  const int &Num_Coude, double &xl)
344 {
345  double dx, dy, dr;
346  double DistEle = 0.;
347 //
348 // FrameWork is consistent with the one used to PhiCell determination
349 // e.g. it assumes HERE to be the LOCAL one of "stac_phys1",
350 // (mother of ACCordion volumes) from which Z> 0. and Z < 0. half_barrel
351 // parts are then defined.
352 //
353 // One needs POINTERS to Electrode neutral fibers
354 // either for straight parts or for folds
355 //
356 // Fold Center ccoordinates
357  double Xc[2];
358  Xc[0] = m_coudeelec->XCentCoude(Num_Coude, PhiCell);
359  Xc[1] = m_coudeelec->YCentCoude(Num_Coude, PhiCell);
360  double radfold = sqrt(Xc[0]*Xc[0]+Xc[1]*Xc[1]);
361  double radhit = sqrt(xhit*xhit+yhit*yhit);
362 
363 // check if the assumed straight number is the correct one
364 // (this can be wrong when we are close to a fold and there is sagging)
365  if (Num_Coude == Num_Straight && radhit <radfold) {
366  if (Num_Straight>0) Num_Straight = Num_Straight-1;
367 // std::cout << "radhit,radfold " << radhit << " " << radfold << " change straight by +1" << std::endl;
368  }
369  if (Num_Coude == (Num_Straight+1) && radhit > radfold) {
370  if (Num_Straight<12) Num_Straight = Num_Straight+1;
371 // std::cout << "radhit,radfold " << radhit << " " << radfold << " change straight by -1" << std::endl;
372  }
373 
374 // u unit 2D_Vector along straight part of the electrode neutral fiber
375  double u[2];
376  u[0] = m_electrode->Cosu(Num_Straight, PhiCell);
377  u[1] = m_electrode->Sinu(Num_Straight, PhiCell);
378 // Middle m_coordinates of this straight part of the electrode neutral fiber
379  double Xm[2];
380  Xm[0] = m_electrode->XCentEle(Num_Straight, PhiCell);
381  Xm[1] = m_electrode->YCentEle(Num_Straight, PhiCell);
382 // m_Hit Vector components
383  dx = xhit - Xm[0]; dy = yhit - Xm[1];
384 
385 // First compute algebric distance m_hit (2D) the 2D_projection of the
386 // m_Hit Vector on this electrode neutral fiber.
387  double m_hit = dx*u[0] + dy*u[1];
388 
389 //
390 // Flat of Fold Region ?
391 //
392  double Half_Elec;
393  Half_Elec = m_electrode->HalfLength(Num_Straight,PhiCell);
394 
395  if(fabs(m_hit) < Half_Elec) {
396 // Flat Region
397  DistEle = u[0]*dy - u[1]*dx;
398  xl=m_hit/Half_Elec;
399  }
400  else {
401 // Fold region
402 // c_Hit Vector components and its length
403  dx = xhit - Xc[0]; dy = yhit - Xc[1]; dr = sqrt( dx*dx + dy*dy);
404  DistEle = (Num_Coude%2 == 0) ? (rint_eleFib-dr) : (dr - rint_eleFib);
405  if (Num_Coude==Num_Straight) xl=-1.;
406  else xl=+1;
407  } // end of Fold Regions
408 
409  return DistEle;
410 
411 } // end of the function Distance_Ele
412 
413 #endif
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
EMBAccordionDetails::Clockwork::Nbrt1
int Nbrt1
Definition: EMBAccordionDetails.cxx:56
EMBAccordionDetails::Clockwork
Definition: EMBAccordionDetails.cxx:19
TestSUSYToolsAlg.dl
dl
Definition: TestSUSYToolsAlg.py:81
EMBAccordionDetails::Clockwork::yc
double yc[15]
Definition: EMBAccordionDetails.cxx:62
GeoStraightAccSection
Record of All Electrode Straight Pieces.
Definition: GeoStraightAccSection.h:24
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
EMBAccordionDetails::Clockwork::absorberStraightSection
const GeoStraightAccSection * absorberStraightSection
Definition: EMBAccordionDetails.cxx:72
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
EMBAccordionDetails::Clockwork::NCellTot
int NCellTot
Definition: EMBAccordionDetails.cxx:68
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
EMBAccordionDetails::Clockwork::zMinBarrel
double zMinBarrel
Definition: EMBAccordionDetails.cxx:65
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
EMBAccordionDetails::Clockwork::electrodeStraightSection
const GeoStraightAccSection * electrodeStraightSection
Definition: EMBAccordionDetails.cxx:71
M_PI
#define M_PI
Definition: ActiveFraction.h:11
EMBAccordionDetails::Clockwork::rint_eleFib
double rint_eleFib
Definition: EMBAccordionDetails.cxx:57
deg
#define deg
Definition: SbPolyhedron.cxx:17
EMBAccordionDetails::phiFirstAbsorber
double phiFirstAbsorber() const
Phi of the first absorber.
Definition: EMBAccordionDetails.cxx:274
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:112
EMBAccordionDetails::Clockwork::zMaxBarrel
double zMaxBarrel
Definition: EMBAccordionDetails.cxx:66
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
x
#define x
EMBAccordionDetails::Clockwork::Distance_Abs
double Distance_Abs(const double &x, const double &y, const int &nabs, const int &Num_Straight, const int &Num_Coude)
Compute the distance to the absorber.
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
GeoStraightAccSection.h
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
EMBAccordionDetails::EMBAccordionDetails
EMBAccordionDetails()
Destructor.
Definition: EMBAccordionDetails.cxx:195
pi
#define pi
Definition: TileMuonFitter.cxx:65
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
EMBAccordionDetails::Clockwork::rc
double rc[15]
Definition: EMBAccordionDetails.cxx:59
EventInfoWrite.AtlasVersion
AtlasVersion
Definition: EventInfoWrite.py:17
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
lumiFormat.i
int i
Definition: lumiFormat.py:85
EMBAccordionDetails::getElectrodeSections
const GeoStraightAccSection * getElectrodeSections() const
Electrode position details:
Definition: EMBAccordionDetails.cxx:306
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CaloNoise_fillDB.dt
dt
Definition: CaloNoise_fillDB.py:58
EMBAccordionDetails::Clockwork::detStore
ServiceHandle< StoreGateSvc > detStore
Definition: EMBAccordionDetails.cxx:74
EMBAccordionDetails::Clockwork::Rmin
double Rmin
Definition: EMBAccordionDetails.cxx:50
EMBAccordionDetails::Clockwork::etaMaxBarrel
double etaMaxBarrel
Definition: EMBAccordionDetails.cxx:67
EMBAccordionDetails::Clockwork::NCellMax
int NCellMax
Definition: EMBAccordionDetails.cxx:69
EMBAccordionDetails::Clockwork::NRphi
int NRphi
Definition: EMBAccordionDetails.cxx:54
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
EMBAccordionDetails::Clockwork::xc
double xc[15]
Definition: EMBAccordionDetails.cxx:61
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
EMBAccordionDetails::Clockwork::dR
double dR
Definition: EMBAccordionDetails.cxx:52
EMBAccordionDetails::~EMBAccordionDetails
~EMBAccordionDetails()
Destructor.
Definition: EMBAccordionDetails.cxx:270
EMBAccordionDetails::Clockwork::rMinAccordion
double rMinAccordion
Definition: EMBAccordionDetails.cxx:63
EMBAccordionDetails::Clockwork::Distance_Ele
double Distance_Ele(const double &x, const double &y, const int &PhiC, int &Num_Straight, const int &Num_Coude, double &xl)
Compute the distance to the electrode.
EMBAccordionDetails::Clockwork::phi0
double phi0(double radius) const
phi of first absorber as function of radius for nominal accordion geometry (before sagging).
Definition: EMBAccordionDetails.cxx:279
EMBAccordionDetails::Clockwork::Rmax
double Rmax
Definition: EMBAccordionDetails.cxx:51
EMBAccordionDetails::Clockwork::gam0
double gam0
Definition: EMBAccordionDetails.cxx:49
ParticleGun_SamplingFraction.radius
radius
Definition: ParticleGun_SamplingFraction.py:96
ir
int ir
counter of the current depth
Definition: fastadd.cxx:49
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
EMBAccordionDetails::Clockwork::getRPhi
void getRPhi()
initialization routine
Definition: EMBAccordionDetails.cxx:77
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
y
#define y
EMBAccordionDetails::Clockwork::phiGap
int phiGap(double radius, double xhit, double yhit) const
compute number (0 to 1023) of closest electrode according to nominal accordion geometry
Definition: EMBAccordionDetails.cxx:179
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
EMBAccordionDetails::getAbsorberSections
const GeoStraightAccSection * getAbsorberSections() const
Absorber position details:
Definition: EMBAccordionDetails.cxx:291
EMBAccordionDetails::Clockwork::delta
double delta[15]
Definition: EMBAccordionDetails.cxx:58
merge.status
status
Definition: merge.py:17
EMBAccordionDetails::m_c
Clockwork * m_c
Definition: EMBAccordionDetails.h:47
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
EMBAccordionDetails.h
IGeoModelSvc.h
EMBAccordionDetails::Clockwork::phic
double phic[15]
Definition: EMBAccordionDetails.cxx:60
StoreGateSvc.h
EMBAccordionDetails::Clockwork::Nbrt
int Nbrt
Definition: EMBAccordionDetails.cxx:55
EMBAccordionDetails::Clockwork::Rphi
double Rphi[5000]
Definition: EMBAccordionDetails.cxx:53
EMBAccordionDetails::Clockwork::rMaxAccordion
double rMaxAccordion
Definition: EMBAccordionDetails.cxx:64
IGeoDbTagSvc.h
ServiceHandle< StoreGateSvc >