Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-06-29 07:05:22

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2022 Whitney Armstrong, Sylvester Joosten, Wouter Deconinck
0003 
0004 #include "JugTrack/GeometryContainers.hpp"
0005 
0006 // Gaudi
0007 #include "Gaudi/Property.h"
0008 #include "GaudiAlg/GaudiAlgorithm.h"
0009 #include "GaudiAlg/GaudiTool.h"
0010 #include "GaudiAlg/Transformer.h"
0011 #include "GaudiKernel/RndmGenerators.h"
0012 #include "GaudiKernel/ToolHandle.h"
0013 
0014 #include "JugBase/DataHandle.h"
0015 #include "JugBase/IGeoSvc.h"
0016 
0017 #include "DD4hep/DD4hepUnits.h"
0018 #include "DD4hep/Volumes.h"
0019 #include "DDRec/CellIDPositionConverter.h"
0020 #include "DDRec/Surface.h"
0021 #include "DDRec/SurfaceManager.h"
0022 
0023 #include "Acts/Definitions/Common.hpp"
0024 #include "Acts/Definitions/Units.hpp"
0025 #include "Acts/Geometry/TrackingGeometry.hpp"
0026 #include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp"
0027 #include "Acts/Surfaces/Surface.hpp"
0028 
0029 #include "JugTrack/Index.hpp"
0030 #include "JugTrack/IndexSourceLink.hpp"
0031 #include "JugTrack/Measurement.hpp"
0032 
0033 #include "edm4eic/TrackerHitCollection.h"
0034 
0035 namespace Jug::Reco {
0036 
0037 /** Source source Linker.
0038  *
0039  * The source linker creates "source links" which map the hit to the tracking surface.
0040  * It also creates "measurements" which take the hit information and creates a corresponding
0041  * "measurement" which contains the covariance matrix and other geometry related hit information.
0042  *
0043  * \ingroup tracking
0044  */
0045 class TrackerSourceLinker : public GaudiAlgorithm {
0046 private:
0047   DataHandle<edm4eic::TrackerHitCollection> m_inputHitCollection{"inputHitCollection", Gaudi::DataHandle::Reader, this};
0048   DataHandle<std::list<IndexSourceLink>> m_sourceLinkStorage{"sourceLinkStorage", Gaudi::DataHandle::Writer, this};
0049   DataHandle<IndexSourceLinkContainer> m_outputSourceLinks{"outputSourceLinks", Gaudi::DataHandle::Writer, this};
0050   DataHandle<MeasurementContainer> m_outputMeasurements{"outputMeasurements", Gaudi::DataHandle::Writer, this};
0051   /// Pointer to the geometry service
0052   SmartIF<IGeoSvc> m_geoSvc;
0053 
0054 public:
0055   TrackerSourceLinker(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) {
0056     declareProperty("inputHitCollection", m_inputHitCollection, "");
0057     declareProperty("sourceLinkStorage", m_sourceLinkStorage, "");
0058     declareProperty("outputSourceLinks", m_outputSourceLinks, "");
0059     declareProperty("outputMeasurements", m_outputMeasurements, "");
0060   }
0061 
0062   StatusCode initialize() override {
0063     if (GaudiAlgorithm::initialize().isFailure()) {
0064       return StatusCode::FAILURE;
0065     }
0066     m_geoSvc = service("GeoSvc");
0067     if (!m_geoSvc) {
0068       error() << "Unable to locate Geometry Service. "
0069               << "Make sure you have GeoSvc and SimSvc in the right order in the configuration." << endmsg;
0070       return StatusCode::FAILURE;
0071     }
0072 
0073     return StatusCode::SUCCESS;
0074   }
0075 
0076   StatusCode execute() override {
0077     constexpr double mm_acts = Acts::UnitConstants::mm;
0078     constexpr double mm_conv = mm_acts / dd4hep::mm; // = 1/0.1
0079 
0080     // input collection
0081     const edm4eic::TrackerHitCollection* hits = m_inputHitCollection.get();
0082     // Create output collections
0083     auto* linkStorage  = m_sourceLinkStorage.createAndPut();
0084     auto* sourceLinks  = m_outputSourceLinks.createAndPut();
0085     auto* measurements = m_outputMeasurements.createAndPut();
0086     sourceLinks->reserve(hits->size());
0087     measurements->reserve(hits->size());
0088 
0089     if (msgLevel(MSG::DEBUG)) {
0090       debug() << (*hits).size() << " hits " << endmsg;
0091     }
0092     int ihit = 0;
0093     for (const auto& ahit : *hits) {
0094 
0095       Acts::SymMatrix2 cov = Acts::SymMatrix2::Zero();
0096       cov(0, 0)            = ahit.getPositionError().xx * mm_acts * mm_acts; // note mm = 1 (Acts)
0097       cov(1, 1)            = ahit.getPositionError().yy * mm_acts * mm_acts;
0098       if (msgLevel(MSG::DEBUG)) {
0099         debug() << "cov matrix:\n" << cov << endmsg;
0100       }
0101 
0102       const auto* vol_ctx = m_geoSvc->cellIDPositionConverter()->findContext(ahit.getCellID());
0103       auto vol_id = vol_ctx->identifier;
0104 
0105       const auto is = m_geoSvc->surfaceMap().find(vol_id);
0106       if (is == m_geoSvc->surfaceMap().end()) {
0107         error() << " vol_id (" << vol_id << ")  not found in m_surfaces." << endmsg;
0108         continue;
0109       }
0110       const Acts::Surface* surface = is->second;
0111       // variable surf_center not used anywhere;
0112       // auto surf_center = surface->center(Acts::GeometryContext());
0113 
0114       // transform global position into local coordinates
0115       // geometry context contains nothing here
0116       Acts::Vector2 pos =
0117           surface
0118               ->globalToLocal(Acts::GeometryContext(),
0119                               {ahit.getPosition().x, ahit.getPosition().y, ahit.getPosition().z}, {0, 0, 0})
0120               .value();
0121 
0122       Acts::Vector2 loc     = Acts::Vector2::Zero();
0123       loc[Acts::eBoundLoc0] = pos[0];
0124       loc[Acts::eBoundLoc1] = pos[1];
0125 
0126       if (msgLevel(MSG::DEBUG)) {
0127         auto volman         = m_geoSvc->detector()->volumeManager();
0128         auto alignment      = volman.lookupDetElement(vol_id).nominal();
0129         auto local_position = (alignment.worldToLocal({ahit.getPosition().x / mm_conv, ahit.getPosition().y / mm_conv,
0130                                                        ahit.getPosition().z / mm_conv})) *
0131                               mm_conv;
0132         debug() << " hit position     : " << ahit.getPosition().x << " " << ahit.getPosition().y << " "
0133                 << ahit.getPosition().z << endmsg;
0134         debug() << " dd4hep loc pos   : " << local_position.x() << " " << local_position.y() << " "
0135                 << local_position.z() << endmsg;
0136         debug() << " surface center   :" << surface->center(Acts::GeometryContext()).transpose() << endmsg;
0137         debug() << " acts local center:" << pos.transpose() << endmsg;
0138         debug() << " acts loc pos     : " << loc[Acts::eBoundLoc0] << ", " << loc[Acts::eBoundLoc1] << endmsg;
0139       }
0140 
0141       // the measurement container is unordered and the index under which the
0142       // measurement will be stored is known before adding it.
0143       //
0144       // variable hitIdx not used anywhere
0145       // Index hitIdx = measurements->size();
0146       linkStorage->emplace_back(surface->geometryId(), ihit);
0147       IndexSourceLink& sourceLink = linkStorage->back();
0148       auto meas                   = Acts::makeMeasurement(sourceLink, loc, cov, Acts::eBoundLoc0, Acts::eBoundLoc1);
0149 
0150       // add to output containers. since the input is already geometry-order,
0151       // new elements in geometry containers can just be appended at the end.
0152       sourceLinks->emplace_hint(sourceLinks->end(), sourceLink);
0153       measurements->emplace_back(std::move(meas));
0154 
0155       ihit++;
0156     }
0157     return StatusCode::SUCCESS;
0158   }
0159 };
0160 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
0161 DECLARE_COMPONENT(TrackerSourceLinker)
0162 
0163 } // namespace Jug::Reco