ATLAS Offline Software
Loading...
Searching...
No Matches
InDet::NnClusterizationFactory Class Reference

#include <NnClusterizationFactory.h>

Inheritance diagram for InDet::NnClusterizationFactory:

Public Member Functions

 NnClusterizationFactory (const std::string &name, const std::string &n, const IInterface *p)
 ~NnClusterizationFactory ()=default
virtual StatusCode initialize () override
virtual StatusCode finalize () override
std::vector< double > estimateNumberOfParticles (const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition) const
std::vector< double > estimateNumberOfParticles (const InDet::PixelCluster &pCluster, const Trk::Surface &pixelSurface, const Trk::TrackParameters &trackParsAtSurface) const
std::vector< Amg::Vector2DestimatePositions (const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition, std::vector< Amg::MatrixX > &errors, int numberSubClusters) const
std::vector< Amg::Vector2DestimatePositions (const InDet::PixelCluster &pCluster, const Trk::Surface &pixelSurface, const Trk::TrackParameters &trackParsAtSurface, std::vector< Amg::MatrixX > &errors, int numberSubClusters) const
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Static Public Member Functions

static const InterfaceID & interfaceID ()
 AlgTool interface methods.

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

enum  ENetworkType {
  kNumberParticlesNN , kPositionNN , kErrorXNN , kErrorYNN ,
  kNNetworkTypes
}
typedef std::vector< Eigen::VectorXd > InputVector
using ReturnType = std::vector<Double_t>
using InputType = std::vector<Double_t>
typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

