ATLAS Offline Software
Public Types | Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
FastCaloSimCaloExtrapolation Class Reference

#include <FastCaloSimCaloExtrapolation.h>

Inheritance diagram for FastCaloSimCaloExtrapolation:
Collaboration diagram for FastCaloSimCaloExtrapolation:

Public Types

enum  SUBPOS { SUBPOS_MID = TFCSExtrapolationState::SUBPOS_MID, SUBPOS_ENT = TFCSExtrapolationState::SUBPOS_ENT, SUBPOS_EXT = TFCSExtrapolationState::SUBPOS_EXT }
 
enum  HITPOSITION { INSIDE, OUTSIDE, ON }
 

Public Member Functions

 FastCaloSimCaloExtrapolation (const std::string &t, const std::string &n, const IInterface *p)
 
 ~FastCaloSimCaloExtrapolation ()=default
 
virtual StatusCode initialize () override final
 
virtual StatusCode finalize () override final
 
virtual void extrapolate (TFCSExtrapolationState &result, const TFCSTruthState *truth, const std::vector< G4FieldTrack > &caloSteps) const override final
 
virtual void extrapolate (TFCSExtrapolationState &result, const TFCSTruthState *truth) const override final
 

Protected Member Functions

const IFastCaloSimGeometryHelperGetCaloGeometry () const
 
bool extrapolateToCylinder (const std::vector< G4FieldTrack > &caloSteps, float cylR, float cylZ, Amg::Vector3D &extPos, Amg::Vector3D &momDir) const
 Finds best extrapolation extPos from the caloSteps for a cylinder defined by radius cylR and half-length cylZ as well as corresponding momentum direction. More...
 
void extrapolateToID (TFCSExtrapolationState &result, const std::vector< G4FieldTrack > &caloSteps, const TFCSTruthState *truth) const
 Extrapolates to ID using three uniquely defined cylinder surfaces. More...
 
void extrapolateToLayers (TFCSExtrapolationState &result, const std::vector< G4FieldTrack > &caloSteps, const TFCSTruthState *truth) const
 Extrapolates to all other layers of the calorimeter. More...
 
void findPCA (float cylR, float cylZ, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2, Amg::Vector3D &PCA) const
 Finds Point of Closest Approach (PCA) on the cylinder defined by radius cylR and half-length cylZ of a line segment spanned by two hit positions to a cylinder. More...
 
void getIterativePCA (float cylR, float cylZ, Amg::Vector3D &BoundA, Amg::Vector3D &BoundB, Amg::Vector3D &PCA) const
 Finds PCA iteratively given two bounds A and B on a line segment, used for (rare) cases with no easy analytical solutions. More...
 
bool extrapolateWithIntersection (const std::vector< G4FieldTrack > &caloSteps, float cylR, float cylZ, Amg::Vector3D &extPos, Amg::Vector3D &momDir) const
 Extrapolates position on cylinder by finding intersections of subsequent hit positions, intersection is considered if we detect a travel through the surface with the line segment or we find a forward intersection (in the travel direction of the particle) which lies on the line segment, returns false if no such postion is found. More...
 
bool extrapolateWithPCA (const std::vector< G4FieldTrack > &caloSteps, float cylR, float cylZ, Amg::Vector3D &extPos, Amg::Vector3D &momDir) const
 Extrapolates to the cylinder using the PCA to the polygon spanned by the individual line segments from the caloSteps. More...
 
int whichIntersection (float cylR, float cylZ, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2, Amg::Vector3D &intersectionA, Amg::Vector3D intersectionB) const
 Returns ID of more sensible intersection between line segment spanned by hitPos1 and hitPos2 and cylinder. More...
 
int circleLineIntersection2D (float circR, Amg::Vector3D &pointA, Amg::Vector3D &pointB, Amg::Vector3D &intersectA, Amg::Vector3D &intersectB) const
 Analytically computes 2D intersections between circle of radius circR and (infinite) line spanned by pointA nad pointB. More...
 
int cylinderLineIntersection (float cylR, float cylZ, Amg::Vector3D &pointA, Amg::Vector3D &pointB, Amg::Vector3D &intersectA, Amg::Vector3D &intersectB) const
 Analytically computes the intersection between the (infinite) line defined by pointA and pointB and the cylinder cover (without endcaps) More...
 
CylinderIntersections getCylinderIntersections (float cylR, float cylZ, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2) const
 Analytically computes the intersection between the (infinite) line spanned by hitPos1 and hitPos2 with a cylinder. More...
 
void minmaxeta (int sample, double eta, double &mineta, double &maxeta) const
 
bool isCaloBarrel (int sample) const
 
double deta (int sample, double eta) const
 
double rzmid (int sample, double eta) const
 
double rzent (int sample, double eta) const
 
double rzext (int sample, double eta) const
 
double rmid (int sample, double eta) const
 
double rent (int sample, double eta) const
 
double rext (int sample, double eta) const
 
double zmid (int sample, double eta) const
 
double zent (int sample, double eta) const
 
double zext (int sample, double eta) const
 
