ATLAS Offline Software
Loading...
Searching...
No Matches
TritonTracccTrackMaker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <memory>
6#include <fstream>
7#include <sstream>
8
10
12
13#include <chrono>
14
16{
17 // input handles / tools
18 ATH_CHECK(detStore()->retrieve(m_pixelID, "PixelID"));
19 ATH_CHECK(detStore()->retrieve(m_stripID, "SCT_ID"));
20
21 ATH_CHECK(m_tracccCellsKey.initialize());
22
23 // output container
25
29
30 // geometry helper for output
31 if (!m_trackingGeometrySvc.empty()) {
33 m_trackingGeometry = m_trackingGeometrySvc->trackingGeometry();
34 if (!m_trackingGeometry) {
35 ATH_MSG_DEBUG("Null Acts::TrackingGeometry from tracking geometry service");
36 return StatusCode::FAILURE;
37 }
38
40 if (!m_detEleToGeoIdMap) {
41 ATH_MSG_DEBUG("Null detector element to Acts geometry ID map from "
42 "tracking geometry service");
43 return StatusCode::FAILURE;
44 }
45 }
46
47 // tools
49
51
52 // Initialize condition handle keys
53 ATH_CHECK(m_pixelDetEleCollKey.initialize());
54 ATH_CHECK(m_stripDetEleCollKey.initialize());
55
56 // Initialize cluster container keys
62
63 // Initialize truth association keys if needed
66
67 ATH_CHECK(m_ctxProvider.initialize());
68
69 return StatusCode::SUCCESS;
70}
71
72StatusCode TritonTracccTrackMaker::execute(const EventContext& ctx) const
73{
74
75 // fill cells struct for sending to traccc
76 auto cell_start = std::chrono::high_resolution_clock::now();
77
78 // Read the cells produced by RDOtoTracccCellConverterAlg.
79 auto cells_handle = SG::makeHandle(m_tracccCellsKey, ctx);
80 ATH_CHECK(cells_handle.isValid());
81
82 traccc::edm::silicon_cell_collection::const_device cells{*cells_handle};
83
84 std::vector<uint8_t> cells_buffer;
85 ATH_CHECK(serializeCells(cells, cells_buffer));
86
87 auto cell_end = std::chrono::high_resolution_clock::now();
88 std::chrono::duration<double, std::milli> cell_time = cell_end - cell_start;
89 ATH_MSG_INFO("Cell reading time: " << cell_time.count() << " ms");
90
91 std::unordered_map<int64_t, int> cluster_map;
92 if (m_doTruth)
93 {
94 cluster_map = readAndConvertClusters(ctx);
95 }
96
97 // create output containers
98 std::vector<TracccTrackParameters> TracccTrackParams;
99 std::vector<LocalMeasurementInfoInTracks> TracccMeasurementsInfoInTracks;
100
101 // Run the inference
102 auto traccc_start = std::chrono::high_resolution_clock::now();
103 ATH_CHECK(m_tracccTrackingTool->getTracks(cells_buffer, TracccTrackParams, TracccMeasurementsInfoInTracks));
104 auto traccc_end = std::chrono::high_resolution_clock::now();
105 std::chrono::duration<double, std::milli> traccc_time = traccc_end - traccc_start;
106 ATH_MSG_INFO("Traccc total inference time: " << traccc_time.count() << " ms");
107
108 // convert to ACTs tracks
109 unsigned int nb_output_tracks = 0;
110 auto convert_start = std::chrono::high_resolution_clock::now();
111 ATH_CHECK(convertTracks(ctx, TracccTrackParams, TracccMeasurementsInfoInTracks,
112 cluster_map, nb_output_tracks));
113 auto convert_end = std::chrono::high_resolution_clock::now();
114 std::chrono::duration<double, std::milli> convert_time = convert_end - convert_start;
115 ATH_MSG_INFO("Traccc total conversion time: " << convert_time.count() << " ms");
116
117 return StatusCode::SUCCESS;
118}
119
120// Serialize the traccc::cells object to a raw uint8 buffer
121inline void appendBytes(std::vector<uint8_t>& out, const uint64_t& value)
122{
123 const auto* p = reinterpret_cast<const uint8_t*>(&value);
124 out.insert(out.end(), p, p + sizeof(value));
125}
126inline void appendBytes(std::vector<uint8_t>& out, const uint32_t& value)
127{
128 const auto* p = reinterpret_cast<const uint8_t*>(&value);
129 out.insert(out.end(), p, p + sizeof(value));
130}
131inline void appendBytes(std::vector<uint8_t>& out, const float& value)
132{
133 const auto* p = reinterpret_cast<const uint8_t*>(&value);
134 out.insert(out.end(), p, p + sizeof(value));
135}
136
138 const traccc::edm::silicon_cell_collection::const_device& cells,
139 std::vector<uint8_t>& out) const
140{
141 const uint64_t nCells = cells.size();
142
143 // Reserve: 8-byte header + 5 columns * (4 or 4-byte scalars) per cell.
144 out.clear();
145 out.reserve(sizeof(uint64_t) + nCells * (3 * sizeof(uint32_t) + 2 * sizeof(float)));
146
147 // Header: number of cells.
148 appendBytes(out, nCells);
149
150 // SoA column blocks, in silicon_cell_collection column order.
151 for (uint64_t i = 0; i < nCells; ++i) {
152 appendBytes(out, static_cast<uint32_t>(cells.channel0()[i]));
153 }
154 for (uint64_t i = 0; i < nCells; ++i) {
155 appendBytes(out, static_cast<uint32_t>(cells.channel1()[i]));
156 }
157 for (uint64_t i = 0; i < nCells; ++i) {
158 appendBytes(out, static_cast<float>(cells.activation()[i]));
159 }
160 for (uint64_t i = 0; i < nCells; ++i) {
161 appendBytes(out, static_cast<float>(cells.time()[i]));
162 }
163 for (uint64_t i = 0; i < nCells; ++i) {
164 appendBytes(out, static_cast<uint32_t>(cells.module_index()[i]));
165 }
166
167 ATH_MSG_DEBUG("Serialized " << nCells << " traccc cells into "
168 << out.size() << " bytes");
169
170 return StatusCode::SUCCESS;
171}
172
173std::unordered_map<int64_t, int> TritonTracccTrackMaker::readAndConvertClusters(
174 const EventContext& eventContext) const
175{
176 int nPix = 0;
177 int nStrip = 0;
178 std::unordered_map<int64_t, int> traccc_to_xaod_cluster_map;
179
180 ATH_MSG_INFO("Converting InDet clusters to xAOD");
182 xAODPixelContainerFromInDetClusters(
184 if ((xAODPixelContainerFromInDetClusters.record(
185 std::make_unique<xAOD::PixelClusterContainer>(),
186 std::make_unique<xAOD::PixelClusterAuxContainer>()))
187 .isFailure()) {
189 "Could not record xAOD Pixel container from InDet Clusters");
190 throw std::runtime_error(
191 "creation of xAOD Pixel container from InDet Clusters failed");
192 }
193
195 xAODStripContainerFromInDetClusters(
197 if ((xAODStripContainerFromInDetClusters.record(
198 std::make_unique<xAOD::StripClusterContainer>(),
199 std::make_unique<xAOD::StripClusterAuxContainer>()))
200 .isFailure()) {
202 "Could not record xAOD Strip container from InDet Clusters");
203 throw std::runtime_error(
204 "creation of xAOD Strip container from InDet Clusters failed");
205 }
206
208 m_pixelDetEleCollKey, eventContext);
209
210 const InDetDD::SiDetectorElementCollection* pixElements{};
211 if (SG::get(pixElements, m_pixelDetEleCollKey, eventContext).isFailure() ||
212 pixElements == nullptr) {
213 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
214 std::ostringstream errMsg;
215 errMsg << m_pixelDetEleCollKey.fullKey() << " is not available.";
216 throw std::runtime_error(errMsg.str());
217 }
218
220 m_stripDetEleCollKey, eventContext);
221 const InDetDD::SiDetectorElementCollection* stripElements(
222 *stripDetEleHandle);
223 if (not stripDetEleHandle.isValid() or stripElements == nullptr) {
224 ATH_MSG_FATAL(m_stripDetEleCollKey.fullKey() << " is not available.");
225 std::ostringstream errMsg;
226 errMsg << m_stripDetEleCollKey.fullKey() << " is not available.";
227 throw std::runtime_error(errMsg.str());
228 }
229
231 xAODSpacepointContainerFromInDetClusters(
233 if (xAODSpacepointContainerFromInDetClusters
234 .record(std::make_unique<xAOD::SpacePointContainer>(),
235 std::make_unique<xAOD::SpacePointAuxContainer>())
236 .isFailure()) {
237 throw std::runtime_error(
238 "creation of InDet spacepoint containers failed");
239 }
240
241 ATH_MSG_DEBUG("Reading clusters");
242
243 const InDet::PixelClusterContainer* inputPixelClusterContainer{};
244 if (SG::get(inputPixelClusterContainer, m_inputPixelClusterContainerKey,
245 eventContext)
246 .isFailure() ||
247 inputPixelClusterContainer == nullptr) {
249 << " is not available.");
250 std::ostringstream errMsg;
251 errMsg << m_inputPixelClusterContainerKey.fullKey()
252 << " is not available.";
253 throw std::runtime_error(errMsg.str());
254 }
255
256 for (const auto* const clusterCollection : *inputPixelClusterContainer) {
257 if (!clusterCollection)
258 continue;
259 for (const auto* const theCluster : *clusterCollection) {
260
261 const InDetDD::SiDetectorElement* element =
262 theCluster->detectorElement();
263 const Identifier Pixel_ModuleID = element->identify();
264
265 auto pixelCl = xAODPixelContainerFromInDetClusters->push_back(
266 std::make_unique<xAOD::PixelCluster>());
267 if ((convertInDetToXaodCluster(*theCluster, *element, *pixelCl))
268 .isFailure()) {
269 ATH_MSG_FATAL("Could not convert InDet pixel cluster to xAOD");
270 throw std::runtime_error(
271 "conversion of InDet pixel cluster to xAOD failed");
272 }
273
274 auto xaod_sp = xAODSpacepointContainerFromInDetClusters->push_back(
275 std::make_unique<xAOD::SpacePoint>());
276 const IdentifierHash Pixel_ModuleHash =
277 m_pixelID->wafer_hash(Pixel_ModuleID);
278
280 xAOD::MeasVector<3> globalPosition{xAOD::toStorage(theCluster->globalPosition())};
281
282 xaod_sp->setSpacePoint(Pixel_ModuleHash, globalPosition,
283 globalVariance(0, 0), globalVariance(1, 0),
284 {pixelCl});
285
286 size_t index = xAODPixelContainerFromInDetClusters->size() - 1;
287 traccc_to_xaod_cluster_map[Pixel_ModuleID.get_compact()] = index;
288
289 nPix++;
290 }
291 }
292 ATH_MSG_DEBUG("Read " << nPix << " pixel clusters");
293
294 const InDet::SCT_ClusterContainer* inputStripClusterContainer{};
295 if (SG::get(inputStripClusterContainer, m_inputStripClusterContainerKey,
296 eventContext)
297 .isFailure() ||
298 inputStripClusterContainer == nullptr) {
300 << " is not available.");
301 std::ostringstream errMsg;
302 errMsg << m_inputStripClusterContainerKey.fullKey()
303 << " is not available.";
304 throw std::runtime_error(errMsg.str());
305 }
306
307 for (const auto* const clusterCollection : *inputStripClusterContainer) {
308 if (!clusterCollection)
309 continue;
310 for (const auto* const theCluster : *clusterCollection) {
311
312 const InDetDD::SiDetectorElement* element =
313 theCluster->detectorElement();
314 const Identifier Strip_ModuleID = element->identify();
315
316 xAOD::StripCluster* stripCl = new xAOD::StripCluster();
317 xAODStripContainerFromInDetClusters->push_back(stripCl);
318 if ((convertInDetToXaodCluster(*theCluster, *element, *stripCl))
319 .isFailure()) {
320 ATH_MSG_FATAL("Could not convert InDet strip cluster to xAOD");
321 throw std::runtime_error(
322 "conversion of InDet strip cluster to xAOD failed");
323 }
324 size_t index = xAODStripContainerFromInDetClusters->size() - 1;
325 traccc_to_xaod_cluster_map[Strip_ModuleID.get_compact()] = index;
326
327 nStrip++;
328 }
329 }
330
331 ATH_MSG_DEBUG("Read " << nStrip << " strip clusters");
332
333 return traccc_to_xaod_cluster_map;
334}
335
337 const InDet::PixelCluster& indetCluster,
338 const InDetDD::SiDetectorElement& element, xAOD::PixelCluster& xaodCluster) const
339{
340 IdentifierHash idHash = element.identifyHash();
341
342 auto localPos = indetCluster.localPosition();
343 auto localCov = indetCluster.localCovariance();
344
345 xAOD::MeasVector<2> localPosition = xAOD::toStorage(localPos);
346
347 xAOD::MeasMatrix<2> localCovariance;
348 localCovariance.setZero();
349 localCovariance(0, 0) = localCov(0, 0);
350 localCovariance(1, 1) = localCov(1, 1);
351
352 auto globalPos = indetCluster.globalPosition();
353 Eigen::Matrix<float, 3, 1> globalPosition(globalPos.x(), globalPos.y(),
354 globalPos.z());
355
356 const auto& RDOs = indetCluster.rdoList();
357 const auto& ToTs = indetCluster.totList();
358 const auto& charges = indetCluster.chargeList();
359 const auto& width = indetCluster.width();
360 //coverity[UNINIT]
361 xaodCluster.setMeasurement<2>(idHash, localPosition, localCovariance);
362 xaodCluster.setIdentifier(indetCluster.identify().get_compact());
363 xaodCluster.setRDOlist(RDOs);
364 xaodCluster.globalPosition() = globalPosition;
365 xaodCluster.setToTlist(ToTs);
366 xaodCluster.setChargelist(charges);
367 xaodCluster.setLVL1A(indetCluster.LVL1A());
368 xaodCluster.setChannelsInPhiEta(width.colRow()[0], width.colRow()[1]);
369 xaodCluster.setWidthInEta(static_cast<float>(width.widthPhiRZ()[1]));
370
371 return StatusCode::SUCCESS;
372}
373
375 const InDet::SCT_Cluster& indetCluster,
376 const InDetDD::SiDetectorElement& element, xAOD::StripCluster& xaodCluster) const
377{
378 constexpr double one_over_twelve = 1. / 12.;
379 IdentifierHash idHash = element.identifyHash();
380
381 auto localPos = indetCluster.localPosition();
382
383 xAOD::MeasVector<1> localPosition;
384 xAOD::MeasMatrix<1> localCovariance;
385 localCovariance.setZero();
386
387 if (element.isBarrel()) {
388 localPosition(0, 0) = localPos.x();
389 localCovariance(0, 0) =
390 element.phiPitch() * element.phiPitch() * one_over_twelve;
391 } else {
392 InDetDD::SiCellId cellId = element.cellIdOfPosition(localPos);
394 dynamic_cast<const InDetDD::StripStereoAnnulusDesign*>(
395 &element.design());
396 if (design == nullptr) {
397 return StatusCode::FAILURE;
398 }
399 InDetDD::SiLocalPosition localInPolar =
400 design->localPositionOfCellPC(cellId);
401 localPosition(0, 0) = localInPolar.xPhi();
402 localCovariance(0, 0) =
403 design->phiPitchPhi() * design->phiPitchPhi() * one_over_twelve;
404 }
405
406 auto globalPos = indetCluster.globalPosition();
407 Eigen::Matrix<float, 3, 1> globalPosition(globalPos.x(), globalPos.y(),
408 globalPos.z());
409
410 const auto& RDOs = indetCluster.rdoList();
411 const auto& width = indetCluster.width();
412 //coverity[UNINIT]
413 xaodCluster.setMeasurement<1>(idHash, localPosition, localCovariance);
414 xaodCluster.setIdentifier(indetCluster.identify().get_compact());
415 xaodCluster.setRDOlist(RDOs);
416 xaodCluster.globalPosition() = globalPosition;
417 xaodCluster.setChannelsInPhi(width.colRow()[0]);
418
419 return StatusCode::SUCCESS;
420}
421
423 const Identifier& atlasID) const
424{
425 const bool isPixel = m_pixelID->is_pixel(atlasID);
426 const IdentifierHash hash = isPixel ? m_pixelID->wafer_hash(atlasID)
427 : m_stripID->wafer_hash(atlasID);
428 const auto measType = isPixel ? xAOD::UncalibMeasType::PixelClusterType
430
431 const auto geoKey = ActsTrk::makeDetectorElementKey(
432 measType, static_cast<unsigned int>(hash));
433 const auto it = m_detEleToGeoIdMap->find(geoKey);
434 if (it != m_detEleToGeoIdMap->end()) {
435 const Acts::Surface* surface = m_trackingGeometry->findSurface(
437 if (surface) {
438 return surface;
439 }
440 }
441 ATH_MSG_DEBUG("No Acts surface corresponding to this ATLAS id: " << atlasID);
442 return nullptr;
443}
444
446 const LocalMeasurementInfoInTracks& state) const
447{
448 // traccc's model output is in Acts-native units
449 Acts::BoundMatrix cov = Acts::BoundMatrix::Zero();
450 for (unsigned int i = 0; i < 5; i++) {
451 for (unsigned int j = 0; j < 5; j++) {
452 size_t index = i * 5 + j;
453 cov(i, j) = state.covariances[index];
454 }
455 }
456
457 // traccc does not fit the time parameter (yet). Give it a
458 // large placeholder uncertainty instead of leaving it at zero.
459 constexpr double kUnconstrainedTimeVariance = 1e6;
460 cov(Acts::eBoundTime, Acts::eBoundTime) = kUnconstrainedTimeVariance;
461
462 return cov;
463}
464
465std::optional<Acts::BoundTrackParameters>
467 const LocalMeasurementInfoInTracks& state) const
468{
469 using namespace Acts::UnitLiterals;
470 std::shared_ptr<const Acts::Surface> actsSurface;
471 Acts::BoundVector params{};
472
473 Identifier const atlas_ID(static_cast<Identifier::value_type>(state.athena_id[0]));
474
475 // get the associated surface
476 const Acts::Surface* surface = actsSurfaceFromAtlasId(atlas_ID);
477 if (!surface) {
478 return std::nullopt;
479 }
480 actsSurface = surface->getSharedPtr();
481
482 // Construct track parameters
483 ATH_MSG_VERBOSE("Constructing track parameters for this state");
484 params << state.local_x[0], state.local_y[0],
485 state.phi[0], state.theta[0], state.qop[0], state.time[0];
486
487 Acts::BoundMatrix const cov = buildBoundCovariance(state);
488
489 Acts::ParticleHypothesis hypothesis{Acts::ParticleHypothesis::pion()};
490
491 return Acts::BoundTrackParameters(actsSurface, params, cov, hypothesis);
492}
493
495 EventContext const& eventContext,
496 std::vector<TracccTrackParameters>& trackParams,
497 std::vector<LocalMeasurementInfoInTracks>& measInfo,
498 const std::unordered_map<int64_t, int>& cluster_map,
499 unsigned& nb_output_tracks) const
500{
501 nb_output_tracks = 0;
502
503 Acts::VectorTrackContainer track_backend;
504 Acts::VectorMultiTrajectory track_state_backend;
505 ActsTrk::MutableTrackContainer track_container(
506 std::move(track_backend), std::move(track_state_backend));
507
508 SG::WriteHandle<ActsTrk::TrackContainer> trackContainerHandle(
509 m_ActsTracccTrackContainerKey, eventContext);
510
511 Acts::GeometryContext tgContext = m_ctxProvider.getGeometryContext(eventContext);
512
513 if (m_doTruth) {
514 ATH_MSG_DEBUG("Will map truth");
515 ATH_MSG_DEBUG("retrieving cluster container keys: "
518 }
519
520 // Debug stats
521 float chi2_min = std::numeric_limits<float>::max();
522 float chi2_max = std::numeric_limits<float>::min();
523
524 float ndf_min = std::numeric_limits<float>::max();
525 float ndf_max = std::numeric_limits<float>::min();
526
527 unsigned meas_min = std::numeric_limits<unsigned>::max();
528 unsigned meas_max = std::numeric_limits<unsigned>::min();
529
530 int excluded_ndf = 0;
531 int excluded_no_sp = 0;
532 int excluded_weird_state = 0;
533
534 for (std::size_t i = 0; i < trackParams.size(); i++) {
535 auto fit_res = trackParams.at(i);
536 auto& states = measInfo.at(i);
537 if (states.local_x.size() < 1) {
538 excluded_no_sp += 1;
539 continue;
540 }
541
542 // In Acts ndf, aka nDoF, is unsigned int. This makes sure the number is
543 // safe to cast; exclude the track otherwise.
544 if (fit_res.ndf >
545 static_cast<float>(std::numeric_limits<unsigned int>::max()) ||
546 fit_res.ndf <
547 static_cast<float>(std::numeric_limits<unsigned int>::min())) {
548 excluded_ndf += 1;
549 continue;
550 }
551
552 // Create the MutableTrack and add the parameters
553 auto actsTrack = track_container.makeTrack();
554 enum TrackValidity { VALID, INVALID_STATE, INVALID_GLOBAL };
555 TrackValidity track_validity = VALID;
556
557
558 actsTrack.chi2() = fit_res.chi2;
559 actsTrack.nDoF() = fit_res.ndf;
560
561 Acts::TrackStatePropMask const mask =
562 Acts::TrackStatePropMask::Smoothed;
563
564 bool first_state = true;
565 for (size_t j = 0; j < states.local_x.size(); ++j) {
566 auto actsTSOS = actsTrack.appendTrackState(mask);
567
568 // Build a measurement struct for this state
570 singleState.local_x = {states.local_x[j]};
571 singleState.local_y = {states.local_y[j]};
572 singleState.phi = {states.phi[j]};
573 singleState.theta = {states.theta[j]};
574 singleState.qop = {states.qop[j]};
575 singleState.time = {states.time[j]};
576 singleState.covariances = {};
577 for (size_t k = 0; k < 25; ++k) {
578 singleState.covariances.push_back(states.covariances[j * 25 + k]);
579 }
580 singleState.athena_id = {states.athena_id[j]};
581
582 std::optional<Acts::BoundTrackParameters> params_opt =
583 convertToActsParameters(singleState);
584 if (!params_opt.has_value()) {
585 // if the measurement was "buggy", the whole track is dismissed.
587 "convertToActsParameters failed: track state is weird");
588 track_validity = INVALID_STATE;
589 break;
590
591 }
592
593 Acts::BoundTrackParameters const& parameters = params_opt.value();
594 ATH_MSG_DEBUG("Track parameters: " << parameters.parameters());
595
596 if (m_doTruth) {
598 m_xAODPixelClusterFromInDetClusterKey.key(), eventContext);
599 ATH_CHECK(pixelClustersHandle.isValid());
600 const xAOD::PixelClusterContainer* inputPixelClusters =
601 pixelClustersHandle.cptr();
602
604 m_xAODStripClusterFromInDetClusterKey.key(), eventContext);
605 ATH_CHECK(stripClustersHandle.isValid());
606 const xAOD::StripClusterContainer* inputStripClusters =
607 stripClustersHandle.cptr();
608
609 // match measurement to the cluster container
610 int cl_index = -1;
611 if (auto it = cluster_map.find(states.athena_id[j]);
612 it != cluster_map.end()) {
613 cl_index = it->second;
614 } else {
615 return StatusCode::FAILURE;
616 }
617
618 // Determine detector type from athena_id
619 Identifier id(static_cast<Identifier::value_type>(states.athena_id[j]));
620 bool isPixel = m_pixelID->is_pixel(id);
621
622 const xAOD::UncalibratedMeasurement* umeas = nullptr;
623 if (isPixel) {
624 umeas = inputPixelClusters->at(cl_index);
625 } else {
626 umeas = inputStripClusters->at(cl_index);
627 }
628
629 actsTSOS.setUncalibratedSourceLink(
631 }
632
633 // This is the conversion of global track parameters
634 // Because Traccc does not do backpropagation yet,
635 // we do not have the reference surface ie the perigee.
636 // So for now we will set the global track params with
637 // the reference surface being the surface of first measurement
638 // and enable back propagation during ACTS->xAOD conversion
639 // this will find the pergee and re-set the global trk params.
640 if (first_state) {
641 // This is the first track state, so we need to set the track
642 // global parameters
643
644 std::optional<Acts::BoundTrackParameters> params_gl =
645 convertToActsParameters(singleState);
646
647 if (!params_gl.has_value()) {
648 // if the params are "buggy", the whole track is dismissed.
650 "convertToActsParameters failed: track state is weird");
651 track_validity = INVALID_GLOBAL;
652 break;
653 }
654
655 Acts::BoundTrackParameters const& parameters_gl =
656 params_gl.value();
657
658 ATH_MSG_VERBOSE("First state of track.");
659 actsTrack.parameters() = parameters_gl.parameters();
660 actsTrack.covariance() = *parameters_gl.covariance();
661 actsTrack.setReferenceSurface(
662 parameters_gl.referenceSurface().getSharedPtr());
663 first_state = false;
664
665 }
666
667 actsTSOS.setReferenceSurface(
668 parameters.referenceSurface().getSharedPtr());
669 actsTSOS.smoothed() = parameters.parameters();
670 actsTSOS.smoothedCovariance() = *parameters.covariance();
671 // Mark this state as a measurement for temporary efficiency matching
672 actsTSOS.typeFlags().setIsMeasurement();
673 if (!(actsTSOS.hasSmoothed() &&
674 actsTSOS.hasReferenceSurface())) {
676 "TrackState does not have smoothed state ["
677 << actsTSOS.hasSmoothed()
678 << "] or reference surface ["
679 << actsTSOS.hasReferenceSurface() << "].");
680 } else {
682 "TrackState has smoothed state and reference "
683 "surface.");
684 }
685 }
686
687 // ATH_MSG_INFO("Done with states of this track.");
688 if (track_validity == INVALID_STATE) {
689 ATH_MSG_INFO("excluding track " << i << " for weird state");
690 excluded_weird_state += 1;
691 track_container.removeTrack(actsTrack.index());
692 } else if (track_validity == INVALID_GLOBAL) {
693 ATH_MSG_INFO("excluding track " << i
694 << " for weird global params");
695 track_container.removeTrack(actsTrack.index());
696 }
697
698
699 // Debug stats
700 chi2_min = std::min(fit_res.chi2, chi2_min);
701 chi2_max = std::max(fit_res.chi2, chi2_max);
702 ndf_min = std::min(fit_res.ndf, ndf_min);
703 ndf_max = std::max(fit_res.ndf, ndf_max);
704 meas_min = std::min<unsigned>(states.local_x.size(), meas_min);
705 meas_max = std::max<unsigned>(states.local_x.size(), meas_max);
706 }
707
708 nb_output_tracks = track_container.size();
709 ATH_MSG_DEBUG("Wrote out "<< nb_output_tracks << " tracks from " << trackParams.size() << " candidates"
710 << ", excluded:"
711 << " no sp: " << excluded_no_sp
712 << ", weird sp: " << excluded_weird_state
713 << ", ndf: " << excluded_ndf
714 );
715
716 Acts::ConstVectorTrackContainer ctrack_backend(
717 std::move(track_container.container()));
718 Acts::ConstVectorMultiTrajectory ctrack_state_backend(
719 std::move(track_container.trackStateContainer()));
720 std::unique_ptr<ActsTrk::TrackContainer> ctrack_container =
721 std::make_unique<ActsTrk::TrackContainer>(
722 std::move(ctrack_backend), std::move(ctrack_state_backend));
723
724 ATH_CHECK(trackContainerHandle.record(std::move(ctrack_container)));
725
726 return StatusCode::SUCCESS;
727}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
static constexpr double one_over_twelve
const double width
void appendBytes(std::vector< uint8_t > &out, const uint64_t &value)
static Acts::SourceLink pack(const Ptr_t &measurement)
Pack the measurement type pointer to an Acts::SourceLink including the intermediate conversion into a...
const ServiceHandle< StoreGateSvc > & detStore() const
const T * at(size_type n) const
Access an element, as an rvalue.
This is a "hash" representation of an Identifier.
value_type get_compact() const
Get the compact id.
Identifier for the strip or pixel cell.
Definition SiCellId.h:29
Class to hold the SiDetectorElement objects to be put in the detector store.
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
double phiPitch() const
Pitch (inline methods).
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
double xPhi() const
position along phi direction:
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
virtual Identifier identify() const override final
identifier of this detector element (inline)
double phiPitchPhi(const SiLocalPosition &localPosition) const
SiLocalPosition localPositionOfCellPC(const SiCellId &cellId) const
This is for debugging only.
const Amg::Vector3D & globalPosition() const
return global position reference
const InDet::SiWidth & width() const
return width class reference
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
SG::ReadHandleKey< InDet::SCT_ClusterContainer > m_inputStripClusterContainerKey
const Acts::Surface * actsSurfaceFromAtlasId(const Identifier &atlasID) const
StatusCode serializeCells(const traccc::edm::silicon_cell_collection::const_device &cells, std::vector< uint8_t > &out) const
Acts::BoundMatrix buildBoundCovariance(const LocalMeasurementInfoInTracks &state) const
ServiceHandle< ActsTrk::ITrackingGeometrySvc > m_trackingGeometrySvc
std::shared_ptr< const Acts::TrackingGeometry > m_trackingGeometry
StatusCode convertInDetToXaodCluster(const InDet::PixelCluster &indetCluster, const InDetDD::SiDetectorElement &element, xAOD::PixelCluster &xaodCluster) const
ActsTrk::MutableTrackContainerHandlesHelper m_tracksBackendHandlesHelper
std::unordered_map< int64_t, int > readAndConvertClusters(const EventContext &eventContext) const
StatusCode convertTracks(EventContext const &eventContext, std::vector< TracccTrackParameters > &trackParams, std::vector< LocalMeasurementInfoInTracks > &measInfo, const std::unordered_map< int64_t, int > &cluster_map, unsigned &nb_output_tracks) const
SG::WriteHandleKey< xAOD::SpacePointContainer > m_xAODSpacepointFromInDetClusterKey
SG::WriteHandleKey< ActsTrk::TrackContainer > m_ActsTracccTrackContainerKey
SG::ReadHandleKey< InDet::PixelClusterContainer > m_inputPixelClusterContainerKey
ActsTrk::ContextUtility m_ctxProvider
Utility to fetch the geometry, magnetic field and calibration context in the event.
SG::ReadHandleKey< ActsTrk::MeasurementToTruthParticleAssociation > m_stripClustersToTruth
const ActsTrk::DetectorElementToActsGeometryIdMap * m_detEleToGeoIdMap
virtual StatusCode execute(const EventContext &ctx) const override
SG::WriteHandleKey< xAOD::PixelClusterContainer > m_xAODPixelClusterFromInDetClusterKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_stripDetEleCollKey
std::optional< Acts::BoundTrackParameters > convertToActsParameters(const LocalMeasurementInfoInTracks &state) const
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_pixelDetEleCollKey
Gaudi::Property< bool > m_doTruth
Truth association for plotting and debugging.
SG::ReadHandleKey< traccc::edm::silicon_cell_collection::const_view > m_tracccCellsKey
virtual StatusCode initialize() override
std::vector< std::string > m_featureNamesVec
SG::ReadHandleKey< ActsTrk::MeasurementToTruthParticleAssociation > m_pixelClustersToTruth
SG::WriteHandleKey< xAOD::StripClusterContainer > m_xAODStripClusterFromInDetClusterKey
ToolHandle< ITracccTritonTool > m_tracccTrackingTool
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
void setChannelsInPhiEta(int channelsInPhi, int channelsInEta)
Sets the dimensions of the cluster in numbers of channels in phi (x) and eta (y) directions.
ConstVectorMap< 3 > globalPosition() const
Returns the global position of the pixel cluster.
void setChargelist(const std::vector< float > &charges)
Sets the list of charges of the channels building the cluster.
void setToTlist(const std::vector< int > &tots)
Sets the list of ToT of the channels building the cluster.
void setLVL1A(int lvl1a)
Sets the LVL1 accept.
void setRDOlist(const std::vector< Identifier > &rdolist)
Sets the list of identifiers of the channels building the cluster.
void setWidthInEta(float widthInEta)
Sets the width of the cluster in eta (y) direction.
ConstVectorMap< 3 > globalPosition() const
Returns the global position of the strip cluster.
void setRDOlist(const std::vector< Identifier > &rdolist)
Sets the list of identifiers of the channels building the cluster.
void setChannelsInPhi(int channelsInPhi)
Sets the dimensions of the cluster in numbers of channels in phi (x).
void setMeasurement(const DetectorIDHashType idHash, MeasVector< N > locPos, MeasMatrix< N > locCov)
Sets IdentifierHash, local position and local covariance of the measurement.
void setIdentifier(const DetectorIdentType measId)
Sets the full Identifier of the measurement.
std::string prefixFromTrackContainerName(const std::string &tracks)
Parse TrackContainer name to get the prefix for backends The name has to contain XYZTracks,...
Acts::TrackContainer< MutableTrackBackend, MutableTrackStateBackend, Acts::detail::ValueHolder > MutableTrackContainer
DetectorElementKey makeDetectorElementKey(xAOD::UncalibMeasType meas_type, unsigned int identifier_hash)
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition index.py:1
PixelClusterContainer_v1 PixelClusterContainer
Define the version of the pixel cluster container.
StripCluster_v1 StripCluster
Define the version of the strip cluster class.
Eigen::Matrix< float, N, N > MeasMatrix
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
Eigen::Matrix< float, N, 1 > MeasVector
Abrivation of the Matrix & Covariance definitions.
StripClusterContainer_v1 StripClusterContainer
Define the version of the strip cluster container.
MeasVector< N > toStorage(const AmgVector(N)&amgVec)
Converts the double precision of the AmgVector into the floating point storage precision of the MeasV...
PixelCluster_v1 PixelCluster
Define the version of the pixel cluster class.
static const Acts::GeometryIdentifier & getValue(const value_type &element)
std::vector< int64_t > athena_id
std::vector< float > covariances