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