PseudoLayerPlugin.cxx
Go to the documentation of this file.
1 #include "PseudoLayerPlugin.h"
2 
3 //Pandora
4 #include "Pandora/AlgorithmHeaders.h"
5 #include "Helpers/XmlHelper.h"
6 
8 
9 using namespace pandora;
10 
11 namespace gar {
12  namespace gar_pandora {
13 
14  PseudoLayerPlugin::PseudoLayerPlugin()
15  : m_barrelInnerR(0.f),
16  m_endCapInnerZ(0.f),
17  m_rCorrection(0.f),
18  m_zCorrection(0.f),
19  m_barrelEdgeR(0.f),
20  m_endCapEdgeZ(0.f)
21  {}
22 
23  //------------------------------------------------------------------------------------------------------------------------------------------
24 
26  {
27  try
28  {
29  this->StoreLayerPositions();
30  this->StoreDetectorOuterEdge();
31  this->StorePolygonAngles();
33  }
34  catch (StatusCodeException &statusCodeException)
35  {
36  std::cout << "PseudoLayerPlugin: Incomplete geometry - consider using a different PseudoLayerCalculator." << std::endl;
37  return statusCodeException.GetStatusCode();
38  }
39 
40  return STATUS_CODE_SUCCESS;
41  }
42 
43  //------------------------------------------------------------------------------------------------------------------------------------------
44 
45  unsigned int PseudoLayerPlugin::GetPseudoLayer(const pandora::CartesianVector &positionVector) const
46  {
47  const float zCoordinate(std::fabs(positionVector.GetZ()));
48 
49  if (zCoordinate > m_endCapEdgeZ) {
50  MF_LOG_WARNING("PseudoLayerPlugin::GetPseudoLayer")
51  << "zCoordinate " << zCoordinate << " > m_endCapEdgeZ " << m_endCapEdgeZ << std::endl;
52  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
53  }
54 
55  const float rCoordinate(this->GetMaximumRadius(m_eCalBarrelAngleVector, positionVector.GetX(), positionVector.GetY()));
56 
57  if (rCoordinate > m_barrelEdgeR) {
58  MF_LOG_WARNING("PseudoLayerPlugin::GetPseudoLayer")
59  << "rCoordinate " << rCoordinate << " > m_barrelEdgeR " << m_barrelEdgeR << std::endl;
60  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
61  }
62 
63  unsigned int pseudoLayer;
64 
65  const StatusCode statusCode(this->GetPseudoLayer(rCoordinate, zCoordinate, m_rCorrection, m_zCorrection, m_barrelInnerR,
66  m_endCapInnerZ, pseudoLayer));
67 
68  if (STATUS_CODE_SUCCESS != statusCode)
69  throw StatusCodeException(statusCode);
70 
71  // Reserve a pseudo layer for track projections, etc.
72  return (1 + pseudoLayer);
73  }
74 
75  //------------------------------------------------------------------------------------------------------------------------------------------
76 
77  StatusCode PseudoLayerPlugin::GetPseudoLayer(const float rCoordinate, const float zCoordinate, const float rCorrection,
78  const float zCorrection, const float barrelInnerR, const float endCapInnerZ, unsigned int &pseudoLayer) const
79  {
80  if (zCoordinate < endCapInnerZ)
81  {
82  return this->FindMatchingLayer(rCoordinate, m_barrelLayerPositions, pseudoLayer);
83  }
84  else if (rCoordinate < barrelInnerR)
85  {
86  return this->FindMatchingLayer(zCoordinate, m_endCapLayerPositions, pseudoLayer);
87  }
88  else
89  {
90  unsigned int bestBarrelLayer(0);
91  const StatusCode barrelStatusCode(this->FindMatchingLayer(rCoordinate - rCorrection, m_barrelLayerPositions, bestBarrelLayer));
92 
93  unsigned int bestEndCapLayer(0);
94  const StatusCode endCapStatusCode(this->FindMatchingLayer(zCoordinate - zCorrection, m_endCapLayerPositions, bestEndCapLayer));
95 
96  if ((STATUS_CODE_SUCCESS != barrelStatusCode) && (STATUS_CODE_SUCCESS != endCapStatusCode))
97  return STATUS_CODE_NOT_FOUND;
98 
99  pseudoLayer = std::max(bestBarrelLayer, bestEndCapLayer);
100  return STATUS_CODE_SUCCESS;
101  }
102  }
103 
104  //------------------------------------------------------------------------------------------------------------------------------------------
105 
106  StatusCode PseudoLayerPlugin::FindMatchingLayer(const float position, const LayerPositionList &layerPositionList,
107  unsigned int &layer) const
108  {
109  LayerPositionList::const_iterator upperIter = std::upper_bound(layerPositionList.begin(), layerPositionList.end(), position);
110 
111  if (layerPositionList.end() == upperIter)
112  {
113  return STATUS_CODE_NOT_FOUND;
114  }
115 
116  if (layerPositionList.begin() == upperIter)
117  {
118  layer = 0;
119  return STATUS_CODE_SUCCESS;
120  }
121 
122  LayerPositionList::const_iterator lowerIter = upperIter - 1;
123 
124  if (std::fabs(position - *lowerIter) < std::fabs(position - *upperIter))
125  {
126  layer = std::distance(layerPositionList.begin(), lowerIter);
127  }
128  else
129  {
130  layer = std::distance(layerPositionList.begin(), upperIter);
131  }
132 
133  return STATUS_CODE_SUCCESS;
134  }
135 
136  //------------------------------------------------------------------------------------------------------------------------------------------
137 
139  {
140  const GeometryManager *const pGeometryManager(this->GetPandora().GetGeometry());
141  this->StoreLayerPositions(pGeometryManager->GetSubDetector(ECAL_BARREL), m_barrelLayerPositions);
142  this->StoreLayerPositions(pGeometryManager->GetSubDetector(ECAL_ENDCAP), m_endCapLayerPositions);
143 
144  if (m_barrelLayerPositions.empty() || m_endCapLayerPositions.empty())
145  {
146  std::cout << "PseudoLayerPlugin: No layer positions specified." << std::endl;
147  throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
148  }
149 
150  std::sort(m_barrelLayerPositions.begin(), m_barrelLayerPositions.end());
151  std::sort(m_endCapLayerPositions.begin(), m_endCapLayerPositions.end());
152 
155 
156  if ((m_barrelLayerPositions.end() != barrelIter) || (m_endCapLayerPositions.end() != endcapIter))
157  {
158  std::cout << "PseudoLayerPlugin: Duplicate layer position detected." << std::endl;
159  throw StatusCodeException(STATUS_CODE_FAILURE);
160  }
161  }
162 
163  //------------------------------------------------------------------------------------------------------------------------------------------
164 
165  void PseudoLayerPlugin::StoreLayerPositions(const SubDetector &subDetector, LayerPositionList &layerPositionList)
166  {
167  if (!subDetector.IsMirroredInZ())
168  {
169  std::cout << "PseudoLayerPlugin: Error, detector must be symmetrical about z=0 plane." << std::endl;
170  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
171  }
172 
173  const SubDetector::SubDetectorLayerVector &subDetectorLayerVector(subDetector.GetSubDetectorLayerVector());
174 
175  for (SubDetector::SubDetectorLayerVector::const_iterator iter = subDetectorLayerVector.begin(), iterEnd = subDetectorLayerVector.end(); iter != iterEnd; ++iter)
176  {
177  layerPositionList.push_back(iter->GetClosestDistanceToIp());
178  }
179  }
180 
181  //------------------------------------------------------------------------------------------------------------------------------------------
182 
184  {
185  const GeometryManager *const pGeometryManager(this->GetPandora().GetGeometry());
186 
187  m_barrelEdgeR = pGeometryManager->GetSubDetector(ECAL_BARREL).GetOuterRCoordinate();
188 
189  m_endCapEdgeZ = std::fabs(pGeometryManager->GetSubDetector(ECAL_ENDCAP).GetOuterZCoordinate());
190 
191  if ((m_barrelLayerPositions.end() != std::upper_bound(m_barrelLayerPositions.begin(), m_barrelLayerPositions.end(), m_barrelEdgeR)) || (m_endCapLayerPositions.end() != std::upper_bound(m_endCapLayerPositions.begin(), m_endCapLayerPositions.end(), m_endCapEdgeZ)))
192  {
193  std::cout << "PseudoLayerPlugin: Layers specified outside detector edge." << std::endl;
194  throw StatusCodeException(STATUS_CODE_FAILURE);
195  }
196 
199  }
200 
201  //------------------------------------------------------------------------------------------------------------------------------------------
202 
204  {
205  const GeometryManager *const pGeometryManager(this->GetPandora().GetGeometry());
206 
207  this->FillAngleVector(pGeometryManager->GetSubDetector(ECAL_BARREL).GetInnerSymmetryOrder(),
208  pGeometryManager->GetSubDetector(ECAL_BARREL).GetInnerPhiCoordinate(), m_eCalBarrelAngleVector);
209  }
210 
211  //------------------------------------------------------------------------------------------------------------------------------------------
212 
214  {
215  const GeometryManager *const pGeometryManager(this->GetPandora().GetGeometry());
216 
217  m_barrelInnerR = pGeometryManager->GetSubDetector(ECAL_BARREL).GetInnerRCoordinate();
218  m_endCapInnerZ = std::fabs(pGeometryManager->GetSubDetector(ECAL_ENDCAP).GetInnerZCoordinate());
219 
220  const float barrelOuterZ = std::fabs(pGeometryManager->GetSubDetector(ECAL_BARREL).GetOuterZCoordinate());
221  const float endCapOuterR = pGeometryManager->GetSubDetector(ECAL_ENDCAP).GetOuterRCoordinate();
222 
223  const bool IsEnclosingEndCap(endCapOuterR > m_barrelInnerR);
224  m_rCorrection = ((!IsEnclosingEndCap) ? 0.f : m_barrelInnerR * ((m_endCapInnerZ / barrelOuterZ) - 1.f));
225  m_zCorrection = ((IsEnclosingEndCap) ? 0.f : m_endCapInnerZ * ((m_barrelInnerR / endCapOuterR) - 1.f));
226  }
227 
228  //------------------------------------------------------------------------------------------------------------------------------------------
229 
230  float PseudoLayerPlugin::GetMaximumRadius(const AngleVector &angleVector, const float x, const float y) const
231  {
232  if (angleVector.size() <= 2)
233  return std::sqrt((x * x) + (y * y));
234 
235  float maxRadius(0.);
236  for (AngleVector::const_iterator iter = angleVector.begin(), iterEnd = angleVector.end(); iter != iterEnd; ++iter)
237  {
238  const float radius((x * iter->first) + (y * iter->second));
239 
240  if (radius > maxRadius)
241  maxRadius = radius;
242  }
243 
244  return maxRadius;
245  }
246 
247  //------------------------------------------------------------------------------------------------------------------------------------------
248 
249  void PseudoLayerPlugin::FillAngleVector(const unsigned int symmetryOrder, const float phi0, AngleVector &angleVector) const
250  {
251  const float twoPi = static_cast<float>(2. * std::acos(-1.));
252  angleVector.clear();
253 
254  for (unsigned int iSymmetry = 0; iSymmetry < symmetryOrder; ++iSymmetry)
255  {
256  const float phi = phi0 + ((twoPi * static_cast<float>(iSymmetry)) / static_cast<float>(symmetryOrder));
257  angleVector.push_back(std::make_pair(std::cos(phi), std::sin(phi)));
258  }
259  }
260 
261  //------------------------------------------------------------------------------------------------------------------------------------------
262 
263  pandora::StatusCode PseudoLayerPlugin::ReadSettings(const pandora::TiXmlHandle /* xmlHandle */)
264  {
265  return STATUS_CODE_SUCCESS;
266  }
267 
268  }
269 }
void StoreLayerPositions()
Store all revelevant barrel and endcap layer positions upon initialization.
void StoreDetectorOuterEdge()
Store positions of barrel and endcap outer edges upon initialization.
float m_barrelEdgeR
Extremal barrel r coordinate.
LayerPositionList m_barrelLayerPositions
List of barrel layer positions.
std::vector< std::pair< float, float > > AngleVector
LayerPositionList m_endCapLayerPositions
List of endcap layer positions.
float m_endCapEdgeZ
Extremal endcap z coordinate.
intermediate_table::const_iterator const_iterator
float m_endCapInnerZ
Endcap inner z position.
unsigned int GetPseudoLayer(const pandora::CartesianVector &positionVector) const
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
void StoreOverlapCorrectionDetails()
Store all details revelevant to barrel/endcap overlap corrections upon initialization.
static int max(int a, int b)
pandora::StatusCode FindMatchingLayer(const float position, const LayerPositionList &layerPositionList, unsigned int &layer) const
Find the layer number corresponding to a specified position, via reference to a specified layer posit...
void FillAngleVector(const unsigned int symmetryOrder, const float phi0, AngleVector &angleVector) const
Fill a vector with sine/cosine values for relevant polygon angles.
float m_zCorrection
Barrel/endcap overlap z correction.
General GArSoft Utilities.
float GetMaximumRadius(const AngleVector &angleVector, const float x, const float y) const
Get the maximum polygon radius, with reference to cached sine/cosine values for relevant polygon angl...
void StorePolygonAngles()
Store sine and cosine of angles used to project hit positions onto polygonal calorimeter surfaces upo...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_barrelInnerR
Barrel inner radius.
list x
Definition: train.py:276
AngleVector m_eCalBarrelAngleVector
The ecal barrel angle vector.
#define MF_LOG_WARNING(category)
float m_rCorrection
Barrel/endcap overlap r correction.
QTextStream & endl(QTextStream &s)
GeomAnalyzerI * GetGeometry(void)
Definition: gAtmoEvGen.cxx:433