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