From 77c64a0c43a5dc859f5a512da3206710cd999f35 Mon Sep 17 00:00:00 2001
From: cvarni <carlo.varni@cern.ch>
Date: Tue, 28 Mar 2023 17:44:55 +0200
Subject: [PATCH] first implementation of the demonstrator

---
 .../ActsTrkSpacePointFormation/CMakeLists.txt |   1 +
 .../src/PixelSpacePointFormationAlg.cxx       | 123 +++++++++++++++---
 .../src/PixelSpacePointFormationAlg.h         |  25 ++++
 .../ActsTrkSpacePointFormationConfig.py       |  12 ++
 4 files changed, 145 insertions(+), 16 deletions(-)

diff --git a/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/CMakeLists.txt b/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/CMakeLists.txt
index a23542e0b56b..239e1fde793e 100644
--- a/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/CMakeLists.txt
+++ b/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/CMakeLists.txt
@@ -20,4 +20,5 @@ atlas_add_component( ActsTrkSpacePointFormation
                      SCT_ReadoutGeometry
                      SiSpacePointFormationLib
                      xAODInDetMeasurement
+		     ActsTrkEventCnvLib
                      )
diff --git a/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/src/PixelSpacePointFormationAlg.cxx b/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/src/PixelSpacePointFormationAlg.cxx
index f751c8eced88..1837ba687565 100644
--- a/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/src/PixelSpacePointFormationAlg.cxx
+++ b/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/src/PixelSpacePointFormationAlg.cxx
@@ -11,6 +11,19 @@
 
 #include "AthenaMonitoringKernel/Monitored.h"
 