std::vector< double > estimateNumberOfParticlesTTN (const TTrainedNetworkCollection &nn_collection, const std::vector< double > &inputData) const
std::vector< double > estimateNumberOfParticlesLWTNN (NnClusterizationFactory::InputVector &input) const
std::vector< Amg::Vector2DestimatePositionsTTN (const TTrainedNetworkCollection &nn_collection, const std::vector< double > &inputData, const NNinput &input, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const
std::vector< Amg::Vector2DestimatePositionsLWTNN (NnClusterizationFactory::InputVector &input, NNinput &rawInput, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const
std::vector< double > estimateNumberOfParticlesONNX (const Eigen::VectorXd &input) const
std::vector< Amg::Vector2DestimatePositionsONNX (const Eigen::VectorXd &input, NNinput &rawInput, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const
double correctedRMS (double posPixels, const std::vector< float > &pitches, unsigned int size) const
NNinput createInput (const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition, double &tanl) const
void addTrackInfoToInput (NNinput &input, const Trk::Surface &pixelSurface, const Trk::TrackParameters &trackParsAtSurface, const double tanl) const
std::vector< double > assembleInputRunI (NNinput &input) const
std::vector< double > assembleInputRunII (NNinput &input) const
InputVector eigenInput (NNinput &input) const
std::vector< Amg::Vector2DgetPositionsFromOutput (std::vector< double > &output, const NNinput &input, const InDet::PixelCluster &pCluster) const
void getErrorMatrixFromOutput (std::vector< double > &outputX, std::vector< double > &outputY, std::vector< Amg::MatrixX > &errorMatrix, int nParticles) const
size_t calculateVectorDimension (const bool useTrackInfo) const
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Private Attributes

Gaudi::Property< std::vector< std::string > > m_nnOrder
unsigned int m_nParticleNNId {}
std::vector< std::vector< unsigned int > > m_NNId {}
std::vector< double >(InDet::NnClusterizationFactory::* m_assembleInput )(NNinput &input) const
ReturnType(::TTrainedNetwork::* m_calculateOutput )(const InputType &input) const
ToolHandle< ISiLorentzAngleToolm_pixelLorentzAngleTool {this, "PixelLorentzAngleTool", "SiLorentzAngleTool/PixelLorentzAngleTool", "Tool to retreive Lorentz angle of Pixel"}
SG::ReadCondHandleKey< PixelChargeCalibCondDatam_chargeDataKey {this, "PixelChargeCalibCondData", "PixelChargeCalibCondData", "Output key"}
SG::ReadCondHandleKey< TTrainedNetworkCollectionm_readKeyWithoutTrack {this, "NnCollectionReadKey", "PixelClusterNN", "The conditions store key for the pixel cluster NNs"}
SG::ReadCondHandleKey< TTrainedNetworkCollectionm_readKeyWithTrack
SG::ReadCondHandleKey< LWTNNCollectionm_readKeyJSON
Gaudi::Property< std::size_t > m_outputNodesPos1
Gaudi::Property< std::vector< std::size_t > > m_outputNodesPos2
Gaudi::Property< std::vector< std::size_t > > m_outputNodesPos3
Gaudi::Property< unsigned int > m_maxSubClusters {this, "MaxSubClusters", 3, "Maximum number of sub cluster supported by the networks." }
Gaudi::Property< double > m_correctLorShiftBarrelWithoutTracks {this, "correctLorShiftBarrelWithoutTracks",0.,"Lorentz shift correction factor when evaluating NN without track input."}
Gaudi::Property< double > m_correctLorShiftBarrelWithTracks {this, "correctLorShiftBarrelWithTracks",0.,"Lorentz shift correction factor when evaluating NN with track input."}
Gaudi::Property< bool > m_useToT {this, "useToT",true,"Use Tot rather than charge." }
Gaudi::Property< bool > m_addIBL {this, "addIBL", false, "Also apply to clusters in IBL." }
Gaudi::Property< bool > m_doRunI {this, "doRunI", false, "Use runI style network (outputs are not normalised; add pitches; use charge if not m_useToT)"}
SG::ReadCondHandleKey< OnnxNNCollectionm_readKeyONNX
Gaudi::Property< bool > m_useONNX {this, "useONNX", false, "Use ONNX models instead of LWTNN for NN inference."}
Gaudi::Property< bool > m_useTTrainedNetworks {this, "useTTrainedNetworks", false, "Use earlier (release-21-like) neural networks stored in ROOT files and accessed via TTrainedNetowrk."}
Gaudi::Property< bool > m_useRecenteringNNWithouTracks {this, "useRecenteringNNWithoutTracks",false,"Recenter x position when evaluating NN without track input."}
Gaudi::Property< bool > m_useRecenteringNNWithTracks {this, "useRecenteringNNWithTracks",false,"Recenter x position when evaluating NN with track input."}
Gaudi::Property< bool > m_useXPitches
Gaudi::Property< unsigned int > m_sizeX {this, "sizeX",7,"Size of pixel matrix along X"}
Gaudi::Property< unsigned int > m_sizeY {this, "sizeY",7,"Size of pixel matrix along Y"}
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default).
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default).
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Static Private Attributes

static constexpr std::array< std::string_view, kNNetworkTypess_nnTypeNames
static constexpr std::array< unsigned int, kNNetworkTypesm_nParticleGroup {0U,1U,1U,1U}
static const std::array< std::regex, kNNetworkTypesm_nnNames

Detailed Description

Definition at line 90 of file NnClusterizationFactory.h.

Member Typedef Documentation

◆ InputType

using InDet::NnClusterizationFactory::InputType = std::vector<Double_t>
private

Definition at line 243 of file NnClusterizationFactory.h.

◆ InputVector

typedef std::vector<Eigen::VectorXd> InDet::NnClusterizationFactory::InputVector
private

Definition at line 127 of file NnClusterizationFactory.h.

◆ ReturnType

using InDet::NnClusterizationFactory::ReturnType = std::vector<Double_t>
private

Definition at line 242 of file NnClusterizationFactory.h.

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Member Enumeration Documentation

◆ ENetworkType

Constructor & Destructor Documentation

◆ NnClusterizationFactory()

InDet::NnClusterizationFactory::NnClusterizationFactory ( const std::string & name,
const std::string & n,
const IInterface * p )

Definition at line 68 of file NnClusterizationFactory.cxx.

70 : AthAlgTool(name, n, p){
71 declareInterface<NnClusterizationFactory>(this);
72 }
AthAlgTool()
Default constructor:

◆ ~NnClusterizationFactory()

InDet::NnClusterizationFactory::~NnClusterizationFactory ( )
default

Member Function Documentation

◆ addTrackInfoToInput()

void InDet::NnClusterizationFactory::addTrackInfoToInput ( NNinput & input,
const Trk::Surface & pixelSurface,
const Trk::TrackParameters & trackParsAtSurface,
const double tanl ) const
private

Definition at line 775 of file NnClusterizationFactory.cxx.

778 {
779 input.useTrackInfo=true;
780 Amg::Vector3D particleDir = trackParsAtSurface.momentum().unit();
781 Amg::Vector3D localIntersection = pixelSurface.transform().inverse().linear() * particleDir;
782 localIntersection *= 0.250/cos(localIntersection.theta());
783 float trackDeltaX = (float)localIntersection.x();
784 float trackDeltaY = (float)localIntersection.y();
785 input.theta=std::atan2(trackDeltaY,0.250);
786 input.phi=std::atan2(trackDeltaX,0.250);
787 ATH_MSG_VERBOSE("Angle phi bef Lorentz corr: " << input.phi );
788 input.phi=std::atan(std::tan(input.phi)-tanl);
789 ATH_MSG_VERBOSE(" From track: angle phi: " << input.phi << " theta: " << input.theta );
790 }
#define ATH_MSG_VERBOSE(x)
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
Eigen::Matrix< double, 3, 1 > Vector3D

◆ assembleInputRunI()

std::vector< double > InDet::NnClusterizationFactory::assembleInputRunI ( NNinput & input) const
private

Definition at line 192 of file NnClusterizationFactory.cxx.

192 {
193 const auto vectorSize{calculateVectorDimension(input.useTrackInfo)};
194 const auto invalidValue{std::numeric_limits<double>::quiet_NaN()};
195 std::vector<double> inputData(vectorSize, invalidValue);
196 size_t vectorIndex{0};
197 for (unsigned int u=0;u<m_sizeX;u++){
198 for (unsigned int s=0;s<m_sizeY;s++){
199 if (m_useToT){
200 inputData[vectorIndex++] = norm_rawToT(input.matrixOfToT[u][s]);
201 } else {
202 inputData[vectorIndex++] = norm_ToT(input.matrixOfToT[u][s]);
203 }
204 }
205 }
206 for (unsigned int s=0;s<m_sizeY;s++){
207 const double rawPitch(input.vectorOfPitchesY[s]);
208 const double normPitch(norm_pitch(rawPitch,m_addIBL));
209 if (std::isnan(normPitch)){
210 ATH_MSG_ERROR("NaN returned from norm_pitch, rawPitch = "<<rawPitch<<" addIBL = "<<m_addIBL);
211 }
212 inputData[vectorIndex++] = normPitch;
213 }
214 inputData[vectorIndex++] = norm_layerNumber(input.ClusterPixLayer);
215 inputData[vectorIndex++] = norm_layerType(input.ClusterPixBarrelEC);
216 if (input.useTrackInfo){
217 inputData[vectorIndex++] = norm_phi(input.phi);
218 inputData[vectorIndex] = norm_theta(input.theta);
219 } else {
220 inputData[vectorIndex++] = norm_phiBS(input.phi);
221 inputData[vectorIndex++] = norm_thetaBS(input.theta);
222 inputData[vectorIndex] = norm_etaModule(input.etaModule);
223 }
224 return inputData;
225 }
#define ATH_MSG_ERROR(x)
double norm_rawToT(const double input)
double norm_pitch(const double input, bool addIBL=false)
double norm_layerNumber(const double input)
double norm_thetaBS(const double input)
double norm_layerType(const double input)
double norm_ToT(const double input)
double norm_phi(const double input)
double norm_phiBS(const double input)
double norm_theta(const double input)
double norm_etaModule(const double input)
Gaudi::Property< unsigned int > m_sizeX
size_t calculateVectorDimension(const bool useTrackInfo) const
Gaudi::Property< unsigned int > m_sizeY
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77

◆ assembleInputRunII()

std::vector< double > InDet::NnClusterizationFactory::assembleInputRunII ( NNinput & input) const
private

Definition at line 170 of file NnClusterizationFactory.cxx.

170 {
171 const auto vectorSize{calculateVectorDimension(input.useTrackInfo)};
172 const auto invalidValue{std::numeric_limits<double>::quiet_NaN()};
173 std::vector<double> inputData(vectorSize, invalidValue);
174 size_t vectorIndex{0};
175 for (unsigned int u=0;u<m_sizeX;u++){
176 for (unsigned int s=0;s<m_sizeY;s++){
177 inputData[vectorIndex++] = input.matrixOfToT[u][s];
178 }
179 }
180 for (unsigned int s=0;s<m_sizeY;s++){
181 inputData[vectorIndex++] = input.vectorOfPitchesY[s];
182 }
183 inputData[vectorIndex++] = input.ClusterPixLayer;
184 inputData[vectorIndex++] = input.ClusterPixBarrelEC;
185 inputData[vectorIndex++] = input.phi;
186 inputData[vectorIndex++] = input.theta;
187 if (not input.useTrackInfo) inputData[vectorIndex] = input.etaModule;
188 return inputData;
189 }

◆ calculateVectorDimension()

size_t InDet::NnClusterizationFactory::calculateVectorDimension ( const bool useTrackInfo) const
private

Definition at line 1017 of file NnClusterizationFactory.cxx.

1017 {
1018 return (m_sizeX * m_sizeY) + m_sizeY + (useTrackInfo ? 4 : 5);
1019 }

◆ correctedRMS()

double InDet::NnClusterizationFactory::correctedRMS ( double posPixels,
const std::vector< float > & pitches,
unsigned int size ) const
private

Definition at line 594 of file NnClusterizationFactory.cxx.

596 {
597 // Convert a pixel-unit RMS to a distance by integrating the actual pitches,
598 // so non-uniform pitch (ITk long/end pixels, 25 um modules) is handled.
599 // size is m_sizeX in phi (x), m_sizeY in eta (y).
600 double p = posPixels + (size - 1) * 0.5;
601 double p_pos = unsetPos;
602 double p_center = unsetPos;
603 double p_actual = 0;
604 for (unsigned int i = 0; i < size; i++) {
605 if (p >= i and p <= (i + 1)) p_pos = p_actual + (p - i + 0.5) * pitches.at(i);
606 if (i == (size - 1) / 2) p_center = p_actual + 0.5 * pitches.at(i);
607 p_actual += pitches.at(i);
608 }
609 return std::abs(p_pos - p_center);
610 }
size_t size() const
Number of registered mappings.

◆ createInput()

NNinput InDet::NnClusterizationFactory::createInput ( const InDet::PixelCluster & pCluster,
Amg::Vector3D & beamSpotPosition,
double & tanl ) const
private

Definition at line 794 of file NnClusterizationFactory.cxx.

796 {
797 NNinput input;
798 ATH_MSG_VERBOSE(" Starting creating input from cluster " );
799 const InDetDD::SiDetectorElement* element=pCluster.detectorElement();
800 if (not element) {
801 ATH_MSG_ERROR("Could not get detector element");
802 return input;
803 }
804 const AtlasDetectorID* aid = element->getIdHelper();
805 if (not aid){
806 ATH_MSG_ERROR("Could not get ATLASDetectorID");
807 return input;
808 }
809
810 if (aid->helper() != AtlasDetectorID::HelperType::Pixel){
811 ATH_MSG_ERROR("Could not get PixelID pointer");
812 return input;
813 }
814 const PixelID* pixelIDp=static_cast<const PixelID*>(aid);
815 const PixelID& pixelID = *pixelIDp;
816 const InDetDD::PixelModuleDesign* design
817 (dynamic_cast<const InDetDD::PixelModuleDesign*>(&element->design()));
818 if (not design){
819 ATH_MSG_ERROR("Dynamic cast failed at line "<<__LINE__<<" of NnClusterizationFactory.cxx.");
820 return input;
821 }
822 SG::ReadCondHandle<PixelChargeCalibCondData> calibDataHandle(m_chargeDataKey);
823 const PixelChargeCalibCondData *calibData = *calibDataHandle;
824 const std::vector<Identifier>& rdos = pCluster.rdoList();
825 const size_t rdoSize = rdos.size();
826 ATH_MSG_VERBOSE(" Number of RDOs: " << rdoSize );
827 const std::vector<float>& chList = pCluster.chargeList();
828 const std::vector<int>& totList = pCluster.totList();
829 std::vector<float> chListRecreated{};
830 chListRecreated.reserve(rdoSize);
831 ATH_MSG_VERBOSE(" Number of charges: " << chList.size() );
832 std::vector<int>::const_iterator tot = totList.begin();
833 std::vector<Identifier>::const_iterator rdosBegin = rdos.begin();
834 std::vector<Identifier>::const_iterator rdosEnd = rdos.end();
835 std::vector<int> totListRecreated{};
836 totListRecreated.reserve(rdoSize);
837 std::vector<int>::const_iterator totRecreated = totListRecreated.begin();
838 // Recreate both charge list and ToT list to correct for the IBL ToT overflow (and later for small hits):
839 ATH_MSG_VERBOSE("Charge list is not filled ... re-creating it.");
840 IdentifierHash moduleHash = element->identifyHash(); // wafer hash
841
842 for ( ; rdosBegin!= rdosEnd and tot != totList.end(); ++tot, ++rdosBegin, ++totRecreated ){
843 // recreate the charge: should be a method of the calibSvc
844 int tot0 = *tot;
845 Identifier pixid = *rdosBegin;
846 assert( element->identifyHash() == pixelID.wafer_hash(pixelID.wafer_id(pixid)));
847
848 std::array<InDetDD::PixelDiodeTree::CellIndexType,2> diode_idx
850 pixelID.eta_index(pixid));
851 InDetDD::PixelDiodeTree::DiodeProxy si_param ( design->diodeProxyFromIdx(diode_idx));
852 std::uint32_t feValue = design->getFE(si_param);
853 auto diode_type = design->getDiodeType(si_param);
854 if ( design->getReadoutTechnology() == InDetDD::PixelReadoutTechnology::FEI3
855 && design->numberOfConnectedCells( design->readoutIdOfCell(InDetDD::SiCellId(diode_idx[0],diode_idx[1])))>1) {
857 }
858
859 float charge = calibData->getCharge(diode_type, moduleHash, feValue, tot0);
860 chListRecreated.push_back(charge);
861 totListRecreated.push_back(tot0);
862 }
863 // reset the rdo iterator
864 rdosBegin = rdos.begin();
865 rdosEnd = rdos.end();
866 // and the tot iterator
867 tot = totList.begin();
868 totRecreated = totListRecreated.begin();
869 // Always use recreated charge and ToT lists:
870 std::vector<float>::const_iterator charge = chListRecreated.begin();
871 std::vector<float>::const_iterator chargeEnd = chListRecreated.end();
872 tot = totListRecreated.begin();
873 std::vector<int>::const_iterator totEnd = totListRecreated.end();
874 InDetDD::SiLocalPosition sumOfWeightedPositions(0,0,0);
875 double sumOfTot=0;
876 int rowMin = 999;
877 int rowMax = 0;
878 int colMin = 999;
879 int colMax = 0;
880 for (; (rdosBegin!= rdosEnd) and (charge != chargeEnd) and (tot != totEnd); ++rdosBegin, ++charge, ++tot){
881 Identifier rId = *rdosBegin;
882 int row = pixelID.phi_index(rId);
883 int col = pixelID.eta_index(rId);
884 InDetDD::SiLocalPosition siLocalPosition (design->positionFromColumnRow(col,row));
885 if (not m_useToT){
886 sumOfWeightedPositions += (*charge)*siLocalPosition;
887 sumOfTot += (*charge);
888 } else {
889 sumOfWeightedPositions += ((double)(*tot))*siLocalPosition;
890 sumOfTot += (double)(*tot);
891 }
892 rowMin = std::min(row, rowMin);
893 rowMax = std::max(row, rowMax);
894 colMin = std::min(col, colMin);
895 colMax = std::max(col, colMax);
896
897 }
898 sumOfWeightedPositions /= sumOfTot;
899 //what you want to know is simple:
900 //just the row and column of this average position!
901 InDetDD::SiCellId cellIdWeightedPosition=design->cellIdOfPosition(sumOfWeightedPositions);
902
903 if (!cellIdWeightedPosition.isValid()){
904 ATH_MSG_WARNING(" Weighted position is on invalid CellID." );
905 }
906 int columnWeightedPosition=cellIdWeightedPosition.etaIndex();
907 int rowWeightedPosition=cellIdWeightedPosition.phiIndex();
908 ATH_MSG_VERBOSE(" weighted pos row: " << rowWeightedPosition << " col: " << columnWeightedPosition );
909 int centralIndexX=(m_sizeX-1)/2;
910 int centralIndexY=(m_sizeY-1)/2;
911 if (std::abs(rowWeightedPosition-rowMin)>centralIndexX or
912 std::abs(rowWeightedPosition-rowMax)>centralIndexX){
913 ATH_MSG_VERBOSE(" Cluster too large rowMin" << rowMin << " rowMax " << rowMax << " centralX " << centralIndexX);
914 return input;
915 }
916 if (std::abs(columnWeightedPosition-colMin)>centralIndexY or
917 std::abs(columnWeightedPosition-colMax)>centralIndexY){
918 ATH_MSG_VERBOSE(" Cluster too large colMin" << colMin << " colMax " << colMax << " centralY " << centralIndexY);
919 return input;
920 }
921 input.matrixOfToT.reserve(m_sizeX);
922 for (unsigned int a=0;a<m_sizeX;a++){
923 input.matrixOfToT.emplace_back(m_sizeY, 0.0);
924 }
925 // Seed the pitches for cells with no hit. For ONNX (ITk) take the nominal
926 // from the design, so non-uniform sensors (e.g. 50x50 or 25x100 um) get the
927 // right value; for lwtnn keep the 0.4 eta seed the models were trained with.
928 if (m_useXPitches) {
929 input.vectorOfPitchesY.assign(m_sizeY, design->etaPitch());
930 input.vectorOfPitchesX.assign(m_sizeX, design->phiPitch());
931 } else {
932 input.vectorOfPitchesY.assign(m_sizeY, 0.4);
933 }
934 rdosBegin = rdos.begin();
935 charge = chListRecreated.begin();
936 chargeEnd = chListRecreated.end();
937 tot = totListRecreated.begin();
938 ATH_MSG_VERBOSE(" Putting together the n. " << rdos.size() << " rdos into a matrix." );
939 Identifier pixidentif=pCluster.identify();
940 input.etaModule=(int)pixelID.eta_module(pixidentif);
941 input.ClusterPixLayer=(int)pixelID.layer_disk(pixidentif);
942 input.ClusterPixBarrelEC=(int)pixelID.barrel_ec(pixidentif);
943 for (;( charge != chargeEnd) and (rdosBegin!= rdosEnd); ++rdosBegin, ++charge, ++tot){
944 Identifier rId = *rdosBegin;
945 unsigned int absrow = pixelID.phi_index(rId)-rowWeightedPosition+centralIndexX;
946 unsigned int abscol = pixelID.eta_index(rId)-columnWeightedPosition+centralIndexY;
947 if (absrow > m_sizeX){
948 ATH_MSG_WARNING(" problem with index: " << absrow << " min: " << 0 << " max: " << m_sizeX);
949 return input;
950 }
951 if (abscol > m_sizeY){
952 ATH_MSG_WARNING(" problem with index: " << abscol << " min: " << 0 << " max: " << m_sizeY);
953 return input;
954 }
955 InDetDD::SiCellId cellId = element->cellIdFromIdentifier(*rdosBegin);
956 InDetDD::SiDiodesParameters diodeParameters = design->parameters(cellId);
957 double pitchY = diodeParameters.width().xEta();
958 double pitchX = diodeParameters.width().xPhi();
959 if (not m_useToT) {
960 input.matrixOfToT[absrow][abscol]=*charge;
961 } else {
962 input.matrixOfToT[absrow][abscol]=(double)(*tot);
963 // in case to RunI setup to make IBL studies
964 if(m_doRunI){
965 if (m_addIBL and (input.ClusterPixLayer==0) and (input.ClusterPixBarrelEC==0)){
966 input.matrixOfToT[absrow][abscol]*=3;
967 }
968 }else{
969 // for RunII IBL is always present
970 if ( (input.ClusterPixLayer==0) and (input.ClusterPixBarrelEC==0)){
971 input.matrixOfToT[absrow][abscol]*=3;
972 }
973 }
974
975 }
976 if (m_useXPitches) {
977 input.vectorOfPitchesY[abscol]=pitchY;
978 input.vectorOfPitchesX[absrow]=pitchX;
979 } else if (std::abs(pitchY-0.4)>1e-5){
980 // lwtnn: only override the 0.4 seed for long pixels
981 input.vectorOfPitchesY[abscol]=pitchY;
982 }
983 }//end iteration on rdos
984 ATH_MSG_VERBOSE(" eta module: " << input.etaModule );
985 ATH_MSG_VERBOSE(" Layer number: " << input.ClusterPixLayer << " Barrel / endcap: " << input.ClusterPixBarrelEC );
986 input.useTrackInfo=false;
987 const Amg::Vector2D& prdLocPos = pCluster.localPosition();
988 InDetDD::SiLocalPosition centroid(prdLocPos);
989 Amg::Vector3D globalPos = element->globalPosition(centroid);
990 Amg::Vector3D my_track = globalPos-beamSpotPosition;
991 const Amg::Vector3D &my_normal = element->normal();
992 const Amg::Vector3D &my_phiax = element->phiAxis();
993 const Amg::Vector3D &my_etaax = element->etaAxis();
994 float trkphicomp = my_track.dot(my_phiax);
995 float trketacomp = my_track.dot(my_etaax);
996 float trknormcomp = my_track.dot(my_normal);
997 double bowphi = std::atan2(trkphicomp,trknormcomp);
998 double boweta = std::atan2(trketacomp,trknormcomp);
999 tanl = m_pixelLorentzAngleTool->getTanLorentzAngle(element->identifyHash(), Gaudi::Hive::currentContext());
1000 if(bowphi > M_PI_2) bowphi -= M_PI;
1001 if(bowphi < -M_PI_2) bowphi += M_PI;
1002 int readoutside = design->readoutSide();
1003 double angle = std::atan(std::tan(bowphi)-readoutside*tanl);
1004 input.phi=angle;
1005 ATH_MSG_VERBOSE(" Angle theta bef corr: " << boweta );
1006 if (boweta>M_PI_2) boweta-=M_PI;
1007 if (boweta<-M_PI_2) boweta+=M_PI;
1008 input.theta=boweta;
1009 ATH_MSG_VERBOSE(" Angle phi: " << angle << " theta: " << boweta );
1010 input.rowWeightedPosition=rowWeightedPosition;
1011 input.columnWeightedPosition=columnWeightedPosition;
1012 ATH_MSG_VERBOSE(" RowWeightedPosition: " << rowWeightedPosition << " ColWeightedPosition: " << columnWeightedPosition );
1013 return input;
1014 }//end create NNinput function
#define M_PI
#define ATH_MSG_WARNING(x)
double charge(const T &p)
Definition AtlasPID.h:997
static Double_t a
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
static constexpr std::array< PixelDiodeTree::CellIndexType, 2 > makeCellIndex(T local_x_idx, T local_y_idx)
Create a 2D cell index from the indices in local-x (phi, row) and local-y (eta, column) direction.
int phiIndex() const
Get phi index. Equivalent to strip().
Definition SiCellId.h:122
bool isValid() const
Test if its in a valid state.
Definition SiCellId.h:136
int etaIndex() const
Get eta index.
Definition SiCellId.h:114
const SiLocalPosition & width() const
width of the diodes:
double xPhi() const
position along phi direction:
double xEta() const
position along eta direction:
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline).
SG::ReadCondHandleKey< PixelChargeCalibCondData > m_chargeDataKey
ToolHandle< ISiLorentzAngleTool > m_pixelLorentzAngleTool
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
float getCharge(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float ToT) const
int eta_index(const Identifier &id) const
Definition PixelID.h:640
int layer_disk(const Identifier &id) const
Definition PixelID.h:602
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition PixelID.h:355
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0).
Definition PixelID.h:595
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition PixelID.h:378
int eta_module(const Identifier &id) const
Definition PixelID.h:627
int phi_index(const Identifier &id) const
Definition PixelID.h:634
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
Eigen::Matrix< double, 2, 1 > Vector2D
row
Appending html table to final .html summary file.

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ eigenInput()

