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 774 of file NnClusterizationFactory.cxx.

777 {
778 input.useTrackInfo=true;
779 Amg::Vector3D particleDir = trackParsAtSurface.momentum().unit();
780 Amg::Vector3D localIntersection = pixelSurface.transform().inverse().linear() * particleDir;
781 localIntersection *= 0.250/cos(localIntersection.theta());
782 float trackDeltaX = (float)localIntersection.x();
783 float trackDeltaY = (float)localIntersection.y();
784 input.theta=std::atan2(trackDeltaY,0.250);
785 input.phi=std::atan2(trackDeltaX,0.250);
786 ATH_MSG_VERBOSE("Angle phi bef Lorentz corr: " << input.phi );
787 input.phi=std::atan(std::tan(input.phi)-tanl);
788 ATH_MSG_VERBOSE(" From track: angle phi: " << input.phi << " theta: " << input.theta );
789 }
#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 1016 of file NnClusterizationFactory.cxx.

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

◆ correctedRMS()

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

Definition at line 593 of file NnClusterizationFactory.cxx.

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

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

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

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

1099 {
1100
1101 std::vector<Amg::Vector2D> allPositions;
1102 if (numberSubClusters < 1 || numberSubClusters > static_cast<int>(m_maxSubClusters)) {
1103 return allPositions;
1104 }
1105
1106 SG::ReadCondHandle<OnnxNNCollection> onnxCollection(m_readKeyONNX);
1107 if (!onnxCollection.isValid()) {
1108 ATH_MSG_FATAL("Failed to get ONNX network collection with key " << m_readKeyONNX.key());
1109 return allPositions;
1110 }
1111 Ort::Session* posNet = nullptr;
1112 if (numberSubClusters == 1) posNet = onnxCollection->positionNetwork1.get();
1113 else if (numberSubClusters == 2) posNet = onnxCollection->positionNetwork2.get();
1114 else if (numberSubClusters == 3) posNet = onnxCollection->positionNetwork3.get();
1115
1116 if (!posNet) {
1117 ATH_MSG_FATAL("ONNX position network for " << numberSubClusters
1118 << " sub-clusters not found in collection");
1119 return allPositions;
1120 }
1121
1122 Ort::Session& session = *posNet;
1123
1124 // Get expected input dimension from the model
1125 auto inputTypeInfo = session.GetInputTypeInfo(0);
1126 auto tensorInfo = inputTypeInfo.GetTensorTypeAndShapeInfo();
1127 const int64_t expectedDim = tensorInfo.GetShape()[1];
1128
1129 // Convert input to float
1130 if (static_cast<int64_t>(input.size()) != expectedDim) {
1131 ATH_MSG_FATAL("ONNX position network (" << numberSubClusters
1132 << " sub-clusters) expects input dimension " << expectedDim
1133 << " but got " << input.size() << " — check model/configuration");
1134 return allPositions;
1135 }
1136 std::vector<float> inputData(expectedDim);
1137 for (int i = 0; i < expectedDim; ++i) {
1138 inputData[i] = static_cast<float>(input[i]);
1139 }
1140
1141 // Create input tensor
1142 Ort::MemoryInfo memInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
1143 std::vector<int64_t> inputShape = {1, expectedDim};
1144 Ort::Value inputTensor = Ort::Value::CreateTensor<float>(
1145 memInfo, inputData.data(), inputData.size(),
1146 inputShape.data(), inputShape.size());
1147 Ort::AllocatorWithDefaultOptions allocator;
1148 auto inputName = session.GetInputNameAllocated(0, allocator);
1149 auto outputName = session.GetOutputNameAllocated(0, allocator);
1150 const char* inputNames[] = {inputName.get()};
1151 const char* outputNames[] = {outputName.get()};
1152
1153 // Run inference
1154 auto outputTensors = session.Run(
1155 Ort::RunOptions{nullptr},
1156 inputNames, &inputTensor, 1,
1157 outputNames, 1);
1158
1159 // Extract output: expect [1, 5*numberSubClusters]
1160 // Format per sub-cluster: [alpha, mean_x, mean_y, prec_x, prec_y]
1161 const float* outputData = outputTensors[0].GetTensorData<float>();
1162
1163 std::vector<double> positionValues;
1164 positionValues.reserve(numberSubClusters * 2);
1165
1166 for (int iSub = 0; iSub < numberSubClusters; ++iSub) {
1167 const int offset = iSub * 5;
1168 // outputData[offset+0] = alpha (unused)
1169 const double mean_x = outputData[offset + 1];
1170 const double mean_y = outputData[offset + 2];
1171 const double prec_x = outputData[offset + 3];
1172 const double prec_y = outputData[offset + 4];
1173
1174 positionValues.push_back(mean_x);
1175 positionValues.push_back(mean_y);
1176
1177 // Convert precision to RMS and build error matrix
1178 if (prec_x <= 0 || prec_y <= 0) {
1179 ATH_MSG_WARNING("ONNX position network returned non-positive precision for sub-cluster "
1180 << iSub << " (prec_x=" << prec_x << ", prec_y=" << prec_y
1181 << "); using fallback RMS of 0.01");
1182 }
1183 const float rawRmsX = (prec_x > 0) ? std::sqrt(1.0f / prec_x) : 0.01f;
1184 const float rawRmsY = (prec_y > 0) ? std::sqrt(1.0f / prec_y) : 0.01f;
1185 const double rmsX = correctedRMS(rawRmsX, rawInput.vectorOfPitchesX, m_sizeX);
1186 const double rmsY = correctedRMS(rawRmsY, rawInput.vectorOfPitchesY, m_sizeY);
1187
1188 Amg::MatrixX erm(2, 2);
1189 erm.setZero();
1190 erm(0, 0) = rmsX * rmsX;
1191 erm(1, 1) = rmsY * rmsY;
1192 errors.push_back(std::move(erm));
1193 }
1194
1195 // Convert raw position outputs to detector coordinates
1196 allPositions = getPositionsFromOutput(positionValues, rawInput, pCluster);
1197 return allPositions;
1198 }
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(inputData);
479 inputDataNew.reserve( inputData.size() + nPositions);
480 inputDataNew.insert(inputDataNew.end(), position1P.begin(), position1P.begin() + nPositions);
481
482 // get error network id for the given cluster multiplicity then
483 // dereference unique_ptr<TTrainedNetwork> then call calculateOutput :
484 const auto xNetworkIndex = m_NNId[kErrorXNN-1].at(subClusterIndex);
485 const auto yNetworkIndex = m_NNId[kErrorYNN-1].at(subClusterIndex);
486 if ((not (xNetworkIndex < endNnIdx)) or (not (yNetworkIndex < endNnIdx))){
487 ATH_MSG_FATAL("estimatePositionsTTN: A requested collection index, "<< xNetworkIndex << " or "<< yNetworkIndex << "is out of range.");
488 return allPositions;
489 }
490 auto *pxNetwork = nn_collection.at(xNetworkIndex).get();
491 auto *pyNetwork = nn_collection.at(yNetworkIndex).get();
492 //call the selected member function of the TTrainedNetwork
493 std::vector<double> errors1PX = (*pxNetwork.*m_calculateOutput)(inputDataNew);
494 std::vector<double> errors1PY = (*pyNetwork.*m_calculateOutput)(inputDataNew);
495 //
496 std::vector<Amg::MatrixX> errorMatrices1;
497 getErrorMatrixFromOutput(errors1PX,errors1PY,errorMatrices1,numberSubClusters);
498 allPositions.reserve( allPositions.size() + myPosition1.size());
499 errors.reserve( errors.size() + myPosition1.size());
500 for (unsigned int i=0;i<myPosition1.size();i++){
501 allPositions.push_back(myPosition1[i]);
502 errors.push_back(errorMatrices1[i]);
503 }
504 }
505 return allPositions;
506 }
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 612 of file NnClusterizationFactory.cxx.

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

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