+// This has to be changed
+#include "ActsGeometry/ATLASSourceLink.h"
+#include "Acts/SpacePointFormation/SpacePointBuilderOptions.hpp"
+#include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+#include "InDetIdentifier/PixelID.h"
+#include "PixelReadoutGeometry/PixelModuleDesign.h"
+#include "InDetReadoutGeometry/SiDetectorElement.h"
+
+#include "TrkSurfaces/Surface.h"
+#include "InDetIdentifier/PixelID.h"
+#include "PixelReadoutGeometry/PixelModuleDesign.h"
+
+
 namespace ActsTrk {
 
   //------------------------------------------------------------------------
@@ -28,10 +41,25 @@ namespace ActsTrk {
     ATH_CHECK( m_pixelSpacePointContainerKey.initialize() );
     ATH_CHECK( m_pixelDetEleCollKey.initialize() );
     ATH_CHECK( m_spacePointMakerTool.retrieve() );
-
+    ATH_CHECK( m_trackingGeometryTool.retrieve() );
+    ATH_CHECK(m_ATLASConverterTool.retrieve());
     if ( not m_monTool.empty() )
       ATH_CHECK( m_monTool.retrieve() );
 
+    ATH_CHECK(detStore()->retrieve(m_pixelId,"PixelID"));
+
+    auto spConstructor =
+      [](const Acts::Vector3& pos, const Acts::Vector2& cov,
+	 boost::container::static_vector<Acts::SourceLink, 2> slinks)
+      -> ActsTrk::sp {
+      return ActsTrk::sp(pos, cov[0], cov[1], std::move(slinks));
+    };
+    
+    auto spBuilderConfig = Acts::SpacePointBuilderConfig();
+    spBuilderConfig.trackingGeometry = m_trackingGeometryTool->trackingGeometry();
+    spBuilderConfig.useCustomCovarianceComputation = false; //true;
+    m_spacePointBuilder = std::make_unique<Acts::SpacePointBuilder<ActsTrk::sp>>(spBuilderConfig, spConstructor, Acts::getDefaultLogger("SpacePointBuilder", Acts::Logging::INFO));
+
     return StatusCode::SUCCESS;
   }
 
@@ -69,6 +97,76 @@ namespace ActsTrk {
     pixelSpacePoints->reserve(pixelClusters->size());
     pixelSpacePointsAux->reserve(pixelClusters->size());
 
+    // make source links 
+    std::vector< ATLASUncalibSourceLink > sourcelinks;
+    sourcelinks.reserve(pixelClusters->size());
+
+    std::vector<ATLASUncalibSourceLink::ElementsType> elementsCollection;
+    elementsCollection.reserve(pixelClusters->size());
+
+    std::vector<ActsTrk::sp> target;
+    target.reserve(pixelClusters->size());
+    
+    // for (const auto* meas : *pixelClusters) {
+    //   sourcelinks.push_back( m_ATLASConverterTool->uncalibratedTrkMeasurementToSourceLink(*pixelElements, *meas, elementsCollection) );
+    // }
+
+    // Prepare extraction function
+    Acts::SpacePointBuilderOptions spOpt;
+    spOpt.paramCovAccessor = [](const Acts::SourceLink& slink) {
+      const auto islink = slink.get<ATLASUncalibSourceLink>();      
+      return std::make_pair(islink.values(), islink.cov());
+    };
+
+    // prepare cov computation
+    spOpt.customCovComputation = [this,&pixelElements](const Acts::SourceLink& slink,
+						       const Acts::BoundSymMatrix& localCov) -> Acts::Vector2
+      {
+	const auto& cluster = *reinterpret_cast<const xAOD::PixelCluster*>(& slink.get<ATLASUncalibSourceLink>().atlasHit() );
+	const InDetDD::SiDetectorElement* pixelElement = pixelElements->getDetectorElement(cluster.identifierHash());
+	const InDetDD::PixelModuleDesign* design
+	(dynamic_cast<const InDetDD::PixelModuleDesign*>(&pixelElement->design()));
+
+	auto rdoList = cluster.rdoList();
+        auto min_max =
+	std::minmax_element(rdoList.begin(), rdoList.end(),
+			    [this] (Identifier const& lh, Identifier const& rh) {
+			      return m_pixelId->eta_index(lh) < m_pixelId->eta_index(rh);
+			    });
+
+        // this is the width expressed in mm
+        float width =
+	design->widthFromColumnRange(m_pixelId->eta_index(*min_max.first),
+				     m_pixelId->eta_index(*min_max.second));
+
+        // using width to scale the cluster covariance for space points
+        float covTerm = width*width/12.;
+        if( covTerm < localCov(1, 1) )
+	  covTerm = localCov(1, 1);
+
+        // use xz, yz, zz terms of rotation matrix to scale the covariance term
+        const Amg::Transform3D &Tp = pixelElement->surface().transform();
+        float cov_z = 6.*covTerm*(float(Tp(0, 2))*float(Tp(0, 2))+float(Tp(1, 2))*float(Tp(1, 2)));
+        float cov_r = 6.*covTerm*(float(Tp(2, 2))*float(Tp(2, 2)));
+	return {cov_r, cov_z};
+      };
+
+    auto geo_context = m_trackingGeometryTool->getNominalGeometryContext();    
+    
+    std::vector<Acts::SourceLink> slinks;
+
+    for (const auto* meas : *pixelClusters) {
+      if (slinks.size() != 0 ) {
+	slinks[0] = Acts::SourceLink{m_ATLASConverterTool->uncalibratedTrkMeasurementToSourceLink(*pixelElements, *meas, elementsCollection)};
+      } else {
+	slinks.push_back( Acts::SourceLink{m_ATLASConverterTool->uncalibratedTrkMeasurementToSourceLink(*pixelElements, *meas, elementsCollection)} );
+      }
+      m_spacePointBuilder->buildSpacePoint(geo_context.context(), 
+					   slinks,
+					   spOpt,
+					   std::back_inserter(target));
+    }
+
     // using trick for fast insertion
     std::vector< xAOD::SpacePoint* > preCollection;
     preCollection.reserve(pixelClusters->size());
@@ -76,21 +174,14 @@ namespace ActsTrk {
       preCollection.push_back( new xAOD::SpacePoint() );
     pixelSpacePoints->insert(pixelSpacePoints->end(), preCollection.begin(), preCollection.end());
 
-    /// production of ActsTrk::SpacePoint from pixel clusters
-    /// Pixel space points are created directly from the clusters global position
-    for (std::size_t idx(0); idx<inputPixelClusterContainer->size(); ++idx) {
-      auto cluster = inputPixelClusterContainer->at(idx);
-      std::vector<std::size_t> measIndexes({idx});
-      const InDetDD::SiDetectorElement* pixelElement = pixelElements->getDetectorElement(cluster->identifierHash());
-      if (pixelElement == nullptr) {
-        ATH_MSG_FATAL("Element pointer is nullptr");
-        return StatusCode::FAILURE;
-      }
-
-      ATH_CHECK( m_spacePointMakerTool->producePixelSpacePoint(*cluster,
-      							       *pixelSpacePoints->at(idx),
-      							       measIndexes,
-      							       *pixelElement ) );
+    for (std::size_t i(0); i<target.size(); ++i) {
+      auto cluster = inputPixelClusterContainer->at(i);
+      pixelSpacePoints->at(i)->setSpacePoint(cluster->identifierHash(),
+					     target[i].pos.cast<float>(),
+					     static_cast<float>(target[i].cov[0]),
+					     static_cast<float>(target[i].cov[1]),
+					     {i});
+      
     }
 
     ATH_CHECK( pixelSpacePointContainer.record( std::move( pixelSpacePoints ), std::move(pixelSpacePointsAux) ) );
diff --git a/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/src/PixelSpacePointFormationAlg.h b/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/src/PixelSpacePointFormationAlg.h
index 6a8a5ed2e882..c6f22c0d1789 100644
--- a/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/src/PixelSpacePointFormationAlg.h
+++ b/Tracking/Acts/ActsTrkAlgs/ActsTrkSpacePointFormation/src/PixelSpacePointFormationAlg.h
@@ -23,8 +23,27 @@
 
 #include <string>
 
+#include "ActsTrkEventCnv/IActsToTrkConverterTool.h"
+#include "Acts/SpacePointFormation/SpacePointBuilder.hpp"
+#include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
+#include "InDetIdentifier/PixelID.h"
+
 namespace ActsTrk {
 
+  struct sp {
+    sp() = delete;
+    sp(const Acts::Vector3& p, double c0, double c2,
+       boost::container::static_vector<Acts::SourceLink, 2>&& l)
+    : pos(p),
+      cov({c0, c2}),
+      slink(std::move(l))
+    {}
+
+    const Acts::Vector3 pos;
+    const Acts::Vector2 cov;
+    boost::container::static_vector<Acts::SourceLink, 2> slink;
+  };
+
     /// @class PixelSpacePointFormationAlg
     /// This version of PixelSpacePointFormationAlg uses xAOD pixel clusters
     /// to find space points in the ITk pixeldetectors.
@@ -45,6 +64,9 @@ namespace ActsTrk {
         //@}
 
     private:
+	const PixelID* m_pixelId{};
+	std::unique_ptr< Acts::SpacePointBuilder<ActsTrk::sp> > m_spacePointBuilder;
+
         /// @name Disallow constructor without parameters, copy constructor, assignment operator
         //@{
         PixelSpacePointFormationAlg() = delete;
@@ -76,6 +98,9 @@ namespace ActsTrk {
         ToolHandle<GenericMonitoringTool> m_monTool{this, "MonTool", "", "Monitoring tool"};
         //@}
 
+	ToolHandle<ActsTrk::IActsToTrkConverterTool> m_ATLASConverterTool{this, "ATLASConverterTool", "ActsToTrkConverterTool"};
+
+	PublicToolHandle< IActsTrackingGeometryTool > m_trackingGeometryTool {this, "TrackingGeometryTool", "ActsTrackingGeometryTool"};
   };
 
 }
diff --git a/Tracking/TrkConfig/python/ActsTrkSpacePointFormationConfig.py b/Tracking/TrkConfig/python/ActsTrkSpacePointFormationConfig.py
index 4d04d94a6a4b..dd30ae7f41eb 100644
--- a/Tracking/TrkConfig/python/ActsTrkSpacePointFormationConfig.py
+++ b/Tracking/TrkConfig/python/ActsTrkSpacePointFormationConfig.py
@@ -32,6 +32,17 @@ def ActsTrkPixelSpacePointFormationCfg(flags,
 
     kwargs.setdefault("PixelSpacePoints", "ITkPixelSpacePoints")
 
+    from ActsTrkEventCnv.ActsTrkEventCnvConfig import ActsToTrkConverterToolCfg
+    kwargs.setdefault(
+        "ATLASConverterTool",
+        acc.popToolsAndMerge(ActsToTrkConverterToolCfg(flags)),
+    )
+
+    from ActsGeometry.ActsGeometryConfig import ActsTrackingGeometryToolCfg    
+    geoTool = acc.popToolsAndMerge(ActsTrackingGeometryToolCfg(flags))
+    acc.addPublicTool(geoTool)
+    kwargs.setdefault('TrackingGeometryTool', acc.getPublicTool(geoTool.name))
+
     if flags.Acts.doMonitoring:
         from ActsTrkAnalysis.ActsTrkMonitoringConfig import ActsTrkPixelSpacePointFormationMonitoringToolCfg
         kwargs.setdefault("MonTool", acc.popToolsAndMerge(ActsTrkPixelSpacePointFormationMonitoringToolCfg(flags)))
@@ -57,6 +68,7 @@ def ActsTrkStripSpacePointFormationCfg(flags,
     kwargs.setdefault("StripOverlapSpacePoints", "ITkStripOverlapSpacePoints")
     kwargs.setdefault("ProcessOverlapForStrip", True)
 
+
     if flags.Acts.doMonitoring:
         from ActsTrkAnalysis.ActsTrkMonitoringConfig import ActsTrkStripSpacePointFormationMonitoringToolCfg
         kwargs.setdefault("MonTool", acc.popToolsAndMerge(ActsTrkStripSpacePointFormationMonitoringToolCfg(flags)))
-- 
GitLab