NnClusterizationFactory::InputVector InDet::NnClusterizationFactory::eigenInput ( NNinput & input) const
private

Definition at line 228 of file NnClusterizationFactory.cxx.

228 {
229 // Input layout: m_sizeX x m_sizeY ToT values, m_sizeY y pitches, the
230 // detector location and the track incidence angles. The no-track lwtnn
231 // networks also take eta module as a trailing value; the ONNX networks do
232 // not. When m_useXPitches is set, the ONNX layout adds the m_sizeX x pitches
233 // after the y pitches, for a matching (60 + m_sizeX)-input model.
234 const bool appendEtaModule{!m_useONNX && !input.useTrackInfo};
235 const auto vecSize{(m_useONNX ? calculateVectorDimension(true)
236 : calculateVectorDimension(input.useTrackInfo))
237 + (m_useXPitches ? m_sizeX.value() : 0u)};
238 Eigen::VectorXd valuesVector( vecSize );
239 // Fill it!
240 // Variable names here need to match the ones in the configuration...
241 // ...IN THE SAME ORDER!!!
242 // location in eigen matrix object where next element goes
243 int location(0);
244 for (const auto & xvec: input.matrixOfToT){
245 for (const auto & xyElement : xvec){
246 valuesVector[location++] = xyElement;
247 }
248 }
249 for (const auto & pitch : input.vectorOfPitchesY) {
250 valuesVector[location++] = pitch;
251 }
252 if (m_useXPitches) {
253 for (const auto & pitch : input.vectorOfPitchesX) {
254 valuesVector[location++] = pitch;
255 }
256 }
257 valuesVector[location] = input.ClusterPixLayer;
258 location++;
259 valuesVector[location] = input.ClusterPixBarrelEC;
260 location++;
261 valuesVector[location] = input.phi;
262 location++;
263 valuesVector[location] = input.theta;
264 location++;
265 if (appendEtaModule) {
266 valuesVector[location] = input.etaModule;
267 location++;
268 }
269 // We have only one node for now, so we just store things there.
270 // Format for use with lwtnn
271 std::vector<Eigen::VectorXd> vectorOfEigen;
272 vectorOfEigen.push_back(std::move(valuesVector));
273 return vectorOfEigen;
274 }

◆ estimateNumberOfParticles() [1/2]

std::vector< double > InDet::NnClusterizationFactory::estimateNumberOfParticles ( const InDet::PixelCluster & pCluster,
Amg::Vector3D & beamSpotPosition ) const

Definition at line 277 of file NnClusterizationFactory.cxx.

278 {
279 double tanl=0;
280 NNinput input( createInput(pCluster,beamSpotPosition,tanl) );
281 if (!input) return {};
282 // If using old TTrainedNetworks, fetch correct ones for the
283 // without-track situation and call them now.
285 const std::vector<double> & inputData=(this->*m_assembleInput)(input);
286 SG::ReadCondHandle<TTrainedNetworkCollection> nn_collection( m_readKeyWithoutTrack );
287 if (!nn_collection.isValid()) {
288 ATH_MSG_FATAL( "Failed to get trained network collection with key " << m_readKeyWithoutTrack.key() );
289 return {};
290 }
291 return estimateNumberOfParticlesTTN(**nn_collection, inputData);
292 }
293 // Otherwise, prepare input vector and use ONNX or LWTNN networks.
295 if (m_useONNX) {
296 return estimateNumberOfParticlesONNX(nnInputVector[0]);
297 }
298 return estimateNumberOfParticlesLWTNN(nnInputVector);
299 }
#define ATH_MSG_FATAL(x)
std::vector< double > estimateNumberOfParticlesLWTNN(NnClusterizationFactory::InputVector &input) const
NNinput createInput(const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition, double &tanl) const
Gaudi::Property< bool > m_useTTrainedNetworks
std::vector< double > estimateNumberOfParticlesTTN(const TTrainedNetworkCollection &nn_collection, const std::vector< double > &inputData) const
SG::ReadCondHandleKey< TTrainedNetworkCollection > m_readKeyWithoutTrack
std::vector< double >(InDet::NnClusterizationFactory::* m_assembleInput)(NNinput &input) const
std::vector< Eigen::VectorXd > InputVector
InputVector eigenInput(NNinput &input) const
std::vector< double > estimateNumberOfParticlesONNX(const Eigen::VectorXd &input) const

◆ estimateNumberOfParticles() [2/2]

std::vector< double > InDet::NnClusterizationFactory::estimateNumberOfParticles ( const InDet::PixelCluster & pCluster,
const Trk::Surface & pixelSurface,
const Trk::TrackParameters & trackParsAtSurface ) const

Definition at line 302 of file NnClusterizationFactory.cxx.

304 {
305 Amg::Vector3D dummyBS(0,0,0);
306 double tanl=0;
307 NNinput input( createInput(pCluster,dummyBS,tanl) );
308
309 if (!input) return {};
310 addTrackInfoToInput(input,pixelSurface,trackParsAtSurface,tanl);
311 std::vector<double> inputData=(this->*m_assembleInput)(input);
312 // If using old TTrainedNetworks, fetch correct ones for the
313 // with-track situation and call them now.
315 SG::ReadCondHandle<TTrainedNetworkCollection> nn_collection( m_readKeyWithTrack );
316 if (!nn_collection.isValid()) {
317 ATH_MSG_FATAL( "Failed to get trained network collection with key " << m_readKeyWithoutTrack.key() );
318 return {};
319 }
320 return estimateNumberOfParticlesTTN(**nn_collection, inputData);
321 }
322 // Otherwise, prepare input vector and use ONNX or LWTNN networks.
324 if (m_useONNX) {
325 return estimateNumberOfParticlesONNX(nnInputVector[0]);
326 }
327 return estimateNumberOfParticlesLWTNN(nnInputVector);
328 }
void addTrackInfoToInput(NNinput &input, const Trk::Surface &pixelSurface, const Trk::TrackParameters &trackParsAtSurface, const double tanl) const
SG::ReadCondHandleKey< TTrainedNetworkCollection > m_readKeyWithTrack

