ATLAS Offline Software
CoreStripSpacePointFormationTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "Acts/Utilities/SpacePointUtility.hpp"
14 #include "Acts/SpacePointFormation/SpacePointBuilderConfig.hpp"
17 
18 #include "StoreGate/WriteHandle.h"
19 namespace ActsTrk
20 {
21 
23  const std::string &name,
24  const IInterface *parent)
25  : base_class(type, name, parent)
26  {}
27 
29 
30  ATH_CHECK(detStore()->retrieve(m_stripId, "SCT_ID"));
31  ATH_CHECK(m_lorentzAngleTool.retrieve());
34  return StatusCode::SUCCESS;
35  }
36 
38  const xAOD::StripClusterContainer &clusterContainer,
41  const Amg::Vector3D &beamSpotVertex,
42  std::vector<StripSP>& spacePoints,
43  std::vector<StripSP>& overlapSpacePoints,
44  bool processOverlaps,
45  const std::vector<IdentifierHash>& hashesToProcess,
47  {
52 
86 
89 
90  auto spBuilderConfig = std::make_shared<Acts::SpacePointBuilderConfig>();
91  const Acts::TrackingGeometry *acts_tracking_geometry=m_trackingGeometryTool->trackingGeometry().get();
92  ATH_CHECK(acts_tracking_geometry != nullptr);
94  detectorElementToGeometryIdMap{m_detectorElementToGeometryIdMapKey, ctx};
95  ATH_CHECK(detectorElementToGeometryIdMap.isValid());
96 
97  ATLASUncalibSourceLinkSurfaceAccessor surfaceAccessor{ *acts_tracking_geometry, **detectorElementToGeometryIdMap };
98 
99  spBuilderConfig->slSurfaceAccessor
100  .connect<&ATLASUncalibSourceLinkSurfaceAccessor::operator()>(&surfaceAccessor);
101 
102  const std::shared_ptr<const Acts::TrackingGeometry> trkGeometry = m_trackingGeometryTool->trackingGeometry();
103  spBuilderConfig->trackingGeometry = trkGeometry;
104 
105 
106  auto spConstructor = [this, &clusterContainer, &elements](const Acts::Vector3 &pos,
107  std::optional<double> /*t*/,
108  const Acts::Vector2 &cov,
109  std::optional<double> /*varT*/,
110  const boost::container::static_vector<Acts::SourceLink, 2> &slinks)
111  -> StripSP{
112  std::vector<std::size_t> measIndices;
113  std::array<StripInformationHelper, 2> stripInfos;
114  size_t idx = 0;
115  for (const auto& slink : slinks){
116  const auto& atlasSourceLink = slink.get<ATLASUncalibSourceLink>();
117  const xAOD::UncalibratedMeasurement *hit = &getUncalibratedMeasurement(atlasSourceLink);
118 
119  // Check if the cluster is in the cluster container
120  const auto it = std::find(clusterContainer.begin(), clusterContainer.end(), dynamic_cast<const xAOD::StripCluster*>(hit));
121  if (it != clusterContainer.end()){
122  const auto cluster_index = it - clusterContainer.begin();
123  const auto id = hit->identifierHash();
124  const auto &element = elements.getDetectorElement(id);
125  size_t stripIndex = 0;
126  auto ends = this->getStripEnds(atlasSourceLink, element, stripIndex);
127  auto vertex = Amg::Vector3D(0,0,0);
128  StripInformationHelper stripInfo(id,ends.first, ends.second, vertex, ActsTrk::localXFromSourceLink(atlasSourceLink), cluster_index, stripIndex);
129  measIndices.push_back(cluster_index);
130  stripInfos[idx++] = std::move(stripInfo);
131  }
132  }
133  const auto& [firstInfo, secondInfo] = stripInfos;
134  const auto topHalfStripLength = 0.5*firstInfo.stripDirection().norm();
135  Eigen::Matrix<double, 3, 1> topStripDirection = -firstInfo.stripDirection()/(2.*topHalfStripLength);
136  Eigen::Matrix<double, 3, 1> topStripCenter = 0.5*firstInfo.trajDirection();
137 
138  const auto bottomHalfStripLength = 0.5*secondInfo.stripDirection().norm();
139  Eigen::Matrix<double, 3, 1> bottomStripDirection = -secondInfo.stripDirection()/(2.*bottomHalfStripLength);
140  Eigen::Matrix<double, 3, 1> stripCenterDistance = firstInfo.stripCenter() - secondInfo.stripCenter();
141 
142  StripSP sp;
143  sp.idHashes = {firstInfo.idHash(), secondInfo.idHash()};
144  sp.globPos = pos.cast<float>();
145  sp.cov_r = cov(0,0);
146  sp.cov_z = cov(1,0);
147  sp.measurementIndexes = measIndices;
148  sp.topHalfStripLength = topHalfStripLength;
149  sp.bottomHalfStripLength = bottomHalfStripLength;
150  sp.topStripDirection = topStripDirection.cast<float>();
151  sp.bottomStripDirection = bottomStripDirection.cast<float>();
152  sp.stripCenterDistance = stripCenterDistance.cast<float>();
153  sp.topStripCenter = topStripCenter.cast<float>();
154 
155  return sp;
156  };
157 
158  auto spBuilder = std::make_shared<Acts::SpacePointBuilder<StripSP>>(*spBuilderConfig, spConstructor);
159 
160  const auto hashesProc = (hashesToProcess.size() > 0 ? hashesToProcess : stripAccessor.allIdentifiers());
161  for (auto &idHash : hashesProc)
162  {
163  const InDetDD::SiDetectorElement *thisElement = elements.getDetectorElement(idHash);
164  if (thisElement->isStereo())
165  continue;
166 
167  // Retrieve the neighbours of the detector element
168  const std::vector<IdentifierHash>& others = *properties.neighbours(idHash);
169 
170  if ( others.empty()) continue;
171 
172  // This flag is use to trigger if the search should be performed.
173  // In case there are no clusters on the neighbours of the selected
174  // detector element, the flag stays false.
175  bool search = false;
176  size_t neighbour = 0;
177  while (not search and neighbour < others.size()){
178  search = stripAccessor.isIdentifierPresent( others.at(neighbour) );
179  neighbour++;
180  }
181  if (not search) continue;
182 
183  // prepare clusters, indices and modules for space point formation
184  std::array<std::vector<std::pair<const xAOD::StripCluster *, size_t>>, static_cast<size_t>(nNeighbours)> neighbourClusters{};
185  std::array<std::vector<std::pair<ATLASUncalibSourceLink, size_t>>, static_cast<size_t>(nNeighbours)> neighbourSourceLinks{};
186  std::array<const InDetDD::SiDetectorElement *, static_cast<size_t>(nNeighbours)> neighbourElements{};
187 
188  auto groupStart = clusterContainer.begin();
189  // Get the detector element and range for the idHash
190  neighbourElements[0] = thisElement;
191  for (auto &this_range : stripAccessor.rangesForIdentifierDirect(idHash)){
192  for (auto start = this_range.first; start != this_range.second; ++start){
193  size_t position = std::distance(groupStart, start);
194  neighbourClusters[0].push_back(std::make_pair(*start, position));
195  if ((*start)->identifierHash() != thisElement->identifyHash()) {
196  throw std::logic_error("Identifier mismatch.");
197  }
198  auto slink = makeATLASUncalibSourceLink(&clusterContainer, (*start)->index());
199  neighbourSourceLinks[0].emplace_back(std::make_pair(slink, position));
200  }
201  }
202 
203  Identifier thisId = thisElement->identify();
204 
205  // define overlap extends before building space points
206  std::array<double, 14> overlapExtents{};
207  // Default case: you test the opposite element and the overlapping in phi (total 3 elements)
208  int Nmax = 4;
209 
210  // In the barrel, test the eta overlaps as well (total 5 elements)
211  if (m_stripId->is_barrel(thisId))
212  Nmax = 6;
213 
214  // You can remove all the overlaps if requested.
215  // Here you test only the opposite element
216  if (not processOverlaps)
217  Nmax = 2;
218 
219  float hwidth(properties.halfWidth(idHash));
220  int n = 0;
221 
222  // The order of the elements in others is such that you first get the opposite element,
223  // the overlapping in phi and then the overlapping in eta
224  // For this reason you need to re-order the indices, since the SiSpacePointMakerTool will process
225  // first the eta overlaps and then the phi ones
226  const std::array<size_t, nNeighbours> neigbourIndices{ThisOne, Opposite, EtaMinus, EtaPlus, PhiMinus, PhiPlus};
227 
228  for (const auto &otherHash : others){
229  if (++n == Nmax) break;
230 
231  if (not stripAccessor.isIdentifierPresent(otherHash))
232  continue;
233 
234  const InDetDD::SiDetectorElement *otherElement = elements.getDetectorElement(otherHash);
235 
236  neighbourElements[neigbourIndices[n]] = otherElement;
237  for (auto &this_range : stripAccessor.rangesForIdentifierDirect(otherHash)){
238  for (auto start = this_range.first; start != this_range.second; ++start){
239  size_t position = std::distance(groupStart, start);
240  neighbourClusters[neigbourIndices[n]].push_back(std::make_pair(*start, position));
241  if ((*start)->identifierHash() != otherElement->identifyHash()) {
242  throw std::logic_error("Identifier mismatch.");
243  }
244  auto slink = makeATLASUncalibSourceLink(&clusterContainer, (*start)->index());
245  neighbourSourceLinks[neigbourIndices[n]].emplace_back(std::make_pair(slink, position));
246  }
247  }
248 
249  switch (n){
250  case Opposite:
251  {
252  overlapExtents[0] = -m_overlapLimitOpposite;
253  overlapExtents[1] = m_overlapLimitOpposite;
254  break;
255  }
256  case PhiMinus:
257  {
258  overlapExtents[6] = -hwidth;
259  overlapExtents[7] = -hwidth + m_overlapLimitPhi;
260  overlapExtents[8] = hwidth - m_overlapLimitPhi;
261  overlapExtents[9] = hwidth;
262  break;
263  }
264  case PhiPlus:
265  {
266  overlapExtents[10] = hwidth - m_overlapLimitPhi;
267  overlapExtents[11] = hwidth;
268  overlapExtents[12] = -hwidth;
269  overlapExtents[13] = -hwidth + m_overlapLimitPhi;
270  break;
271  }
272  case EtaMinus:
273  {
274  if ((m_stripId->layer_disk(thisId) & 1) == 0){
275  overlapExtents[2] = m_overlapLimitEtaMin;
276  overlapExtents[3] = m_overlapLimitEtaMax;
277  } else{
278  overlapExtents[2] = -m_overlapLimitEtaMax;
279  overlapExtents[3] = -m_overlapLimitEtaMin;
280  }
281  break;
282  }
283  default:
284  {
285  if ((m_stripId->layer_disk(thisId) & 1) == 0){
286  overlapExtents[4] = -m_overlapLimitEtaMax;
287  overlapExtents[5] = -m_overlapLimitEtaMin;
288  } else {
289  overlapExtents[4] = m_overlapLimitEtaMin;
290  overlapExtents[5] = m_overlapLimitEtaMax;
291  }
292  break;
293  }
294  }
295  }
296 
297  ATH_CHECK( fillSpacePoints(ctx, spBuilder, neighbourElements, neighbourSourceLinks, overlapExtents, beamSpotVertex,
298  spacePoints, overlapSpacePoints) );
299  }
300 
301  return StatusCode::SUCCESS;
302  }
303 
305  std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
306  const std::array<const InDetDD::SiDetectorElement *,nNeighbours>& elements,
307  const std::array<std::vector<std::pair<ATLASUncalibSourceLink, size_t>>,nNeighbours>& sourceLinks,
308  const std::array<double, 14>& overlapExtents,
309  const Amg::Vector3D &beamSpotVertex,
310  std::vector<StripSP>& spacePoints,
311  std::vector<StripSP>& overlapSpacePoints ) const
312  {
313  // This function is called once all the needed quantities are collected.
314  // It is used to build space points checking the compatibility of clusters on pairs of detector elements.
315  // Detector elements and cluster collections are elements and clusters, respectively.
316  // [0] is the trigger element
317  // [1] is the opposite element
318  // [2]-[3] are the elements tested for eta overlaps
319  // [4]-[5] are the elements tested for phi overlaps
320  //
321  // To build space points:
322  // - For the opposite element and the ones tested for eta overlaps, you have to check
323  // if clusters are compatible with the local position of the trigger cluster
324  // requiring that the distance between the two clusters in phi is withing a specified range.
325  // - overlapExtents[0], overlapExtents[1] are filled for the opposite element
326  // - overlapExtents[2], overlapExtents[3], overlapExtents[4], overlapExtents[5] are filled for the eta overlapping elements
327  // - For the elements tested for phi overlaps, you have to check
328  // if clusters are compatible with the local position of the trigger cluster.
329  // This needs that the trigger cluster is at the edge of the trigger module
330  // and that the other cluster is on the compatible edge of its module
331  // - overlapExtents[6], overlapExtents[7], overlapExtents[10], overlapExtents[11]
332  // overlapExtents[8], overlapExtents[9], overlapExtents[12], overlapExtents[13] are filled for the phi overlapping elements
333 
334 
335 
336  Acts::Vector3 vertex(beamSpotVertex.x(), beamSpotVertex.y(), beamSpotVertex.z());
337  constexpr int otherSideIndex{1};
338  constexpr int maxEtaIndex{3};
339  std::array<int,nNeighbours - 1> elementIndex{};
340  int nElements = 0;
341 
342  // For the nNeighbours sides, fill elementIndex with the indices of the existing elements.
343  // Same the number of elements in nElements to loop on the later on
344  for (int n = 1; n != nNeighbours; ++n) {
345  if (elements[n]){
346  elementIndex[nElements++] = n;
347  }
348  }
349  // return if all detector elements are nullptr
350  if(!nElements) return StatusCode::SUCCESS;
351 
352  const InDetDD::SiDetectorElement *triggerElement = elements[0];
353 
354  bool isEndcap = triggerElement->isEndcap();
355  std::vector<StripInformationHelper> stripInfos;
356  stripInfos.reserve(sourceLinks[0].size());
357 
358  std::vector<ATLASUncalibSourceLink> triggerSlinks;
359  triggerSlinks.reserve(sourceLinks[0].size());
360 
361  // loop on all clusters on the trigger detector element and save the related information
362  for (auto &sourceLink_index : sourceLinks[0]){
363  triggerSlinks.emplace_back(sourceLink_index.first);
364  }
365 
366  double limit = 1. + m_stripLengthTolerance;
367  double slimit = 0.;
368 
369  if (not m_allClusters){
370  // Start processing the opposite side and the eta overlapping elements
371  int n = 0;
372  for (; n < nElements; ++n){
373  int currentIndex = elementIndex[n];
374  if (currentIndex > maxEtaIndex)
375  break;
376 
377  // get the detector element and the IdentifierHash
378  const InDetDD::SiDetectorElement *currentElement = elements[currentIndex];
379 
380  // retrieve the range
381  double min = overlapExtents[currentIndex * 2 - 2];
382  double max = overlapExtents[currentIndex * 2 - 1];
383 
384  size_t minStrip, maxStrip = 0;
385 
386  if (m_stripGapParameter != 0.){
387  updateRange(*triggerElement, *currentElement, slimit, min, max);
388  correctPolarRange(triggerElement, min, max, minStrip, maxStrip);
389  }
390 
391  StripInformationHelper currentStripInfo;
392  for (auto &sourceLink_index : sourceLinks[currentIndex]){
393  float source_local_x = ActsTrk::localXFromSourceLink( sourceLink_index.first );
394  const auto currentSlink = sourceLink_index.first;
395  for (auto triggerSlink : triggerSlinks){
396 
397  double diff = source_local_x - ActsTrk::localXFromSourceLink( triggerSlink );
398  if (diff < min || diff > max)
399  continue;
400  if (currentIndex == otherSideIndex){
401  ATH_CHECK( makeSpacePoint(ctx, spacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
402  currentElement, limit, slimit, vertex));
403 
404  } else {
405  ATH_CHECK(makeSpacePoint(ctx, overlapSpacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
406  currentElement, limit, slimit, vertex));
407  }
408  }
409  }
410  }
411  // process the phi overlapping elements
412  // if possible n starts from 4
413  for (; n < nElements; ++n){
414  int currentIndex = elementIndex[n];
415  const InDetDD::SiDetectorElement *currentElement = elements[currentIndex];
416  double min = overlapExtents[4 * currentIndex - 10];
417  double max = overlapExtents[4 * currentIndex - 9];
418 
419  size_t minStrip, maxStrip = 0;
420 
421  if (m_stripGapParameter != 0.){
422  updateRange(*triggerElement, *currentElement, slimit, min, max);
423  correctPolarRange(triggerElement, min, max, minStrip, maxStrip);
424  }
425 
426  std::vector<ATLASUncalibSourceLink> triggerPhiSlinks;
427  triggerSlinks.reserve(triggerSlinks.size());
428  for (auto triggerSlink : triggerSlinks){
429  auto centralValue = ActsTrk::localXFromSourceLink( triggerSlink );
430  auto minValue = min;
431  auto maxValue = max;
432  if (isEndcap){
433  size_t stripIndex = 0;
434  getStripEnds(triggerSlink, triggerElement, stripIndex);
435  centralValue = stripIndex;
436  minValue = minStrip;
437  maxValue = maxStrip;
438  }
439  if (minValue <= centralValue and centralValue <= maxValue){
440  triggerPhiSlinks.emplace_back(triggerSlink);
441  }
442  }
443  if (triggerPhiSlinks.empty())
444  continue;
445  min = overlapExtents[4 * currentIndex - 8];
446  max = overlapExtents[4 * currentIndex - 7];
447  if (m_stripGapParameter != 0.){
448  updateRange(*triggerElement, *currentElement, slimit, min, max);
449  correctPolarRange(currentElement, min, max, minStrip, maxStrip);
450  }
451 
452  for (auto &sourceLink_index : sourceLinks[currentIndex]){
453  const auto currentSlink = sourceLink_index.first;
454 
455  size_t currentStripIndex = 0;
456  getStripEnds(currentSlink, currentElement, currentStripIndex);
457  auto centralValue = ActsTrk::localXFromSourceLink( sourceLink_index.first );
458  auto minValue = min;
459  auto maxValue = max;
460  if (isEndcap) {
461  centralValue = currentStripIndex;
462  minValue = minStrip;
463  maxValue = maxStrip;
464  }
465  if (centralValue < minValue or centralValue > maxValue)
466  continue;
467  for (auto &triggerSlink : triggerPhiSlinks) {
468  ATH_CHECK(makeSpacePoint(ctx, overlapSpacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
469  currentElement, limit, slimit, vertex));
470  }
471  }
472  }
473  return StatusCode::SUCCESS;
474 
475  } // not m_allClusters
476 
477  for (int n = 0; n != nElements; ++n){
478 
479  int currentIndex = elementIndex[n];
480  const InDetDD::SiDetectorElement *currentElement = elements[currentIndex];
481 
482  if (m_stripGapParameter != 0.){
483  computeOffset(*triggerElement, *currentElement, slimit);
484  }
485 
486  for (auto &sourceLink_index : sourceLinks[currentIndex]){
487  size_t currentStripIndex = 0;
488  getStripEnds(sourceLink_index.first, triggerElement, currentStripIndex);
489  const auto currentSlink = sourceLink_index.first;
490 
491  for (auto triggerSlink : triggerSlinks){
492  if (currentIndex == otherSideIndex){
493  ATH_CHECK(makeSpacePoint(ctx, spacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
494  currentElement, limit, slimit, vertex));
495  }else{
496  ATH_CHECK(makeSpacePoint(ctx, overlapSpacePoints, spBuilder, triggerSlink, currentSlink, triggerElement,
497  currentElement, limit, slimit, vertex));
498  }
499  }
500  }
501  }
502  return StatusCode::SUCCESS;
503  }
504 
505 
507  std::vector<StripSP>& collection,
508  std::shared_ptr<Acts::SpacePointBuilder<StripSP>> spBuilder,
509  const ATLASUncalibSourceLink& currentSlink,
510  const ATLASUncalibSourceLink& anotherSlink,
511  const InDetDD::SiDetectorElement *currentElement,
512  const InDetDD::SiDetectorElement *anotherElement,
513  const double limit,
514  const double slimit,
515  const Acts::Vector3& vertex) const
516  {
517 
518  auto tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
519 
520  size_t stripIndex = 0;
521  auto ends1 = getStripEnds(currentSlink, currentElement, stripIndex);
522  auto ends2 = getStripEnds(anotherSlink, anotherElement, stripIndex);
523  std::pair<Acts::Vector3, Acts::Vector3> ends1_acts;
524  std::pair<Acts::Vector3, Acts::Vector3> ends2_acts;
525  ends1_acts.first = ends1.first;
526  ends1_acts.second = ends1.second;
527  ends2_acts.first = ends2.first;
528  ends2_acts.second = ends2.second;
529  auto paramCovAccessor = [&](const Acts::SourceLink &slink) {
530  const auto &atlasSLink = slink.get<ATLASUncalibSourceLink>();
531  const xAOD::UncalibratedMeasurement *measurement = &getUncalibratedMeasurement(atlasSLink);
532  Acts::BoundVector loc = Acts::BoundVector::Zero();
533  Acts::BoundSquareMatrix cov = Acts::BoundMatrix::Zero();
534  switch (measurement->type()) {
536  loc[Acts::eBoundLoc0] = measurement->localPosition<1>()[Trk::locX];
537  cov.topLeftCorner<1, 1>() =
538  measurement->localCovariance<1>().cast<double>();
539  break;
541  loc[Acts::eBoundLoc0] = measurement->localPosition<2>()[Trk::locX];
542  loc[Acts::eBoundLoc1] = measurement->localPosition<2>()[Trk::locY];
543  cov.topLeftCorner<2, 2>() =
544  measurement->localCovariance<2>().cast<double>();
545  break;
546  default:
547  throw std::domain_error(
548  "Can only handle measurement type pixel or strip");
549  }
550  return std::make_pair(loc, cov);
551  };
552  std::vector<Acts::SourceLink> slinks;
553 
554  slinks.emplace_back(Acts::SourceLink{currentSlink});
555  slinks.emplace_back(Acts::SourceLink{anotherSlink});
556 
557  Acts::SpacePointBuilderOptions spOpt{std::make_pair(ends1_acts, ends2_acts), paramCovAccessor};
558  spOpt.vertex = vertex;
559  spOpt.stripLengthTolerance = limit - 1;
560  spOpt.stripLengthGapTolerance = slimit;
561 
562 
563  spBuilder->buildSpacePoint(tgContext, slinks, spOpt,
564  std::back_inserter(collection));
565  return StatusCode::SUCCESS;
566  }
567 
569  const InDetDD::SiDetectorElement& element2,
570  double& stripLengthGapTolerance) const
571 {
572  // Get transformation matrices and center positions of detector elements
573  const Amg::Transform3D& t1 = element1.transform();
574  const Amg::Transform3D& t2 = element2.transform();
575  const Amg::Vector3D& c = element1.center();
576 
577  // Check if first element is an annulus
578  bool isAnnulus = (element1.design().shape() == InDetDD::Annulus);
579 
580  // Compute x12 and radius of detector element
581  double x12 = t1.linear().col(0).dot(t2.linear().col(0));
582  double r = isAnnulus ? c.perp() : std::sqrt(t1(0, 3) * t1(0, 3) + t1(1, 3) * t1(1, 3));
583 
584  // Compute distance between detector elements in the direction of strips
585  Amg::Vector3D dPos = t1.translation() - t2.translation();
586  double s = dPos.dot(t1.linear().col(2));
587 
588  // Compute offset distance
589  double dm = (m_stripGapParameter * r) * std::abs(s * x12);
590  double d = isAnnulus ? dm / 0.04 : dm / std::sqrt((1. - x12) * (1. + x12));
591 
592  // Adjust offset distance for z-component of transformation matrix
593  const double zComponentTolerance = 0.7;
594  if (std::abs(t1(2, 2)) > zComponentTolerance)
595  d *= (r / std::abs(t1(2, 3)));
596 
597  stripLengthGapTolerance = d;
598 
599  return dm;
600 }
601 
603  const InDetDD::SiDetectorElement &element2,
604  double &stripLengthGapTolerance,
605  double &min, double &max) const
606  {
607  double dm = computeOffset(element1, element2, stripLengthGapTolerance);
608  min -= dm;
609  max += dm;
610  }
611 
613  double &min,
614  double &max,
615  size_t &minStrip,
616  size_t &maxStrip) const
617  {
618  if (element->isBarrel())
619  return;
620 
621  // design for endcap modules
622  const InDetDD::StripStereoAnnulusDesign *design = dynamic_cast<const InDetDD::StripStereoAnnulusDesign *>(&element->design());
623  if (!design){
624  ATH_MSG_FATAL("Invalid strip annulus design for module with identifier/identifierHash " << element->identify() << "/" << element->identifyHash());
625  return;
626  }
627 
628  // converting min and max from cartesian reference frame to polar frame
629  auto firstPosition = (design->localPositionOfCell(design->strip1Dim(0, 0)) +
630  design->localPositionOfCell(design->strip1Dim(design->diodesInRow(0) - 1, 0))) *
631  0.5;
632 
633  double radius = firstPosition.xEta();
634 
637 
638  if (not minCellId.isValid())
639  minCellId = InDetDD::SiCellId(0);
640 
641  if (not maxCellId.isValid())
642  maxCellId = InDetDD::SiCellId(design->diodesInRow(0) - 1);
643 
644  minStrip = minCellId.strip();
645  maxStrip = maxCellId.strip();
646 
647  // re-evaluate min and max in polar coordinate
648  min = std::atan2(min, radius);
649  max = std::atan2(max, radius);
650  }
651 
652  std::pair<Amg::Vector3D, Amg::Vector3D>
654  const InDetDD::SiDetectorElement *element,
655  size_t &stripIndex) const
656  {
657  const xAOD::UncalibratedMeasurement &measurement = getUncalibratedMeasurement(sourceLink);
658  auto cluster = dynamic_cast<const xAOD::StripCluster *>(&measurement);
659  if(!cluster){
660  ATH_MSG_FATAL("Could not cast UncalibratedMeasurement as StripCluster");
661  return {};
662  }
663  float source_local_x = ActsTrk::localXFromSourceLink( sourceLink );
664  if (element->isEndcap()) {
665  // design for endcap modules
666  const InDetDD::StripStereoAnnulusDesign *design = dynamic_cast<const InDetDD::StripStereoAnnulusDesign *>(&element->design());
667  if (!design){
668  ATH_MSG_FATAL("Invalid strip annulus design for module with identifier/identifierHash " << element->identify() << "/" << element->identifyHash());
669  return {};
670  }
671 
672  // calculate phi pitch for evaluating the strip index
673  double phiPitchPhi = design->phiWidth()/design->diodesInRow(0);
674  stripIndex = -std::floor(source_local_x / phiPitchPhi) + design->diodesInRow(0) *0.5 - 0.5;
675 
676  std::pair<Amg::Vector3D, Amg::Vector3D > ends = {
677  element->globalPosition(design->stripPosAtR(stripIndex, 0, design->minR())),
678  element->globalPosition(design->stripPosAtR(stripIndex, 0, design->maxR()))
679  };
680  return ends;
681  }
682 
683  InDetDD::SiLocalPosition localPosition(0., source_local_x, 0.);
684  std::pair<Amg::Vector3D, Amg::Vector3D> ends(element->endsOfStrip(localPosition));
685  return ends;
686  }
687 
688 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
ActsTrk::CoreStripSpacePointFormationTool::m_detectorElementToGeometryIdMapKey
SG::ReadCondHandleKey< ActsTrk::DetectorElementToActsGeometryIdMap > m_detectorElementToGeometryIdMapKey
Definition: CoreStripSpacePointFormationTool.h:105
beamspotman.r
def r
Definition: beamspotman.py:676
ActsTrk::EtaMinus
@ EtaMinus
Definition: StripInformationHelper.h:13
ActsTrk::StripSP::cov_z
float cov_z
Definition: IStripSpacePointFormationTool.h:24
InDetDD::SiDetectorElement::isEndcap
bool isEndcap() const
ActsTrk::CoreStripSpacePointFormationTool::m_stripLengthTolerance
Gaudi::Property< float > m_stripLengthTolerance
Definition: CoreStripSpacePointFormationTool.h:113
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
SCT_ID.h
This is an Identifier helper class for the SCT subdetector. This class is a factory for creating comp...
InDetDD::SolidStateDetectorElementBase::cellIdOfPosition
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
Definition: SolidStateDetectorElementBase.cxx:224
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
ActsTrk::StripSP
Definition: IStripSpacePointFormationTool.h:18
maxValue
#define maxValue(current, test)
Definition: CompoundLayerMaterialCreator.h:22
ContainerAccessor
Definition: ContainerAccessor.h:25
InDetDD::SiDetectorElementCollection
Definition: SiDetectorElementCollection.h:30
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
InDetDD::StripStereoAnnulusDesign::strip1Dim
virtual int strip1Dim(int strip, int row) const override
only relevant for SCT.
Definition: StripStereoAnnulusDesign.cxx:294
ContainerAccessor::allIdentifiers
std::vector< identifier_t > allIdentifiers() const
Function to return all available identifier (i.e. keys in the map)
Definition: ContainerAccessor.h:84
python.TestDriveDummies.properties
dictionary properties
Definition: TestDriveDummies.py:14
Trk::locX
@ locX
Definition: ParamDefs.h:37
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:38
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
xAOD::UncalibMeasType::StripClusterType
@ StripClusterType
hist_file_dump.d
d
Definition: hist_file_dump.py:137
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
InDetDD::DetectorDesign::shape
virtual DetectorShape shape() const
Shape of element.
Definition: DetectorDesign.cxx:96
InDetDD::SolidStateDetectorElementBase::center
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
InDetDD::SiCellId::isValid
bool isValid() const
Test if its in a valid state.
Definition: SiCellId.h:136
ALFA_EventTPCnv_Dict::t1
std::vector< ALFA_RawDataCollection_p1 > t1
Definition: ALFA_EventTPCnvDict.h:43
skel.it
it
Definition: skel.GENtoEVGEN.py:396
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
ActsTrk::StripSP::measurementIndexes
std::vector< std::size_t > measurementIndexes
Definition: IStripSpacePointFormationTool.h:25
InDetDD::StripStereoAnnulusDesign::phiWidth
double phiWidth() const
Definition: StripStereoAnnulusDesign.h:331
ActsTrk::localXFromSourceLink
float localXFromSourceLink(const ATLASUncalibSourceLink &source_link)
Definition: ATLASSourceLink.h:53
ActsTrk::StripSP::topStripDirection
Eigen::Matrix< float, 3, 1 > topStripDirection
Definition: IStripSpacePointFormationTool.h:28
ISiLorentzAngleTool.h
InDetDD::SiCellId::strip
int strip() const
Get strip number. Equivalent to phiIndex().
Definition: SiCellId.h:131
ActsTrk::Opposite
@ Opposite
Definition: StripInformationHelper.h:13
ActsTrk::EtaPlus
@ EtaPlus
Definition: StripInformationHelper.h:13
ActsTrk::CoreStripSpacePointFormationTool::getStripEnds
std::pair< Amg::Vector3D, Amg::Vector3D > getStripEnds(const xAOD::StripCluster *cluster, const InDetDD::SiDetectorElement *element, size_t &stripIndex) const
search
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
Definition: hcg.cxx:738
ActsTrk::StripSP::cov_r
float cov_r
Definition: IStripSpacePointFormationTool.h:23
InDetDD::SolidStateDetectorElementBase::identifyHash
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
ActsTrk::StripInformationHelper
Definition: StripInformationHelper.h:15
ActsTrk::StripSP::globPos
Eigen::Matrix< float, 3, 1 > globPos
Definition: IStripSpacePointFormationTool.h:22
InDetDD::SiLocalPosition
Definition: SiLocalPosition.h:31
InDetDD::StripStereoAnnulusDesign::diodesInRow
virtual int diodesInRow(const int row) const override
Definition: StripStereoAnnulusDesign.h:251
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
WriteHandle.h
Handle class for recording to StoreGate.
InDetDD::StripStereoAnnulusDesign::stripPosAtR
SiLocalPosition stripPosAtR(int strip, int row, double r) const
Definition: StripStereoAnnulusDesign.cxx:385
ContainerAccessor::rangesForIdentifierDirect
const boost::container::small_vector< Range, inline_size > rangesForIdentifierDirect(const identifier_t &identifier) const
Function to return the list of ranges corresponding to a given identifier.
Definition: ContainerAccessor.h:69
xAOD::UncalibratedMeasurement_v1
Definition: UncalibratedMeasurement_v1.h:13
ActsTrk::CoreStripSpacePointFormationTool::makeSpacePoint
StatusCode makeSpacePoint(const EventContext &ctx, std::vector< StripSP > &collection, std::shared_ptr< Acts::SpacePointBuilder< StripSP >> spBuilder, const ATLASUncalibSourceLink &currentSlink, const ATLASUncalibSourceLink &anotherSlink, const InDetDD::SiDetectorElement *currentElement, const InDetDD::SiDetectorElement *anotherElement, const double limit, const double slimit, const Acts::Vector3 &vertex) const
Definition: CoreStripSpacePointFormationTool.cxx:506
ActsTrk::makeATLASUncalibSourceLink
ATLASUncalibSourceLink makeATLASUncalibSourceLink(const xAOD::UncalibratedMeasurementContainer *container, std::size_t index, [[maybe_unused]] const EventContext &ctx)
Definition: ATLASSourceLink.h:30
InDetDD::StripStereoAnnulusDesign::minR
double minR() const
Definition: StripStereoAnnulusDesign.h:322
ActsTrk::StripSP::topHalfStripLength
float topHalfStripLength
Definition: IStripSpacePointFormationTool.h:26
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
InDetDD::Annulus
@ Annulus
Definition: DetectorDesign.h:42
InDetDD::StripStereoAnnulusDesign
Definition: StripStereoAnnulusDesign.h:50
ActsTrk::CoreStripSpacePointFormationTool::initialize
virtual StatusCode initialize() override
Definition: CoreStripSpacePointFormationTool.cxx:28
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
ActsTrk::CoreStripSpacePointFormationTool::m_stripId
const SCT_ID * m_stripId
Definition: CoreStripSpacePointFormationTool.h:99
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ActsTrk::CoreStripSpacePointFormationTool::produceSpacePoints
virtual StatusCode produceSpacePoints(const EventContext &ctx, const xAOD::StripClusterContainer &clusterContainer, const InDet::SiElementPropertiesTable &properties, const InDetDD::SiDetectorElementCollection &elements, const Amg::Vector3D &beamSpotVertex, std::vector< StripSP > &spacePoints, std::vector< StripSP > &overlapSpacePoints, bool processOverlaps, const std::vector< IdentifierHash > &hashesToProcess, const ContainerAccessor< xAOD::StripCluster, IdentifierHash, 1 > &stripAccessor) const override
Definition: CoreStripSpacePointFormationTool.cxx:37
xAOD::StripCluster_v1
Definition: StripCluster_v1.h:17
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsTrk::PhiPlus
@ PhiPlus
Definition: StripInformationHelper.h:13
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
ReadCellNoiseFromCool.dm
dm
Definition: ReadCellNoiseFromCool.py:235
ActsTrk::StripSP::bottomHalfStripLength
float bottomHalfStripLength
Definition: IStripSpacePointFormationTool.h:27
ActsTrk::CoreStripSpacePointFormationTool::m_overlapLimitPhi
Gaudi::Property< float > m_overlapLimitPhi
Definition: CoreStripSpacePointFormationTool.h:110
lumiFormat.array
array
Definition: lumiFormat.py:91
ActsTrk::StripSP::bottomStripDirection
Eigen::Matrix< float, 3, 1 > bottomStripDirection
Definition: IStripSpacePointFormationTool.h:29
ActsTrk::CoreStripSpacePointFormationTool::m_overlapLimitOpposite
Gaudi::Property< float > m_overlapLimitOpposite
Definition: CoreStripSpacePointFormationTool.h:109
ActsTrk::CoreStripSpacePointFormationTool::m_overlapLimitEtaMin
Gaudi::Property< float > m_overlapLimitEtaMin
Definition: CoreStripSpacePointFormationTool.h:111
ActsTrk::CoreStripSpacePointFormationTool::m_overlapLimitEtaMax
Gaudi::Property< float > m_overlapLimitEtaMax
Definition: CoreStripSpacePointFormationTool.h:112
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
InDetDD::SiDetectorElement::endsOfStrip
std::pair< Amg::Vector3D, Amg::Vector3D > endsOfStrip(const Amg::Vector2D &position) const
Special method for SCT to retrieve the two ends of a "strip" Returned coordinates are in global frame...
Definition: SiDetectorElement.cxx:339
ActsTrk::CoreStripSpacePointFormationTool::m_allClusters
Gaudi::Property< bool > m_allClusters
Definition: CoreStripSpacePointFormationTool.h:108
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
ActsTrk::CoreStripSpacePointFormationTool::CoreStripSpacePointFormationTool
CoreStripSpacePointFormationTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CoreStripSpacePointFormationTool.cxx:22
ActsTrk::CoreStripSpacePointFormationTool::m_stripGapParameter
Gaudi::Property< float > m_stripGapParameter
Definition: CoreStripSpacePointFormationTool.h:114
ActsTrk::getUncalibratedMeasurement
const xAOD::UncalibratedMeasurement & getUncalibratedMeasurement(const ATLASUncalibSourceLink &source_link)
Definition: ATLASSourceLink.h:26
SCT_ID::layer_disk
int layer_disk(const Identifier &id) const
Definition: SCT_ID.h:734
dumpNswErrorDb.maxStrip
tuple maxStrip
Definition: dumpNswErrorDb.py:27
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
InDet::SiElementPropertiesTable
Definition: SiElementPropertiesTable.h:30
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
InDetDD::SiDetectorElement::isBarrel
bool isBarrel() const
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
ActsTrk::CoreStripSpacePointFormationTool::computeOffset
double computeOffset(const InDetDD::SiDetectorElement &element1, const InDetDD::SiDetectorElement &element2, double &stripLengthGapTolerance) const
Definition: CoreStripSpacePointFormationTool.cxx:568
ParticleGun_SamplingFraction.radius
radius
Definition: ParticleGun_SamplingFraction.py:96
ActsTrk::StripSP::stripCenterDistance
Eigen::Matrix< float, 3, 1 > stripCenterDistance
Definition: IStripSpacePointFormationTool.h:30
SiDetectorElement.h
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
InDetDD::SiCellId
Definition: SiCellId.h:29
StripClusterAuxContainer.h
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
StripStereoAnnulusDesign.h
ALFA_EventTPCnv_Dict::t2
std::vector< ALFA_RawDataContainer_p1 > t2
Definition: ALFA_EventTPCnvDict.h:44
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
ContainerAccessor.h
ActsTrk::CoreStripSpacePointFormationTool::m_lorentzAngleTool
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
Definition: CoreStripSpacePointFormationTool.h:101
ActsTrk::PhiMinus
@ PhiMinus
Definition: StripInformationHelper.h:13
ActsTrk::ThisOne
@ ThisOne
Definition: StripInformationHelper.h:13
InDetDD::SolidStateDetectorElementBase::globalPosition
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
dumpNswErrorDb.minStrip
int minStrip
Definition: dumpNswErrorDb.py:26
ActsTrk::CoreStripSpacePointFormationTool::correctPolarRange
void correctPolarRange(const InDetDD::SiDetectorElement *element, double &min, double &max, size_t &minStrip, size_t &maxStrip) const
Definition: CoreStripSpacePointFormationTool.cxx:612
ATLASSourceLinkSurfaceAccessor.h
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MuonDetectorBuilderTool.cxx:54
InDetDD::StripStereoAnnulusDesign::localPositionOfCell
virtual SiLocalPosition localPositionOfCell(const SiCellId &cellId) const override
id -> position
Definition: StripStereoAnnulusDesign.cxx:362
CoreStripSpacePointFormationTool.h
ActsTrk::ATLASUncalibSourceLinkSurfaceAccessor
Definition: ATLASSourceLinkSurfaceAccessor.h:26
InDetDD::SiDetectorElement::isStereo
bool isStereo() const
Check if it is the stereo side (useful for SCT)
Definition: SiDetectorElement.cxx:300
SiCellId.h
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
minValue
#define minValue(current, test)
Definition: CompoundLayerMaterialCreator.h:21
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
ContainerAccessor::isIdentifierPresent
bool isIdentifierPresent(const identifier_t &identifier) const
Function to verify if a given identifier is present in the map, i.e.
Definition: ContainerAccessor.h:77
python.compressB64.c
def c
Definition: compressB64.py:93
updateCoolNtuple.limit
int limit
Definition: updateCoolNtuple.py:45
InDetDD::SiDetectorElementCollection::getDetectorElement
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Definition: SiDetectorElementCollection.cxx:15
ActsTrk::nNeighbours
@ nNeighbours
Definition: StripInformationHelper.h:13
ActsTrk::StripSP::topStripCenter
Eigen::Matrix< float, 3, 1 > topStripCenter
Definition: IStripSpacePointFormationTool.h:31
InDetDD::SolidStateDetectorElementBase::identify
virtual Identifier identify() const override final
identifier of this detector element (inline)
ActsTrk::CoreStripSpacePointFormationTool::fillSpacePoints
StatusCode fillSpacePoints(const EventContext &ctx, std::shared_ptr< Acts::SpacePointBuilder< StripSP >> spBuilder, const std::array< const InDetDD::SiDetectorElement *, nNeighbours > &neighbourElements, const std::array< std::vector< std::pair< ATLASUncalibSourceLink, size_t >>, nNeighbours > &neighbourSourceLinks, const std::array< double, 14 > &overlapExtents, const Amg::Vector3D &beamSpotVertex, std::vector< StripSP > &spacePoints, std::vector< StripSP > &overlapSpacePoints) const
Definition: CoreStripSpacePointFormationTool.cxx:304
InDetDD::StripStereoAnnulusDesign::maxR
double maxR() const
Definition: StripStereoAnnulusDesign.h:326
ActsTrk::CoreStripSpacePointFormationTool::m_trackingGeometryTool
ToolHandle< IActsTrackingGeometryTool > m_trackingGeometryTool
Definition: CoreStripSpacePointFormationTool.h:102
InDetDD::SolidStateDetectorElementBase::transform
virtual const Amg::Transform3D & transform() const override final
Return local to global transform.
ActsTrk::StripSP::idHashes
std::vector< unsigned int > idHashes
Definition: IStripSpacePointFormationTool.h:21
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
xAOD::UncalibMeasType::PixelClusterType
@ PixelClusterType
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
SCT_ID::is_barrel
bool is_barrel(const Identifier &id) const
Test for barrel - WARNING: id MUST be sct id, otherwise answer is not accurate. Use SiliconID for gen...
Definition: SCT_ID.h:721
ActsTrk::CoreStripSpacePointFormationTool::updateRange
void updateRange(const InDetDD::SiDetectorElement &element1, const InDetDD::SiDetectorElement &element2, double &stripLengthGapTolerance, double &min, double &max) const
Definition: CoreStripSpacePointFormationTool.cxx:602
Identifier
Definition: IdentifierFieldParser.cxx:14