ATLAS Offline Software
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 //Heavily inspired by https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/Acts/ActsTrackReconstruction/src/RandomProtoTrackCreator.cxx
10 
12  const std::string& name,
13  const IInterface* parent): base_class(type,name,parent) { }
14 
15 
17 
18  ATH_MSG_DEBUG("Initializing FPGAActsTrkConverter...");
19 
20  // Get SCT & pixel Identifier helpers
21  ATH_CHECK(detStore()->retrieve(m_pixelId, "PixelID"));
22  ATH_CHECK(detStore()->retrieve(m_SCTId, "SCT_ID"));
23 
24  return StatusCode::SUCCESS;
25 
26 }
27 
31  std::vector<ActsTrk::ProtoTrack> & foundProtoTracks,
32  const std::vector<std::vector<FPGATrackSimHit>>& hitsInRoads,
33  const std::vector<FPGATrackSimRoad>& roads) const {
34 
35  ATH_MSG_INFO("Creating Acts proto-tracks from FPGA roads...");
36 
37  if (hitsInRoads.size() > 0) {
38 
39  for(size_t roadIndex=0; roadIndex<=hitsInRoads.size()-1;roadIndex++) {
40  std::vector<ActsTrk::ATLASUncalibSourceLink> points;
41 
42  if (hitsInRoads.at(roadIndex).size()>0) {
43  // TODO: move from loops over cluster container to links
44  for(const FPGATrackSimHit& h : hitsInRoads.at(roadIndex)){
45  IdentifierHash hash = h.getIdentifierHash();
46  if (h.isReal()) {
47  if (h.isPixel()){
48  ATH_MSG_DEBUG("Looking for Pixel cluster to match");
49  Identifier wafer_id = m_pixelId->wafer_id(hash);
50  Identifier id = m_pixelId->pixel_id(wafer_id, h.getPhiIndex(), h.getEtaIndex());
51  for (const xAOD::PixelCluster* cl : pixelContainer) {
52  const auto& rdoList = cl->rdoList();
53  const auto it = std::find(rdoList.begin(), rdoList.end(), id);
54  if (it != rdoList.end()) {
55  points.emplace_back(ActsTrk::makeATLASUncalibSourceLink(&pixelContainer, cl->index(), ctx));
56  break;
57  }
58  }
59  }
60  if (h.isStrip()) {
61  ATH_MSG_DEBUG("Looking for Strip cluster to match");
62  int strip = static_cast<int>(h.getPhiCoord());
63  Identifier wafer_id = m_SCTId->wafer_id(hash);
64  Identifier id = m_SCTId->strip_id(wafer_id, strip);
65  for (const xAOD::StripCluster *cl : stripContainer){
66  const auto& rdoList = cl->rdoList();
67  const auto it = std::find(rdoList.begin(), rdoList.end(), id);
68  if (it != rdoList.end()) {
69  points.push_back(ActsTrk::makeATLASUncalibSourceLink(&stripContainer, cl->index(), ctx));
70  break;}
71  }
72  }
73  }
74  }
75  if(!points.size()){
76  ATH_MSG_ERROR("Found a proto-track with no measurements");
77  continue; // TODO: once resolved, instead of simply discarding these cases, return StatusCode::FAILURE
78  }
79  else {
80  ATH_MSG_INFO("\tMade a proto-track with " << points.size() << " clusters");
81 
82  // Make the input perigee
83  std::unique_ptr<Acts::BoundTrackParameters> inputPerigee = makeParams(roads.at(roadIndex));
84  foundProtoTracks.emplace_back(points, std::move(inputPerigee));
85  }
86  }
87  }
88  }
89 
90  return StatusCode::SUCCESS;
91 }
92 
96  std::vector<ActsTrk::ProtoTrack> & foundProtoTracks,
97  const std::vector<FPGATrackSimTrack>& tracks) const {
98 
99  ATH_MSG_INFO("Creating Acts proto-tracks from FPGA tracks...");
100 
101  for (const FPGATrackSimTrack& track : tracks) {
102  if (not track.passedOR()) continue;
103  std::vector<ActsTrk::ATLASUncalibSourceLink> points;
104  const std::vector <FPGATrackSimHit>& hits = track.getFPGATrackSimHits();
105 
106  if (hits.size() > 0) {
107 
108  // TODO: move from loops over cluster container to links
109 
110  for (const FPGATrackSimHit& h : hits) {
111  IdentifierHash hash = h.getIdentifierHash();
112  if (h.isReal()) {
113  if (h.isPixel()) {
114  ATH_MSG_DEBUG("Looking for Pixel cluster to match");
115  Identifier wafer_id = m_pixelId->wafer_id(hash);
116  Identifier id = m_pixelId->pixel_id(wafer_id, h.getPhiIndex(), h.getEtaIndex());
117  for (const xAOD::PixelCluster* cl : pixelContainer) {
118  const auto& rdoList = cl->rdoList();
119  const auto it = std::find(rdoList.begin(), rdoList.end(), id);
120  if (it != rdoList.end()) {
121  points.emplace_back(ActsTrk::makeATLASUncalibSourceLink(&pixelContainer, cl->index(), ctx));
122  break;}
123  }
124  }
125  else if (h.isStrip()) {
126  ATH_MSG_DEBUG("Looking for Strip cluster to match");
127  int strip = static_cast<int>(h.getPhiCoord());
128  Identifier wafer_id = m_SCTId->wafer_id(hash);
129  Identifier id = m_SCTId->strip_id(wafer_id, strip);
130  for (const xAOD::StripCluster* cl : stripContainer) {
131  const auto& rdoList = cl->rdoList();
132  const auto it = std::find(rdoList.begin(), rdoList.end(), id);
133  if (it != rdoList.end()) {
134  points.push_back(ActsTrk::makeATLASUncalibSourceLink(&stripContainer, cl->index(), ctx));
135  break;
136  }
137  }
138  }
139  else {
140  ATH_MSG_ERROR("FPGA hit not clasified as pixel or strip");
141  return StatusCode::FAILURE;
142  }
143  }
144  else
145  ATH_MSG_DEBUG("Skipping hit as non-Real");
146  }
147  if (!points.size()){
148  ATH_MSG_ERROR("Found a proto-track with no measurements");
149  continue; // TODO: once resolved, instead of simply discarding these cases, return StatusCode::FAILURE
150  }
151  else {
152  ATH_MSG_INFO("\tMade a proto-track with " << points.size() << " clusters");
153 
154  // Make the intput perigee
155  std::unique_ptr<Acts::BoundTrackParameters> inputPerigee = makeParams(track);
156  foundProtoTracks.emplace_back(points, std::move(inputPerigee));
157  }
158  }
159  else {
160  ATH_MSG_ERROR("Found FPGATrack without hits");
161  return StatusCode::FAILURE;
162  }
163  }
164 
165  return StatusCode::SUCCESS;
166 }
167 
168 std::unique_ptr<Acts::BoundTrackParameters> FPGAActsTrkConverter::makeParams (const FPGATrackSimRoad &road) const{
169  using namespace Acts::UnitLiterals;
170 
171  std::shared_ptr<const Acts::Surface> actsSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3(0., 0., 0.));
172  Acts::BoundVector params;
173 
174  constexpr double GeVToMeV = 1000;
175  double d0=0.; //?
176  double z0=0.; //?
177  double phi=road.getX();
178  double eta=0.2;
179  double theta=2*std::atan(std::exp(-eta));
180  double qop=road.getY()/GeVToMeV; //
181  double t=0.; //?
182  ATH_MSG_DEBUG("\tphi=" <<phi << " eta=" << eta << " qop=" << qop);
183 
184  params << d0, z0, phi, theta, qop, t;
185 
186  // Covariance - TODO
187  Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Identity();
188  cov *= (GeVToMeV*GeVToMeV);
189 
190  // some ACTS paperwork
191  Trk::ParticleHypothesis hypothesis = Trk::pion;
193  Acts::PdgParticle absPdg = Acts::makeAbsolutePdgParticle(Acts::ePionPlus);
194  Acts::ParticleHypothesis actsHypothesis{
195  absPdg, mass, Acts::AnyCharge{1.0f}};
196 
197  return std::make_unique<Acts::BoundTrackParameters>(actsSurface, params,
198  cov, actsHypothesis);
199 
200 }
201 
202 
203 std::unique_ptr<Acts::BoundTrackParameters> FPGAActsTrkConverter::makeParams (const FPGATrackSimTrack &track) const{
204 
205  using namespace Acts::UnitLiterals;
206  std::shared_ptr<const Acts::Surface> actsSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3(0., 0., 0.));
207  Acts::BoundVector params;
208 
209  constexpr double GeVToMeV = 1000;
210  double d0=track.getD0();
211  double z0=track.getZ0();
212  double phi=track.getPhi();
213  double theta=track.getTheta();
214  double qop=track.getQOverPt();
215  double t=0.;
216 
217  params << d0, z0, phi, theta, qop, t;
218  ATH_MSG_DEBUG("\td0= " << d0 << " z0=" <<z0 << " phi=" <<phi << " theta=" << theta<< " qoverp=" << qop);
219 
220  // Covariance - let's be honest and say we have no clue ;-)
221  Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Identity();
222  cov *= (GeVToMeV*GeVToMeV);
223 
224  // some ACTS paperwork
225  Trk::ParticleHypothesis hypothesis = Trk::pion;
227  Acts::PdgParticle absPdg = Acts::makeAbsolutePdgParticle(Acts::ePionPlus);
228  Acts::ParticleHypothesis actsHypothesis{
229  absPdg, mass, Acts::AnyCharge{1.0f}};
230 
231  return std::make_unique<Acts::BoundTrackParameters>(actsSurface, params,
232  cov, actsHypothesis);
233 
234 }
235 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
SiliconTech::strip
@ strip
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
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
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:42
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:11
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
skel.it
it
Definition: skel.GENtoEVGEN.py:396
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
DataPrepToActsConfig.stripContainer
stripContainer
Definition: DataPrepToActsConfig.py:10
FPGATrackSimRoad::getX
float getX() const
Definition: FPGATrackSimRoad.h:86
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
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
xAOD::StripCluster_v1
Definition: StripCluster_v1.h:17
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
FPGAActsTrkConverter::m_pixelId
const PixelID * m_pixelId
Definition: FPGAActsTrkConverter.h:41
Trk::ParticleMasses::mass
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:53
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
IdentifierHash.h
FPGAActsTrkConverter::initialize
virtual StatusCode initialize() override final
Definition: FPGAActsTrkConverter.cxx:16
xAOD::ParticleHypothesis
ParticleHypothesis
Definition: TrackingPrimitives.h:192
FPGATrackSimRoad::getY
float getY() const
Definition: FPGATrackSimRoad.h:87
xAOD::PixelCluster_v1
Definition: PixelCluster_v1.h:17
h
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
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:28
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
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:168
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
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
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
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:30
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