◆ estimateNumberOfParticlesLWTNN()

std::vector< double > InDet::NnClusterizationFactory::estimateNumberOfParticlesLWTNN ( NnClusterizationFactory::InputVector & input) const
private

Definition at line 354 of file NnClusterizationFactory.cxx.

354 {
355 std::vector<double> result(3,0.0);//ok as invalid result?
356 SG::ReadCondHandle<LWTNNCollection> lwtnn_collection(m_readKeyJSON) ;
357 if (!lwtnn_collection.isValid()) {
358 ATH_MSG_FATAL( "Failed to get LWTNN network collection with key " << m_readKeyJSON.key() );
359 return result;
360 }
361 if (lwtnn_collection->empty()){
362 ATH_MSG_FATAL( "LWTNN network collection with key " << m_readKeyJSON.key()<<" is empty." );
363 return result;
364 }
365 ATH_MSG_DEBUG("Using lwtnn number network");
366 // Order of output matches order in JSON config in "outputs"
367 // Only 1 node here, simple compute function
368 Eigen::VectorXd discriminant = lwtnn_collection->at(0)->compute(input);
369 const double & num0 = discriminant[0];
370 const double & num1 = discriminant[1];
371 const double & num2 = discriminant[2];
372 // Get normalized predictions
373 const auto inverseSum = 1./(num0+num1+num2);
374 result[0] = num0 * inverseSum;
375 result[1] = num1 * inverseSum;
376 result[2] = num2 * inverseSum;
377 ATH_MSG_VERBOSE(" LWTNN Prob of n. particles (1): " << result[0] <<
378 " (2): " << result[1] <<
379 " (3): " << result[2]);
380 return result;
381 }
#define ATH_MSG_DEBUG(x)
SG::ReadCondHandleKey< LWTNNCollection > m_readKeyJSON

◆ estimateNumberOfParticlesONNX()

std::vector< double > InDet::NnClusterizationFactory::estimateNumberOfParticlesONNX ( const Eigen::VectorXd & input) const
private

Definition at line 1026 of file NnClusterizationFactory.cxx.

1027 {
1028
1029 std::vector<double> result(3, 0.0);
1030 SG::ReadCondHandle<OnnxNNCollection> onnxCollection(m_readKeyONNX);
1031 if (!onnxCollection.isValid()) {
1032 ATH_MSG_FATAL("Failed to get ONNX network collection with key " << m_readKeyONNX.key());
1033 return result;
1034 }
1035 Ort::Session& session = *onnxCollection->numberNetwork;
1036
1037 // Get expected input dimension from the model
1038 auto inputTypeInfo = session.GetInputTypeInfo(0);
1039 auto tensorInfo = inputTypeInfo.GetTensorTypeAndShapeInfo();
1040 const int64_t expectedDim = tensorInfo.GetShape()[1];
1041
1042 // Convert Eigen double vector to float
1043 if (static_cast<int64_t>(input.size()) != expectedDim) {
1044 ATH_MSG_FATAL("ONNX number network expects input dimension " << expectedDim
1045 << " but got " << input.size() << " — check model/configuration");
1046 return result;
1047 }
1048 std::vector<float> inputData(expectedDim);
1049 for (int i = 0; i < expectedDim; ++i) {
1050 inputData[i] = static_cast<float>(input[i]);
1051 }
1052
1053 // Create input tensor
1054 Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
1055 std::vector<int64_t> inputShape = {1, expectedDim};
1056 Ort::Value inputTensor = Ort::Value::CreateTensor<float>(
1057 memInfo, inputData.data(), inputData.size(),
1058 inputShape.data(), inputShape.size());
1059 Ort::AllocatorWithDefaultOptions allocator;
1060 auto inputName = session.GetInputNameAllocated(0, allocator);
1061 auto outputName = session.GetOutputNameAllocated(0, allocator);
1062 const char* inputNames[] = {inputName.get()};
1063 const char* outputNames[] = {outputName.get()};
1064
1065 // Run inference
1066 auto outputTensors = session.Run(
1067 Ort::RunOptions{nullptr},
1068 inputNames, &inputTensor, 1,
1069 outputNames, 1);
1070
1071 // Extract output
1072 const float* outputData = outputTensors[0].GetTensorData<float>();
1073 double num0 = outputData[0];
1074 double num1 = outputData[1];
1075 double num2 = outputData[2];
1076
1077 // Normalize
1078 const double sum = num0 + num1 + num2;
1079 if (sum <= 0.0) {
1080 ATH_MSG_WARNING("ONNX number network output sum is non-positive: " << sum);
1081 return result;
1082 }
1083 const double inverseSum = 1.0 / sum;
1084 result[0] = num0 * inverseSum;
1085 result[1] = num1 * inverseSum;
1086 result[2] = num2 * inverseSum;
1087
1088 ATH_MSG_VERBOSE("ONNX Prob of n. particles (1): " << result[0]
1089 << " (2): " << result[1]
1090 << " (3): " << result[2]);
1091 return result;
1092 }
SG::ReadCondHandleKey< OnnxNNCollection > m_readKeyONNX
str outputName
Definition lumiFormat.py:65

◆ estimateNumberOfParticlesTTN()

std::vector< double > InDet::NnClusterizationFactory::estimateNumberOfParticlesTTN ( const TTrainedNetworkCollection & nn_collection,
const std::vector< double > & inputData ) const
private

Definition at line 331 of file NnClusterizationFactory.cxx.

332 {
333 ATH_MSG_DEBUG("Using TTN number network");
334 std::vector<double> resultNN_TTN{};
335 if (not (m_nParticleNNId < nn_collection.size())){ //note: m_nParticleNNId is unsigned
336 ATH_MSG_FATAL("NnClusterizationFactory::estimateNumberOfParticlesTTN: Index "<<m_nParticleNNId<< "is out of range.");
337 return resultNN_TTN;
338 }
339 auto *const pNetwork = nn_collection[m_nParticleNNId].get();
340 if (not pNetwork){
341 ATH_MSG_FATAL("NnClusterizationFactory::estimateNumberOfParticlesTTN: nullptr returned for TrainedNetwork");
342 return resultNN_TTN;
343 }
344 // dereference unique_ptr<TTrainedNetwork> then call calculateOutput :
345 resultNN_TTN = (*pNetwork.*m_calculateOutput)(inputData);
346 ATH_MSG_VERBOSE(" TTN Prob of n. particles (1): " << resultNN_TTN[0] <<
347 " (2): " << resultNN_TTN[1] <<
348 " (3): " << resultNN_TTN[2]);
349 return resultNN_TTN;
350 }
ReturnType(::TTrainedNetwork::* m_calculateOutput)(const InputType &input) const

◆ estimatePositions() [1/2]

std::vector< Amg::Vector2D > InDet::NnClusterizationFactory::estimatePositions ( const InDet::PixelCluster & pCluster,
Amg::Vector3D & beamSpotPosition,
std::vector< Amg::MatrixX > & errors,
int numberSubClusters ) const

Definition at line 385 of file NnClusterizationFactory.cxx.