double rpos (int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const
 
double zpos (int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const
 
double rzpos (int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const
 

Static Protected Member Functions

static double getPointLineSegmentDistance (Amg::Vector3D &point, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2)
 Computes the distance between a point and the line segment spanned by hitPos1 and hitPos2. More...
 
static bool isOnSegment (Amg::Vector3D &point, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2)
 Returns true if point lies on the line segment spanned by hitPos1 and hitPos2, otherwise returns false. More...
 
static bool cylinderEndcapIntersection (float cylR, float cylZ, bool positiveEndcap, Amg::Vector3D &pointA, Amg::Vector3D &pointB, Amg::Vector3D &intersection)
 Computes intersection between the (infinite) line spanned by pointA and pointB with the positive (negative) endcap of a cylinder, returns true if intersection is found. More...
 
static bool doesTravelThroughSurface (float cylR, float cylZ, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2)
 Returns true if the line segment spanned by hitPos1 and hitPos2 crosses the cylinder surface, false otherwise. More...
 
static enum HITPOSITION whereOnCylinder (float cylR, float cylZ, Amg::Vector3D &hitPos)
 Checks if position of hitPos is inside, outside or on the cylinder bounds. More...
 
static Amg::Vector3D projectOnCylinder (float cylR, float cylZ, Amg::Vector3D &hitPos)
 Projects position hitPos onto the cylinder surface and returns projected position. More...
 

Protected Attributes

HepPDT::ParticleDataTable * m_particleDataTable {nullptr}
 
FloatArrayProperty m_CaloBoundaryR {this, "CaloBoundaryR", {1148.0,120.0,41.0}}
 
FloatArrayProperty m_CaloBoundaryZ {this, "CaloBoundaryZ", {3550.0,4587.0,4587.0}}
 
PublicToolHandle< IFastCaloSimCaloTransportationm_CaloTransportation {this, "CaloTransportation", "FastCaloSimCaloTransportation"}
 
PublicToolHandle< IFastCaloSimGeometryHelperm_CaloGeometryHelper {this, "CaloGeometryHelper", "FastCaloSimGeometryHelper"}
 

Detailed Description

Definition at line 31 of file FastCaloSimCaloExtrapolation.h.

Member Enumeration Documentation

◆ HITPOSITION

Enumerator
INSIDE 
OUTSIDE 
ON 

Definition at line 48 of file FastCaloSimCaloExtrapolation.h.

48  {
49  INSIDE, //hit position is inside cylinder bounds
50  OUTSIDE, //hit position is outside cylinder bounds
51  ON //hit position is on cylinder bounds
52  };

◆ SUBPOS

Enumerator
SUBPOS_MID 
SUBPOS_ENT 
SUBPOS_EXT 

Definition at line 42 of file FastCaloSimCaloExtrapolation.h.

42  {
43  SUBPOS_MID = TFCSExtrapolationState::SUBPOS_MID, //MID=middle of calo layer
44  SUBPOS_ENT = TFCSExtrapolationState::SUBPOS_ENT, //ENT=entrance of calo layer
45  SUBPOS_EXT = TFCSExtrapolationState::SUBPOS_EXT //EXT=exit of calo layer
46  };

Constructor & Destructor Documentation

◆ FastCaloSimCaloExtrapolation()

FastCaloSimCaloExtrapolation::FastCaloSimCaloExtrapolation ( const std::string &  t,
const std::string &  n,
const IInterface *  p 
)

Definition at line 47 of file FastCaloSimCaloExtrapolation.cxx.

48  : base_class(t,n,p)
49 {
50 }

◆ ~FastCaloSimCaloExtrapolation()

FastCaloSimCaloExtrapolation::~FastCaloSimCaloExtrapolation ( )
default

Member Function Documentation

◆ circleLineIntersection2D()

int FastCaloSimCaloExtrapolation::circleLineIntersection2D ( float  circR,
Amg::Vector3D pointA,
Amg::Vector3D pointB,
Amg::Vector3D intersectA,
Amg::Vector3D intersectB 
) const
protected

Analytically computes 2D intersections between circle of radius circR and (infinite) line spanned by pointA nad pointB.

Definition at line 565 of file FastCaloSimCaloExtrapolation.cxx.

565  {
566  //find intersections intA and intB with line spanned by pointA and pointB
567  //returns number of intersections
568  //assumes circle lays in xy plane
569 
570  double dx, dy, A, B, C, det, t;
571 
572  dx = pointB[Amg::x] - pointA[Amg::x];
573  dy = pointB[Amg::y] - pointA[Amg::y];
574 
575  A = dx * dx + dy * dy;
576  B = 2 * (dx * pointA[Amg::x] + dy * pointA[Amg::y]);
577  C = pointA[Amg::x] * pointA[Amg::x] + pointA[Amg::y] * pointA[Amg::y] - circR * circR;
578 
579  det = B * B - 4 * A * C;
580 
581  if (A <= 0.0000001 || det < 0){
582  ATH_MSG_DEBUG("[circleLineIntersection2D] No intersections.");
583  return 0;
584  }
585  else if (std::abs(det) < 0.00001){
586  //one solution, tangential case.
587  t = -B / (2 * A);
588  intersectA = {pointA[Amg::x] + t * dx, pointA[Amg::y] + t * dy, pointA[Amg::z]};
589  ATH_MSG_DEBUG("[circleLineIntersection2D] One intersection at ("<<intersectA[Amg::x]<<","<<intersectA[Amg::y]<<","<<intersectA[Amg::z]<<").");
590  return 1;
591  }
592  else{
593  // two solutions
594  t = (-B + std::sqrt(det)) / (2 * A);
595  intersectA = {pointA[Amg::x] + t * dx, pointA[Amg::y] + t * dy, pointA[Amg::z]};
596  t = (-B - std::sqrt(det)) / (2 * A);
597  intersectB = {pointA[Amg::x] + t * dx, pointA[Amg::y] + t * dy, pointB[Amg::z]};
598  ATH_MSG_DEBUG("[circleLineIntersection2D] Two intersections at ("<<intersectA[Amg::x]<<","<<intersectA[Amg::y]<<","<<intersectA[Amg::z]<<") and at ("<<intersectB[Amg::x]<<","<<intersectB[Amg::y]<<","<<intersectB[Amg::z]<<").");
599  return 2;
600  }
601 
602 
603 }

◆ cylinderEndcapIntersection()

bool FastCaloSimCaloExtrapolation::cylinderEndcapIntersection ( float  cylR,
float  cylZ,
bool  positiveEndcap,
Amg::Vector3D pointA,
Amg::Vector3D pointB,
Amg::Vector3D intersection 
)
staticprotected

Computes intersection between the (infinite) line spanned by pointA and pointB with the positive (negative) endcap of a cylinder, returns true if intersection is found.

Definition at line 772 of file FastCaloSimCaloExtrapolation.cxx.

772  {
773 
774  //normal and point on endcap defines the plane
775  Amg::Vector3D pointOnEndcap;
776  Amg::Vector3D normal(0, 0, 1);
777  positiveEndcap ? pointOnEndcap = {0, 0, cylZ} : pointOnEndcap = {0, 0, -cylZ};
778  Amg::Vector3D hitDir = (pointB - pointA);
779 
780  double denom = normal.dot(hitDir);
781  if (std::abs(denom) > 1e-6) {
782  double t = normal.dot(pointOnEndcap - pointB)/denom;
783  //compute intersection regardless of direction (t>0 or t<0)
784  intersection = pointB + t*hitDir;
785  Amg::Vector3D v = intersection - pointOnEndcap;
786 
787  //check if intersection is within cylR bounds
788  return std::sqrt(v.dot(v)) <= cylR;
789 
790  }
791 
792  return false;
793 
794  }

◆ cylinderLineIntersection()

int FastCaloSimCaloExtrapolation::cylinderLineIntersection ( float  cylR,
float  cylZ,
Amg::Vector3D pointA,
Amg::Vector3D pointB,
Amg::Vector3D intersectA,
Amg::Vector3D intersectB 
) const
protected

Analytically computes the intersection between the (infinite) line defined by pointA and pointB and the cylinder cover (without endcaps)

Definition at line 730 of file FastCaloSimCaloExtrapolation.cxx.

730  {
731 
732  //projections of points spanning the line onto the xy plane
733  Amg::Vector3D projPointA(pointA[Amg::x], pointA[Amg::y], 0);
734  Amg::Vector3D projPointB(pointB[Amg::x], pointB[Amg::y], 0);
735  Amg::Vector3D projDiff = projPointA - projPointB;
736 
737  //calculate distance from (0,0,0) to line spanned by projPointA and projPointB
738  double projDiffNorm2 = projDiff.dot(projDiff);
739  double t = projPointA.dot(projDiff) / projDiffNorm2;
740  double d2 = projPointA.dot(projPointA) - t*t*projDiffNorm2;
741 
742  if(d2 < 0){
743  ATH_MSG_COND("[cylinderLineIntersection] Got negative distance (d2="<<d2<<"). Forcing to 0.", d2 > -0.001);
744  d2 = 0;
745  }
746 
747  //if distance larger than cylinder radius then there are no intersection and we are done
748  if(d2 > cylR*cylR) return 0;
749 
750  double k = std::sqrt((cylR*cylR - d2)/projDiffNorm2);
751 
752  intersectA = pointA + (t+k)*(pointB - pointA);
753  intersectB = pointA + (t-k)*(pointB - pointA);
754 
755  //check if intersection is outside z bounds
756  bool IntAisValid = (intersectA[Amg::z] <= cylZ && intersectA[Amg::z] >= -cylZ);
757  bool IntBisValid = (intersectB[Amg::z] <= cylZ && intersectB[Amg::z] >= -cylZ);
758 
759  if(IntAisValid && IntBisValid) return 2;
760  else if(IntAisValid) return 1;
761  else if(IntBisValid){
762  intersectA = intersectB;
763  return 1;
764  }
765 
766 
767  return 0;
768 
769 }

◆ deta()

double FastCaloSimCaloExtrapolation::deta ( int  sample,
double  eta 
) const
protected

Definition at line 880 of file FastCaloSimCaloExtrapolation.cxx.

881 {
882  return GetCaloGeometry()->deta(sample, eta);
883 }

◆ doesTravelThroughSurface()

bool FastCaloSimCaloExtrapolation::doesTravelThroughSurface ( float  cylR,
float  cylZ,
Amg::Vector3D hitPos1,
Amg::Vector3D hitPos2 
)
staticprotected

Returns true if the line segment spanned by hitPos1 and hitPos2 crosses the cylinder surface, false otherwise.

Definition at line 866 of file FastCaloSimCaloExtrapolation.cxx.

866  {
867  //travel through surface in case one hit position is outside and the other outside of cylinder surface
868  return (whereOnCylinder(cylR, cylZ, hitPos1) == INSIDE) ^ (whereOnCylinder(cylR, cylZ, hitPos2) == INSIDE);
869 }

◆ extrapolate() [1/2]

void FastCaloSimCaloExtrapolation::extrapolate ( TFCSExtrapolationState result,
const TFCSTruthState truth 
) const
finaloverridevirtual

Definition at line 84 of file FastCaloSimCaloExtrapolation.cxx.

84  {
85 
86  ATH_MSG_DEBUG("[extrapolate] Initializing transport of track through calorimeter system with ATLAS tracking tools.");
87  std::vector<G4FieldTrack> caloSteps = m_CaloTransportation -> transport(truth, false);
88  ATH_MSG_DEBUG("[extrapolate] Finalized transport of track through calorimeter system with ATLAS tracking tools.");
89 
90  extrapolate(result, truth, caloSteps);
91 }

◆ extrapolate() [2/2]

void FastCaloSimCaloExtrapolation::extrapolate ( TFCSExtrapolationState result,
const TFCSTruthState truth,
const std::vector< G4FieldTrack > &  caloSteps 
) const
finaloverridevirtual

Definition at line 72 of file FastCaloSimCaloExtrapolation.cxx.

72  {
73 
74  ATH_MSG_DEBUG("[extrapolate] Initializing extrapolation to ID-Calo boundary");
75  extrapolateToID(result, caloSteps, truth);
76 
77  ATH_MSG_DEBUG("[extrapolate] Initializing extrapolation to calorimeter layers");
78  extrapolateToLayers(result, caloSteps, truth);
79 
80  ATH_MSG_DEBUG("[extrapolate] Extrapolation done");
81 
82 }

◆ extrapolateToCylinder()

bool FastCaloSimCaloExtrapolation::extrapolateToCylinder ( const std::vector< G4FieldTrack > &  caloSteps,
float  cylR,
float  cylZ,
Amg::Vector3D extPos,
Amg::Vector3D momDir 
) const
protected

Finds best extrapolation extPos from the caloSteps for a cylinder defined by radius cylR and half-length cylZ as well as corresponding momentum direction.

Definition at line 237 of file FastCaloSimCaloExtrapolation.cxx.

237  {
238 
239  if(caloSteps.size() == 1){
240  Amg::Vector3D hitPos = Amg::Hep3VectorToEigen(caloSteps.at(0).GetPosition());
241  ATH_MSG_DEBUG("[extrapolateWithPCA(R="<<cylR<<",Z="<<cylZ<<")] Extrapolating single hit position to surface.");
242  extPos = projectOnCylinder(cylR, cylZ, hitPos);
243  momDir = Amg::Hep3VectorToEigen(caloSteps.at(0).GetMomentum());
244  return true;
245  }
246 
247  //if we do not find any good intersections, extrapolate to closest point on surface
248  bool foundHit = extrapolateWithIntersection(caloSteps, cylR, cylZ, extPos, momDir) ? true : extrapolateWithPCA(caloSteps, cylR, cylZ, extPos, momDir);
249 
250  if(foundHit){
251  ATH_MSG_DEBUG("[extrapolateToCylinder(R="<<cylR<<",Z="<<cylZ<<")::END] Extrapolated to cylinder with R="<<cylR<<" and Z="<<cylZ<<" at ("<< extPos[Amg::x]<<","<<extPos[Amg::y]<<","<<extPos[Amg::z]<<")");
252  }
253  else{
254  //this is not expected to ever happen
255  ATH_MSG_DEBUG("(R="<<cylR<<", Z="<<cylZ<<"::END) Extrapolation to cylinder surface failed!");
256  }
257 
258 
259  return foundHit;
260 
261 }

◆ extrapolateToID()

void FastCaloSimCaloExtrapolation::extrapolateToID ( TFCSExtrapolationState result,
const std::vector< G4FieldTrack > &  caloSteps,
const TFCSTruthState truth 
) const
protected

Extrapolates to ID using three uniquely defined cylinder surfaces.

Definition at line 94 of file FastCaloSimCaloExtrapolation.cxx.

94  {
95 
96  ATH_MSG_DEBUG("Start extrapolateToID()");
97 
98  //pT threshold of truth particles over which extrapolation failures will be printed as warnings
99  const float transverseMomWarningLimit = 500;
100 
101  //initialize values
102  result.set_IDCaloBoundary_eta(-999.);
103  result.set_IDCaloBoundary_phi(-999.);
104  result.set_IDCaloBoundary_r(0);
105  result.set_IDCaloBoundary_z(0);
106  result.set_IDCaloBoundary_AngleEta(-999.);
107  result.set_IDCaloBoundary_Angle3D(-999.);
108 
109  //magnitude of extrapolated position
110  double extPosDist = -1;
111 
112  for (unsigned int surfID = 0; surfID<3; surfID++){
113 
114  double R = m_CaloBoundaryR.value().at(surfID);
115  double Z = m_CaloBoundaryZ.value().at(surfID);
116 
117  ATH_MSG_DEBUG("[ExtrapolateToID] Extrapolating to ID-Calo boundary with ID="<<surfID<<" R="<<R<<" Z="<<Z);
118 
119  //extrapolated position and momentum direction at IDCaloBoundary
120  Amg::Vector3D extPos, momDir;
121 
122  //main extrapolation call
123  if(!extrapolateToCylinder(caloSteps, R, Z, extPos, momDir)) continue;
124 
125  double tolerance = 0.001;
126 
127  //test if z inside previous cylinder within some tolerance
128  ATH_MSG_DEBUG("[ExtrapolateToID] Testing condition 1: hit z="<< extPos[Amg::z]);
129  if(surfID > 0 && std::abs(extPos[Amg::z]) < m_CaloBoundaryZ[surfID-1] - tolerance) continue;
130  ATH_MSG_DEBUG("[ExtrapolateToID] Passed condition 1.");
131 
132  //test if r inside next cylinder within some tolerance
133  ATH_MSG_DEBUG("[ExtrapolateToID] Testing condition 2: hit r="<< extPos.perp());
134  if(surfID < m_CaloBoundaryR.size()-1 && extPos.perp() < m_CaloBoundaryR[surfID + 1] - tolerance) continue;
135  ATH_MSG_DEBUG("[ExtrapolateToID] Passed condition 2.");
136 
137  ATH_MSG_DEBUG("[ExtrapolateToID] Testing condition 3: hit magnitude="<< extPos.mag());
138  if(extPosDist >= 0 && extPos.mag() > extPosDist) continue;
139  ATH_MSG_DEBUG("[ExtrapolateToID] Passed condition 3.");
140 
141  extPosDist = extPos.mag();
142 
143  result.set_IDCaloBoundary_eta(extPos.eta());
144  result.set_IDCaloBoundary_phi(extPos.phi());
145  result.set_IDCaloBoundary_r(extPos.perp());
146  result.set_IDCaloBoundary_z(extPos[Amg::z]);
147 
148  ATH_MSG_DEBUG("[ExtrapolateToID] Setting IDCaloBoundary to eta="<<extPos.eta()<<" phi="<<extPos.phi()<< " r="<<extPos.perp()<<" z="<<extPos.z());
149 
150  //compute angle between extrapolated position vector and momentum at IDCaloBoundary
151  //can be used to correct shower shapes for particles which do not originate from {0,0,0}
152  double Angle3D = Amg::angle(extPos, momDir);
153  double AngleEta = extPos.theta() - momDir.theta();
154  result.set_IDCaloBoundary_AngleEta(AngleEta);
155  result.set_IDCaloBoundary_Angle3D(Angle3D);
156 
157  } //end of loop over surfaces
158 
159  if(result.IDCaloBoundary_eta() == -999) ATH_MSG_COND("[ExtrapolateToID] Failed extrapolation to ID-Calo boundary. \n[ExtrapolateToID] Particle with truth vertex at (" << truth->vertex().X() <<","<<truth->vertex().Y()<<","<<truth->vertex().Z()<<")"<<" with"<<" PdgId="<<truth->pdgid()<<" pT="<<truth->Pt()<<" eta="<<truth->Eta()<<" phi="<<truth->Phi()<<" E="<<truth->E()<<" Ekin_off="<<truth->Ekin_off(), truth->Pt() < transverseMomWarningLimit);
160 
161  ATH_MSG_DEBUG("[ExtrapolateToID] End extrapolateToID()");
162 
163 }

◆ extrapolateToLayers()

void FastCaloSimCaloExtrapolation::extrapolateToLayers ( TFCSExtrapolationState result,
const std::vector< G4FieldTrack > &  caloSteps,
const TFCSTruthState truth 
) const
protected

Extrapolates to all other layers of the calorimeter.

Definition at line 166 of file FastCaloSimCaloExtrapolation.cxx.

167 {
168  ATH_MSG_DEBUG("[extrapolateToLayers] Start extrapolate");
169 
170  //pT threshold of truth particles over which extrapolation failures will be printed as warnings
171  const float transverseMomWarningLimit = 500;
172 
174  // Start calo extrapolation
176 
177  //only continue if inside the calo
178  if(std::abs(result.IDCaloBoundary_eta()) < 6){
179  //now try to extrapolate to all calo layers that contain energy
181  for(int subpos=SUBPOS_MID; subpos<=SUBPOS_EXT; ++subpos){
182 
183  float cylR, cylZ;
184  if(isCaloBarrel(sample)){
185  cylR = std::abs(rpos(sample, result.IDCaloBoundary_eta(), subpos));
186  //EMB0 - EMB3 use z position of EME1 front end surface for extrapolation
187  //else extrapolate to cylinder with symmetrized maximum Z bounds
188  //set eta to a dummy value of 1000 and -1000 to force detector side
189  if(sample < 4) cylZ = result.IDCaloBoundary_eta() > 0 ? std::abs(zpos(5, 1000, 1)) : std::abs(zpos(5, -1000, 1));
190  else cylZ = 0.5*(std::abs(zpos(sample, 1000, subpos)) + std::abs(zpos(sample, -1000, subpos)));
191  }
192  else{
193  //if we are not at barrel surface, extrapolate to cylinder with maximum R to reduce extrapolation length
194  cylZ = std::abs(zpos(sample, result.IDCaloBoundary_eta(), subpos));
195  //calculate radius of cylinder we will extrapolate to
196  double mineta, maxeta, eta;
197  minmaxeta(sample, result.IDCaloBoundary_eta(), mineta, maxeta);
198  //get eta where we will look up the layer radius
199  eta = result.IDCaloBoundary_eta() > 0 ? mineta : maxeta;
200  //calculate azimuthal angle from pseudorapidity
201  double theta = 2*std::atan(std::exp(-eta));
202  //calculate maximum R of last cell of layer from z and theta
203  cylR = std::abs(cylZ*std::sqrt((1/(std::cos(theta)*std::cos(theta))) - 1));
204  }
205 
206  Amg::Vector3D extPos, momDir;
207  if(extrapolateToCylinder(caloSteps, cylR, cylZ, extPos, momDir)){
208 
209  //scale the extrapolation to fit the radius of the cylinder in the case of barrel and scale extrapolation to fit z component in case of endcap layer
210  //scale is only non-unitary in case we extrapolate to the endcaps of the cylinder for barrel and in case we extrapolate to cover for endcaps
211  //this will keep phi, eta intact and only scale r and z to fit a sensible position on the cylinder
212  double scale = 1;
213  if (isCaloBarrel(sample) && std::abs(extPos.perp()) > 1e-6) scale = cylR / extPos.perp();
214  else if (!isCaloBarrel(sample) && std::abs(extPos.z()) > 1e-6) scale = cylZ / std::abs(extPos.z());
215  //scale extrapolated position accordingly
216  extPos = scale * extPos;
217 
218  result.set_OK(sample, subpos, true);
219  result.set_phi(sample, subpos, extPos.phi());
220  result.set_z (sample, subpos, extPos.z());
221  result.set_eta(sample, subpos, extPos.eta());
222  result.set_r (sample, subpos, extPos.perp());
223  }
224  else{
225  ATH_MSG_COND(" [extrapolateToLayers] Extrapolation to cylinder failed. Sample="<<sample<<" subpos="<<subpos<<" eta="<<result.IDCaloBoundary_eta()<<" phi="<<result.IDCaloBoundary_phi()<<" r="<<result.IDCaloBoundary_r()<<" z="<<result.IDCaloBoundary_z(), truth->Pt() < transverseMomWarningLimit);
226  }
227  } //for pos
228  } //for sample
229  } //inside calo
230 
231  else ATH_MSG_COND("[extrapolateToLayers] Ups. Not inside calo. result.IDCaloBoundary_eta()="<<result.IDCaloBoundary_eta()<< "\n[extrapolateToLayers] Particle with truth vertex at (" << truth->vertex().X() <<","<<truth->vertex().Y()<<","<<truth->vertex().Z()<<")"<<" with"<<" PdgId="<<truth->pdgid()<<" pT="<<truth->Pt()<<" eta="<<truth->Eta()<<" phi="<<truth->Phi()<<" E="<<truth->E()<<" Ekin_off="<<truth->Ekin_off(), truth->Pt() < transverseMomWarningLimit);
232 
233 
234  ATH_MSG_DEBUG("[extrapolateToLayers] End extrapolateToLayers()");
235 }

◆ extrapolateWithIntersection()

bool FastCaloSimCaloExtrapolation::extrapolateWithIntersection ( const std::vector< G4FieldTrack > &  caloSteps,
float  cylR,
float  cylZ,
Amg::Vector3D extPos,
Amg::Vector3D momDir 
) const
protected

Extrapolates position on cylinder by finding intersections of subsequent hit positions, intersection is considered if we detect a travel through the surface with the line segment or we find a forward intersection (in the travel direction of the particle) which lies on the line segment, returns false if no such postion is found.

Definition at line 264 of file FastCaloSimCaloExtrapolation.cxx.

264  {
265 
266  ATH_MSG_DEBUG("[extrapolateWithIntersection(R="<<cylR<<",Z="<<cylZ<<")] Checking for cylinder intersections of line segments.");
267 
268  //counter for number of computed extrapolations, does not count cases of rejected extrapolations due to close by hit positions
269  unsigned int nExtrapolations = 0;
270  for (size_t hitID = 1; hitID < caloSteps.size(); hitID++){
271  //initialize intersection result variables
272  //get current and consecutive hit position and build hitLine
273  Amg::Vector3D hitPos1 = Amg::Hep3VectorToEigen(caloSteps.at(hitID-1).GetPosition());
274  Amg::Vector3D hitPos2 = Amg::Hep3VectorToEigen(caloSteps.at(hitID).GetPosition());
275  Amg::Vector3D hitDir = hitPos2 - hitPos1;
276 
277  ATH_MSG_DEBUG("[extrapolateWithIntersection(R="<<cylR<<",Z="<<cylZ<<")] Considering line segment between ("<<hitPos1[Amg::x]<<","<<hitPos1[Amg::y]<<","<<hitPos1[Amg::z]<<") and ("
278  <<hitPos2[Amg::x]<<","<<hitPos2[Amg::y]<<","<<hitPos2[Amg::z]<<")");
279  //get position of the hit positions on the cylinder
280  HITPOSITION cylPosHit1 = whereOnCylinder(cylR, cylZ, hitPos1);
281  HITPOSITION cylPosHit2 = whereOnCylinder(cylR, cylZ, hitPos2);
282 
283  //check if one of the hit positions already lays on the cylinder surface
284  if(cylPosHit1 == ON || cylPosHit2 == ON){
285  extPos = cylPosHit1 == ON ? hitPos1 : hitPos2;
286  momDir = cylPosHit1 == ON ? Amg::Hep3VectorToEigen(caloSteps.at(hitID-1).GetMomentum()) : Amg::Hep3VectorToEigen(caloSteps.at(hitID).GetMomentum());
287  ATH_MSG_DEBUG("[extrapolateWithIntersection(R="<<cylR<<",Z="<<cylZ<<")] Hit position already on cylinder surface.");
288  return true;
289  }
290 
291  //do not try to extrapolate with intersections if the hit position are very close together
292  if(hitDir.norm() < 0.01) continue;
293 
294  //get intersections through cylinder
295  CylinderIntersections intersections = getCylinderIntersections(cylR, cylZ, hitPos1, hitPos2);
296  nExtrapolations++;
297 
298  Amg::Vector3D selectedIntersection(0, 0, 0);
299 
300  //select the best intersection
301  if(intersections.number == 1) selectedIntersection = intersections.first;
302  else if(intersections.number > 1) selectedIntersection = whichIntersection(cylR, cylZ, hitPos1, hitPos2, intersections.first, intersections.second) == 0 ?
303  intersections.first : intersections.second;
304 
305  if(intersections.number > 0){
306 
307  bool isForwardExtrapolation = (selectedIntersection[Amg::x] - hitPos1[Amg::x]) / (hitPos2[Amg::x] - hitPos1[Amg::x]) >= 0;
308  bool travelThroughSurface = doesTravelThroughSurface(cylR, cylZ, hitPos1, hitPos2);
309 
310  //do not allow for backward extrapolation except in the case of first two (distinguishable) hit positions outside cylinder
311  //and in the case we detect a travel though the surface
312  if(nExtrapolations > 1 && !isForwardExtrapolation && !travelThroughSurface) continue;
313 
314  //check if the intersection between infinite line and cylinder lays on segment spanned by hit positions
315  bool intersectionOnSegment = isOnSegment(selectedIntersection, hitPos1, hitPos2);
316  //check if both hit positions lay outside of the cylinder
317  bool hitPosOutside = cylPosHit1 == OUTSIDE && cylPosHit2 == OUTSIDE;
318 
319  //we found our extrapolated hit position in case that either
320  //we detect that the line segment crosses the surface of the cylinder
321  //the intersection between the infinite lines and the cylinder lays on the line segment
322  //both hit positions are outside of the cylinder and there is a backwards extrapolation for the first two hit positions
323  //if this is not the case for any of the hit position pairs we will use the last two hit position for the linear extrapolation
324  //if these do not have any intersection, then we will pass back to extrapolateWithPCA
325  if(travelThroughSurface || intersectionOnSegment || (hitPosOutside && !isForwardExtrapolation && nExtrapolations == 1) || caloSteps.size()-1 == hitID){
326  //take momentum direction of hit position closest to cylinder surface
327  //alternatively one could also take the extrapolated direction normDir = hitPos2 - hitPos1
328  double distHitPos1 = (hitPos1 - projectOnCylinder(cylR, cylZ, hitPos1)).norm();
329  double distHitPos2 = (hitPos2 - projectOnCylinder(cylR, cylZ, hitPos2)).norm();
330  momDir = distHitPos1 < distHitPos2 ? Amg::Hep3VectorToEigen(caloSteps.at(hitID-1).GetMomentum()) : Amg::Hep3VectorToEigen(caloSteps.at(hitID).GetMomentum());
331  extPos = selectedIntersection;
332  return true;
333  }
334  ATH_MSG_DEBUG("[extrapolateWithIntersection(R="<<cylR<<",Z="<<cylZ<<")] Extrapolated position at ("<<selectedIntersection[Amg::x]<<","<<selectedIntersection[Amg::y]<<","<<selectedIntersection[Amg::z]<<")");
335  }
336  } //end of loop over hit positions
337 
338  return false;
339 }

◆ extrapolateWithPCA()

bool FastCaloSimCaloExtrapolation::extrapolateWithPCA ( const std::vector< G4FieldTrack > &  caloSteps,
float  cylR,
float  cylZ,
Amg::Vector3D extPos,
Amg::Vector3D momDir 
) const
protected

Extrapolates to the cylinder using the PCA to the polygon spanned by the individual line segments from the caloSteps.

Definition at line 342 of file FastCaloSimCaloExtrapolation.cxx.

342  {
343 
344  bool foundHit = false;
345  ATH_MSG_DEBUG("[extrapolateWithPCA(R="<<cylR<<",Z="<<cylZ<<")] No forward intersections with cylinder surface. Extrapolating to closest point on surface.");
346 
347  //here we also need to consider distances from line segments to the cylinder
348  double minDistToSurface = 100000;
349  for (size_t hitID = 1; hitID < caloSteps.size(); hitID++){
350 
351  Amg::Vector3D hitPos1 = Amg::Hep3VectorToEigen(caloSteps.at(hitID-1).GetPosition());
352  Amg::Vector3D hitPos2 = Amg::Hep3VectorToEigen(caloSteps.at(hitID).GetPosition());
353 
354  ATH_MSG_DEBUG("[extrapolateWithPCA(R="<<cylR<<",Z="<<cylZ<<")] Considering line segment between ("<<hitPos1[Amg::x]<<","<<hitPos1[Amg::y]<<","<<hitPos1[Amg::z]<<") and ("<<hitPos2[Amg::x]<<","<<hitPos2[Amg::y]<<","<<hitPos2[Amg::z]<<")");
355 
356  Amg::Vector3D PCA;
357  //find the point of closest approach (PCA) to the cylinder on the line segment
358  findPCA(cylR, cylZ, hitPos1, hitPos2, PCA);
359  //compute distance between PCA and cylinder
360  Amg::Vector3D cylinderSurfacePCA = projectOnCylinder(cylR, cylZ, PCA);
361  double tmpMinDistToSurface = (PCA - cylinderSurfacePCA).norm();
362 
363  ATH_MSG_DEBUG("[extrapolateWithPCA(R="<<cylR<<",Z="<<cylZ<<")] Extrapolated line segment to ("<<cylinderSurfacePCA[Amg::x]<<","<<cylinderSurfacePCA[Amg::y]<<","<<cylinderSurfacePCA[Amg::z]<<") with distance "<<tmpMinDistToSurface);
364 
365  if(tmpMinDistToSurface < minDistToSurface){
366  foundHit = true;
367  extPos = cylinderSurfacePCA;
368  //take momentum direction of hit position closest to cylinder surface
369  //alternatively one could also take the extrapolated direction normDir = hitPos2 - hitPos1
370  double distHitPos1 = (hitPos1 - projectOnCylinder(cylR, cylZ, hitPos1)).norm();
371  double distHitPos2 = (hitPos2 - projectOnCylinder(cylR, cylZ, hitPos2)).norm();
372  momDir = distHitPos1 < distHitPos2 ? Amg::Hep3VectorToEigen(caloSteps.at(hitID-1).GetMomentum()) : Amg::Hep3VectorToEigen(caloSteps.at(hitID).GetMomentum());
373 
374  minDistToSurface = tmpMinDistToSurface;
375  }
376  } //end over loop of hit postions
377 
378  return foundHit;
379 }

◆ finalize()

StatusCode FastCaloSimCaloExtrapolation::finalize ( )
finaloverridevirtual

Definition at line 66 of file FastCaloSimCaloExtrapolation.cxx.

66  {
67  ATH_MSG_INFO( "Finalizing FastCaloSimCaloExtrapolation" );
68  return StatusCode::SUCCESS;
69 }

◆ findPCA()

void FastCaloSimCaloExtrapolation::findPCA ( float  cylR,
float  cylZ,
Amg::Vector3D hitPos1,
Amg::Vector3D hitPos2,
Amg::Vector3D PCA 
) const
protected

Finds Point of Closest Approach (PCA) on the cylinder defined by radius cylR and half-length cylZ of a line segment spanned by two hit positions to a cylinder.

Definition at line 382 of file FastCaloSimCaloExtrapolation.cxx.

382  {
383  //in the following we will try to find the closest point-of-approach (PCA) to the cylinder on the line segment
384  //hit direction
385  Amg::Vector3D hitDir = hitPos2 - hitPos1;
386 
387  //project both hit positions onto the cylinder
388  Amg::Vector3D projCylinderHitPos1 = projectOnCylinder(cylR, cylZ, hitPos1);
389  Amg::Vector3D projCylinderHitPos2 = projectOnCylinder(cylR, cylZ, hitPos2);
390  //direction of line spanned by the two projected points on the cylinder surface
391  Amg::Vector3D cylinderProjDir = projCylinderHitPos2 - projCylinderHitPos1;
392 
393  //CASE A: projections on the cylinder are close enough, take one of the hit positions as PCA
394  if(cylinderProjDir.norm() < 0.0001) {PCA = hitPos1; return;};
395 
396  //CASE B: we are outside the Z bounds of the cylinder
397  if((hitPos1[Amg::z] > cylZ || hitPos1[Amg::z] < -cylZ) || (hitPos2[Amg::z] > cylZ || hitPos2[Amg::z] < -cylZ)){
398 
399  //calculate PCA to point on endcap
400  Amg::Vector3D cylZEndcap(0, 0, cylZ);
401  bool isParallelToEndcap = std::abs(hitPos1[Amg::z] - hitPos2[Amg::z]) < 0.00001;
402 
403  //Check if parallel to endcap plane
404  if(isParallelToEndcap){
405 
406  //if both inside there are infinite solutions take one in the middle
407  Amg::Vector3D intersectA, intersectB;
408  intersectA.setZero();
409  intersectB.setZero();
410  int nIntersections = circleLineIntersection2D(cylR, hitPos1, hitPos2, intersectA, intersectB);
411 
412  if(nIntersections == 2){
413 
414  bool IntAOnSegment = isOnSegment(intersectA, hitPos1, hitPos2);
415  bool IntBOnSegment = isOnSegment(intersectB, hitPos1, hitPos2);
416 
417  if(IntAOnSegment && IntBOnSegment) PCA = intersectA + 0.5*(intersectB-intersectA);
418  else if(IntAOnSegment) PCA = hitPos1.perp() <= cylR ? intersectA + 0.5*(hitPos1 - intersectA) : intersectA + 0.5*(hitPos2 - intersectA);
419  else if(IntBOnSegment) PCA = hitPos1.perp() <= cylR ? intersectB + 0.5*(hitPos1 - intersectB) : intersectB + 0.5*(hitPos2 - intersectB);
420  //intersections are not on line segment, i.e. line segment is within extended cylinder
421  else PCA = hitPos1 + 0.5*hitDir;
422 
423  }
424  else if(!intersectA.isZero() || !intersectB.isZero()){
425  //this can only happen if the extended line is tangetial to the cylinder
426  //if intersection lays on segment PCA will be intersection, if not it will be the corresponding end points
427  Amg::Vector3D intersect = intersectA.isZero() ? intersectB : intersectA;
428  Amg::Vector3D hitPos = (hitPos1 - intersect).norm() < (hitPos2 - intersect).norm() ? hitPos1 : hitPos2;
429  bool IntOnSegment = isOnSegment(intersectA, hitPos1, hitPos2);
430  PCA = IntOnSegment ? intersect : hitPos;
431 
432  }
433  else{
434  //line segment is outside extended cylinder
435  //PCA corresponds to closest distance to center {0, 0, cylZ}
436  Amg::Vector3D infLinePCA = hitPos1 + ((cylZEndcap-hitPos1).dot(hitDir)/hitDir.dot(hitDir))*(hitDir);
437 
438  if(isOnSegment(infLinePCA, hitPos1, hitPos2)) PCA = infLinePCA;
439  else PCA = (hitPos1 - infLinePCA).norm() < (hitPos2 - infLinePCA).norm() ? hitPos1 : hitPos2;
440 
441  }
442  }
443 
444  else{
445 
446  //figure out all other cases iteratively beginning with BoundA and BoundB
447  Amg::Vector3D BoundA, BoundB;
448  //this is point on line closest to {0, 0, cylZ}, always on segment
449  double t = ((cylZEndcap-hitPos1).dot(hitDir)/hitDir.dot(hitDir));
450  BoundA = t <= 0 ? hitPos1 : (t >= 1 ? hitPos2 : hitPos1 + t*hitDir);
451 
452  //calculate intersection point of line segment and endcap plane and project intersection onto cylinder
453  //check if t is between 0 and 1, if not, take hitpos as starting bound
454  t = (cylZ-hitPos1[Amg::z]) / hitDir[Amg::z];
455  BoundB = t <= 0 ? hitPos1 : (t >= 1 ? hitPos2 : hitPos1 + t*hitDir);
456  //looks for the PCA iteratively in cases there is no easy analytical solution
457  getIterativePCA(cylR, cylZ, BoundA, BoundB, PCA);
458 
459  }
460 
461  return;
462  }
463 
464  //CASE C: we are inside the Z bounds of the cylinder
465  //construct Z axis as straight line surface
466  Trk::StraightLineSurface line(Amg::Transform3D(Trk::s_idTransform), 0, cylZ);
467  //compute point of closest approach to z axis
468  //this is analogous to finding the PCA of two 3D lines
469  Trk::Intersection PCACylBounds = line.straightLineIntersection(hitPos1, hitDir.unit(), false, true);
470 
471  double distSurfHit1 = (projCylinderHitPos1 - hitPos1).norm();
472  double distSurfHit2 = (projCylinderHitPos2 - hitPos2).norm();
473 
474  //take PCA on line in case it lays on segment, otherwise take closest hit position to surface
475  PCA = isOnSegment(PCACylBounds.position, hitPos1, hitPos2) ? PCACylBounds.position : (distSurfHit1 < distSurfHit2 ? hitPos1 : hitPos2);
476 
477 }

◆ GetCaloGeometry()

const IFastCaloSimGeometryHelper* FastCaloSimCaloExtrapolation::GetCaloGeometry ( ) const
inlineprotected

Definition at line 59 of file FastCaloSimCaloExtrapolation.h.

59 {return &(*m_CaloGeometryHelper);};

◆ getCylinderIntersections()

CylinderIntersections FastCaloSimCaloExtrapolation::getCylinderIntersections ( float  cylR,
float  cylZ,
Amg::Vector3D hitPos1,
Amg::Vector3D hitPos2 
) const
protected

Analytically computes the intersection between the (infinite) line spanned by hitPos1 and hitPos2 with a cylinder.

Definition at line 649 of file FastCaloSimCaloExtrapolation.cxx.

649  {
650  //calculates intersection of infinite line with cylinder --> can have 0 or 2 intersections
651  CylinderIntersections intersections;
652 
653  //look for intersections with the cover of the cylinder
654  unsigned int nCoverIntersections = cylinderLineIntersection(cylR, cylZ, hitPos1, hitPos2, intersections.first, intersections.second);
655  if(nCoverIntersections == 2){
656  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found two cylinder intersections through cylinder cover.");
657  intersections.number = 2;
658  return intersections;
659  }
660  else if (nCoverIntersections == 1){
661 
662  Amg::Vector3D positiveEndcapIntersection, negativeEndcapIntersection;
663  bool IsPositiveEndcapIntersection = cylinderEndcapIntersection(cylR, cylZ, true, hitPos1, hitPos2, positiveEndcapIntersection);
664  bool IsNegativeEndcapIntersection = cylinderEndcapIntersection(cylR, cylZ, false, hitPos1, hitPos2, negativeEndcapIntersection);
665 
666  if(IsPositiveEndcapIntersection && IsNegativeEndcapIntersection){
667  //if we have a cover intersection we only expect one additional endcap intersection
668  //both endcap intersections can be valid in case the intersection is at the edge of the cylinder cover and endcap
669  //in that case take the endcap intersection which is further away from the cylinder cover intersection to prevent taking the same intersection twice
670  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found intersection through cylinder cover and both endcaps. Intersection seems to be at edge of cover and endcap.");
671  intersections.second = (positiveEndcapIntersection - intersections.first).norm() > (negativeEndcapIntersection - intersections.first).norm() ? positiveEndcapIntersection : negativeEndcapIntersection;
672  intersections.number = 2;
673  }
674  else if(IsPositiveEndcapIntersection) {
675  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found intersection through cylinder cover and positive endcap.");
676  intersections.second = positiveEndcapIntersection;
677  intersections.number = 2;
678  }
679  else if(IsNegativeEndcapIntersection) {
680  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found intersection through cylinder cover and negative endcap.");
681  intersections.second = negativeEndcapIntersection;
682  intersections.number = 2;
683  }
684  else{
685  //line is tangential to cylinder cover
686  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found single intersection through cylinder cover.");
687  intersections.number = 1;
688  }
689 
690  }
691  else{
692  //no cylinder cover intersections
693  Amg::Vector3D positiveEndcapIntersection, negativeEndcapIntersection;
694  bool IsPositiveEndcapIntersection = cylinderEndcapIntersection(cylR, cylZ, true, hitPos1, hitPos2, positiveEndcapIntersection);
695  bool IsNegativeEndcapIntersection = cylinderEndcapIntersection(cylR, cylZ, false, hitPos1, hitPos2, negativeEndcapIntersection);
696 
697  if(IsPositiveEndcapIntersection && IsNegativeEndcapIntersection){
698  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found intersections through both endcaps.");
699  intersections.first = positiveEndcapIntersection;
700  intersections.second = negativeEndcapIntersection;
701  intersections.number = 2;
702  }
703  else if(IsPositiveEndcapIntersection) {
704  //dont expect this to ever happen
705  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found single intersection through positive endcap. This should not happen.");
706  intersections.first = positiveEndcapIntersection;
707  intersections.number = 1;
708  }
709  else if(IsNegativeEndcapIntersection) {
710  //dont expect this to ever happen
711  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found single intersection through negative endcap. This should not happen.");
712  intersections.first = negativeEndcapIntersection;
713  intersections.number = 1;
714  }
715  else{
716  ATH_MSG_DEBUG("[getCylinderIntersections(R="<<cylR<<",Z="<<cylZ<<")] Found no cylinder intersections.");
717  //no intersections at all
718  intersections.number = 0;
719 
720  }
721  }
722 
723  return intersections;
724 
725 
726 }

◆ getIterativePCA()

void FastCaloSimCaloExtrapolation::getIterativePCA ( float  cylR,
float  cylZ,
Amg::Vector3D BoundA,
Amg::Vector3D BoundB,
Amg::Vector3D PCA 
) const
protected

Finds PCA iteratively given two bounds A and B on a line segment, used for (rare) cases with no easy analytical solutions.

Definition at line 488 of file FastCaloSimCaloExtrapolation.cxx.

488  {
489 
490  ATH_MSG_DEBUG("[getIterativePCA] Finding PCA iteratively.");
491 
492  Amg::Vector3D boundDir = BoundB - BoundA;
493  double distBounds = boundDir.norm();
494 
495  //this sets the precision of the iterative finding procedure
496  const double stepSize = 0.01;
497 
498  //if bounds are close enough together, there is nothing to do
499  //should make sure that nHalfDivisions >= 2
500  if (distBounds <= 4*stepSize){PCA = BoundA + 0.5*(BoundB - BoundA); return;}
501 
502  Amg::Vector3D tmpBoundA, tmpBoundB, tmpOnCylinderBoundA, tmpOnCylinderBoundB;
503  Amg::Vector3D resBoundA, resBoundB, resOnCylinderBoundA, resOnCylinderBoundB;
504 
505 
506  //initial positions on cylinder and distance to line segment
507  Amg::Vector3D OnCylinderBoundA = projectOnCylinder(cylR, cylZ, BoundA);
508  Amg::Vector3D OnCylinderBoundB = projectOnCylinder(cylR, cylZ, BoundB);
509 
510  double minDistA = (BoundA - OnCylinderBoundA).norm();
511  double minDistB = (BoundB - OnCylinderBoundB).norm();
512 
513  //initialize result bounds with closest input bounds as fall back option
514  if(minDistA < minDistB){
515  resBoundA = BoundA;
516  resBoundB = BoundA;
517  }
518  else{
519  resBoundA = BoundB;
520  resBoundB = BoundB;
521  }
522  double tmpMinDistA, tmpMinDistB;
523  unsigned int nHalfDivisions = (distBounds/stepSize)/2;
524  for(unsigned int step = 0; step < nHalfDivisions; step++){
525 
526  //temporary bounds on line segment
527  tmpBoundA = BoundA + (step+1)*stepSize*(boundDir/distBounds);
528  tmpBoundB = BoundB - (step+1)*stepSize*(boundDir/distBounds);
529 
530  //temporary projected bounds on cylinder
531  tmpOnCylinderBoundA = projectOnCylinder(cylR, cylZ, tmpBoundA);
532  tmpOnCylinderBoundB = projectOnCylinder(cylR, cylZ, tmpBoundB);
533 
534  //temporary minimum distance between bound on segment and bound on cylinder
535  tmpMinDistA = (tmpBoundA - tmpOnCylinderBoundA).norm();
536  tmpMinDistB = (tmpBoundB - tmpOnCylinderBoundB).norm();
537 
538  if(minDistA >= tmpMinDistA){
539  minDistA = tmpMinDistA;
540  }
541  else{
542  double t = (step*stepSize)/distBounds;
543  resBoundA = BoundA + t*boundDir;
544  resBoundB = tmpBoundA;
545  break;
546  }
547 
548  if(minDistB >= tmpMinDistB){
549  minDistB = tmpMinDistB;
550  }
551  else{
552  double t = (step*stepSize)/distBounds;
553  resBoundB = BoundB - t*boundDir;
554  resBoundA = tmpBoundB;
555  break;
556  }
557  }
558 
559  //return middle of best bounds
560  PCA = resBoundA + 0.5*(resBoundB - resBoundA);
561 
562 }

◆ getPointLineSegmentDistance()

double FastCaloSimCaloExtrapolation::getPointLineSegmentDistance ( Amg::Vector3D point,
Amg::Vector3D hitPos1,
Amg::Vector3D hitPos2 
)
staticprotected

Computes the distance between a point and the line segment spanned by hitPos1 and hitPos2.

Definition at line 834 of file FastCaloSimCaloExtrapolation.cxx.

834  {
835 
836  Amg::Vector3D hitDir = hitPos2 - hitPos1;
837  Amg::Vector3D w = point - hitPos1;
838 
839  double c1 = w.dot(hitDir);
840  if(c1 <= 0) return Amg::distance(point, hitPos1);
841  double c2 = hitDir.dot(hitDir);
842  if(c2 <= c1) return Amg::distance(point, hitPos2);
843  double t = c1/c2;
844  Amg::Vector3D vec = hitPos1 + t*hitDir;
845  return Amg::distance(point, vec);
846 
847 }

◆ initialize()

StatusCode FastCaloSimCaloExtrapolation::initialize ( )
finaloverridevirtual

Definition at line 52 of file FastCaloSimCaloExtrapolation.cxx.

53 {
54  ATH_MSG_INFO( "Initializing FastCaloSimCaloExtrapolation" );
55 
56  // Retrieve the fast calo sim geometry helper
57  ATH_CHECK(m_CaloGeometryHelper.retrieve());
58  // Retrieve the tool to transport particles through calorimeter with ATLAS tracking tools
59  ATH_CHECK(m_CaloTransportation.retrieve());
60 
61  return StatusCode::SUCCESS;
62 
63 
64 }

◆ isCaloBarrel()

bool FastCaloSimCaloExtrapolation::isCaloBarrel ( int  sample) const
protected

Definition at line 875 of file FastCaloSimCaloExtrapolation.cxx.

876 {
878 }

◆ isOnSegment()

bool FastCaloSimCaloExtrapolation::isOnSegment ( Amg::Vector3D point,
Amg::Vector3D hitPos1,
Amg::Vector3D hitPos2 
)
staticprotected

Returns true if point lies on the line segment spanned by hitPos1 and hitPos2, otherwise returns false.

Definition at line 871 of file FastCaloSimCaloExtrapolation.cxx.

871  {
872  return getPointLineSegmentDistance(point, hitPos1, hitPos2) < 0.001;
873 }

◆ minmaxeta()

void FastCaloSimCaloExtrapolation::minmaxeta ( int  sample,
double  eta,
double &  mineta,
double &  maxeta 
) const
protected

Definition at line 885 of file FastCaloSimCaloExtrapolation.cxx.

886 {
887  GetCaloGeometry()->minmaxeta(sample, eta, mineta, maxeta);
888 }

◆ projectOnCylinder()

Amg::Vector3D FastCaloSimCaloExtrapolation::projectOnCylinder ( float  cylR,
float  cylZ,
Amg::Vector3D hitPos 
)
staticprotected

Projects position hitPos onto the cylinder surface and returns projected position.

Definition at line 614 of file FastCaloSimCaloExtrapolation.cxx.

614  {
615 
616  Amg::Vector3D closestPointOnCylinder;
617  Amg::Vector3D cylAxis(0, 0, cylZ);
618 
619  //positive side
620  if(hitPos[Amg::z] >= cylZ){
621  //project hit position on x-y plane at positive side
622  Amg::Vector3D projHitPos(hitPos[Amg::x], hitPos[Amg::y], cylZ);
623 
624  //if r of hit position outside cylinder, closest hit is always on edge
625  if(hitPos.perp() > cylR) closestPointOnCylinder = cylAxis + cylR * (projHitPos - cylAxis).unit();
626  else closestPointOnCylinder = cylAxis + hitPos.perp() * (projHitPos - cylAxis).unit();
627 
628  }
629  //negative side
630  else if (hitPos[Amg::z] <= -cylZ){
631  //project hit position on x-y plane at negative side
632  Amg::Vector3D projHitPos(hitPos[Amg::x], hitPos[Amg::y], -cylZ);
633 
634  if(hitPos.perp() > cylR) closestPointOnCylinder = -cylAxis + cylR * (projHitPos + cylAxis).unit();
635  else closestPointOnCylinder = -cylAxis + hitPos.perp() * (projHitPos + cylAxis).unit();
636 
637  }
638  else{
639  Amg::Vector3D hitPosZ(0, 0, hitPos[Amg::z]);
640  closestPointOnCylinder = hitPosZ + cylR * (hitPos - hitPosZ).unit();
641  }
642 
643  return closestPointOnCylinder;
644 
645 }

◆ rent()

double FastCaloSimCaloExtrapolation::rent ( int  sample,
double  eta 
) const
protected

Definition at line 905 of file FastCaloSimCaloExtrapolation.cxx.

906 {
907  return GetCaloGeometry()->rent(sample, eta);
908 }

◆ rext()

double FastCaloSimCaloExtrapolation::rext ( int  sample,
double  eta 
) const
protected

Definition at line 920 of file FastCaloSimCaloExtrapolation.cxx.

921 {
922  return GetCaloGeometry()->rext(sample, eta);
923 }

◆ rmid()

double FastCaloSimCaloExtrapolation::rmid ( int  sample,
double  eta 
) const
protected

Definition at line 890 of file FastCaloSimCaloExtrapolation.cxx.

891 {
892  return GetCaloGeometry()->rmid(sample, eta);
893 }

◆ rpos()

double FastCaloSimCaloExtrapolation::rpos ( int  sample,
double  eta,
int  subpos = CaloSubPos::SUBPOS_MID 
) const
protected

Definition at line 935 of file FastCaloSimCaloExtrapolation.cxx.

936 {
937  return GetCaloGeometry()->rpos(sample, eta, subpos);
938 }

◆ rzent()

double FastCaloSimCaloExtrapolation::rzent ( int  sample,
double  eta 
) const
protected

Definition at line 915 of file FastCaloSimCaloExtrapolation.cxx.

916 {
917  return GetCaloGeometry()->rzent(sample, eta);
918 }

◆ rzext()

double FastCaloSimCaloExtrapolation::rzext ( int  sample,
double  eta 
) const
protected

Definition at line 930 of file FastCaloSimCaloExtrapolation.cxx.

931 {
932  return GetCaloGeometry()->rzext(sample, eta);
933 }

◆ rzmid()

double FastCaloSimCaloExtrapolation::rzmid ( int  sample,
double  eta 
) const
protected

Definition at line 900 of file FastCaloSimCaloExtrapolation.cxx.

901 {
902  return GetCaloGeometry()->rzmid(sample, eta);
903 }

◆ rzpos()

double FastCaloSimCaloExtrapolation::rzpos ( int  sample,
double  eta,
int  subpos = CaloSubPos::SUBPOS_MID 
) const
protected

Definition at line 945 of file FastCaloSimCaloExtrapolation.cxx.

946 {
947  return GetCaloGeometry()->rzpos(sample, eta, subpos);
948 }

◆ whereOnCylinder()

enum FastCaloSimCaloExtrapolation::HITPOSITION FastCaloSimCaloExtrapolation::whereOnCylinder ( float  cylR,
float  cylZ,
Amg::Vector3D hitPos 
)
staticprotected

Checks if position of hitPos is inside, outside or on the cylinder bounds.

Definition at line 834 of file FastCaloSimCaloExtrapolation.cxx.

849  {
850  //set a 1mm tolerance within which the hit position is considered to be on the cylinder surface
851  //setting this higher can lead to extrapolation failures around truth particle eta ~4
852  float tolerance = 1;
853 
854  bool isOnEndcap = hitPos.perp() <= cylR + tolerance && (hitPos[Amg::z] > 0 ? std::abs(hitPos[Amg::z] - cylZ) < tolerance : std::abs(hitPos[Amg::z] + cylZ) < tolerance);
855  bool isOnCover = std::abs(hitPos.perp() - cylR) < tolerance && hitPos[Amg::z] < cylZ && hitPos[Amg::z] > -cylZ;
856 
857  //check if hit position is on endcap or cover of cylinder
858  if(isOnEndcap || isOnCover) return HITPOSITION::ON;
859 
860  //check if hit position is inside cover
861  if(hitPos[Amg::z] < cylZ && hitPos[Amg::z] > -cylZ && hitPos.perp() < cylR) return HITPOSITION::INSIDE;
862 
863  return HITPOSITION::OUTSIDE;
864 }

◆ whichIntersection()

int FastCaloSimCaloExtrapolation::whichIntersection ( float  cylR,
float  cylZ,
Amg::Vector3D hitPos1,
Amg::Vector3D hitPos2,
Amg::Vector3D intersectionA,
Amg::Vector3D  intersectionB 
) const
protected

Returns ID of more sensible intersection between line segment spanned by hitPos1 and hitPos2 and cylinder.

Definition at line 796 of file FastCaloSimCaloExtrapolation.cxx.

796  {
797 
798  //check if the hit positions are outside or inside the cylinder surface
799  HITPOSITION cylPosHit1 = whereOnCylinder(cylR, cylZ, hitPos1);
800  HITPOSITION cylPosHit2 = whereOnCylinder(cylR, cylZ, hitPos2);
801 
802  if((cylPosHit1 == INSIDE) ^ (cylPosHit2 == INSIDE)){
803  /* CASE A: one hit position inside and one outside of the cylinder (travel through surface),
804  one intersection is on cylinder, take intersection closest to line segment */
805  ATH_MSG_DEBUG("[whichIntersection] Travel through surface.");
806  return getPointLineSegmentDistance(intersectionA, hitPos1, hitPos2) > getPointLineSegmentDistance(intersectionB, hitPos1, hitPos2);
807  }
808  else if(cylPosHit1 == INSIDE && cylPosHit2 == INSIDE){
809  /* CASE B: both hit position inside, take intersection which points towards travel direction of particle */
810  Amg::Vector3D directionA = intersectionA - hitPos2;
811  Amg::Vector3D directionB = intersectionB - hitPos2;
812  Amg::Vector3D hitDir = hitPos2 - hitPos1;
813  ATH_MSG_DEBUG("[whichIntersection] Both hit positions inside.");
814  return directionA.dot(hitDir) < directionB.dot(hitDir);
815  }
816  else{
817  // /* CASE C: both hit position outside and the intersections lay on the segment, take intersection closest to second hit position */
818  // /* CASE D: both hit positions are outside and the intersections are not on the line segment, take intersection closest to one of the hit positions */
819  double distHitPosIntersectA = (hitPos2 - intersectionA).norm();
820  double distHitPosIntersectB = (hitPos2 - intersectionB).norm();
821  ATH_MSG_DEBUG("[whichIntersection] Both hit positions outside.");
822  return distHitPosIntersectA > distHitPosIntersectB;
823  }
824 }

◆ zent()

double FastCaloSimCaloExtrapolation::zent ( int  sample,
double  eta 
) const
protected

Definition at line 910 of file FastCaloSimCaloExtrapolation.cxx.

911 {
912  return GetCaloGeometry()->zent(sample, eta);
913 }

◆ zext()

double FastCaloSimCaloExtrapolation::zext ( int  sample,
double  eta 
) const
protected

Definition at line 925 of file FastCaloSimCaloExtrapolation.cxx.

926 {
927  return GetCaloGeometry()->zext(sample, eta);
928 }

◆ zmid()

double FastCaloSimCaloExtrapolation::zmid ( int  sample,
double  eta 
) const
protected

Definition at line 895 of file FastCaloSimCaloExtrapolation.cxx.

896 {
897  return GetCaloGeometry()->zmid(sample, eta);
898 }

◆ zpos()

double FastCaloSimCaloExtrapolation::zpos ( int  sample,
double  eta,
int  subpos = CaloSubPos::SUBPOS_MID 
) const
protected

Definition at line 940 of file FastCaloSimCaloExtrapolation.cxx.

941 {
942  return GetCaloGeometry()->zpos(sample, eta, subpos);
943 }

Member Data Documentation

◆ m_CaloBoundaryR

FloatArrayProperty FastCaloSimCaloExtrapolation::m_CaloBoundaryR {this, "CaloBoundaryR", {1148.0,120.0,41.0}}
protected

Definition at line 122 of file FastCaloSimCaloExtrapolation.h.

◆ m_CaloBoundaryZ

FloatArrayProperty FastCaloSimCaloExtrapolation::m_CaloBoundaryZ {this, "CaloBoundaryZ", {3550.0,4587.0,4587.0}}
protected

Definition at line 123 of file FastCaloSimCaloExtrapolation.h.

◆ m_CaloGeometryHelper

PublicToolHandle<IFastCaloSimGeometryHelper> FastCaloSimCaloExtrapolation::m_CaloGeometryHelper {this, "CaloGeometryHelper", "FastCaloSimGeometryHelper"}
protected

Definition at line 128 of file FastCaloSimCaloExtrapolation.h.

◆ m_CaloTransportation

PublicToolHandle<IFastCaloSimCaloTransportation> FastCaloSimCaloExtrapolation::m_CaloTransportation {this, "CaloTransportation", "FastCaloSimCaloTransportation"}
protected

Definition at line 126 of file FastCaloSimCaloExtrapolation.h.

◆ m_particleDataTable

HepPDT::ParticleDataTable* FastCaloSimCaloExtrapolation::m_particleDataTable {nullptr}
protected

Definition at line 119 of file FastCaloSimCaloExtrapolation.h.


The documentation for this class was generated from the following files:
FastCaloSimCaloExtrapolation::doesTravelThroughSurface
static bool doesTravelThroughSurface(float cylR, float cylZ, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2)
Returns true if the line segment spanned by hitPos1 and hitPos2 crosses the cylinder surface,...
Definition: FastCaloSimCaloExtrapolation.cxx:866
ICaloGeometry::deta
virtual double deta(int sample, double eta) const =0
PlotCalibFromCool.norm
norm
Definition: PlotCalibFromCool.py:100
checkFileSG.line
line
Definition: checkFileSG.py:75
tolerance
constexpr double tolerance
Definition: runMdtGeoComparison.cxx:105
Trk::Intersection
Definition: Intersection.h:24
get_generator_info.result
result
Definition: get_generator_info.py:21
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
IDTPM::R
float R(const U &p)
Definition: TrackParametersHelper.h:101
Amg::angle
double angle(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
calculates the opening angle between two vectors
Definition: GeoPrimitivesHelpers.h:41
CaloCell_ID_FCS::FirstSample
@ FirstSample
Definition: FastCaloSim_CaloCell_ID.h:18
FastCaloSimCaloExtrapolation::SUBPOS_EXT
@ SUBPOS_EXT
Definition: FastCaloSimCaloExtrapolation.h:45
ICaloGeometry::rpos
virtual double rpos(int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const =0
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
Monitored::Z
@ Z
Definition: HistogramFillerUtils.h:24
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:71
extractSporadic.c1
c1
Definition: extractSporadic.py:134
DMTest::C
C_v1 C
Definition: C.h:26
FastCaloSimCaloExtrapolation::circleLineIntersection2D
int circleLineIntersection2D(float circR, Amg::Vector3D &pointA, Amg::Vector3D &pointB, Amg::Vector3D &intersectA, Amg::Vector3D &intersectB) const
Analytically computes 2D intersections between circle of radius circR and (infinite) line spanned by ...
Definition: FastCaloSimCaloExtrapolation.cxx:565
Amg::y
@ y
Definition: GeoPrimitives.h:35
FastCaloSimCaloExtrapolation::isOnSegment
static bool isOnSegment(Amg::Vector3D &point, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2)
Returns true if point lies on the line segment spanned by hitPos1 and hitPos2, otherwise returns fals...
Definition: FastCaloSimCaloExtrapolation.cxx:871
FastCaloSimCaloExtrapolation::zpos
double zpos(int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const
Definition: FastCaloSimCaloExtrapolation.cxx:940
CylinderIntersections::second
Amg::Vector3D second
Definition: FastCaloSimCaloExtrapolation.h:25
TFCSExtrapolationState::SUBPOS_ENT
@ SUBPOS_ENT
Definition: TFCSExtrapolationState.h:21
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ICaloGeometry::rmid
virtual double rmid(int sample, double eta) const =0
TFCSExtrapolationState::SUBPOS_MID
@ SUBPOS_MID
Definition: TFCSExtrapolationState.h:20
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
TFCSExtrapolationState::SUBPOS_EXT
@ SUBPOS_EXT
Definition: TFCSExtrapolationState.h:22
intersection
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Definition: compareFlatTrees.cxx:25
FastCaloSimCaloExtrapolation::extrapolateWithIntersection
bool extrapolateWithIntersection(const std::vector< G4FieldTrack > &caloSteps, float cylR, float cylZ, Amg::Vector3D &extPos, Amg::Vector3D &momDir) const
Extrapolates position on cylinder by finding intersections of subsequent hit positions,...
Definition: FastCaloSimCaloExtrapolation.cxx:264
FastCaloSimCaloExtrapolation::projectOnCylinder
static Amg::Vector3D projectOnCylinder(float cylR, float cylZ, Amg::Vector3D &hitPos)
Projects position hitPos onto the cylinder surface and returns projected position.
Definition: FastCaloSimCaloExtrapolation.cxx:614
TFCSTruthState::vertex
const TLorentzVector & vertex() const
Definition: TFCSTruthState.h:28
CylinderIntersections::first
Amg::Vector3D first
Definition: FastCaloSimCaloExtrapolation.h:24
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
ICaloGeometry::zext
virtual double zext(int sample, double eta) const =0
Amg::Hep3VectorToEigen
Amg::Vector3D Hep3VectorToEigen(const CLHEP::Hep3Vector &CLHEPvector)
Converts a CLHEP-based CLHEP::Hep3Vector into an Eigen-based Amg::Vector3D.
Definition: CLHEPtoEigenConverter.h:137
FastCaloSimCaloExtrapolation::findPCA
void findPCA(float cylR, float cylZ, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2, Amg::Vector3D &PCA) const
Finds Point of Closest Approach (PCA) on the cylinder defined by radius cylR and half-length cylZ of ...
Definition: FastCaloSimCaloExtrapolation.cxx:382
dqt_zlumi_alleff_HIST.A
A
Definition: dqt_zlumi_alleff_HIST.py:110
FastCaloSimCaloExtrapolation::getCylinderIntersections
CylinderIntersections getCylinderIntersections(float cylR, float cylZ, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2) const
Analytically computes the intersection between the (infinite) line spanned by hitPos1 and hitPos2 wit...
Definition: FastCaloSimCaloExtrapolation.cxx:649
FastCaloSimCaloExtrapolation::SUBPOS_ENT
@ SUBPOS_ENT
Definition: FastCaloSimCaloExtrapolation.h:44
FastCaloSimCaloExtrapolation::m_CaloBoundaryR
FloatArrayProperty m_CaloBoundaryR
Definition: FastCaloSimCaloExtrapolation.h:122
Amg::z
@ z
Definition: GeoPrimitives.h:36
FastCaloSimCaloExtrapolation::getPointLineSegmentDistance
static double getPointLineSegmentDistance(Amg::Vector3D &point, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2)
Computes the distance between a point and the line segment spanned by hitPos1 and hitPos2.
Definition: FastCaloSimCaloExtrapolation.cxx:834
CaloCell_ID_FCS::MaxSample
@ MaxSample
Definition: FastCaloSim_CaloCell_ID.h:47
FastCaloSimCaloExtrapolation::INSIDE
@ INSIDE
Definition: FastCaloSimCaloExtrapolation.h:49
FastCaloSimCaloExtrapolation::ON
@ ON
Definition: FastCaloSimCaloExtrapolation.h:51
ICaloGeometry::zmid
virtual double zmid(int sample, double eta) const =0
ICaloGeometry::isCaloBarrel
virtual bool isCaloBarrel(int sample) const =0
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:100
FastCaloSimCaloExtrapolation::isCaloBarrel
bool isCaloBarrel(int sample) const
Definition: FastCaloSimCaloExtrapolation.cxx:875
beamspotman.n
n
Definition: beamspotman.py:731
ICaloGeometry::minmaxeta
virtual void minmaxeta(int sample, double eta, double &mineta, double &maxeta) const =0
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::x
@ x
Definition: GeoPrimitives.h:34
WritePulseShapeToCool.det
det
Definition: WritePulseShapeToCool.py:204
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
ICaloGeometry::rext
virtual double rext(int sample, double eta) const =0
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
FastCaloSimCaloExtrapolation::whichIntersection
int whichIntersection(float cylR, float cylZ, Amg::Vector3D &hitPos1, Amg::Vector3D &hitPos2, Amg::Vector3D &intersectionA, Amg::Vector3D intersectionB) const
Returns ID of more sensible intersection between line segment spanned by hitPos1 and hitPos2 and cyli...
Definition: FastCaloSimCaloExtrapolation.cxx:796
FastCaloSimCaloExtrapolation::whereOnCylinder
static enum HITPOSITION whereOnCylinder(float cylR, float cylZ, Amg::Vector3D &hitPos)
Checks if position of hitPos is inside, outside or on the cylinder bounds.
Definition: FastCaloSimCaloExtrapolation.cxx:849
Trk::Intersection::position
Amg::Vector3D position
Definition: Intersection.h:25
FastCaloSimCaloExtrapolation::m_CaloBoundaryZ
FloatArrayProperty m_CaloBoundaryZ
Definition: FastCaloSimCaloExtrapolation.h:123
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
compute_lumi.denom
denom
Definition: compute_lumi.py:76
FastCaloSimCaloExtrapolation::OUTSIDE
@ OUTSIDE
Definition: FastCaloSimCaloExtrapolation.h:50
FastCaloSimCaloExtrapolation::m_CaloGeometryHelper
PublicToolHandle< IFastCaloSimGeometryHelper > m_CaloGeometryHelper
Definition: FastCaloSimCaloExtrapolation.h:128
tolerance
Definition: suep_shower.h:17
ATH_MSG_COND
#define ATH_MSG_COND(MSG, CONDITION)
Definition: FastCaloSimCaloExtrapolation.cxx:37
CylinderIntersections::number
unsigned int number
Definition: FastCaloSimCaloExtrapolation.h:26
FastCaloSimCaloExtrapolation::cylinderEndcapIntersection
static bool cylinderEndcapIntersection(float cylR, float cylZ, bool positiveEndcap, Amg::Vector3D &pointA, Amg::Vector3D &pointB, Amg::Vector3D &intersection)
Computes intersection between the (infinite) line spanned by pointA and pointB with the positive (neg...
Definition: FastCaloSimCaloExtrapolation.cxx:772
Amg
Definition of ATLAS Math & Geometry primitives (Amg)
Definition: AmgStringHelpers.h:19
FastCaloSimCaloExtrapolation::cylinderLineIntersection
int cylinderLineIntersection(float cylR, float cylZ, Amg::Vector3D &pointA, Amg::Vector3D &pointB, Amg::Vector3D &intersectA, Amg::Vector3D &intersectB) const
Analytically computes the intersection between the (infinite) line defined by pointA and pointB and t...
Definition: FastCaloSimCaloExtrapolation.cxx:730
compileRPVLLRates.c2
c2
Definition: compileRPVLLRates.py:361
dqt_zlumi_alleff_HIST.B
B
Definition: dqt_zlumi_alleff_HIST.py:110
TFCSTruthState::pdgid
int pdgid() const
Definition: TFCSTruthState.h:25
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
ICaloGeometry::rent
virtual double rent(int sample, double eta) const =0
FastCaloSimCaloExtrapolation::m_CaloTransportation
PublicToolHandle< IFastCaloSimCaloTransportation > m_CaloTransportation
Definition: FastCaloSimCaloExtrapolation.h:126
python.PyAthena.v
v
Definition: PyAthena.py:157
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
FastCaloSimCaloExtrapolation::extrapolate
virtual void extrapolate(TFCSExtrapolationState &result, const TFCSTruthState *truth, const std::vector< G4FieldTrack > &caloSteps) const override final
Definition: FastCaloSimCaloExtrapolation.cxx:72
TFCSTruthState::Ekin_off
double Ekin_off() const
Definition: TFCSTruthState.h:27
FastCaloSimCaloExtrapolation::extrapolateToLayers
void extrapolateToLayers(TFCSExtrapolationState &result, const std::vector< G4FieldTrack > &caloSteps, const TFCSTruthState *truth) const
Extrapolates to all other layers of the calorimeter.
Definition: FastCaloSimCaloExtrapolation.cxx:166
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
FastCaloSimCaloExtrapolation::SUBPOS_MID
@ SUBPOS_MID
Definition: FastCaloSimCaloExtrapolation.h:43
Amg::intersect
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the closest approach of two lines.
Definition: GeoPrimitivesHelpers.h:302
ICaloGeometry::rzent
virtual double rzent(int sample, double eta) const =0
unit
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
Definition: AmgMatrixBasePlugin.h:20
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
ICaloGeometry::zpos
virtual double zpos(int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const =0
FastCaloSimCaloExtrapolation::rpos
double rpos(int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const
Definition: FastCaloSimCaloExtrapolation.cxx:935
CylinderIntersections
Definition: FastCaloSimCaloExtrapolation.h:23
LArCellBinning.step
step
Definition: LArCellBinning.py:158
FastCaloSimCaloExtrapolation::getIterativePCA
void getIterativePCA(float cylR, float cylZ, Amg::Vector3D &BoundA, Amg::Vector3D &BoundB, Amg::Vector3D &PCA) const
Finds PCA iteratively given two bounds A and B on a line segment, used for (rare) cases with no easy ...
Definition: FastCaloSimCaloExtrapolation.cxx:488
FastCaloSimCaloExtrapolation::extrapolateToCylinder
bool extrapolateToCylinder(const std::vector< G4FieldTrack > &caloSteps, float cylR, float cylZ, Amg::Vector3D &extPos, Amg::Vector3D &momDir) const
Finds best extrapolation extPos from the caloSteps for a cylinder defined by radius cylR and half-len...
Definition: FastCaloSimCaloExtrapolation.cxx:237
ICaloGeometry::zent
virtual double zent(int sample, double eta) const =0
FastCaloSimCaloExtrapolation::GetCaloGeometry
const IFastCaloSimGeometryHelper * GetCaloGeometry() const
Definition: FastCaloSimCaloExtrapolation.h:59
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
ICaloGeometry::rzpos
virtual double rzpos(int sample, double eta, int subpos=CaloSubPos::SUBPOS_MID) const =0
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
FastCaloSimCaloExtrapolation::extrapolateToID
void extrapolateToID(TFCSExtrapolationState &result, const std::vector< G4FieldTrack > &caloSteps, const TFCSTruthState *truth) const
Extrapolates to ID using three uniquely defined cylinder surfaces.
Definition: FastCaloSimCaloExtrapolation.cxx:94
FastCaloSimCaloExtrapolation::minmaxeta
void minmaxeta(int sample, double eta, double &mineta, double &maxeta) const
Definition: FastCaloSimCaloExtrapolation.cxx:885
FastCaloSimCaloExtrapolation::HITPOSITION
HITPOSITION
Definition: FastCaloSimCaloExtrapolation.h:48
Trk::StraightLineSurface
Definition: StraightLineSurface.h:51
fitman.k
k
Definition: fitman.py:528
ICaloGeometry::rzext
virtual double rzext(int sample, double eta) const =0
FastCaloSimCaloExtrapolation::extrapolateWithPCA
bool extrapolateWithPCA(const std::vector< G4FieldTrack > &caloSteps, float cylR, float cylZ, Amg::Vector3D &extPos, Amg::Vector3D &momDir) const
Extrapolates to the cylinder using the PCA to the polygon spanned by the individual line segments fro...
Definition: FastCaloSimCaloExtrapolation.cxx:342
ICaloGeometry::rzmid
virtual double rzmid(int sample, double eta) const =0