From 7ce5f9613e2d36e9b9eaefe7ed1317af21148124 Mon Sep 17 00:00:00 2001 From: Markus Prim <markus.prim@cern.ch> Date: Fri, 5 Nov 2021 18:15:49 +0100 Subject: [PATCH] First prototyp for tracker station alignment. The prototype operates in the global coordinate space and is thus only be able to align xyz. --- .../CMakeLists.txt | 18 + .../GlobalChi2EquationGenerator/ReadMe | 4 + .../src/GlobalChi2EquationGenerator.cxx | 558 ++++++++++++++++++ .../src/GlobalChi2EquationGenerator.h | 171 ++++++ .../GlobalChi2EquationGenerator_entries.cxx | 4 + 5 files changed, 755 insertions(+) create mode 100644 Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/CMakeLists.txt create mode 100644 Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/ReadMe create mode 100755 Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/GlobalChi2EquationGenerator.cxx create mode 100755 Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/GlobalChi2EquationGenerator.h create mode 100644 Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/components/GlobalChi2EquationGenerator_entries.cxx diff --git a/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/CMakeLists.txt b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/CMakeLists.txt new file mode 100644 index 000000000..3f468a9df --- /dev/null +++ b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/CMakeLists.txt @@ -0,0 +1,18 @@ +################################################################################ +# Package: GlobalChi2EquationGenerator +################################################################################ + +# Declare the package name: +atlas_subdir( GlobalChi2EquationGenerator ) + +# External dependencies: +find_package( Eigen ) + +find_package( ROOT COMPONENTS Core Tree MathCore) + +atlas_add_component( GlobalChi2EquationGenerator + src/components/*.cxx src/*.cxx src/*.h + INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${EIGEN_LIBRARIES} ${ROOT_LIBRARIES} AthenaBaseComps AthContainers GeoPrimitives Identifier GaudiKernel TrackerReadoutGeometry TrackerPrepRawData TrackerSpacePoint AthenaMonitoringKernelLib FaserDetDescr xAODEventInfo TrkEventPrimitives TrackerIdentifier FaserSiSpacePointToolLib TrkSpacePoint ) + +atlas_install_python_modules( python/*.py ) diff --git a/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/ReadMe b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/ReadMe new file mode 100644 index 000000000..9caf9456f --- /dev/null +++ b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/ReadMe @@ -0,0 +1,4 @@ +GlobalChi2EquationGenerator: + Generates the matrix and vector for the global chi2 alignment equation. + +For each station, select the spacepoint triplets first, then perform a 3D line fit and require the chi2 less than chi2max. diff --git a/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/GlobalChi2EquationGenerator.cxx b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/GlobalChi2EquationGenerator.cxx new file mode 100755 index 000000000..8a59cca70 --- /dev/null +++ b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/GlobalChi2EquationGenerator.cxx @@ -0,0 +1,558 @@ +/* + Copyright (C) 2002-2021 ChRN for the benefit of the ATLAS collaboration + */ + +/*************************************************************************** + ------------------- + ***************************************************************************/ + +//<<<<<< INCLUDES >>>>>> + + +#include "TrackerSPFit.h" + +// For processing clusters +#include "TrackerReadoutGeometry/SiLocalPosition.h" +#include "TrackerReadoutGeometry/SiDetectorDesign.h" +#include "TrackerReadoutGeometry/SiDetectorElement.h" + +// Space point Classes, +#include "TrackerSpacePoint/FaserSCT_SpacePointContainer.h" +#include "TrackerIdentifier/FaserSCT_ID.h" + + +// general Atlas classes +#include "FaserDetDescr/FaserDetectorID.h" +#include "xAODEventInfo/EventInfo.h" +#include "StoreGate/ReadCondHandle.h" + +#include "AthenaMonitoringKernel/Monitored.h" + +#include <fstream> + +namespace Tracker +{ + //------------------------------------------------------------------------ + TrackerSPFit::TrackerSPFit(const std::string& name, + ISvcLocator* pSvcLocator) + : AthReentrantAlgorithm(name, pSvcLocator) + , m_thistSvc("THistSvc", name) + { + declareProperty("SaveAllSPInfo", m_saveallsp=false); + declareProperty("chi2Max", m_chi2max=10); + declareProperty("OutputDir", m_outputdir="./"); + + m_t.resize(144, 1); + m_t.setZero(); + m_M.resize(144, 144); + m_M.setZero(); + + for (unsigned int i=0; i < 8; ++i) { + TrackerSPFit::AlignVector18D t; + t.setZero(); + m_ts.push_back(t); + TrackerSPFit::AlignMatrix18x18 M; + M.setZero(); + m_Ms.push_back(M); + } + } + + //----------------------------------------------------------------------- + StatusCode TrackerSPFit::initialize() + { + ATH_MSG_DEBUG( "TrackerSPFit::initialize()" ); + + CHECK(m_thistSvc.retrieve()); + // Check that clusters, space points and ids have names + if(m_Sct_clcontainerKey.key().empty()){ + ATH_MSG_FATAL( "SCTs selected and no name set for SCT clusters"); + return StatusCode::FAILURE; + } + ATH_CHECK( m_Sct_clcontainerKey.initialize() ); + + 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() ); + + m_tree= new TTree("spfit","tree"); + TrackerSPFit::initializeTree(); + + // 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()); + + + CHECK(m_thistSvc->regTree("/TrackerSPFit/spfit",m_tree)); + ATH_MSG_INFO( "TrackerSPFit::initialized" ); + return StatusCode::SUCCESS; + } + + //------------------------------------------------------------------------- + void TrackerSPFit::initializeTree(){ + m_tree->Branch("evtId",&m_eventNumber); + m_tree->Branch("initial_track_chi2", &m_initial_track_chi2); + m_tree->Branch("initial_track_cx", &m_initial_track_cx); + m_tree->Branch("initial_track_mx", &m_initial_track_mx); + m_tree->Branch("initial_track_cy", &m_initial_track_cy); + m_tree->Branch("initial_track_my", &m_initial_track_my); + m_tree->Branch("initial_track_residual_x0", &m_initial_track_residual_x0); + m_tree->Branch("initial_track_residual_x1", &m_initial_track_residual_x1); + m_tree->Branch("initial_track_residual_x2", &m_initial_track_residual_x2); + m_tree->Branch("initial_track_residual_y0", &m_initial_track_residual_y0); + m_tree->Branch("initial_track_residual_y1", &m_initial_track_residual_y1); + m_tree->Branch("initial_track_residual_y2", &m_initial_track_residual_y2); + m_tree->Branch("x0", &m_x0); + m_tree->Branch("x1", &m_x1); + m_tree->Branch("x2", &m_x2); + m_tree->Branch("y0", &m_y0); + m_tree->Branch("y1", &m_y1); + m_tree->Branch("y2", &m_y2); + m_tree->Branch("sigma_x0", &m_sigma_x0); + m_tree->Branch("sigma_x1", &m_sigma_x1); + m_tree->Branch("sigma_x2", &m_sigma_x2); + m_tree->Branch("sigma_y0", &m_sigma_y0); + m_tree->Branch("sigma_y1", &m_sigma_y1); + m_tree->Branch("sigma_y2", &m_sigma_y2); + m_tree->Branch("z0", &m_z0); + m_tree->Branch("z1", &m_z1); + m_tree->Branch("z2", &m_z2); + m_tree->Branch("module0", &m_module0); + m_tree->Branch("module1", &m_module1); + m_tree->Branch("module2", &m_module2); + m_tree->Branch("x0_local", &m_x0_local); + m_tree->Branch("x1_local", &m_x1_local); + m_tree->Branch("x2_local", &m_x2_local); + m_tree->Branch("y0_local", &m_y0_local); + m_tree->Branch("y1_local", &m_y1_local); + m_tree->Branch("y2_local", &m_y2_local); + // m_tree->Branch("z0_local", &m_z0_local); + // m_tree->Branch("z1_local", &m_z1_local); + // m_tree->Branch("z2_local", &m_z2_local); + if(m_saveallsp){ + m_tree->Branch("sp_all_x", &m_sp_all_x); + m_tree->Branch("sp_all_y", &m_sp_all_y); + m_tree->Branch("sp_all_z", &m_sp_all_z); + m_tree->Branch("sp_all_station", &m_sp_all_station); + m_tree->Branch("sp_all_layer", &m_sp_all_layer); + m_tree->Branch("sp_all_module", &m_sp_all_module); + } + } + //------------------------------------------------------------------------- + void TrackerSPFit::clearVariables() const { + m_initial_track_chi2.clear(); + m_initial_track_cx.clear(); + m_initial_track_mx.clear(); + m_initial_track_cy.clear(); + m_initial_track_my.clear(); + m_initial_track_residual_x0.clear(); + m_initial_track_residual_x1.clear(); + m_initial_track_residual_x2.clear(); + m_initial_track_residual_y0.clear(); + m_initial_track_residual_y1.clear(); + m_initial_track_residual_y2.clear(); + m_x0.clear(); + m_x1.clear(); + m_x2.clear(); + m_y0.clear(); + m_y1.clear(); + m_y2.clear(); + m_sigma_x0.clear(); + m_sigma_x1.clear(); + m_sigma_x2.clear(); + m_sigma_y0.clear(); + m_sigma_y1.clear(); + m_sigma_y2.clear(); + m_z0.clear(); + m_z1.clear(); + m_z2.clear(); + m_module0.clear(); + m_module1.clear(); + m_module2.clear(); + m_x0_local.clear(); + m_x1_local.clear(); + m_x2_local.clear(); + m_y0_local.clear(); + m_y1_local.clear(); + m_y2_local.clear(); + // m_z0_local.clear(); + // m_z1_local.clear(); + // m_z2_local.clear(); + + if(m_saveallsp){ + m_sp_all_x.clear(); + m_sp_all_y.clear(); + m_sp_all_z.clear(); + m_sp_all_station.clear(); + m_sp_all_layer.clear(); + m_sp_all_module.clear(); + } + + + } + //------------------------------------------------------------------------- + + StatusCode TrackerSPFit::execute (const EventContext& ctx) const + { + + ++m_numberOfEvents; + m_eventNumber=m_numberOfEvents; + clearVariables(); + 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; + } + + // retrieve SCT spacepoint container + SG::ReadHandle<FaserSCT_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; + } + + // save all the sp information + if(m_saveallsp){ + ATH_MSG_DEBUG( "SCT spacepoint container found: " << sct_spcontainer->size() << " collections" ); + + for (const auto& colNext : *sct_spcontainer) { + ++m_numberOfSPCol; + Identifier elementID = colNext->identify(); + for (const auto& sp : *colNext) { + ++m_numberOfSP; + m_sp_all_x.push_back(sp->globalPosition().x()); + m_sp_all_y.push_back(sp->globalPosition().y()); + m_sp_all_z.push_back(sp->globalPosition().z()); + m_sp_all_station.push_back(m_idHelper->station(elementID)); + m_sp_all_layer.push_back(m_idHelper->layer(elementID)); + auto ietamodule = m_idHelper->eta_module(elementID); + auto iphimodule = m_idHelper->phi_module(elementID); + if(ietamodule < 0) { + iphimodule += 4; + } + m_sp_all_module.push_back(iphimodule); + } + } + } + + // register the IdentifiableContainer into StoreGate + + ATH_MSG_DEBUG( "SCT spacepoint container found: " << sct_spcontainer->size() << " collections" ); + + // Collect all space points in a flat vector + + std::vector<SP_Seed> space_points_layer0; + std::vector<SP_Seed> space_points_layer1; + std::vector<SP_Seed> space_points_layer2; + for (const auto& colNext : *sct_spcontainer) { + Identifier elementID = colNext->identify(); + ATH_MSG_DEBUG("reading SpacePoints collection "<<elementID.get_compact()<<" , and hash = "<<colNext->identifyHash() ); + + auto istation = m_idHelper->station(elementID); + auto ilayer = m_idHelper->layer(elementID); + auto ietamodule = m_idHelper->eta_module(elementID); + auto iphimodule = m_idHelper->phi_module(elementID); + auto imodule = iphimodule; + if(ietamodule < 0) { + imodule += 4; + } + auto size = colNext->size(); + if (size == 0) { + ATH_MSG_DEBUG( "TrackerSPFit 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 + for (const auto& sp : *colNext) { + // sp->globalPosition(); + // sp->globCovariance(), + struct SP_Seed tmp{ + *sp, + ilayer, + imodule + }; + if(istation == 0) { // We want to align station by station, so make this an argument and call it repeatedly. + if(ilayer==0) space_points_layer0.push_back(tmp); + if(ilayer==1) space_points_layer1.push_back(tmp); + if(ilayer==2) space_points_layer2.push_back(tmp); + } + } + ATH_MSG_DEBUG( size << " SpacePoints successfully added to Container !" ); + } + } + ATH_MSG_DEBUG( "TrackerSPFit number of spacepoints in each layer: " << space_points_layer0.size() << " " << space_points_layer1.size() << " " << space_points_layer2.size() ); + + + // First check to filter out freak events in the cosmic / test beam data + if ((space_points_layer0.size() > 8) or (space_points_layer1.size() > 8) or (space_points_layer0.size() > 8)) { + return StatusCode::SUCCESS; + } + + // Arange all possible combinations of hit triplets + std::vector<HitTriplet> hit_triplets; + for (const auto& sp0 : space_points_layer0) { + for (const auto& sp1 : space_points_layer1) { + for (const auto& sp2 : space_points_layer2) { + hit_triplets.emplace_back(HitTriplet({sp0.sp, sp1.sp, sp2.sp, sp0.module, sp1.module, sp2.module})); + } + } + } + ATH_MSG_DEBUG( "TrackerSPFit number of hit triplets: " << hit_triplets.size() ); + + // Second check to filter out freak events in the cosmic / test beam data. + if (hit_triplets.size() > 8) { + return StatusCode::SUCCESS; + } + + for (const auto& hit_triplet : hit_triplets) { + const AlignVector3D x{ + hit_triplet.sp0.globalPosition()[0], + hit_triplet.sp1.globalPosition()[0], + hit_triplet.sp2.globalPosition()[0] + }; + const AlignVector3D y{ + hit_triplet.sp0.globalPosition()[1], + hit_triplet.sp1.globalPosition()[1], + hit_triplet.sp2.globalPosition()[1] + }; + const AlignVector3D z{ + hit_triplet.sp0.globalPosition()[2], + hit_triplet.sp1.globalPosition()[2], + hit_triplet.sp2.globalPosition()[2] + }; + const auto sigma_x0 = hit_triplet.sp0.globCovariance()(0, 0); + const auto sigma_x1 = hit_triplet.sp1.globCovariance()(0, 0); + const auto sigma_x2 = hit_triplet.sp2.globCovariance()(0, 0); + const auto sigma_y0 = hit_triplet.sp0.globCovariance()(1, 1); + const auto sigma_y1 = hit_triplet.sp1.globCovariance()(1, 1); + const auto sigma_y2 = hit_triplet.sp2.globCovariance()(1, 1); + + const auto W_ = W( + 1./sigma_x0, + 1./sigma_x1, + 1./sigma_x2, + 1./sigma_y0, + 1./sigma_y1, + 1./sigma_y2 + ); + + const auto track_fit_result = SolveLocalTrackFitWeighted(A(z), b(x,y), W_); + const AlignVector3D x_local{ + hit_triplet.sp0.localParameters().x(), + hit_triplet.sp1.localParameters().x(), + hit_triplet.sp2.localParameters().x() + }; + const AlignVector3D y_local{ + hit_triplet.sp0.localParameters().y(), + hit_triplet.sp1.localParameters().y(), + hit_triplet.sp2.localParameters().y() + }; + + AlignVector6D xy; + xy << x[0], x[1], x[2], y[0], y[1], y[2]; + // std::cout << "xy: " << xy.transpose() << std::endl; + // std::cout << "z: " << z.transpose() << std::endl; + + const auto prediction_layer0 = TrackPrediction(z[0], track_fit_result); + const auto prediction_layer1 = TrackPrediction(z[1], track_fit_result); + const auto prediction_layer2 = TrackPrediction(z[2], track_fit_result); + AlignVector6D xy_predicted; + xy_predicted << prediction_layer0[0], prediction_layer1[0], prediction_layer2[0], prediction_layer0[1], prediction_layer1[1], prediction_layer2[1]; + // std::cout << "pr: " << xy_predicted.transpose() << std::endl; + + const auto residual = xy_predicted - xy; + // std::cout << "r: " << residual.transpose() << std::endl; + + const double chi2 = residual.transpose() * W_ * residual; + const auto& module0 = hit_triplet.module0; + const auto& module1 = hit_triplet.module1; + const auto& module2 = hit_triplet.module2; + + + m_initial_track_chi2.push_back(chi2); + m_initial_track_cx.push_back(track_fit_result[0]); + m_initial_track_mx.push_back(track_fit_result[1]); + m_initial_track_cy.push_back(track_fit_result[2]); + m_initial_track_my.push_back(track_fit_result[3]); + m_initial_track_residual_x0.push_back(residual[0]); + m_initial_track_residual_x1.push_back(residual[1]); + m_initial_track_residual_x2.push_back(residual[2]); + m_initial_track_residual_y0.push_back(residual[3]); + m_initial_track_residual_y1.push_back(residual[4]); + m_initial_track_residual_y2.push_back(residual[5]); + m_x0.push_back(x[0]); + m_x1.push_back(x[1]); + m_x2.push_back(x[2]); + m_y0.push_back(y[0]); + m_y1.push_back(y[1]); + m_y2.push_back(y[2]); + m_z0.push_back(z[0]); + m_z1.push_back(z[1]); + m_z2.push_back(z[2]); + m_sigma_x0.push_back(sigma_x0); + m_sigma_x1.push_back(sigma_x1); + m_sigma_x2.push_back(sigma_x2); + m_sigma_y0.push_back(sigma_y0); + m_sigma_y1.push_back(sigma_y1); + m_sigma_y2.push_back(sigma_y2); + m_module0.push_back(module0); + m_module1.push_back(module1); + m_module2.push_back(module2); + m_x0_local.push_back(x_local[0]); + m_x1_local.push_back(x_local[1]); + m_x2_local.push_back(x_local[2]); + m_y0_local.push_back(y_local[0]); + m_y1_local.push_back(y_local[1]); + m_y2_local.push_back(y_local[2]); + // m_z0_local.push_back(z[0]); + // m_z1_local.push_back(z[1]); + // m_z2_local.push_back(z[2]); + const double chi2max = 10; + if (chi2 < chi2max) { + m_numberOfAlignmentTracks += 1; + ATH_MSG_INFO( "TrackerSPFit first track fit result: chi2: " << chi2 << " pars: " << track_fit_result[0] << " " << track_fit_result[1] << " " << track_fit_result[2] << " " << track_fit_result[3]); + const double mx = track_fit_result[1]; + const double my = track_fit_result[3]; + const auto dr_da = AlignmentDerivatives(x, y, mx, my); + const auto t = dr_da.transpose() * What(W_, A(z)) * residual; + const auto M = dr_da.transpose() * What(W_, A(z)) * dr_da; + + // Save the local alignment matrices (module wise) + if ((module0 == module1) and (module0 == module2)) { + m_ts[module0] += t; + m_Ms[module0] += M; + } + // std::cout << dr_da << std::endl; + + // In the following assign the blocks to the global matrix + const auto index0 = GetIndexInSolutionMatrix(0, module0); + const auto index1 = GetIndexInSolutionMatrix(1, module1); + const auto index2 = GetIndexInSolutionMatrix(2, module2); + + // Add t terms in correct position of global alignment matrix + m_t.block<6, 1>(index0, 0) += t.block<6, 1>( 0, 0); + m_t.block<6, 1>(index1, 0) += t.block<6, 1>( 6, 0); + m_t.block<6, 1>(index2, 0) += t.block<6, 1>(12, 0); + + // Add t terms in correct position of global alignment matrix + m_M.block<6, 6>(index0, index0) += M.block<6, 6>( 0, 0); + m_M.block<6, 6>(index0, index1) += M.block<6, 6>( 0, 6); + m_M.block<6, 6>(index0, index2) += M.block<6, 6>( 0, 12); + + m_M.block<6, 6>(index1, index0) += M.block<6, 6>( 6, 0); + m_M.block<6, 6>(index1, index1) += M.block<6, 6>( 6, 6); + m_M.block<6, 6>(index1, index2) += M.block<6, 6>( 6, 12); + + m_M.block<6, 6>(index2, index0) += M.block<6, 6>(12, 0); + m_M.block<6, 6>(index2, index1) += M.block<6, 6>(12, 6); + m_M.block<6, 6>(index2, index2) += M.block<6, 6>(12, 12); + + } + } + + if (hit_triplets.size() > 0) m_tree->Fill(); + return StatusCode::SUCCESS; + } + + //--------------------------------------------------------------------------- + StatusCode TrackerSPFit::finalize() + { + ATH_MSG_INFO( "TrackerSPFit::finalize()" ); + ATH_MSG_INFO( m_numberOfEvents << " events processed" ); + ATH_MSG_INFO( m_numberOfSPCol<< " sct SP collections processed" ); + ATH_MSG_INFO( m_numberOfSP<< " sct SP processed" ); + ATH_MSG_INFO( m_numberOfAlignmentTracks << " tracks are used for alignment." ); + + const static Eigen::IOFormat CSVFormat(Eigen::StreamPrecision, Eigen::DontAlignCols, ", ", "\n"); + std::ofstream file_M("./" + m_outputdir + "/M.csv"); + file_M << m_M.format(CSVFormat); + file_M << std::endl; + std::ofstream file_t("./" + m_outputdir + "/t.csv"); + file_t << m_t.format(CSVFormat); + file_t << std::endl; + + for (unsigned int i=0; i<8; ++i) { + std::ofstream file_M("./" + m_outputdir + "/M" + std::to_string(i) + ".csv"); + file_M << m_Ms[i].format(CSVFormat); + file_M << std::endl; + std::ofstream file_t("./" + m_outputdir + "/t" + std::to_string(i) + ".csv"); + file_t << m_ts[i].format(CSVFormat); + file_t << std::endl; + } + + return StatusCode::SUCCESS; + } + + //-------------------------------------------------------------------------- + + TrackerSPFit::AlignVector3D TrackerSPFit::TrackPrediction(double z, const TrackerSPFit::AlignVector4D& parameters) const { + AlignVector3D prediction; + prediction << parameters[0] + parameters[1] * z, parameters[2] + parameters[3] * z, z; + return prediction; + } + + TrackerSPFit::AlignMatrix6x4 TrackerSPFit::A(const TrackerSPFit::AlignVector3D& z) const { + TrackerSPFit::AlignMatrix6x4 A; + A << 1, z[0], 0, 0, + 1, z[1], 0, 0, + 1, z[2], 0, 0, + 0, 0, 1, z[0], + 0, 0, 1, z[1], + 0, 0, 1, z[2]; + return A; + } + + TrackerSPFit::AlignVector6D TrackerSPFit::b(const TrackerSPFit::AlignVector3D& x, const TrackerSPFit::AlignVector3D& y) const { + TrackerSPFit::AlignVector6D b; + b << x[0], x[1], x[2], y[0], y[1], y[2]; + return b; + } + + TrackerSPFit::AlignVector4D TrackerSPFit::SolveLocalTrackFitWeighted(const TrackerSPFit::AlignMatrix6x4& A, const TrackerSPFit::AlignVector6D& b, const TrackerSPFit::AlignDiagonalMatrix6x6& W) const { + return (A.transpose() * W * A).ldlt().solve(A.transpose() * W * b); + } + + TrackerSPFit::AlignMatrix4x4 TrackerSPFit::TrackParameterCovariance(const TrackerSPFit::AlignMatrix6x4& A, const TrackerSPFit::AlignDiagonalMatrix6x6& W) const { + return (A.transpose() * A).inverse() * A.transpose() * W.inverse() * A * (A.transpose() * A).inverse(); + } + + TrackerSPFit::AlignDiagonalMatrix6x6 TrackerSPFit::W(const double w_x0, const double w_x1, const double w_x2, const double w_y0, const double w_y1, const double w_y2) const { + TrackerSPFit::AlignDiagonalMatrix6x6 W; + W.diagonal() << w_x0, w_x1, w_x2, w_y0, w_y1, w_y2; + return W; + } + + TrackerSPFit::AlignMatrix6x6 TrackerSPFit::What(const TrackerSPFit::AlignDiagonalMatrix6x6& W, const TrackerSPFit::AlignMatrix6x4& A) const { + auto I = TrackerSPFit::AlignMatrix6x6::Identity(); + return (I - A * (A.transpose() * W * A).inverse() * A.transpose() * W).transpose() * W; + } + + TrackerSPFit::AlignMatrix6x18 TrackerSPFit::AlignmentDerivatives(const TrackerSPFit::AlignVector3D& x, const TrackerSPFit::AlignVector3D& y, double mx, double my) const { + TrackerSPFit::AlignVector6D dx_da; + dx_da << -1, 0, mx, 0, 0, 0; + TrackerSPFit::AlignVector6D dy_da; + dy_da << 0, -1, my, 0, 0, 0; + + TrackerSPFit::AlignMatrix6x18 dr_da; // FIXME: Last three entries are currently 0, these are reserved for rotations_xy, that is when we need x, y + dr_da.setZero(); + dr_da.block<1, 6>( 0, 0) += dx_da.transpose(); // Layer 0 + dr_da.block<1, 6>( 1, 6) += dx_da.transpose(); // Layer 1 + dr_da.block<1, 6>( 2, 12) += dx_da.transpose(); // Layer 2 + dr_da.block<1, 6>( 3, 0) += dy_da.transpose(); // Layer 0 + dr_da.block<1, 6>( 4, 6) += dy_da.transpose(); // Layer 1 + dr_da.block<1, 6>( 5, 12) += dy_da.transpose(); // Layer 2 + return dr_da; + } + + unsigned int TrackerSPFit::GetIndexInSolutionMatrix(const unsigned int layer, const unsigned int module) const { + const unsigned int parameters_per_layer = 6; + const unsigned int layers_per_module = 3; + return layer * parameters_per_layer + module * parameters_per_layer * layers_per_module; + } + +} diff --git a/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/GlobalChi2EquationGenerator.h b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/GlobalChi2EquationGenerator.h new file mode 100755 index 000000000..95bd2f5fc --- /dev/null +++ b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/GlobalChi2EquationGenerator.h @@ -0,0 +1,171 @@ +// -*- C++ -*- + +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + */ + +#ifndef TRACKERSPFIT_TRACKERSPACEPOINTMAKERALG_H +#define TRACKERSPFIT_TRACKERSPACEPOINTMAKERALG_H + +#include "StoreGate/ReadCondHandleKey.h" +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "Identifier/Identifier.h" + +#include "TrackerPrepRawData/FaserSCT_ClusterCollection.h" +#include "TrackerPrepRawData/FaserSCT_ClusterContainer.h" +#include "TrackerPrepRawData/TrackerClusterContainer.h" +#include "TrackerReadoutGeometry/SiDetectorElementCollection.h" +#include "TrackerSpacePoint/FaserSCT_SpacePoint.h" +#include "TrackerSpacePoint/FaserSCT_SpacePointContainer.h" +#include "TrackerSpacePoint/FaserSCT_SpacePointOverlapCollection.h" +#include "TrkEventPrimitives/LocalParameters.h" + +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/ITHistSvc.h" + +#include <string> +#include <vector> +#include "TTree.h" + +#include <Eigen/Sparse> + +#include <string> + +class FaserSCT_ID; +namespace Tracker +{ + + class TrackerSPFit:public AthReentrantAlgorithm { + + // Define typedefs which shortcut eigen matrices and vectors for the dimensions we need in our use case. + typedef Eigen::Matrix<double, 4, 4> AlignMatrix4x4; + typedef Eigen::Matrix<double, 6, 4> AlignMatrix6x4; + typedef Eigen::Matrix<double, 6, 6> AlignMatrix6x6; + typedef Eigen::Matrix<double, 6, 18> AlignMatrix6x18; + typedef Eigen::Matrix<double, 18, 18> AlignMatrix18x18; + typedef Eigen::Matrix<double, 144, 144> AlignMatrix144x144; + typedef Eigen::DiagonalMatrix<double, 6> AlignDiagonalMatrix6x6; + typedef Eigen::Matrix<double, 3, 1> AlignVector3D; + typedef Eigen::Matrix<double, 4, 1> AlignVector4D; + typedef Eigen::Matrix<double, 6, 1> AlignVector6D; + typedef Eigen::Matrix<double, 18, 1> AlignVector18D; + typedef Eigen::Matrix<double, 144, 1> AlignVector144D; + + public: + + /** + * @name AthReentrantAlgorithm methods + */ + //@{ + TrackerSPFit(const std::string& name, + ISvcLocator* pSvcLocator); + + virtual ~TrackerSPFit() = default; + + virtual StatusCode initialize() override; + + virtual StatusCode execute (const EventContext& ctx) const override; + + virtual StatusCode finalize() override; + + struct SP_Seed{FaserSCT_SpacePoint sp; int layer; int module;}; + struct HitTriplet{ + FaserSCT_SpacePoint sp0; + FaserSCT_SpacePoint sp1; + FaserSCT_SpacePoint sp2; + int module0; + int module1; + int module2; + }; + + private: + AlignVector3D TrackPrediction(double z, const AlignVector4D& parameters) const; + AlignMatrix6x4 A(const AlignVector3D& z) const; + AlignVector6D b(const AlignVector3D& x, const AlignVector3D& y) const; + AlignDiagonalMatrix6x6 W(const double w_x0, const double w_x1, const double w_x2, const double w_y0, const double w_y1, const double w_y2) const; + AlignMatrix6x6 What(const AlignDiagonalMatrix6x6& W, const AlignMatrix6x4& A) const; + AlignVector4D SolveLocalTrackFitWeighted(const AlignMatrix6x4& A, const AlignVector6D& b, const AlignDiagonalMatrix6x6& W) const; + AlignMatrix4x4 TrackParameterCovariance(const AlignMatrix6x4& A, const AlignDiagonalMatrix6x6& W) const; + AlignMatrix6x18 AlignmentDerivatives(const AlignVector3D& x, const AlignVector3D& y, double mx, double my) const; + unsigned int GetIndexInSolutionMatrix(const unsigned int layer, const unsigned int module) const; + + void initializeTree(); + void clearVariables() const; + mutable TTree* m_tree; + TrackerSPFit() = delete; + TrackerSPFit(const TrackerSPFit&) =delete; + TrackerSPFit &operator=(const TrackerSPFit&) = delete; + + SG::ReadHandleKey<FaserSCT_SpacePointContainer> m_Sct_spcontainerKey{this, "SpacePointsSCTName", "SCT_SpacePointContainer"}; + SG::ReadHandleKey<Tracker::FaserSCT_ClusterContainer> m_Sct_clcontainerKey{this, "SCT_ClustersName", "SCT clContainer"}; + SG::ReadCondHandleKey<TrackerDD::SiDetectorElementCollection> m_SCTDetEleCollKey{this, "SCTDetEleCollKey", "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"}; + + const FaserSCT_ID* m_idHelper{nullptr}; + mutable std::atomic<int> m_numberOfEvents{0}; + mutable std::atomic<int> m_numberOfSCT{0}; + mutable std::atomic<int> m_numberOfTrack{0}; + mutable std::atomic<int> m_numberOfSP{0}; + mutable std::atomic<int> m_numberOfSPCol{0}; + mutable std::atomic<int> m_numberOfAlignmentTracks{0}; + //@} + ServiceHandle<ITHistSvc> m_thistSvc; + + mutable int m_eventNumber; + mutable std::vector<double> m_initial_track_chi2; + mutable std::vector<double> m_initial_track_cx; + mutable std::vector<double> m_initial_track_mx; + mutable std::vector<double> m_initial_track_cy; + mutable std::vector<double> m_initial_track_my; + mutable std::vector<double> m_initial_track_residual_x0; + mutable std::vector<double> m_initial_track_residual_x1; + mutable std::vector<double> m_initial_track_residual_x2; + mutable std::vector<double> m_initial_track_residual_y0; + mutable std::vector<double> m_initial_track_residual_y1; + mutable std::vector<double> m_initial_track_residual_y2; + mutable std::vector<double> m_x0; + mutable std::vector<double> m_x1; + mutable std::vector<double> m_x2; + mutable std::vector<double> m_y0; + mutable std::vector<double> m_y1; + mutable std::vector<double> m_y2; + mutable std::vector<double> m_sigma_x0; + mutable std::vector<double> m_sigma_x1; + mutable std::vector<double> m_sigma_x2; + mutable std::vector<double> m_sigma_y0; + mutable std::vector<double> m_sigma_y1; + mutable std::vector<double> m_sigma_y2; + mutable std::vector<double> m_z0; + mutable std::vector<double> m_z1; + mutable std::vector<double> m_z2; + mutable std::vector<double> m_module0; + mutable std::vector<double> m_module1; + mutable std::vector<double> m_module2; + mutable std::vector<double> m_x0_local; + mutable std::vector<double> m_x1_local; + mutable std::vector<double> m_x2_local; + mutable std::vector<double> m_y0_local; + mutable std::vector<double> m_y1_local; + mutable std::vector<double> m_y2_local; + // mutable std::vector<double> m_z0_local; + // mutable std::vector<double> m_z1_local; + // mutable std::vector<double> m_z2_local; + bool m_saveallsp; + bool m_chi2max; + std::string m_outputdir; + mutable std::vector<double> m_sp_all_x; + mutable std::vector<double> m_sp_all_y; + mutable std::vector<double> m_sp_all_z; + mutable std::vector<int> m_sp_all_station; + mutable std::vector<int> m_sp_all_layer; + mutable std::vector<int> m_sp_all_module; + + mutable Eigen::MatrixXd m_t; + mutable Eigen::MatrixXd m_M; + + mutable std::vector<AlignVector18D> m_ts; + mutable std::vector<AlignMatrix18x18> m_Ms; + + }; + +} +#endif // TrackerSpacePointMakerAlg_TRACKERSPACEPOINTMAKERALG_H diff --git a/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/components/GlobalChi2EquationGenerator_entries.cxx b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/components/GlobalChi2EquationGenerator_entries.cxx new file mode 100644 index 000000000..dae3ad64e --- /dev/null +++ b/Tracker/TrackerAlignAlgs/GlobalChi2EquationGenerator/src/components/GlobalChi2EquationGenerator_entries.cxx @@ -0,0 +1,4 @@ +#include "../TrackerSPFit.h" + +DECLARE_COMPONENT( Tracker::TrackerSPFit ) + -- GitLab