388 {
389 ATH_MSG_VERBOSE(" Starting to estimate positions...");
390 double tanl=0;
391 NNinput input( createInput(pCluster,beamSpotPosition,tanl) );
392 if (!input){
393 return {};
394 }
395 // If using old TTrainedNetworks, fetch correct ones for the
396 // without-track situation and call them now.
398 const std::vector<double> & inputData=(this->*m_assembleInput)(input);
399 SG::ReadCondHandle<TTrainedNetworkCollection> nn_collection( m_readKeyWithoutTrack );
400 if (!nn_collection.isValid()) {
401 ATH_MSG_FATAL( "Failed to get trained network collection with key " << m_readKeyWithoutTrack.key() );
402 return {};
403 }
404 // *(ReadCondHandle<>) returns a pointer rather than a reference ...
405 return estimatePositionsTTN(**nn_collection, inputData,input,pCluster,numberSubClusters,errors);
406 }
407 // Otherwise, prepare input vector and use ONNX or LWTNN networks.
409 if (m_useONNX) {
410 return estimatePositionsONNX(nnInputVector[0],input,pCluster,numberSubClusters,errors);
411 }
412 return estimatePositionsLWTNN(nnInputVector,input,pCluster,numberSubClusters,errors);
413 }
std::vector< Amg::Vector2D > estimatePositionsONNX(const Eigen::VectorXd &input, NNinput &rawInput, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const
std::vector< Amg::Vector2D > estimatePositionsLWTNN(NnClusterizationFactory::InputVector &input, NNinput &rawInput, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const
std::vector< Amg::Vector2D > estimatePositionsTTN(const TTrainedNetworkCollection &nn_collection, const std::vector< double > &inputData, const NNinput &input, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const

◆ estimatePositions() [2/2]

std::vector< Amg::Vector2D > InDet::NnClusterizationFactory::estimatePositions ( const InDet::PixelCluster & pCluster,
const Trk::Surface & pixelSurface,
const Trk::TrackParameters & trackParsAtSurface,
std::vector< Amg::MatrixX > & errors,
int numberSubClusters ) const

Definition at line 417 of file NnClusterizationFactory.cxx.

421 {
422 ATH_MSG_VERBOSE(" Starting to estimate positions...");
423 Amg::Vector3D dummyBS(0,0,0);
424 double tanl=0;
425 NNinput input( createInput(pCluster, dummyBS, tanl) );
426 if (!input) return {};
427 addTrackInfoToInput(input,pixelSurface,trackParsAtSurface,tanl);
428 // If using old TTrainedNetworks, fetch correct ones for the
429 // without-track situation and call them now.
431 std::vector<double> inputData=(this->*m_assembleInput)(input);
432 SG::ReadCondHandle<TTrainedNetworkCollection> nn_collection( m_readKeyWithTrack );
433 if (!nn_collection.isValid()) {
434 ATH_MSG_FATAL( "Failed to get trained network collection with key " << m_readKeyWithTrack.key() );
435 return {};
436 }
437 return estimatePositionsTTN(**nn_collection, inputData,input,pCluster,numberSubClusters,errors);
438 }
439 // Otherwise, prepare input vector and use ONNX or LWTNN networks.
441 if (m_useONNX) {
442 return estimatePositionsONNX(nnInputVector[0],input,pCluster,numberSubClusters,errors);
443 }
444 return estimatePositionsLWTNN(nnInputVector,input,pCluster,numberSubClusters,errors);
445 }

◆ estimatePositionsLWTNN()

std::vector< Amg::Vector2D > InDet::NnClusterizationFactory::estimatePositionsLWTNN ( NnClusterizationFactory::InputVector & input,
NNinput & rawInput,
const InDet::PixelCluster & pCluster,
int numberSubClusters,
std::vector< Amg::MatrixX > & errors ) const
private

Definition at line 511 of file NnClusterizationFactory.cxx.

515 {
516 SG::ReadCondHandle<LWTNNCollection> lwtnn_collection(m_readKeyJSON) ;
517 if (not lwtnn_collection.isValid()) {
518 ATH_MSG_FATAL( "Failed to get LWTNN network collection with key " << m_readKeyJSON.key() );
519 return {};
520 }
521 if (lwtnn_collection->empty()){
522 ATH_MSG_FATAL( "estimatePositionsLWTNN: LWTNN network collection with key " << m_readKeyJSON.key()<<" is empty." );
523 return {};
524 }
525 // Need to evaluate the correct network once per cluster we're interested in.
526 // Save the output
527 std::vector<double> positionValues{};
528 std::vector<Amg::MatrixX> errorMatrices;
529 errorMatrices.reserve(numberSubClusters);
530 positionValues.reserve(numberSubClusters * 2);
531 std::size_t outputNode(0);
532 for (int cluster = 1; cluster < numberSubClusters+1; cluster++) {
533 // Check that the network is defined.
534 // If not, we are outside an IOV and should fail
535 const auto pNetwork = lwtnn_collection->find(numberSubClusters);
536 const bool validGraph = (pNetwork != lwtnn_collection->end()) and (pNetwork->second != nullptr);
537 if (not validGraph) {
538 std::string infoMsg ="Acceptable numbers of subclusters for the lwtnn collection:\n ";
539 for (const auto & pair: **lwtnn_collection){
540 infoMsg += std::to_string(pair.first) + "\n ";
541 }
542 infoMsg += "\nNumber of subclusters requested : "+ std::to_string(numberSubClusters);
543 ATH_MSG_DEBUG(infoMsg);
544 ATH_MSG_FATAL( "estimatePositionsLWTNN: No lwtnn network found for the number of clusters.\n"
545 <<" If you are outside the valid range for an lwtnn-based configuration, please run with useNNTTrainedNetworks instead.\n Key = "
546 << m_readKeyJSON.key() );
547 return {};
548 }
549 if(numberSubClusters==1) {
550 outputNode = m_outputNodesPos1;
551 } else if(numberSubClusters==2) {
552 outputNode = m_outputNodesPos2[cluster-1];
553 } else if(numberSubClusters==3) {
554 outputNode = m_outputNodesPos3[cluster-1];
555 } else {
556 ATH_MSG_FATAL( "Cannot evaluate LWTNN networks with " << numberSubClusters << " numberSubClusters" );
557 return {};
558 }
559
560 // Order of output matches order in JSON config in "outputs"
561 // "alpha", "mean_x", "mean_y", "prec_x", "prec_y"
562 // Assume here that 1 particle network is in position 1, 2 at 2, and 3 at 3.
563 Eigen::VectorXd position = lwtnn_collection->at(numberSubClusters)->compute(input, {}, outputNode);
564 ATH_MSG_DEBUG("Testing for numberSubClusters " << numberSubClusters << " and cluster " << cluster);
565 for (int i=0; i<position.rows(); i++) {
566 ATH_MSG_DEBUG(" position " << position[i]);
567 }
568 positionValues.push_back(position[1]); //mean_x
569 positionValues.push_back(position[2]); //mean_y
570 // Fill errors.
571 // Values returned by NN are inverse of variance, and we want variances.
572 const float rawRmsX = std::sqrt(1.0/position[3]); //prec_x
573 const float rawRmsY = std::sqrt(1.0/position[4]); //prec_y
574 // Convert to real space units: x uses the nominal pixel pitch, y
575 // integrates the actual pitches. (estimatePositionsONNX uses correctedRMS
576 // for both directions.)
577 const double rmsX = rawRmsX * legacyPhiPitch;
578 const double rmsY = correctedRMS(rawRmsY, rawInput.vectorOfPitchesY, m_sizeY);
579 ATH_MSG_DEBUG(" Estimated RMS errors (1) x: " << rmsX << ", y: " << rmsY);
580 // Fill matrix
581 Amg::MatrixX erm(2,2);
582 erm.setZero();
583 erm(0,0)=rmsX*rmsX;
584 erm(1,1)=rmsY*rmsY;
585 errorMatrices.push_back(std::move(erm));
586 }
587 std::vector<Amg::Vector2D> myPositions = getPositionsFromOutput(positionValues,rawInput,pCluster);
588 ATH_MSG_DEBUG(" Estimated myPositions (1) x: " << myPositions[0][Trk::locX] << " y: " << myPositions[0][Trk::locY]);
589 errors=std::move(errorMatrices);
590 return myPositions;
591 }
double correctedRMS(double posPixels, const std::vector< float > &pitches, unsigned int size) const
Gaudi::Property< std::size_t > m_outputNodesPos1
Gaudi::Property< std::vector< std::size_t > > m_outputNodesPos2
Gaudi::Property< std::vector< std::size_t > > m_outputNodesPos3
std::vector< Amg::Vector2D > getPositionsFromOutput(std::vector< double > &output, const NNinput &input, const InDet::PixelCluster &pCluster) const
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
const Amg::Vector3D & position() const
Method to retrieve the position of the Intersection.

◆ estimatePositionsONNX()

std::vector< Amg::Vector2D > InDet::NnClusterizationFactory::estimatePositionsONNX ( const Eigen::VectorXd & input,
NNinput & rawInput,
const InDet::PixelCluster & pCluster,
int numberSubClusters,
std::vector< Amg::MatrixX > & errors ) const
private

Definition at line 1095 of file NnClusterizationFactory.cxx.

1100 {
1101
1102 std::vector<Amg::Vector2D> allPositions;
1103 if (numberSubClusters < 1 || numberSubClusters > static_cast<int>(m_maxSubClusters)) {
1104 return allPositions;
1105 }
1106
1107 SG::ReadCondHandle<OnnxNNCollection> onnxCollection(m_readKeyONNX);
1108 if (!onnxCollection.isValid()) {
1109 ATH_MSG_FATAL("Failed to get ONNX network collection with key " << m_readKeyONNX.key());
1110 return allPositions;
1111 }
1112 Ort::Session* posNet = nullptr;
1113 if (numberSubClusters == 1) posNet = onnxCollection->positionNetwork1.get();
1114 else if (numberSubClusters == 2) posNet = onnxCollection->positionNetwork2.get();
1115 else if (numberSubClusters == 3) posNet = onnxCollection->positionNetwork3.get();
1116
1117 if (!posNet) {
1118 ATH_MSG_FATAL("ONNX position network for " << numberSubClusters
1119 << " sub-clusters not found in collection");
1120 return allPositions;
1121 }
1122
1123 Ort::Session& session = *posNet;
1124
1125 // Get expected input dimension from the model
1126 auto inputTypeInfo = session.GetInputTypeInfo(0);
1127 auto tensorInfo = inputTypeInfo.GetTensorTypeAndShapeInfo();
1128 const int64_t expectedDim = tensorInfo.GetShape()[1];
1129
1130 // Convert input to float
1131 if (static_cast<int64_t>(input.size()) != expectedDim) {
1132 ATH_MSG_FATAL("ONNX position network (" << numberSubClusters
1133 << " sub-clusters) expects input dimension " << expectedDim
1134 << " but got " << input.size() << " — check model/configuration");
1135 return allPositions;
1136 }
1137 std::vector<float> inputData(expectedDim);
1138 for (int i = 0; i < expectedDim; ++i) {
1139 inputData[i] = static_cast<float>(input[i]);
1140 }
1141
1142 // Create input tensor
1143 Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
1144 std::vector<int64_t> inputShape = {1, expectedDim};
1145 Ort::Value inputTensor = Ort::Value::CreateTensor<float>(
1146 memInfo, inputData.data(), inputData.size(),
1147 inputShape.data(), inputShape.size());
1148 Ort::AllocatorWithDefaultOptions allocator;
1149 auto inputName = session.GetInputNameAllocated(0, allocator);
1150 auto outputName = session.GetOutputNameAllocated(0, allocator);
1151 const char* inputNames[] = {inputName.get()};
1152 const char* outputNames[] = {outputName.get()};
1153
1154 // Run inference
1155 auto outputTensors = session.Run(
1156 Ort::RunOptions{nullptr},
1157 inputNames, &inputTensor, 1,
1158 outputNames, 1);
1159
1160 // Extract output: expect [1, 5*numberSubClusters]
1161 // Format per sub-cluster: [alpha, mean_x, mean_y, prec_x, prec_y]
1162 const float* outputData = outputTensors[0].GetTensorData<float>();
1163
1164 std::vector<double> positionValues;
1165 positionValues.reserve(numberSubClusters * 2);
1166
1167 for (int iSub = 0; iSub < numberSubClusters; ++iSub) {
1168 const int offset = iSub * 5;
1169 // outputData[offset+0] = alpha (unused)
1170 const double mean_x = outputData[offset + 1];
1171 const double mean_y = outputData[offset + 2];
1172 const double prec_x = outputData[offset + 3];
1173 const double prec_y = outputData[offset + 4];
1174
1175 positionValues.push_back(mean_x);
1176 positionValues.push_back(mean_y);
1177
1178 // Convert precision to RMS and build error matrix
1179 if (prec_x <= 0 || prec_y <= 0) {
1180 ATH_MSG_WARNING("ONNX position network returned non-positive precision for sub-cluster "
1181 << iSub << " (prec_x=" << prec_x << ", prec_y=" << prec_y
1182 << "); using fallback RMS of 0.01");
1183 }
1184 const float rawRmsX = (prec_x > 0) ? std::sqrt(1.0f / prec_x) : 0.01f;
1185 const float rawRmsY = (prec_y > 0) ? std::sqrt(1.0f / prec_y) : 0.01f;
1186 const double rmsX = correctedRMS(rawRmsX, rawInput.vectorOfPitchesX, m_sizeX);
1187 const double rmsY = correctedRMS(rawRmsY, rawInput.vectorOfPitchesY, m_sizeY);
1188
1189 Amg::MatrixX erm(2, 2);
1190 erm.setZero();
1191 erm(0, 0) = rmsX * rmsX;
1192 erm(1, 1) = rmsY * rmsY;
1193 errors.push_back(std::move(erm));
1194 }
1195
1196 // Convert raw position outputs to detector coordinates
1197 allPositions = getPositionsFromOutput(positionValues, rawInput, pCluster);
1198 return allPositions;
1199 }
Gaudi::Property< unsigned int > m_maxSubClusters

◆ estimatePositionsTTN()

std::vector< Amg::Vector2D > InDet::NnClusterizationFactory::estimatePositionsTTN ( const TTrainedNetworkCollection & nn_collection,
const std::vector< double > & inputData,
const NNinput & input,
const InDet::PixelCluster & pCluster,
int numberSubClusters,
std::vector< Amg::MatrixX > & errors ) const
private

Definition at line 448 of file NnClusterizationFactory.cxx.

453 {
454 bool applyRecentering=(!input.useTrackInfo and m_useRecenteringNNWithouTracks) or (input.useTrackInfo and m_useRecenteringNNWithTracks);
455 std::vector<Amg::Vector2D> allPositions{};
456 const auto endNnIdx = nn_collection.size();
457 if (numberSubClusters>0 and static_cast<unsigned int>(numberSubClusters) < m_maxSubClusters) {
458 const auto subClusterIndex = numberSubClusters-1;
459 // get position network id for the given cluster multiplicity then
460 // dereference unique_ptr<TTrainedNetwork> then call calculateOutput :
461 const auto networkIndex = m_NNId[kPositionNN-1].at(subClusterIndex);
462 //TTrainedNetworkCollection inherits from std::vector
463 if (not(networkIndex < endNnIdx)){
464 ATH_MSG_FATAL("estimatePositionsTTN: Requested collection index, "<< networkIndex << " is out of range.");
465 return allPositions;
466 }
467 auto *const pNetwork = nn_collection[networkIndex].get();
468 std::vector<double> position1P = (*pNetwork.*m_calculateOutput)(inputData);
469 std::vector<Amg::Vector2D> myPosition1=getPositionsFromOutput(position1P,input,pCluster);
470 assert( position1P.size() % 2 == 0);
471 for (unsigned int i=0; i<position1P.size()/2 ; ++i) {
472 ATH_MSG_DEBUG(" Original RAW Estimated positions (" << i << ") x: " << back_posX(position1P[0+i*2],applyRecentering) << " y: " << back_posY(position1P[1+i*2]));
473 ATH_MSG_DEBUG(" Original estimated myPositions (" << i << ") x: " << myPosition1[i][Trk::locX] << " y: " << myPosition1[i][Trk::locY]);
474 }
475 const std::size_t nPositions{static_cast<std::size_t>(numberSubClusters*2)};
476 assert( nPositions <= position1P.size() );
477 //reserve space before copy, to avoid reallocation
478 std::vector<double> inputDataNew;
479 inputDataNew.reserve( inputDataNew.size() + nPositions);
480 inputDataNew.insert(inputDataNew.end(), inputData.begin(), inputData.end());
481 inputDataNew.insert(inputDataNew.end(), position1P.begin(), position1P.begin() + nPositions);
482
483 // get error network id for the given cluster multiplicity then
484 // dereference unique_ptr<TTrainedNetwork> then call calculateOutput :
485 const auto xNetworkIndex = m_NNId[kErrorXNN-1].at(subClusterIndex);
486 const auto yNetworkIndex = m_NNId[kErrorYNN-1].at(subClusterIndex);
487 if ((not (xNetworkIndex < endNnIdx)) or (not (yNetworkIndex < endNnIdx))){
488 ATH_MSG_FATAL("estimatePositionsTTN: A requested collection index, "<< xNetworkIndex << " or "<< yNetworkIndex << "is out of range.");
489 return allPositions;
490 }
491 auto *pxNetwork = nn_collection.at(xNetworkIndex).get();
492 auto *pyNetwork = nn_collection.at(yNetworkIndex).get();
493 //call the selected member function of the TTrainedNetwork
494 std::vector<double> errors1PX = (*pxNetwork.*m_calculateOutput)(inputDataNew);
495 std::vector<double> errors1PY = (*pyNetwork.*m_calculateOutput)(inputDataNew);
496 //
497 std::vector<Amg::MatrixX> errorMatrices1;
498 getErrorMatrixFromOutput(errors1PX,errors1PY,errorMatrices1,numberSubClusters);
499 allPositions.reserve( allPositions.size() + myPosition1.size());
500 errors.reserve( errors.size() + myPosition1.size());
501 for (unsigned int i=0;i<myPosition1.size();i++){
502 allPositions.push_back(myPosition1[i]);
503 errors.push_back(errorMatrices1[i]);
504 }
505 }
506 return allPositions;
507 }
double back_posX(const double input, const bool recenter=false)
double back_posY(const double input)
Gaudi::Property< bool > m_useRecenteringNNWithouTracks
void getErrorMatrixFromOutput(std::vector< double > &outputX, std::vector< double > &outputY, std::vector< Amg::MatrixX > &errorMatrix, int nParticles) const
Gaudi::Property< bool > m_useRecenteringNNWithTracks
std::vector< std::vector< unsigned int > > m_NNId

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ finalize()

virtual StatusCode InDet::NnClusterizationFactory::finalize ( )
inlineoverridevirtual

Definition at line 102 of file NnClusterizationFactory.h.

102{ return StatusCode::SUCCESS; };

◆ getErrorMatrixFromOutput()

void InDet::NnClusterizationFactory::getErrorMatrixFromOutput ( std::vector< double > & outputX,
std::vector< double > & outputY,
std::vector< Amg::MatrixX > & errorMatrix,
int nParticles ) const
private

Definition at line 613 of file NnClusterizationFactory.cxx.

616 {
617 int sizeOutputX=outputX.size()/nParticles;
618 int sizeOutputY=outputY.size()/nParticles;
619 double minimumX=-errorHalfIntervalX(nParticles);
620 double maximumX=errorHalfIntervalX(nParticles);
621 double minimumY=-errorHalfIntervalY(nParticles);
622 double maximumY=errorHalfIntervalY(nParticles);
623 //X=0...sizeOutput-1
624 //Y=minimum+(maximum-minimum)/sizeOutput*(X+1./2.)
625 errorMatrix.reserve( errorMatrix.size() + nParticles);
626 for (int i=0;i<nParticles;i++){
627 double sumValuesX=0;
628 for (int u=0;u<sizeOutputX;u++){
629 sumValuesX+=outputX[i*sizeOutputX+u];
630 }
631 double sumValuesY=0;
632 for (int u=0;u<sizeOutputY;u++){
633 sumValuesY+=outputY[i*sizeOutputY+u];
634 }
635 ATH_MSG_VERBOSE(" minimumX: " << minimumX << " maximumX: " << maximumX << " sizeOutputX " << sizeOutputX);
636 ATH_MSG_VERBOSE(" minimumY: " << minimumY << " maximumY: " << maximumY << " sizeOutputY " << sizeOutputY);
637 double RMSx=0;
638 for (int u=0;u<sizeOutputX;u++){
639 RMSx+=outputX[i*sizeOutputX+u]/sumValuesX*std::pow(minimumX+(maximumX-minimumX)/(double)(sizeOutputX-2)*(u-1./2.),2);
640 }
641 RMSx=std::sqrt(RMSx);//computed error!
642 ATH_MSG_VERBOSE(" first Iter RMSx: " << RMSx);
643 double intervalErrorX=3*RMSx;
644 //now recompute between -3*RMSx and +3*RMSx
645 int minBinX=(int)(1+(-intervalErrorX-minimumX)/(maximumX-minimumX)*(double)(sizeOutputX-2));
646 int maxBinX=(int)(1+(intervalErrorX-minimumX)/(maximumX-minimumX)*(double)(sizeOutputX-2));
647 if (maxBinX>sizeOutputX-1) maxBinX=sizeOutputX-1;
648 if (minBinX<0) minBinX=0;
649 ATH_MSG_VERBOSE(" minBinX: " << minBinX << " maxBinX: " << maxBinX );
650 RMSx=0;
651 for (int u=minBinX;u<maxBinX+1;u++){
652 RMSx+=outputX[i*sizeOutputX+u]/sumValuesX*std::pow(minimumX+(maximumX-minimumX)/(double)(sizeOutputX-2)*(u-1./2.),2);
653 }
654 RMSx=std::sqrt(RMSx);//computed error!
655 double RMSy=0;
656 for (int u=0;u<sizeOutputY;u++){
657 RMSy+=outputY[i*sizeOutputY+u]/sumValuesY*std::pow(minimumY+(maximumY-minimumY)/(double)(sizeOutputY-2)*(u-1./2.),2);
658 }
659 RMSy=std::sqrt(RMSy);//computed error!
660 ATH_MSG_VERBOSE("first Iter RMSy: " << RMSy );
661 double intervalErrorY=3*RMSy;
662 //now recompute between -3*RMSy and +3*RMSy
663 int minBinY=(int)(1+(-intervalErrorY-minimumY)/(maximumY-minimumY)*(double)(sizeOutputY-2));
664 int maxBinY=(int)(1+(intervalErrorY-minimumY)/(maximumY-minimumY)*(double)(sizeOutputY-2));
665 if (maxBinY>sizeOutputY-1) maxBinY=sizeOutputY-1;
666 if (minBinY<0) minBinY=0;
667 ATH_MSG_VERBOSE("minBinY: " << minBinY << " maxBinY: " << maxBinY );
668 RMSy=0;
669 for (int u=minBinY;u<maxBinY+1;u++){
670 RMSy+=outputY[i*sizeOutputY+u]/sumValuesY*std::pow(minimumY+(maximumY-minimumY)/(double)(sizeOutputY-2)*(u-1./2.),2);
671 }
672 RMSy=std::sqrt(RMSy);//computed error!
673 ATH_MSG_VERBOSE("Computed error, sigma(X) " << RMSx << " sigma(Y) " << RMSy );
674 Amg::MatrixX erm(2,2);
675 erm.setZero();
676 erm(0,0)=RMSx*RMSx;
677 erm(1,1)=RMSy*RMSy;
678 errorMatrix.push_back(std::move(erm));
679 }//end nParticles
680 }//getErrorMatrixFromOutput
double errorHalfIntervalY(const int nParticles)
double errorHalfIntervalX(const int nParticles)

◆ getPositionsFromOutput()

std::vector< Amg::Vector2D > InDet::NnClusterizationFactory::getPositionsFromOutput ( std::vector< double > & output,
const NNinput & input,
const InDet::PixelCluster & pCluster ) const
private

Definition at line 684 of file NnClusterizationFactory.cxx.

686 {
687 ATH_MSG_VERBOSE(" Translating output back into a position " );
688 const InDetDD::SiDetectorElement* element=pCluster.detectorElement();//DEFINE
689 const InDetDD::PixelModuleDesign* design
690 (dynamic_cast<const InDetDD::PixelModuleDesign*>(&element->design()));
691 if (not design){
692 ATH_MSG_ERROR("Dynamic cast failed at line "<<__LINE__<<" of NnClusterizationFactory.cxx.");
693 return {};
694 }
695 int numParticles=output.size()/2;
696 int columnWeightedPosition=input.columnWeightedPosition;
697 int rowWeightedPosition=input.rowWeightedPosition;
698 ATH_MSG_VERBOSE(" REF POS columnWeightedPos: " << columnWeightedPosition << " rowWeightedPos: " << rowWeightedPosition );
699 bool applyRecentering=false;
700 if (m_useRecenteringNNWithouTracks and (not input.useTrackInfo)){
701 applyRecentering=true;
702 }
703 if (m_useRecenteringNNWithTracks and input.useTrackInfo){
704 applyRecentering=true;
705 }
706 std::vector<Amg::Vector2D> positions;
707 for (int u=0;u<numParticles;u++){
708 double posXid{};
709 double posYid{};
710 if(m_doRunI){
711 posXid=back_posX(output[2*u],applyRecentering)+rowWeightedPosition;
712 posYid=back_posY(output[2*u+1])+columnWeightedPosition;
713 }else{
714 posXid=output[2*u]+rowWeightedPosition;
715 posYid=output[2*u+1]+columnWeightedPosition;
716 }
717 ATH_MSG_VERBOSE(" N. particle: " << u << " idx posX " << posXid << " posY " << posYid );
718 //ATLASRECTS-7155 : Pixel Charge Calibration needs investigating
719 const auto & [posXid_int, coercedX]=coerceToIntRange(posXid+0.5);
720 const auto & [posYid_int, coercedY]=coerceToIntRange(posYid+0.5);
721 if (coercedX or coercedY){
722 ATH_MSG_WARNING("X or Y position value has been limited in range; original values are (" << posXid<<", "<<posYid<<")");
723 //we cannot skip these values, it seems client code relies on the size of input vector and output vector being the same
724 }
725 ATH_MSG_VERBOSE(" N. particle: " << u << " TO INTEGER idx posX " << posXid_int << " posY " << posYid_int );
726 InDetDD::SiLocalPosition siLocalPositionDiscrete(design->positionFromColumnRow(posYid_int,posXid_int));
727 InDetDD::SiCellId cellIdOfPositionDiscrete=design->cellIdOfPosition(siLocalPositionDiscrete);
728 if ( not cellIdOfPositionDiscrete.isValid()){
729 ATH_MSG_WARNING(" Cell is outside validity region with index Y: " << posYid_int << " and index X: " << posXid_int << ". Not foreseen... " );
730 }
731 InDetDD::SiDiodesParameters diodeParameters = design->parameters(cellIdOfPositionDiscrete);
732 double pitchY = diodeParameters.width().xEta();
733 double pitchX = diodeParameters.width().xPhi();
734 ATH_MSG_VERBOSE(" Translated weighted position : " << siLocalPositionDiscrete.xPhi()
735 << " Translated weighted position : " << siLocalPositionDiscrete.xEta() );
736 //FOR TEST
737 InDetDD::SiLocalPosition siLocalPositionDiscreteOneRowMoreOneColumnMore(design->positionFromColumnRow(posYid_int+1,posXid_int+1));
738 ATH_MSG_VERBOSE(" Translated weighted position +1col +1row phi: " << siLocalPositionDiscreteOneRowMoreOneColumnMore.xPhi()
739 << " Translated weighted position +1col +1row eta: " << siLocalPositionDiscreteOneRowMoreOneColumnMore.xEta() );
740 ATH_MSG_VERBOSE("PitchY: " << pitchY << " pitchX " << pitchX );
741 InDetDD::SiLocalPosition siLocalPositionAdd(pitchY*(posYid-(double)posYid_int),
742 pitchX*(posXid-(double)posXid_int));
743 double lorentzShift=m_pixelLorentzAngleTool->getLorentzShift(element->identifyHash(), Gaudi::Hive::currentContext());
744 if (input.ClusterPixBarrelEC == 0){
745 if (not input.useTrackInfo){
747 } else {
749 }
750 }
751
752 InDetDD::SiLocalPosition
753 siLocalPosition(siLocalPositionDiscrete.xEta()+pitchY*(posYid-(double)posYid_int),
754 siLocalPositionDiscrete.xPhi()+pitchX*(posXid-(double)posXid_int)+lorentzShift);
755 ATH_MSG_VERBOSE(" Translated final position phi: " << siLocalPosition.xPhi() << " eta: " << siLocalPosition.xEta() );
756 const auto halfWidth{design->width()*0.5};
757 if (siLocalPositionDiscrete.xPhi() > halfWidth){
758 siLocalPosition=InDetDD::SiLocalPosition(siLocalPositionDiscrete.xEta()+pitchY*(posYid-(double)posYid_int),
759 halfWidth-1e-6);
760 ATH_MSG_WARNING(" Corrected out of boundary cluster from x(phi): " << siLocalPositionDiscrete.xPhi()+pitchX*(posXid-(double)posXid_int)
761 << " to: " << halfWidth-1e-6);
762 } else if (siLocalPositionDiscrete.xPhi() < -halfWidth) {
763 siLocalPosition=InDetDD::SiLocalPosition(siLocalPositionDiscrete.xEta()+pitchY*(posYid-(double)posYid_int),
764 -halfWidth+1e-6);
765 ATH_MSG_WARNING(" Corrected out of boundary cluster from x(phi): " << siLocalPositionDiscrete.xPhi()+pitchX*(posXid-(double)posXid_int)
766 << " to: " << -halfWidth+1e-6);
767 }
768 positions.emplace_back(siLocalPosition);
769 }//iterate over all particles
770 return positions;
771 }
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
Gaudi::Property< double > m_correctLorShiftBarrelWithoutTracks
Gaudi::Property< double > m_correctLorShiftBarrelWithTracks
output
Definition merge.py:16

◆ initialize()

StatusCode InDet::NnClusterizationFactory::initialize ( )
overridevirtual

Definition at line 74 of file NnClusterizationFactory.cxx.

74 {
75 ATH_CHECK(m_chargeDataKey.initialize());
78 if (m_doRunI) {
80 } else {
82 }
83 // =0 means invalid in the following, but later on the values will be decremented by one and they indicate the index in the NN collection
85 m_NNId.clear();
86 m_NNId.resize( kNNetworkTypes -1 ) ;
87 // map networks to element in network collection
88 unsigned int nn_id=0;
89 std::smatch match_result;
90 for(const std::string &nn_name : m_nnOrder) {
91 ++nn_id;
92 for (unsigned int network_i=0; network_i<kNNetworkTypes; ++network_i) {
93 if (std::regex_match( nn_name, match_result, m_nnNames[network_i])) {
94 if (network_i == kNumberParticlesNN) {
95 m_nParticleNNId = nn_id;
96 } else {
97 if (m_nParticleGroup[network_i]>0) {
98 if (m_nParticleGroup[network_i]>=match_result.size()) {
99 ATH_MSG_ERROR("Regex and match group of particle multiplicity do not coincide (groups=" << match_result.size()
100 << " n particle group=" << m_nParticleGroup[network_i]
101 << "; type=" << network_i << ")");
102 }
103 int n_particles=std::stoi( match_result[m_nParticleGroup[network_i]].str());
104 if (n_particles<=0 or static_cast<unsigned int>(n_particles)>m_maxSubClusters) {
105 ATH_MSG_ERROR( "Failed to extract number of clusters the NN is meant for. Got " << match_result[m_nParticleGroup[network_i]].str()
106 << " But this is not in the valid range 1..." << m_maxSubClusters);
107 return StatusCode::FAILURE;
108 }
109 if (static_cast<unsigned int>(n_particles)>=m_NNId[network_i-1].size()) {
110 m_NNId[network_i-1].resize( n_particles );
111 }
112 m_NNId[network_i-1][n_particles-1] = nn_id;
113 } else {
114 if (m_NNId[network_i-1].empty()) {
115 m_NNId[network_i-1].resize(1);
116 }
117 m_NNId[network_i-1][0] = nn_id;
118 }
119 }
120 }
121 }
122 }
123 // check whether the NN IDs are all valid
124 // if valid decrease IDs by 1, because the ID is used as index in the NN collection.
125 if ((m_nParticleNNId==0) or (m_nParticleNNId>=m_nnOrder.size())) {
126 ATH_MSG_ERROR( "No NN specified to estimate the number of particles.");
127 return StatusCode::FAILURE;
128 }
130 ATH_MSG_VERBOSE("Expect NN " << s_nnTypeNames[0] << " at index " << m_nParticleNNId );
131 unsigned int type_i=0;
132 for (std::vector<unsigned int> &nn_id : m_NNId) {
133 ++type_i;
134 if (nn_id.empty()) {
135 ATH_MSG_ERROR( "No " << s_nnTypeNames[type_i] << " specified.");
136 return StatusCode::FAILURE;
137 }
138 if (m_nParticleGroup[type_i-1]>0 and nn_id.size() != m_maxSubClusters) {
139 ATH_MSG_ERROR( "Number of networks of type " << s_nnTypeNames[type_i] << " does match the maximum number of supported sub clusters " << m_maxSubClusters);
140 return StatusCode::FAILURE;
141 }
142 unsigned int n_particles=0;
143 for (unsigned int &a_nn_id : nn_id ) {
144 ++n_particles;
145 if ((a_nn_id==0) or (a_nn_id>m_nnOrder.size())) {
146 ATH_MSG_ERROR( "No " << s_nnTypeNames[type_i] << " specified for " << n_particles);
147 return StatusCode::FAILURE;
148 }
149 --a_nn_id;
150 ATH_MSG_VERBOSE("Expect NN " << s_nnTypeNames[type_i] << " for " << n_particles << " particle(s) at index " << a_nn_id );
151 }
152 }
153 // The X pitches are only fed to the ONNX network; the lwtnn and TTN
154 // variable orders have no slot for them.
155 if (m_useXPitches && !m_useONNX) {
156 ATH_MSG_FATAL("useXPitches=True is only supported with the ONNX backend "
157 "(useONNX=True): the lwtnn VariableOrder and the "
158 "TTrainedNetwork inputs do not include the X pitches.");
159 return StatusCode::FAILURE;
160 }
161 ATH_CHECK( m_readKeyWithoutTrack.initialize( !m_readKeyWithoutTrack.key().empty() ) );
162 ATH_CHECK( m_readKeyWithTrack.initialize( !m_readKeyWithTrack.key().empty() ) );
163 ATH_CHECK( m_readKeyJSON.initialize( !m_readKeyJSON.key().empty() ) );
164 ATH_CHECK( m_readKeyONNX.initialize( !m_readKeyONNX.key().empty() ) );
165 return StatusCode::SUCCESS;
166 }
#define ATH_CHECK
Evaluate an expression and check for errors.
static const Attributes_t empty
std::vector< double > assembleInputRunII(NNinput &input) const
std::vector< double > assembleInputRunI(NNinput &input) const
Gaudi::Property< std::vector< std::string > > m_nnOrder
static constexpr std::array< unsigned int, kNNetworkTypes > m_nParticleGroup
static const std::array< std::regex, kNNetworkTypes > m_nnNames
static constexpr std::array< std::string_view, kNNetworkTypes > s_nnTypeNames
std::vector< Double_t > calculateOutputValues(std::vector< Double_t > &input) const

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ interfaceID()

const InterfaceID & InDet::NnClusterizationFactory::interfaceID ( )
inlinestatic

AlgTool interface methods.

Definition at line 95 of file NnClusterizationFactory.h.

static const InterfaceID IID_NnClusterizationFactory("InDet::NnClusterizationFactory", 1, 0)

◆ msg()

MsgStream & AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, and AthCheckedComponent<::AthAlgTool >.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

Member Data Documentation

◆ m_addIBL

Gaudi::Property<bool> InDet::NnClusterizationFactory::m_addIBL {this, "addIBL", false, "Also apply to clusters in IBL." }
private

Definition at line 294 of file NnClusterizationFactory.h.

295{this, "addIBL", false, "Also apply to clusters in IBL." };

◆ m_assembleInput

std::vector< double >(InDet::NnClusterizationFactory::* InDet::NnClusterizationFactory::m_assembleInput) (NNinput &input) const
inlineprivate

◆ m_calculateOutput

ReturnType(::TTrainedNetwork::* InDet::NnClusterizationFactory::m_calculateOutput) (const InputType &input) const
inlineprivate

◆ m_chargeDataKey

SG::ReadCondHandleKey<PixelChargeCalibCondData> InDet::NnClusterizationFactory::m_chargeDataKey {this, "PixelChargeCalibCondData", "PixelChargeCalibCondData", "Output key"}
private

Definition at line 252 of file NnClusterizationFactory.h.

253{this, "PixelChargeCalibCondData", "PixelChargeCalibCondData", "Output key"};

◆ m_correctLorShiftBarrelWithoutTracks

Gaudi::Property<double> InDet::NnClusterizationFactory::m_correctLorShiftBarrelWithoutTracks {this, "correctLorShiftBarrelWithoutTracks",0.,"Lorentz shift correction factor when evaluating NN without track input."}
private

Definition at line 285 of file NnClusterizationFactory.h.

286{this, "correctLorShiftBarrelWithoutTracks",0.,"Lorentz shift correction factor when evaluating NN without track input."};

◆ m_correctLorShiftBarrelWithTracks

Gaudi::Property<double> InDet::NnClusterizationFactory::m_correctLorShiftBarrelWithTracks {this, "correctLorShiftBarrelWithTracks",0.,"Lorentz shift correction factor when evaluating NN with track input."}
private

Definition at line 288 of file NnClusterizationFactory.h.

289{this, "correctLorShiftBarrelWithTracks",0.,"Lorentz shift correction factor when evaluating NN with track input."};

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default).

Definition at line 393 of file AthCommonDataStore.h.

◆ m_doRunI

Gaudi::Property<bool> InDet::NnClusterizationFactory::m_doRunI {this, "doRunI", false, "Use runI style network (outputs are not normalised; add pitches; use charge if not m_useToT)"}
private

Definition at line 297 of file NnClusterizationFactory.h.

298{this, "doRunI", false, "Use runI style network (outputs are not normalised; add pitches; use charge if not m_useToT)"};

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default).

