diff --git a/.gitignore b/.gitignore index 84bc868d107179b702448f6a7f0ca094b86a07ee..555a2beb5b9b82f76bf2dabd227cb5e2e9af266a 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ *.lib *.root tmp.* +.idea/** +cmake-debug-build/** diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7fe8c1fa0e248c98fdcfbbd65a0aa79738292674..4c9843953aedfea314e7996b98c26f44531b52e1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,7 +27,7 @@ build_image: - set +e && source ${ATLAS_LOCAL_ROOT_BASE}/user/atlasLocalSetup.sh; set -e - set +e && asetup --input=../../calypso/asetup.faser master,latest,Athena; set -e - cmake ../../calypso - - make -j + - make -j 3 artifacts: paths: - build/ diff --git a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelTool.h b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelTool.h index 307d858b20dba55a69db3a041515800832a52530..1b0e98652db1907d64fc91434f599e8116e499de 100644 --- a/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelTool.h +++ b/DetectorDescription/GeoModel/GeoModelInterfaces/GeoModelInterfaces/IGeoModelTool.h @@ -7,6 +7,7 @@ #include "GaudiKernel/IAlgTool.h" #include "AthenaKernel/IOVSvcDefs.h" +#include "CxxUtils/checker_macros.h" static const InterfaceID IID_IGeoModelTool( "IGeoModelTool", 1, 0 ); @@ -25,7 +26,7 @@ public: virtual StatusCode clear() = 0; // Register callback function on ConDB object - virtual StatusCode registerCallback() = 0; + virtual StatusCode registerCallback ATLAS_NOT_THREAD_SAFE () = 0; // Callback function itself virtual StatusCode align(IOVSVC_CALLBACK_ARGS) = 0; diff --git a/Scintillator/ScintDetDescr/PreshowerGeoModel/PreshowerGeoModel/PreshowerDetectorTool.h b/Scintillator/ScintDetDescr/PreshowerGeoModel/PreshowerGeoModel/PreshowerDetectorTool.h index 634f702e9fec22a4585ee4ea708fefb6ae9be924..818dd7ce590b7ca03c059b3698b76a82061efa18 100644 --- a/Scintillator/ScintDetDescr/PreshowerGeoModel/PreshowerGeoModel/PreshowerDetectorTool.h +++ b/Scintillator/ScintDetDescr/PreshowerGeoModel/PreshowerGeoModel/PreshowerDetectorTool.h @@ -33,7 +33,7 @@ public: virtual StatusCode clear() override final; // Register callback function on ConDB object - virtual StatusCode registerCallback() override final; + virtual StatusCode registerCallback ATLAS_NOT_THREAD_SAFE () override final; // Callback function itself virtual StatusCode align(IOVSVC_CALLBACK_ARGS) override; diff --git a/Scintillator/ScintDetDescr/TriggerGeoModel/TriggerGeoModel/TriggerDetectorTool.h b/Scintillator/ScintDetDescr/TriggerGeoModel/TriggerGeoModel/TriggerDetectorTool.h index f947787e92e34459b0f2e0ae9d600331d54277ee..1cc12211f0eaf6b14096c4df634a954d874ad2d6 100644 --- a/Scintillator/ScintDetDescr/TriggerGeoModel/TriggerGeoModel/TriggerDetectorTool.h +++ b/Scintillator/ScintDetDescr/TriggerGeoModel/TriggerGeoModel/TriggerDetectorTool.h @@ -33,7 +33,7 @@ public: virtual StatusCode clear() override final; // Register callback function on ConDB object - virtual StatusCode registerCallback() override final; + virtual StatusCode registerCallback ATLAS_NOT_THREAD_SAFE () override final; // Callback function itself virtual StatusCode align(IOVSVC_CALLBACK_ARGS) override; diff --git a/Scintillator/ScintDetDescr/VetoGeoModel/VetoGeoModel/VetoDetectorTool.h b/Scintillator/ScintDetDescr/VetoGeoModel/VetoGeoModel/VetoDetectorTool.h index bad48487d32f1c098ac23d430aafd753314c289d..6e8895e1db59e74820cff9a91bedff1c824cbc8c 100644 --- a/Scintillator/ScintDetDescr/VetoGeoModel/VetoGeoModel/VetoDetectorTool.h +++ b/Scintillator/ScintDetDescr/VetoGeoModel/VetoGeoModel/VetoDetectorTool.h @@ -33,7 +33,7 @@ public: virtual StatusCode clear() override final; // Register callback function on ConDB object - virtual StatusCode registerCallback() override final; + virtual StatusCode registerCallback ATLAS_NOT_THREAD_SAFE () override final; // Callback function itself virtual StatusCode align(IOVSVC_CALLBACK_ARGS) override; diff --git a/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformCnv_p0.cxx b/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformCnv_p0.cxx index ffc6f0d8df91fe68a4433b33c4784d2238a7c555..477849763c6bd19b5ce9cbf82b36c14b9f7303d7 100644 --- a/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformCnv_p0.cxx +++ b/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformCnv_p0.cxx @@ -5,7 +5,7 @@ #include "ScintWaveformCnv_p0.h" void -ScintWaveformCnv_p0::persToTrans(const ScintWaveform_p0* persObj, ScintWaveform* transObj, MsgStream& log) { +ScintWaveformCnv_p0::persToTrans(const ScintWaveform_p0* persObj, ScintWaveform* transObj, MsgStream& /*log*/) { // Just fill available data here // Rest of it patched up in ScintWaveformContainerCnv_p0 @@ -16,7 +16,7 @@ ScintWaveformCnv_p0::persToTrans(const ScintWaveform_p0* persObj, ScintWaveform* } void -ScintWaveformCnv_p0::transToPers(const ScintWaveform* transObj, ScintWaveform_p0* persObj, MsgStream& log) { +ScintWaveformCnv_p0::transToPers(const ScintWaveform* transObj, ScintWaveform_p0* persObj, MsgStream& /*log*/) { // log << MSG::DEBUG << "ScintWaveformCnv_p0::transToPers called" << endmsg; // log << MSG::DEBUG << "Transient waveform:" << endmsg; diff --git a/Simulation/G4Utilities/Geo2G4/src/Geo2G4OpticalSurfaceFactory.cxx b/Simulation/G4Utilities/Geo2G4/src/Geo2G4OpticalSurfaceFactory.cxx index 3af74f855bbd89eeaabbb4cc48dad4e3e14d285d..5440a1dca7039ab9af0d8a8a9e2d5072877656f1 100644 --- a/Simulation/G4Utilities/Geo2G4/src/Geo2G4OpticalSurfaceFactory.cxx +++ b/Simulation/G4Utilities/Geo2G4/src/Geo2G4OpticalSurfaceFactory.cxx @@ -115,7 +115,7 @@ G4OpticalSurface* Geo2G4OpticalSurfaceFactory::Build(const GeoOpticalSurface* ge // Create material properties table Geo2G4MatPropTableFactory* tFactory = Geo2G4MatPropTableFactory::instance(); - GeoMaterialPropertiesTable* geoPropTable = geoOpticalSurface->GetMaterialPropertiesTable(); + const GeoMaterialPropertiesTable* geoPropTable = geoOpticalSurface->GetMaterialPropertiesTable(); if(geoPropTable){ G4MaterialPropertiesTable* g4PropTable = tFactory->Build(geoPropTable); diff --git a/Tracker/TrackerDetDescr/FaserSCT_GeoModel/FaserSCT_GeoModel/FaserSCT_DetectorTool.h b/Tracker/TrackerDetDescr/FaserSCT_GeoModel/FaserSCT_GeoModel/FaserSCT_DetectorTool.h index c4cc0f8eb6e753ac51d20377110d1fcedd1ce498..45011c9bbbcd565c8cad2ca482e34f5698f00bae 100644 --- a/Tracker/TrackerDetDescr/FaserSCT_GeoModel/FaserSCT_GeoModel/FaserSCT_DetectorTool.h +++ b/Tracker/TrackerDetDescr/FaserSCT_GeoModel/FaserSCT_GeoModel/FaserSCT_DetectorTool.h @@ -30,7 +30,7 @@ public: virtual StatusCode clear() override final; // Register callback function on ConDB object - virtual StatusCode registerCallback() override final; + virtual StatusCode registerCallback ATLAS_NOT_THREAD_SAFE () override final; // Callback function itself virtual StatusCode align(IOVSVC_CALLBACK_ARGS) override; diff --git a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/python/TruthSeededTrackFinderConfig.py b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/python/TruthSeededTrackFinderConfig.py index 671f16ffd7cc43b38dcb1ed1f35bf3cb0d0da685..25ea502023aa075b792f5962280a60ca161a8e86 100644 --- a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/python/TruthSeededTrackFinderConfig.py +++ b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/python/TruthSeededTrackFinderConfig.py @@ -4,17 +4,20 @@ Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration """ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator from AthenaConfiguration.ComponentFactory import CompFactory + Tracker__TruthSeededTrackFinder, THistSvc=CompFactory.getComps("Tracker::TruthSeededTrackFinder", "THistSvc") from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg + def TruthSeededTrackFinderBasicCfg(flags, **kwargs): """Return ComponentAccumulator for TruthSeededTrackFinder""" acc = ComponentAccumulator() kwargs.setdefault("SpacePointsSCTName", "SCT_SpacePointContainer") - kwargs.setdefault("SpacePointsSeedsName", "Seeds_SpacePointContainer") + kwargs.setdefault("FaserSpacePointsSeedsName", "Seeds_SpacePointContainer") acc.addEventAlgo(Tracker__TruthSeededTrackFinder(**kwargs)) + # attach ToolHandles return acc def TruthSeededTrackFinder_OutputCfg(flags): diff --git a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.cxx b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.cxx index 7c63367f8b313f2c4b6615cb016c3d45fbd847a7..7464461b9799451564a567c73fefeb92d4834047 100755 --- a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.cxx +++ b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.cxx @@ -19,7 +19,6 @@ // Space point Classes, #include "TrkSpacePoint/SpacePointCollection.h" -// #include "TrkSpacePoint/SpacePointCLASS_DEF.h" #include "TrackerIdentifier/FaserSCT_ID.h" @@ -30,346 +29,581 @@ #include "AthenaMonitoringKernel/Monitored.h" +//!!!!!!!!!!!!!!!!!!!!!!!! +//#include "Acts/EventData/TrackParameters.hpp" +#include "TrackerReadoutGeometry/SCT_DetectorManager.h" +#include "Acts/Utilities/detail/periodic.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Units.hpp" +using namespace Acts::UnitLiterals; +//!!!!!!!!!!!!!!!!!!!!!!!! namespace Tracker { -//------------------------------------------------------------------------ -TruthSeededTrackFinder::TruthSeededTrackFinder(const std::string& name, - ISvcLocator* pSvcLocator) - : AthReentrantAlgorithm(name, pSvcLocator) - , m_hist_n(0) - , m_hist_x(0) - , m_hist_y(0) - , m_hist_z(0) - , m_hist_r(0) - , m_hist_phi(0) - , m_hist_eta(0) - , m_hist_layer(0) - , m_hist_strip(0) - , m_hist_station(0) - , m_hist_x_y_plane0(0) - , m_hist_x_y_plane1(0) - , m_hist_x_y_plane2(0) - , m_hist_x_y_plane3(0) - , m_hist_x_y_plane4(0) - , m_hist_x_y_plane5(0) - , m_hist_x_y_plane6(0) - , m_hist_x_y_plane7(0) - , m_hist_x_y_plane8(0) - , m_hist_x_z(0) - , m_hist_y_z(0) - , m_hist_sp_sensor(0) - , m_hist_sp_module (0) - , m_hist_sp_row (0) - , m_hist_sp_plane (0) - , m_hist_sp_layer (0) - , m_hist_sp_station (0) - - , m_thistSvc("THistSvc", name) -{ -} + //------------------------------------------------------------------------ + TruthSeededTrackFinder::TruthSeededTrackFinder(const std::string& name, + ISvcLocator* pSvcLocator) + : AthReentrantAlgorithm(name, pSvcLocator) + , m_hist_n(0) + , m_hist_x(0) + , m_hist_y(0) + , m_hist_z(0) + , m_hist_r(0) + , m_hist_phi(0) + , m_hist_eta(0) + , m_hist_layer(0) + , m_hist_strip(0) + , m_hist_station(0) + , m_hist_x_y_plane0(0) + , m_hist_x_y_plane1(0) + , m_hist_x_y_plane2(0) + , m_hist_x_y_plane3(0) + , m_hist_x_y_plane4(0) + , m_hist_x_y_plane5(0) + , m_hist_x_y_plane6(0) + , m_hist_x_y_plane7(0) + , m_hist_x_y_plane8(0) + , m_hist_x_z(0) + , m_hist_y_z(0) + , m_hist_sp_sensor(0) + , m_hist_sp_module (0) + , m_hist_sp_row (0) + , m_hist_sp_plane (0) + , m_hist_sp_layer (0) + , m_hist_sp_station (0) + //!!!!!!!!!!!!!!!!!!!! + , m_hist_InitReso_px (0) + , m_hist_InitReso_py (0) + , m_hist_InitReso_pz (0) + //!!!!!!!!!!!!!!!!!!!! + + , m_thistSvc("THistSvc", name) + { + } -//----------------------------------------------------------------------- -StatusCode TruthSeededTrackFinder::initialize() -{ - // - ATH_MSG_DEBUG( "TruthTrackSeeds::initialize()" ); + //----------------------------------------------------------------------- + StatusCode TruthSeededTrackFinder::initialize() + { + // + ATH_MSG_DEBUG( "TruthTrackSeeds::initialize()" ); + + CHECK(m_thistSvc.retrieve()); + // Check that clusters, space points and ids have names + if ( m_Sct_spcontainerKey.key().empty()){ + ATH_MSG_FATAL( "SCTs selected and no name set for SCT clusters"); + return StatusCode::FAILURE; + } + ATH_CHECK( m_Sct_spcontainerKey.initialize() ); - CHECK(m_thistSvc.retrieve()); - // Check that clusters, space points and ids have names - if ( m_Sct_spcontainerKey.key().empty()){ - ATH_MSG_FATAL( "SCTs selected and no name set for SCT clusters"); - return StatusCode::FAILURE; - } - ATH_CHECK( m_Sct_spcontainerKey.initialize() ); + // create containers (requires the Identifier Helpers) + ATH_CHECK(detStore()->retrieve(m_idHelper,"FaserSCT_ID")); + + // Initialize the key of input SiElementPropertiesTable and SiDetectorElementCollection for SCT + ATH_CHECK(m_SCTDetEleCollKey.initialize()); - if ( m_seed_spcontainerKey.key().empty()){ - ATH_MSG_FATAL( "No name set for output seeds space points"); - return StatusCode::FAILURE; + if ( m_seed_spcontainerKey.key().empty()){ + ATH_MSG_FATAL( "No name set for output seeds space points"); + return StatusCode::FAILURE; + } + + ATH_CHECK( m_seed_spcontainerKey.initialize() ); + + ATH_CHECK( m_mcEventKey.initialize() ); + ATH_CHECK( m_faserSiHitKey.initialize() ); + ATH_CHECK( m_faserRdoKey.initialize()); + ATH_CHECK( m_sctMap.initialize()); + ATH_MSG_INFO( "Using GenEvent collection with key " << m_mcEventKey.key()); + ATH_MSG_INFO( "Using Faser SiHit collection with key " << m_faserSiHitKey.key()); + ATH_MSG_INFO( "Using FaserSCT RDO Container with key " << m_faserRdoKey.key()); + ATH_MSG_INFO( "Using SCT_SDO_Map with key "<< m_sctMap.key()); + + m_hist_n=new TH1D("sp_n","sp_n",20,0,20); + m_hist_x=new TH1D("sp_x","sp_x",100,-200,200); + m_hist_y=new TH1D("sp_y","sp_y",100,-200,200); + m_hist_z=new TH1D("sp_z","sp_z",3500,0,3500); + m_hist_r=new TH1D("sp_r","sp_r",100,0,200); + m_hist_eta=new TH1D("sp_eta","sp_eta",100,0,5); + m_hist_phi=new TH1D("sp_phi","sp_phi",100,-3.2,3.2); + m_hist_strip=new TH1D("sp_strip","sp_strip",1000,0,1000); + m_hist_layer=new TH1D("sp_layer","sp_layer",100,-10,10); + m_hist_station=new TH1D("sp_station","sp_station",100,-10,10); + m_hist_sp_station=new TH1D("sp_all_station","sp_station",100,-10,10); + m_hist_sp_row=new TH1D("sp_all_row","sp_station",100,-10,10); + m_hist_sp_module=new TH1D("sp_all_module","sp_station",100,-10,10); + m_hist_sp_sensor=new TH1D("sp_all_sensor","sp_station",100,-10,10); + m_hist_sp_plane=new TH1D("sp_all_plane","sp_station",100,-10,10); + m_hist_sp_layer=new TH1D("sp_all_layer","sp_station",100,-10,10); + m_hist_x_z=new TH2D("sp_x_z","sp_x_z",100,-200,200,3500,0,3500); + m_hist_y_z=new TH2D("sp_y_z","sp_y_z",100,-200,200,3500,0,3500); + m_hist_x_y_plane0=new TH2D("sp_x_y_plane0","sp_x_y_plane0",100,-200,200,100,-200,200); + m_hist_x_y_plane1=new TH2D("sp_x_y_plane1","sp_x_y_plane1",100,-200,200,100,-200,200); + m_hist_x_y_plane2=new TH2D("sp_x_y_plane2","sp_x_y_plane2",100,-200,200,100,-200,200); + m_hist_x_y_plane3=new TH2D("sp_x_y_plane3","sp_x_y_plane3",100,-200,200,100,-200,200); + m_hist_x_y_plane4=new TH2D("sp_x_y_plane4","sp_x_y_plane4",100,-200,200,100,-200,200); + m_hist_x_y_plane5=new TH2D("sp_x_y_plane5","sp_x_y_plane5",100,-200,200,100,-200,200); + m_hist_x_y_plane6=new TH2D("sp_x_y_plane6","sp_x_y_plane6",100,-200,200,100,-200,200); + m_hist_x_y_plane7=new TH2D("sp_x_y_plane7","sp_x_y_plane7",100,-200,200,100,-200,200); + m_hist_x_y_plane8=new TH2D("sp_x_y_plane8","sp_x_y_plane8",100,-200,200,100,-200,200); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_n",m_hist_n)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x",m_hist_x)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_y",m_hist_y)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_z",m_hist_z)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_r",m_hist_r)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_eta",m_hist_eta)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_phi",m_hist_phi)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_strip",m_hist_strip)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_layer",m_hist_layer)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_station",m_hist_station)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_station",m_hist_sp_station)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_layer",m_hist_sp_layer)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_module",m_hist_sp_module)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_plane",m_hist_sp_plane)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_row",m_hist_sp_row)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_sensor",m_hist_sp_sensor)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_z",m_hist_x_z)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_y_z",m_hist_y_z)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane0",m_hist_x_y_plane0)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane1",m_hist_x_y_plane1)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane2",m_hist_x_y_plane2)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane3",m_hist_x_y_plane3)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane4",m_hist_x_y_plane4)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane5",m_hist_x_y_plane5)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane6",m_hist_x_y_plane6)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane7",m_hist_x_y_plane7)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane8",m_hist_x_y_plane8)); + //!!!!!!!!!!!!!!!!!!!! + m_hist_InitReso_px=new TH1D("InitReso_px","InitReso_px",200,-10,10); + m_hist_InitReso_py=new TH1D("InitReso_py","InitReso_py",200,-10,10); + m_hist_InitReso_pz=new TH1D("InitReso_pz","InitReso_pz",200,-10,10); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/InitReso_px",m_hist_InitReso_px)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/InitReso_py",m_hist_InitReso_py)); + CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/InitReso_pz",m_hist_InitReso_pz)); + //!!!!!!!!!!!!!!!!!!!! + ATH_MSG_INFO( "TruthTrackSeeds::initialized for package version " << PACKAGE_VERSION ); + return StatusCode::SUCCESS; } - ATH_CHECK( m_seed_spcontainerKey.initialize() ); - - // create containers (requires the Identifier Helpers) - ATH_CHECK(detStore()->retrieve(m_idHelper,"FaserSCT_ID")); - - // Initialize the key of input SiElementPropertiesTable and SiDetectorElementCollection for SCT - ATH_CHECK(m_SCTDetEleCollKey.initialize()); - - ATH_CHECK( m_mcEventKey.initialize() ); - ATH_CHECK( m_faserSiHitKey.initialize() ); - ATH_CHECK( m_faserRdoKey.initialize()); - ATH_CHECK( m_sctMap.initialize()); - ATH_MSG_INFO( "Using GenEvent collection with key " << m_mcEventKey.key()); - ATH_MSG_INFO( "Using Faser SiHit collection with key " << m_faserSiHitKey.key()); - ATH_MSG_INFO( "Using FaserSCT RDO Container with key " << m_faserRdoKey.key()); - ATH_MSG_INFO( "Using SCT_SDO_Map with key "<< m_sctMap.key()); - - m_hist_n=new TH1D("sp_n","sp_n",20,0,20); - m_hist_x=new TH1D("sp_x","sp_x",100,-200,200); - m_hist_y=new TH1D("sp_y","sp_y",100,-200,200); - m_hist_z=new TH1D("sp_z","sp_z",3500,0,3500); - m_hist_r=new TH1D("sp_r","sp_r",100,0,200); - m_hist_eta=new TH1D("sp_eta","sp_eta",100,0,5); - m_hist_phi=new TH1D("sp_phi","sp_phi",100,-3.2,3.2); - m_hist_strip=new TH1D("sp_strip","sp_strip",1000,0,1000); - m_hist_layer=new TH1D("sp_layer","sp_layer",100,-10,10); - m_hist_station=new TH1D("sp_station","sp_station",100,-10,10); - m_hist_sp_station=new TH1D("sp_all_station","sp_station",100,-10,10); - m_hist_sp_row=new TH1D("sp_all_row","sp_station",100,-10,10); - m_hist_sp_module=new TH1D("sp_all_module","sp_station",100,-10,10); - m_hist_sp_sensor=new TH1D("sp_all_sensor","sp_station",100,-10,10); - m_hist_sp_plane=new TH1D("sp_all_plane","sp_station",100,-10,10); - m_hist_sp_layer=new TH1D("sp_all_layer","sp_station",100,-10,10); - m_hist_x_z=new TH2D("sp_x_z","sp_x_z",100,-200,200,3500,0,3500); - m_hist_y_z=new TH2D("sp_y_z","sp_y_z",100,-200,200,3500,0,3500); - m_hist_x_y_plane0=new TH2D("sp_x_y_plane0","sp_x_y_plane0",100,-200,200,100,-200,200); - m_hist_x_y_plane1=new TH2D("sp_x_y_plane1","sp_x_y_plane1",100,-200,200,100,-200,200); - m_hist_x_y_plane2=new TH2D("sp_x_y_plane2","sp_x_y_plane2",100,-200,200,100,-200,200); - m_hist_x_y_plane3=new TH2D("sp_x_y_plane3","sp_x_y_plane3",100,-200,200,100,-200,200); - m_hist_x_y_plane4=new TH2D("sp_x_y_plane4","sp_x_y_plane4",100,-200,200,100,-200,200); - m_hist_x_y_plane5=new TH2D("sp_x_y_plane5","sp_x_y_plane5",100,-200,200,100,-200,200); - m_hist_x_y_plane6=new TH2D("sp_x_y_plane6","sp_x_y_plane6",100,-200,200,100,-200,200); - m_hist_x_y_plane7=new TH2D("sp_x_y_plane7","sp_x_y_plane7",100,-200,200,100,-200,200); - m_hist_x_y_plane8=new TH2D("sp_x_y_plane8","sp_x_y_plane8",100,-200,200,100,-200,200); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_n",m_hist_n)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x",m_hist_x)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_y",m_hist_y)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_z",m_hist_z)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_r",m_hist_r)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_eta",m_hist_eta)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_phi",m_hist_phi)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_strip",m_hist_strip)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_layer",m_hist_layer)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_station",m_hist_station)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_station",m_hist_sp_station)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_layer",m_hist_sp_layer)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_module",m_hist_sp_module)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_plane",m_hist_sp_plane)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_row",m_hist_sp_row)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_all_sensor",m_hist_sp_sensor)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_z",m_hist_x_z)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_y_z",m_hist_y_z)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane0",m_hist_x_y_plane0)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane1",m_hist_x_y_plane1)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane2",m_hist_x_y_plane2)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane3",m_hist_x_y_plane3)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane4",m_hist_x_y_plane4)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane5",m_hist_x_y_plane5)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane6",m_hist_x_y_plane6)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane7",m_hist_x_y_plane7)); - CHECK(m_thistSvc->regHist("/TruthTrackSeeds/sp/sp_x_y_plane8",m_hist_x_y_plane8)); - ATH_MSG_INFO( "TruthTrackSeeds::initialized for package version " << PACKAGE_VERSION ); - return StatusCode::SUCCESS; -} + //------------------------------------------------------------------------- -//------------------------------------------------------------------------- + StatusCode TruthSeededTrackFinder::execute (const EventContext& ctx) const + { -StatusCode TruthSeededTrackFinder::execute (const EventContext& ctx) const -{ + ++m_numberOfEvents; - ++m_numberOfEvents; + // Handles created from handle keys behave like pointers to the corresponding container + SG::ReadHandle<McEventCollection> h_mcEvents(m_mcEventKey, ctx); + ATH_MSG_INFO("Read McEventContainer with " << h_mcEvents->size() << " events"); + if (h_mcEvents->size() == 0) return StatusCode::FAILURE; - // Handles created from handle keys behave like pointers to the corresponding container - SG::ReadHandle<McEventCollection> h_mcEvents(m_mcEventKey, ctx); - ATH_MSG_INFO("Read McEventContainer with " << h_mcEvents->size() << " events"); - if (h_mcEvents->size() == 0) return StatusCode::FAILURE; + SG::ReadHandle<FaserSiHitCollection> h_siHits(m_faserSiHitKey, ctx); + ATH_MSG_INFO("Read FaserSiHitCollection with " << h_siHits->size() << " hits"); - SG::ReadHandle<FaserSiHitCollection> h_siHits(m_faserSiHitKey, ctx); - ATH_MSG_INFO("Read FaserSiHitCollection with " << h_siHits->size() << " hits"); + SG::ReadHandle<FaserSCT_RDO_Container> h_sctRDO(m_faserRdoKey, ctx); - SG::ReadHandle<FaserSCT_RDO_Container> h_sctRDO(m_faserRdoKey, ctx); + SG::WriteHandle<SpacePointForSeedCollection> seedContainer_SCT(m_seed_spcontainerKey, ctx ); - SG::WriteHandle<SpacePointContainer> seedContainer_SCT(m_seed_spcontainerKey, ctx ); + ATH_CHECK( seedContainer_SCT.record( std::make_unique<SpacePointForSeedCollection>() ) ); + ATH_MSG_INFO("Created SpacePointContainer " << m_seed_spcontainerKey.key() << " N= " << m_idHelper->wafer_hash_max()); - ATH_CHECK( seedContainer_SCT.record( std::make_unique<SpacePointContainer>(m_idHelper->wafer_hash_max()) ) ); - ATH_MSG_DEBUG("Created SpacePointContainer " << m_seed_spcontainerKey.key() << " N= " << m_idHelper->wafer_hash_max()); + const TrackerDD::SiDetectorElementCollection* elements = nullptr; + SG::ReadCondHandle<TrackerDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx); + elements = sctDetEle.retrieve(); + if (elements==nullptr) { + ATH_MSG_FATAL("Pointer of SiDetectorElementCollection (" << m_SCTDetEleCollKey.fullKey() << ") could not be retrieved"); + return StatusCode::SUCCESS; + } - const TrackerDD::SiDetectorElementCollection* elements = nullptr; - SG::ReadCondHandle<TrackerDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx); - elements = sctDetEle.retrieve(); - if (elements==nullptr) { - ATH_MSG_FATAL("Pointer of SiDetectorElementCollection (" << m_SCTDetEleCollKey.fullKey() << ") could not be retrieved"); - return StatusCode::SUCCESS; - } - // register the IdentifiableContainer into StoreGate + // retrieve SCT cluster container + SG::ReadHandle<SpacePointContainer> sct_spcontainer( m_Sct_spcontainerKey, ctx ); + if (!sct_spcontainer.isValid()){ + msg(MSG:: FATAL) << "Could not find the data object "<< sct_spcontainer.name() << " !" << endmsg; + return StatusCode::RECOVERABLE; + } + //!!!!!!!!!!!!!!!!!!!! + static const TrackerDD::SCT_DetectorManager *s_sct; + if(detStore()->retrieve(s_sct,"SCT").isFailure()) s_sct = 0; + int N_1_0=0, N_1_1=0, N_1_2=0, N_2_0=0, N_2_1=0, N_2_2=0; + int match_N_1_0=0, match_N_1_1=0, match_N_1_2=0, match_N_2_0=0, match_N_2_1=0, match_N_2_2=0; + HepMC::FourVector truthmom; + //!!!!!!!!!!!!!!!!!!!! + + ATH_MSG_DEBUG( "SCT spacepoint container found: " << sct_spcontainer->size() << " collections" ); + SpacePointContainer::const_iterator it = sct_spcontainer->begin(); + SpacePointContainer::const_iterator itend = sct_spcontainer->end(); + + int nTruthSP=0; + ATH_MSG_DEBUG( "Start iteration of spacepoint collections" ); + for (; it != itend; ++it){ + ++m_numberOfSPCollection; + const SpacePointCollection *colNext=&(**it); + int nReceivedSPSCT = colNext->size(); + + // Create SpacePointCollection + IdentifierHash idHash = colNext->identifyHash(); + Identifier elementID = colNext->identify(); + + + ATH_MSG_DEBUG( "Spacepoint collection in iteraction: size = " <<nReceivedSPSCT <<", IDHash = "<<idHash<<", ID = "<<elementID ); + if (nReceivedSPSCT== 0){ + ATH_MSG_VERBOSE( "Algorithm found no space points" ); + ++m_numberOfEmptySPCollection; + } else { + SpacePointCollection::const_iterator sp_begin= colNext->begin(); + SpacePointCollection::const_iterator sp_end= colNext->end(); + + ATH_MSG_DEBUG( "Iterate the spacepoint in collection " ); + for (; sp_begin != sp_end; ++sp_begin){ + ++m_numberOfSP; + const Trk::SpacePoint* sp=&(**sp_begin); + bool match=false; + //get truth hit + const auto identifier = sp->clusterList().first->identify(); + int station = m_idHelper->station(identifier); + int plane = m_idHelper->layer(identifier); + int row = m_idHelper->phi_module(identifier); + int module = m_idHelper->eta_module(identifier); + int sensor = m_idHelper->side(identifier); + m_hist_sp_station->Fill(station); + m_hist_sp_plane->Fill(plane); + m_hist_sp_layer->Fill((station-1)*3+plane); + m_hist_sp_row->Fill(row); + m_hist_sp_module->Fill(module); + m_hist_sp_sensor->Fill(sensor); + //!!!!!!!!!!!!!!!!!!!! + if (station==1 && plane==0) N_1_0++; + if (station==1 && plane==1) N_1_1++; + if (station==1 && plane==2) N_1_2++; + if (station==2 && plane==0) N_2_0++; + if (station==2 && plane==1) N_2_1++; + if (station==2 && plane==2) N_2_2++; + //!!!!!!!!!!!!!!!!!!!! + + ATH_MSG_DEBUG( "Spacepoint :"<<identifier ); + SG::ReadHandle<TrackerSimDataCollection> h_collectionMap(m_sctMap, ctx); + ATH_MSG_DEBUG("map size "<<h_collectionMap->size()); + //!!!!!!!!!!!!!!!!!!!! + std::cout<<"!!!!!!!!! cluster: "<<sp->clusterList().first<<std::endl; + ATH_MSG_DEBUG("!!!!!!!!! cluster: "<<sp->clusterList().first->rdoList() ); + //!!!!!!!!!!!!!!!!!!!! + if( h_collectionMap->count(identifier) == 0) + { + ATH_MSG_INFO("no map found w/identifier "<<identifier); + ++m_numberOfNoMap; + continue; + } - // retrieve SCT cluster container - SG::ReadHandle<SpacePointContainer> sct_spcontainer( m_Sct_spcontainerKey, ctx ); - if (!sct_spcontainer.isValid()){ - msg(MSG:: FATAL) << "Could not find the data object "<< sct_spcontainer.name() << " !" << endmsg; - return StatusCode::RECOVERABLE; - } + //Collection map takes identifier and returns simulation data + const auto& simdata = h_collectionMap->find(identifier)->second; + const auto& deposits = simdata.getdeposits(); + //loop through deposits to find one w/ highest energy & get barcode + float highestDep = 0; + int barcode = 0; + HepMcParticleLink primary{}; + for( const auto& depositPair : deposits) + { + //!!!!!!!!!!!!!!!!!!!!!!!! + depositPair.first->print(std::cout); + std::cout<<"!!!!!!!!!!! pdg id = "<<depositPair.first->pdg_id()<<std::endl; + if (depositPair.first->pdg_id() == -13) { + HepMC::FourVector pv = depositPair.first->production_vertex()->position(); + HepMC::FourVector ev = depositPair.first->end_vertex()->position (); + truthmom = depositPair.first->momentum(); + std::cout<<"!!!!!!!!!!! production_vertex: ( "<<pv.x()<<", "<<pv.y()<<", "<<pv.z()<<" ) "<<std::endl; + std::cout<<"!!!!!!!!!!! end_vertex: ( "<<ev.x()<<", "<<ev.y()<<", "<<ev.z()<<" ) "<<std::endl; + } + //!!!!!!!!!!!!!!!!!!!!!!!! + if( depositPair.second > highestDep) + { + highestDep = depositPair.second; + barcode = depositPair.first->barcode(); + primary = depositPair.first; + //!!!!depositPair.first->print(std::cout); + ATH_MSG_DEBUG("pdg id "<<depositPair.first->pdg_id()); + } + } + + ATH_MSG_DEBUG("final barcode of: "<<barcode); + if(barcode%1000000 != 10001) continue; + + //!!!!!!!!!!!!!!!!!!!!!!!! + if (primary->end_vertex() != nullptr) + { + for (auto daughter : primary->particles_out()) + { + // TODO: Check that daughter->production_vertex() and daughter->end_vertex() exist, and bracket the point you're interested in + if (daughter->barcode() % 1000000 == primary->barcode()) { + ATH_MSG_INFO(" daughter barcode: " << daughter->barcode() << " with energy " << daughter->momentum().e() << " px = " << daughter->momentum().px() << " py = " << daughter->momentum().py() << " pz = " << daughter->momentum().pz() ); + if (daughter->production_vertex() != nullptr && daughter->end_vertex() != nullptr) { + HepMC::FourVector pv = daughter->production_vertex()->position(); + HepMC::FourVector ev = daughter->end_vertex()->position (); + std::cout<<"!!!!!!!!!!! production_vertex: ( "<<pv.x()<<", "<<pv.y()<<", "<<pv.z()<<" ) "<<std::endl; + std::cout<<"!!!!!!!!!!! end_vertex: ( "<<ev.x()<<", "<<ev.y()<<", "<<ev.z()<<" ) "<<std::endl; + } + } + } + } + //!!!!!!!!!!!!!!!!!!!!!!!! + + //Helper function to get hit location information from RDO identifier + ATH_MSG_DEBUG("trying to match hit to stat/plane/row/mod/sens: "<<station<<" "<<plane<<" "<<row<<" "<<module<<" "<<sensor); + for (const FaserSiHit& hit : *h_siHits) + { + ++m_numberOfHits; + ATH_MSG_DEBUG("hit w/vals "<<hit.getStation()<<" "<<hit.getPlane()<<" "<<hit.getRow()<<" "<<hit.getModule()<<" "<<hit.getSensor()<<" barcode: "<<hit.trackNumber()); + //set of conditions to confirm looking at same particle in same place for SiHit as RDO + if(hit.getStation() == station + && hit.getPlane() == plane + && hit.getRow() == row + && hit.getModule() == module + && hit.getSensor() == sensor + && hit.trackNumber() == barcode) + { + ++m_numberOfMatchSP; + ATH_MSG_DEBUG("matched particle and plotting w/ barcode "<<barcode); + match=true; + } + //!!!!!!!!!!!!!!!!!!!!!!!! + const TrackerDD::SiDetectorElement *geoelement=NULL; + Identifier id = m_idHelper->wafer_id(hit.getStation(), + hit.getPlane(), + hit.getRow(), + hit.getModule(), + hit.getSensor() ); + + geoelement = s_sct->getDetectorElement(id); + if (geoelement) { + double m_ran_pos=(double)(std::rand())/RAND_MAX; + HepGeom::Point3D<double> m_lp_start,m_lp_end; + HepGeom::Point3D<double> m_new_pos; + //start and end position + m_lp_start=hit.localStartPosition(); + m_lp_end=hit.localEndPosition(); + m_new_pos=m_lp_start+(m_lp_end-m_lp_start)*m_ran_pos; + //muPos=Amg::EigenTransformToCLHEP(geoelement->transformHit()) * HepGeom::Point3D<double>(m_new_pos); + std::cout<<"!!!!!!!!!!! hit start pos: "<<Amg::EigenTransformToCLHEP(geoelement->transformHit()) * HepGeom::Point3D<double>(m_lp_start)<<std::endl; + std::cout<<"!!!!!!!!!!! hit end pos: "<<Amg::EigenTransformToCLHEP(geoelement->transformHit()) * HepGeom::Point3D<double>(m_lp_end)<<std::endl; + } + //!!!!!!!!!!!!!!!!!!!!!!!! + } + // + if(!match) + continue; + ++m_numberOfFills; + ++nTruthSP; + + SpacePointForSeed* spseed=new SpacePointForSeed(sp); + seedContainer_SCT->push_back(spseed); + m_hist_r->Fill(sp->r()); + m_hist_eta->Fill(sp->eta()); + m_hist_phi->Fill(sp->phi()); + Amg::Vector3D gloPos=sp->globalPosition(); + m_hist_x->Fill(gloPos.x()); + m_hist_y->Fill(gloPos.y()); + m_hist_z->Fill(gloPos.z()); + m_hist_strip->Fill(m_idHelper->strip(elementID)); + m_hist_station->Fill(m_idHelper->station(elementID)); + m_hist_layer->Fill(m_idHelper->layer(elementID)); + m_hist_x_z->Fill(gloPos.x(),gloPos.z()); + m_hist_y_z->Fill(gloPos.y(),gloPos.z()); + int ilayer=m_idHelper->layer(elementID); + int istation=m_idHelper->station(elementID); + if ( ((istation-1)*3+ilayer) == 0 ) m_hist_x_y_plane0->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 1 ) m_hist_x_y_plane1->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 2 ) m_hist_x_y_plane2->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 3 ) m_hist_x_y_plane3->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 4 ) m_hist_x_y_plane4->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 5 ) m_hist_x_y_plane5->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 6 ) m_hist_x_y_plane6->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 7 ) m_hist_x_y_plane7->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 8 ) m_hist_x_y_plane8->Fill(gloPos.x(),gloPos.y()); + //!!!!!!!!!!!!!!!!!!!! + if (istation==1 && ilayer==0) { match_N_1_0++; } + if (istation==1 && ilayer==1) { match_N_1_1++; } + if (istation==1 && ilayer==2) { match_N_1_2++; } + if (istation==2 && ilayer==0) { match_N_2_0++; } + if (istation==2 && ilayer==1) { match_N_2_1++; } + if (istation==2 && ilayer==2) { match_N_2_2++; } + std::cout<<"!!!!!!!!!!! (station, layer) = ("<<istation<<", "<<ilayer<<") positopn = ("<<gloPos.x()<<", "<<gloPos.y()<<", "<<gloPos.z()<<") "<<std::endl; + if (std::fabs(gloPos.x())>100) std::cout<<"!!!!!!!!!!! badXXX "<<std::endl; + //!!!!!!!!!!!!!!!!!!!! + } + ATH_MSG_VERBOSE( nReceivedSPSCT << " SpacePoints successfully added to Container !" ); + } + } + + m_hist_n->Fill(nTruthSP); + + //!!!!!!!!!!!!!!!!!!!!!!!! + std::cout<<"!!!!!!!!!!! N_1_0 = "<<N_1_0<<", N_1_1 = "<<N_1_1<<", N_1_2 = "<<N_1_2<<", N_2_0 = "<<N_2_0<<", N_2_1 = "<<N_2_1<<", N_2_2 = "<<N_2_2<<std::endl; + std::cout<<"!!!!!!!!!!! match_N_1_0 = "<<match_N_1_0<<", match_N_1_1 = "<<match_N_1_1<<", match_N_1_2 = "<<match_N_1_2<<", match_N_2_0 = "<<match_N_2_0<<", match_N_2_1 = "<<match_N_2_1<<", match_N_2_2 = "<<match_N_2_2<<std::endl; + if ( (N_1_0==1 && match_N_1_0==1) && (N_1_1==1 && match_N_1_1==1) && (N_1_2==1 && match_N_1_2==1) && (N_2_0==1 && match_N_2_0==1) && (N_2_1==1 && match_N_2_1==1) && (N_2_2==1 && match_N_2_2==1)) { + Acts::Vector3D pos1_0(0., 0., 0.); + Acts::Vector3D pos1_1(0., 0., 0.); + Acts::Vector3D pos1_2(0., 0., 0.); + Acts::Vector3D pos2_0(0., 0., 0.); + Acts::Vector3D pos2_1(0., 0., 0.); + Acts::Vector3D pos2_2(0., 0., 0.); - ATH_MSG_DEBUG( "SCT spacepoint container found: " << sct_spcontainer->size() << " collections" ); SpacePointContainer::const_iterator it = sct_spcontainer->begin(); SpacePointContainer::const_iterator itend = sct_spcontainer->end(); - //use 0 as the hash - IdentifierHash idHash(0); - Identifier id(0); - auto spCollection = std::make_unique<SpacePointCollection>(idHash); - spCollection->setIdentifier(id); - spCollection->reserve(100); - SpacePointContainer::IDC_WriteHandle lock = seedContainer_SCT->getWriteHandle(idHash); - - int nTruthSP=0; - ATH_MSG_DEBUG( "Start iteration of spacepoint collections" ); for (; it != itend; ++it){ - ++m_numberOfSPCollection; const SpacePointCollection *colNext=&(**it); - int nReceivedSPSCT = colNext->size(); // Create SpacePointCollection IdentifierHash idHash = colNext->identifyHash(); Identifier elementID = colNext->identify(); + int istation = m_idHelper->station(elementID); + int ilayer = m_idHelper->layer(elementID); size_t size = colNext->size(); - ATH_MSG_DEBUG( "Spacepoint collection in iteraction: size = " <<nReceivedSPSCT <<", IDHash = "<<idHash<<", ID = "<<elementID ); if (size == 0){ - ATH_MSG_VERBOSE( "Algorithm found no space points" ); - ++m_numberOfEmptySPCollection; + ATH_MSG_VERBOSE( "StatisticsAlg algorithm found no space points" ); } else { //In a MT environment the cache maybe filled by another thread in which case this will delete the duplicate SpacePointCollection::const_iterator sp_begin= colNext->begin(); SpacePointCollection::const_iterator sp_end= colNext->end(); - ATH_MSG_DEBUG( "Iterate the spacepoint in collection " ); for (; sp_begin != sp_end; ++sp_begin){ - ++m_numberOfSP; const Trk::SpacePoint* sp=&(**sp_begin); - bool match=false; - //get truth hit - const auto identifier = sp->clusterList().first->identify(); - int station = m_idHelper->station(identifier); - int plane = m_idHelper->layer(identifier); - int row = m_idHelper->phi_module(identifier); - int module = m_idHelper->eta_module(identifier); - int sensor = m_idHelper->side(identifier); - m_hist_sp_station->Fill(station); - m_hist_sp_plane->Fill(plane); - m_hist_sp_layer->Fill((station-1)*3+plane); - m_hist_sp_row->Fill(row); - m_hist_sp_module->Fill(module); - m_hist_sp_sensor->Fill(sensor); - - ATH_MSG_DEBUG( "Spacepoint :"<<identifier ); - SG::ReadHandle<TrackerSimDataCollection> h_collectionMap(m_sctMap, ctx); - ATH_MSG_DEBUG("map size "<<h_collectionMap->size()); - if( h_collectionMap->count(identifier) == 0) - { - ATH_MSG_INFO("no map found w/identifier "<<identifier); - ++m_numberOfNoMap; - continue; - } - - //Collection map takes identifier and returns simulation data - const auto& simdata = h_collectionMap->find(identifier)->second; - const auto& deposits = simdata.getdeposits(); - - //loop through deposits to find one w/ highest energy & get barcode - float highestDep = 0; - int barcode = 0; - for( const auto& depositPair : deposits) - { - if( depositPair.second > highestDep) - { - highestDep = depositPair.second; - barcode = depositPair.first->barcode(); - depositPair.first->print(std::cout); - ATH_MSG_INFO("pdg id "<<depositPair.first->pdg_id()); - } - } - ATH_MSG_INFO("final barcode of: "<<barcode); - if(barcode%1000000 != 10001) - continue; - - //Helper function to get hit location information from RDO identifier - ATH_MSG_INFO("trying to match hit to stat/plane/row/mod/sens: "<<station<<" "<<plane<<" "<<row<<" "<<module<<" "<<sensor); - for (const FaserSiHit& hit : *h_siHits) - { - ++m_numberOfHits; - ATH_MSG_INFO("hit w/vals "<<hit.getStation()<<" "<<hit.getPlane()<<" "<<hit.getRow()<<" "<<hit.getModule()<<" "<<hit.getSensor()<<" barcode: "<<hit.trackNumber()); - //set of conditions to confirm looking at same particle in same place for SiHit as RDO - if(hit.getStation() == station - && hit.getPlane() == plane - && hit.getRow() == row - && hit.getModule() == module - && hit.getSensor() == sensor - && hit.trackNumber() == barcode) - { - ++m_numberOfMatchSP; - ATH_MSG_INFO("matched particle and plotting w/ barcode "<<barcode); - match=true; - } - } -// // -// - if(!match) - continue; -// - ++m_numberOfFills; - ++nTruthSP; -// fails, don't know why -// spCollection->push_back(const_cast<TrackerSpacePoint*>(sp)); - - m_hist_r->Fill(sp->r()); - m_hist_eta->Fill(sp->eta()); - m_hist_phi->Fill(sp->phi()); Amg::Vector3D gloPos=sp->globalPosition(); - m_hist_x->Fill(gloPos.x()); - m_hist_y->Fill(gloPos.y()); - m_hist_z->Fill(gloPos.z()); - m_hist_strip->Fill(m_idHelper->strip(elementID)); - m_hist_station->Fill(m_idHelper->station(elementID)); - m_hist_layer->Fill(m_idHelper->layer(elementID)); - m_hist_x_z->Fill(gloPos.x(),gloPos.z()); - m_hist_y_z->Fill(gloPos.y(),gloPos.z()); - int ilayer=m_idHelper->layer(elementID); - int istation=m_idHelper->station(elementID); - if ( ((istation-1)*3+ilayer) == 0 ) m_hist_x_y_plane0->Fill(gloPos.x(),gloPos.y()); - if ( ((istation-1)*3+ilayer) == 1 ) m_hist_x_y_plane1->Fill(gloPos.x(),gloPos.y()); - if ( ((istation-1)*3+ilayer) == 2 ) m_hist_x_y_plane2->Fill(gloPos.x(),gloPos.y()); - if ( ((istation-1)*3+ilayer) == 3 ) m_hist_x_y_plane3->Fill(gloPos.x(),gloPos.y()); - if ( ((istation-1)*3+ilayer) == 4 ) m_hist_x_y_plane4->Fill(gloPos.x(),gloPos.y()); - if ( ((istation-1)*3+ilayer) == 5 ) m_hist_x_y_plane5->Fill(gloPos.x(),gloPos.y()); - if ( ((istation-1)*3+ilayer) == 6 ) m_hist_x_y_plane6->Fill(gloPos.x(),gloPos.y()); - if ( ((istation-1)*3+ilayer) == 7 ) m_hist_x_y_plane7->Fill(gloPos.x(),gloPos.y()); - if ( ((istation-1)*3+ilayer) == 8 ) m_hist_x_y_plane8->Fill(gloPos.x(),gloPos.y()); + if ( ((istation-1)*3+ilayer) == 0 ) pos1_0 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + if ( ((istation-1)*3+ilayer) == 1 ) pos1_1 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + if ( ((istation-1)*3+ilayer) == 2 ) pos1_2 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + if ( ((istation-1)*3+ilayer) == 3 ) pos2_0 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + if ( ((istation-1)*3+ilayer) == 4 ) pos2_1 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + if ( ((istation-1)*3+ilayer) == 5 ) pos2_2 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); } - ATH_MSG_VERBOSE( size << " SpacePoints successfully added to Container !" ); } } + + std::cout<<"!!!!!!!!!!! pos1_0 = ("<<pos1_0.x()<<", "<<pos1_0.y()<<", "<<pos1_0.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos1_1 = ("<<pos1_1.x()<<", "<<pos1_1.y()<<", "<<pos1_1.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos1_2 = ("<<pos1_2.x()<<", "<<pos1_2.y()<<", "<<pos1_2.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos2_0 = ("<<pos2_0.x()<<", "<<pos2_0.y()<<", "<<pos2_0.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos2_1 = ("<<pos2_1.x()<<", "<<pos2_1.y()<<", "<<pos2_1.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos2_2 = ("<<pos2_2.x()<<", "<<pos2_2.y()<<", "<<pos2_2.z()<<") "<<std::endl; + + double charge = 1; + double B = 0.57; + // const Acts::Vector3D pos = pos1_0; + /* + Acts::Vector3D d1 = pos1_2 - pos1_0; + Acts::Vector3D d2 = pos2_2 - pos2_0; + */ + + // the least square of three space pionts + // Note: when z2 = (z1 + z3)/2 , the slope is the same as (pos1_2 - pos1_0) + // calculate the averages + double Ax1 = (pos1_0.x() + pos1_1.x() +pos1_2.x()) / 3; + double Ay1 = (pos1_0.y() + pos1_1.y() +pos1_2.y()) / 3; + double Az1 = (pos1_0.z() + pos1_1.z() +pos1_2.z()) / 3; + // calculate the sums + double Sxz1 = pos1_0.x()*pos1_0.z() + pos1_1.x()*pos1_1.z() + pos1_2.x()*pos1_2.z(); + double Syz1 = pos1_0.y()*pos1_0.z() + pos1_1.y()*pos1_1.z() + pos1_2.y()*pos1_2.z(); + double Szz1 = pos1_0.z()*pos1_0.z() + pos1_1.z()*pos1_1.z() + pos1_2.z()*pos1_2.z(); + // calculate the slope + double kxz1 = (Sxz1 - 3*Ax1*Az1) / (Szz1 - 3*Az1*Az1); + double kyz1 = (Syz1 - 3*Ay1*Az1) / (Szz1 - 3*Az1*Az1); + Acts::Vector3D d1( kxz1, kyz1, 1.0); + // calculate the averages + double Ax2 = (pos2_0.x() + pos2_1.x() +pos2_2.x()) / 3; + double Ay2 = (pos2_0.y() + pos2_1.y() +pos2_2.y()) / 3; + double Az2 = (pos2_0.z() + pos2_1.z() +pos2_2.z()) / 3; + // calculate the sums + double Sxz2 = pos2_0.x()*pos2_0.z() + pos2_1.x()*pos2_1.z() + pos2_2.x()*pos2_2.z(); + double Syz2 = pos2_0.y()*pos2_0.z() + pos2_1.y()*pos2_1.z() + pos2_2.y()*pos2_2.z(); + double Szz2 = pos2_0.z()*pos2_0.z() + pos2_1.z()*pos2_1.z() + pos2_2.z()*pos2_2.z(); + // calculate the slope + double kxz2 = (Sxz2 - 3*Ax2*Az2) / (Szz2 - 3*Az2*Az2); + double kyz2 = (Syz2 - 3*Ay2*Az2) / (Szz2 - 3*Az2*Az2); + Acts::Vector3D d2( kxz2, kyz2, 1.0); + // - m_hist_n->Fill(nTruthSP); - StatusCode sc= lock.addOrDelete( std::move(spCollection) ); - if (sc.isFailure()){ - ATH_MSG_ERROR( "Failed to add SpacePoints to container" ); - return StatusCode::RECOVERABLE; + // the direction of momentum in the first station + Acts::Vector3D direct1 = d1.normalized(); + std::cout<<"!!!!!!!!!!! direct1 = ("<<direct1.x()<<", "<<direct1.y()<<", "<<direct1.z()<<") "<<std::endl; + // the direction of momentum in the second station + Acts::Vector3D direct2 = d2.normalized(); + std::cout<<"!!!!!!!!!!! direct2 = ("<<direct2.x()<<", "<<direct2.y()<<", "<<direct2.z()<<") "<<std::endl; + // the vector pointing from the center of circle to the particle at layer 2 in Y-Z plane + double R1_z = charge * direct1.y() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z()); + double R1_y = -charge * direct1.z() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z()); + std::cout<<"!!!!!!!!!!! (R1_y, R1_z) = ("<<R1_y<<", "<<R1_z<<") "<<std::endl; + // the vector pointing from the center of circle to the particle at layer 3 in Y-Z plane + double R2_z = charge * direct2.y() / std::sqrt(direct2.y()*direct2.y() + direct2.z()*direct2.z()); + double R2_y = -charge * direct2.z() / std::sqrt(direct2.y()*direct2.y() + direct2.z()*direct2.z()); + std::cout<<"!!!!!!!!!!! (R2_y, R2_z) = ("<<R2_y<<", "<<R2_z<<") "<<std::endl; + // the norm of radius + double R = (pos2_0.z() - pos1_2.z()) / (R2_z - R1_z); + std::cout<<"!!!!!!!!!!! R = "<<R<<std::endl; + // the norm of momentum in Y-Z plane + double p_yz = 0.3*B*R / 1000.0; // R(mm), p(GeV), B(T) + double p_z = p_yz * direct1.z() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z()); + double p_y = p_yz * direct1.y() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z()); + double p_x = direct1.x() * p_z / direct1.z(); + // total momentum at the layer 0 + const Acts::Vector3D mom(p_x, p_y, p_z); + double p = mom.norm(); + std::cout<<"!!!!!!!!!!! InitTrack momentum on layer 0: ( "<<mom.x()*1000<<", "<<mom.y()*1000<<", "<<mom.z()*1000<<", "<<p*1000<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! truth momentum: ( "<<truthmom.px()<<", "<<truthmom.py()<<", "<<truthmom.pz()<<", "<<truthmom.m()<<" ) "<<std::endl; + + if ((p_x*1000 - truthmom.px()) / std::fabs(truthmom.px()) < -10) m_hist_InitReso_px->Fill( -9.5 ); + else if ((p_x*1000 - truthmom.px()) / std::fabs(truthmom.px()) > 10) m_hist_InitReso_px->Fill( 9.5 ); + else m_hist_InitReso_px->Fill( (p_x*1000 - truthmom.px()) / std::fabs(truthmom.px()) ); + + if ((p_y*1000 - truthmom.py()) / std::fabs(truthmom.py()) < -10) m_hist_InitReso_py->Fill( -9.5 ); + else if ((p_y*1000 - truthmom.py()) / std::fabs(truthmom.py()) > 10) m_hist_InitReso_py->Fill( 9.5 ); + else m_hist_InitReso_py->Fill( (p_y*1000 - truthmom.py()) / std::fabs(truthmom.py()) ); + + if ((p_z*1000 - truthmom.pz()) / std::fabs(truthmom.pz()) < -10) m_hist_InitReso_pz->Fill( -9.5 ); + else if ((p_z*1000 - truthmom.pz()) / std::fabs(truthmom.pz())>10) m_hist_InitReso_pz->Fill( 9.5 ); + else m_hist_InitReso_pz->Fill( (p_z*1000 - truthmom.pz()) / std::fabs(truthmom.pz()) ); + + /* + // build the track covariance matrix using the smearing sigmas + double sigmaU = 20_um; + double sigmaV = 20_um; + double sigmaPhi = 1_degree; + double sigmaTheta = 1_degree; + double sigmaQOverP = 0.01*p / (p*p); + double sigmaT0 = 1_ns; + Acts::BoundSymMatrix cov = Acts::BoundSymMatrix::Zero(); + cov(Acts::eLOC_0, Acts::eLOC_0) = sigmaU * sigmaU; + cov(Acts::eLOC_1, Acts::eLOC_1) = sigmaV * sigmaV; + cov(Acts::ePHI, Acts::ePHI) = sigmaPhi * sigmaPhi; + cov(Acts::eTHETA, Acts::eTHETA) = sigmaTheta * sigmaTheta; + cov(Acts::eQOP, Acts::eQOP) = sigmaQOverP * sigmaQOverP; + cov(Acts::eT, Acts::eT) = sigmaT0 * sigmaT0; + + double time =0; + Acts::CurvilinearParameters InitTrackParam(std::make_optional(std::move(cov)), pos, mom, charge, time); + */ + } + //!!!!!!!!!!!!!!!!!!!!!! + + return StatusCode::SUCCESS; } - return StatusCode::SUCCESS; -} - -//--------------------------------------------------------------------------- -StatusCode TruthSeededTrackFinder::finalize() -{ - ATH_MSG_INFO( "Finalizing" ); - ATH_MSG_INFO( m_numberOfEvents << " events processed" ); - ATH_MSG_INFO( m_numberOfSPCollection << " spacepoint collections processed" ); - ATH_MSG_INFO( m_numberOfEmptySPCollection<< " spacepoint collections empty" ); - ATH_MSG_INFO( m_numberOfSP<< " sct SP collections processed" ); - ATH_MSG_INFO( m_numberOfNoMap<< " not maped spacepoint" ); - ATH_MSG_INFO( m_numberOfHits<< " sim hits" ); - ATH_MSG_INFO( m_numberOfMatchSP<< " matched spacepoint" ); - ATH_MSG_INFO( m_numberOfFills<< " spacepoint saved" ); - return StatusCode::SUCCESS; -} + //--------------------------------------------------------------------------- + StatusCode TruthSeededTrackFinder::finalize() + { + ATH_MSG_INFO( "Finalizing" ); + ATH_MSG_INFO( m_numberOfEvents << " events processed" ); + ATH_MSG_INFO( m_numberOfSPCollection << " spacepoint collections processed" ); + ATH_MSG_INFO( m_numberOfEmptySPCollection<< " spacepoint collections empty" ); + ATH_MSG_INFO( m_numberOfSP<< " sct SP collections processed" ); + ATH_MSG_INFO( m_numberOfNoMap<< " not maped spacepoint" ); + ATH_MSG_INFO( m_numberOfHits<< " sim hits" ); + ATH_MSG_INFO( m_numberOfMatchSP<< " matched spacepoint" ); + ATH_MSG_INFO( m_numberOfFills<< " spacepoint saved" ); + return StatusCode::SUCCESS; + } -//-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- } diff --git a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.h b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.h index f115049cff7c963a43d3150faaa45c17819b74aa..1e91539955a063585de8b823a30a5d28081acee4 100755 --- a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.h +++ b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/TruthSeededTrackFinder.h @@ -18,6 +18,7 @@ #include "TrackerReadoutGeometry/SiDetectorElementCollection.h" #include "TrkSpacePoint/SpacePoint.h" #include "TrkSpacePoint/SpacePointContainer.h" +#include "TrackerSpacePoint/SpacePointForSeedCollection.h" #include "TrkSpacePoint/SpacePointOverlapCollection.h" #include "TrackerSimEvent/FaserSiHitCollection.h" #include "TrackerRawData/FaserSCT_RDO_Container.h" @@ -26,6 +27,7 @@ #include "GaudiKernel/ServiceHandle.h" #include "GaudiKernel/ITHistSvc.h" +#include "GaudiKernel/ToolHandle.h" #include <string> #include <vector> @@ -63,7 +65,7 @@ class TruthSeededTrackFinder:public AthReentrantAlgorithm { TruthSeededTrackFinder &operator=(const TruthSeededTrackFinder&) = delete; SG::ReadHandleKey<SpacePointContainer> m_Sct_spcontainerKey{this, "SpacePointsSCTName", "SCT spContainer"}; - SG::WriteHandleKey<SpacePointContainer> m_seed_spcontainerKey{this, "SpacePointsSeedsName", "TrackerSpacePointContainer", "output seeds"}; + SG::WriteHandleKey<SpacePointForSeedCollection> m_seed_spcontainerKey{this, "FaserSpacePointsSeedsName", "SpacePointForSeedCollection", "SpacePointForSeedCollection"}; SG::ReadCondHandleKey<TrackerDD::SiDetectorElementCollection> m_SCTDetEleCollKey{this, "SCTDetEleCollKey", "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"}; @@ -109,9 +111,13 @@ class TruthSeededTrackFinder:public AthReentrantAlgorithm { TH1* m_hist_sp_plane; TH1* m_hist_sp_layer; TH1* m_hist_sp_station; + //!!!!!!!!!!!!!!!!!!!!! + TH1* m_hist_InitReso_px; + TH1* m_hist_InitReso_py; + TH1* m_hist_InitReso_pz; + //!!!!!!!!!!!!!!!!!!!!! ServiceHandle<ITHistSvc> m_thistSvc; - }; } diff --git a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/components/TruthSeededTrackFinder_entries.cxx b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/components/TruthSeededTrackFinder_entries.cxx index de277e191deea1a934510c7f795cd66458ae0bb5..1dc261b788e2324993347798265ecc4a28471db2 100644 --- a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/components/TruthSeededTrackFinder_entries.cxx +++ b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/src/components/TruthSeededTrackFinder_entries.cxx @@ -1,4 +1,3 @@ #include "../TruthSeededTrackFinder.h" DECLARE_COMPONENT( Tracker::TruthSeededTrackFinder ) - diff --git a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/test/TruthSeededTrackFinderDbg.py b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/test/TruthSeededTrackFinderDbg.py index 7e96fca34691af58f9406d5ee8319684dd1c7f11..eab4d204cdca384e1bb4e757fde40228f6c8b067 100644 --- a/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/test/TruthSeededTrackFinderDbg.py +++ b/Tracker/TrackerRecAlgs/TruthSeededTrackFinder/test/TruthSeededTrackFinderDbg.py @@ -28,6 +28,7 @@ ConfigFlags.Input.Files = ['my.RDO.pool.root'] ConfigFlags.Output.ESDFileName = "mySeeds.ESD.pool.root" ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" ConfigFlags.GeoModel.Align.Dynamic = False +#ConfigFlags.Concurrency.NumThreads = 1 ConfigFlags.Beam.NumberOfCollisions = 0. ConfigFlags.lock() @@ -48,15 +49,15 @@ acc.merge(TruthSeededTrackFinderCfg(ConfigFlags)) #acc.merge(MergeRecoTimingObjCfg(ConfigFlags)) # Dump config -# logging.getLogger('forcomps').setLevel(VERBOSE) -# acc.foreach_component("*").OutputLevel = VERBOSE -# acc.foreach_component("*ClassID*").OutputLevel = INFO +logging.getLogger('forcomps').setLevel(VERBOSE) +acc.foreach_component("*").OutputLevel = VERBOSE +acc.foreach_component("*ClassID*").OutputLevel = INFO # acc.getCondAlgo("FaserSCT_AlignCondAlg").OutputLevel = VERBOSE # acc.getCondAlgo("FaserSCT_DetectorElementCondAlg").OutputLevel = VERBOSE -# acc.getService("StoreGateSvc").Dump = True -# acc.getService("ConditionStore").Dump = True -# acc.printConfig(withDetails=True) -# ConfigFlags.dump() +acc.getService("StoreGateSvc").Dump = True +acc.getService("ConditionStore").Dump = True +acc.printConfig(withDetails=True) +ConfigFlags.dump() # Execute and finish sc = acc.run(maxEvents=-1) diff --git a/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/SpacePointForSeed.h b/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/SpacePointForSeed.h new file mode 100644 index 0000000000000000000000000000000000000000..9b3f7fcf67b830190245546fe0923e19b08e4b61 --- /dev/null +++ b/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/SpacePointForSeed.h @@ -0,0 +1,24 @@ +#ifndef SpacePointForSeed_h +#define SpacePointForSeed_h + +#include "TrkSpacePoint/SpacePoint.h" + +namespace Trk{ + class SpacePoint; +} + +class SpacePointForSeed{ + public: + SpacePointForSeed() = delete; + SpacePointForSeed(const Trk::SpacePoint* sp) : m_spacepoint(sp) {}; + ~SpacePointForSeed() = default; + const Trk::SpacePoint* SpacePoint() const { + return m_spacepoint; + } + + private: + const Trk::SpacePoint * m_spacepoint; +}; + +#endif + diff --git a/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/SpacePointForSeedCollection.h b/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/SpacePointForSeedCollection.h new file mode 100755 index 0000000000000000000000000000000000000000..625b700ab5a9ed22a74f15c880ed1f7bc3035bb9 --- /dev/null +++ b/Tracker/TrackerRecEvent/TrackerSpacePoint/TrackerSpacePoint/SpacePointForSeedCollection.h @@ -0,0 +1,18 @@ + +#ifndef SPACEPOINTFORSEED_SPACEPOINTCOLLECTION_H +#define SPACEPOINTFORSEED_SPACEPOINTCOLLECTION_H + +// Base classes +#include "AthContainers/DataVector.h" +#include "GaudiKernel/DataObject.h" +//class SpacePoint; +#include "TrackerSpacePoint/SpacePointForSeed.h" + + + +typedef DataVector<SpacePointForSeed> SpacePointForSeedCollection; + +#include "AthenaKernel/CLASS_DEF.h" +CLASS_DEF(SpacePointForSeedCollection,1123314789,1) + +#endif // TRKSPACEPOINT_SPACEPOINTCOLLECTION_H diff --git a/Tracker/TrackerRecEvent/TrackerSpacePoint/src/SpacePointForSeed.cxx b/Tracker/TrackerRecEvent/TrackerSpacePoint/src/SpacePointForSeed.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0dee96b188712436c3247af1be051e20fe7836da --- /dev/null +++ b/Tracker/TrackerRecEvent/TrackerSpacePoint/src/SpacePointForSeed.cxx @@ -0,0 +1,6 @@ +//#include "TrackerSpacePoint/SpacePointForSeed.h" +//SpacePointForSeed::SpacePointForSeed(const Trk::SpacePoint* sp): m_spacepoint( sp) {} +//SpacePointForSeed::~SpacePointForSeed() {} +//const Trk::SpacePoint* SpacePointForSeed::SpacePoint() const { +// return m_spacepoint; +//} \ No newline at end of file diff --git a/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/CMakeLists.txt b/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6b02af22a8306bfe2605c1c4edc49cd0ac536abc --- /dev/null +++ b/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/CMakeLists.txt @@ -0,0 +1,37 @@ +################################################################################ +# Package: FaserSiSpacePointTool +################################################################################ + +# Declare the package name: +atlas_subdir( TruthSeededTrackFinderTool) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( PUBLIC + Control/AthenaBaseComps + Control/AthenaKernel + DetectorDescription/GeoPrimitives + Tracker/TrackerRecEvent/TrackerPrepRawData + DetectorDescription/Identifier + PRIVATE + GaudiKernel + Tracker/TrackerDetDescr/TrackerReadoutGeometry + Tracker/TrackerDetDescr/TrackerIdentifier + Tracker/TrackerRecEvent/TrackerSpacePoint + ) + +# External dependencies: +find_package( Eigen ) + +# Component(s) in the package: +atlas_add_library( TruthSeededTrackFinderToolLib + TruthSeededTrackFinderTool/*.h src/*.cxx src/*.h + PUBLIC_HEADERS TruthSeededTrackFinderTool + INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS} + LINK_LIBRARIES ${EIGEN_LIBRARIES} AthenaBaseComps AthenaKernel GeoPrimitives TrackerPrepRawData + PRIVATE_LINK_LIBRARIES GaudiKernel TrackerIdentifier TrackerReadoutGeometry TrackerSpacePoint ) + +atlas_add_component( TruthSeededTrackFinderTool + src/components/*.cxx + INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS} + LINK_LIBRARIES ${EIGEN_LIBRARIES} AthenaBaseComps AthenaKernel GeoPrimitives TrackerPrepRawData GaudiKernel TrackerIdentifier TrackerReadoutGeometry TrackerSpacePoint TruthSeededTrackFinderToolLib ) + diff --git a/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/TruthSeededTrackFinderTool/TruthSeededTrackFinderTool.h b/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/TruthSeededTrackFinderTool/TruthSeededTrackFinderTool.h new file mode 100644 index 0000000000000000000000000000000000000000..e08e5b1fa429f3bc2018ed7f10bc17db3e222934 --- /dev/null +++ b/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/TruthSeededTrackFinderTool/TruthSeededTrackFinderTool.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TruthSeededTrackFinderTool_H +#define TruthSeededTrackFinderTool_H + +#include "AthenaBaseComps/AthAlgTool.h" + +#include "AthenaKernel/SlotSpecificObj.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "TrackerPrepRawData/FaserSCT_ClusterCollection.h" +#include "TrkSpacePoint/SpacePoint.h" + +#include <mutex> +#include <string> + +class SpacePointCollection; +class SpacePointOverlapCollection; +namespace Tracker { + class TrackerCluster; +} + + +namespace Tracker +{ + + class TruthSeededTrackFinderTool : public AthAlgTool { + + public: + /// Constructor + TruthSeededTrackFinderTool(const std::string& type, const std::string& name, const IInterface* parent); + + /// Default destructor + virtual ~TruthSeededTrackFinderTool() = default; + + /// Return interfaceID + static const InterfaceID& interfaceID(); + + /// Initialize + virtual StatusCode initialize() override; + + /// Finalize + virtual StatusCode finalize() override; + + + /// Convert clusters to space points: SCT_Clusters -> SCT_SpacePoints + void fillSCT_SpacePointCollection(const SpacePointCollection* clusters1, + SpacePointCollection* clusters2) const; + + + private: + /// @name Cut parameters + //@{ + }; +} +#endif //TrackerSpacePointMakerTool_H diff --git a/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/src/TruthSeededTrackFinderTool.cxx b/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/src/TruthSeededTrackFinderTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..075440a4b066e55a032d759f8bba4f6dd43eda94 --- /dev/null +++ b/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/src/TruthSeededTrackFinderTool.cxx @@ -0,0 +1,56 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + */ + +#include "TruthSeededTrackFinderTool/TruthSeededTrackFinderTool.h" + +// Cluster and space point collections +#include "TrkSpacePoint/SpacePointCollection.h" +#include "TrkSpacePoint/SpacePointOverlapCollection.h" + +#include "TrackerSpacePoint/FaserSCT_SpacePoint.h" + +namespace Tracker +{ + +static const InterfaceID IID_ITruthSeededTrackFinderTool +("TruthSeededTrackFinderTool", 99490493, 0); + +const InterfaceID& TruthSeededTrackFinderTool::interfaceID() { + return IID_ITruthSeededTrackFinderTool; +} + +// Constructor with parameters: +TruthSeededTrackFinderTool::TruthSeededTrackFinderTool(const std::string& type, + const std::string& name, + const IInterface* parent) : + AthAlgTool(type, name, parent) { + declareInterface< TruthSeededTrackFinderTool>(this); + } +//-------------------------------------------------------------------------- +StatusCode TruthSeededTrackFinderTool::initialize() { + // Get the SCT Helper + return StatusCode::SUCCESS; +} +//-------------------------------------------------------------------------- +StatusCode TruthSeededTrackFinderTool::finalize() { + return StatusCode::SUCCESS; +} + +//-------------------------------------------------------------------------- +void TruthSeededTrackFinderTool::fillSCT_SpacePointCollection(const SpacePointCollection* clusters1, + SpacePointCollection* clusters2 + ) const { + SpacePointCollection::const_iterator clusters1Next = clusters1->begin(); + SpacePointCollection::const_iterator clusters1Finish = clusters1->end(); + + for (; clusters1Next!= clusters1Finish; ++clusters1Next){ + const Trk::SpacePoint* sp=&(**clusters1Finish); + clusters2->push_back(const_cast<Trk::SpacePoint*>(sp)); + } + + +} + + +} diff --git a/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/src/components/TruthSeededTrackFinderTool_entries.cxx b/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/src/components/TruthSeededTrackFinderTool_entries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ec655e68e07bd6c8ef8cd05965e2971c1f98e539 --- /dev/null +++ b/Tracker/TrackerRecTools/TruthSeededTrackFinderTool/src/components/TruthSeededTrackFinderTool_entries.cxx @@ -0,0 +1,4 @@ +#include "TruthSeededTrackFinderTool/TruthSeededTrackFinderTool.h" + +DECLARE_COMPONENT( Tracker::TruthSeededTrackFinderTool ) + diff --git a/Tracking/Acts/ActsInterop/ActsInterop/IdentityHelper.h b/Tracking/Acts/ActsInterop/ActsInterop/IdentityHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..6095fb5daba5a79c30c84c66bec90c1b54c84cfa --- /dev/null +++ b/Tracking/Acts/ActsInterop/ActsInterop/IdentityHelper.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#pragma once + +#include "TrackerReadoutGeometry/SiDetectorElement.h" +#include "TrackerIdentifier/FaserSCT_ID.h" +#include "FaserDetDescr/FaserDetectorID.h" + +namespace TrackerDD { + class SiDetectorElement; +} + +class SCT_ID; + +class IdentityHelper { + +public: + IdentityHelper(const TrackerDD::SiDetectorElement* detElem); + +private: + const TrackerDD::SiDetectorElement* m_elem; + + const FaserDetectorID* getSCTIDHelper() const; + + +}; diff --git a/Tracking/Acts/ActsInterop/ActsInterop/Logger.h b/Tracking/Acts/ActsInterop/ActsInterop/Logger.h new file mode 100644 index 0000000000000000000000000000000000000000..cf0b4a4f9af8ab364220d680882d3a01d9e9bfb2 --- /dev/null +++ b/Tracking/Acts/ActsInterop/ActsInterop/Logger.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#pragma once + +#include "Acts/Utilities/Logger.hpp" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/CommonMessaging.h" +#include "GaudiKernel/INamedInterface.h" + +#include <memory> + +#include <boost/optional.hpp> + +class ActsAthenaPrintPolicy final : public Acts::Logging::OutputPrintPolicy +{ +public: + + ActsAthenaPrintPolicy(std::shared_ptr<MsgStream> msg) : m_msg(msg) {} + + void + flush(const Acts::Logging::Level& lvl, const std::ostringstream& input); + +private: + std::shared_ptr<MsgStream> m_msg; +}; + +class ActsAthenaFilterPolicy final : public Acts::Logging::OutputFilterPolicy { +public: + ActsAthenaFilterPolicy(std::shared_ptr<MsgStream> msg) : m_msg(msg) {} + + //~AthenaFilterPolicy() = default; + + bool doPrint(const Acts::Logging::Level& lvl) const; + +private: + std::shared_ptr<MsgStream> m_msg; +}; + + +std::unique_ptr<const Acts::Logger> +makeActsAthenaLogger(IMessageSvc *svc, const std::string& name, + int level, boost::optional<std::string> parent_name); + +std::unique_ptr<const Acts::Logger> +makeActsAthenaLogger(const CommonMessagingBase* parent, const std::string& name); + +std::unique_ptr<const Acts::Logger> +makeActsAthenaLogger(const CommonMessagingBase* parent, const std::string& name, + boost::optional<std::string> parent_name); + +// problem: string literal does not play well with boost::optional +std::unique_ptr<const Acts::Logger> +makeActsAthenaLogger(const CommonMessagingBase* parent, const std::string& name, + const std::string& parent_name); + diff --git a/Tracking/Acts/ActsInterop/CMakeLists.txt b/Tracking/Acts/ActsInterop/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..41632f128825078ea3e7bc471117c1e35caae2fa --- /dev/null +++ b/Tracking/Acts/ActsInterop/CMakeLists.txt @@ -0,0 +1,21 @@ + +# Declare the package name: +atlas_subdir( ActsInterop ) + +# External dependencies: + +find_package(Acts COMPONENTS Core) + +# Component(s) in the package: +atlas_add_library( ActsInteropLib + src/*.cxx + PUBLIC_HEADERS ActsInterop + LINK_LIBRARIES + AthenaBaseComps + Identifier + FaserDetDescr + TrackerIdentifier + TrackerReadoutGeometry + ActsCore) + + diff --git a/Tracking/Acts/ActsInterop/src/IdentityHelper.cxx b/Tracking/Acts/ActsInterop/src/IdentityHelper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0343ebe68a6a005653628442a17ea52c689efb28 --- /dev/null +++ b/Tracking/Acts/ActsInterop/src/IdentityHelper.cxx @@ -0,0 +1,22 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "ActsInterop/IdentityHelper.h" + +#include "TrackerReadoutGeometry/SiDetectorElement.h" +#include "TrackerIdentifier/FaserSCT_ID.h" +#include "FaserDetDescr/FaserDetectorID.h" + + +IdentityHelper::IdentityHelper(const TrackerDD::SiDetectorElement *elem) + : m_elem(elem) +{} + + +const FaserDetectorID* +IdentityHelper::getSCTIDHelper() const +{ + return dynamic_cast<const FaserDetectorID*>(m_elem->getIdHelper()); +} + diff --git a/Tracking/Acts/ActsInterop/src/Logger.cxx b/Tracking/Acts/ActsInterop/src/Logger.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e40f9e47943baee1e5a33f7b34d535008661285e --- /dev/null +++ b/Tracking/Acts/ActsInterop/src/Logger.cxx @@ -0,0 +1,95 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "ActsInterop/Logger.h" + +#include "GaudiKernel/INamedInterface.h" +#include "GaudiKernel/CommonMessaging.h" +#include "GaudiKernel/IMessageSvc.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/CommonMessaging.h" + +#include "Acts/Utilities/Logger.hpp" + +#include <boost/optional.hpp> + +#include <iostream> +#include <string> + +namespace { + const std::array<MSG::Level, 6> athLevelVector{ + MSG::VERBOSE, + MSG::DEBUG, + MSG::INFO, + MSG::WARNING, + MSG::ERROR, + MSG::FATAL + }; +} + +void +ActsAthenaPrintPolicy::flush(const Acts::Logging::Level& lvl, const std::ostringstream& input) +{ + MSG::Level athLevel = athLevelVector[lvl]; + (*m_msg) << athLevel << input.str() << endmsg; +} + + +bool +ActsAthenaFilterPolicy::doPrint(const Acts::Logging::Level& lvl) const +{ + + MSG::Level athLevel = athLevelVector[lvl]; + return m_msg->level() <= athLevel; +} + + +std::unique_ptr<const Acts::Logger> +makeActsAthenaLogger(IMessageSvc *svc, const std::string& name, int level, boost::optional<std::string> parent_name) +{ + using namespace Acts::Logging; + + std::string full_name = name; + if (parent_name) { + full_name = *parent_name + "." + full_name; + } + + auto msg = std::make_shared<MsgStream>(svc, full_name); + msg->setLevel(level); + auto filter = std::make_unique<ActsAthenaFilterPolicy>(msg); + auto print = std::make_unique<ActsAthenaPrintPolicy>(msg); + return std::make_unique<const Acts::Logger>(std::move(print), std::move(filter)); +} + +std::unique_ptr<const Acts::Logger> +makeActsAthenaLogger(const CommonMessagingBase* parent, const std::string& name) +{ + // no explicit name, get from component + const INamedInterface *inamed = dynamic_cast<const INamedInterface*>(parent); + boost::optional<std::string> parent_name = boost::none; + // this will not prefix if parent is not named (which it should be) + if (inamed == nullptr) { + throw std::invalid_argument("parent needs to be INamedInterface"); + } + parent_name = inamed->name(); + return makeActsAthenaLogger(parent, name, parent_name); +} + +std::unique_ptr<const Acts::Logger> +makeActsAthenaLogger(const CommonMessagingBase* parent, const std::string& name, boost::optional<std::string> parent_name) +{ + int level = 0; + const INamedInterface *inamed = dynamic_cast<const INamedInterface*>(parent); + if (inamed != nullptr) { + level = parent->msg().level(); + } + return makeActsAthenaLogger(parent->msgSvc().get(), name, level, parent_name); +} + +std::unique_ptr<const Acts::Logger> +makeActsAthenaLogger(const CommonMessagingBase* parent, const std::string& name, const std::string& parent_name) +{ + + return makeActsAthenaLogger(parent, name, boost::optional<std::string>(parent_name)); +} diff --git a/Tracking/Acts/FaserActsGeometry/CMakeLists.txt b/Tracking/Acts/FaserActsGeometry/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..260732e2f948613aecae732b06a03fc6a9a1ef6e --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/CMakeLists.txt @@ -0,0 +1,85 @@ + +# Declare the package name: +atlas_subdir( FaserActsGeometry ) + +# External dependencies: +find_package( CLHEP ) +find_package( Eigen ) +find_package( Boost ) + +find_package( Acts COMPONENTS Core ) + +atlas_add_library( FaserActsGeometryLib + FaserActsGeometry/FaserActsGeometryContext.h + FaserActsGeometry/FaserActsDetectorElement.h + src/FaserActsAlignmentStore.cxx + src/FaserActsDetectorElement.cxx + src/FaserActsLayerBuilder.cxx + src/CuboidVolumeBuilder.cxx + src/util/*.cxx + PUBLIC_HEADERS FaserActsGeometry + INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${BOOST_INCLUDE_DIRS} + LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} ${BOOST_LIBRARIES} + TrackerIdentifier + TrackerReadoutGeometry + ActsInteropLib + FaserActsGeometryInterfacesLib + AthenaKernel + ActsCore + MagFieldInterfaces + MagFieldElements + MagFieldConditions + TrackerRawData + TrackerSimData + GeneratorObjects + TrackerSimEvent + TrackerSpacePoint + TrackerIdentifier + TrackerPrepRawData + TrkSpacePoint + ) + + +# Component(s) in the package: +atlas_add_component( FaserActsGeometry +##src/*.cxx + src/FaserActsTrackingGeometrySvc.cxx + src/FaserActsTrackingGeometryTool.cxx + src/FaserActsWriteTrackingGeometry.cxx + src/FaserActsObjWriterTool.cxx + src/FaserActsExtrapolationAlg.cxx + src/FaserActsExtrapolationTool.cxx + src/FaserActsPropStepRootWriterSvc.cxx + src/FaserActsAlignmentCondAlg.cxx + src/NominalAlignmentCondAlg.cxx +#src/FaserActsKalmanFilterAlg.cxx + src/components/*.cxx + PUBLIC_HEADERS FaserActsGeometry + INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${BOOST_INCLUDE_DIRS} + LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} ${BOOST_LIBRARIES} + EventInfo + AthenaBaseComps + GaudiKernel + FaserActsGeometryLib + ActsInteropLib + FaserActsGeometryInterfacesLib + ActsCore + MagFieldInterfaces + MagFieldElements + MagFieldConditions + TrackerRawData + TrackerSimData + GeneratorObjects + TrackerSimEvent + TrackerSpacePoint + TrackerIdentifier + TrackerPrepRawData + TrkSpacePoint + + ) + +# Install files from the package: +atlas_install_headers( FaserActsGeometry ) +atlas_install_python_modules( python/*.py ) +atlas_install_scripts( test/*.py ) + diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/CuboidVolumeBuilder.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/CuboidVolumeBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..44170eb23fe9152f2786fee8e7d06ce78fee5a5b --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/CuboidVolumeBuilder.h @@ -0,0 +1,184 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2018 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <functional> +#include <memory> +#include <vector> +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Geometry/ITrackingVolumeBuilder.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Geometry/GenericApproachDescriptor.hpp" + +namespace Acts{ + +class TrackingVolume; +class VolumeBounds; +class RectangleBounds; +class ISurfaceMaterial; +class IVolumeMaterial; +class DetectorElementBase; +class PlaneSurface; +class Surface; + +} + +namespace FaserActs{ + +/// @brief This class builds a box detector with a configurable amount of +/// surfaces in it. The idea is to allow a quick configuration of a detector for +/// mostly unit test applications. Therefore this class does not demand to be a +/// universal construction factory but a raw first draft of the idea of factory +/// that may be extended in the future. +class CuboidVolumeBuilder : public Acts::ITrackingVolumeBuilder { + public: + /// @brief This struct stores the data for the construction of a single + /// PlaneSurface + struct SurfaceConfig { + // Center position + Acts::Vector3D position; + // Rotation + Acts::RotationMatrix3D rotation = Acts::RotationMatrix3D::Identity(); + // Bounds + std::shared_ptr<const Acts::RectangleBounds> rBounds = nullptr; + // Attached material + std::shared_ptr<const Acts::ISurfaceMaterial> surMat = nullptr; + // Thickness + double thickness = 0.; + // Constructor function for optional detector elements + // Arguments are transform, rectangle bounds and thickness. + std::function<Acts::DetectorElementBase*(std::shared_ptr<const Acts::Transform3D>, + std::shared_ptr<const Acts::RectangleBounds>, + double)> + detElementConstructor; + }; + + /// @brief This struct stores the data for the construction of a PlaneLayer + /// that has a single PlaneSurface encapsulated or array of surfaces + struct LayerConfig { + // Configuration of the surface + SurfaceConfig surfaceCfg; + // Encapsulated surface + std::shared_ptr<const Acts::PlaneSurface> surface = nullptr; + std::vector<std::shared_ptr<const Acts::Surface>> surfaces; + // Boolean flag if layer is active + bool active = false; + // Bins in X direction + size_t binsX = 1; + // Bins in Y direction + size_t binsY = 1; + // The approach descriptor + Acts::GenericApproachDescriptor *approachDescriptor = nullptr; + }; + + /// @brief This struct stores the data for the construction of a cuboid + /// TrackingVolume with a given number of PlaneLayers + struct VolumeConfig { + // Center position + Acts::Vector3D position; + // Lengths in x,y,z + Acts::Vector3D length; + // Configurations of its layers + std::vector<LayerConfig> layerCfg; + // Stored layers + std::vector<std::shared_ptr<const Acts::Layer>> layers; + // Configurations of confined volumes + std::vector<VolumeConfig> volumeCfg; + // Stored confined volumes + std::vector<std::shared_ptr<Acts::TrackingVolume>> trackingVolumes; + // Name of the volume + std::string name = "Volume"; + // Material + std::shared_ptr<const Acts::IVolumeMaterial> volumeMaterial = nullptr; + }; + + /// @brief This struct stores the configuration of the tracking geometry + struct Config { + // Center position + Acts::Vector3D position = Acts::Vector3D(0., 0., 0.); + // Length in x,y,z + Acts::Vector3D length = Acts::Vector3D(0., 0., 0.); + // Configuration of its volumes + std::vector<VolumeConfig> volumeCfg = {}; + }; + + /// @brief Default constructor without a configuration + CuboidVolumeBuilder() = default; + + /// @brief Constructor that sets the config + /// + /// @param [in] cfg Configuration of the detector + CuboidVolumeBuilder(Config& cfg) : m_cfg(cfg) {} + + /// @brief Setter of the config + /// + /// @param [in] cfg Configuration that is set + void setConfig(Config& cfg) { m_cfg = cfg; } + + /// @brief This function creates a surface with a given configuration. A + /// detector element is attached if the template parameter is non-void. + /// + /// @param [in] gctx the geometry context for this building + /// @param [in] cfg Configuration of the surface + /// + /// @return Pointer to the created surface + std::shared_ptr<const Acts::PlaneSurface> buildSurface( + const Acts::GeometryContext& gctx, const SurfaceConfig& cfg) const; + + /// @brief This function creates a layer with a surface encaspulated with a + /// given configuration. The surface gets a detector element attached if the + /// template parameter is non-void. + /// + /// @param [in] gctx the geometry context for this building + /// @param [in, out] cfg Configuration of the layer and the surface + /// + /// @return Pointer to the created layer + std::shared_ptr<const Acts::Layer> buildLayer(const Acts::GeometryContext& gctx, + LayerConfig& cfg) const; + + /// @brief This function creates a TrackingVolume with a configurable number + /// of layers and surfaces. Each surface gets a detector element attached if + /// the template parameter is non-void. + /// + /// @param [in] gctx the geometry context for this building + /// @param [in, out] cfg Configuration of the TrackingVolume + /// + /// @return Pointer to the created TrackingVolume + std::shared_ptr<Acts::TrackingVolume> buildVolume(const Acts::GeometryContext& gctx, + VolumeConfig& cfg) const; + + /// @brief This function evaluates the minimum and maximum of the binning as + /// given by the configurations of the surfaces and layers. The ordering + /// depends on the binning value specified in the configuration of the volume. + /// + /// @param [in] gctx the geometry context for this building + /// @param [in] cfg Container with the given surfaces and layers + /// + /// @return Pair containing the minimum and maximum along the binning + /// direction + std::pair<double, double> binningRange(const Acts::GeometryContext& gctx, + const VolumeConfig& cfg) const; + + /// @brief This function builds a world TrackingVolume based on a given + /// configuration + /// + /// @param [in] gctx the geometry context for this building + /// + /// @return Pointer to the created TrackingGeometry + std::shared_ptr<Acts::TrackingVolume> trackingVolume( + const Acts::GeometryContext& gctx, + std::shared_ptr<const Acts::TrackingVolume> /*unused*/, + std::shared_ptr<const Acts::VolumeBounds> /*unused*/) const override; + + private: + /// Configuration of the world volume + Config m_cfg; +}; + +} // namespace Acts diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FASERMagneticFieldWrapper.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FASERMagneticFieldWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..b6700c291ca5a08e0ad703f8015a4bc255568319 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FASERMagneticFieldWrapper.h @@ -0,0 +1,70 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef FASERACTSGEOMETRY_FASERMAGNETICFIELDWRAPPER_H +#define FASERACTSGEOMETRY_FASERMAGNETICFIELDWRAPPER_H + +#include "GaudiKernel/PhysicalConstants.h" +#include "MagFieldConditions/FaserFieldCacheCondObj.h" +#include "MagFieldElements/FaserFieldCache.h" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Units.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" + +class FASERMagneticFieldWrapper +{ + + + public: + + struct Cache { + + Cache(std::reference_wrapper<const Acts::MagneticFieldContext> mctx) { + std::any_cast<const FaserFieldCacheCondObj*>(mctx)->getInitializedCache(fieldCache); + } + + MagField::FaserFieldCache fieldCache; + }; + + + FASERMagneticFieldWrapper() = default; + + Acts::Vector3D + getField(const Acts::Vector3D& pos, Cache& cache) const + { + double pos0[]{pos.x(), pos.y(), pos.z()}; + double bfield0[]{0., 0., 0.}; + cache.fieldCache.getField(pos0, bfield0); + Acts::Vector3D bfield(bfield0[0], bfield0[1], bfield0[2]); + + bfield *= m_bFieldUnit; // kT -> T; + + return bfield; + } + + Acts::Vector3D + getFieldGradient(const Acts::Vector3D& position, Acts::ActsMatrixD<3, 3>& gradient, Cache& cache) const + { + double position0[]{position.x(), position.y(), position.z()}; + double bfield0[]{0., 0., 0.}; + double grad[9]; + cache.fieldCache.getField(position0, bfield0, grad); + Acts::Vector3D bfield(bfield0[0], bfield0[1], bfield0[2]); + Acts::ActsMatrixD<3, 3> tempGrad; + tempGrad << grad[0], grad[1], grad[2], grad[3], grad[4], grad[5], grad[6], grad[7], grad[8]; + gradient = tempGrad; + + bfield *= m_bFieldUnit; // kT -> T; + gradient *= m_bFieldUnit; + + return bfield; + } + + + private: + const double m_bFieldUnit = 1000.*Acts::UnitConstants::T; +}; + + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsAlignmentCondAlg.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsAlignmentCondAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..1a1d56fb174e7c3938009043353066fa1af7e2f1 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsAlignmentCondAlg.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSALIGNMENTCONDALG_H +#define FASERACTSGEOMETRY_ACTSALIGNMENTCONDALG_H + +// ATHENA +#include "AthenaBaseComps/AthAlgorithm.h" +#include "EventInfo/EventInfo.h" // ReadHandleKey wants complete type +#include "GaudiKernel/ServiceHandle.h" +#include "StoreGate/WriteCondHandleKey.h" + +// PACKAGE + +// STL +#include <string> + +namespace TrackerDD { +class SCT_DetectorManager; +} + +class EventInfo; +class ICondSvc; +class StoreGateSvc; +class IFaserActsTrackingGeometrySvc; +class FaserActsAlignmentStore; +class GeoAlignableTransform; +class FaserActsGeometryContext; +class GeoAlignmentStore; + +class FaserActsAlignmentCondAlg : public AthAlgorithm { + +public: + FaserActsAlignmentCondAlg(const std::string &name, ISvcLocator *pSvcLocator); + virtual ~FaserActsAlignmentCondAlg(); + + virtual bool isClonable() const override { return true; } + + virtual StatusCode initialize() override; + virtual StatusCode execute() override; + virtual StatusCode finalize() override; + +private: + + SG::ReadCondHandleKey<GeoAlignmentStore> m_sctAlignStoreReadKey{ + this, "SCTAlignStoreReadKey", "SCTAlignmentStore", ""}; + + SG::WriteCondHandleKey<FaserActsGeometryContext> m_wchk{ + this, "FaserActsAlignmentKey", "FaserActsAlignment", "cond handle key"}; + + ServiceHandle<ICondSvc> m_cs; + ServiceHandle<IFaserActsTrackingGeometrySvc> m_trackingGeometrySvc; + + const TrackerDD::SCT_DetectorManager *p_SCTManager; +}; + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsAlignmentStore.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsAlignmentStore.h new file mode 100644 index 0000000000000000000000000000000000000000..5566b42c71f6dd052a939bcfa47b50c35796a811 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsAlignmentStore.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSALIGNMENTSTORE_H +#define FASERACTSGEOMETRY_ACTSALIGNMENTSTORE_H + +#include "GeoModelUtilities/GeoAlignmentStore.h" +#include "GeoModelUtilities/TransformMap.h" +#include "AthenaKernel/CLASS_DEF.h" +#include "AthenaKernel/CondCont.h" + +#include "Acts/Utilities/Definitions.hpp" + +#include <stdexcept> + +class FaserActsDetectorElement; + +class FaserActsAlignmentStore : public GeoAlignmentStore +{ + public: + FaserActsAlignmentStore() {} + FaserActsAlignmentStore(const GeoAlignmentStore& gas); + + void setTransform(const FaserActsDetectorElement* key, const Acts::Transform3D&); + const Acts::Transform3D* getTransform(const FaserActsDetectorElement* key) const; + + void append(const GeoAlignmentStore& gas); + + private: + TransformMap<FaserActsDetectorElement, Acts::Transform3D> m_transforms; +}; + +CLASS_DEF(FaserActsAlignmentStore, 58650257, 1) +CONDCONT_DEF( FaserActsAlignmentStore , 124731561 ); + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsDetectorElement.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsDetectorElement.h new file mode 100644 index 0000000000000000000000000000000000000000..9d985df94d31f2afdad19757126114d605a06291 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsDetectorElement.h @@ -0,0 +1,100 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSDETECTORELEMENT_H +#define FASERACTSGEOMETRY_ACTSDETECTORELEMENT_H + +// ATHENA INCLUDES +#include "TrackerIdentifier/FaserSCT_ID.h" +#include "TrackerReadoutGeometry/SiDetectorElement.h" + +// ACTS +#include "Acts/Geometry/DetectorElementBase.hpp" +#include "Acts/Geometry/GeometryContext.hpp" + +// STL +#include <mutex> +#include <iostream> + +// BOOST +#include <boost/variant.hpp> + +namespace Acts { + class SurfaceBounds; +} + +class FaserActsTrackingGeometrySvc; +class FaserActsAlignmentStore; + +class IdentityHelper; + +/// @class FaserActsDetectorElement +/// +class FaserActsDetectorElement : public Acts::DetectorElementBase +{ +public: + enum class Subdetector { SCT }; + + FaserActsDetectorElement(const TrackerDD::SiDetectorElement* detElem); + + /// Destructor + virtual ~FaserActsDetectorElement() {} + + /// Identifier + Identifier + identify() const; + + void + storeTransform(FaserActsAlignmentStore* gas) const; + virtual const Acts::Transform3D & + transform(const Acts::GeometryContext &gctx) const final override; + + + /// Return surface associated with this identifier, which should come from the + virtual const Acts::Surface& + surface() const final override; + + /// Returns the thickness of the module + virtual double + thickness() const final override; + + IdentityHelper identityHelper() const; + + bool operator==(const FaserActsDetectorElement& otherElem) { + return m_detElement->identify() == otherElem.identify(); + } + +private: + + /// For silicon detectors it is calulated from GM, and stored. Thus the method + /// is not const. The store is mutexed. + const Acts::Transform3D& + getDefaultTransformMutexed() const; + + /// Detector element + const TrackerDD::SiDetectorElement* m_detElement; + /// Boundaries of the detector element + std::shared_ptr<const Acts::SurfaceBounds> m_bounds; + /// Thickness of this detector element + double m_thickness; + /// Corresponding Surface + std::shared_ptr<const Acts::Surface> m_surface; + std::vector<std::shared_ptr<const Acts::Surface>> m_surfaces; + + // this is pretty much only used single threaded, so + // the mutex does not hurt + mutable std::mutex m_cacheMutex; + mutable std::shared_ptr<const Acts::Transform3D> m_defTransform; + + const FaserActsTrackingGeometrySvc* m_trackingGeometrySvc; + + Identifier m_explicitIdentifier; + + // this is threadsafe! + //mutable Gaudi::Hive::ContextSpecificData<Acts::Transform3D> m_ctxSpecificTransform; + + +}; + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationAlg.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationAlg.h new file mode 100755 index 0000000000000000000000000000000000000000..56c903c07c87c7b2054b4a7fadd840b906cb8445 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationAlg.h @@ -0,0 +1,75 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSEXTRAPOLATIONALG_H +#define FASERACTSGEOMETRY_ACTSEXTRAPOLATIONALG_H + +// ATHENA +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "GaudiKernel/ServiceHandle.h" +#include "Gaudi/Property.h" /*no forward decl: typedef*/ +#include "GaudiKernel/ISvcLocator.h" + +// ACTS +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Geometry/GeometryID.hpp" +#include "Acts/Utilities/Helpers.hpp" + +// PACKAGE +#include "MagFieldConditions/FaserFieldCacheCondObj.h" +#include "MagFieldElements/FaserFieldCache.h" + +// STL +#include <memory> +#include <vector> +#include <fstream> +#include <mutex> + + +namespace Acts { + class TrackingGeometry; + + namespace detail { + class Step; + } +} + +//class IFaserActsMaterialTrackWriterSvc; + +class EventContext; +class IAthRNGSvc; +class IFaserActsExtrapolationTool; +class IFaserActsPropStepRootWriterSvc; + +class FaserActsExtrapolationAlg : public AthReentrantAlgorithm { +public: + FaserActsExtrapolationAlg (const std::string& name, ISvcLocator* pSvcLocator); + StatusCode initialize() override; + StatusCode execute(const EventContext& ctx) const override; + StatusCode finalize() override; + +private: + ServiceHandle<IFaserActsPropStepRootWriterSvc> m_propStepWriterSvc; + ServiceHandle<IAthRNGSvc> m_rndmGenSvc; + + ToolHandle<IFaserActsExtrapolationTool> m_extrapolationTool{this, "ExtrapolationTool", "FaserActsExtrapolationTool"}; + + // poor-mans Particle Gun is included here right now + Gaudi::Property<std::vector<double>> m_etaRange{this, "EtaRange", {4, 10}, ""}; + Gaudi::Property<std::vector<double>> m_ptRange{this, "PtRange", {0.1, 1000}, ""}; + Gaudi::Property<size_t> m_nParticlePerEvent{this, "NParticlesPerEvent", 1, "The number of particles per event"}; + + // this does not work right now + //Gaudi::Property<bool> m_writeMaterialTracks{this, "WriteMaterialTracks", false, ""}; + //ServiceHandle<IFaserActsMaterialTrackWriterSvc> m_materialTrackWriterSvc; + + mutable std::mutex m_writeMutex{}; + mutable std::unique_ptr<std::ofstream> m_objOut; + mutable size_t m_objVtxCount{0}; + + void writeStepsObj(std::vector<Acts::detail::Step> steps) const; + +}; + +#endif // ActsGeometry_ActsExtrapolation_h diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationTool.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationTool.h new file mode 100644 index 0000000000000000000000000000000000000000..24498ac803be5dac0147c88ca0a9de6eb57f9f40 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsExtrapolationTool.h @@ -0,0 +1,143 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSEXTRAPOLATIONTOOL_H +#define FASERACTSGEOMETRY_ACTSEXTRAPOLATIONTOOL_H + +// ATHENA +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/ServiceHandle.h" +#include "Gaudi/Property.h" +#include "GaudiKernel/EventContext.h" + +// Need to include this early; otherwise, we run into errors with +// ReferenceWrapperAnyCompat in clang builds due the is_constructable +// specialization defined there getting implicitly instantiated earlier. +#include "Acts/Propagator/Propagator.hpp" + + +// PACKAGE +#include "FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h" +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "MagFieldConditions/FaserFieldCacheCondObj.h" +#include "MagFieldElements/FaserFieldCache.h" +#include "FaserActsGeometry/FASERMagneticFieldWrapper.h" + +// ACTS +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/detail/SteppingLogger.hpp" +#include "Acts/Propagator/Navigator.hpp" +#include "Acts/Propagator/DebugOutputActor.hpp" +#include "Acts/Propagator/StandardAborters.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/Utilities/Result.hpp" +#include "Acts/Utilities/Units.hpp" +#include "Acts/Utilities/Helpers.hpp" + +namespace Acts { + class Surface; + class BoundaryCheck; + class Logger; +} + +namespace ActsExtrapolationDetail { + class VariantPropagator; +} + + + +class FaserActsExtrapolationTool : public extends<AthAlgTool, IFaserActsExtrapolationTool> +{ + +public: + virtual StatusCode initialize() override; + + FaserActsExtrapolationTool(const std::string& type, const std::string& name, + const IInterface* parent); + + ~FaserActsExtrapolationTool(); + +private: + // set up options for propagation + using SteppingLogger = Acts::detail::SteppingLogger; + using DebugOutput = Acts::DebugOutputActor; + using EndOfWorld = Acts::EndOfWorldReached; + using ResultType = Acts::Result<std::pair<ActsPropagationOutput, + DebugOutput::result_type>>; + +public: + virtual + ActsPropagationOutput + propagationSteps(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + Acts::NavigationDirection navDir = Acts::forward, + double pathLimit = std::numeric_limits<double>::max()) const override; + + virtual + std::unique_ptr<const Acts::CurvilinearParameters> + propagate(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + Acts::NavigationDirection navDir = Acts::forward, + double pathLimit = std::numeric_limits<double>::max()) const override; + + virtual + ActsPropagationOutput + propagationSteps(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + const Acts::Surface& target, + Acts::NavigationDirection navDir = Acts::forward, + double pathLimit = std::numeric_limits<double>::max()) const override; + + virtual + std::unique_ptr<const Acts::BoundParameters> + propagate(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + const Acts::Surface& target, + Acts::NavigationDirection navDir = Acts::forward, + double pathLimit = std::numeric_limits<double>::max()) const override; + + virtual + const IFaserActsTrackingGeometryTool* + trackingGeometryTool() const override + { + return m_trackingGeometryTool.get(); + } + + virtual + Acts::MagneticFieldContext + getMagneticFieldContext(const EventContext& ctx) const override; + + + +private: + + std::unique_ptr<ActsExtrapolationDetail::VariantPropagator> m_varProp; + + std::unique_ptr<const Acts::Logger> m_logger{nullptr}; + + // Read handle for conditions object to get the field cache + SG::ReadCondHandleKey<FaserFieldCacheCondObj> m_fieldCondObjInputKey {this, "FaserFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"}; + + ToolHandle<IFaserActsTrackingGeometryTool> m_trackingGeometryTool{this, "TrackingGeometryTool", "FaserActsTrackingGeometryTool"}; + + Gaudi::Property<std::string> m_fieldMode{this, "FieldMode", "FASER"}; + Gaudi::Property<std::vector<double>> m_constantFieldVector{this, "ConstantFieldVector", {0, 0, 0}}; + + Gaudi::Property<double> m_ptLoopers{this, "PtLoopers", 300, "PT loop protection threshold. Will be converted to Acts MeV unit"}; + + Gaudi::Property<double> m_maxStepSize{this, "MaxStepSize", 10, "Max step size in Acts m unit"}; + + // Material inteaction option + Gaudi::Property<bool> m_interactionMultiScatering{this, "InteractionMultiScatering", false, "Whether to consider multiple scattering in the interactor"}; + Gaudi::Property<bool> m_interactionEloss{this, "InteractionEloss", false, "Whether to consider energy loss in the interactor"}; + Gaudi::Property<bool> m_interactionRecord{this, "InteractionRecord", false, "Whether to record all material interactions"}; + +}; + + + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsGeometryContext.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsGeometryContext.h new file mode 100644 index 0000000000000000000000000000000000000000..5ff79e737b8ee67c215c647981c3c9a060eca73a --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsGeometryContext.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSGEOMETRYCONTEXT_H +#define FASERACTSGEOMETRY_ACTSGEOMETRYCONTEXT_H + +#include "FaserActsGeometry/FaserActsAlignmentStore.h" + +#include "AthenaKernel/CLASS_DEF.h" +#include "AthenaKernel/CondCont.h" + +#include "Acts/Geometry/GeometryContext.hpp" + +#include <memory> + +struct FaserActsGeometryContext { + + bool construction{false}; + + std::unique_ptr<const FaserActsAlignmentStore> ownedAlignmentStore{nullptr}; + + const FaserActsAlignmentStore* alignmentStore{nullptr}; + + Acts::GeometryContext + any() const + { + return {this}; + } +}; + +CLASS_DEF(FaserActsGeometryContext, 123437909, 1) +CONDCONT_DEF( FaserActsGeometryContext , 27906711 ); + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..69843abf30e7ec18f6201f4686c5f3525177e4c2 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsLayerBuilder.h @@ -0,0 +1,130 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_FASEERACTSLAYERBUILDER_H +#define FASERACTSGEOMETRY_FASEERACTSLAYERBUILDER_H + +// PACKAGE +#include "FaserActsGeometry/FaserActsDetectorElement.h" + +// ATHENA +#include "TrackerReadoutGeometry/SiDetectorElement.h" + +// ACTS +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Geometry/ILayerBuilder.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Units.hpp" +#include "FaserActsGeometry/CuboidVolumeBuilder.h" + +using namespace Acts::UnitLiterals; + +class FaserActsTrackingGeomtrySvc; + +namespace TrackerDD { + class SCT_DetectorManager; +} + +namespace Acts { +class Surface; +class LayerCreator; +} + +/// @class FaserActsLayerBuilder +class FaserActsLayerBuilder +{ +public: + /// @struct Config + /// nested configuration struct for steering of the layer builder + + struct Config + { + /// string based identification + std::string configurationName = "undefined"; + FaserActsDetectorElement::Subdetector subdetector + = FaserActsDetectorElement::Subdetector::SCT; + const TrackerDD::SCT_DetectorManager* mng; + std::shared_ptr<const Acts::LayerCreator> layerCreator = nullptr; + std::shared_ptr<std::vector<std::shared_ptr<const FaserActsDetectorElement>>> elementStore; + int station; + int plane; + }; + + /// Constructor + /// @param cfg is the configuration struct + /// @param logger the local logging instance + FaserActsLayerBuilder(const Config& cfg, + std::unique_ptr<const Acts::Logger> logger + = Acts::getDefaultLogger("GMLayBldr", Acts::Logging::INFO)) + : m_logger(std::move(logger)) + { + // std::cout << "GMLB construct" << std::endl; + m_cfg = cfg; + } + + /// Destructor + ~FaserActsLayerBuilder() {} + + /// set the configuration object + /// @param cfg is the configuration struct + void + setConfiguration(const Config& cfg); + + /// get the configuration object + // Config + // getConfiguration() const; + + FaserActsLayerBuilder::Config + getConfiguration() const + { + return m_cfg; + } + + const std::string& + identification() const + { + return m_cfg.configurationName; + } + + /// set logging instance + void + setLogger(std::unique_ptr<const Acts::Logger> logger); + + FaserActs::CuboidVolumeBuilder::Config + buildVolume(const Acts::GeometryContext&); + + void + buildLayers(const Acts::GeometryContext&, std::vector<std::shared_ptr<const Acts::Surface> >&, FaserActs::CuboidVolumeBuilder::LayerConfig&, FaserActs::CuboidVolumeBuilder::SurfaceConfig&); + +private: + double m_ModuleWidth; + double m_ModuleLength; + /// configruation object + Config m_cfg; + Acts::Vector3D m_worldDimensions = { 400.0_mm, 400.0_mm, 6000.0_mm }; + Acts::Vector3D m_worldCenter = {0.0, 0.0, 1276.0_mm}; + Acts::Vector3D m_trackerDimensions = { 400.0_mm, 400.0_mm, 1200.0_mm }; + + /// Private access to the logger + const Acts::Logger& + logger() const + { + return *m_logger; + } + + std::vector<std::shared_ptr<const FaserActsDetectorElement>> + getDetectorElements() const; + + /// logging instance + std::unique_ptr<const Acts::Logger> m_logger; + + ///// @todo make clear where the FaserActsDetectorElement lives + //std::vector<std::shared_ptr<const FaserActsDetectorElement>> m_elementStore; + +}; + + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsObjWriterTool.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsObjWriterTool.h new file mode 100644 index 0000000000000000000000000000000000000000..94aa12fe4fb99f4eb1bb94e27066863cb914eeee --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsObjWriterTool.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSOBJWRITERTOOL_H +#define FASERACTSGEOMETRY_ACTSOBJWRITERTOOL_H + +#include <vector> + +#include "GaudiKernel/IAlgTool.h" +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/IInterface.h" +#include "Gaudi/Property.h" /*no forward decl: typedef*/ +#include "FaserActsGeometry/FaserActsGeometryContext.h" + + +namespace Acts { + +class TrackingGeometry; +class ObjTrackingGeometryWriter; + +} + +static const InterfaceID IID_FaserActsObjWriterTool("FaserActsObjWriterTool", 1, 0); + +class FaserActsObjWriterTool : public AthAlgTool +{ + +public: + + static const InterfaceID& interfaceID(){return IID_FaserActsObjWriterTool;} + + StatusCode initialize() override; + + FaserActsObjWriterTool(const std::string& type, const std::string& name, + const IInterface* parent); + + void + write(const FaserActsGeometryContext& gctx, const Acts::TrackingGeometry&) const; + +private: + + Gaudi::Property<std::string> m_outputDirectory{this, "OutputDirectory", ".", ""}; + Gaudi::Property<std::vector<std::string>> m_subDetectors{this, "SubDetectors", {}, ""}; + + std::shared_ptr<Acts::ObjTrackingGeometryWriter> m_tgObjWriter; + + +}; + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsPropStepRootWriterSvc.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsPropStepRootWriterSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..eeca580eb76f82fced49477a8ca1067cbea8d472 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsPropStepRootWriterSvc.h @@ -0,0 +1,87 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSPROPSTEPROOTWRITERSVC_H +#define FASERACTSGEOMETRY_ACTSPROPSTEPROOTWRITERSVC_H + +#include "AthenaBaseComps/AthService.h" +#include "GaudiKernel/IInterface.h" +#include "Gaudi/Property.h" /*no forward decl: typedef*/ + +#include "FaserActsGeometry/IFaserActsPropStepRootWriterSvc.h" + +#include "Acts/EventData/TrackParameters.hpp" + +#include <vector> +#include <deque> +#include <mutex> +#include <thread> +#include <atomic> + +template <typename T> +class RootPropStepWriter; + +namespace Acts { + +template <class> +class ExtrapolationCell; + +} + +class TFile; +class TTree; + + +class FaserActsPropStepRootWriterSvc : public extends<AthService, IFaserActsPropStepRootWriterSvc> { +public: + + virtual StatusCode initialize() override; + virtual StatusCode finalize() override; + + FaserActsPropStepRootWriterSvc( const std::string& name, ISvcLocator* svc ); + + using StepVector = std::vector<Acts::detail::Step>; + + void + write(const StepVector& steps) override; + +private: + using queue_item_t = std::pair<size_t, StepVector>; + + //std::shared_ptr<RootPropStepWriter<Acts::TrackParameters>> m_rootEccWriter; + std::deque<queue_item_t> m_queue; + std::mutex m_writeMutex; + std::thread m_writeThread; + std::atomic<bool> m_doEnd; + + void writeThread(); + void doWrite(const StepVector& steps, size_t evtNum); + void end(); + + // jobOptions properties + Gaudi::Property<std::string> m_filePath{this, "FilePath", "propsteps.root", "Output root file for charged particle"}; + Gaudi::Property<std::string> m_treeName{this, "TreeName", "propsteps", ""}; + //Gaudi::Property<bool> m_writeBoundary{this, "WriteBoundary", true, ""}; + //Gaudi::Property<bool> m_writeMaterial{this, "WriteMaterial", true, ""}; + //Gaudi::Property<bool> m_writeSensitive{this, "WriteSensitive", true, ""}; + //Gaudi::Property<bool> m_writePassive{this, "WritePassive", true, ""}; + + // root branch storage + TFile* m_outputFile; ///< the output file + TTree* m_outputTree; ///< the output tree + int m_eventNum; + std::vector<float> m_s_pX; ///< global position x of the step + std::vector<float> m_s_pY; ///< global position y of the step + std::vector<float> m_s_pZ; ///< global position z of the step + std::vector<float> m_s_pR; ///< global position z of the step + std::vector<int> m_s_volumeID; ///< volume identification + std::vector<int> m_s_boundaryID; ///< boundary identification + std::vector<int> m_s_layerID; ///< layer identification + std::vector<int> m_s_approachID; ///< approach identification + std::vector<int> m_s_sensitiveID; ///< sensitive identification + +}; + + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometrySvc.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometrySvc.h new file mode 100644 index 0000000000000000000000000000000000000000..28ef43bd3e51d8ecbb307182d25e9984f1756849 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometrySvc.h @@ -0,0 +1,82 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSTRACKINGGEOMETRYSVC_H +#define FASERACTSGEOMETRY_ACTSTRACKINGGEOMETRYSVC_H + +// ATHENA +#include "AthenaBaseComps/AthService.h" +#include "StoreGate/StoreGateSvc.h" +#include "GaudiKernel/EventContext.h" + +// ACTS +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Units.hpp" + +// PACKAGE +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h" + +// STL +#include <map> + +using namespace Acts::UnitLiterals; + +namespace TrackerDD { + class SCT_DetectorManager; +} + +class FaserActsAlignmentStore; + +class FaserActsDetectorElement; + +namespace Acts { + +class TrackingGeometry; +class CylinderVolumeHelper; +class ITrackingVolumeBuilder; + +class GeometryID; +class BinnedSurfaceMaterial; + +} + + +class FaserActsTrackingGeometrySvc : public extends<AthService, IFaserActsTrackingGeometrySvc> { +public: + + StatusCode initialize() override; + //virtual StatusCode finalize() override; + + FaserActsTrackingGeometrySvc( const std::string& name, ISvcLocator* pSvcLocator ); + + std::shared_ptr<const Acts::TrackingGeometry> + trackingGeometry() override; + + void + populateAlignmentStore(FaserActsAlignmentStore *store) const override; + + const FaserActsAlignmentStore* + getNominalAlignmentStore() const override; + +private: + std::shared_ptr<const Acts::ITrackingVolumeBuilder> + makeVolumeBuilder(const Acts::GeometryContext& gctx, const TrackerDD::SCT_DetectorManager* manager); + + ServiceHandle<StoreGateSvc> m_detStore; + const TrackerDD::SCT_DetectorManager* p_SCTManager; + + std::shared_ptr<std::vector<std::shared_ptr<const FaserActsDetectorElement>>> m_elementStore; + std::shared_ptr<const Acts::TrackingGeometry> m_trackingGeometry; + + std::unique_ptr<const FaserActsAlignmentStore> m_nominalAlignmentStore{nullptr}; + + Gaudi::Property<bool> m_useMaterialMap{this, "UseMaterialMap", false, ""}; + Gaudi::Property<std::string> m_materialMapInputFile{this, "MaterialMapInputFile", "", ""}; + Gaudi::Property<std::vector<size_t>> m_MaterialBins{this, "BarrelMaterialBins", {10, 10}}; +}; + + + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometryTool.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometryTool.h new file mode 100644 index 0000000000000000000000000000000000000000..7a32e70e994b29b5f2583d5104ad3b2cdd186c70 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsTrackingGeometryTool.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSTRACKINGGEOMETRYTOOL_H +#define FASERACTSGEOMETRY_ACTSTRACKINGGEOMETRYTOOL_H + +// ATHENA +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/EventContext.h" +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/ServiceHandle.h" +#include "StoreGate/ReadCondHandleKey.h" + +// PACKAGE +#include "FaserActsGeometry/FaserActsAlignmentStore.h" // ReadCondHandleKey wants complete type +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h" + +// ACTS + +namespace Acts { +class TrackingGeometry; +} + +class FaserActsGeometryContext; +class IFaserActsTrackingGeometrySvc; + + +class FaserActsTrackingGeometryTool : public extends<AthAlgTool, IFaserActsTrackingGeometryTool> +{ + +public: + StatusCode initialize() override; + + FaserActsTrackingGeometryTool(const std::string &type, const std::string &name, + const IInterface *parent); + + virtual + std::shared_ptr<const Acts::TrackingGeometry> + trackingGeometry() const override; + + virtual + const FaserActsGeometryContext& + getGeometryContext(const EventContext& ctx = Gaudi::Hive::currentContext()) const override; + + virtual + FaserActsGeometryContext + getNominalGeometryContext() const override; + +private: + ServiceHandle<IFaserActsTrackingGeometrySvc> m_trackingGeometrySvc; + + SG::ReadCondHandleKey<FaserActsGeometryContext> m_rchk{ + this, "FaserActsAlignmentKey", "FaserActsAlignment", "cond read key"}; +}; + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsWriteTrackingGeometry.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsWriteTrackingGeometry.h new file mode 100755 index 0000000000000000000000000000000000000000..2de2fef9c67193d8b0d52e1352124bbe41e55939 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserActsWriteTrackingGeometry.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_ACTSWRITETRACKINGGEOMETRY_H +#define FASERACTSGEOMETRY_ACTSWRITETRACKINGGEOMETRY_H + +// ATHENA +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "GaudiKernel/ServiceHandle.h" +#include "AthenaKernel/IAthRNGSvc.h" +#include "Gaudi/Property.h" /*no forward decl: typedef*/ +#include "GaudiKernel/ISvcLocator.h" + +// PACKAGE +#include "FaserActsGeometry/FaserActsObjWriterTool.h" +#include "FaserActsGeometry/FaserActsTrackingGeometryTool.h" + +// STL +#include <fstream> +#include <memory> +#include <vector> + +namespace Acts { + class TrackingGeometry; +} + +class IFaserActsTrackingGeometrySvc; + +class FaserActsWriteTrackingGeometry : public AthReentrantAlgorithm { +public: + FaserActsWriteTrackingGeometry (const std::string& name, ISvcLocator* pSvcLocator); + virtual StatusCode initialize() override; + virtual StatusCode execute(const EventContext& ctx) const override; + virtual StatusCode finalize() override; + +private: + + ToolHandle<FaserActsTrackingGeometryTool> m_trackingGeometryTool{this, "TrackingGeometryTool", "FaserActsTrackingGeometryTool"}; + + ToolHandle<FaserActsObjWriterTool> m_objWriterTool{this, "ObjWriterTool", "FaserActsObjWriterTool"}; + +}; + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserNominalAlignmentCondAlg.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserNominalAlignmentCondAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..bed4135c09794f919f3d5cd0db3c2405ec1e16a5 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/FaserNominalAlignmentCondAlg.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#pragma once + +// ATHENA +#include "AthenaBaseComps/AthAlgorithm.h" +#include "GaudiKernel/ICondSvc.h" +#include "StoreGate/WriteCondHandleKey.h" + +// PACKAGE + +// STL +#include <string> + +class IFaserActsTrackingGeometrySvc; +class FaserActsAlignmentStore; + +class FaserActsGeometryContext; + +/// @class FaserNominalAlignmentCondAlg +/// Conditions algorithm which produces an (effectively) +/// infinitely valid FaserActsAlignmentStore which has +/// nominal alignments (= identity deltas) +/// +class FaserNominalAlignmentCondAlg : public AthAlgorithm { + +public: + FaserNominalAlignmentCondAlg(const std::string &name, ISvcLocator *pSvcLocator); + virtual ~FaserNominalAlignmentCondAlg(); + + virtual bool isClonable() const override { return true; } + + virtual StatusCode initialize() override; + virtual StatusCode execute() override; + virtual StatusCode finalize() override; + +private: + SG::WriteCondHandleKey<FaserActsGeometryContext> m_wchk{ + this, "FaserActsAlignmentKey", "FaserActsAlignment", "cond handle key"}; + + ServiceHandle<ICondSvc> m_cs; + ServiceHandle<IFaserActsTrackingGeometrySvc> m_trackingGeometrySvc; +}; diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/IFaserActsExCellWriterSvc.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/IFaserActsExCellWriterSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..9c657fadb9467fb07b7abbbe63ca9225f242f8b3 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/IFaserActsExCellWriterSvc.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_IACTSEXCELLWRITERSVC_H +#define FASERACTSGEOMETRY_IACTSEXCELLWRITERSVC_H + +#include "GaudiKernel/IInterface.h" +#include "Acts/EventData/TrackParameters.hpp" + +namespace Acts { + +template <class> +class ExtrapolationCell; + +} + + +class IFaserActsExCellWriterSvc : virtual public IInterface { +public: + + DeclareInterfaceID(IFaserActsExCellWriterSvc, 1, 0); + + IFaserActsExCellWriterSvc() {;} + + void + virtual + store(std::vector<Acts::ExtrapolationCell<Acts::TrackParameters>>& ecells) = 0; + +}; + + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/IFaserActsPropStepRootWriterSvc.h b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/IFaserActsPropStepRootWriterSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..45202b670818d420e8806505683c165968119439 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/FaserActsGeometry/IFaserActsPropStepRootWriterSvc.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRY_IACTSPROPSTEPROOTWRITERSVC_H +#define FASERACTSGEOMETRY_IACTSPROPSTEPROOTWRITERSVC_H + +#include "GaudiKernel/IInterface.h" +#include "Acts/EventData/TrackParameters.hpp" + +namespace Acts { + namespace detail { + class Step; + } +} + + +class IFaserActsPropStepRootWriterSvc : virtual public IInterface { +public: + + DeclareInterfaceID(IFaserActsPropStepRootWriterSvc, 1, 0); + + IFaserActsPropStepRootWriterSvc() {;} + + void + virtual + write(const std::vector<Acts::detail::Step>& steps) = 0; + +}; + + +#endif diff --git a/Tracking/Acts/FaserActsGeometry/python/FaserActsExtrapolationConfig.py b/Tracking/Acts/FaserActsGeometry/python/FaserActsExtrapolationConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..ee53a9aac0530e4359fac3cc327be4ac683fb8af --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/python/FaserActsExtrapolationConfig.py @@ -0,0 +1,58 @@ +""" +Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +""" +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from AthenaConfiguration.ComponentFactory import CompFactory +from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg +from FaserGeoModel.SCTGMConfig import SctGeometryCfg +from MagFieldServices.MagFieldServicesConfig import MagneticFieldSvcCfg + + +FaserActsExtrapolationAlg,FaserActsExtrapolationTool,FaserActsTrackingGeometrySvc,FaserActsTrackingGeometryTool,FaserActsAlignmentCondAlg = CompFactory.getComps("FaserActsExtrapolationAlg","FaserActsExtrapolationTool","FaserActsTrackingGeometrySvc","FaserActsTrackingGeometryTool","FaserActsAlignmentCondAlg") + +def FaserActsTrackingGeometrySvcCfg(flags, **kwargs): + acc = ComponentAccumulator() + acc.addService(FaserActsTrackingGeometrySvc(name = "FaserActsTrackingGeometrySvc", **kwargs)) + return acc + + +def FaserActsAlignmentCondAlgCfg(flags, **kwargs): + acc = ComponentAccumulator() + acc.addCondAlgo(CompFactory.FaserActsAlignmentCondAlg(name = "FaserActsAlignmentCondAlg", **kwargs)) + #acc.addCondAlgo(CompFactory.NominalAlignmentCondAlg(name = "NominalAlignmentCondAlg", **kwargs)) + return acc + + +def FaserActsExtrapolationAlgBasicCfg(flags, **kwargs): + acc = ComponentAccumulator() + actsExtrapolationAlg=FaserActsExtrapolationAlg(**kwargs) + actsExtrapolationTool=FaserActsExtrapolationTool("FaserActsExtrapolationTool") + actsExtrapolationTool.FieldMode="FASER" + #actsExtrapolationTool.FieldMode="Constant" + actsExtrapolationTool.TrackingGeometryTool=FaserActsTrackingGeometryTool("TrackingGeometryTool") + actsExtrapolationAlg.ExtrapolationTool=actsExtrapolationTool + actsExtrapolationAlg.EtaRange=[1, 10] + actsExtrapolationAlg.PtRange=[0.1, 100] + actsExtrapolationAlg.NParticlesPerEvent=int(1e4) + acc.addEventAlgo(actsExtrapolationAlg) + return acc + + +def FaserActsExtrapolationAlg_OutputCfg(flags): + acc = ComponentAccumulator() + return acc + + +def FaserActsExtrapolationAlgCfg(flags, **kwargs): + # Initialize GeoModel + #acc = FaserGeometryCfg(flags) + acc = SctGeometryCfg(flags) + + # Initialize field service + acc.merge(MagneticFieldSvcCfg(flags)) + + acc.merge(FaserActsTrackingGeometrySvcCfg(flags, **kwargs)) + #acc.merge(FaserActsAlignmentCondAlgCfg(flags)) + acc.merge(FaserActsExtrapolationAlgBasicCfg(flags, **kwargs)) + acc.merge(FaserActsExtrapolationAlg_OutputCfg(flags)) + return acc diff --git a/Tracking/Acts/FaserActsGeometry/python/FaserActsWriteTrackingGeometryConfig.py b/Tracking/Acts/FaserActsGeometry/python/FaserActsWriteTrackingGeometryConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..d4453a69f079186dc0181bdbe519b9932a4f9890 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/python/FaserActsWriteTrackingGeometryConfig.py @@ -0,0 +1,45 @@ +""" +Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +""" +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from AthenaConfiguration.ComponentFactory import CompFactory +#from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg +from FaserGeoModel.SCTGMConfig import SctGeometryCfg + +FaserActsWriteTrackingGeometry,FaserActsTrackingGeometrySvc,FaserActsTrackingGeometryTool,FaserActsObjWriterTool,FaserActsAlignmentCondAlg = CompFactory.getComps("FaserActsWriteTrackingGeometry","FaserActsTrackingGeometrySvc","FaserActsTrackingGeometryTool","FaserActsObjWriterTool","FaserActsAlignmentCondAlg") + +def FaserActsTrackingGeometrySvcCfg(flags, **kwargs): + acc = ComponentAccumulator() + acc.addService(FaserActsTrackingGeometrySvc(name = "FaserActsTrackingGeometrySvc", **kwargs)) + return acc + + +def FaserActsAlignmentCondAlgCfg(flags, **kwargs): + acc = ComponentAccumulator() + acc.addCondAlgo(CompFactory.FaserActsAlignmentCondAlg(name = "FaserActsAlignmentCondAlg", **kwargs)) + #acc.addCondAlgo(CompFactory.NominalAlignmentCondAlg(name = "NominalAlignmentCondAlg", **kwargs)) + return acc + + +def FaserActsWriteTrackingGeometryBasicCfg(flags, **kwargs): + acc = ComponentAccumulator() + actsWriteTrackingGeometry=FaserActsWriteTrackingGeometry(**kwargs) + actsWriteTrackingGeometry.TrackingGeometryTool=FaserActsTrackingGeometryTool("TrackingGeometryTool") + actsWriteTrackingGeometry.ObjWriterTool=FaserActsObjWriterTool("FaserActsObjWriterTool",OutputDirectory="./", SubDetectors=["Station_1","Station_2","Station_3"]) + acc.addEventAlgo(actsWriteTrackingGeometry) + return acc + + +def FaserActsWriteTrackingGeometry_OutputCfg(flags): + acc = ComponentAccumulator() + return acc + + +def FaserActsWriteTrackingGeometryCfg(flags, **kwargs): + #acc = FaserGeometryCfg(flags) + acc = SctGeometryCfg(flags) + acc.merge(FaserActsTrackingGeometrySvcCfg(flags, **kwargs)) + #acc.merge(FaserActsAlignmentCondAlgCfg(flags)) + acc.merge(FaserActsWriteTrackingGeometryBasicCfg(flags, **kwargs)) + acc.merge(FaserActsWriteTrackingGeometry_OutputCfg(flags)) + return acc diff --git a/Tracking/Acts/FaserActsGeometry/src/CuboidVolumeBuilder.cxx b/Tracking/Acts/FaserActsGeometry/src/CuboidVolumeBuilder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2ded998d64f261412fc154226b23bb7832734e67 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/CuboidVolumeBuilder.cxx @@ -0,0 +1,237 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2018 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "FaserActsGeometry/CuboidVolumeBuilder.h" + +#include "Acts/Geometry/CuboidVolumeBounds.hpp" +#include "Acts/Geometry/Layer.hpp" +#include "Acts/Geometry/LayerArrayCreator.hpp" +#include "Acts/Geometry/LayerCreator.hpp" +#include "Acts/Geometry/PlaneLayer.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Geometry/TrackingVolume.hpp" +#include "Acts/Geometry/detail/DefaultDetectorElementBase.hpp" +#include "Acts/Geometry/ApproachDescriptor.hpp" +#include "Acts/Material/HomogeneousSurfaceMaterial.hpp" +#include "Acts/Material/MaterialProperties.hpp" +#include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/Surfaces/SurfaceArray.hpp" +#include "Acts/Utilities/BinnedArray.hpp" +#include "Acts/Utilities/BinnedArrayXD.hpp" +#include "Acts/Utilities/Definitions.hpp" + +namespace FaserActs{ + +std::shared_ptr<const Acts::PlaneSurface> +CuboidVolumeBuilder::buildSurface( + const Acts::GeometryContext& /*gctx*/, + const CuboidVolumeBuilder::SurfaceConfig& cfg) const { + std::shared_ptr<Acts::PlaneSurface> surface; + + // Build transformation + Acts::Transform3D trafo(Acts::Transform3D::Identity() * cfg.rotation); + trafo.translation() = cfg.position; + + // Create and store surface + if (cfg.detElementConstructor) { + surface = Acts::Surface::makeShared<Acts::PlaneSurface>( + cfg.rBounds, + *(cfg.detElementConstructor(std::make_shared<const Acts::Transform3D>(trafo), + cfg.rBounds, cfg.thickness))); + } else { + surface = Acts::Surface::makeShared<Acts::PlaneSurface>( + std::make_shared<const Acts::Transform3D>(trafo), cfg.rBounds); + } + surface->assignSurfaceMaterial(cfg.surMat); + return surface; +} + +std::shared_ptr<const Acts::Layer> CuboidVolumeBuilder::buildLayer( + const Acts::GeometryContext& gctx, + CuboidVolumeBuilder::LayerConfig& cfg) const { + // Build the surface + if ( cfg.surface==nullptr && cfg.surfaces.empty() ) { + cfg.surface = buildSurface(gctx, cfg.surfaceCfg); + } + // Build transformation centered at the surface position + Acts::Transform3D trafo(Acts::Transform3D::Identity() * cfg.surfaceCfg.rotation); + trafo.translation() = cfg.surfaceCfg.position; + + Acts::LayerCreator::Config lCfg; + lCfg.surfaceArrayCreator = std::make_shared<const Acts::SurfaceArrayCreator>(); + Acts::LayerCreator layerCreator(lCfg); + + std::unique_ptr<Acts::ApproachDescriptor> ap(cfg.approachDescriptor); + + if ( !cfg.surfaces.empty() ) { + return layerCreator.planeLayer(gctx, cfg.surfaces, cfg.binsX, cfg.binsY, + Acts::BinningValue::binZ, std::nullopt, + std::make_shared<const Acts::Transform3D>(trafo), + std::move(ap)); + } else { + return layerCreator.planeLayer(gctx, {cfg.surface}, cfg.binsX, cfg.binsY, + Acts::BinningValue::binZ, std::nullopt, + std::make_shared<const Acts::Transform3D>(trafo), + std::move(ap)); + } +} + +std::pair<double, double> CuboidVolumeBuilder::binningRange( + const Acts::GeometryContext& /*gctx*/, + const CuboidVolumeBuilder::VolumeConfig& cfg) const { + using namespace Acts::UnitLiterals; + // Construct return value + std::pair<double, double> minMax = std::make_pair( + std::numeric_limits<double>::max(), -std::numeric_limits<double>::max()); + for (const auto& layercfg : cfg.layerCfg) { + // Test if new extreme is found and set it + + // For Faser, the thickness of each layer is about 5 mm due to staggering structure of SCTs + //if (layercfg.surfaceCfg.position.z() - 1_um < minMax.first) { + //minMax.first = layercfg.surfaceCfg.position.z() - 1_um; + if (layercfg.surfaceCfg.position.z() - 8_mm < minMax.first) { + minMax.first = layercfg.surfaceCfg.position.z() - 8_mm; + } + //if (layercfg.surfaceCfg.position.z() + 1_um > minMax.second) { + //minMax.second = layercfg.surfaceCfg.position.z() + 1_um; + if (layercfg.surfaceCfg.position.z() + 8_mm > minMax.second) { + minMax.second = layercfg.surfaceCfg.position.z() + 8_mm; + } + } + return minMax; +} + +std::shared_ptr<Acts::TrackingVolume> CuboidVolumeBuilder::buildVolume( + const Acts::GeometryContext& gctx, + CuboidVolumeBuilder::VolumeConfig& cfg) const { + // Build transformation + Acts::Transform3D trafo(Acts::Transform3D::Identity()); + trafo.translation() = cfg.position; + // Set bounds + auto bounds = std::make_shared<const Acts::CuboidVolumeBounds>( + cfg.length.x() * 0.5, cfg.length.y() * 0.5, cfg.length.z() * 0.5); + + if (cfg.layerCfg.empty()) { + // Build dummy layer if no layer is given (tmp solution) + SurfaceConfig sCfg; + sCfg.position = cfg.position; + // Rotation of the surfaces: +pi/2 around axis y + Acts::Vector3D xPos(0., 0., 1.); + Acts::Vector3D yPos(0., 1., 0.); + Acts::Vector3D zPos(-1., 0., 0.); + sCfg.rotation.col(0) = xPos; + sCfg.rotation.col(1) = yPos; + sCfg.rotation.col(2) = zPos; + // Bounds + sCfg.rBounds = std::make_shared<const Acts::RectangleBounds>( + Acts::RectangleBounds(cfg.length.y() * 0.5, cfg.length.z() * 0.5)); + + LayerConfig lCfg; + lCfg.surfaceCfg = sCfg; + + cfg.layerCfg.push_back(lCfg); + } + + // Gather the layers + Acts::LayerVector layVec; + if (cfg.layers.empty()) { + cfg.layers.reserve(cfg.layerCfg.size()); + + for (auto& layerCfg : cfg.layerCfg) { + cfg.layers.push_back(buildLayer(gctx, layerCfg)); + layVec.push_back(cfg.layers.back()); + } + } else { + for (auto& lay : cfg.layers) { + layVec.push_back(lay); + } + } + + // Build layer array + std::pair<double, double> minMax = binningRange(gctx, cfg); + Acts::LayerArrayCreator::Config lacCnf; + Acts::LayerArrayCreator layArrCreator( + lacCnf, Acts::getDefaultLogger("Acts::LayerArrayCreator", Acts::Logging::INFO)); + std::unique_ptr<const Acts::LayerArray> layArr( + layArrCreator.layerArray(gctx, layVec, minMax.first, minMax.second, + Acts::BinningType::arbitrary, Acts::BinningValue::binZ)); + + // Build confined volumes + if (cfg.trackingVolumes.empty()) + for (VolumeConfig vc : cfg.volumeCfg) + cfg.trackingVolumes.push_back(buildVolume(gctx, vc)); + + // Build TrackingVolume + auto trackVolume = Acts::TrackingVolume::create( + std::make_shared<const Acts::Transform3D>(trafo), bounds, cfg.volumeMaterial, + std::move(layArr), nullptr, cfg.trackingVolumes, cfg.name); + + return trackVolume; +} + +Acts::MutableTrackingVolumePtr CuboidVolumeBuilder::trackingVolume( + const Acts::GeometryContext& gctx, Acts::TrackingVolumePtr /*unused*/, + Acts::VolumeBoundsPtr /*unused*/) const { + // Build volumes + std::vector<std::shared_ptr<Acts::TrackingVolume>> volumes; + volumes.reserve(m_cfg.volumeCfg.size()); + for (VolumeConfig volCfg : m_cfg.volumeCfg) { + volumes.push_back(buildVolume(gctx, volCfg)); + } + + // Glue volumes + for (unsigned int i = 0; i < volumes.size() - 1; i++) { + volumes[i + 1]->glueTrackingVolume( + gctx, Acts::BoundarySurfaceFace::negativeFaceXY, volumes[i].get(), + Acts::BoundarySurfaceFace::positiveFaceXY); + volumes[i]->glueTrackingVolume(gctx, Acts::BoundarySurfaceFace::positiveFaceXY, + volumes[i + 1].get(), + Acts::BoundarySurfaceFace::negativeFaceXY); + } + + // Translation + Acts::Transform3D trafo(Acts::Transform3D::Identity()); + trafo.translation() = m_cfg.position; + + // Size of the volume + auto volume = std::make_shared<const Acts::CuboidVolumeBounds>( + m_cfg.length.x() * 0.5, m_cfg.length.y() * 0.5, m_cfg.length.z() * 0.5); + + // Build vector of confined volumes + std::vector<std::pair<Acts::TrackingVolumePtr, Acts::Vector3D>> tapVec; + tapVec.reserve(m_cfg.volumeCfg.size()); + for (auto& tVol : volumes) { + tapVec.push_back(std::make_pair(tVol, tVol->center())); + } + + // Set bin boundaries along binning + std::vector<float> binBoundaries; + binBoundaries.push_back(volumes[0]->center().z() - + m_cfg.volumeCfg[0].length.z() * 0.5); + for (size_t i = 0; i < volumes.size(); i++) { + binBoundaries.push_back(volumes[i]->center().z() + + m_cfg.volumeCfg[i].length.z() * 0.5); + } + + // Build binning + Acts::BinningData binData(Acts::BinningOption::open, Acts::BinningValue::binZ, binBoundaries); + auto bu = std::make_unique<const Acts::BinUtility>(binData); + + // Build TrackingVolume array + std::shared_ptr<const Acts::TrackingVolumeArray> trVolArr( + new Acts::BinnedArrayXD<Acts::TrackingVolumePtr>(tapVec, std::move(bu))); + + // Create world volume + Acts::MutableTrackingVolumePtr mtvp(Acts::TrackingVolume::create( + std::make_shared<const Acts::Transform3D>(trafo), volume, trVolArr, "World")); + + return mtvp; +} + +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentCondAlg.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentCondAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..66cfdc7bd6b0fd92654fa1a4f45c2c79704084b7 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentCondAlg.cxx @@ -0,0 +1,140 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsAlignmentCondAlg.h" + +// ATHENA +#include "EventInfo/EventID.h" +#include "EventInfo/EventInfo.h" +#include "GaudiKernel/EventIDBase.h" +#include "GaudiKernel/EventIDRange.h" +#include "GaudiKernel/ICondSvc.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "StoreGate/StoreGateSvc.h" +#include "StoreGate/WriteCondHandle.h" +#include "TrackerReadoutGeometry/SCT_DetectorManager.h" + +// PACKAGE +#include "FaserActsGeometry/FaserActsAlignmentStore.h" +#include "FaserActsGeometry/FaserActsDetectorElement.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h" + +// ACTS +#include "Acts/Geometry/DetectorElementBase.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Surfaces/Surface.hpp" +#include "Acts/Utilities/Definitions.hpp" + +// STL +#include <memory> + +FaserActsAlignmentCondAlg::FaserActsAlignmentCondAlg(const std::string &name, + ISvcLocator *pSvcLocator) + : ::AthAlgorithm(name, pSvcLocator), m_cs("CondSvc", name), + m_trackingGeometrySvc("FaserActsTrackingGeometrySvc", name) {} + +FaserActsAlignmentCondAlg::~FaserActsAlignmentCondAlg() {} + +StatusCode FaserActsAlignmentCondAlg::initialize() { + ATH_MSG_DEBUG("initialize " << name()); + + ATH_CHECK(m_sctAlignStoreReadKey.initialize()); + + if (m_cs.retrieve().isFailure()) { + ATH_MSG_ERROR("unable to retrieve CondSvc"); + return StatusCode::FAILURE; + } + + ATH_CHECK(detStore()->retrieve(p_SCTManager, "SCT")); + + if (m_wchk.initialize().isFailure()) { + ATH_MSG_ERROR("unable to initialize WriteCondHandle with key" + << m_wchk.key()); + return StatusCode::FAILURE; + } + + if (m_cs->regHandle(this, m_wchk).isFailure()) { + ATH_MSG_ERROR("unable to register WriteCondHandle " << m_wchk.fullKey() + << " with CondSvc"); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode FaserActsAlignmentCondAlg::finalize() { + ATH_MSG_DEBUG("finalize " << name()); + return StatusCode::SUCCESS; +} + +StatusCode FaserActsAlignmentCondAlg::execute() { + ATH_MSG_DEBUG("execute " << name()); + + auto trkGeom = m_trackingGeometrySvc->trackingGeometry(); + + EventIDBase now(getContext().eventID()); + SG::WriteCondHandle<FaserActsGeometryContext> wch(m_wchk); + + if (wch.isValid(now)) { + ATH_MSG_DEBUG( + "CondHandle is already valid for " + << now << ". In theory this should not be called, but may happen" + << " if multiple concurrent events are being processed out of order."); + + } else { + + ATH_MSG_DEBUG(" CondHandle " << wch.key() << " not valid now (" << now + << "). Getting new info for dbKey \"" + << wch.dbKey() << "\" from CondDb"); + + SG::ReadCondHandle<GeoAlignmentStore> sctAlignStore(m_sctAlignStoreReadKey); + + + EventIDRange sctRange; + if(!sctAlignStore.range(sctRange)) { + ATH_MSG_FATAL("Failed to retrieve validity range for " << sctAlignStore.key()); + return StatusCode::FAILURE; + } + + // create an Acts aware geo alignment store from the one given + // (this makes a copy for now, which is not ideal) + auto actsAlignStore = + std::make_unique<FaserActsAlignmentStore>(**sctAlignStore); + + // deltas are set, now populate sensitive element transforms + ATH_MSG_DEBUG("Populating FaserActsAlignmentStore for IOV"); + size_t nElems = 0; + trkGeom->visitSurfaces([&actsAlignStore, &nElems](const Acts::Surface *srf) { + const Acts::DetectorElementBase *detElem = + srf->associatedDetectorElement(); + const auto *gmde = static_cast<const FaserActsDetectorElement *>(detElem); + gmde->storeTransform(actsAlignStore.get()); + nElems++; + }); + ATH_MSG_DEBUG("FaserActsAlignmentStore populated for " << nElems + << " detector elements"); + + // get a nominal alignment store from the tracking geometry service + // and plug it into a geometry context + auto gctx = std::make_unique<FaserActsGeometryContext>(); + gctx->ownedAlignmentStore = + std::move(actsAlignStore); // GCTX owns the alignment store + gctx->alignmentStore = gctx->ownedAlignmentStore.get(); + + if (wch.record(sctRange, gctx.release()).isFailure()) { + ATH_MSG_ERROR("could not record alignment store " + << wch.key() << " = " << gctx.get() << " with EventRange " + << sctRange); + return StatusCode::FAILURE; + } + + ATH_MSG_INFO("Recorded new " << wch.key() << " " + << " with range " << sctRange); + } + + + + return StatusCode::SUCCESS; +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentStore.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentStore.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1abb7d734075c8ad1892ad315f516d3ed32dcc74 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentStore.cxx @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsAlignmentStore.h" + +#include "FaserActsGeometry/FaserActsDetectorElement.h" + +#include "Acts/Utilities/Definitions.hpp" + +FaserActsAlignmentStore::FaserActsAlignmentStore(const GeoAlignmentStore &gas){ + + m_deltas = gas.getDeltas(); + m_absPositions = gas.getAbsPositions(); + m_defAbsPositions = gas.getDefAbsPositions(); + +} + +void FaserActsAlignmentStore::setTransform(const FaserActsDetectorElement *ade, + const Acts::Transform3D &xf) { + if (!m_transforms.setTransform(ade, xf)) { + throw ExcAlignmentStore( + "Attempted to overwrite Delta in the Alignment Store"); + } +} + +const Acts::Transform3D * +FaserActsAlignmentStore::getTransform(const FaserActsDetectorElement *ade) const { + return m_transforms.getTransform(ade); +} + +void FaserActsAlignmentStore::append(const GeoAlignmentStore& gas) { + for(const auto& it : gas.getDeltas().container()) { + setDelta(it.first, it.second); + } + + for(const auto& it : gas.getAbsPositions().container()) { + setAbsPosition(it.first, it.second); + } + + for(const auto& it : gas.getDefAbsPositions().container()) { + setDefAbsPosition(it.first, it.second); + } +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx new file mode 100644 index 0000000000000000000000000000000000000000..622f1d0b87a505fd4be48c79ba06795c65df38b8 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx @@ -0,0 +1,173 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsDetectorElement.h" + +// ATHENA +#include "TrkSurfaces/RectangleBounds.h" +#include "TrkSurfaces/SurfaceBounds.h" +#include "TrkSurfaces/TrapezoidBounds.h" +#include "GeoPrimitives/CLHEPtoEigenConverter.h" + +// PACKAGE +#include "FaserActsGeometry/FaserActsTrackingGeometrySvc.h" +#include "FaserActsGeometry/FaserActsAlignmentStore.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "ActsInterop/IdentityHelper.h" + +// ACTS +#include "Acts/Surfaces/StrawSurface.hpp" +#include "Acts/Surfaces/LineBounds.hpp" +#include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/Surfaces/TrapezoidBounds.hpp" +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Utilities/Units.hpp" + +// STL +#include <mutex> + +using Acts::Transform3D; +using Acts::Surface; + +using namespace Acts::UnitLiterals; + +constexpr double length_unit = 1_mm; + +FaserActsDetectorElement::FaserActsDetectorElement(const TrackerDD::SiDetectorElement* detElem) +{ + m_detElement = detElem; + + //auto center = detElem->center(); + auto boundsType = detElem->bounds().type(); + + // thickness + m_thickness = detElem->thickness(); + + if (boundsType == Trk::SurfaceBounds::Rectangle) { + + const TrackerDD::SiDetectorDesign &design = detElem->design(); + double hlX = design.width()/2. * length_unit; + double hlY = design.length()/2. * length_unit; + + auto rectangleBounds = std::make_shared<const Acts::RectangleBounds>(hlX, hlY); + + m_bounds = rectangleBounds; + + m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(rectangleBounds, *this); + + } else if (boundsType == Trk::SurfaceBounds::Trapezoid) { + + std::string shapeString = detElem->getMaterialGeom()->getLogVol()->getShape()->type(); + //std::cout << __FUNCTION__ << "tapezoid, GeoLogVol -> shape says: " << shapeString << std::endl; + + const TrackerDD::SiDetectorDesign &design = detElem->design(); + + double minHlX = design.minWidth()/2. * length_unit; + double maxHlX = design.maxWidth()/2. * length_unit; + double hlY = design.length()/2. * length_unit; + + auto trapezoidBounds = std::make_shared<const Acts::TrapezoidBounds>( + minHlX, maxHlX, hlY); + + m_bounds = trapezoidBounds; + + m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(trapezoidBounds, *this); + + } else { + throw std::domain_error("FaserActsDetectorElement does not support this surface type"); + } +} + + +IdentityHelper +FaserActsDetectorElement::identityHelper() const +{ + return IdentityHelper(m_detElement); +} + +const Acts::Transform3D& +FaserActsDetectorElement::transform(const Acts::GeometryContext& anygctx) const +{ + // any cast to known context type + const FaserActsGeometryContext* gctx = std::any_cast<const FaserActsGeometryContext*>(anygctx); + + // This is needed for initial geometry construction. At that point, we don't have a + // consistent view of the geometry yet, and thus we can't populate an alignment store + // at that time. + if (gctx->construction) { + // this should only happen at initialize (1 thread, but mutex anyway) + return getDefaultTransformMutexed(); + } + + // unpack the alignment store from the context + const FaserActsAlignmentStore* alignmentStore = gctx->alignmentStore; + + // no GAS, is this initialization? + assert(alignmentStore != nullptr); + + // get the correct cached transform + // units should be fine here since we converted at construction + const Transform3D* cachedTrf = alignmentStore->getTransform(this); + + assert(cachedTrf != nullptr); + + return *cachedTrf; +} + +void +FaserActsDetectorElement::storeTransform(FaserActsAlignmentStore* gas) const +{ + Amg::Transform3D g2l + = m_detElement->getMaterialGeom()->getDefAbsoluteTransform() + * Amg::CLHEPTransformToEigen(m_detElement->recoToHitTransform()); + + // need to make sure translation has correct units + g2l.translation() *= length_unit; + + gas->setTransform(this, g2l); + if (gas->getTransform(this) == nullptr) { + throw std::runtime_error("Detector element was unable to store transform in GAS"); + } + +} + +const Acts::Transform3D& +FaserActsDetectorElement::getDefaultTransformMutexed() const +{ + Amg::Transform3D g2l + = m_detElement->getMaterialGeom()->getDefAbsoluteTransform() + * Amg::CLHEPTransformToEigen(m_detElement->recoToHitTransform()); + + // need to make sure translation has correct units + g2l.translation() *= length_unit; + + std::lock_guard<std::mutex> guard(m_cacheMutex); + if (m_defTransform) { + return *m_defTransform; + } + // transform not yet set + m_defTransform + = std::make_shared<const Transform3D>( g2l ); + + return *m_defTransform; +} + +const Acts::Surface& +FaserActsDetectorElement::surface() const +{ + return (*m_surface); +} + +double +FaserActsDetectorElement::thickness() const +{ + return m_thickness; +} + +Identifier +FaserActsDetectorElement::identify() const +{ + return m_detElement->identify(); +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationAlg.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationAlg.cxx new file mode 100755 index 0000000000000000000000000000000000000000..5130f68e0c2ee0221fad2beb60aaf59bc29f72bb --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationAlg.cxx @@ -0,0 +1,149 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsExtrapolationAlg.h" + +// ATHENA +#include "AthenaKernel/RNGWrapper.h" +#include "AthenaKernel/IAthRNGSvc.h" +#include "GaudiKernel/EventContext.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/PhysicalConstants.h" + +// ACTS +#include "Acts/Utilities/Helpers.hpp" +#include "Acts/Propagator/detail/SteppingLogger.hpp" +#include "Acts/Utilities/Units.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "Acts/Surfaces/PerigeeSurface.hpp" + +// PACKAGE +#include "FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h" +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h" +#include "ActsInterop/Logger.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "FaserActsGeometry/IFaserActsPropStepRootWriterSvc.h" +//#include "FaserActsGeometry/IFaserActsMaterialTrackWriterSvc.h" + +// OTHER +#include "CLHEP/Random/RandomEngine.h" + +// STL +#include <string> +#include <fstream> + +using namespace Acts::UnitLiterals; + +FaserActsExtrapolationAlg::FaserActsExtrapolationAlg(const std::string& name, + ISvcLocator* pSvcLocator) + : AthReentrantAlgorithm(name, pSvcLocator), + m_propStepWriterSvc("FaserActsPropStepRootWriterSvc", name), + m_rndmGenSvc("AthRNGSvc", name)//, + //m_materialTrackWriterSvc("FaserActsMaterialTrackWriterSvc", name) +{ +} + +StatusCode FaserActsExtrapolationAlg::initialize() { + + ATH_MSG_DEBUG(name() << "::" << __FUNCTION__); + + ATH_CHECK( m_rndmGenSvc.retrieve() ); + ATH_CHECK( m_extrapolationTool.retrieve() ); + ATH_CHECK( m_propStepWriterSvc.retrieve() ); + + //if (m_writeMaterialTracks) { + //ATH_CHECK( m_materialTrackWriterSvc.retrieve() ); + //} + + m_objOut = std::make_unique<std::ofstream>("steps.obj"); + + return StatusCode::SUCCESS; +} + +StatusCode FaserActsExtrapolationAlg::execute(const EventContext& ctx) const +{ + + ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__); + + ATHRNG::RNGWrapper* rngWrapper = m_rndmGenSvc->getEngine(this); + rngWrapper->setSeed( name(), ctx ); + CLHEP::HepRandomEngine* rngEngine = rngWrapper->getEngine(ctx); + + ATH_MSG_VERBOSE("Extrapolating " << m_nParticlePerEvent << " particles"); + + for (size_t i = 0; i < m_nParticlePerEvent; i++) { + + double d0 = 0; + double z0 = 0; + double phi = rngEngine->flat() * 2*M_PI - M_PI; + std::vector<double> etaRange = m_etaRange; + double etaMin = etaRange.at(0); + double etaMax = etaRange.at(1); + double eta = rngEngine->flat() * std::abs(etaMax - etaMin) + etaMin; + + std::vector<double> ptRange = m_ptRange; + double ptMin = ptRange.at(0) * 1_GeV; + double ptMax = ptRange.at(1) * 1_GeV; + + double pt = rngEngine->flat() * std::abs(ptMax - ptMin) + ptMin; + + Acts::Vector3D momentum( + pt * std::cos(phi), pt * std::sin(phi), pt * std::sinh(eta)); + + double theta = Acts::VectorHelpers::theta(momentum); + + double charge = rngEngine->flat() > 0.5 ? -1 : 1; + + double qop = charge / momentum.norm(); + + std::shared_ptr<Acts::PerigeeSurface> surface + = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3D(0, 0, 0)); + + double t = 0; + + Acts::BoundVector pars; + pars << d0, z0, phi, theta, qop, t; + std::optional<Acts::BoundSymMatrix> cov = std::nullopt; + + if(charge != 0.) { + // Perigee, no alignment -> default geo context + FaserActsGeometryContext gctx + = m_extrapolationTool->trackingGeometryTool()->getNominalGeometryContext(); + auto anygctx = gctx.any(); + Acts::BoundParameters startParameters(anygctx, + std::move(cov), std::move(pars), std::move(surface)); + auto output = m_extrapolationTool->propagationSteps(ctx, startParameters); + m_propStepWriterSvc->write(output.first); + writeStepsObj(output.first); + } + + + ATH_MSG_VERBOSE(name() << " execute done"); + } + + return StatusCode::SUCCESS; +} + +StatusCode FaserActsExtrapolationAlg::finalize() { + return StatusCode::SUCCESS; +} + +void FaserActsExtrapolationAlg::writeStepsObj(std::vector<Acts::detail::Step> steps) const +{ + std::lock_guard<std::mutex> lock(m_writeMutex); + + std::ofstream& out = *m_objOut; + std::stringstream lstr; + lstr << "l"; + for(const auto& step : steps) { + const auto& pos = step.position; + out << "v " << pos.x() << " " << pos.y() << " " << pos.z() << std::endl; + lstr << " " << m_objVtxCount; + m_objVtxCount++; + } + + lstr << std::endl; + + out << lstr.str() << std::endl; +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d4b1b08db63c0049e3c631f53e547e90e766f3ab --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx @@ -0,0 +1,380 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsExtrapolationTool.h" + +// ATHENA +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/PhysicalConstants.h" + +// PACKAGE +#include "FaserActsGeometry/FaserActsTrackingGeometrySvc.h" +#include "FaserActsGeometry/FaserActsTrackingGeometryTool.h" +#include "ActsInterop/Logger.h" + +// ACTS +#include "Acts/Surfaces/Surface.hpp" +#include "Acts/Surfaces/BoundaryCheck.hpp" +#include "Acts/Propagator/Navigator.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Propagator/AbortList.hpp" +#include "Acts/Propagator/ActionList.hpp" + +// BOOST +#include <boost/variant/variant.hpp> +#include <boost/variant/apply_visitor.hpp> +#include <boost/variant/static_visitor.hpp> + +// STL +#include <iostream> +#include <memory> + +namespace ActsExtrapolationDetail { + using VariantPropagatorBase = boost::variant< + Acts::Propagator<Acts::EigenStepper<FASERMagneticFieldWrapper>, Acts::Navigator>, + Acts::Propagator<Acts::EigenStepper<Acts::ConstantBField>, Acts::Navigator> + >; + + class VariantPropagator : public VariantPropagatorBase + { + public: + using VariantPropagatorBase::VariantPropagatorBase; + }; + +} + + +using ActsExtrapolationDetail::VariantPropagator; + + + +FaserActsExtrapolationTool::FaserActsExtrapolationTool(const std::string& type, const std::string& name, + const IInterface* parent) + : base_class(type, name, parent) +{ +} + + +FaserActsExtrapolationTool::~FaserActsExtrapolationTool() +{ +} + + + +StatusCode +FaserActsExtrapolationTool::initialize() +{ + using namespace std::literals::string_literals; + + + ATH_MSG_INFO("Initializing ACTS extrapolation"); + + m_logger = makeActsAthenaLogger(this, "Prop", "FaserActsExtrapTool"); + + ATH_CHECK( m_trackingGeometryTool.retrieve() ); + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry + = m_trackingGeometryTool->trackingGeometry(); + + Acts::Navigator navigator(trackingGeometry); + + if (m_fieldMode == "FASER") { + ATH_MSG_INFO("Using FASER magnetic field service"); + using BField_t = FASERMagneticFieldWrapper; + ATH_CHECK( m_fieldCondObjInputKey.initialize() ); + BField_t bField; + auto stepper = Acts::EigenStepper<BField_t>(std::move(bField)); + auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper), + std::move(navigator)); + m_varProp = std::make_unique<VariantPropagator>(propagator); + } + else if (m_fieldMode == "Constant") { + std::vector<double> constantFieldVector = m_constantFieldVector; + double Bx = constantFieldVector.at(0); + double By = constantFieldVector.at(1); + double Bz = constantFieldVector.at(2); + ATH_MSG_INFO("Using constant magnetic field: (Bx, By, Bz) = (" << Bx << ", " << By << ", " << Bz << ")"); + using BField_t = Acts::ConstantBField; + BField_t bField(Bx, By, Bz); + auto stepper = Acts::EigenStepper<BField_t>(std::move(bField)); + auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper), + std::move(navigator)); + m_varProp = std::make_unique<VariantPropagator>(propagator); + } + + ATH_MSG_INFO("ACTS extrapolation successfully initialized"); + return StatusCode::SUCCESS; +} + + +ActsPropagationOutput +FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + Acts::NavigationDirection navDir /*= Acts::forward*/, + double pathLimit /*= std::numeric_limits<double>::max()*/) const + { + using namespace Acts::UnitLiterals; + ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " begin"); + + Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx); + const FaserActsGeometryContext& gctx + //= m_trackingGeometryTool->getGeometryContext(ctx); + = m_trackingGeometryTool->getNominalGeometryContext(); + + auto anygctx = gctx.any(); + + // Action list and abort list + using ActionList = Acts::ActionList<SteppingLogger, Acts::MaterialInteractor, DebugOutput>; + using AbortConditions = Acts::AbortList<EndOfWorld>; + + using Options = Acts::PropagatorOptions<ActionList, AbortConditions>; + + Options options(anygctx, mctx, Acts::LoggerWrapper{*m_logger}); + options.pathLimit = pathLimit; + bool debug = msg().level() == MSG::VERBOSE; + options.debug = debug; + + options.loopProtection + = (Acts::VectorHelpers::perp(startParameters.momentum()) + < m_ptLoopers * 1_MeV); + + options.maxStepSize = m_maxStepSize * 1_m; + options.direction = navDir; + + auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>(); + mInteractor.multipleScattering = m_interactionMultiScatering; + mInteractor.energyLoss = m_interactionEloss; + mInteractor.recordInteractions = m_interactionRecord; + + ActsPropagationOutput output; + DebugOutput::result_type debugOutput; + + auto res = boost::apply_visitor([&](const auto& propagator) -> ResultType { + auto result = propagator.propagate(startParameters, options); + if (!result.ok()) { + return result.error(); + } + auto& propRes = *result; + + auto steppingResults = propRes.template get<SteppingLogger::result_type>(); + auto debugOutput = propRes.template get<DebugOutput::result_type>(); + auto materialResult = propRes.template get<Acts::MaterialInteractor::result_type>(); + output.first = std::move(steppingResults.steps); + output.second = std::move(materialResult); + // try to force return value optimization, not sure this is necessary + return std::make_pair(std::move(output), std::move(debugOutput)); + }, *m_varProp); + + if (!res.ok()) { + ATH_MSG_ERROR("Got error during propagation:" << res.error() << " " << res.error().message() + << ". Returning empty step vector."); + return {}; + } + std::tie(output, debugOutput) = std::move(*res); + + if(debug) { + ATH_MSG_VERBOSE(debugOutput.debugString); + } + + ATH_MSG_VERBOSE("Collected " << output.first.size() << " steps"); + if (output.first.size() == 0) { + ATH_MSG_WARNING("ZERO steps returned by stepper, that is not typically a good sign"); + } + + ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " end"); + + return output; + } + + +std::unique_ptr<const Acts::CurvilinearParameters> +FaserActsExtrapolationTool::propagate(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + Acts::NavigationDirection navDir /*= Acts::forward*/, + double pathLimit /*= std::numeric_limits<double>::max()*/) const +{ + using namespace Acts::UnitLiterals; + ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " begin"); + + Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx); + const FaserActsGeometryContext& gctx + //= m_trackingGeometryTool->getGeometryContext(ctx); + = m_trackingGeometryTool->getNominalGeometryContext(); + + auto anygctx = gctx.any(); + + // Action list and abort list + using ActionList = Acts::ActionList<Acts::MaterialInteractor, DebugOutput>; + using AbortConditions = Acts::AbortList<EndOfWorld>; + using Options = Acts::PropagatorOptions<ActionList, AbortConditions>; + + Options options(anygctx, mctx, Acts::LoggerWrapper{*m_logger}); + options.pathLimit = pathLimit; + bool debug = msg().level() == MSG::VERBOSE; + options.debug = debug; + + options.loopProtection + = (Acts::VectorHelpers::perp(startParameters.momentum()) + < m_ptLoopers * 1_MeV); + options.maxStepSize = m_maxStepSize * 1_m; + options.direction = navDir; + + auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>(); + mInteractor.multipleScattering = m_interactionMultiScatering; + mInteractor.energyLoss = m_interactionEloss; + mInteractor.recordInteractions = m_interactionRecord; + + auto parameters = boost::apply_visitor([&](const auto& propagator) -> std::unique_ptr<const Acts::CurvilinearParameters> { + auto result = propagator.propagate(startParameters, options); + if (!result.ok()) { + ATH_MSG_ERROR("Got error during propagation:" << result.error() + << ". Returning empty parameters."); + return nullptr; + } + return std::move(result.value().endParameters); + }, *m_varProp); + + return parameters; +} + +ActsPropagationOutput +FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + const Acts::Surface& target, + Acts::NavigationDirection navDir /*= Acts::forward*/, + double pathLimit /*= std::numeric_limits<double>::max()*/) const +{ + using namespace Acts::UnitLiterals; + ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " begin"); + + Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx); + const FaserActsGeometryContext& gctx + //= m_trackingGeometryTool->getGeometryContext(ctx); + = m_trackingGeometryTool->getGeometryContext(ctx ); + + auto anygctx = gctx.any(); + + // Action list and abort list + using ActionList = Acts::ActionList<SteppingLogger, Acts::MaterialInteractor, DebugOutput>; + using AbortConditions = Acts::AbortList<EndOfWorld>; + using Options = Acts::PropagatorOptions<ActionList, AbortConditions>; + + Options options(anygctx, mctx, Acts::LoggerWrapper{*m_logger}); + options.pathLimit = pathLimit; + bool debug = msg().level() == MSG::VERBOSE; + options.debug = debug; + + options.loopProtection + = (Acts::VectorHelpers::perp(startParameters.momentum()) + < m_ptLoopers * 1_MeV); + options.maxStepSize = m_maxStepSize * 1_m; + options.direction = navDir; + + auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>(); + mInteractor.multipleScattering = m_interactionMultiScatering; + mInteractor.energyLoss = m_interactionEloss; + mInteractor.recordInteractions = m_interactionRecord; + + ActsPropagationOutput output; + DebugOutput::result_type debugOutput; + + auto res = boost::apply_visitor([&](const auto& propagator) -> ResultType { + auto result = propagator.propagate(startParameters, target, options); + if (!result.ok()) { + return result.error(); + } + auto& propRes = *result; + + auto steppingResults = propRes.template get<SteppingLogger::result_type>(); + auto debugOutput = propRes.template get<DebugOutput::result_type>(); + auto materialResult = propRes.template get<Acts::MaterialInteractor::result_type>(); + output.first = std::move(steppingResults.steps); + output.second = std::move(materialResult); + return std::make_pair(std::move(output), std::move(debugOutput)); + }, *m_varProp); + + if (!res.ok()) { + ATH_MSG_ERROR("Got error during propagation:" << res.error() << res.error().message() + << ". Returning empty step vector."); + return {}; + } + std::tie(output, debugOutput) = std::move(*res); + + if(debug) { + ATH_MSG_VERBOSE(debugOutput.debugString); + } + + ATH_MSG_VERBOSE("Collected " << output.first.size() << " steps"); + if (output.first.size() == 0) { + ATH_MSG_WARNING("ZERO steps returned by stepper, that is not typically a good sign"); + } + + ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " end"); + + return output; +} + +std::unique_ptr<const Acts::BoundParameters> +FaserActsExtrapolationTool::propagate(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + const Acts::Surface& target, + Acts::NavigationDirection navDir /*= Acts::forward*/, + double pathLimit /*= std::numeric_limits<double>::max()*/) const +{ + using namespace Acts::UnitLiterals; + ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " begin"); + + Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx); + const FaserActsGeometryContext& gctx + //= m_trackingGeometryTool->getGeometryContext(ctx); + = m_trackingGeometryTool->getGeometryContext(ctx); + + auto anygctx = gctx.any(); + + // Action list and abort list + using ActionList = Acts::ActionList<Acts::MaterialInteractor, DebugOutput>; + using AbortConditions = Acts::AbortList<EndOfWorld>; + using Options = Acts::PropagatorOptions<ActionList, AbortConditions>; + + Options options(anygctx, mctx, Acts::LoggerWrapper{*m_logger}); + options.pathLimit = pathLimit; + bool debug = msg().level() == MSG::VERBOSE; + options.debug = debug; + + options.loopProtection + = (Acts::VectorHelpers::perp(startParameters.momentum()) + < m_ptLoopers * 1_MeV); + options.maxStepSize = m_maxStepSize * 1_m; + options.direction = navDir; + + auto& mInteractor = options.actionList.get<Acts::MaterialInteractor>(); + mInteractor.multipleScattering = m_interactionMultiScatering; + mInteractor.energyLoss = m_interactionEloss; + mInteractor.recordInteractions = m_interactionRecord; + + auto parameters = boost::apply_visitor([&](const auto& propagator) -> std::unique_ptr<const Acts::BoundParameters> { + auto result = propagator.propagate(startParameters, target, options); + if (!result.ok()) { + ATH_MSG_ERROR("Got error during propagation: " << result.error() + << ". Returning empty parameters."); + return nullptr; + } + return std::move(result.value().endParameters); + }, *m_varProp); + + return parameters; +} + +Acts::MagneticFieldContext FaserActsExtrapolationTool::getMagneticFieldContext(const EventContext& ctx) const { + SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx}; + if (!readHandle.isValid()) { + std::stringstream msg; + msg << "Failed to retrieve magnetic field condition data " << m_fieldCondObjInputKey.key() << "."; + throw std::runtime_error(msg.str()); + } + const FaserFieldCacheCondObj* fieldCondObj{*readHandle}; + + return Acts::MagneticFieldContext(fieldCondObj); +} + diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsLayerBuilder.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsLayerBuilder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f714148940079b8a10357b93b65c13c2b2328f10 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsLayerBuilder.cxx @@ -0,0 +1,201 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ +// ATHENA +#include "TrackerReadoutGeometry/SiDetectorElement.h" +#include "TrackerReadoutGeometry/SiDetectorElementCollection.h" +#include "TrackerReadoutGeometry/SCT_DetectorManager.h" + +// PACKAGE +#include "FaserActsGeometry/FaserActsLayerBuilder.h" +#include "FaserActsGeometry/FaserActsDetectorElement.h" +#include "FaserActsGeometry/CuboidVolumeBuilder.h" +#include "ActsInterop/IdentityHelper.h" + +// ACTS +#include "Acts/Material/ProtoSurfaceMaterial.hpp" +#include "Acts/Surfaces/CylinderSurface.hpp" +#include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/Geometry/GenericApproachDescriptor.hpp" +#include "Acts/Geometry/ApproachDescriptor.hpp" +#include "Acts/Geometry/ProtoLayer.hpp" +#include "Acts/Geometry/LayerCreator.hpp" +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Utilities/Units.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/BinningType.hpp" + +using Acts::Surface; +using Acts::Transform3D; +using Acts::Translation3D; + +using namespace Acts::UnitLiterals; + +FaserActs::CuboidVolumeBuilder::Config FaserActsLayerBuilder::buildVolume(const Acts::GeometryContext& gctx) +{ + //Acts::CuboidVolumeBuilder::Config cvbConfig; + FaserActs::CuboidVolumeBuilder::Config cvbConfig; + //std::vector<Acts::CuboidVolumeBuilder::VolumeConfig> volumeConfigs = {}; + std::vector<FaserActs::CuboidVolumeBuilder::VolumeConfig> volumeConfigs = {}; + + + for (int iStation=1; iStation<4; iStation++) { + + //Acts::CuboidVolumeBuilder::VolumeConfig volumeConfig; + FaserActs::CuboidVolumeBuilder::VolumeConfig volumeConfig; + + //std::vector<Acts::CuboidVolumeBuilder::LayerConfig> layerConfigs; + std::vector<FaserActs::CuboidVolumeBuilder::LayerConfig> layerConfigs; + layerConfigs.clear(); + + for (int iPlane=0; iPlane<3; iPlane++) { + + m_cfg.station = iStation; + m_cfg.plane = iPlane; + std::vector<std::shared_ptr<const Acts::Surface>> surfaces; + surfaces.clear(); + + + //Acts::CuboidVolumeBuilder::SurfaceConfig surfacecfg; + FaserActs::CuboidVolumeBuilder::SurfaceConfig surfacecfg; + + //Acts::CuboidVolumeBuilder::LayerConfig layercfg; + FaserActs::CuboidVolumeBuilder::LayerConfig layercfg; + layercfg.binsX = 2; + layercfg.binsY = 4; + + buildLayers(gctx, surfaces, layercfg, surfacecfg); + + layercfg.surfaceCfg = surfacecfg; + layercfg.active = true; + + layercfg.surfaces = surfaces; + layerConfigs.push_back(layercfg); + + if (iPlane == 1) { + volumeConfig.position = Acts::Vector3D(0, 0, surfacecfg.position.z()); + } + if (iStation == 0 && iPlane == 1) { + cvbConfig.position = Acts::Vector3D(0, 0, surfacecfg.position.z()); + } + } + + volumeConfig.length = m_trackerDimensions; + volumeConfig.layerCfg = layerConfigs; + volumeConfig.name = "Station_" + std::to_string(iStation); + volumeConfigs.push_back(volumeConfig); + } + + //cvbConfig.position = m_worldCenter; + cvbConfig.length = m_worldDimensions; + cvbConfig.volumeCfg = volumeConfigs; + + return cvbConfig; +} + +void +FaserActsLayerBuilder::buildLayers(const Acts::GeometryContext& gctx, + std::vector<std::shared_ptr<const Surface>>& surfaces, + FaserActs::CuboidVolumeBuilder::LayerConfig& layercfg, + FaserActs::CuboidVolumeBuilder::SurfaceConfig& surfacecfg) +{ + + auto siDetMng = static_cast<const TrackerDD::SCT_DetectorManager*>(m_cfg.mng); + + for (int iRow = 0; iRow < 4; iRow++) { + for (int iModule = -1; iModule < 2; iModule++) { + for (int iSensor = 0; iSensor < 2; iSensor++) { + //for (int iSensor = 0; iSensor < 1; iSensor++) { // only use the first sensor to construct the surface + + if (iModule == 0) continue; + const TrackerDD::SiDetectorElement* siDetElement = siDetMng->getDetectorElement(m_cfg.station, m_cfg.plane, iRow, iModule, iSensor) ; + + if (logger().doPrint(Acts::Logging::VERBOSE)) { + ACTS_VERBOSE("Found SCT sensor (" << m_cfg.station << "/" << m_cfg.plane << "/" << iRow << "/" << iModule << "/" << iSensor << ") with global center at (" << siDetElement->center().x() << ", " << siDetElement->center().y() << ", " << siDetElement->center().z() << ")." ); + } + + auto element = std::make_shared<const FaserActsDetectorElement>(siDetElement); + + surfaces.push_back(element->surface().getSharedPtr()); + + m_cfg.elementStore->push_back(element); + + m_ModuleWidth = siDetElement->width(); + m_ModuleLength = siDetElement->length(); + } + } + } + + + Acts::ProtoLayer pl(gctx, surfaces); + + if (logger().doPrint(Acts::Logging::VERBOSE)) { + ACTS_VERBOSE(" Plane's zMin / zMax: " << pl.min(Acts::binZ) << " / " << pl.max(Acts::binZ)); + } + + std::shared_ptr<const Acts::ProtoSurfaceMaterial> materialProxy = nullptr; + + double layerZ = 0.5 * (pl.min(Acts::binZ) + pl.max(Acts::binZ)); + double layerThickness = (pl.max(Acts::binZ) - pl.min(Acts::binZ)); + double layerZInner = layerZ - layerThickness/2.; + double layerZOuter = layerZ + layerThickness/2.; + + surfacecfg.position = Acts::Vector3D(0, 0, layerZ); + + if (std::abs(layerZInner) > std::abs(layerZOuter)) std::swap(layerZInner, layerZOuter); + + auto rBounds = std::make_shared<const Acts::RectangleBounds>( 0.5*layercfg.binsY*m_ModuleWidth, 0.5*layercfg.binsX*m_ModuleLength ) ; + + auto transformNominal + = std::make_shared<const Transform3D>(Translation3D(0., 0., layerZ)); + + auto transformInner + = std::make_shared<const Transform3D>(Translation3D(0., 0., layerZInner)); + + auto transformOuter + = std::make_shared<const Transform3D>(Translation3D(0., 0., layerZOuter)); + + std::shared_ptr<Acts::PlaneSurface> innerBoundary + = Acts::Surface::makeShared<Acts::PlaneSurface>(transformInner, rBounds); + + std::shared_ptr<Acts::PlaneSurface> nominalSurface + = Acts::Surface::makeShared<Acts::PlaneSurface>(transformNominal, rBounds); + + std::shared_ptr<Acts::PlaneSurface> outerBoundary + = Acts::Surface::makeShared<Acts::PlaneSurface>(transformOuter, rBounds); + + size_t matBinsX = layercfg.binsX; + size_t matBinsY = layercfg.binsY; + + Acts::BinUtility materialBinUtil( + matBinsX, -0.5*layercfg.binsY*m_ModuleWidth, 0.5*layercfg.binsY*m_ModuleWidth, Acts::open, Acts::binX); + materialBinUtil += Acts::BinUtility( + matBinsY, -0.5*layercfg.binsX*m_ModuleLength, 0.5*layercfg.binsX*m_ModuleLength, Acts::open, Acts::binY, transformInner); + + materialProxy + = std::make_shared<const Acts::ProtoSurfaceMaterial>(materialBinUtil); + + ACTS_VERBOSE("[L] Layer is marked to carry support material on Surface ( " + "inner=0 / center=1 / outer=2 ) : " << "inner"); + ACTS_VERBOSE("with binning: [" << matBinsX << ", " << matBinsY << "]"); + + ACTS_VERBOSE("Created ApproachSurfaces for layer at:"); + ACTS_VERBOSE(" - inner: Z=" << layerZInner); + ACTS_VERBOSE(" - central: Z=" << layerZ); + ACTS_VERBOSE(" - outer: Z=" << layerZOuter); + + + // set material on inner + // @TODO: make this configurable somehow + innerBoundary->assignSurfaceMaterial(materialProxy); + + std::vector<std::shared_ptr<const Acts::Surface>> aSurfaces; + aSurfaces.push_back(std::move(innerBoundary)); + aSurfaces.push_back(std::move(nominalSurface)); + aSurfaces.push_back(std::move(outerBoundary)); + + layercfg.approachDescriptor = new Acts::GenericApproachDescriptor(aSurfaces); + +} + diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsObjWriterTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsObjWriterTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..61a84e4c5d2617225261c85fdbb0a3195340c21b --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsObjWriterTool.cxx @@ -0,0 +1,86 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsObjWriterTool.h" + +// std +#include <iostream> +#include <vector> + +// Gaudi / Athena +#include "GaudiKernel/IInterface.h" + +#include "FaserActsGeometry/FaserActsGeometryContext.h" +// ACTS +#include "Acts/Geometry/TrackingGeometry.hpp" + +// PRIVATE +#include "util/ObjSurfaceWriter.h" +#include "util/ObjTrackingGeometryWriter.h" + +FaserActsObjWriterTool::FaserActsObjWriterTool(const std::string& type, const std::string& name, + const IInterface* parent) + : AthAlgTool(type, name, parent) +{ + //declareProperty("OutputDirectory", m_outputDirectory = ""); + //declareProperty("SubDetectors", m_subDetectors = {}); +} + +StatusCode +FaserActsObjWriterTool::initialize() +{ + + + return StatusCode::SUCCESS; +} + +void +FaserActsObjWriterTool::write(const FaserActsGeometryContext& gctx, const Acts::TrackingGeometry& tg) const +{ + + const auto& ctx = Gaudi::Hive::currentContext(); + std::stringstream ss; + ss << ctx.eventID().run_number() << "_" << ctx.eventID().event_number(); + + using namespace std::string_literals; + + std::vector<std::shared_ptr<Acts::ObjSurfaceWriter>> subWriters; + std::vector<std::shared_ptr<std::ofstream>> subStreams; + + for (const auto& sdet : m_subDetectors) { + auto sdStream = std::shared_ptr<std::ofstream>(new std::ofstream); + std::string sdOutputName = m_outputDirectory + "/"s + sdet + "_" + ss.str() + ".obj"s; + sdStream->open(sdOutputName); + // object surface writers + Acts::ObjSurfaceWriter::Config sdObjWriterConfig(sdet, + Acts::Logging::INFO); + sdObjWriterConfig.filePrefix = ""; + sdObjWriterConfig.outputPhiSegments = 10; + sdObjWriterConfig.outputPrecision = 6; + sdObjWriterConfig.outputScalor = 1.; + sdObjWriterConfig.outputThickness = 1.; + sdObjWriterConfig.outputSensitive = true; + sdObjWriterConfig.outputLayerSurface = false; + sdObjWriterConfig.outputStream = sdStream; + auto sdObjWriter + = std::make_shared<Acts::ObjSurfaceWriter>(sdObjWriterConfig); + // push back + subWriters.push_back(sdObjWriter); + subStreams.push_back(sdStream); + } + + + // configure the tracking geometry writer + Acts::ObjTrackingGeometryWriter::Config tgObjWriterConfig( + "ObjTrackingGeometryWriter", Acts::Logging::INFO); + tgObjWriterConfig.surfaceWriters = subWriters; + tgObjWriterConfig.filePrefix = ""; + tgObjWriterConfig.sensitiveGroupPrefix = ""; + tgObjWriterConfig.layerPrefix = ""; + // the tracking geometry writers + auto tgObjWriter + = std::make_shared<Acts::ObjTrackingGeometryWriter>(tgObjWriterConfig); + + tgObjWriter->write(gctx.any(), tg); +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsPropStepRootWriterSvc.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsPropStepRootWriterSvc.cxx new file mode 100644 index 0000000000000000000000000000000000000000..44e93ff0e3c1234d996e207d1d59e507a0c05e56 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsPropStepRootWriterSvc.cxx @@ -0,0 +1,182 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsPropStepRootWriterSvc.h" +#include "GaudiKernel/IInterface.h" + +#include "Acts/Propagator/detail/SteppingLogger.hpp" +#include "Acts/Geometry/TrackingVolume.hpp" + + +#include <vector> +#include <deque> +#include <mutex> +#include <thread> + +#include "TTree.h" +#include "TFile.h" + +FaserActsPropStepRootWriterSvc::FaserActsPropStepRootWriterSvc( const std::string& name, ISvcLocator* svc ) +: base_class(name, svc) { +} + +StatusCode +FaserActsPropStepRootWriterSvc::initialize() +{ + + ATH_MSG_INFO("Starting writer thread"); + m_doEnd = false; + m_writeThread = std::thread(&FaserActsPropStepRootWriterSvc::writeThread, this); + + std::string filePath = m_filePath; + m_outputFile = TFile::Open(filePath.c_str(), "RECREATE"); + if(m_outputFile == nullptr) { + ATH_MSG_ERROR("Unable to open output file at " << m_filePath); + return StatusCode::FAILURE; + } + m_outputFile->cd(); + + std::string treeName = m_treeName; + m_outputTree = new TTree(treeName.c_str(), "Acts Propagation Steps"); + if(m_outputTree == nullptr) { + ATH_MSG_ERROR("Unable to create TTree"); + return StatusCode::FAILURE; + } + + m_outputTree->Branch("event_nr", &m_eventNum); + m_outputTree->Branch("step_x", &m_s_pX); + m_outputTree->Branch("step_y", &m_s_pY); + m_outputTree->Branch("step_z", &m_s_pZ); + m_outputTree->Branch("step_r", &m_s_pR); + m_outputTree->Branch("volume_id", &m_s_volumeID); + m_outputTree->Branch("boundary_id", &m_s_boundaryID); + m_outputTree->Branch("layer_id", &m_s_layerID); + m_outputTree->Branch("approach_id", &m_s_approachID); + m_outputTree->Branch("sensitive_id", &m_s_sensitiveID); + + + return StatusCode::SUCCESS; +} + +StatusCode +FaserActsPropStepRootWriterSvc::finalize() +{ + ATH_MSG_INFO("Waiting for writer thread to finish."); + m_doEnd = true; + m_writeThread.join(); + ATH_MSG_INFO("Writer thread has terminated."); + + return StatusCode::SUCCESS; +} + +void +FaserActsPropStepRootWriterSvc::write(const StepVector& steps) +{ + + auto ctx = Gaudi::Hive::currentContext(); + + std::lock_guard<std::mutex> lock(m_writeMutex); + + //for(size_t i=0;i<ecells.size();++i) { + //m_queue.emplace_back(ctx.eventID().event_number(), std::move(ecells[i])); + //} + m_queue.emplace_back(ctx.eventID().event_number(), steps); +} + +void +FaserActsPropStepRootWriterSvc::writeThread() +{ + using namespace std::chrono_literals; + // wait until we have events + while(m_queue.size() == 0) { + std::this_thread::sleep_for(2s); + if (m_doEnd) return; + } + + while(true) { + std::unique_lock<std::mutex> lock(m_writeMutex); + + if (m_queue.empty()) { + lock.unlock(); + if (!m_doEnd) { + std::this_thread::sleep_for(0.5s); + continue; + } else { + ATH_MSG_INFO("Writer thread caught termination signal. Shutting down."); + end(); + return; + } + } + + queue_item_t queue_item = std::move(m_queue.front()); + m_queue.pop_front(); + + lock.unlock(); + + size_t eventNum = queue_item.first; + StepVector steps = std::move(queue_item.second); + + doWrite(steps, eventNum); + } + +} + +void +FaserActsPropStepRootWriterSvc::doWrite(const StepVector& steps, size_t evtNum) +{ + using ag = Acts::GeometryID; + + m_eventNum = evtNum; + m_s_pX.clear(); + m_s_pY.clear(); + m_s_pZ.clear(); + m_s_pR.clear(); + m_s_volumeID.clear(); + m_s_boundaryID.clear(); + m_s_layerID.clear(); + m_s_approachID.clear(); + m_s_sensitiveID.clear(); + + for(const auto& step : steps) { + Acts::GeometryID::Value volumeID = 0; + Acts::GeometryID::Value boundaryID = 0; + Acts::GeometryID::Value layerID = 0; + Acts::GeometryID::Value approachID = 0; + Acts::GeometryID::Value sensitiveID = 0; + // get the identification from the surface first + if (step.surface) { + auto geoID = step.surface->geoID(); + sensitiveID = geoID.sensitive(); + approachID = geoID.approach(); + layerID = geoID.layer(); + boundaryID = geoID.boundary(); + volumeID = geoID.volume(); + } + // a current volume overwrites the surface tagged one + if (step.volume) { + volumeID = step.volume->geoID().volume(); + } + // now fill + m_s_sensitiveID.push_back(sensitiveID); + m_s_approachID.push_back(approachID); + m_s_layerID.push_back(layerID); + m_s_boundaryID.push_back(boundaryID); + m_s_volumeID.push_back(volumeID); + + m_s_pX.push_back(step.position.x()); + m_s_pY.push_back(step.position.y()); + m_s_pZ.push_back(step.position.z()); + m_s_pR.push_back(Acts::VectorHelpers::perp(step.position)); + } + + m_outputTree->Fill(); +} + +void +FaserActsPropStepRootWriterSvc::end() +{ + m_outputFile->cd(); + m_outputTree->Write(); + //m_outputFile->Close(); +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fe4e3a99fc7604fac4b523cf6413e2a0239886fb --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx @@ -0,0 +1,157 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsTrackingGeometrySvc.h" + +// ATHENA +#include "TrackerReadoutGeometry/SCT_DetectorManager.h" +#include "StoreGate/StoreGateSvc.h" +#include "GaudiKernel/EventContext.h" +#include "TrackerIdentifier/FaserSCT_ID.h" + +// ACTS +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Geometry/ITrackingVolumeBuilder.hpp" +#include "Acts/Geometry/LayerArrayCreator.hpp" +#include "Acts/Geometry/SurfaceArrayCreator.hpp" +#include "Acts/Geometry/LayerCreator.hpp" +#include "Acts/Geometry/TrackingVolumeArrayCreator.hpp" +#include "Acts/Geometry/CylinderVolumeHelper.hpp" +#include "Acts/Geometry/TrackingGeometryBuilder.hpp" +#include "Acts/Geometry/CylinderVolumeBuilder.hpp" +//#include "Acts/Geometry/CuboidVolumeBuilder.hpp" +#include "FaserActsGeometry/CuboidVolumeBuilder.h" +#include "Acts/ActsVersion.hpp" +#include "Acts/Utilities/Units.hpp" + +// PACKAGE +#include "FaserActsGeometry/FaserActsLayerBuilder.h" +#include "FaserActsGeometry/FaserActsDetectorElement.h" +#include "FaserActsGeometry/FaserActsAlignmentStore.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "ActsInterop/IdentityHelper.h" +#include "ActsInterop/Logger.h" + +using namespace Acts::UnitLiterals; + +FaserActsTrackingGeometrySvc::FaserActsTrackingGeometrySvc(const std::string& name, ISvcLocator* svc) + : base_class(name,svc), + m_detStore("StoreGateSvc/DetectorStore", name) +{ + m_elementStore = std::make_shared<std::vector<std::shared_ptr<const FaserActsDetectorElement>>>(); +} + +StatusCode +FaserActsTrackingGeometrySvc::initialize() +{ + ATH_MSG_INFO(name() << " is initializing"); + ATH_MSG_INFO("Acts version is: v" << Acts::VersionMajor << "." + << Acts::VersionMinor << "." + << Acts::VersionPatch + << " [" << Acts::CommitHash << "]"); + + ATH_CHECK ( m_detStore->retrieve(p_SCTManager, "SCT") ); + + Acts::LayerArrayCreator::Config lacCfg; + auto layerArrayCreator = std::make_shared<const Acts::LayerArrayCreator>( + lacCfg, makeActsAthenaLogger(this, "LayArrCrtr", "ActsTGSvc")); + + Acts::TrackingVolumeArrayCreator::Config tvcCfg; + auto trackingVolumeArrayCreator + = std::make_shared<const Acts::TrackingVolumeArrayCreator>( + tvcCfg, makeActsAthenaLogger(this, "TrkVolArrCrtr", "ActsTGSvc")); + + Acts::CylinderVolumeHelper::Config cvhConfig; + cvhConfig.layerArrayCreator = layerArrayCreator; + cvhConfig.trackingVolumeArrayCreator = trackingVolumeArrayCreator; + + auto cylinderVolumeHelper + = std::make_shared<const Acts::CylinderVolumeHelper>( + cvhConfig, makeActsAthenaLogger(this, "CylVolHlpr", "ActsTGSvc")); + + Acts::TrackingGeometryBuilder::Config tgbConfig; + try { + // SCT + tgbConfig.trackingVolumeBuilders.push_back([&]( + const auto& gctx, const auto& /*inner*/, const auto&) { + auto tv = makeVolumeBuilder(gctx, p_SCTManager); + return tv->trackingVolume(gctx); + }); + + } + catch (const std::invalid_argument& e) { + ATH_MSG_ERROR(e.what()); + return StatusCode::FAILURE; + } + + + auto trackingGeometryBuilder + = std::make_shared<const Acts::TrackingGeometryBuilder>(tgbConfig, + makeActsAthenaLogger(this, "TrkGeomBldr", "ActsTGSvc")); + + + // default geometry context, this is nominal + FaserActsGeometryContext constructionContext; + constructionContext.construction = true; + + m_trackingGeometry = trackingGeometryBuilder + ->trackingGeometry(constructionContext.any()); + + ATH_MSG_VERBOSE("Building nominal alignment store"); + FaserActsAlignmentStore* nominalAlignmentStore = new FaserActsAlignmentStore(); + + populateAlignmentStore(nominalAlignmentStore); + + // manage ownership + m_nominalAlignmentStore = std::unique_ptr<const FaserActsAlignmentStore>(nominalAlignmentStore); + + ATH_MSG_INFO("Acts TrackingGeometry construction completed"); + + return StatusCode::SUCCESS; +} + +std::shared_ptr<const Acts::TrackingGeometry> +FaserActsTrackingGeometrySvc::trackingGeometry() { + + ATH_MSG_VERBOSE("Retrieving tracking geometry"); + return m_trackingGeometry; +} + +std::shared_ptr<const Acts::ITrackingVolumeBuilder> +FaserActsTrackingGeometrySvc::makeVolumeBuilder(const Acts::GeometryContext& gctx, const TrackerDD::SCT_DetectorManager* manager) +{ + std::string managerName = manager->getName(); + + std::shared_ptr<FaserActsLayerBuilder> gmLayerBuilder; + + FaserActsLayerBuilder::Config cfg; + cfg.subdetector = FaserActsDetectorElement::Subdetector::SCT; + cfg.mng = static_cast<const TrackerDD::SCT_DetectorManager*>(manager); + cfg.elementStore = m_elementStore; + gmLayerBuilder = std::make_shared<FaserActsLayerBuilder>(cfg, + makeActsAthenaLogger(this, "GMLayBldr", "ActsTGSvc")); + auto cvbConfig = gmLayerBuilder->buildVolume(gctx); + auto cvb = std::make_shared<const FaserActs::CuboidVolumeBuilder>(cvbConfig); + + return cvb; +} + +void +FaserActsTrackingGeometrySvc::populateAlignmentStore(FaserActsAlignmentStore *store) const +{ + // populate the alignment store with all detector elements + m_trackingGeometry->visitSurfaces( + [store](const Acts::Surface* srf) { + const Acts::DetectorElementBase* detElem = srf->associatedDetectorElement(); + const auto* gmde = dynamic_cast<const FaserActsDetectorElement*>(detElem); + gmde->storeTransform(store); + }); +} + +const FaserActsAlignmentStore* +FaserActsTrackingGeometrySvc::getNominalAlignmentStore() const +{ + return m_nominalAlignmentStore.get(); +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometryTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometryTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ae50ea2756e3c705f6eb9f1942849c6c9ec5b331 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometryTool.cxx @@ -0,0 +1,64 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsTrackingGeometryTool.h" + +// ATHENA +#include "GaudiKernel/EventContext.h" + +// PACKAGE +#include "FaserActsGeometry/FaserActsAlignmentStore.h" +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h" + +// STL +#include <iostream> +#include <memory> + +FaserActsTrackingGeometryTool::FaserActsTrackingGeometryTool(const std::string& type, const std::string& name, + const IInterface* parent) + : base_class(type, name, parent), + m_trackingGeometrySvc("FaserActsTrackingGeometrySvc", name) +{ +} + +StatusCode +FaserActsTrackingGeometryTool::initialize() +{ + ATH_MSG_INFO(name() << " initializing"); + + ATH_CHECK( m_trackingGeometrySvc.retrieve() ); + + ATH_CHECK( m_rchk.initialize() ); + + return StatusCode::SUCCESS; +} + +std::shared_ptr<const Acts::TrackingGeometry> +FaserActsTrackingGeometryTool::trackingGeometry() const +{ + return m_trackingGeometrySvc->trackingGeometry(); +} + +const FaserActsGeometryContext& +FaserActsTrackingGeometryTool::getGeometryContext(const EventContext& ctx) const +{ + ATH_MSG_DEBUG("Creating alignment context for event"); + SG::ReadCondHandle<FaserActsGeometryContext> rch(m_rchk, ctx); + + if(!rch.isValid()) { + ATH_MSG_ERROR("Creating alignment context failed: read cond handle invalid!"); + } + + return **rch; +} + +FaserActsGeometryContext +FaserActsTrackingGeometryTool::getNominalGeometryContext() const +{ + + FaserActsGeometryContext gctx; + gctx.alignmentStore = m_trackingGeometrySvc->getNominalAlignmentStore(); + + return gctx; +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsWriteTrackingGeometry.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsWriteTrackingGeometry.cxx new file mode 100755 index 0000000000000000000000000000000000000000..3e05c12a23433253b0050966f530103aa017c656 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsWriteTrackingGeometry.cxx @@ -0,0 +1,49 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ +#include "FaserActsGeometry/FaserActsWriteTrackingGeometry.h" + +// ATHENA +#include "AthenaKernel/RNGWrapper.h" +#include "Acts/Utilities/Logger.hpp" +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "GaudiKernel/ISvcLocator.h" + +// PACKAGE +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "ActsInterop/Logger.h" + +// STL +#include <string> + +FaserActsWriteTrackingGeometry::FaserActsWriteTrackingGeometry(const std::string& name, + ISvcLocator* pSvcLocator) + : AthReentrantAlgorithm(name, pSvcLocator) +{ +} + +StatusCode FaserActsWriteTrackingGeometry::initialize() { + ATH_MSG_INFO("initializing"); + + ATH_CHECK(m_objWriterTool.retrieve()); + ATH_CHECK(m_trackingGeometryTool.retrieve()); + + return StatusCode::SUCCESS; +} + +StatusCode FaserActsWriteTrackingGeometry::execute(const EventContext& /*ctx*/ ) const { + auto trackingGeometry = m_trackingGeometryTool->trackingGeometry(); + + // Use nominal context + //FaserActsGeometryContext defGctx; + //const FaserActsGeometryContext& gctx = m_trackingGeometryTool->getGeometryContext(ctx); + const FaserActsGeometryContext& gctx = m_trackingGeometryTool->getNominalGeometryContext(); + + m_objWriterTool->write(gctx, *trackingGeometry); + return StatusCode::SUCCESS; +} + +StatusCode FaserActsWriteTrackingGeometry::finalize() { + return StatusCode::SUCCESS; +} diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserNominalAlignmentCondAlg.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserNominalAlignmentCondAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b63cf8d48290c78204ed0a04670a412047a05b18 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/FaserNominalAlignmentCondAlg.cxx @@ -0,0 +1,103 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserNominalAlignmentCondAlg.h" + +// ATHENA +#include "StoreGate/WriteCondHandle.h" +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/EventIDBase.h" +#include "GaudiKernel/EventIDRange.h" + +// PACKAGE +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h" +#include "FaserActsGeometry/FaserActsDetectorElement.h" +#include "FaserActsGeometry/FaserActsAlignmentStore.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" + +// ACTS +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Surfaces/Surface.hpp" + +FaserNominalAlignmentCondAlg::FaserNominalAlignmentCondAlg( const std::string& name, + ISvcLocator* pSvcLocator ) : + ::AthAlgorithm( name, pSvcLocator ), + m_cs("CondSvc",name), + m_trackingGeometrySvc("FaserActsTrackingGeometrySvc", name) +{ +} + +FaserNominalAlignmentCondAlg::~FaserNominalAlignmentCondAlg() {} + +StatusCode FaserNominalAlignmentCondAlg::initialize() { + ATH_MSG_DEBUG(name() << "::" << __FUNCTION__); + + if (m_cs.retrieve().isFailure()) { + ATH_MSG_ERROR("unable to retrieve CondSvc"); + } + + if (m_wchk.initialize().isFailure()) { + ATH_MSG_ERROR("unable to initialize WriteCondHandle with key" << m_wchk.key() ); + return StatusCode::FAILURE; + } + + if (m_cs->regHandle(this, m_wchk).isFailure()) { + ATH_MSG_ERROR("unable to register WriteCondHandle " << m_wchk.fullKey() + << " with CondSvc"); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode FaserNominalAlignmentCondAlg::finalize() { + ATH_MSG_DEBUG(name() << "::" << __FUNCTION__); + return StatusCode::SUCCESS; +} + +StatusCode FaserNominalAlignmentCondAlg::execute() { + ATH_MSG_DEBUG(name() << "::" << __FUNCTION__); + + SG::WriteCondHandle<FaserActsGeometryContext> wch(m_wchk); + + EventIDBase now(getContext().eventID()); + + // do we have a valid m_wch for current time? + if ( wch.isValid(now) ) { + ATH_MSG_DEBUG("CondHandle is already valid for " << now + << ". In theory this should not be called, but may happen" + << " if multiple concurrent events are being processed out of order."); + + } else { + + ATH_MSG_DEBUG(" CondHandle " << wch.key() + << " not valid now (" << now << "). Setting nominal alignment cond"); + + + EventIDBase start(1, EventIDBase::UNDEFEVT); + EventIDBase end(1, EventIDBase::UNDEFEVT); + start.set_lumi_block(0); + end.set_lumi_block(9999); // this is not actually forever + + EventIDRange r(start, end); + + ATH_MSG_DEBUG("Will register nominal alignment for range: " << r); + + // get a nominal alignment store from the tracking geometry service + // and plug it into a geometry context + auto gctx = std::make_unique<FaserActsGeometryContext>(); + gctx->alignmentStore = m_trackingGeometrySvc->getNominalAlignmentStore(); + + // and write it to the conditions store + if (wch.record(r, gctx.release()).isFailure()) { + ATH_MSG_ERROR("could not record nominal FaserActsGeometryContext " << wch.key() + << " with EventRange " << r); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG("WCH is valid now? " << wch.isValid(now)); + } + return StatusCode::SUCCESS; +} diff --git a/Tracking/Acts/FaserActsGeometry/src/components/FaserActsGeometry_entries.cxx b/Tracking/Acts/FaserActsGeometry/src/components/FaserActsGeometry_entries.cxx new file mode 100755 index 0000000000000000000000000000000000000000..9ad80a9d5d68164965de8c40d355bd9fc02e05ae --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/components/FaserActsGeometry_entries.cxx @@ -0,0 +1,34 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsGeometry/FaserActsExtrapolationAlg.h" +#include "FaserActsGeometry/FaserActsWriteTrackingGeometry.h" +#include "FaserActsGeometry/FaserActsTrackingGeometrySvc.h" +#include "FaserActsGeometry/FaserActsExtrapolationTool.h" +#include "FaserActsGeometry/FaserActsObjWriterTool.h" +#include "FaserActsGeometry/FaserActsTrackingGeometryTool.h" +#include "FaserActsGeometry/FaserActsPropStepRootWriterSvc.h" +#include "FaserActsGeometry/FaserActsAlignmentCondAlg.h" +#include "FaserActsGeometry/FaserNominalAlignmentCondAlg.h" +//#include "FaserActsGeometry/FaserActsKalmanFilterAlg.h" +//#include "FaserActsGeometry/FaserActsExCellWriterSvc.h" +//#include "FaserActsGeometry/FaserActsMaterialTrackWriterSvc.h" +//#include "FaserActsGeometry/GeomShiftCondAlg.h" +//#include "FaserActsGeometry/FaserActsWriteTrackingGeometryTransforms.h" + + +DECLARE_COMPONENT( FaserActsTrackingGeometrySvc ) +DECLARE_COMPONENT( FaserActsTrackingGeometryTool ) +DECLARE_COMPONENT( FaserActsExtrapolationAlg ) +DECLARE_COMPONENT( FaserActsExtrapolationTool ) +DECLARE_COMPONENT( FaserActsPropStepRootWriterSvc ) +DECLARE_COMPONENT( FaserActsObjWriterTool ) +DECLARE_COMPONENT( FaserActsWriteTrackingGeometry ) +DECLARE_COMPONENT( FaserActsAlignmentCondAlg ) +//DECLARE_COMPONENT( FaserActsKalmanFilterAlg ) +//DECLARE_COMPONENT( FaserNominalAlignmentCondAlg ) +//DECLARE_COMPONENT( FaserActsExCellWriterSvc ) +//DECLARE_COMPONENT( FaserActsMaterialTrackWriterSvc ) +//DECLARE_COMPONENT( FaserActsWriteTrackingGeometryTransforms ) +//DECLARE_COMPONENT( FaserGeomShiftCondAlg ) diff --git a/Tracking/Acts/FaserActsGeometry/src/util/ObjHelper.cxx b/Tracking/Acts/FaserActsGeometry/src/util/ObjHelper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..66181d9810cb614df41406f8df5ebe45d5dc134e --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/util/ObjHelper.cxx @@ -0,0 +1,195 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +// This file was largely imported from the Acts testing framework + +#include "ObjHelper.h" + +#include <vector> + +void +ObjHelper::writeVTN(std::ofstream& stream, + VtnCounter& vtnCounter, + double scalor, + const Acts::Vector3D& vertex, + const std::string& vtntype, + bool point) +{ + // in case you make a point + unsigned int cp = 0; + // the counter + if (vtntype == "v") { + ++vtnCounter.vcounter; + cp = vtnCounter.vcounter; + } else if (vtntype == "t") { + ++vtnCounter.vtcounter; + cp = vtnCounter.vtcounter; + } else if (vtntype == "n") { + ++vtnCounter.ncounter; + cp = vtnCounter.ncounter; + } else + return; + + // write out the vertex, texture vertex, normal + stream << vtntype << " " << scalor * vertex.x() << " " << scalor * vertex.y() + << " " << scalor * vertex.z() << '\n'; + // we create a point if needed + if (point) stream << "p " << cp; +} + +void +ObjHelper::constructVerticalFaces( + std::ofstream& stream, + unsigned int start, + const std::vector<unsigned int>& vsides) +{ + // construct the vertical faces + size_t nsides = vsides.size(); + unsigned int sstart = start; + for (auto vside : vsides) { + if (vside) { + // start streaming the side + // all but the last + if (start - sstart < nsides - 1) { + stream << "f " << start << " " << start + 1 << " "; + stream << start + nsides + 1 << " " << start + nsides; + } else { + stream << "f " << start << " " << sstart << " "; + stream << sstart + nsides << " " << start + nsides; + } + } + stream << '\n'; + // increase + ++start; + } +} + +void +ObjHelper::writePlanarFace(std::ofstream& stream, + VtnCounter& vtnCounter, + double scalor, + const std::vector<Acts::Vector3D>& vertices, + double thickness, + const std::vector<unsigned int>& vsides) +{ + // minimum 3 vertices needed + if (vertices.size() < 3) return; + // the first vertex + unsigned int fvertex = vtnCounter.vcounter + 1; + // lets create the normal vector first + Acts::Vector3D sideOne = vertices[1] - vertices[0]; + Acts::Vector3D sideTwo = vertices[2] - vertices[1]; + Acts::Vector3D nvector(sideTwo.cross(sideOne).normalized()); + // write the normal vector + writeVTN(stream, vtnCounter, scalor, nvector, "n"); + // thickness or not thickness + std::vector<int> sides = {1}; + if (thickness != 0.) sides = {-1, 1}; + // now write all the vertices - this works w/wo thickness + for (auto side : sides) { + // save the current vertex counter + unsigned int cvc = vtnCounter.vcounter; + // loop over the sides + for (auto v : vertices) + writeVTN(stream, + vtnCounter, + scalor, + v + (0.5 * side * thickness) * nvector, + "v"); + // decide if you want to add texture + std::string vtphr + = "/"; // vtnCounter.vtcounter ? "/"+std::to_string(vtcounter) : "/"; + std::string ntphr = "/" + std::to_string(vtnCounter.ncounter); + // now write the face + stream << "f "; + for (size_t i=0;i<vertices.size();++i) stream << ++cvc << vtphr << ntphr << " "; + stream << '\n'; + } + // now process the vertical sides + constructVerticalFaces(stream, fvertex, vsides); +} + +void +ObjHelper::writeTube(std::ofstream& stream, + VtnCounter& vtnCounter, + double scalor, + unsigned int nSegments, + const Acts::Transform3D& transform, + double r, + double hZ, + double thickness) +{ + // flip along plus/minus and declare the faces + std::vector<int> flip = {-1, 1}; + std::vector<int> vfaces = {1, 2, 4, 3}; + // the number of phisteps + double phistep = 2 * M_PI / nSegments; + // make it twice if necessary + std::vector<double> roffsets = {0.}; + if (thickness != 0.) roffsets = {-0.5 * thickness, 0.5 * thickness}; + // now loop over the thickness and make an outer and inner + unsigned int cvc = vtnCounter.vcounter; + size_t iside = 0; + for (auto t : roffsets) { + size_t iphi = 0; + // loop over phi steps + for (; iphi < nSegments; ++iphi) { + // currentPhi + double phi = -M_PI + iphi * phistep; + for (auto iflip : flip) { + // create the vertex + Acts::Vector3D point(transform * Acts::Vector3D((r + t) * cos(phi), + (r + t) * sin(phi), + iflip * hZ)); + // write the normal vector + writeVTN(stream, vtnCounter, scalor, point, "v"); + } + } + // now create the faces + iphi = 0; + // side offset for faces + unsigned int soff = 2 * iside * nSegments; + for (; iphi < nSegments - 1; ++iphi) { + // output to file + stream << "f "; + for (auto face : vfaces) stream << soff + cvc + (2 * iphi) + face << " "; + stream << '\n'; + } + // close the loop + stream << "f " << soff + cvc + (2 * iphi) + 1 << " " + << soff + cvc + (2 * iphi) + 2 << " " << soff + cvc + 2 << " " + << soff + cvc + 1 << '\n'; + // new line at the end of the line + stream << '\n'; + ++iside; + } + + // construct the sides at the end when all vertices are done + Acts::Vector3D nvectorSide = transform.rotation().col(2); + // write the normal vector @todo flip sides + writeVTN(stream, vtnCounter, scalor, nvectorSide, "n"); + std::string ntphr = "//" + std::to_string(vtnCounter.ncounter); + + if (thickness != 0.) { + // loop over the two sides + for (iside = 0; iside < 2; ++iside) { + // rest iphi + size_t iphi = 0; + for (; iphi < nSegments - 1; ++iphi) { + stream << "f "; + unsigned int base = cvc + (2 * iphi) + 1; + stream << iside + base << ntphr << " "; + stream << iside + base + 2 << ntphr << " "; + stream << iside + base + (2 * nSegments) + 2 << ntphr << " "; + stream << iside + base + (2 * nSegments) << ntphr << '\n'; + } + // close the loop + stream << "f "; + stream << iside + cvc + (2 * iphi) + 1 << ntphr << " "; + stream << iside + cvc + 1 << ntphr << " "; + stream << iside + cvc + 1 + (2 * nSegments) << ntphr << " "; + stream << iside + cvc + (2 * iphi) + 1 + (2 * nSegments) << ntphr << '\n'; + } + } +} diff --git a/Tracking/Acts/FaserActsGeometry/src/util/ObjHelper.h b/Tracking/Acts/FaserActsGeometry/src/util/ObjHelper.h new file mode 100644 index 0000000000000000000000000000000000000000..2c55113fc96b4a257267c1074f7a5e409e64bd87 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/util/ObjHelper.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +// This file was largely imported from the Acts testing framework + +#pragma once + +#include <fstream> +#include <vector> +#include "Acts/Utilities/Definitions.hpp" + + +namespace ObjHelper { + + /// This is the counter struct for keeping track of the vertices + struct VtnCounter + { + unsigned int vcounter = 0; + unsigned int vtcounter = 0; + unsigned int ncounter = 0; + }; + + /// This will write a vertex to the fstream + /// @param stream is the stream where to write to + /// @param vertex is the vertex to be written out + /// @param cvertex is the current vertex number + void + writeVTN(std::ofstream& stream, + VtnCounter& vtnCounter, + double scalor, + const Acts::Vector3D& vertex, + const std::string& vtntype = "v", + bool point = false); + + /// construct vertical faces + /// this takes a range and constructs faces + void + constructVerticalFaces(std::ofstream& stream, + unsigned int start, + const std::vector<unsigned int>& vsides); + + /// This will write a planar face + /// - normal is given by cross product + /// + /// @param stream is the stream where to write to + /// @param face is the face to be written out + /// @param cvertex is the current vertex number + /// @param thickness is the (optional) thickness + void + writePlanarFace(std::ofstream& stream, + VtnCounter& vtnCounter, + double scalor, + const std::vector<Acts::Vector3D>& vertices, + double thickness = 0., + const std::vector<unsigned int>& vsides = {}); + + /// This will write a cylindrical object + /// + /// @param stream is the stream where to write to + void + writeTube(std::ofstream& stream, + VtnCounter& vtnCounter, + double scalor, + unsigned int nSegments, + const Acts::Transform3D& transform, + double r, + double hZ, + double thickness = 0.); + +} // enf of namespace + diff --git a/Tracking/Acts/FaserActsGeometry/src/util/ObjSurfaceWriter.cxx b/Tracking/Acts/FaserActsGeometry/src/util/ObjSurfaceWriter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..162a34efc441269d2d3f8266a2de852989b37800 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/util/ObjSurfaceWriter.cxx @@ -0,0 +1,209 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +// This file was largely imported from the Acts testing framework + +#include "ObjSurfaceWriter.h" + +#include <ios> +#include <iostream> +#include <stdexcept> + +#include "Acts/Geometry/Layer.hpp" +#include "Acts/Surfaces/CylinderBounds.hpp" +#include "Acts/Surfaces/PlanarBounds.hpp" +#include "Acts/Surfaces/RadialBounds.hpp" +#include "Acts/Surfaces/SurfaceBounds.hpp" +#include "Acts/Geometry/GeometryID.hpp" + +#include "Acts/Geometry/Polyhedron.hpp" +#include "Acts/Surfaces/CylinderSurface.hpp" +#include "Acts/Surfaces/StrawSurface.hpp" + +namespace { + // this method went away in acts 0.19.0. Porting over this code to use IVisualization seems + // to be not worth, so porting this (relatively simple) method here. + std::string objString(const Acts::Polyhedron& polyhedron, size_t vtxOffset) { + std::stringstream sstr; + + for (const auto& vtx : polyhedron.vertices) { + sstr << "v " << vtx.x() << " " << vtx.y() << " " << vtx.z() << std::endl; + + } + for (const auto& face : polyhedron.faces) { + sstr << "f"; + for (const auto& idx : face) { + sstr << " " << (vtxOffset + idx + 1); + + } + sstr << std::endl; + + } + return sstr.str(); + + } +} + + + + +Acts::ObjSurfaceWriter::ObjSurfaceWriter( + const ObjSurfaceWriter::Config& cfg) + : m_cfg(cfg) +{ + // Validate the configuration + if (!m_cfg.logger) { + throw std::invalid_argument("Missing logger"); + } else if (m_cfg.name.empty()) { + throw std::invalid_argument("Missing algorithm name"); + } else if (!m_cfg.outputStream) { + throw std::invalid_argument("Missing output stream"); + } + + // Write down the file prefix + (*(m_cfg.outputStream)) << m_cfg.filePrefix << '\n'; +} + +std::string +Acts::ObjSurfaceWriter::name() const +{ + return m_cfg.name; +} +void +Acts::ObjSurfaceWriter::write(const std::string& sinfo) +{ + // lock the mutex for writing + std::lock_guard<std::mutex> lock(m_write_mutex); + // and write + (*m_cfg.outputStream) << sinfo; +} + +void +Acts::ObjSurfaceWriter::write(const Acts::GeometryContext &gctx, + const Acts::Surface &surface) +{ + std::lock_guard<std::mutex> lock(m_write_mutex); + + // check + ACTS_DEBUG(">>Obj: Writer for Surface object called."); + + auto scalor = m_cfg.outputScalor; + // let's get the bounds & the transform + const Acts::SurfaceBounds& surfaceBounds = surface.bounds(); + auto sTransform = surface.transform(gctx); + + // dynamic_cast to PlanarBounds + const Acts::PlanarBounds* planarBounds + = dynamic_cast<const Acts::PlanarBounds*>(&surfaceBounds); + + const Acts::CylinderBounds* cylinderBounds + = dynamic_cast<const Acts::CylinderBounds*>(&surfaceBounds); + + const Acts::StrawSurface* strawSurface + = dynamic_cast<const Acts::StrawSurface*>(&surface); + + // only continue if the cast worked + if (m_cfg.outputSensitive) { + if (planarBounds) { + ACTS_VERBOSE(">>Obj: Writing out a PlaneSurface"); + // set the precision - just to be sure + (*(m_cfg.outputStream)) << '\n'; + (*(m_cfg.outputStream)) << std::setprecision(m_cfg.outputPrecision); + // get the vertices + auto planarVertices = planarBounds->vertices(); + // loop over the vertices + std::vector<Acts::Vector3D> vertices; + vertices.reserve(planarVertices.size()); + for (auto pv : planarVertices) { + // get the point in 3D + Acts::Vector3D v3D(sTransform * Acts::Vector3D(pv.x(), pv.y(), 0.)); + vertices.push_back(v3D); + } + // get the thickness and vertical faces + double thickness = 0.; + std::vector<unsigned int> vfaces; + if (surface.associatedDetectorElement()) { + // get the thickness form the detector element + thickness = surface.associatedDetectorElement()->thickness(); + vfaces = {1, 1, 1, 1}; + } + // output to file + ObjHelper::writePlanarFace(*(m_cfg.outputStream), + m_vtnCounter, + scalor, + vertices, + thickness, + vfaces); + (*(m_cfg.outputStream)) << '\n'; + } + else if(cylinderBounds) { + + auto cylinderSurface = dynamic_cast<const Acts::CylinderSurface*>(&surface); + + Acts::Polyhedron ph = + cylinderSurface->polyhedronRepresentation(gctx, 10); + (*(m_cfg.outputStream)) << objString(ph, m_vtnCounter.vcounter); + m_vtnCounter.vcounter += ph.vertices.size(); + + } + else if(strawSurface) { + + Acts::Polyhedron ph = + strawSurface->polyhedronRepresentation(gctx, 10); + (*(m_cfg.outputStream)) << objString(ph, m_vtnCounter.vcounter); + m_vtnCounter.vcounter += ph.vertices.size(); + + } + else { + ACTS_ERROR("Unable to print this bounds type: " << surfaceBounds.type()); + } + } + + // check if you have layer and check what your have + // dynamic cast to CylinderBounds work the same + if (cylinderBounds && m_cfg.outputLayerSurface) { + ACTS_VERBOSE(">>Obj: Writing out a CylinderSurface with r = " + << cylinderBounds->get(Acts::CylinderBounds::eR)); + // name the object + auto layerID = surface.geoID().layer(); + (*(m_cfg.outputStream)) + << " o Cylinder_" << std::to_string(layerID) << '\n'; + // output to the file + ObjHelper::writeTube(*(m_cfg.outputStream), + m_vtnCounter, + scalor, + m_cfg.outputPhiSegments, + sTransform, + cylinderBounds->get(Acts::CylinderBounds::eR), + cylinderBounds->get(Acts::CylinderBounds::eHalfLengthZ), + m_cfg.outputThickness); + (*(m_cfg.outputStream)) << '\n'; + } + + ////dynamic cast to RadialBounds or disc bounds work the same + const Acts::RadialBounds* radialBounds + = dynamic_cast<const Acts::RadialBounds*>(&surfaceBounds); + if (radialBounds && m_cfg.outputLayerSurface) { + ACTS_VERBOSE(">>Obj: Writing out a DiskSurface at z = " + << sTransform.translation().z()); + // name the object + auto layerID = surface.geoID().layer(); + (*(m_cfg.outputStream)) << "o Disk_" << std::to_string(layerID) << '\n'; + // we use the tube writer in the other direction + double rMin = radialBounds->rMin(); + double rMax = radialBounds->rMax(); + double thickness = rMax - rMin; + // output to the file + ObjHelper::writeTube(*(m_cfg.outputStream), + m_vtnCounter, + scalor, + m_cfg.outputPhiSegments, + sTransform, + 0.5 * (rMin + rMax), + m_cfg.outputThickness, + thickness); + (*(m_cfg.outputStream)) << '\n'; + } + +} diff --git a/Tracking/Acts/FaserActsGeometry/src/util/ObjSurfaceWriter.h b/Tracking/Acts/FaserActsGeometry/src/util/ObjSurfaceWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..37507ef6aa42fe8f38a8e496f6332dc1c3f54627 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/util/ObjSurfaceWriter.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +// This file was largely imported from the Acts testing framework + +#pragma once + +#include "Acts/Geometry/GeometryContext.hpp" +#include <fstream> +#include <iostream> +#include <mutex> +#include "ObjHelper.h" +#include "Acts/Surfaces/Surface.hpp" +#include "Acts/Utilities/Logger.hpp" + +namespace Acts { + +/// @class ObjSurfaceWriter +/// +/// An Obj writer for the geometry +/// +class ObjSurfaceWriter +{ +public: + // @class Config + // + // The nested config class + class Config + { + public: + /// the default logger + std::shared_ptr<const Acts::Logger> logger; + /// the name of the algorithm + std::string name; + /// approximate cyinders by that + unsigned int outputPhiSegments = 72; + /// write thickness if available + double outputThickness = 2.; + /// write sensitive surfaces + bool outputSensitive = true; + /// write the layer surface out + bool outputLayerSurface = true; + /// output scalor + double outputScalor = 1.; + /// precision for out + unsigned int outputPrecision = 6; + /// file prefix to be written out + std::string filePrefix = ""; + /// prefixes + /// @todo These aren't used anywhere, should they be dropped? + std::string planarPrefix = ""; + std::string cylinderPrefix = ""; + std::string diskPrefix = ""; + /// the output stream + std::shared_ptr<std::ofstream> outputStream = nullptr; + + Config(const std::string& lname = "ObjSurfaceWriter", + Acts::Logging::Level lvl = Acts::Logging::INFO) + : logger(Acts::getDefaultLogger(lname, lvl)), name(lname) + { + } + }; + + /// Constructor + /// + /// @param cfg is the configuration class + ObjSurfaceWriter(const Config& cfg); + + /// Framework name() method + std::string + name() const; + + /// The write interface + /// @param surface to be written out + void + write(const Acts::GeometryContext &gctx, const Acts::Surface &surface); + + /// write a bit of string + /// @param is the string to be written + void + write(const std::string& sinfo); + +private: + Config m_cfg; ///< the config class + ObjHelper::VtnCounter m_vtnCounter; ///< vertex, texture, normal + std::mutex m_write_mutex; ///< mutex to protect multi-threaded writes + + /// Private access to the logging instance + const Acts::Logger& + logger() const + { + return *m_cfg.logger; + } +}; + +} diff --git a/Tracking/Acts/FaserActsGeometry/src/util/ObjTrackingGeometryWriter.cxx b/Tracking/Acts/FaserActsGeometry/src/util/ObjTrackingGeometryWriter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..05da67b11c553987e898ccffae915ede2b0e8f30 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/util/ObjTrackingGeometryWriter.cxx @@ -0,0 +1,84 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +// This file was largely imported from the Acts testing framework + +#include "ObjTrackingGeometryWriter.h" + +#include <iostream> +#include "Acts/Geometry/TrackingVolume.hpp" +#include "Acts/Surfaces/Surface.hpp" +#include "Acts/Geometry/GeometryContext.hpp" + +Acts::ObjTrackingGeometryWriter::ObjTrackingGeometryWriter( + const ObjTrackingGeometryWriter::Config& cfg) + : m_cfg(cfg) +{ +} + +std::string +Acts::ObjTrackingGeometryWriter::name() const +{ + return m_cfg.name; +} + +void +Acts::ObjTrackingGeometryWriter::write(const Acts::GeometryContext& gctx, const Acts::TrackingGeometry& tGeometry) +{ + ACTS_DEBUG(">>Obj: Writer for TrackingGeometry object called."); + // get the world volume + auto world = tGeometry.highestTrackingVolume(); + if (world) write(gctx, *world); + // return the success code +} + +/// process this volume +void +Acts::ObjTrackingGeometryWriter::write(const Acts::GeometryContext& gctx, const Acts::TrackingVolume& tVolume) +{ + ACTS_DEBUG(">>Obj: Writer for TrackingVolume object called."); + // get the confined layers and process them + if (tVolume.confinedLayers()) { + ACTS_VERBOSE(">>Obj: Layers are present, process them."); + // loop over the layers + for (auto layer : tVolume.confinedLayers()->arrayObjects()) { + // we jump navigation layers + if (layer->layerType() == Acts::navigation) continue; + // get the volume name + const std::string& volumeName = tVolume.volumeName(); + // find the right surfacewriter + std::shared_ptr<ObjSurfaceWriter> surfaceWriter = nullptr; + for (auto writer : m_cfg.surfaceWriters) { + // get name and writer + auto writerName = writer->name(); + if (volumeName.find(writerName) != std::string::npos) { + // asign the writer + surfaceWriter = writer; + // and break + break; + } + } + // bail out if you have no surface writer + if (!surfaceWriter) return; + // layer prefix + surfaceWriter->write(m_cfg.layerPrefix); + // check for sensitive surfaces + if (layer->surfaceArray() && surfaceWriter) { + // surfaces + surfaceWriter->write(m_cfg.sensitiveGroupPrefix); + // loop over the surface + for (auto surface : layer->surfaceArray()->surfaces()) { + if (surface) surfaceWriter->write(gctx, *surface); + } + } + } + } + // get the confined volumes and step down the hierarchy + if (tVolume.confinedVolumes()) { + // loop over the volumes and write what they have + for (auto volume : tVolume.confinedVolumes()->arrayObjects()) { + write(gctx, *volume.get()); + } + } +} diff --git a/Tracking/Acts/FaserActsGeometry/src/util/ObjTrackingGeometryWriter.h b/Tracking/Acts/FaserActsGeometry/src/util/ObjTrackingGeometryWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..65f263739e6e7b35277b5a69d5e890308ca095ce --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/src/util/ObjTrackingGeometryWriter.h @@ -0,0 +1,84 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +// This file was largely imported from the Acts testing framework + +#pragma once + +#include <mutex> + +#include <fstream> +#include <iostream> +#include "ObjSurfaceWriter.h" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Surfaces/Surface.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "Acts/Geometry/GeometryContext.hpp" + +namespace Acts { +class TrackingVolume; + +/// @class ObjTrackingGeometryWriter +/// +/// An Obj writer for the geometry +/// It delegates the writing of surfaces to the surface writers +class ObjTrackingGeometryWriter { +public: + // @class Config + // + // The nested config class + class Config + { + public: + /// the default logger + std::shared_ptr<const Acts::Logger> logger; + /// the name of the writer + std::string name = ""; + /// surfaceWriters + std::vector<std::shared_ptr<ObjSurfaceWriter>> surfaceWriters; + std::string filePrefix = ""; + std::string sensitiveGroupPrefix = ""; + std::string layerPrefix = ""; + + Config(const std::string& lname = "ObjTrackingGeometryWriter", + Acts::Logging::Level lvl = Acts::Logging::INFO) + : logger(Acts::getDefaultLogger(lname, lvl)) + , name(lname) + , surfaceWriters() + { + } + }; + + /// Constructor + /// @param cfg is the configuration class + ObjTrackingGeometryWriter(const Config& cfg); + + /// Framework name() method + /// @return the name of the tool + std::string + name() const; + + /// The write interface + /// @param tGeometry is the geometry to be written out + /// @return ProcessCode to indicate success/failure + void + write(const Acts::GeometryContext& gctx, const Acts::TrackingGeometry& tGeometry); + +private: + Config m_cfg; ///< the config class + + /// process this volume + /// @param tVolume the volume to be processed + void + write(const Acts::GeometryContext& gctx, const Acts::TrackingVolume& tVolume); + + /// Private access to the logging instance + const Acts::Logger& + logger() const + { + return *m_cfg.logger; + } +}; + +} diff --git a/Tracking/Acts/FaserActsGeometry/test/FaserActsExtrapolationAlg.py b/Tracking/Acts/FaserActsGeometry/test/FaserActsExtrapolationAlg.py new file mode 100644 index 0000000000000000000000000000000000000000..136742de70c41c077304d0f942a68ccd6ead6ca5 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/test/FaserActsExtrapolationAlg.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python + +import sys +from AthenaCommon.Logging import log, logging +from AthenaCommon.Constants import DEBUG, VERBOSE, INFO +from AthenaCommon.Configurable import Configurable +from CalypsoConfiguration.AllConfigFlags import ConfigFlags +from AthenaConfiguration.TestDefaults import defaultTestFiles +from AthenaConfiguration.MainServicesConfig import MainServicesCfg +from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg +from AthenaPoolCnvSvc.PoolWriteConfig import PoolWriteCfg +from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg +from FaserActsGeometry.FaserActsExtrapolationConfig import FaserActsExtrapolationAlgCfg + +# Set up logging and new style config +log.setLevel(DEBUG) +Configurable.configurableRun3Behavior = True + +# Configure +#ConfigFlags.Input.Files = ["/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/esd/100evts10lumiblocks.ESD.root"] +#ConfigFlags.Output.RDOFileName = "myRDO_sp.pool.root" +ConfigFlags.Input.isMC = True # Needed to bypass autoconfig +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Always needed +# Workaround for bug/missing flag; unimportant otherwise +ConfigFlags.addFlag("Input.InitialTimeStamp", 0) +# Workaround to avoid problematic ISF code +ConfigFlags.GeoModel.Layout = "Development" +ConfigFlags.Detector.SimulateFaserSCT = True +#ConfigFlags.GeoModel.AtlasVersion = "ATLAS-R2-2016-01-00-01" # Always needed to fool autoconfig; value ignored +ConfigFlags.GeoModel.Align.Dynamic = False +#ConfigFlags.Concurrency.NumThreads = 1 +#ConfigFlags.Beam.NumberOfCollisions = 0. +ConfigFlags.lock() + +# Core components +acc = MainServicesCfg(ConfigFlags) +#acc.merge(PoolReadCfg(ConfigFlags)) +#acc.merge(PoolWriteCfg(ConfigFlags)) + +# Inner Detector +acc.merge(FaserActsExtrapolationAlgCfg(ConfigFlags)) + +# Dump config +logging.getLogger('forcomps').setLevel(VERBOSE) +acc.foreach_component("*").OutputLevel = VERBOSE +acc.foreach_component("*ClassID*").OutputLevel = INFO +#acc.getCondAlgo("FaserActsAlignmentCondAlg").OutputLevel = VERBOSE +#acc.getCondAlgo("FaserNominalAlignmentCondAlg").OutputLevel = VERBOSE +acc.getService("StoreGateSvc").Dump = True +acc.getService("ConditionStore").Dump = True +acc.printConfig(withDetails=True) +ConfigFlags.dump() +# Execute and finish +sc = acc.run(maxEvents=1) +# Success should be 0 +sys.exit(not sc.isSuccess()) diff --git a/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py b/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py new file mode 100644 index 0000000000000000000000000000000000000000..d7aa806a3916cc65b62a60677b884392a82b9fe7 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometry/test/FaserActsWriteTrackingGeometry.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +import sys +from AthenaCommon.Logging import log, logging +from AthenaCommon.Constants import DEBUG, VERBOSE, INFO +from AthenaCommon.Configurable import Configurable +from CalypsoConfiguration.AllConfigFlags import ConfigFlags +from AthenaConfiguration.TestDefaults import defaultTestFiles +from AthenaConfiguration.MainServicesConfig import MainServicesCfg +from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg +from AthenaPoolCnvSvc.PoolWriteConfig import PoolWriteCfg +from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg +from FaserActsGeometry.FaserActsWriteTrackingGeometryConfig import FaserActsWriteTrackingGeometryCfg + +# Set up logging and new style config +log.setLevel(DEBUG) +Configurable.configurableRun3Behavior = True + +# Configure +ConfigFlags.Input.Files = ["/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/esd/100evts10lumiblocks.ESD.root"] +#ConfigFlags.Output.RDOFileName = "myRDO_sp.pool.root" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.GeoModel.FaserVersion = "FASER-01" # Always needed +# Workaround for bug/missing flag; unimportant otherwise +ConfigFlags.addFlag("Input.InitialTimeStamp", 0) +# Workaround to avoid problematic ISF code +ConfigFlags.GeoModel.Layout = "Development" +ConfigFlags.Detector.SimulateFaserSCT = True +ConfigFlags.GeoModel.AtlasVersion = "ATLAS-R2-2016-01-00-01" # Always needed to fool autoconfig; value ignored +ConfigFlags.GeoModel.Align.Dynamic = False +#ConfigFlags.Concurrency.NumThreads = 1 +#ConfigFlags.Beam.NumberOfCollisions = 0. +ConfigFlags.lock() + +# Core components +acc = MainServicesCfg(ConfigFlags) +acc.merge(PoolReadCfg(ConfigFlags)) +acc.merge(PoolWriteCfg(ConfigFlags)) + +# Inner Detector +acc.merge(FaserActsWriteTrackingGeometryCfg(ConfigFlags)) + +# Output Stream customization +#oStream = acc.getEventAlgo("OutputStreamRDO") +#oStream.ItemList += ["EventInfo#*", +# "McEventCollection#TruthEvent", +# "McEventCollection#GEN_EVENT" +# ] + +# Timing +#acc.merge(MergeRecoTimingObjCfg(ConfigFlags)) + +# Dump config +logging.getLogger('forcomps').setLevel(VERBOSE) +acc.foreach_component("*").OutputLevel = VERBOSE +acc.foreach_component("*ClassID*").OutputLevel = INFO +#acc.getCondAlgo("FaserActsAlignmentCondAlg").OutputLevel = VERBOSE +#acc.getCondAlgo("FaserNominalAlignmentCondAlg").OutputLevel = VERBOSE +acc.getService("StoreGateSvc").Dump = True +acc.getService("ConditionStore").Dump = True +acc.printConfig(withDetails=True) +ConfigFlags.dump() +# Execute and finish +sc = acc.run(maxEvents=-1) +# Success should be 0 +sys.exit(not sc.isSuccess()) diff --git a/Tracking/Acts/FaserActsGeometryInterfaces/CMakeLists.txt b/Tracking/Acts/FaserActsGeometryInterfaces/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..633d8584e7fb89fbfe48d84c3eb634eae4807b56 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometryInterfaces/CMakeLists.txt @@ -0,0 +1,19 @@ + +# Declare the package name: +atlas_subdir( FaserActsGeometryInterfaces ) + +# External dependencies: +find_package( Eigen ) +find_package( Acts COMPONENTS Core ) + +# Component(s) in the package: + +atlas_add_library( FaserActsGeometryInterfacesLib + FaserActsGeometryInterfaces/*.h + INTERFACE + PUBLIC_HEADERS FaserActsGeometryInterfaces + INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS} + LINK_LIBRARIES ${EIGEN_LIBRARIES} + AthenaKernel + ActsInteropLib + ActsCore) diff --git a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h new file mode 100644 index 0000000000000000000000000000000000000000..6f04868ee03c29a0e35513eb4d7ff94345d39940 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h @@ -0,0 +1,78 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRYINTERFACES_IACTSEXTRAPOLATIONTOOL_H +#define FASERACTSGEOMETRYINTERFACES_IACTSEXTRAPOLATIONTOOL_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/IAlgTool.h" +#include "GaudiKernel/EventContext.h" + +#include "Acts/Propagator/detail/SteppingLogger.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Propagator/MaterialInteractor.hpp" + +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "Acts/MagneticField/MagneticFieldContext.hpp" + +/// Using some short hands for Recorded Material +using ActsRecordedMaterial = Acts::MaterialInteractor::result_type; +/// Finally the output of the propagation test +using ActsPropagationOutput = + std::pair<std::vector<Acts::detail::Step>, ActsRecordedMaterial>; + + +namespace Acts { + class TrackingGeometry; +} + +class IFaserActsTrackingGeometryTool; + + +class IFaserActsExtrapolationTool : virtual public IAlgTool { + public: + + DeclareInterfaceID(IFaserActsExtrapolationTool, 1, 0); + + virtual + ActsPropagationOutput + propagationSteps(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + Acts::NavigationDirection navDir = Acts::forward, + double pathLimit = std::numeric_limits<double>::max()) const = 0; + + virtual + std::unique_ptr<const Acts::CurvilinearParameters> + propagate(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + Acts::NavigationDirection navDir = Acts::forward, + double pathLimit = std::numeric_limits<double>::max()) const = 0; + + virtual + ActsPropagationOutput + propagationSteps(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + const Acts::Surface& target, + Acts::NavigationDirection navDir = Acts::forward, + double pathLimit = std::numeric_limits<double>::max()) const = 0; + + virtual + std::unique_ptr<const Acts::BoundParameters> + propagate(const EventContext& ctx, + const Acts::BoundParameters& startParameters, + const Acts::Surface& target, + Acts::NavigationDirection navDir = Acts::forward, + double pathLimit = std::numeric_limits<double>::max()) const = 0; + + virtual + const IFaserActsTrackingGeometryTool* + trackingGeometryTool() const = 0; + + virtual + Acts::MagneticFieldContext getMagneticFieldContext(const EventContext& ctx) const = 0; + +}; + +#endif diff --git a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h new file mode 100644 index 0000000000000000000000000000000000000000..1c7798352d663f87435d00f12337cee263b0cb4e --- /dev/null +++ b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometrySvc.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRYINTERFACES_IACTSTRACKINGGEOMETRYSVC_H +#define FASERACTSGEOMETRYINTERFACES_IACTSTRACKINGGEOMETRYSVC_H + +#include "GaudiKernel/IInterface.h" + +class EventContext; +class FaserActsAlignmentStore; + +namespace Acts { + class TrackingGeometry; +} + + +class IFaserActsTrackingGeometrySvc : virtual public IInterface { + public: + + DeclareInterfaceID(IFaserActsTrackingGeometrySvc, 1, 0); + + virtual + std::shared_ptr<const Acts::TrackingGeometry> + trackingGeometry() = 0; + + virtual + void + populateAlignmentStore(FaserActsAlignmentStore *store) const = 0; + + virtual + const FaserActsAlignmentStore* + getNominalAlignmentStore() const = 0; + +}; + +#endif diff --git a/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h new file mode 100644 index 0000000000000000000000000000000000000000..e13ff4454b95a16de7b8932bd002260432d80069 --- /dev/null +++ b/Tracking/Acts/FaserActsGeometryInterfaces/FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSGEOMETRYINTERFACES_IACTSTRACKINGGEOMETRYTOOL_H +#define FASERACTSGEOMETRYINTERFACES_IACTSTRACKINGGEOMETRYTOOL_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/IInterface.h" +#include "GaudiKernel/IAlgTool.h" +#include "GaudiKernel/EventContext.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" + +namespace Acts { + class TrackingGeometry; +} + + +class IFaserActsTrackingGeometryTool : virtual public IAlgTool { + public: + + DeclareInterfaceID(IFaserActsTrackingGeometryTool, 1, 0); + + virtual + std::shared_ptr<const Acts::TrackingGeometry> + trackingGeometry() const = 0; + + virtual + const FaserActsGeometryContext& + getGeometryContext(const EventContext& ctx = Gaudi::Hive::currentContext()) const = 0; + + virtual + FaserActsGeometryContext + getNominalGeometryContext() const = 0; +}; + +#endif diff --git a/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt b/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..2e4f94741746e376b7f79ea1da16cb2921f825a3 --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt @@ -0,0 +1,55 @@ +# Declare the package name: +atlas_subdir(FaserActsKalmanFilter) + +# External dependencies: +find_package( CLHEP ) +find_package( Eigen ) +find_package( Boost ) +find_package( Acts COMPONENTS Core ) + +# Component(s) in the package: +atlas_add_library( FaserActsKalmanFilterLib + PUBLIC_HEADERS FaserActsKalmanFilter + INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${BOOST_INCLUDE_DIRS} + LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} + AthenaKernel + ActsCore + TrackerIdentifier + TrackerReadoutGeometry + ActsInteropLib + FaserActsGeometryLib + FaserActsGeometryInterfacesLib +) + +atlas_add_component(FaserActsKalmanFilter + src/*.cxx + src/components/*.cxx + FaserActsKalmanFilter/*.h + FaserActsKalmanFilter/src/*.cxx + PUBLIC_HEADERS FaserActsKalmanFilter + INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${BOOST_INCLUDE_DIRS} + LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} + ActsCore + EventInfo + FaserActsKalmanFilterLib + ActsInteropLib + FaserActsGeometryLib + FaserActsGeometryInterfacesLib + MagFieldInterfaces + MagFieldElements + MagFieldConditions + TrkPrepRawData + TrackerPrepRawData + TrackerSpacePoint + GeoModelUtilities + GeneratorObjects + TrackerIdentifier + TrackerReadoutGeometry + Identifier + TrackerSimData +) + +# Install files from the package: +atlas_install_headers(FaserActsKalmanFilter) +atlas_install_python_modules( python/*.py ) +atlas_install_scripts( test/*.py ) diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h new file mode 100755 index 0000000000000000000000000000000000000000..da8f7995c1e16469392f48e2472763049dea053d --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h @@ -0,0 +1,271 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERACTSKALMANFILTER_FASERACTSKALMANFILTERALG_H +#define FASERACTSKALMANFILTER_FASERACTSKALMANFILTERALG_H + +// ATHENA +#include "AthenaBaseComps/AthAlgorithm.h" +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/ITHistSvc.h" +#include "Gaudi/Property.h" /*no forward decl: typedef*/ +#include "GaudiKernel/ISvcLocator.h" +#include "StoreGate/StoreGateSvc.h" +#include "StoreGate/ReadCondHandleKey.h" +#include "TrackerPrepRawData/FaserSCT_ClusterCollection.h" +#include "TrkSpacePoint/SpacePoint.h" +#include "MagFieldConditions/FaserFieldCacheCondObj.h" +#include "MagFieldElements/FaserFieldCache.h" +#include "TrackerReadoutGeometry/SiDetectorElementCollection.h" +#include "TrackerSpacePoint/SpacePointForSeedCollection.h" +#include "Identifier/Identifier.h" +#include "GeneratorObjects/McEventCollection.h" +#include "TrackerSimData/TrackerSimDataCollection.h" + +// ACTS +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/InterpolatedBFieldMap.hpp" +#include "Acts/MagneticField/SharedBField.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Propagator/detail/SteppingLogger.hpp" +#include "Acts/Fitter/KalmanFitter.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Geometry/GeometryID.hpp" +#include "Acts/Utilities/Helpers.hpp" +#include "Acts/Utilities/Definitions.hpp" + +// PACKAGE +#include "FaserActsGeometry/FASERMagneticFieldWrapper.h" +#include "FaserActsGeometry/FaserActsTrackingGeometryTool.h" +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h" +#include "FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h" +#include "FaserActsKalmanFilter/FaserActsRecSourceLink.h" +#include "FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h" + +// STL +#include <memory> +#include <vector> +#include <fstream> +#include <mutex> + +class EventContext; +class IAthRNGSvc; +class FaserSCT_ID; +class TTree; + +namespace ActsExtrapolationDetail { + class VariantPropagator; +} + +namespace TrackerDD { + class SCT_DetectorManager; +} + +using TrajectoryContainer = std::vector<FaserActsRecMultiTrajectory>; + +//class FaserActsKalmanFilterAlg : public AthReentrantAlgorithm { +class FaserActsKalmanFilterAlg : public AthAlgorithm { +public: + FaserActsKalmanFilterAlg (const std::string& name, ISvcLocator* pSvcLocator); + StatusCode initialize() override; + //StatusCode execute(const EventContext& ctx) const override; + StatusCode execute() override; + StatusCode finalize() override; + + using FitterResult = Acts::Result<Acts::KalmanFitterResult<RecSourceLink>>; + // Fit function that takes input measurements, initial trackstate and fitter + // options and returns some fit-specific result. + using FitterFunction = std::function<FitterResult( + const std::vector<RecSourceLink>&, + const Acts::CurvilinearParameters&, + const Acts::KalmanFitterOptions<Acts::VoidOutlierFinder>&)>; + + // Create the fitter function implementation. + static FitterFunction + makeFitterFunction( + ActsExtrapolationDetail::VariantPropagator* varProp); + + virtual + Acts::MagneticFieldContext + //getMagneticFieldContext(const EventContext& ctx) const; + getMagneticFieldContext() const; + + void initializeTree(); + + void fillFitResult(const Acts::GeometryContext& geoctx, const TrajectoryContainer& trajectories, const Acts::BoundParameters& truthParam); + + void clearTrackVariables(); + +private: + const FaserSCT_ID* m_idHelper{nullptr}; + + // Read handle for conditions object to get the field cache + SG::ReadCondHandleKey<FaserFieldCacheCondObj> m_fieldCondObjInputKey {this, "FaserFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"}; + + ToolHandle<IFaserActsExtrapolationTool> m_extrapolationTool{this, "ExtrapolationTool", "FaserActsExtrapolationTool"}; + + Gaudi::Property<std::string> m_fieldMode{this, "FieldMode", "FASER"}; + Gaudi::Property<std::vector<double>> m_constantFieldVector{this, "ConstantFieldVector", {0, 0, 0}}; + + SG::ReadHandleKey<SpacePointForSeedCollection> m_seed_spcollectionKey{this, "FaserSpacePointsSeedsName", "SpacePointForSeedCollection", "SpacePointForSeedCollection"}; + + SG::ReadHandleKey<McEventCollection> m_mcEventKey { this, "McEventCollection", "GEN_EVENT" }; + SG::ReadHandleKey<TrackerSimDataCollection> m_sctMap {this, "TrackerSimDataCollection", "SCT_SDO_Map"}; + const TrackerDD::SCT_DetectorManager* m_detManager{nullptr}; + + ServiceHandle<ITHistSvc> m_thistSvc; + + TTree *m_trackTree{nullptr}; + + /// Acts tree values + int m_eventNr{0}; + int m_trajNr{0}; + int m_trackNr{0}; + + unsigned long m_t_barcode{0}; /// Truth particle barcode + int m_t_charge{0}; /// Truth particle charge + float m_t_eT{0}; /// Truth particle time on the first layer + float m_t_eLOC0{-99.}; /// Truth local x on the first layer + float m_t_eLOC1{-99.}; /// Truth local y on the first layer + float m_t_eTHETA{-99.}; /// Truth particle momentum theta on the first layer + float m_t_ePHI{-99.}; /// Truth particle momentum phi on the first layer + float m_t_eQOP{-99.}; /// Truth particle momentum qop on the first layer + float m_t_x{-99.}; /// Truth particle position x on the first layer + float m_t_y{-99.}; /// Truth particle position y on the first layer + float m_t_z{-99.}; /// Truth particle position z on the first layer + float m_t_px{-99.}; /// Truth particle momentum px on the first layer + float m_t_py{-99.}; /// Truth particle momentum py on the first layer + float m_t_pz{-99.}; /// Truth particle momentum pz on the first layer + + int m_nHoles{0}; /// number of holes in the track fit + int m_nOutliers{0}; /// number of outliers in the track fit + int m_nStates{0}; /// number of all states + int m_nMeasurements{0}; /// number of states with measurements + std::vector<int> m_volumeID; /// volume identifier + std::vector<int> m_layerID; /// layer identifier + std::vector<int> m_moduleID; /// surface identifier + std::vector<float> m_lx_hit; /// uncalibrated measurement local x + std::vector<float> m_ly_hit; /// uncalibrated measurement local y + std::vector<float> m_x_hit; /// uncalibrated measurement global x + std::vector<float> m_y_hit; /// uncalibrated measurement global y + std::vector<float> m_z_hit; /// uncalibrated measurement global z + std::vector<float> m_res_x_hit; /// hit residual x + std::vector<float> m_res_y_hit; /// hit residual y + std::vector<float> m_err_x_hit; /// hit err x + std::vector<float> m_err_y_hit; /// hit err y + std::vector<float> m_pull_x_hit; /// hit pull x + std::vector<float> m_pull_y_hit; /// hit pull y + std::vector<int> m_dim_hit; /// dimension of measurement + + bool m_hasFittedParams{false}; /// if the track has fitted parameter + float m_eLOC0_fit{-99.}; /// fitted parameter eLOC_0 + float m_eLOC1_fit{-99.}; /// fitted parameter eLOC_1 + float m_ePHI_fit{-99.}; /// fitted parameter ePHI + float m_eTHETA_fit{-99.}; /// fitted parameter eTHETA + float m_eQOP_fit{-99.}; /// fitted parameter eQOP + float m_eT_fit{-99.}; /// fitted parameter eT + float m_err_eLOC0_fit{-99.}; /// fitted parameter eLOC_-99.err + float m_err_eLOC1_fit{-99.}; /// fitted parameter eLOC_1 err + float m_err_ePHI_fit{-99.}; /// fitted parameter ePHI err + float m_err_eTHETA_fit{-99.}; /// fitted parameter eTHETA err + float m_err_eQOP_fit{-99.}; /// fitted parameter eQOP err + float m_err_eT_fit{-99.}; /// fitted parameter eT err + float m_px_fit{-99.}; /// fitted parameter global px + float m_py_fit{-99.}; /// fitted parameter global py + float m_pz_fit{-99.}; /// fitted parameter global pz + float m_x_fit{-99.}; /// fitted parameter global PCA x + float m_y_fit{-99.}; /// fitted parameter global PCA y + float m_z_fit{-99.}; /// fitted parameter global PCA z + float m_chi2_fit{-99.}; /// fitted parameter chi2 + float m_ndf_fit{-99.}; /// fitted parameter ndf + int m_charge_fit{-99}; /// fitted parameter charge + + int m_nPredicted{0}; /// number of states with predicted parameter + std::vector<bool> m_prt; /// predicted status + std::vector<float> m_eLOC0_prt; /// predicted parameter eLOC0 + std::vector<float> m_eLOC1_prt; /// predicted parameter eLOC1 + std::vector<float> m_ePHI_prt; /// predicted parameter ePHI + std::vector<float> m_eTHETA_prt; /// predicted parameter eTHETA + std::vector<float> m_eQOP_prt; /// predicted parameter eQOP + std::vector<float> m_eT_prt; /// predicted parameter eT + std::vector<float> m_res_eLOC0_prt; /// predicted parameter eLOC0 residual + std::vector<float> m_res_eLOC1_prt; /// predicted parameter eLOC1 residual + std::vector<float> m_err_eLOC0_prt; /// predicted parameter eLOC0 error + std::vector<float> m_err_eLOC1_prt; /// predicted parameter eLOC1 error + std::vector<float> m_err_ePHI_prt; /// predicted parameter ePHI error + std::vector<float> m_err_eTHETA_prt; /// predicted parameter eTHETA error + std::vector<float> m_err_eQOP_prt; /// predicted parameter eQOP error + std::vector<float> m_err_eT_prt; /// predicted parameter eT error + std::vector<float> m_pull_eLOC0_prt; /// predicted parameter eLOC0 pull + std::vector<float> m_pull_eLOC1_prt; /// predicted parameter eLOC1 pull + std::vector<float> m_x_prt; /// predicted global x + std::vector<float> m_y_prt; /// predicted global y + std::vector<float> m_z_prt; /// predicted global z + std::vector<float> m_px_prt; /// predicted momentum px + std::vector<float> m_py_prt; /// predicted momentum py + std::vector<float> m_pz_prt; /// predicted momentum pz + std::vector<float> m_eta_prt; /// predicted momentum eta + std::vector<float> m_pT_prt; /// predicted momentum pT + + int m_nFiltered{0}; /// number of states with filtered parameter + std::vector<bool> m_flt; /// filtered status + std::vector<float> m_eLOC0_flt; /// filtered parameter eLOC0 + std::vector<float> m_eLOC1_flt; /// filtered parameter eLOC1 + std::vector<float> m_ePHI_flt; /// filtered parameter ePHI + std::vector<float> m_eTHETA_flt; /// filtered parameter eTHETA + std::vector<float> m_eQOP_flt; /// filtered parameter eQOP + std::vector<float> m_eT_flt; /// filtered parameter eT + std::vector<float> m_res_eLOC0_flt; /// filtered parameter eLOC0 residual + std::vector<float> m_res_eLOC1_flt; /// filtered parameter eLOC1 residual + std::vector<float> m_err_eLOC0_flt; /// filtered parameter eLOC0 error + std::vector<float> m_err_eLOC1_flt; /// filtered parameter eLOC1 error + std::vector<float> m_err_ePHI_flt; /// filtered parameter ePHI error + std::vector<float> m_err_eTHETA_flt; /// filtered parameter eTHETA error + std::vector<float> m_err_eQOP_flt; /// filtered parameter eQOP error + std::vector<float> m_err_eT_flt; /// filtered parameter eT error + std::vector<float> m_pull_eLOC0_flt; /// filtered parameter eLOC0 pull + std::vector<float> m_pull_eLOC1_flt; /// filtered parameter eLOC1 pull + std::vector<float> m_x_flt; /// filtered global x + std::vector<float> m_y_flt; /// filtered global y + std::vector<float> m_z_flt; /// filtered global z + std::vector<float> m_px_flt; /// filtered momentum px + std::vector<float> m_py_flt; /// filtered momentum py + std::vector<float> m_pz_flt; /// filtered momentum pz + std::vector<float> m_eta_flt; /// filtered momentum eta + std::vector<float> m_pT_flt; /// filtered momentum pT + std::vector<float> m_chi2; /// chisq from filtering + + int m_nSmoothed{0}; /// number of states with smoothed parameter + std::vector<bool> m_smt; /// smoothed status + std::vector<float> m_eLOC0_smt; /// smoothed parameter eLOC0 + std::vector<float> m_eLOC1_smt; /// smoothed parameter eLOC1 + std::vector<float> m_ePHI_smt; /// smoothed parameter ePHI + std::vector<float> m_eTHETA_smt; /// smoothed parameter eTHETA + std::vector<float> m_eQOP_smt; /// smoothed parameter eQOP + std::vector<float> m_eT_smt; /// smoothed parameter eT + std::vector<float> m_res_eLOC0_smt; /// smoothed parameter eLOC0 residual + std::vector<float> m_res_eLOC1_smt; /// smoothed parameter eLOC1 residual + std::vector<float> m_err_eLOC0_smt; /// smoothed parameter eLOC0 error + std::vector<float> m_err_eLOC1_smt; /// smoothed parameter eLOC1 error + std::vector<float> m_err_ePHI_smt; /// smoothed parameter ePHI error + std::vector<float> m_err_eTHETA_smt; /// smoothed parameter eTHETA error + std::vector<float> m_err_eQOP_smt; /// smoothed parameter eQOP error + std::vector<float> m_err_eT_smt; /// smoothed parameter eT error + std::vector<float> m_pull_eLOC0_smt; /// smoothed parameter eLOC0 pull + std::vector<float> m_pull_eLOC1_smt; /// smoothed parameter eLOC1 pull + std::vector<float> m_x_smt; /// smoothed global x + std::vector<float> m_y_smt; /// smoothed global y + std::vector<float> m_z_smt; /// smoothed global z + std::vector<float> m_px_smt; /// smoothed momentum px + std::vector<float> m_py_smt; /// smoothed momentum py + std::vector<float> m_pz_smt; /// smoothed momentum pz + std::vector<float> m_eta_smt; /// smoothed momentum eta + std::vector<float> m_pT_smt; /// smoothed momentum pT + +}; + +#endif diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h new file mode 100644 index 0000000000000000000000000000000000000000..bea0c15839b628789ffee7da18b54b9b9e255350 --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h @@ -0,0 +1,87 @@ +// Copyright (C) 2019 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +#pragma once + +#include <unordered_map> +#include <utility> + +// ACTS +#include "Acts/EventData/MultiTrajectory.hpp" +#include "Acts/EventData/TrackParameters.hpp" + +// PACKAGE +#include "FaserActsKalmanFilter/FaserActsRecSourceLink.h" + +using IndexedParams = std::unordered_map<size_t, Acts::BoundParameters>; + +struct FaserActsRecMultiTrajectory +{ + public: + FaserActsRecMultiTrajectory() = default; + + FaserActsRecMultiTrajectory(const Acts::MultiTrajectory<RecSourceLink>& multiTraj, + const std::vector<size_t>& tTips, + const IndexedParams& parameters) + : m_multiTrajectory(multiTraj), + m_trackTips(tTips), + m_trackParameters(parameters) {} + + FaserActsRecMultiTrajectory(const FaserActsRecMultiTrajectory& rhs) + : m_multiTrajectory(rhs.m_multiTrajectory), + m_trackTips(rhs.m_trackTips), + m_trackParameters(rhs.m_trackParameters) {} + + FaserActsRecMultiTrajectory(FaserActsRecMultiTrajectory&& rhs) + : m_multiTrajectory(std::move(rhs.m_multiTrajectory)), + m_trackTips(std::move(rhs.m_trackTips)), + m_trackParameters(std::move(rhs.m_trackParameters)) {} + + ~FaserActsRecMultiTrajectory() = default; + + FaserActsRecMultiTrajectory& operator=(const FaserActsRecMultiTrajectory& rhs) { + m_multiTrajectory = rhs.m_multiTrajectory; + m_trackTips = rhs.m_trackTips; + m_trackParameters = rhs.m_trackParameters; + return *this; + } + + FaserActsRecMultiTrajectory& operator=(FaserActsRecMultiTrajectory&& rhs) { + m_multiTrajectory = std::move(rhs.m_multiTrajectory); + m_trackTips = std::move(rhs.m_trackTips); + m_trackParameters = std::move(rhs.m_trackParameters); + return *this; + } + + bool hasTrajectory(const size_t& entryIndex) const { + return std::count(m_trackTips.begin(), m_trackTips.end(), entryIndex) > 0; + } + + bool hasTrackParameters(const size_t& entryIndex) const { + return m_trackParameters.count(entryIndex) > 0; + } + + std::pair<std::vector<size_t>, Acts::MultiTrajectory<RecSourceLink>> + trajectory() const { + return std::make_pair(m_trackTips, m_multiTrajectory); + } + + const Acts::BoundParameters& trackParameters(const size_t& entryIndex) const { + auto it = m_trackParameters.find(entryIndex); + if (it != m_trackParameters.end()) { + return it->second; + } else { + throw std::runtime_error( + "No fitted track parameters for trajectory with entry index = " + + std::to_string(entryIndex)); + } + } + + private: + Acts::MultiTrajectory<RecSourceLink> m_multiTrajectory; + std::vector<size_t> m_trackTips = {}; + IndexedParams m_trackParameters = {}; +}; diff --git a/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecSourceLink.h b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecSourceLink.h new file mode 100644 index 0000000000000000000000000000000000000000..def70b00d059e7f8271a50c475e2e62514bec2a2 --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/FaserActsKalmanFilter/FaserActsRecSourceLink.h @@ -0,0 +1,44 @@ +# pragma once + +// ACTS +#include "Acts/EventData/Measurement.hpp" +#include "Acts/Utilities/ParameterDefinitions.hpp" + +// ATHENA +#include "TrkSpacePoint/SpacePoint.h" + + +class RecSourceLink { +public: + // TODO convert Trk::LocalParameters to acts::BoundVector and Amg::MatrixX& to ACTS::BoundMatrix + RecSourceLink(const Acts::Surface& surface, const Trk::SpacePoint& spacePoint) + : m_values(spacePoint.localParameters()), + m_cov(spacePoint.localCovariance()), + m_surface(&surface), + m_spacePoint(&spacePoint) {} + + RecSourceLink() = default; + + constexpr const Acts::Surface& referenceSurface() const { return *m_surface; } + constexpr const Trk::SpacePoint& spacePoint() const { return *m_spacePoint; } + + Acts::FittableMeasurement<RecSourceLink> operator*() const { + return Acts::Measurement<RecSourceLink, Acts::BoundParametersIndices, Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_1> { + m_surface->getSharedPtr(), + *this, + m_cov.topLeftCorner<2, 2>(), + m_values[0], + m_values[1] + }; + } + +private: + Acts::BoundVector m_values; + Acts::BoundMatrix m_cov; + const Acts::Surface* m_surface; + const Trk::SpacePoint* m_spacePoint; + + friend constexpr bool operator==(const RecSourceLink& lhs, const RecSourceLink& rhs) { + return lhs.m_spacePoint == rhs.m_spacePoint; + } +}; diff --git a/Tracking/Acts/FaserActsKalmanFilter/python/FaserActsKalmanFilterConfig.py b/Tracking/Acts/FaserActsKalmanFilter/python/FaserActsKalmanFilterConfig.py new file mode 100644 index 0000000000000000000000000000000000000000..0a955d80a50c7fcb5de8878841404565cd870f1b --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/python/FaserActsKalmanFilterConfig.py @@ -0,0 +1,48 @@ +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from AthenaConfiguration.ComponentFactory import CompFactory +from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg +from MagFieldServices.MagFieldServicesConfig import MagneticFieldSvcCfg + +FaserActsKalmanFilterAlg,FaserActsTrackingGeometrySvc, FaserActsTrackingGeometryTool, FaserActsExtrapolationTool,FaserActsAlignmentCondAlg, THistSvc = CompFactory.getComps("FaserActsKalmanFilterAlg","FaserActsTrackingGeometrySvc", "FaserActsTrackingGeometryTool", "FaserActsExtrapolationTool","FaserActsAlignmentCondAlg", "THistSvc") + +def FaserActsTrackingGeometrySvcCfg(flags, **kwargs): + acc = ComponentAccumulator() + acc.addService(FaserActsTrackingGeometrySvc(name = "FaserActsTrackingGeometrySvc", **kwargs)) + return acc + +def FaserActsAlignmentCondAlgCfg(flags, **kwargs): + acc = ComponentAccumulator() + acc.addCondAlgo(CompFactory.FaserActsAlignmentCondAlg(name = "FaserActsAlignmentCondAlg", **kwargs)) + #acc.addCondAlgo(CompFactory.NominalAlignmentCondAlg(name = "NominalAlignmentCondAlg", **kwargs)) + return acc + +def FaserActsKalmanFilterCfg(flags, **kwargs): + acc = ComponentAccumulator() + # Initialize field service + acc.merge(MagneticFieldSvcCfg(flags)) + + acc.merge(FaserActsTrackingGeometrySvcCfg(flags, **kwargs)) + acc.merge(FaserActsAlignmentCondAlgCfg(flags, **kwargs)) + + kwargs.setdefault("FaserSpacePointsSeedsName", "Seeds_SpacePointContainer") + actsKalmanFilterAlg = FaserActsKalmanFilterAlg(**kwargs) + #actsKalmanFilterAlg.TrackingGeometryTool = FaserActsTrackingGeometryTool("TrackingGeometryTool") + actsExtrapolationTool=FaserActsExtrapolationTool("FaserActsExtrapolationTool") + actsExtrapolationTool.FieldMode="FASER" + #actsExtrapolationTool.FieldMode="Constant" + actsExtrapolationTool.TrackingGeometryTool=FaserActsTrackingGeometryTool("TrackingGeometryTool") + actsKalmanFilterAlg.ExtrapolationTool=actsExtrapolationTool + acc.addEventAlgo(actsKalmanFilterAlg) + histSvc= THistSvc() + histSvc.Output += [ "KalmanTracks DATAFILE='KalmanTracks.root' OPT='RECREATE'" ] + acc.addService(histSvc) + acc.merge(FaserActsKalmanFilter_OutputCfg(flags)) + return acc + +def FaserActsKalmanFilter_OutputCfg(flags): + """Return ComponentAccumulator with Output for SCT. Not standalone.""" + acc = ComponentAccumulator() + acc.merge(OutputStreamCfg(flags, "ESD")) + ostream = acc.getEventAlgo("OutputStreamESD") + ostream.TakeItemsFromInput = True + return acc diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsKalmanFilterAlg.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsKalmanFilterAlg.cxx new file mode 100755 index 0000000000000000000000000000000000000000..7edff9fcd843ed8edbfdadab52ba8ed0c1f6c95a --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/src/FaserActsKalmanFilterAlg.cxx @@ -0,0 +1,1207 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h" + +// ATHENA +#include "GaudiKernel/EventContext.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/PhysicalConstants.h" +#include "TrackerReadoutGeometry/SCT_DetectorManager.h" +#include "TrackerReadoutGeometry/SiDetectorDesign.h" +#include "TrackerReadoutGeometry/SiLocalPosition.h" +#include "TrackerReadoutGeometry/SiDetectorElement.h" +#include "TrackerSpacePoint/FaserSCT_SpacePoint.h" +#include "TrackerSpacePoint/SpacePointForSeedCollection.h" +#include "TrackerIdentifier/FaserSCT_ID.h" +#include "FaserDetDescr/FaserDetectorID.h" + +// ACTS +#include "Acts/Fitter/GainMatrixSmoother.hpp" +#include "Acts/Fitter/GainMatrixUpdater.hpp" +#include "Acts/Geometry/GeometryID.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/InterpolatedBFieldMap.hpp" +#include "Acts/MagneticField/SharedBField.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Navigator.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Surfaces/Surface.hpp" +#include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Surfaces/PerigeeSurface.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/Utilities/Units.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "Acts/Utilities/Helpers.hpp" +#include "Acts/Utilities/detail/periodic.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/ParameterDefinitions.hpp" +#include "Acts/Utilities/CalibrationContext.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/EventData/MultiTrajectoryHelpers.hpp" +#include "Acts/EventData/Measurement.hpp" + + +// PACKAGE +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h" +#include "ActsInterop/Logger.h" +#include "FaserActsGeometry/FaserActsGeometryContext.h" +#include "FaserActsGeometry/IFaserActsPropStepRootWriterSvc.h" +#include "FaserActsGeometry/FaserActsDetectorElement.h" +#include "FaserActsKalmanFilter/FaserActsRecSourceLink.h" +#include "FaserActsKalmanFilter/FaserActsRecMultiTrajectory.h" + +//ROOT +#include <TTree.h> + +// BOOST +#include <boost/variant/variant.hpp> +#include <boost/variant/apply_visitor.hpp> +#include <boost/variant/static_visitor.hpp> + +// STL +#include <string> +#include <fstream> +#include <cmath> +#include <random> + +using TrajectoryContainer = std::vector<FaserActsRecMultiTrajectory>; + +using namespace Acts::UnitLiterals; +using Acts::VectorHelpers::eta; +using Acts::VectorHelpers::perp; +using Acts::VectorHelpers::phi; +using Acts::VectorHelpers::theta; +using Measurement = Acts::Measurement<RecSourceLink, Acts::BoundParametersIndices, Acts::ParDef::eLOC_0, + Acts::ParDef::eLOC_1>; + +namespace ActsExtrapolationDetail { + using VariantPropagatorBase = boost::variant< + Acts::Propagator<Acts::EigenStepper<FASERMagneticFieldWrapper>, Acts::Navigator>, + Acts::Propagator<Acts::EigenStepper<Acts::ConstantBField>, Acts::Navigator> + >; + + class VariantPropagator : public VariantPropagatorBase + { + public: + using VariantPropagatorBase::VariantPropagatorBase; + }; + +} + +using ActsExtrapolationDetail::VariantPropagator; + + +FaserActsKalmanFilterAlg::FaserActsKalmanFilterAlg(const std::string& name, + ISvcLocator* pSvcLocator) + //: AthReentrantAlgorithm(name, pSvcLocator) + : AthAlgorithm(name, pSvcLocator) + , m_thistSvc("THistSvc", name) +{ +} + +StatusCode FaserActsKalmanFilterAlg::initialize() { + + ATH_MSG_DEBUG(name() << "::" << __FUNCTION__); + + ATH_MSG_INFO("Initializing ACTS kalman filter"); + + ATH_CHECK( m_fieldCondObjInputKey.initialize() ); + + ATH_CHECK( m_extrapolationTool.retrieve() ); + + if ( m_seed_spcollectionKey.key().empty()){ + ATH_MSG_FATAL( "SCTs selected and no name set for SCT clusters"); + return StatusCode::FAILURE; + } + + ATH_CHECK( m_seed_spcollectionKey.initialize() ); + + ATH_CHECK( m_mcEventKey.initialize() ); + + ATH_CHECK( m_sctMap.initialize()); + + ATH_CHECK(detStore()->retrieve(m_idHelper,"FaserSCT_ID")); + + ATH_CHECK(detStore()->retrieve(m_detManager, "SCT")); + + ATH_CHECK(m_thistSvc.retrieve()); + + m_trackTree = new TTree("tracks", ""); + + ATH_CHECK(m_thistSvc->regTree("/KalmanTracks/tracks", m_trackTree)); + + if (m_trackTree) { + initializeTree(); + } + else { + ATH_MSG_ERROR("No tree found!"); + } + + ATH_MSG_INFO("ACTS kalman filter successfully initialized"); + return StatusCode::SUCCESS; +} + +//StatusCode FaserActsKalmanFilterAlg::execute(const EventContext& ctx) const +StatusCode FaserActsKalmanFilterAlg::execute() +{ + + ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__); + + m_eventNr++; + + //SG::ReadHandle<SpacePointForSeedCollection> seed_spcollection( m_seed_spcollectionKey, ctx ); + SG::ReadHandle<SpacePointForSeedCollection> seed_spcollection( m_seed_spcollectionKey ); + if (!seed_spcollection.isValid()){ + msg(MSG:: FATAL) << "Could not find the data object "<< seed_spcollection.name() << " !" << endmsg; + return StatusCode::RECOVERABLE; + } + + const FaserActsGeometryContext& gctx + = m_extrapolationTool->trackingGeometryTool()->getNominalGeometryContext(); + auto geoctx = gctx.any(); + Acts::MagneticFieldContext magctx = getMagneticFieldContext(); + Acts::CalibrationContext calctx; + + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry + = m_extrapolationTool->trackingGeometryTool()->trackingGeometry(); + const Acts::TrackingVolume* tVolume = trackingGeometry->highestTrackingVolume(); + + std::vector<RecSourceLink> sourceLinks; + + std::shared_ptr<const Acts::Surface> pSurface; + + // Get SiDetectorElements + const TrackerDD::SiDetectorElementCollection* elCollection{m_detManager->getDetectorElementCollection()}; + if (elCollection == nullptr) { + ATH_MSG_FATAL("Null pointer is returned by getDetectorElementCollection()"); + return StatusCode::FAILURE; + } + + + //!!!!!!!!!!!!!!!!!!!! + static const TrackerDD::SCT_DetectorManager *s_sct; + if(detStore()->retrieve(s_sct,"SCT").isFailure()) s_sct = 0; + int N_1_0=0, N_1_1=0, N_1_2=0, N_2_0=0, N_2_1=0, N_2_2=0; + Acts::Vector3D pos1_0(0., 0., 0.); + Acts::Vector3D pos1_1(0., 0., 0.); + Acts::Vector3D pos1_2(0., 0., 0.); + Acts::Vector3D pos2_0(0., 0., 0.); + Acts::Vector3D pos2_1(0., 0., 0.); + Acts::Vector3D pos2_2(0., 0., 0.); + HepMC::FourVector truthmom; + HepMC::FourVector pv; + //!!!!!!!!!!!!!!!!!!!! + + // Make the source links + SpacePointForSeedCollection::const_iterator it = seed_spcollection->begin(); + SpacePointForSeedCollection::const_iterator itend = seed_spcollection->end(); + for (; it != itend; ++it){ + const SpacePointForSeed *seed_sp = &(**it); + const Trk::SpacePoint *sp = seed_sp->SpacePoint(); + auto faserSp = (Tracker::FaserSCT_SpacePoint*)sp; + ATH_MSG_DEBUG("TruthSeededTrack: SapcePoint test"); + faserSp->dump(msg(MSG::INFO)); + // ATH_MSG_DEBUG("TruthSeededTrack: SapcePoint " << *sp); + const Identifier id = sp->clusterList().first->identify(); + + const TrackerDD::SiDetectorElement* siSpElement = m_detManager->getDetectorElement(id); + auto spElement = static_cast<const FaserActsDetectorElement>(siSpElement); + + //!!!!!!!!!!!!!!!!!!!! + // Get the truth position and momentum + //SG::ReadHandle<McEventCollection> h_mcEvents(m_mcEventKey, ctx); + //SG::ReadHandle<TrackerSimDataCollection> h_collectionMap(m_sctMap, ctx); + SG::ReadHandle<McEventCollection> h_mcEvents(m_mcEventKey); + SG::ReadHandle<TrackerSimDataCollection> h_collectionMap(m_sctMap); + const auto& simdata = h_collectionMap->find(id)->second; + const auto& deposits = simdata.getdeposits(); + for( const auto& depositPair : deposits) + { + if (depositPair.first->pdg_id() == -13) { + pv = depositPair.first->production_vertex()->position(); + truthmom = depositPair.first->momentum(); + std::cout<<"!!!!!!!!!!! production_vertex: ( "<<pv.x()<<", "<<pv.y()<<", "<<pv.z()<<" ) "<<std::endl; + } + } + + // Get the measurements + Amg::Vector3D gloPos=sp->globalPosition(); + int station = m_idHelper->station(id); + int plane = m_idHelper->layer(id); + if (station==1 && plane==0) { + N_1_0++; + pos1_0 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + // Construct a plane surface as the target surface + const TrackerDD::SiDetectorDesign &design = siSpElement->design(); + double hlX = design.width()/2. * 1_mm; + double hlY = design.length()/2. * 1_mm; + auto rectangleBounds = std::make_shared<const Acts::RectangleBounds>(hlX, hlY); + Amg::Transform3D g2l = siSpElement->getMaterialGeom()->getDefAbsoluteTransform() + * Amg::CLHEPTransformToEigen(siSpElement->recoToHitTransform()); + pSurface = Acts::Surface::makeShared<Acts::PlaneSurface>( + std::make_shared<const Acts::Transform3D>( g2l ), rectangleBounds ); + + } + if (station==1 && plane==1) { + N_1_1++; + pos1_1 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + } + if (station==1 && plane==2) { + N_1_2++; + pos1_2 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + } + if (station==2 && plane==0) { + N_2_0++; + pos2_0 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + } + if (station==2 && plane==1) { + N_2_1++; + pos2_1 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + } + if (station==2 && plane==2) { + N_2_2++; + pos2_2 = Acts::Vector3D(gloPos.x(), gloPos.y(), gloPos.z()); + } + //!!!!!!!!!!!!!!!!!!!! + + if (tVolume->confinedVolumes()) { + for (auto volume : tVolume->confinedVolumes()->arrayObjects()) { + if (volume->confinedLayers()) { + for (const auto& layer : volume->confinedLayers()->arrayObjects()) { + if (layer->layerType() == Acts::navigation) continue; + for (auto surface : layer->surfaceArray()->surfaces()) { + if (surface) { + const Acts::DetectorElementBase *detElement = surface->associatedDetectorElement(); + const auto *faserDetElement = dynamic_cast<const FaserActsDetectorElement*>(detElement); + auto* tmp = const_cast<FaserActsDetectorElement*>(faserDetElement); + if (*tmp == spElement) { + sourceLinks.emplace_back(*const_cast<Acts::Surface*>(surface), *const_cast<Trk::SpacePoint*>(sp)); + } + } + } + } + } + } + } + } + + // Calculate the initial track parameters + if ( (N_1_0==1) && (N_1_1==1) && (N_1_2==1) && (N_2_0==1) && (N_2_1==1) && (N_2_2==1)) { + std::cout<<"!!!!!!!!!!! pos1_0 = ("<<pos1_0.x()<<", "<<pos1_0.y()<<", "<<pos1_0.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos1_1 = ("<<pos1_1.x()<<", "<<pos1_1.y()<<", "<<pos1_1.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos1_2 = ("<<pos1_2.x()<<", "<<pos1_2.y()<<", "<<pos1_2.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos2_0 = ("<<pos2_0.x()<<", "<<pos2_0.y()<<", "<<pos2_0.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos2_1 = ("<<pos2_1.x()<<", "<<pos2_1.y()<<", "<<pos2_1.z()<<") "<<std::endl; + std::cout<<"!!!!!!!!!!! pos2_2 = ("<<pos2_2.x()<<", "<<pos2_2.y()<<", "<<pos2_2.z()<<") "<<std::endl; + //@FIXME: change the hard codes in future + double charge = 1; + double B = 0.55; + //const Acts::Vector3D pos = pos1_0; + const Acts::Vector3D pos(pos1_0.x(), pos1_0.y(), pos1_0.z()-1); + Acts::Vector3D d1 = pos1_2 - pos1_0; + Acts::Vector3D d2 = pos2_2 - pos2_0; + // the direction of momentum in the first station + Acts::Vector3D direct1 = d1.normalized(); + // the direction of momentum in the second station + Acts::Vector3D direct2 = d2.normalized(); + // the vector pointing from the center of circle to the particle at layer 2 in Y-Z plane + double R1_z = charge * direct1.y() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z()); + // double R1_y = -charge * direct1.z() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z()); + // the vector pointing from the center of circle to the particle at layer 3 in Y-Z plane + double R2_z = charge * direct2.y() / std::sqrt(direct2.y()*direct2.y() + direct2.z()*direct2.z()); + // double R2_y = -charge * direct2.z() / std::sqrt(direct2.y()*direct2.y() + direct2.z()*direct2.z()); + // the norm of radius + double R = (pos2_0.z() - pos1_2.z()) / (R2_z - R1_z); + // the norm of momentum in Y-Z plane + double p_yz = 0.3*B*R / 1000.0; // R(mm), p(GeV), B(T) + double p_z = p_yz * direct1.z() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z()); + double p_y = p_yz * direct1.y() / std::sqrt(direct1.y()*direct1.y() + direct1.z()*direct1.z()); + double p_x = direct1.x() * p_z / direct1.z(); + // total momentum at the layer 0 + const Acts::Vector3D mom(p_x, p_y, p_z); + double p = mom.norm(); + std::cout<<"!!!!!!!!!!! InitTrack momentum on layer 0: ( "<<mom.x()*1000<<", "<<mom.y()*1000<<", "<<mom.z()*1000<<", "<<p*1000<<") "<<std::endl; + // build the track covariance matrix using the smearing sigmas + double sigmaU = 200_um; + double sigmaV = 200_um; + double sigmaPhi = 1_degree; + double sigmaTheta = 1_degree; + double sigmaQOverP = 0.01*p / (p*p); + double sigmaT0 = 1_ns; + Acts::BoundSymMatrix cov = Acts::BoundSymMatrix::Zero(); + cov(Acts::eLOC_0, Acts::eLOC_0) = sigmaU * sigmaU; + cov(Acts::eLOC_1, Acts::eLOC_1) = sigmaV * sigmaV; + cov(Acts::ePHI, Acts::ePHI) = sigmaPhi * sigmaPhi; + cov(Acts::eTHETA, Acts::eTHETA) = sigmaTheta * sigmaTheta; + cov(Acts::eQOP, Acts::eQOP) = sigmaQOverP * sigmaQOverP; + cov(Acts::eT, Acts::eT) = sigmaT0 * sigmaT0; + double time =0; + //Acts::CurvilinearParameters InitTrackParam(std::make_optional(std::move(cov)), pos, mom, charge, time); // calculated initial parameters + + // Smearing truth parameters as initial parameters + Acts::Vector3D pPos(pv.x(), pv.y(), pv.z()); + Acts::Vector3D pMom(truthmom.x()/1000., truthmom.y()/1000., truthmom.z()/1000.); + std::random_device rd; + std::default_random_engine rng {rd()}; + std::normal_distribution<> norm; // mu: 0 sigma: 1 + Acts::Vector3D deltaPos(sigmaU*norm(rng), sigmaU*norm(rng), sigmaU*norm(rng)); + auto theta = Acts::VectorHelpers::theta(pMom.normalized()); + auto phi = Acts::VectorHelpers::phi(pMom.normalized()); + auto angles = Acts::detail::ensureThetaBounds(phi + sigmaPhi*norm(rng), theta + sigmaTheta*norm(rng)); + Acts::Vector3D dir(std::sin(angles.second) * std::cos(angles.first), + std::sin(angles.second) * std::sin(angles.first), + std::cos(angles.second)); + const Acts::Vector3D deltaMom = ( pMom.norm()*(1 + 0.01*norm(rng)) ) * dir - pMom; + std::cout << "deltaPos: " << deltaPos << std::endl; + std::cout << "deltaMom: " << deltaMom << std::endl; + Acts::CurvilinearParameters InitTrackParam(std::make_optional(std::move(cov)), pPos+deltaPos, pMom+deltaMom, charge, time); + + // the surface which the production point is bound to + Acts::Vector3D center(0, 0, pPos.z()); + Acts::Vector3D normal(0, 0, 1); + std::shared_ptr<const Acts::Surface> initSurface = Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal); + // extrapolate the particle from production point to the first layer + Acts::BoundParameters startParameters(geoctx, std::nullopt, pPos, pMom, charge, time, initSurface); + auto truthParam = m_extrapolationTool->propagate(Gaudi::Hive::currentContext(), startParameters, *pSurface); + std::cout << "truth pos on 1st layer: " << truthParam->position() << std::endl; + std::cout << "truth mom on 1st layer: " << truthParam->momentum() << std::endl; + std::cout << "truth parameters on 1st layer: " << truthParam->parameters() << std::endl; + + + // Call the Acts Kalman Filter + // Prepare the output data with MultiTrajectory + TrajectoryContainer trajectories; + trajectories.reserve(1); + + // Construct a perigee surface as the target surface + //auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>( + // Acts::Vector3D{0., 0., 0.}); + + // Set the KalmanFitter options + std::unique_ptr<const Acts::Logger> logger = Acts::getDefaultLogger("KalmanFitter", Acts::Logging::VERBOSE); + Acts::KalmanFitterOptions<Acts::VoidOutlierFinder> kfOptions( + geoctx, + magctx, + calctx, + Acts::VoidOutlierFinder(), + Acts::LoggerWrapper{*logger}, + &(*pSurface), + true, // scattering + true, // energy loss + false // backward filtering + ); + + ATH_MSG_DEBUG("Invoke fitter"); + + Acts::Navigator navigator(trackingGeometry); + navigator.resolvePassive = false; + navigator.resolveMaterial = true; + navigator.resolveSensitive = true; + + ActsExtrapolationDetail::VariantPropagator* varProp {nullptr}; + + if (m_fieldMode == "FASER") { + ATH_MSG_INFO("Using FASER magnetic field service"); + using BField_t = FASERMagneticFieldWrapper; + BField_t bField; + auto stepper = Acts::EigenStepper<BField_t>(std::move(bField)); + auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper), + std::move(navigator)); + varProp = new VariantPropagator(propagator); + } + else if (m_fieldMode == "Constant") { + std::vector<double> constantFieldVector = m_constantFieldVector; + double Bx = constantFieldVector.at(0); + double By = constantFieldVector.at(1); + double Bz = constantFieldVector.at(2); + ATH_MSG_INFO("Using constant magnetic field: (Bx, By, Bz) = (" << Bx << ", " << By << ", " << Bz << ")"); + using BField_t = Acts::ConstantBField; + BField_t bField(Bx, By, Bz); + auto stepper = Acts::EigenStepper<BField_t>(std::move(bField)); + auto propagator = Acts::Propagator<decltype(stepper), Acts::Navigator>(std::move(stepper), + std::move(navigator)); + varProp = new VariantPropagator(propagator); + } + + auto fit = makeFitterFunction(varProp); + auto result = fit(sourceLinks, InitTrackParam, kfOptions); + + ATH_MSG_VERBOSE("Size of sourceLinks: " << sourceLinks.size()); + + int itrack = 0; + if (result.ok()) { + // Get the fit output object + const auto& fitOutput = result.value(); + + // The track entry indices container. One element here. + std::vector<size_t> trackTips; + trackTips.reserve(1); + trackTips.emplace_back(fitOutput.trackTip); + // The fitted parameters container. One element (at most) here. + IndexedParams indexedParams; + + if (fitOutput.fittedParameters) { + const auto& params = fitOutput.fittedParameters.value(); + ATH_MSG_VERBOSE("Fitted paramemeters for track " << itrack); + ATH_MSG_VERBOSE(" parameters: " << params); + ATH_MSG_VERBOSE(" position: " << params.position().transpose()); + ATH_MSG_VERBOSE(" momentum: " << params.momentum().transpose()); + // Push the fitted parameters to the container + indexedParams.emplace(fitOutput.trackTip, std::move(params)); + } else { + ATH_MSG_DEBUG("No fitted paramemeters for track " << itrack); + } + // Create a SimMultiTrajectory + trajectories.emplace_back(std::move(fitOutput.fittedStates), + std::move(trackTips), std::move(indexedParams)); + } else { + ATH_MSG_WARNING("Fit failed for track " << itrack << " with error" + << result.error()); + // Fit failed, but still create a empty truth fit track + trajectories.push_back(FaserActsRecMultiTrajectory()); + } + + + fillFitResult(geoctx, trajectories, *truthParam); + + } + return StatusCode::SUCCESS; +} + +StatusCode FaserActsKalmanFilterAlg::finalize() +{ + return StatusCode::SUCCESS; +} + + +template <typename Fitter> +struct FitterFunctionImpl + { + Fitter fitter; + + FitterFunctionImpl(Fitter&& f) : fitter(std::move(f)) {} + + FaserActsKalmanFilterAlg::FitterResult + operator()( + const std::vector<RecSourceLink>& sourceLinks, + const Acts::CurvilinearParameters& initialParameters, + const Acts::KalmanFitterOptions<Acts::VoidOutlierFinder>& options) const + { + return fitter.fit(sourceLinks, initialParameters, options); + }; + }; + +FaserActsKalmanFilterAlg::FitterFunction +FaserActsKalmanFilterAlg::makeFitterFunction( + ActsExtrapolationDetail::VariantPropagator* varProp) +{ + + return boost::apply_visitor([&](const auto& propagator) -> FitterFunction { + using Updater = Acts::GainMatrixUpdater; + using Smoother = Acts::GainMatrixSmoother; + using Fitter = Acts::KalmanFitter<typename std::decay_t<decltype(propagator)>, Updater, Smoother>; + + Fitter fitter(std::move(propagator)); + // build the fitter functions. owns the fitter object. + return FitterFunctionImpl<Fitter>(std::move(fitter)); + }, *varProp); + +} + +//Acts::MagneticFieldContext FaserActsKalmanFilterAlg::getMagneticFieldContext(const EventContext& ctx) const { + //SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx}; +Acts::MagneticFieldContext FaserActsKalmanFilterAlg::getMagneticFieldContext() const { + SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey}; + if (!readHandle.isValid()) { + std::stringstream msg; + msg << "Failed to retrieve magnetic field condition data " << m_fieldCondObjInputKey.key() << "."; + throw std::runtime_error(msg.str()); + } + const FaserFieldCacheCondObj* fieldCondObj{*readHandle}; + + return Acts::MagneticFieldContext(fieldCondObj); +} + +void FaserActsKalmanFilterAlg::initializeTree() +{ + m_trackTree->Branch("event_nr", &m_eventNr); + m_trackTree->Branch("traj_nr", &m_trajNr); + m_trackTree->Branch("track_nr", &m_trackNr); + m_trackTree->Branch("t_barcode", &m_t_barcode, "t_barcode/l"); + m_trackTree->Branch("t_charge", &m_t_charge); + m_trackTree->Branch("t_eT", &m_t_eT); + m_trackTree->Branch("t_eLOC0", &m_t_eLOC0); + m_trackTree->Branch("t_eLOC1", &m_t_eLOC1); + m_trackTree->Branch("t_x", &m_t_x); + m_trackTree->Branch("t_y", &m_t_y); + m_trackTree->Branch("t_z", &m_t_z); + m_trackTree->Branch("t_px", &m_t_px); + m_trackTree->Branch("t_py", &m_t_py); + m_trackTree->Branch("t_pz", &m_t_pz); + m_trackTree->Branch("t_eTHETA", &m_t_eTHETA); + m_trackTree->Branch("t_ePHI", &m_t_ePHI); + m_trackTree->Branch("t_eQOP", &m_t_eQOP); + + m_trackTree->Branch("hasFittedParams", &m_hasFittedParams); + m_trackTree->Branch("chi2_fit", &m_chi2_fit); + m_trackTree->Branch("ndf_fit", &m_ndf_fit); + m_trackTree->Branch("eLOC0_fit", &m_eLOC0_fit); + m_trackTree->Branch("eLOC1_fit", &m_eLOC1_fit); + m_trackTree->Branch("ePHI_fit", &m_ePHI_fit); + m_trackTree->Branch("eTHETA_fit", &m_eTHETA_fit); + m_trackTree->Branch("eQOP_fit", &m_eQOP_fit); + m_trackTree->Branch("eT_fit", &m_eT_fit); + m_trackTree->Branch("charge_fit", &m_charge_fit); + m_trackTree->Branch("err_eLOC0_fit", &m_err_eLOC0_fit); + m_trackTree->Branch("err_eLOC1_fit", &m_err_eLOC1_fit); + m_trackTree->Branch("err_ePHI_fit", &m_err_ePHI_fit); + m_trackTree->Branch("err_eTHETA_fit", &m_err_eTHETA_fit); + m_trackTree->Branch("err_eQOP_fit", &m_err_eQOP_fit); + m_trackTree->Branch("err_eT_fit", &m_err_eT_fit); + m_trackTree->Branch("g_px_fit", &m_px_fit); + m_trackTree->Branch("g_py_fit", &m_py_fit); + m_trackTree->Branch("g_pz_fit", &m_pz_fit); + m_trackTree->Branch("g_x_fit" , &m_x_fit); + m_trackTree->Branch("g_y_fit" , &m_y_fit); + m_trackTree->Branch("g_z_fit" , &m_z_fit); + + m_trackTree->Branch("nHoles", &m_nHoles); + m_trackTree->Branch("nOutliers", &m_nOutliers); + m_trackTree->Branch("nStates", &m_nStates); + m_trackTree->Branch("nMeasurements", &m_nMeasurements); + m_trackTree->Branch("volume_id", &m_volumeID); + m_trackTree->Branch("layer_id", &m_layerID); + m_trackTree->Branch("module_id", &m_moduleID); + m_trackTree->Branch("l_x_hit", &m_lx_hit); + m_trackTree->Branch("l_y_hit", &m_ly_hit); + m_trackTree->Branch("g_x_hit", &m_x_hit); + m_trackTree->Branch("g_y_hit", &m_y_hit); + m_trackTree->Branch("g_z_hit", &m_z_hit); + m_trackTree->Branch("res_x_hit", &m_res_x_hit); + m_trackTree->Branch("res_y_hit", &m_res_y_hit); + m_trackTree->Branch("err_x_hit", &m_err_x_hit); + m_trackTree->Branch("err_y_hit", &m_err_y_hit); + m_trackTree->Branch("pull_x_hit", &m_pull_x_hit); + m_trackTree->Branch("pull_y_hit", &m_pull_y_hit); + m_trackTree->Branch("dim_hit", &m_dim_hit); + + m_trackTree->Branch("nPredicted", &m_nPredicted); + m_trackTree->Branch("predicted", &m_prt); + m_trackTree->Branch("eLOC0_prt", &m_eLOC0_prt); + m_trackTree->Branch("eLOC1_prt", &m_eLOC1_prt); + m_trackTree->Branch("ePHI_prt", &m_ePHI_prt); + m_trackTree->Branch("eTHETA_prt", &m_eTHETA_prt); + m_trackTree->Branch("eQOP_prt", &m_eQOP_prt); + m_trackTree->Branch("eT_prt", &m_eT_prt); + m_trackTree->Branch("res_eLOC0_prt", &m_res_eLOC0_prt); + m_trackTree->Branch("res_eLOC1_prt", &m_res_eLOC1_prt); + m_trackTree->Branch("err_eLOC0_prt", &m_err_eLOC0_prt); + m_trackTree->Branch("err_eLOC1_prt", &m_err_eLOC1_prt); + m_trackTree->Branch("err_ePHI_prt", &m_err_ePHI_prt); + m_trackTree->Branch("err_eTHETA_prt", &m_err_eTHETA_prt); + m_trackTree->Branch("err_eQOP_prt", &m_err_eQOP_prt); + m_trackTree->Branch("err_eT_prt", &m_err_eT_prt); + m_trackTree->Branch("pull_eLOC0_prt", &m_pull_eLOC0_prt); + m_trackTree->Branch("pull_eLOC1_prt", &m_pull_eLOC1_prt); + m_trackTree->Branch("g_x_prt", &m_x_prt); + m_trackTree->Branch("g_y_prt", &m_y_prt); + m_trackTree->Branch("g_z_prt", &m_z_prt); + m_trackTree->Branch("px_prt", &m_px_prt); + m_trackTree->Branch("py_prt", &m_py_prt); + m_trackTree->Branch("pz_prt", &m_pz_prt); + m_trackTree->Branch("eta_prt", &m_eta_prt); + m_trackTree->Branch("pT_prt", &m_pT_prt); + + m_trackTree->Branch("nFiltered", &m_nFiltered); + m_trackTree->Branch("filtered", &m_flt); + m_trackTree->Branch("eLOC0_flt", &m_eLOC0_flt); + m_trackTree->Branch("eLOC1_flt", &m_eLOC1_flt); + m_trackTree->Branch("ePHI_flt", &m_ePHI_flt); + m_trackTree->Branch("eTHETA_flt", &m_eTHETA_flt); + m_trackTree->Branch("eQOP_flt", &m_eQOP_flt); + m_trackTree->Branch("eT_flt", &m_eT_flt); + m_trackTree->Branch("res_eLOC0_flt", &m_res_eLOC0_flt); + m_trackTree->Branch("res_eLOC1_flt", &m_res_eLOC1_flt); + m_trackTree->Branch("err_eLOC0_flt", &m_err_eLOC0_flt); + m_trackTree->Branch("err_eLOC1_flt", &m_err_eLOC1_flt); + m_trackTree->Branch("err_ePHI_flt", &m_err_ePHI_flt); + m_trackTree->Branch("err_eTHETA_flt", &m_err_eTHETA_flt); + m_trackTree->Branch("err_eQOP_flt", &m_err_eQOP_flt); + m_trackTree->Branch("err_eT_flt", &m_err_eT_flt); + m_trackTree->Branch("pull_eLOC0_flt", &m_pull_eLOC0_flt); + m_trackTree->Branch("pull_eLOC1_flt", &m_pull_eLOC1_flt); + m_trackTree->Branch("g_x_flt", &m_x_flt); + m_trackTree->Branch("g_y_flt", &m_y_flt); + m_trackTree->Branch("g_z_flt", &m_z_flt); + m_trackTree->Branch("px_flt", &m_px_flt); + m_trackTree->Branch("py_flt", &m_py_flt); + m_trackTree->Branch("pz_flt", &m_pz_flt); + m_trackTree->Branch("eta_flt", &m_eta_flt); + m_trackTree->Branch("pT_flt", &m_pT_flt); + m_trackTree->Branch("chi2", &m_chi2); + + m_trackTree->Branch("nSmoothed", &m_nSmoothed); + m_trackTree->Branch("smoothed", &m_smt); + m_trackTree->Branch("eLOC0_smt", &m_eLOC0_smt); + m_trackTree->Branch("eLOC1_smt", &m_eLOC1_smt); + m_trackTree->Branch("ePHI_smt", &m_ePHI_smt); + m_trackTree->Branch("eTHETA_smt", &m_eTHETA_smt); + m_trackTree->Branch("eQOP_smt", &m_eQOP_smt); + m_trackTree->Branch("eT_smt", &m_eT_smt); + m_trackTree->Branch("res_eLOC0_smt", &m_res_eLOC0_smt); + m_trackTree->Branch("res_eLOC1_smt", &m_res_eLOC1_smt); + m_trackTree->Branch("err_eLOC0_smt", &m_err_eLOC0_smt); + m_trackTree->Branch("err_eLOC1_smt", &m_err_eLOC1_smt); + m_trackTree->Branch("err_ePHI_smt", &m_err_ePHI_smt); + m_trackTree->Branch("err_eTHETA_smt", &m_err_eTHETA_smt); + m_trackTree->Branch("err_eQOP_smt", &m_err_eQOP_smt); + m_trackTree->Branch("err_eT_smt", &m_err_eT_smt); + m_trackTree->Branch("pull_eLOC0_smt", &m_pull_eLOC0_smt); + m_trackTree->Branch("pull_eLOC1_smt", &m_pull_eLOC1_smt); + m_trackTree->Branch("g_x_smt", &m_x_smt); + m_trackTree->Branch("g_y_smt", &m_y_smt); + m_trackTree->Branch("g_z_smt", &m_z_smt); + m_trackTree->Branch("px_smt", &m_px_smt); + m_trackTree->Branch("py_smt", &m_py_smt); + m_trackTree->Branch("pz_smt", &m_pz_smt); + m_trackTree->Branch("eta_smt", &m_eta_smt); + m_trackTree->Branch("pT_smt", &m_pT_smt); +} + +void FaserActsKalmanFilterAlg::fillFitResult( + const Acts::GeometryContext& geoctx, + const TrajectoryContainer& trajectories, + const Acts::BoundParameters& truthParam + ) +{ + m_t_eLOC0 = truthParam.parameters()[Acts::ParDef::eLOC_0]; + m_t_eLOC1 = truthParam.parameters()[Acts::ParDef::eLOC_1]; + m_t_ePHI = truthParam.parameters()[Acts::ParDef::ePHI]; + m_t_eTHETA = truthParam.parameters()[Acts::ParDef::eTHETA]; + m_t_eQOP = truthParam.parameters()[Acts::ParDef::eQOP]; + m_t_eT = truthParam.parameters()[Acts::ParDef::eT]; + m_t_x = truthParam.position()(0); + m_t_y = truthParam.position()(1); + m_t_z = truthParam.position()(2); + m_t_px = truthParam.momentum()(0); + m_t_py = truthParam.momentum()(1); + m_t_pz = truthParam.momentum()(2); + std::cout<<"truth global position on the first layer = "<<m_t_x<<" "<<m_t_y<<" "<<m_t_z<<" "<<std::endl; + std::cout<<"truth momentum on the first layer = "<<m_t_px<<" "<<m_t_py<<" "<<m_t_pz<<" "<<std::endl; + std::cout<<"truth local parameters on the first layer = "<<m_t_eLOC0<<" "<<m_t_eLOC1<<" "<<m_t_ePHI<<" "<<m_t_eTHETA<<" "<<m_t_eQOP<<" "<<std::endl; + + // Loop over the trajectories + int iTraj = 0; + for (const auto& traj : trajectories) { + m_trajNr = iTraj; + + // The trajectory entry indices and the multiTrajectory + const auto& [trackTips, mj] = traj.trajectory(); + if (trackTips.empty()) { + ATH_MSG_WARNING("Empty multiTrajectory."); + continue; + } + + // Get the entry index for the single trajectory + auto& trackTip = trackTips.front(); + std::cout<<"trackTip = "<<trackTip<<std::endl; + + // Collect the trajectory summary info + auto trajState = + Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); + + m_nMeasurements = trajState.nMeasurements; + m_nStates = trajState.nStates; + m_nOutliers = trajState.nOutliers; + m_nHoles = trajState.nHoles; + m_chi2_fit = trajState.chi2Sum; + m_ndf_fit = trajState.NDF; + std::cout << "Track has " << trajState.nMeasurements + << " measurements and " << trajState.nHoles + << " holes and " << trajState.nOutliers + << " outliers and " << trajState.nStates + << " states " << std::endl; + + /// If it has track parameters, fill the values + if (traj.hasTrackParameters(trackTip)) + { + m_hasFittedParams = true; + const auto &boundParam = traj.trackParameters(trackTip); + const auto ¶meter = boundParam.parameters(); + const auto &covariance = *boundParam.covariance(); + m_charge_fit = boundParam.charge(); + m_eLOC0_fit = parameter[Acts::ParDef::eLOC_0]; + m_eLOC1_fit = parameter[Acts::ParDef::eLOC_1]; + m_ePHI_fit = parameter[Acts::ParDef::ePHI]; + m_eTHETA_fit = parameter[Acts::ParDef::eTHETA]; + m_eQOP_fit = parameter[Acts::ParDef::eQOP]; + m_eT_fit = parameter[Acts::ParDef::eT]; + m_err_eLOC0_fit = + sqrt(covariance(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0)); + m_err_eLOC1_fit = + sqrt(covariance(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1)); + m_err_ePHI_fit = sqrt(covariance(Acts::ParDef::ePHI, Acts::ParDef::ePHI)); + m_err_eTHETA_fit = + sqrt(covariance(Acts::ParDef::eTHETA, Acts::ParDef::eTHETA)); + m_err_eQOP_fit = sqrt(covariance(Acts::ParDef::eQOP, Acts::ParDef::eQOP)); + m_err_eT_fit = sqrt(covariance(Acts::ParDef::eT, Acts::ParDef::eT)); + + m_px_fit = boundParam.momentum()(0); + m_py_fit = boundParam.momentum()(1); + m_pz_fit = boundParam.momentum()(2); + m_x_fit = boundParam.position()(0); + m_y_fit = boundParam.position()(1); + m_z_fit = boundParam.position()(2); + } + + m_nPredicted = 0; + m_nFiltered = 0; + m_nSmoothed = 0; + + mj.visitBackwards(trackTip, [&](const auto &state) { + /// Only fill the track states with non-outlier measurement + auto typeFlags = state.typeFlags(); + if (not typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) + { + return true; + } + + /// Get the geometry ID + auto geoID = state.referenceSurface().geoID(); + m_volumeID.push_back(geoID.volume()); + m_layerID.push_back(geoID.layer()); + m_moduleID.push_back(geoID.sensitive()); + + auto meas = std::get<Measurement>(*state.uncalibrated()); + + /// Get local position + Acts::Vector2D local(meas.parameters()[Acts::ParDef::eLOC_0], + meas.parameters()[Acts::ParDef::eLOC_1]); + /// Get global position + Acts::Vector3D global(0, 0, 0); + /// This is an arbitrary vector. Doesn't matter in coordinate transformation + /// in Acts code + Acts::Vector3D mom(1, 1, 1); + meas.referenceObject().localToGlobal(geoctx, + local, mom, global); + + /// Get measurement covariance + auto cov = meas.covariance(); + + m_lx_hit.push_back(local.x()); + m_ly_hit.push_back(local.y()); + m_x_hit.push_back(global.x()); + m_y_hit.push_back(global.y()); + m_z_hit.push_back(global.z()); + + /// Get the predicted parameter for this state + bool predicted = false; + if (state.hasPredicted()) + { + predicted = true; + m_nPredicted++; + Acts::BoundParameters parameter( + geoctx, + state.predictedCovariance(), + state.predicted(), + state.referenceSurface().getSharedPtr()); + auto covariance = state.predictedCovariance(); + + /// Local hit residual info + auto H = meas.projector(); + auto resCov = cov + H * covariance * H.transpose(); + auto residual = meas.residual(parameter); + + /// Predicted residual + m_res_eLOC0_prt.push_back(residual(Acts::ParDef::eLOC_0)); + m_res_eLOC1_prt.push_back(residual(Acts::ParDef::eLOC_1)); + + /// Predicted parameter pulls + m_pull_eLOC0_prt.push_back( + residual(Acts::ParDef::eLOC_0) / + sqrt(resCov(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0))); + m_pull_eLOC1_prt.push_back( + residual(Acts::ParDef::eLOC_1) / + sqrt(resCov(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1))); + + + /// Predicted parameter + m_eLOC0_prt.push_back(parameter.parameters()[Acts::ParDef::eLOC_0]); + m_eLOC1_prt.push_back(parameter.parameters()[Acts::ParDef::eLOC_1]); + m_ePHI_prt.push_back(parameter.parameters()[Acts::ParDef::ePHI]); + m_eTHETA_prt.push_back(parameter.parameters()[Acts::ParDef::eTHETA]); + m_eQOP_prt.push_back(parameter.parameters()[Acts::ParDef::eQOP]); + m_eT_prt.push_back(parameter.parameters()[Acts::ParDef::eT]); + + /// Predicted parameter Uncertainties + m_err_eLOC0_prt.push_back( + sqrt(covariance(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0))); + m_err_eLOC1_prt.push_back( + sqrt(covariance(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1))); + m_err_ePHI_prt.push_back( + sqrt(covariance(Acts::ParDef::ePHI, Acts::ParDef::ePHI))); + m_err_eTHETA_prt.push_back( + sqrt(covariance(Acts::ParDef::eTHETA, Acts::ParDef::eTHETA))); + m_err_eQOP_prt.push_back( + sqrt(covariance(Acts::ParDef::eQOP, Acts::ParDef::eQOP))); + m_err_eT_prt.push_back( + sqrt(covariance(Acts::ParDef::eT, Acts::ParDef::eT))); + + m_x_prt.push_back(parameter.position().x()); + m_y_prt.push_back(parameter.position().y()); + m_z_prt.push_back(parameter.position().z()); + m_px_prt.push_back(parameter.momentum().x()); + m_py_prt.push_back(parameter.momentum().y()); + m_pz_prt.push_back(parameter.momentum().z()); + m_pT_prt.push_back(parameter.pT()); + m_eta_prt.push_back(eta(parameter.position())); + } + else + { + /// Push bad values if no predicted parameter + m_eLOC0_prt.push_back(-9999); + m_eLOC1_prt.push_back(-9999); + m_ePHI_prt.push_back(-9999); + m_eTHETA_prt.push_back(-9999); + m_eQOP_prt.push_back(-9999); + m_eT_prt.push_back(-9999); + m_res_eLOC0_prt.push_back(-9999); + m_res_eLOC1_prt.push_back(-9999); + m_err_eLOC0_prt.push_back(-9999); + m_err_eLOC1_prt.push_back(-9999); + m_err_ePHI_prt.push_back(-9999); + m_err_eTHETA_prt.push_back(-9999); + m_err_eQOP_prt.push_back(-9999); + m_err_eT_prt.push_back(-9999); + m_pull_eLOC0_prt.push_back(-9999); + m_pull_eLOC1_prt.push_back(-9999); + m_x_prt.push_back(-9999); + m_y_prt.push_back(-9999); + m_z_prt.push_back(-9999); + m_px_prt.push_back(-9999); + m_py_prt.push_back(-9999); + m_pz_prt.push_back(-9999); + m_pT_prt.push_back(-9999); + m_eta_prt.push_back(-9999); + } + + bool filtered = false; + if (state.hasFiltered()) + { + filtered = true; + m_nFiltered++; + Acts::BoundParameters parameter( + geoctx, + state.filteredCovariance(), state.filtered(), + state.referenceSurface().getSharedPtr()); + auto covariance = state.filteredCovariance(); + + /// Local hit residual info + auto H = meas.projector(); + auto resCov = cov + H * covariance * H.transpose(); + auto residual = meas.residual(parameter); + + /// Filtered residual + m_res_eLOC0_flt.push_back(residual(Acts::ParDef::eLOC_0)); + m_res_eLOC1_flt.push_back(residual(Acts::ParDef::eLOC_1)); + + /// Filtered parameter pulls + m_pull_eLOC0_flt.push_back( + residual(Acts::ParDef::eLOC_0) / + sqrt(resCov(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0))); + m_pull_eLOC1_flt.push_back( + residual(Acts::ParDef::eLOC_1) / + sqrt(resCov(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1))); + + /// Filtered parameter + m_eLOC0_flt.push_back(parameter.parameters()[Acts::ParDef::eLOC_0]); + m_eLOC1_flt.push_back(parameter.parameters()[Acts::ParDef::eLOC_1]); + m_ePHI_flt.push_back(parameter.parameters()[Acts::ParDef::ePHI]); + m_eTHETA_flt.push_back(parameter.parameters()[Acts::ParDef::eTHETA]); + m_eQOP_flt.push_back(parameter.parameters()[Acts::ParDef::eQOP]); + m_eT_flt.push_back(parameter.parameters()[Acts::ParDef::eT]); + + /// Filtered parameter uncertainties + m_err_eLOC0_flt.push_back( + sqrt(covariance(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0))); + m_err_eLOC1_flt.push_back( + sqrt(covariance(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1))); + m_err_ePHI_flt.push_back( + sqrt(covariance(Acts::ParDef::ePHI, Acts::ParDef::ePHI))); + m_err_eTHETA_flt.push_back( + sqrt(covariance(Acts::ParDef::eTHETA, Acts::ParDef::eTHETA))); + m_err_eQOP_flt.push_back( + sqrt(covariance(Acts::ParDef::eQOP, Acts::ParDef::eQOP))); + m_err_eT_flt.push_back( + sqrt(covariance(Acts::ParDef::eT, Acts::ParDef::eT))); + + /// Other filtered parameter info + m_x_flt.push_back(parameter.position().x()); + m_y_flt.push_back(parameter.position().y()); + m_z_flt.push_back(parameter.position().z()); + m_px_flt.push_back(parameter.momentum().x()); + m_py_flt.push_back(parameter.momentum().y()); + m_pz_flt.push_back(parameter.momentum().z()); + m_pT_flt.push_back(parameter.pT()); + m_eta_flt.push_back(eta(parameter.position())); + m_chi2.push_back(state.chi2()); + + } + else + { + /// Push bad values if no filtered parameter + m_eLOC0_flt.push_back(-9999); + m_eLOC1_flt.push_back(-9999); + m_ePHI_flt.push_back(-9999); + m_eTHETA_flt.push_back(-9999); + m_eQOP_flt.push_back(-9999); + m_eT_flt.push_back(-9999); + m_res_eLOC0_flt.push_back(-9999); + m_res_eLOC1_flt.push_back(-9999); + m_err_eLOC0_flt.push_back(-9999); + m_err_eLOC1_flt.push_back(-9999); + m_err_ePHI_flt.push_back(-9999); + m_err_eTHETA_flt.push_back(-9999); + m_err_eQOP_flt.push_back(-9999); + m_err_eT_flt.push_back(-9999); + m_pull_eLOC0_flt.push_back(-9999); + m_pull_eLOC1_flt.push_back(-9999); + m_x_flt.push_back(-9999); + m_y_flt.push_back(-9999); + m_z_flt.push_back(-9999); + m_py_flt.push_back(-9999); + m_pz_flt.push_back(-9999); + m_pT_flt.push_back(-9999); + m_eta_flt.push_back(-9999); + m_chi2.push_back(-9999); + } + + bool smoothed = false; + if (state.hasSmoothed()) + { + smoothed = true; + m_nSmoothed++; + Acts::BoundParameters parameter( + geoctx, + state.smoothedCovariance(), state.smoothed(), + state.referenceSurface().getSharedPtr()); + auto covariance = state.smoothedCovariance(); + + /// Local hit residual info + auto H = meas.projector(); + auto resCov = cov + H * covariance * H.transpose(); + auto residual = meas.residual(parameter); + + m_res_x_hit.push_back(residual(Acts::ParDef::eLOC_0)); + m_res_y_hit.push_back(residual(Acts::ParDef::eLOC_1)); + m_err_x_hit.push_back( + sqrt(resCov(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0))); + m_err_y_hit.push_back( + sqrt(resCov(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1))); + m_pull_x_hit.push_back( + residual(Acts::ParDef::eLOC_0) / + sqrt(resCov(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0))); + m_pull_y_hit.push_back( + residual(Acts::ParDef::eLOC_1) / + sqrt(resCov(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1))); + m_dim_hit.push_back(state.calibratedSize()); + + /// Smoothed residual + m_res_eLOC0_smt.push_back(residual(Acts::ParDef::eLOC_0)); + m_res_eLOC1_smt.push_back(residual(Acts::ParDef::eLOC_1)); + + /// Smoothed parameter pulls + m_pull_eLOC0_smt.push_back( + residual(Acts::ParDef::eLOC_0) / + sqrt(resCov(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0))); + m_pull_eLOC1_smt.push_back( + residual(Acts::ParDef::eLOC_1) / + sqrt(resCov(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1))); + + /// Smoothed parameter + m_eLOC0_smt.push_back(parameter.parameters()[Acts::ParDef::eLOC_0]); + m_eLOC1_smt.push_back(parameter.parameters()[Acts::ParDef::eLOC_1]); + m_ePHI_smt.push_back(parameter.parameters()[Acts::ParDef::ePHI]); + m_eTHETA_smt.push_back(parameter.parameters()[Acts::ParDef::eTHETA]); + m_eQOP_smt.push_back(parameter.parameters()[Acts::ParDef::eQOP]); + m_eT_smt.push_back(parameter.parameters()[Acts::ParDef::eT]); + + /// Smoothed parameter uncertainties + m_err_eLOC0_smt.push_back( + sqrt(covariance(Acts::ParDef::eLOC_0, Acts::ParDef::eLOC_0))); + m_err_eLOC1_smt.push_back( + sqrt(covariance(Acts::ParDef::eLOC_1, Acts::ParDef::eLOC_1))); + m_err_ePHI_smt.push_back( + sqrt(covariance(Acts::ParDef::ePHI, Acts::ParDef::ePHI))); + m_err_eTHETA_smt.push_back( + sqrt(covariance(Acts::ParDef::eTHETA, Acts::ParDef::eTHETA))); + m_err_eQOP_smt.push_back( + sqrt(covariance(Acts::ParDef::eQOP, Acts::ParDef::eQOP))); + m_err_eT_smt.push_back( + sqrt(covariance(Acts::ParDef::eT, Acts::ParDef::eT))); + + m_x_smt.push_back(parameter.position().x()); + m_y_smt.push_back(parameter.position().y()); + m_z_smt.push_back(parameter.position().z()); + m_px_smt.push_back(parameter.momentum().x()); + m_py_smt.push_back(parameter.momentum().y()); + m_pz_smt.push_back(parameter.momentum().z()); + m_pT_smt.push_back(parameter.pT()); + m_eta_smt.push_back(eta(parameter.position())); + } + else + { + /// Push bad values if no smoothed parameter + m_eLOC0_smt.push_back(-9999); + m_eLOC1_smt.push_back(-9999); + m_ePHI_smt.push_back(-9999); + m_eTHETA_smt.push_back(-9999); + m_eQOP_smt.push_back(-9999); + m_eT_smt.push_back(-9999); + m_res_eLOC0_smt.push_back(-9999); + m_res_eLOC1_smt.push_back(-9999); + m_err_eLOC0_smt.push_back(-9999); + m_err_eLOC1_smt.push_back(-9999); + m_err_ePHI_smt.push_back(-9999); + m_err_eTHETA_smt.push_back(-9999); + m_err_eQOP_smt.push_back(-9999); + m_err_eT_smt.push_back(-9999); + m_pull_eLOC0_smt.push_back(-9999); + m_pull_eLOC1_smt.push_back(-9999); + m_x_smt.push_back(-9999); + m_y_smt.push_back(-9999); + m_z_smt.push_back(-9999); + m_px_smt.push_back(-9999); + m_py_smt.push_back(-9999); + m_pz_smt.push_back(-9999); + m_pT_smt.push_back(-9999); + m_eta_smt.push_back(-9999); + m_res_x_hit.push_back(-9999); + m_res_y_hit.push_back(-9999); + m_err_x_hit.push_back(-9999); + m_err_y_hit.push_back(-9999); + m_pull_x_hit.push_back(-9999); + m_pull_y_hit.push_back(-9999); + m_dim_hit.push_back(-9999); + } + + /// Save whether or not states had various KF steps + m_prt.push_back(predicted); + m_flt.push_back(filtered); + m_smt.push_back(smoothed); + + return true; + } /// Finish lambda function + ); /// Finish multi trajectory visitBackwards call + + iTraj++; + + } // all trajectories + + m_trackTree->Fill(); + + clearTrackVariables(); +} + +void FaserActsKalmanFilterAlg::clearTrackVariables() +{ + m_volumeID.clear(); + m_layerID.clear(); + m_moduleID.clear(); + m_lx_hit.clear(); + m_ly_hit.clear(); + m_x_hit.clear(); + m_y_hit.clear(); + m_z_hit.clear(); + m_res_x_hit.clear(); + m_res_y_hit.clear(); + m_err_x_hit.clear(); + m_err_y_hit.clear(); + m_pull_x_hit.clear(); + m_pull_y_hit.clear(); + m_dim_hit.clear(); + + m_prt.clear(); + m_eLOC0_prt.clear(); + m_eLOC1_prt.clear(); + m_ePHI_prt.clear(); + m_eTHETA_prt.clear(); + m_eQOP_prt.clear(); + m_eT_prt.clear(); + m_res_eLOC0_prt.clear(); + m_res_eLOC1_prt.clear(); + m_err_eLOC0_prt.clear(); + m_err_eLOC1_prt.clear(); + m_err_ePHI_prt.clear(); + m_err_eTHETA_prt.clear(); + m_err_eQOP_prt.clear(); + m_err_eT_prt.clear(); + m_pull_eLOC0_prt.clear(); + m_pull_eLOC1_prt.clear(); + m_x_prt.clear(); + m_y_prt.clear(); + m_z_prt.clear(); + m_px_prt.clear(); + m_py_prt.clear(); + m_pz_prt.clear(); + m_eta_prt.clear(); + m_pT_prt.clear(); + + m_flt.clear(); + m_eLOC0_flt.clear(); + m_eLOC1_flt.clear(); + m_ePHI_flt.clear(); + m_eTHETA_flt.clear(); + m_eQOP_flt.clear(); + m_eT_flt.clear(); + m_res_eLOC0_flt.clear(); + m_res_eLOC1_flt.clear(); + m_err_eLOC0_flt.clear(); + m_err_eLOC1_flt.clear(); + m_err_ePHI_flt.clear(); + m_err_eTHETA_flt.clear(); + m_err_eQOP_flt.clear(); + m_err_eT_flt.clear(); + m_pull_eLOC0_flt.clear(); + m_pull_eLOC1_flt.clear(); + m_x_flt.clear(); + m_y_flt.clear(); + m_z_flt.clear(); + m_px_flt.clear(); + m_py_flt.clear(); + m_pz_flt.clear(); + m_eta_flt.clear(); + m_pT_flt.clear(); + m_chi2.clear(); + + m_smt.clear(); + m_eLOC0_smt.clear(); + m_eLOC1_smt.clear(); + m_ePHI_smt.clear(); + m_eTHETA_smt.clear(); + m_eQOP_smt.clear(); + m_eT_smt.clear(); + m_res_eLOC0_smt.clear(); + m_res_eLOC1_smt.clear(); + m_err_eLOC0_smt.clear(); + m_err_eLOC1_smt.clear(); + m_err_ePHI_smt.clear(); + m_err_eTHETA_smt.clear(); + m_err_eQOP_smt.clear(); + m_err_eT_smt.clear(); + m_pull_eLOC0_smt.clear(); + m_pull_eLOC1_smt.clear(); + m_x_smt.clear(); + m_y_smt.clear(); + m_z_smt.clear(); + m_px_smt.clear(); + m_py_smt.clear(); + m_pz_smt.clear(); + m_eta_smt.clear(); + m_pT_smt.clear(); + + return; +} diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx new file mode 100755 index 0000000000000000000000000000000000000000..59a385596f4fad95415b5d6291ab3901482e7b1f --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx @@ -0,0 +1,8 @@ +/* + Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h" + + +DECLARE_COMPONENT( FaserActsKalmanFilterAlg ) diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/components/KalmanFilter_entries.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/components/KalmanFilter_entries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4634ae05271a0d4b4dbbb6c24d39d313b60a8ba6 --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/src/components/KalmanFilter_entries.cxx @@ -0,0 +1,3 @@ +#include "FaserActsKalmanFilter/FaserActsKalmanFilterAlg.h" + +DECLARE_COMPONENT( FaserActsKalmanFilterAlg ) \ No newline at end of file diff --git a/Tracking/Acts/FaserActsKalmanFilter/test/FaserActsKalmanFilterAlg.py b/Tracking/Acts/FaserActsKalmanFilter/test/FaserActsKalmanFilterAlg.py new file mode 100644 index 0000000000000000000000000000000000000000..20e97d74555122d99e0857e3f75f468532fba111 --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/test/FaserActsKalmanFilterAlg.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +import sys +from AthenaCommon.Logging import log, logging +from AthenaCommon.Constants import DEBUG, VERBOSE, INFO +from AthenaCommon.Configurable import Configurable +from CalypsoConfiguration.AllConfigFlags import ConfigFlags +from AthenaConfiguration.TestDefaults import defaultTestFiles +from AthenaConfiguration.MainServicesConfig import MainServicesCfg +from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg +from AthenaPoolCnvSvc.PoolWriteConfig import PoolWriteCfg +from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg +from TrackerPrepRawDataFormation.TrackerPrepRawDataFormationConfig import FaserSCT_ClusterizationCfg +from TrackerSpacePointFormation.TrackerSpacePointFormationConfig import TrackerSpacePointFinderCfg +from TruthSeededTrackFinder.TruthSeededTrackFinderConfig import TruthSeededTrackFinderCfg +from FaserActsKalmanFilter.FaserActsKalmanFilterConfig import FaserActsKalmanFilterCfg + + +log.setLevel(DEBUG) +Configurable.configurableRun3Behavior = True + +# Configure +ConfigFlags.Input.Files = ['my.RDO.pool.root'] +ConfigFlags.Output.ESDFileName = "tmp.root" +ConfigFlags.IOVDb.GlobalTag = "OFLCOND-XXXX-XXX-XX" +ConfigFlags.GeoModel.Align.Dynamic = False +ConfigFlags.Beam.NumberOfCollisions = 0. +#ConfigFlags.Concurrency.NumThreads = 1 +ConfigFlags.lock() + +# Core components +acc = MainServicesCfg(ConfigFlags) +acc.merge(PoolReadCfg(ConfigFlags)) + +# Inner Detector +acc.merge(FaserSCT_ClusterizationCfg(ConfigFlags)) +acc.merge(TrackerSpacePointFinderCfg(ConfigFlags)) +acc.merge(TruthSeededTrackFinderCfg(ConfigFlags)) +acc.merge(FaserActsKalmanFilterCfg(ConfigFlags)) + +logging.getLogger('forcomps').setLevel(VERBOSE) +acc.foreach_component("*").OutputLevel = VERBOSE +acc.foreach_component("*ClassID*").OutputLevel = INFO +acc.getService("StoreGateSvc").Dump = True +acc.getService("ConditionStore").Dump = True +acc.printConfig(withDetails=True) +ConfigFlags.dump() + +# Execute and finish +sc = acc.run(maxEvents=-1) + +# Success should be 0 +sys.exit(not sc.isSuccess()) diff --git a/Tracking/Acts/README.md b/Tracking/Acts/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2a0874fce87ed08d42fa4ac7c77d0226d430e318 --- /dev/null +++ b/Tracking/Acts/README.md @@ -0,0 +1,8 @@ + +1) Go to the installation (run) directory + +2) source ./setup.sh + +3) To write the tracking geometry, type the command: FaserActsWriteTrackingGeometry.py + +4) To run the extrapolator, type the command: FaserActsExtrapolationAlg.py