Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
FPGAActsTrkConverter.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 
3 #include "FPGAActsTrkConverter.h"
5 #include "Acts/Surfaces/PerigeeSurface.hpp"
8 
9 #include <format>
10 #include <sstream>
11 //Heavily inspired by https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/Acts/ActsTrackReconstruction/src/RandomProtoTrackCreator.cxx
12 
14  const std::string& name,
15  const IInterface* parent): base_class(type,name,parent) { }
16 
17 
19 
20  ATH_MSG_DEBUG("Initializing FPGAActsTrkConverter...");
21 
22  // Get SCT & pixel Identifier helpers
23  ATH_CHECK(detStore()->retrieve(m_pixelId, "PixelID"));
24  ATH_CHECK(detStore()->retrieve(m_SCTId, "SCT_ID"));
25 
26  return StatusCode::SUCCESS;
27 
28 }
29 
33  std::vector<ActsTrk::ProtoTrack> & foundProtoTracks,
34  const std::vector<std::vector<FPGATrackSimHit>>& hitsInRoads,
35  const std::vector<FPGATrackSimRoad>& roads) const {
36 
37  ATH_MSG_INFO("Creating Acts proto-tracks from FPGA roads...");
38 
39  if (hitsInRoads.size() > 0) {
40 
41  for(size_t roadIndex=0; roadIndex<=hitsInRoads.size()-1;roadIndex++) {
42  std::vector<ActsTrk::ATLASUncalibSourceLink> points;
43  ATH_CHECK(findPrototrackMeasurements(ctx, pixelContainer, stripContainer, points, hitsInRoads.at(roadIndex)));
44  if (points.size()) {
45  std::unique_ptr<Acts::BoundTrackParameters> inputPerigee = makeParams(roads.at(roadIndex));
46  foundProtoTracks.emplace_back(points, std::move(inputPerigee));
47  ATH_MSG_INFO("Made a prototrack with " << points.size() << " measurements");
48  }
49  }
50  }
51 
52  return StatusCode::SUCCESS;
53 }
54 
58  std::vector<ActsTrk::ProtoTrack> & foundProtoTracks,
59  const std::vector<FPGATrackSimTrack>& tracks) const {
60 
61  ATH_MSG_INFO("Creating Acts proto-tracks from FPGA tracks...");
62 
63  for (const FPGATrackSimTrack& track : tracks) {
64  if (not track.passedOR()) continue;
65  std::vector<ActsTrk::ATLASUncalibSourceLink> points;
66  const std::vector <FPGATrackSimHit>& hits = track.getFPGATrackSimHits();
68  if (points.size()){
69  ATH_MSG_INFO("\tMaking a proto-track with " << points.size() << " clusters");
70  std::unique_ptr<Acts::BoundTrackParameters> inputPerigee = makeParams(track);
71  foundProtoTracks.emplace_back(points, std::move(inputPerigee));
72  }
73  }
74  return StatusCode::SUCCESS;
75 }
76 
78  const xAOD::PixelClusterContainer &pixelClusterContainer,
79  const xAOD::StripClusterContainer &stripClusterContainer,
80  std::vector<ActsTrk::ATLASUncalibSourceLink>& measurements,
81  const std::vector <FPGATrackSimHit>& hits) const {
82  if (hits.empty()) {
83  ATH_MSG_ERROR("Found FPGATrack without hits");
84  return StatusCode::FAILURE;
85  }
86  // TODO: move from loops over cluster container to links
87  for (const FPGATrackSimHit& h : hits) {
88  if (h.isReal()) {
89  std::vector<Identifier> ids = getRdoIdList(h);
90  if (h.isPixel()) {
91  ATH_MSG_DEBUG("Looking for Pixel cluster to match");
92  ATH_CHECK(matchTrackMeasurements<xAOD::PixelCluster>(ctx, pixelClusterContainer, ids, measurements));
93  }
94  else if (h.isStrip()) {
95  ATH_MSG_DEBUG("Looking for Strip cluster to match");
96  ATH_CHECK(matchTrackMeasurements<xAOD::StripCluster>(ctx, stripClusterContainer, ids, measurements));
97  }
98  else {
99  ATH_MSG_ERROR("FPGA hit not classified as pixel or strip");
100  return StatusCode::FAILURE;
101  }
102  }
103  else
104  ATH_MSG_DEBUG("Skipping hit as non-Real");
105  }
106  return StatusCode::SUCCESS;
107 }
108 
109 std::vector<Identifier> FPGAActsTrkConverter::getRdoIdList(const FPGATrackSimHit& hit) const
110 {
111  std::vector<Identifier> ids;
112  const auto& idHashVec = hit.getIDHashVec();
113  const auto& phiIndexVec = hit.getPhiIndexVec();
114  const auto& etaIndexVec = hit.getEtaIndexVec();
115 
116  ids.reserve(idHashVec.size());
117 
118  if (hit.isPixel())
119  {
120  for (size_t i = 0; i < idHashVec.size(); ++i)
121  {
122  ids.emplace_back(m_pixelId->pixel_id(
123  m_pixelId->wafer_id(idHashVec[i]),
124  phiIndexVec[i],
125  etaIndexVec[i]
126  ));
127  }
128  }
129  else if (hit.isStrip())
130  {
131  for (size_t i = 0; i < idHashVec.size(); ++i)
132  {
133  ids.emplace_back(m_SCTId->strip_id(
134  m_SCTId->wafer_id(idHashVec[i]),
135  phiIndexVec[i]
136  ));
137  }
138  }
139  return ids;
140 }
141 
142 
143 template <typename XAOD_CLUSTER>
145  const DataVector<XAOD_CLUSTER>& clusterContainer,
146  const std::vector<Identifier>& rdoIDs,
147  std::vector<ActsTrk::ATLASUncalibSourceLink>& measurements) const
148 {
149  for (const XAOD_CLUSTER* cl : clusterContainer) {
150  const auto& rdoList = cl->rdoList();
151  if(rdoIDs.size() != rdoList.size()) continue;
152  size_t matchedCounter=0;
153  for (const Identifier& id: rdoIDs){
154  if(std::find(rdoList.begin(), rdoList.end(),id) != rdoList.end()) matchedCounter++;
155  }
156  if(matchedCounter == rdoList.size())
157  measurements.emplace_back(ActsTrk::makeATLASUncalibSourceLink(&clusterContainer, cl->index(), ctx));
158  else if (matchedCounter>0) {
159  std::stringstream ss;
160  ss << "List of xAOD cluster rdoIDs:\n";
161  for (const Identifier& id: rdoList) ss << id << "\n";
162 
163  ss << "\nList of FPGA cluster rdoIDs:\n";
164  for (const Identifier& id: rdoIDs) ss << id << "\n";
165 
166  ATH_MSG_ERROR(std::format("Noticed rdoID mismatch: commonHits = {} | xAODClusterHits = {} | FPGAClusterHits = {}\n{}",
167  matchedCounter, rdoList.size(), rdoIDs.size(), ss.str()));
168  return StatusCode::FAILURE;
169  }
170  }
171  return StatusCode::SUCCESS;
172 }
173 
174 std::unique_ptr<Acts::BoundTrackParameters> FPGAActsTrkConverter::makeParams (const FPGATrackSimRoad &road) const{
175  using namespace Acts::UnitLiterals;
176 
177  std::shared_ptr<const Acts::Surface> actsSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3(0., 0., 0.));
178  Acts::BoundVector params;
179 
180  constexpr double GeVToMeV = 1000;
181  double d0=0.; //?
182  double z0=0.; //?
183  double phi=road.getX();
184  double eta=0.2;
185  double theta=2*std::atan(std::exp(-eta));
186  double qop = (std::abs(road.getY()) > 1E-9) ? road.getY()/GeVToMeV : 1E-12;
187  double t=0.; //?
188  ATH_MSG_DEBUG("\tphi=" <<phi << " eta=" << eta << " qop=" << qop);
189 
190  params << d0, z0, phi, theta, qop, t;
191 
192  // Covariance - TODO
193  Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Identity();
194  cov *= (GeVToMeV*GeVToMeV);
195 
196  // some ACTS paperwork
197  Trk::ParticleHypothesis hypothesis = Trk::pion;
199  Acts::PdgParticle absPdg = Acts::makeAbsolutePdgParticle(Acts::ePionPlus);
200  Acts::ParticleHypothesis actsHypothesis{
201  absPdg, mass, Acts::AnyCharge{1.0f}};
202 
203  return std::make_unique<Acts::BoundTrackParameters>(actsSurface, params,
204  cov, actsHypothesis);
205 
206 }
207 
208 
209 std::unique_ptr<Acts::BoundTrackParameters> FPGAActsTrkConverter::makeParams (const FPGATrackSimTrack &track) const{
210 
211  using namespace Acts::UnitLiterals;
212  std::shared_ptr<const Acts::Surface> actsSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3(0., 0., 0.));
213  Acts::BoundVector params;
214 
215  constexpr double GeVToMeV = 1000;
216  double d0=track.getD0();
217  double z0=track.getZ0();
218  double phi=track.getPhi();
219  double theta=track.getTheta();
220  double qop=track.getQOverPt();
221  double t=0.;
222 
223  params << d0, z0, phi, theta, qop, t;
224  ATH_MSG_DEBUG("\td0= " << d0 << " z0=" <<z0 << " phi=" <<phi << " theta=" << theta<< " qoverp=" << qop);
225 
226  // Covariance - let's be honest and say we have no clue ;-)
227  Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Identity();
228  cov *= (GeVToMeV*GeVToMeV);
229 
230  // some ACTS paperwork
231  Trk::ParticleHypothesis hypothesis = Trk::pion;
233  Acts::PdgParticle absPdg = Acts::makeAbsolutePdgParticle(Acts::ePionPlus);
234  Acts::ParticleHypothesis actsHypothesis{
235  absPdg, mass, Acts::AnyCharge{1.0f}};
236 
237  return std::make_unique<Acts::BoundTrackParameters>(actsSurface, params,
238  cov, actsHypothesis);
239 
240 }
241 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
FPGATrackSimHit::getEtaIndexVec
const std::vector< int > & getEtaIndexVec() const
Definition: FPGATrackSimHit.h:189
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
FPGATrackSimHit::isStrip
bool isStrip() const
Definition: FPGATrackSimHit.h:65
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
vtune_athena.format
format
Definition: vtune_athena.py:14
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
FPGAActsTrkConverter::getRdoIdList
std::vector< Identifier > getRdoIdList(const FPGATrackSimHit &hit) const
Definition: FPGAActsTrkConverter.cxx:109
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
FPGATrackSimTrack
Definition: FPGATrackSimTrack.h:18
FPGAActsTrkConverter::m_SCTId
const SCT_ID * m_SCTId
Definition: FPGAActsTrkConverter.h:54
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
FPGAActsTrkConverter::FPGAActsTrkConverter
FPGAActsTrkConverter(const std::string &type, const std::string &name, const IInterface *parent)
Definition: FPGAActsTrkConverter.cxx:13
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
FPGATrackSimHit::getPhiIndexVec
const std::vector< int > & getPhiIndexVec() const
Definition: FPGATrackSimHit.h:188
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
FPGATrackSimHit::getIDHashVec
const std::vector< unsigned > & getIDHashVec() const
Definition: FPGATrackSimHit.h:190
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
FPGAActsTrkConverter::matchTrackMeasurements
StatusCode matchTrackMeasurements(const EventContext &ctx, const DataVector< XAOD_CLUSTER > &clusterContainer, const std::vector< Identifier > &rdoIDs, std::vector< ActsTrk::ATLASUncalibSourceLink > &measurements) const
Definition: FPGAActsTrkConverter.cxx:144
DataPrepToActsConfig.stripContainer
stripContainer
Definition: DataPrepToActsConfig.py:10
FPGATrackSimRoad::getX
float getX() const
Definition: FPGATrackSimRoad.h:87
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
PixelID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: PixelID.h:364
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
FPGATrackSimHit
Definition: FPGATrackSimHit.h:41
Trk::ParticleHypothesis
ParticleHypothesis
Definition: ParticleHypothesis.h:25
ActsTrk::makeATLASUncalibSourceLink
ATLASUncalibSourceLink makeATLASUncalibSourceLink(const xAOD::UncalibratedMeasurementContainer *container, std::size_t index, [[maybe_unused]] const EventContext &ctx)
Definition: ATLASSourceLink.h:30
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
FPGAActsTrkConverter.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Trk::pion
@ pion
Definition: ParticleHypothesis.h:29
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TRT::Track::z0
@ z0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:63
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
ParticleHypothesis.h
FPGATrackSimHit::isPixel
bool isPixel() const
Definition: FPGATrackSimHit.h:64
FPGAActsTrkConverter::m_pixelId
const PixelID * m_pixelId
Definition: FPGAActsTrkConverter.h:53
Trk::ParticleMasses::mass
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:53
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
FPGAActsTrkConverter::findPrototrackMeasurements
StatusCode findPrototrackMeasurements(const EventContext &ctx, const xAOD::PixelClusterContainer &pixelClusterContainer, const xAOD::StripClusterContainer &stripClusterContainer, std::vector< ActsTrk::ATLASUncalibSourceLink > &measurements, const std::vector< FPGATrackSimHit > &hits) const
Definition: FPGAActsTrkConverter.cxx:77
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
python.subdetectors.mmg.ids
ids
Definition: mmg.py:8
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
IdentifierHash.h
FPGAActsTrkConverter::initialize
virtual StatusCode initialize() override final
Definition: FPGAActsTrkConverter.cxx:18
xAOD::ParticleHypothesis
ParticleHypothesis
Definition: TrackingPrimitives.h:193
FPGATrackSimRoad::getY
float getY() const
Definition: FPGATrackSimRoad.h:88
h
FPGAActsTrkConverter::findProtoTracks
virtual StatusCode findProtoTracks(const EventContext &ctx, const xAOD::PixelClusterContainer &pixelContainer, const xAOD::StripClusterContainer &stripContainer, std::vector< ActsTrk::ProtoTrack > &foundProtoTracks, const std::vector< std::vector< FPGATrackSimHit >> &hitsInRoads, const std::vector< FPGATrackSimRoad > &roads) const override final
Definition: FPGAActsTrkConverter.cxx:30
PixelID::pixel_id
Identifier pixel_id(int barrel_ec, int layer_disk, int phi_module, int eta_module, int phi_index, int eta_index) const
For an individual pixel.
Definition: PixelID.h:432
FPGAActsTrkConverter::makeParams
std::unique_ptr< Acts::BoundTrackParameters > makeParams(const FPGATrackSimRoad &road) const
Definition: FPGAActsTrkConverter.cxx:174
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
SCT_ID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module, int side) const
For a single side of module.
Definition: SCT_ID.h:464
DataPrepToActsConfig.pixelContainer
pixelContainer
Definition: DataPrepToActsConfig.py:9
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
jobOptions.points
points
Definition: jobOptions.GenevaPy8_Zmumu.py:97
FPGATrackSimRoad
Definition: FPGATrackSimRoad.h:31
SCT_ID::strip_id
Identifier strip_id(int barrel_ec, int layer_disk, int phi_module, int eta_module, int side, int strip) const
For an individual strip.
Definition: SCT_ID.h:535
Identifier
Definition: IdentifierFieldParser.cxx:14