Definition at line 390 of file AthCommonDataStore.h.

◆ m_maxSubClusters

Gaudi::Property<unsigned int> InDet::NnClusterizationFactory::m_maxSubClusters {this, "MaxSubClusters", 3, "Maximum number of sub cluster supported by the networks." }
private

Definition at line 282 of file NnClusterizationFactory.h.

283{this, "MaxSubClusters", 3, "Maximum number of sub cluster supported by the networks." };

◆ m_NNId

std::vector< std::vector<unsigned int> > InDet::NnClusterizationFactory::m_NNId {}
private

Definition at line 232 of file NnClusterizationFactory.h.

232{};

◆ m_nnNames

const std::array< std::regex, NnClusterizationFactory::kNNetworkTypes > InDet::NnClusterizationFactory::m_nnNames
staticprivate
Initial value:
{
std::regex("^NumberParticles(|/|_.*)$"),
std::regex("^ImpactPoints([0-9])P(|/|_.*)$"),
std::regex("^ImpactPointErrorsX([0-9])(|/|_.*)$"),
std::regex("^ImpactPointErrorsY([0-9])(|/|_.*)$"),
}

Definition at line 229 of file NnClusterizationFactory.h.

◆ m_nnOrder

Gaudi::Property< std::vector<std::string> > InDet::NnClusterizationFactory::m_nnOrder
private
Initial value:
{this, "NetworkOrder", {
"NumberParticles",
"ImpactPoints1P",
"ImpactPoints2P",
"ImpactPoints3P",
"ImpactPointErrorsX1",
"ImpactPointErrorsX2",
"ImpactPointErrorsX3",
"ImpactPointErrorsY1",
"ImpactPointErrorsY2",
"ImpactPointErrorsY3"},
"The order in which the networks will appear in the TTrainedNetworkCollection"}

Definition at line 204 of file NnClusterizationFactory.h.

205 {this, "NetworkOrder", {
206 "NumberParticles",
207 "ImpactPoints1P",
208 "ImpactPoints2P",
209 "ImpactPoints3P",
210 "ImpactPointErrorsX1",
211 "ImpactPointErrorsX2",
212 "ImpactPointErrorsX3",
213 "ImpactPointErrorsY1",
214 "ImpactPointErrorsY2",
215 "ImpactPointErrorsY3"},
216 "The order in which the networks will appear in the TTrainedNetworkCollection"};

◆ m_nParticleGroup

std::array<unsigned int, kNNetworkTypes> InDet::NnClusterizationFactory::m_nParticleGroup {0U,1U,1U,1U}
staticconstexprprivate

Definition at line 228 of file NnClusterizationFactory.h.

228{0U,1U,1U,1U}; // unsigned int

◆ m_nParticleNNId

unsigned int InDet::NnClusterizationFactory::m_nParticleNNId {}
private

Definition at line 231 of file NnClusterizationFactory.h.

231{};

◆ m_outputNodesPos1

Gaudi::Property< std::size_t > InDet::NnClusterizationFactory::m_outputNodesPos1
private
Initial value:
{this, "OutputNodePos1", 7,
"Output node for the 1 position networks (LWTNN)"}

Definition at line 270 of file NnClusterizationFactory.h.

271 {this, "OutputNodePos1", 7,
272 "Output node for the 1 position networks (LWTNN)"};

◆ m_outputNodesPos2

Gaudi::Property< std::vector<std::size_t> > InDet::NnClusterizationFactory::m_outputNodesPos2
private
Initial value:
{this, "OutputNodePos2", { 10, 11 },
"List of output nodes for the 2 position network (LWTNN)"}

Definition at line 274 of file NnClusterizationFactory.h.

275 {this, "OutputNodePos2", { 10, 11 },
276 "List of output nodes for the 2 position network (LWTNN)"};

◆ m_outputNodesPos3

Gaudi::Property< std::vector<std::size_t> > InDet::NnClusterizationFactory::m_outputNodesPos3
private
Initial value:
{this, "OutputNodePos3", { 13, 14, 15 },
"List of output nodes for the 3 position networks (LWTNN)"}

Definition at line 278 of file NnClusterizationFactory.h.

279 {this, "OutputNodePos3", { 13, 14, 15 },
280 "List of output nodes for the 3 position networks (LWTNN)"};

◆ m_pixelLorentzAngleTool

ToolHandle<ISiLorentzAngleTool> InDet::NnClusterizationFactory::m_pixelLorentzAngleTool {this, "PixelLorentzAngleTool", "SiLorentzAngleTool/PixelLorentzAngleTool", "Tool to retreive Lorentz angle of Pixel"}
private

Definition at line 249 of file NnClusterizationFactory.h.

250{this, "PixelLorentzAngleTool", "SiLorentzAngleTool/PixelLorentzAngleTool", "Tool to retreive Lorentz angle of Pixel"};

◆ m_readKeyJSON

SG::ReadCondHandleKey<LWTNNCollection> InDet::NnClusterizationFactory::m_readKeyJSON
private
Initial value:
{this, "NnCollectionJSONReadKey", "PixelClusterNNJSON",
"The conditions key for the pixel cluster NNs configured via JSON file and accessed with lwtnn"}

Definition at line 262 of file NnClusterizationFactory.h.

263 {this, "NnCollectionJSONReadKey", "PixelClusterNNJSON",
264 "The conditions key for the pixel cluster NNs configured via JSON file and accessed with lwtnn"};

◆ m_readKeyONNX

SG::ReadCondHandleKey<OnnxNNCollection> InDet::NnClusterizationFactory::m_readKeyONNX
private
Initial value:
{this, "NnCollectionONNXReadKey", "",
"The conditions key for ONNX-based pixel cluster NNs"}

Definition at line 300 of file NnClusterizationFactory.h.

301 {this, "NnCollectionONNXReadKey", "",
302 "The conditions key for ONNX-based pixel cluster NNs"};

◆ m_readKeyWithoutTrack

SG::ReadCondHandleKey<TTrainedNetworkCollection> InDet::NnClusterizationFactory::m_readKeyWithoutTrack {this, "NnCollectionReadKey", "PixelClusterNN", "The conditions store key for the pixel cluster NNs"}
private

Definition at line 255 of file NnClusterizationFactory.h.

256{this, "NnCollectionReadKey", "PixelClusterNN", "The conditions store key for the pixel cluster NNs"};

◆ m_readKeyWithTrack

SG::ReadCondHandleKey<TTrainedNetworkCollection> InDet::NnClusterizationFactory::m_readKeyWithTrack
private
Initial value:
{this, "NnCollectionWithTrackReadKey", "PixelClusterNNWithTrack",
"The conditions store key for the pixel cluster NNs which needs tracks as input"}

Definition at line 258 of file NnClusterizationFactory.h.

259 {this, "NnCollectionWithTrackReadKey", "PixelClusterNNWithTrack",
260 "The conditions store key for the pixel cluster NNs which needs tracks as input"};

◆ m_sizeX

Gaudi::Property<unsigned int> InDet::NnClusterizationFactory::m_sizeX {this, "sizeX",7,"Size of pixel matrix along X"}
private

Definition at line 322 of file NnClusterizationFactory.h.

323{this, "sizeX",7,"Size of pixel matrix along X"};

◆ m_sizeY

Gaudi::Property<unsigned int> InDet::NnClusterizationFactory::m_sizeY {this, "sizeY",7,"Size of pixel matrix along Y"}
private

Definition at line 325 of file NnClusterizationFactory.h.

326{this, "sizeY",7,"Size of pixel matrix along Y"};

◆ m_useONNX

Gaudi::Property<bool> InDet::NnClusterizationFactory::m_useONNX {this, "useONNX", false, "Use ONNX models instead of LWTNN for NN inference."}
private

Definition at line 304 of file NnClusterizationFactory.h.

305{this, "useONNX", false, "Use ONNX models instead of LWTNN for NN inference."};

◆ m_useRecenteringNNWithouTracks

Gaudi::Property<bool> InDet::NnClusterizationFactory::m_useRecenteringNNWithouTracks {this, "useRecenteringNNWithoutTracks",false,"Recenter x position when evaluating NN without track input."}
private

Definition at line 310 of file NnClusterizationFactory.h.

311{this, "useRecenteringNNWithoutTracks",false,"Recenter x position when evaluating NN without track input."};

◆ m_useRecenteringNNWithTracks

Gaudi::Property<bool> InDet::NnClusterizationFactory::m_useRecenteringNNWithTracks {this, "useRecenteringNNWithTracks",false,"Recenter x position when evaluating NN with track input."}
private

Definition at line 313 of file NnClusterizationFactory.h.

314{this, "useRecenteringNNWithTracks",false,"Recenter x position when evaluating NN with track input."};

◆ m_useToT

Gaudi::Property<bool> InDet::NnClusterizationFactory::m_useToT {this, "useToT",true,"Use Tot rather than charge." }
private

Definition at line 291 of file NnClusterizationFactory.h.

292{this, "useToT",true,"Use Tot rather than charge." }; // @TODO toggle mode depending on whether a PxielCalibSvc is set ?

◆ m_useTTrainedNetworks

Gaudi::Property<bool> InDet::NnClusterizationFactory::m_useTTrainedNetworks {this, "useTTrainedNetworks", false, "Use earlier (release-21-like) neural networks stored in ROOT files and accessed via TTrainedNetowrk."}
private

Definition at line 307 of file NnClusterizationFactory.h.

308{this, "useTTrainedNetworks", false, "Use earlier (release-21-like) neural networks stored in ROOT files and accessed via TTrainedNetowrk."};

◆ m_useXPitches

Gaudi::Property<bool> InDet::NnClusterizationFactory::m_useXPitches
private
Initial value:
{this, "useXPitches", false,
"Also feed the phi-direction (X) pixel pitch vector as NN input "
"(ONNX only). Off by default so existing 60-input models are "
"unaffected; needs a (60 + sizeX)-input model when enabled."}

Definition at line 316 of file NnClusterizationFactory.h.

317 {this, "useXPitches", false,
318 "Also feed the phi-direction (X) pixel pitch vector as NN input "
319 "(ONNX only). Off by default so existing 60-input models are "
320 "unaffected; needs a (60 + sizeX)-input model when enabled."};

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.

◆ s_nnTypeNames

std::array<std::string_view, kNNetworkTypes> InDet::NnClusterizationFactory::s_nnTypeNames
staticconstexprprivate
Initial value:
{
"NumberParticlesNN",
"PositionNN",
"ErrorXNN",
"ErrorYNN" }

Definition at line 223 of file NnClusterizationFactory.h.

223 {
224 "NumberParticlesNN",
225 "PositionNN",
226 "ErrorXNN",
227 "ErrorYNN" };

The documentation for this class was generated from the following files: