ATLAS Offline Software
NnClusterizationFactory.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
18 
19 
20 
21 #include "GaudiKernel/ITHistSvc.h"
25 
26 //for position estimate and clustering
34 
35 //get std::isnan()
36 #include <cmath>
37 #include <algorithm>
38 #include <limits>
39 
40 namespace {
41  std::pair<int, bool>
42  coerceToIntRange(double v){
43  constexpr double minint = std::numeric_limits<int>::min();
44  constexpr double maxint = std::numeric_limits<int>::max();
45  auto d = std::clamp(v, minint, maxint);
46 
47  return {static_cast<int>(d), d != v};
48  }
49 }
50 
51 
52 namespace InDet {
53  const std::array<std::regex, NnClusterizationFactory::kNNetworkTypes>
55  std::regex("^NumberParticles(|/|_.*)$"),
56  std::regex("^ImpactPoints([0-9])P(|/|_.*)$"),
57  std::regex("^ImpactPointErrorsX([0-9])(|/|_.*)$"),
58  std::regex("^ImpactPointErrorsY([0-9])(|/|_.*)$"),
59  };
60 
62  const std::string& n, const IInterface* p)
63  : AthAlgTool(name, n, p){
64  declareInterface<NnClusterizationFactory>(this);
65  }
66 
71  if (m_doRunI) {
73  } else {
75  }
76  // =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
78  m_NNId.clear();
79  m_NNId.resize( kNNetworkTypes -1 ) ;
80  // map networks to element in network collection
81  unsigned int nn_id=0;
82  std::smatch match_result;
83  for(const std::string &nn_name : m_nnOrder) {
84  ++nn_id;
85  for (unsigned int network_i=0; network_i<kNNetworkTypes; ++network_i) {
86  if (std::regex_match( nn_name, match_result, m_nnNames[network_i])) {
87  if (network_i == kNumberParticlesNN) {
88  m_nParticleNNId = nn_id;
89  } else {
90  if (m_nParticleGroup[network_i]>0) {
91  if (m_nParticleGroup[network_i]>=match_result.size()) {
92  ATH_MSG_ERROR("Regex and match group of particle multiplicity do not coincide (groups=" << match_result.size()
93  << " n particle group=" << m_nParticleGroup[network_i]
94  << "; type=" << network_i << ")");
95  }
96  int n_particles=std::stoi( match_result[m_nParticleGroup[network_i]].str());
97  if (n_particles<=0 or static_cast<unsigned int>(n_particles)>m_maxSubClusters) {
98  ATH_MSG_ERROR( "Failed to extract number of clusters the NN is meant for. Got " << match_result[m_nParticleGroup[network_i]].str()
99  << " But this is not in the valid range 1..." << m_maxSubClusters);
100  return StatusCode::FAILURE;
101  }
102  if (static_cast<unsigned int>(n_particles)>=m_NNId[network_i-1].size()) {
103  m_NNId[network_i-1].resize( n_particles );
104  }
105  m_NNId[network_i-1][n_particles-1] = nn_id;
106  } else {
107  if (m_NNId[network_i-1].empty()) {
108  m_NNId[network_i-1].resize(1);
109  }
110  m_NNId[network_i-1][0] = nn_id;
111  }
112  }
113  }
114  }
115  }
116  // check whether the NN IDs are all valid
117  // if valid decrease IDs by 1, because the ID is used as index in the NN collection.
118  if ((m_nParticleNNId==0) or (m_nParticleNNId>=m_nnOrder.size())) {
119  ATH_MSG_ERROR( "No NN specified to estimate the number of particles.");
120  return StatusCode::FAILURE;
121  }
122  --m_nParticleNNId;
123  ATH_MSG_VERBOSE("Expect NN " << s_nnTypeNames[0] << " at index " << m_nParticleNNId );
124  unsigned int type_i=0;
125  for (std::vector<unsigned int> &nn_id : m_NNId) {
126  ++type_i;
127  if (nn_id.empty()) {
128  ATH_MSG_ERROR( "No " << s_nnTypeNames[type_i] << " specified.");
129  return StatusCode::FAILURE;
130  }
131  if (m_nParticleGroup[type_i-1]>0 and nn_id.size() != m_maxSubClusters) {
132  ATH_MSG_ERROR( "Number of networks of type " << s_nnTypeNames[type_i] << " does match the maximum number of supported sub clusters " << m_maxSubClusters);
133  return StatusCode::FAILURE;
134  }
135  unsigned int n_particles=0;
136  for (unsigned int &a_nn_id : nn_id ) {
137  ++n_particles;
138  if ((a_nn_id==0) or (a_nn_id>m_nnOrder.size())) {
139  ATH_MSG_ERROR( "No " << s_nnTypeNames[type_i] << " specified for " << n_particles);
140  return StatusCode::FAILURE;
141  }
142  --a_nn_id;
143  ATH_MSG_VERBOSE("Expect NN " << s_nnTypeNames[type_i] << " for " << n_particles << " particle(s) at index " << a_nn_id );
144  }
145  }
149  return StatusCode::SUCCESS;
150  }
151 
152 
153  std::vector<double>
155  const auto vectorSize{calculateVectorDimension(input.useTrackInfo)};
156  const auto invalidValue{std::numeric_limits<double>::quiet_NaN()};
157  std::vector<double> inputData(vectorSize, invalidValue);
158  size_t vectorIndex{0};
159  for (unsigned int u=0;u<m_sizeX;u++){
160  for (unsigned int s=0;s<m_sizeY;s++){
161  inputData[vectorIndex++] = input.matrixOfToT[u][s];
162  }
163  }
164  for (unsigned int s=0;s<m_sizeY;s++){
165  inputData[vectorIndex++] = input.vectorOfPitchesY[s];
166  }
167  inputData[vectorIndex++] = input.ClusterPixLayer;
168  inputData[vectorIndex++] = input.ClusterPixBarrelEC;
169  inputData[vectorIndex++] = input.phi;
170  inputData[vectorIndex++] = input.theta;
171  if (not input.useTrackInfo) inputData[vectorIndex] = input.etaModule;
172  return inputData;
173  }
174 
175  std::vector<double>
177  const auto vectorSize{calculateVectorDimension(input.useTrackInfo)};
178  const auto invalidValue{std::numeric_limits<double>::quiet_NaN()};
179  std::vector<double> inputData(vectorSize, invalidValue);
180  size_t vectorIndex{0};
181  for (unsigned int u=0;u<m_sizeX;u++){
182  for (unsigned int s=0;s<m_sizeY;s++){
183  if (m_useToT){
184  inputData[vectorIndex++] = norm_rawToT(input.matrixOfToT[u][s]);
185  } else {
186  inputData[vectorIndex++] = norm_ToT(input.matrixOfToT[u][s]);
187  }
188  }
189  }
190  for (unsigned int s=0;s<m_sizeY;s++){
191  const double rawPitch(input.vectorOfPitchesY[s]);
192  const double normPitch(norm_pitch(rawPitch,m_addIBL));
193  if (std::isnan(normPitch)){
194  ATH_MSG_ERROR("NaN returned from norm_pitch, rawPitch = "<<rawPitch<<" addIBL = "<<m_addIBL);
195  }
196  inputData[vectorIndex++] = normPitch;
197  }
198  inputData[vectorIndex++] = norm_layerNumber(input.ClusterPixLayer);
199  inputData[vectorIndex++] = norm_layerType(input.ClusterPixBarrelEC);
200  if (input.useTrackInfo){
201  inputData[vectorIndex++] = norm_phi(input.phi);
202  inputData[vectorIndex] = norm_theta(input.theta);
203  } else {
204  inputData[vectorIndex++] = norm_phiBS(input.phi);
205  inputData[vectorIndex++] = norm_thetaBS(input.theta);
206  inputData[vectorIndex] = norm_etaModule(input.etaModule);
207  }
208  return inputData;
209  }
210 
213  // we know the size to be
214  // - m_sizeX x m_sizeY pixel ToT values
215  // - m_sizeY pitch sizes in y
216  // - 2 values: detector location
217  // - 2 values: track incidence angles
218  // - optional: eta module
219  const auto vecSize{calculateVectorDimension(input.useTrackInfo)};
220  Eigen::VectorXd valuesVector( vecSize );
221  // Fill it!
222  // Variable names here need to match the ones in the configuration...
223  // ...IN THE SAME ORDER!!!
224  // location in eigen matrix object where next element goes
225  int location(0);
226  for (const auto & xvec: input.matrixOfToT){
227  for (const auto & xyElement : xvec){
228  valuesVector[location++] = xyElement;
229  }
230  }
231  for (const auto & pitch : input.vectorOfPitchesY) {
232  valuesVector[location++] = pitch;
233  }
234  valuesVector[location] = input.ClusterPixLayer;
235  location++;
236  valuesVector[location] = input.ClusterPixBarrelEC;
237  location++;
238  valuesVector[location] = input.phi;
239  location++;
240  valuesVector[location] = input.theta;
241  location++;
242  if (!input.useTrackInfo) {
243  valuesVector[location] = input.etaModule;
244  location++;
245  }
246  // We have only one node for now, so we just store things there.
247  // Format for use with lwtnn
248  std::vector<Eigen::VectorXd> vectorOfEigen;
249  vectorOfEigen.push_back(valuesVector);
250  return vectorOfEigen;
251  }
252 
253  std::vector<double>
255  Amg::Vector3D & beamSpotPosition) const{
256  double tanl=0;
257  NNinput input( createInput(pCluster,beamSpotPosition,tanl) );
258  if (!input) return {};
259  // If using old TTrainedNetworks, fetch correct ones for the
260  // without-track situation and call them now.
261  if (m_useTTrainedNetworks) {
262  const std::vector<double> & inputData=(this->*m_assembleInput)(input);
264  if (!nn_collection.isValid()) {
265  ATH_MSG_FATAL( "Failed to get trained network collection with key " << m_readKeyWithoutTrack.key() );
266  return {};
267  }
268  return estimateNumberOfParticlesTTN(**nn_collection, inputData);
269  }
270  // Otherwise, prepare lwtnn input map and use new networks.
271  NnClusterizationFactory::InputVector nnInputVector = eigenInput(input);
272  return estimateNumberOfParticlesLWTNN(nnInputVector);
273  }
274 
275  std::vector<double>
277  const Trk::Surface& pixelSurface,
278  const Trk::TrackParameters& trackParsAtSurface) const{
279  Amg::Vector3D dummyBS(0,0,0);
280  double tanl=0;
281  NNinput input( createInput(pCluster,dummyBS,tanl) );
282 
283  if (!input) return {};
284  addTrackInfoToInput(input,pixelSurface,trackParsAtSurface,tanl);
285  std::vector<double> inputData=(this->*m_assembleInput)(input);
286  // If using old TTrainedNetworks, fetch correct ones for the
287  // with-track situation and call them now.
288  if (m_useTTrainedNetworks) {
290  if (!nn_collection.isValid()) {
291  ATH_MSG_FATAL( "Failed to get trained network collection with key " << m_readKeyWithoutTrack.key() );
292  return {};
293  }
294  return estimateNumberOfParticlesTTN(**nn_collection, inputData);
295  }
296  // Otherwise, prepare lwtnn input map and use new networks.
297  NnClusterizationFactory::InputVector nnInputVector = eigenInput(input);
298  return estimateNumberOfParticlesLWTNN(nnInputVector);
299  }
300 
301  std::vector<double>
303  const std::vector<double>& inputData) const{
304  ATH_MSG_DEBUG("Using TTN number network");
305  std::vector<double> resultNN_TTN{};
306  if (not (m_nParticleNNId < nn_collection.size())){ //note: m_nParticleNNId is unsigned
307  ATH_MSG_FATAL("NnClusterizationFactory::estimateNumberOfParticlesTTN: Index "<<m_nParticleNNId<< "is out of range.");
308  return resultNN_TTN;
309  }
310  auto *const pNetwork = nn_collection[m_nParticleNNId].get();
311  if (not pNetwork){
312  ATH_MSG_FATAL("NnClusterizationFactory::estimateNumberOfParticlesTTN: nullptr returned for TrainedNetwork");
313  return resultNN_TTN;
314  }
315  // dereference unique_ptr<TTrainedNetwork> then call calculateOutput :
316  resultNN_TTN = (*pNetwork.*m_calculateOutput)(inputData);
317  ATH_MSG_VERBOSE(" TTN Prob of n. particles (1): " << resultNN_TTN[0] <<
318  " (2): " << resultNN_TTN[1] <<
319  " (3): " << resultNN_TTN[2]);
320  return resultNN_TTN;
321  }
322 
323 
324  std::vector<double>
326  std::vector<double> result(3,0.0);//ok as invalid result?
328  if (!lwtnn_collection.isValid()) {
329  ATH_MSG_FATAL( "Failed to get LWTNN network collection with key " << m_readKeyJSON.key() );
330  return result;
331  }
332  if (lwtnn_collection->empty()){
333  ATH_MSG_FATAL( "LWTNN network collection with key " << m_readKeyJSON.key()<<" is empty." );
334  return result;
335  }
336  ATH_MSG_DEBUG("Using lwtnn number network");
337  // Order of output matches order in JSON config in "outputs"
338  // Only 1 node here, simple compute function
339  Eigen::VectorXd discriminant = lwtnn_collection->at(0)->compute(input);
340  const double & num0 = discriminant[0];
341  const double & num1 = discriminant[1];
342  const double & num2 = discriminant[2];
343  // Get normalized predictions
344  const auto inverseSum = 1./(num0+num1+num2);
345  result[0] = num0 * inverseSum;
346  result[1] = num1 * inverseSum;
347  result[2] = num2 * inverseSum;
348  ATH_MSG_VERBOSE(" LWTNN Prob of n. particles (1): " << result[0] <<
349  " (2): " << result[1] <<
350  " (3): " << result[2]);
351  return result;
352  }
353 
354 
355  std::vector<Amg::Vector2D>
357  Amg::Vector3D & beamSpotPosition,
358  std::vector<Amg::MatrixX> & errors,
359  int numberSubClusters) const{
360  ATH_MSG_VERBOSE(" Starting to estimate positions...");
361  double tanl=0;
362  NNinput input( createInput(pCluster,beamSpotPosition,tanl) );
363  if (!input){
364  return {};
365  }
366  // If using old TTrainedNetworks, fetch correct ones for the
367  // without-track situation and call them now.
368  if (m_useTTrainedNetworks) {
369  const std::vector<double> & inputData=(this->*m_assembleInput)(input);
371  if (!nn_collection.isValid()) {
372  ATH_MSG_FATAL( "Failed to get trained network collection with key " << m_readKeyWithoutTrack.key() );
373  return {};
374  }
375  // *(ReadCondHandle<>) returns a pointer rather than a reference ...
376  return estimatePositionsTTN(**nn_collection, inputData,input,pCluster,numberSubClusters,errors);
377  }
378  // Otherwise, prepare lwtnn input map and use new networks.
379  NnClusterizationFactory::InputVector nnInputVector = eigenInput(input);
380  return estimatePositionsLWTNN(nnInputVector,input,pCluster,numberSubClusters,errors);
381  }
382 
383 
384  std::vector<Amg::Vector2D>
386  const Trk::Surface& pixelSurface,
387  const Trk::TrackParameters& trackParsAtSurface,
388  std::vector<Amg::MatrixX> & errors,
389  int numberSubClusters) const{
390  ATH_MSG_VERBOSE(" Starting to estimate positions...");
391  Amg::Vector3D dummyBS(0,0,0);
392  double tanl=0;
393  NNinput input( createInput(pCluster, dummyBS, tanl) );
394  if (!input) return {};
395  addTrackInfoToInput(input,pixelSurface,trackParsAtSurface,tanl);
396  // If using old TTrainedNetworks, fetch correct ones for the
397  // without-track situation and call them now.
398  if (m_useTTrainedNetworks) {
399  std::vector<double> inputData=(this->*m_assembleInput)(input);
401  if (!nn_collection.isValid()) {
402  ATH_MSG_FATAL( "Failed to get trained network collection with key " << m_readKeyWithTrack.key() );
403  return {};
404  }
405  return estimatePositionsTTN(**nn_collection, inputData,input,pCluster,numberSubClusters,errors);
406  }
407  // Otherwise, prepare lwtnn input map and use new networks.
408  NnClusterizationFactory::InputVector nnInputVector = eigenInput(input);
409  return estimatePositionsLWTNN(nnInputVector,input,pCluster,numberSubClusters,errors);
410  }
411 
412  std::vector<Amg::Vector2D>
414  const std::vector<double>& inputData,
415  const NNinput& input,
416  const InDet::PixelCluster& pCluster,
417  int numberSubClusters,
418  std::vector<Amg::MatrixX> & errors) const{
419  bool applyRecentering=(!input.useTrackInfo and m_useRecenteringNNWithouTracks) or (input.useTrackInfo and m_useRecenteringNNWithTracks);
420  std::vector<Amg::Vector2D> allPositions{};
421  const auto endNnIdx = nn_collection.size();
422  if (numberSubClusters>0 and static_cast<unsigned int>(numberSubClusters) < m_maxSubClusters) {
423  const auto subClusterIndex = numberSubClusters-1;
424  // get position network id for the given cluster multiplicity then
425  // dereference unique_ptr<TTrainedNetwork> then call calculateOutput :
426  const auto networkIndex = m_NNId[kPositionNN-1].at(subClusterIndex);
427  //TTrainedNetworkCollection inherits from std::vector
428  if (not(networkIndex < endNnIdx)){
429  ATH_MSG_FATAL("estimatePositionsTTN: Requested collection index, "<< networkIndex << " is out of range.");
430  return allPositions;
431  }
432  auto *const pNetwork = nn_collection[networkIndex].get();
433  std::vector<double> position1P = (*pNetwork.*m_calculateOutput)(inputData);
434  std::vector<Amg::Vector2D> myPosition1=getPositionsFromOutput(position1P,input,pCluster);
435  assert( position1P.size() % 2 == 0);
436  for (unsigned int i=0; i<position1P.size()/2 ; ++i) {
437  ATH_MSG_DEBUG(" Original RAW Estimated positions (" << i << ") x: " << back_posX(position1P[0+i*2],applyRecentering) << " y: " << back_posY(position1P[1+i*2]));
438  ATH_MSG_DEBUG(" Original estimated myPositions (" << i << ") x: " << myPosition1[i][Trk::locX] << " y: " << myPosition1[i][Trk::locY]);
439  }
440  std::vector<double> inputDataNew=inputData;
441  inputDataNew.reserve( inputDataNew.size() + numberSubClusters*2);
442  assert( static_cast<unsigned int>(numberSubClusters*2) <= position1P.size() );
443  for (unsigned int i=0; i<static_cast<unsigned int>(numberSubClusters*2); ++i) {
444  inputDataNew.push_back(position1P[i]);
445  }
446  // get error network id for the given cluster multiplicity then
447  // dereference unique_ptr<TTrainedNetwork> then call calculateOutput :
448  const auto xNetworkIndex = m_NNId[kErrorXNN-1].at(subClusterIndex);
449  const auto yNetworkIndex = m_NNId[kErrorYNN-1].at(subClusterIndex);
450  if ((not (xNetworkIndex < endNnIdx)) or (not (yNetworkIndex < endNnIdx))){
451  ATH_MSG_FATAL("estimatePositionsTTN: A requested collection index, "<< xNetworkIndex << " or "<< yNetworkIndex << "is out of range.");
452  return allPositions;
453  }
454  auto *pxNetwork = nn_collection.at(xNetworkIndex).get();
455  auto *pyNetwork = nn_collection.at(yNetworkIndex).get();
456  //call the selected member function of the TTrainedNetwork
457  std::vector<double> errors1PX = (*pxNetwork.*m_calculateOutput)(inputDataNew);
458  std::vector<double> errors1PY = (*pyNetwork.*m_calculateOutput)(inputDataNew);
459  //
460  std::vector<Amg::MatrixX> errorMatrices1;
461  getErrorMatrixFromOutput(errors1PX,errors1PY,errorMatrices1,numberSubClusters);
462  allPositions.reserve( allPositions.size() + myPosition1.size());
463  errors.reserve( errors.size() + myPosition1.size());
464  for (unsigned int i=0;i<myPosition1.size();i++){
465  allPositions.push_back(myPosition1[i]);
466  errors.push_back(errorMatrices1[i]);
467  }
468  }
469  return allPositions;
470  }
471 
472 
473  std::vector<Amg::Vector2D>
475  NNinput& rawInput,
476  const InDet::PixelCluster& pCluster,
477  int numberSubClusters,
478  std::vector<Amg::MatrixX> & errors) const {
480  if (not lwtnn_collection.isValid()) {
481  ATH_MSG_FATAL( "Failed to get LWTNN network collection with key " << m_readKeyJSON.key() );
482  return {};
483  }
484  if (lwtnn_collection->empty()){
485  ATH_MSG_FATAL( "estimatePositionsLWTNN: LWTNN network collection with key " << m_readKeyJSON.key()<<" is empty." );
486  return {};
487  }
488  // Need to evaluate the correct network once per cluster we're interested in.
489  // Save the output
490  std::vector<double> positionValues{};
491  std::vector<Amg::MatrixX> errorMatrices;
492  errorMatrices.reserve(numberSubClusters);
493  positionValues.reserve(numberSubClusters * 2);
494  std::size_t outputNode(0);
495  for (int cluster = 1; cluster < numberSubClusters+1; cluster++) {
496  // Check that the network is defined.
497  // If not, we are outside an IOV and should fail
498  const auto pNetwork = lwtnn_collection->find(numberSubClusters);
499  const bool validGraph = (pNetwork != lwtnn_collection->end()) and (pNetwork->second != nullptr);
500  if (not validGraph) {
501  std::string infoMsg ="Acceptable numbers of subclusters for the lwtnn collection:\n ";
502  for (const auto & pair: **lwtnn_collection){
503  infoMsg += std::to_string(pair.first) + "\n ";
504  }
505  infoMsg += "\nNumber of subclusters requested : "+ std::to_string(numberSubClusters);
506  ATH_MSG_DEBUG(infoMsg);
507  ATH_MSG_FATAL( "estimatePositionsLWTNN: No lwtnn network found for the number of clusters.\n"
508  <<" If you are outside the valid range for an lwtnn-based configuration, please run with useNNTTrainedNetworks instead.\n Key = "
509  << m_readKeyJSON.key() );
510  return {};
511  }
512  if(numberSubClusters==1) {
513  outputNode = m_outputNodesPos1;
514  } else if(numberSubClusters==2) {
515  outputNode = m_outputNodesPos2[cluster-1];
516  } else if(numberSubClusters==3) {
517  outputNode = m_outputNodesPos3[cluster-1];
518  } else {
519  ATH_MSG_FATAL( "Cannot evaluate LWTNN networks with " << numberSubClusters << " numberSubClusters" );
520  return {};
521  }
522 
523  // Order of output matches order in JSON config in "outputs"
524  // "alpha", "mean_x", "mean_y", "prec_x", "prec_y"
525  // Assume here that 1 particle network is in position 1, 2 at 2, and 3 at 3.
526  Eigen::VectorXd position = lwtnn_collection->at(numberSubClusters)->compute(input, {}, outputNode);
527  ATH_MSG_DEBUG("Testing for numberSubClusters " << numberSubClusters << " and cluster " << cluster);
528  for (int i=0; i<position.rows(); i++) {
529  ATH_MSG_DEBUG(" position " << position[i]);
530  }
531  positionValues.push_back(position[1]); //mean_x
532  positionValues.push_back(position[2]); //mean_y
533  // Fill errors.
534  // Values returned by NN are inverse of variance, and we want variances.
535  const float rawRmsX = std::sqrt(1.0/position[3]); //prec_x
536  const float rawRmsY = std::sqrt(1.0/position[4]); //prec_y
537  // Now convert to real space units
538  const double rmsX = correctedRMSX(rawRmsX);
539  const double rmsY = correctedRMSY(rawRmsY, rawInput.vectorOfPitchesY);
540  ATH_MSG_DEBUG(" Estimated RMS errors (1) x: " << rmsX << ", y: " << rmsY);
541  // Fill matrix
542  Amg::MatrixX erm(2,2);
543  erm.setZero();
544  erm(0,0)=rmsX*rmsX;
545  erm(1,1)=rmsY*rmsY;
546  errorMatrices.push_back(erm);
547  }
548  std::vector<Amg::Vector2D> myPositions = getPositionsFromOutput(positionValues,rawInput,pCluster);
549  ATH_MSG_DEBUG(" Estimated myPositions (1) x: " << myPositions[0][Trk::locX] << " y: " << myPositions[0][Trk::locY]);
550  errors=std::move(errorMatrices);
551  return myPositions;
552  }
553 
554  double
556  // This gives location in pixels
557  constexpr double pitch = 0.05;
558  const double corrected = posPixels * pitch;
559  return corrected;
560  }
561 
562  double
564  std::vector<float>& pitches) const{
565  double p = posPixels + (m_sizeY - 1) * 0.5;
566  double p_Y = -100;
567  double p_center = -100;
568  double p_actual = 0;
569  for (unsigned int i = 0; i < m_sizeY; i++) {
570  if (p >= i and p <= (i + 1)) p_Y = p_actual + (p - i + 0.5) * pitches.at(i);
571  if (i == (m_sizeY - 1) / 2) p_center = p_actual + 0.5 * pitches.at(i);
572  p_actual += pitches.at(i);
573  }
574  return std::abs(p_Y - p_center);
575  }
576 
577  void
579  std::vector<double>& outputY,
580  std::vector<Amg::MatrixX>& errorMatrix,
581  int nParticles) const{
582  int sizeOutputX=outputX.size()/nParticles;
583  int sizeOutputY=outputY.size()/nParticles;
584  double minimumX=-errorHalfIntervalX(nParticles);
585  double maximumX=errorHalfIntervalX(nParticles);
586  double minimumY=-errorHalfIntervalY(nParticles);
587  double maximumY=errorHalfIntervalY(nParticles);
588  //X=0...sizeOutput-1
589  //Y=minimum+(maximum-minimum)/sizeOutput*(X+1./2.)
590  errorMatrix.reserve( errorMatrix.size() + nParticles);
591  for (int i=0;i<nParticles;i++){
592  double sumValuesX=0;
593  for (int u=0;u<sizeOutputX;u++){
594  sumValuesX+=outputX[i*sizeOutputX+u];
595  }
596  double sumValuesY=0;
597  for (int u=0;u<sizeOutputY;u++){
598  sumValuesY+=outputY[i*sizeOutputY+u];
599  }
600  ATH_MSG_VERBOSE(" minimumX: " << minimumX << " maximumX: " << maximumX << " sizeOutputX " << sizeOutputX);
601  ATH_MSG_VERBOSE(" minimumY: " << minimumY << " maximumY: " << maximumY << " sizeOutputY " << sizeOutputY);
602  double RMSx=0;
603  for (int u=0;u<sizeOutputX;u++){
604  RMSx+=outputX[i*sizeOutputX+u]/sumValuesX*std::pow(minimumX+(maximumX-minimumX)/(double)(sizeOutputX-2)*(u-1./2.),2);
605  }
606  RMSx=std::sqrt(RMSx);//computed error!
607  ATH_MSG_VERBOSE(" first Iter RMSx: " << RMSx);
608  double intervalErrorX=3*RMSx;
609  //now recompute between -3*RMSx and +3*RMSx
610  int minBinX=(int)(1+(-intervalErrorX-minimumX)/(maximumX-minimumX)*(double)(sizeOutputX-2));
611  int maxBinX=(int)(1+(intervalErrorX-minimumX)/(maximumX-minimumX)*(double)(sizeOutputX-2));
612  if (maxBinX>sizeOutputX-1) maxBinX=sizeOutputX-1;
613  if (minBinX<0) minBinX=0;
614  ATH_MSG_VERBOSE(" minBinX: " << minBinX << " maxBinX: " << maxBinX );
615  RMSx=0;
616  for (int u=minBinX;u<maxBinX+1;u++){
617  RMSx+=outputX[i*sizeOutputX+u]/sumValuesX*std::pow(minimumX+(maximumX-minimumX)/(double)(sizeOutputX-2)*(u-1./2.),2);
618  }
619  RMSx=std::sqrt(RMSx);//computed error!
620  double RMSy=0;
621  for (int u=0;u<sizeOutputY;u++){
622  RMSy+=outputY[i*sizeOutputY+u]/sumValuesY*std::pow(minimumY+(maximumY-minimumY)/(double)(sizeOutputY-2)*(u-1./2.),2);
623  }
624  RMSy=std::sqrt(RMSy);//computed error!
625  ATH_MSG_VERBOSE("first Iter RMSy: " << RMSy );
626  double intervalErrorY=3*RMSy;
627  //now recompute between -3*RMSy and +3*RMSy
628  int minBinY=(int)(1+(-intervalErrorY-minimumY)/(maximumY-minimumY)*(double)(sizeOutputY-2));
629  int maxBinY=(int)(1+(intervalErrorY-minimumY)/(maximumY-minimumY)*(double)(sizeOutputY-2));
630  if (maxBinY>sizeOutputY-1) maxBinY=sizeOutputY-1;
631  if (minBinY<0) minBinY=0;
632  ATH_MSG_VERBOSE("minBinY: " << minBinY << " maxBinY: " << maxBinY );
633  RMSy=0;
634  for (int u=minBinY;u<maxBinY+1;u++){
635  RMSy+=outputY[i*sizeOutputY+u]/sumValuesY*std::pow(minimumY+(maximumY-minimumY)/(double)(sizeOutputY-2)*(u-1./2.),2);
636  }
637  RMSy=std::sqrt(RMSy);//computed error!
638  ATH_MSG_VERBOSE("Computed error, sigma(X) " << RMSx << " sigma(Y) " << RMSy );
639  Amg::MatrixX erm(2,2);
640  erm.setZero();
641  erm(0,0)=RMSx*RMSx;
642  erm(1,1)=RMSy*RMSy;
643  errorMatrix.push_back(erm);
644  }//end nParticles
645  }//getErrorMatrixFromOutput
646 
647 
648  std::vector<Amg::Vector2D>
650  const NNinput & input,
651  const InDet::PixelCluster& pCluster) const{
652  ATH_MSG_VERBOSE(" Translating output back into a position " );
653  const InDetDD::SiDetectorElement* element=pCluster.detectorElement();//DEFINE
654  const InDetDD::PixelModuleDesign* design
655  (dynamic_cast<const InDetDD::PixelModuleDesign*>(&element->design()));
656  if (not design){
657  ATH_MSG_ERROR("Dynamic cast failed at line "<<__LINE__<<" of NnClusterizationFactory.cxx.");
658  return {};
659  }
660  int numParticles=output.size()/2;
661  int columnWeightedPosition=input.columnWeightedPosition;
662  int rowWeightedPosition=input.rowWeightedPosition;
663  ATH_MSG_VERBOSE(" REF POS columnWeightedPos: " << columnWeightedPosition << " rowWeightedPos: " << rowWeightedPosition );
664  bool applyRecentering=false;
665  if (m_useRecenteringNNWithouTracks and (not input.useTrackInfo)){
666  applyRecentering=true;
667  }
668  if (m_useRecenteringNNWithTracks and input.useTrackInfo){
669  applyRecentering=true;
670  }
671  std::vector<Amg::Vector2D> positions;
672  for (int u=0;u<numParticles;u++){
673  double posXid{};
674  double posYid{};
675  if(m_doRunI){
676  posXid=back_posX(output[2*u],applyRecentering)+rowWeightedPosition;
677  posYid=back_posY(output[2*u+1])+columnWeightedPosition;
678  }else{
679  posXid=output[2*u]+rowWeightedPosition;
680  posYid=output[2*u+1]+columnWeightedPosition;
681  }
682  ATH_MSG_VERBOSE(" N. particle: " << u << " idx posX " << posXid << " posY " << posYid );
683  //ATLASRECTS-7155 : Pixel Charge Calibration needs investigating
684  const auto & [posXid_int, coercedX]=coerceToIntRange(posXid+0.5);
685  const auto & [posYid_int, coercedY]=coerceToIntRange(posYid+0.5);
686  if (coercedX or coercedY){
687  ATH_MSG_WARNING("X or Y position value has been limited in range; original values are (" << posXid<<", "<<posYid<<")");
688  //we cannot skip these values, it seems client code relies on the size of input vector and output vector being the same
689  }
690  ATH_MSG_VERBOSE(" N. particle: " << u << " TO INTEGER idx posX " << posXid_int << " posY " << posYid_int );
691  InDetDD::SiLocalPosition siLocalPositionDiscrete(design->positionFromColumnRow(posYid_int,posXid_int));
692  InDetDD::SiCellId cellIdOfPositionDiscrete=design->cellIdOfPosition(siLocalPositionDiscrete);
693  if ( not cellIdOfPositionDiscrete.isValid()){
694  ATH_MSG_WARNING(" Cell is outside validity region with index Y: " << posYid_int << " and index X: " << posXid_int << ". Not foreseen... " );
695  }
696  InDetDD::SiDiodesParameters diodeParameters = design->parameters(cellIdOfPositionDiscrete);
697  double pitchY = diodeParameters.width().xEta();
698  double pitchX = diodeParameters.width().xPhi();
699  ATH_MSG_VERBOSE(" Translated weighted position : " << siLocalPositionDiscrete.xPhi()
700  << " Translated weighted position : " << siLocalPositionDiscrete.xEta() );
701  //FOR TEST
702  InDetDD::SiLocalPosition siLocalPositionDiscreteOneRowMoreOneColumnMore(design->positionFromColumnRow(posYid_int+1,posXid_int+1));
703  ATH_MSG_VERBOSE(" Translated weighted position +1col +1row phi: " << siLocalPositionDiscreteOneRowMoreOneColumnMore.xPhi()
704  << " Translated weighted position +1col +1row eta: " << siLocalPositionDiscreteOneRowMoreOneColumnMore.xEta() );
705  ATH_MSG_VERBOSE("PitchY: " << pitchY << " pitchX " << pitchX );
706  InDetDD::SiLocalPosition siLocalPositionAdd(pitchY*(posYid-(double)posYid_int),
707  pitchX*(posXid-(double)posXid_int));
708  double lorentzShift=m_pixelLorentzAngleTool->getLorentzShift(element->identifyHash(), Gaudi::Hive::currentContext());
709  if (input.ClusterPixBarrelEC == 0){
710  if (not input.useTrackInfo){
712  } else {
713  lorentzShift+=m_correctLorShiftBarrelWithTracks;
714  }
715  }
716 
718  siLocalPosition(siLocalPositionDiscrete.xEta()+pitchY*(posYid-(double)posYid_int),
719  siLocalPositionDiscrete.xPhi()+pitchX*(posXid-(double)posXid_int)+lorentzShift);
720  ATH_MSG_VERBOSE(" Translated final position phi: " << siLocalPosition.xPhi() << " eta: " << siLocalPosition.xEta() );
721  const auto halfWidth{design->width()*0.5};
722  if (siLocalPositionDiscrete.xPhi() > halfWidth){
723  siLocalPosition=InDetDD::SiLocalPosition(siLocalPositionDiscrete.xEta()+pitchY*(posYid-(double)posYid_int),
724  halfWidth-1e-6);
725  ATH_MSG_WARNING(" Corrected out of boundary cluster from x(phi): " << siLocalPositionDiscrete.xPhi()+pitchX*(posXid-(double)posXid_int)
726  << " to: " << halfWidth-1e-6);
727  } else if (siLocalPositionDiscrete.xPhi() < -halfWidth) {
728  siLocalPosition=InDetDD::SiLocalPosition(siLocalPositionDiscrete.xEta()+pitchY*(posYid-(double)posYid_int),
729  -halfWidth+1e-6);
730  ATH_MSG_WARNING(" Corrected out of boundary cluster from x(phi): " << siLocalPositionDiscrete.xPhi()+pitchX*(posXid-(double)posXid_int)
731  << " to: " << -halfWidth+1e-6);
732  }
733  positions.emplace_back(siLocalPosition);
734  }//iterate over all particles
735  return positions;
736  }
737 
738 
739  void
741  const Trk::Surface& pixelSurface, // pixelSurface = pcot->associatedSurface();
742  const Trk::TrackParameters& trackParsAtSurface,
743  const double tanl) const {
744  input.useTrackInfo=true;
745  Amg::Vector3D particleDir = trackParsAtSurface.momentum().unit();
746  Amg::Vector3D localIntersection = pixelSurface.transform().inverse().linear() * particleDir;
747  localIntersection *= 0.250/cos(localIntersection.theta());
748  float trackDeltaX = (float)localIntersection.x();
749  float trackDeltaY = (float)localIntersection.y();
750  input.theta=std::atan2(trackDeltaY,0.250);
751  input.phi=std::atan2(trackDeltaX,0.250);
752  ATH_MSG_VERBOSE("Angle phi bef Lorentz corr: " << input.phi );
753  input.phi=std::atan(std::tan(input.phi)-tanl);
754  ATH_MSG_VERBOSE(" From track: angle phi: " << input.phi << " theta: " << input.theta );
755  }
756 
757 
758  NNinput
760  Amg::Vector3D & beamSpotPosition,
761  double & tanl) const{
762  NNinput input;
763  ATH_MSG_VERBOSE(" Starting creating input from cluster " );
764  const InDetDD::SiDetectorElement* element=pCluster.detectorElement();
765  if (not element) {
766  ATH_MSG_ERROR("Could not get detector element");
767  return input;
768  }
769  const AtlasDetectorID* aid = element->getIdHelper();
770  if (not aid){
771  ATH_MSG_ERROR("Could not get ATLASDetectorID");
772  return input;
773  }
774 
775  if (aid->helper() != AtlasDetectorID::HelperType::Pixel){
776  ATH_MSG_ERROR("Could not get PixelID pointer");
777  return input;
778  }
779  const PixelID* pixelIDp=static_cast<const PixelID*>(aid);
780  const PixelID& pixelID = *pixelIDp;
781  const InDetDD::PixelModuleDesign* design
782  (dynamic_cast<const InDetDD::PixelModuleDesign*>(&element->design()));
783  if (not design){
784  ATH_MSG_ERROR("Dynamic cast failed at line "<<__LINE__<<" of NnClusterizationFactory.cxx.");
785  return input;
786  }
788  const PixelChargeCalibCondData *calibData = *calibDataHandle;
789  const std::vector<Identifier>& rdos = pCluster.rdoList();
790  const size_t rdoSize = rdos.size();
791  ATH_MSG_VERBOSE(" Number of RDOs: " << rdoSize );
792  const std::vector<float>& chList = pCluster.chargeList();
793  const std::vector<int>& totList = pCluster.totList();
794  std::vector<float> chListRecreated{};
795  chListRecreated.reserve(rdoSize);
796  ATH_MSG_VERBOSE(" Number of charges: " << chList.size() );
797  std::vector<int>::const_iterator tot = totList.begin();
798  std::vector<Identifier>::const_iterator rdosBegin = rdos.begin();
799  std::vector<Identifier>::const_iterator rdosEnd = rdos.end();
800  std::vector<int> totListRecreated{};
801  totListRecreated.reserve(rdoSize);
802  std::vector<int>::const_iterator totRecreated = totListRecreated.begin();
803  // Recreate both charge list and ToT list to correct for the IBL ToT overflow (and later for small hits):
804  ATH_MSG_VERBOSE("Charge list is not filled ... re-creating it.");
805  IdentifierHash moduleHash = element->identifyHash(); // wafer hash
806 
807  for ( ; rdosBegin!= rdosEnd and tot != totList.end(); ++tot, ++rdosBegin, ++totRecreated ){
808  // recreate the charge: should be a method of the calibSvc
809  int tot0 = *tot;
810  Identifier pixid = *rdosBegin;
811  assert( element->identifyHash() == pixelID.wafer_hash(pixelID.wafer_id(pixid)));
812 
813  std::array<InDetDD::PixelDiodeTree::CellIndexType,2> diode_idx
815  pixelID.eta_index(pixid));
816  InDetDD::PixelDiodeTree::DiodeProxy si_param ( design->diodeProxyFromIdx(diode_idx));
817  std::uint32_t feValue = design->getFE(si_param);
818  auto diode_type = design->getDiodeType(si_param);
819  if ( design->getReadoutTechnology() == InDetDD::PixelReadoutTechnology::FEI3
820  && design->numberOfConnectedCells( design->readoutIdOfCell(InDetDD::SiCellId(diode_idx[0],diode_idx[1])))>1) {
821  diode_type = InDetDD::PixelDiodeType::GANGED;
822  }
823 
824  float charge = calibData->getCharge(diode_type, moduleHash, feValue, tot0);
825  chListRecreated.push_back(charge);
826  totListRecreated.push_back(tot0);
827  }
828  // reset the rdo iterator
829  rdosBegin = rdos.begin();
830  rdosEnd = rdos.end();
831  // and the tot iterator
832  tot = totList.begin();
833  totRecreated = totListRecreated.begin();
834  // Always use recreated charge and ToT lists:
835  std::vector<float>::const_iterator charge = chListRecreated.begin();
836  std::vector<float>::const_iterator chargeEnd = chListRecreated.end();
837  tot = totListRecreated.begin();
838  std::vector<int>::const_iterator totEnd = totListRecreated.end();
839  InDetDD::SiLocalPosition sumOfWeightedPositions(0,0,0);
840  double sumOfTot=0;
841  int rowMin = 999;
842  int rowMax = 0;
843  int colMin = 999;
844  int colMax = 0;
845  for (; (rdosBegin!= rdosEnd) and (charge != chargeEnd) and (tot != totEnd); ++rdosBegin, ++charge, ++tot){
846  Identifier rId = *rdosBegin;
847  int row = pixelID.phi_index(rId);
848  int col = pixelID.eta_index(rId);
849  InDetDD::SiLocalPosition siLocalPosition (design->positionFromColumnRow(col,row));
850  if (not m_useToT){
851  sumOfWeightedPositions += (*charge)*siLocalPosition;
852  sumOfTot += (*charge);
853  } else {
854  sumOfWeightedPositions += ((double)(*tot))*siLocalPosition;
855  sumOfTot += (double)(*tot);
856  }
857  rowMin = std::min(row, rowMin);
858  rowMax = std::max(row, rowMax);
859  colMin = std::min(col, colMin);
860  colMax = std::max(col, colMax);
861 
862  }
863  sumOfWeightedPositions /= sumOfTot;
864  //what you want to know is simple:
865  //just the row and column of this average position!
866  InDetDD::SiCellId cellIdWeightedPosition=design->cellIdOfPosition(sumOfWeightedPositions);
867 
868  if (!cellIdWeightedPosition.isValid()){
869  ATH_MSG_WARNING(" Weighted position is on invalid CellID." );
870  }
871  int columnWeightedPosition=cellIdWeightedPosition.etaIndex();
872  int rowWeightedPosition=cellIdWeightedPosition.phiIndex();
873  ATH_MSG_VERBOSE(" weighted pos row: " << rowWeightedPosition << " col: " << columnWeightedPosition );
874  int centralIndexX=(m_sizeX-1)/2;
875  int centralIndexY=(m_sizeY-1)/2;
876  if (std::abs(rowWeightedPosition-rowMin)>centralIndexX or
877  std::abs(rowWeightedPosition-rowMax)>centralIndexX){
878  ATH_MSG_VERBOSE(" Cluster too large rowMin" << rowMin << " rowMax " << rowMax << " centralX " << centralIndexX);
879  return input;
880  }
881  if (std::abs(columnWeightedPosition-colMin)>centralIndexY or
882  std::abs(columnWeightedPosition-colMax)>centralIndexY){
883  ATH_MSG_VERBOSE(" Cluster too large colMin" << colMin << " colMax " << colMax << " centralY " << centralIndexY);
884  return input;
885  }
886  input.matrixOfToT.reserve(m_sizeX);
887  for (unsigned int a=0;a<m_sizeX;a++){
888  input.matrixOfToT.emplace_back(m_sizeY, 0.0);
889  }
890  input.vectorOfPitchesY.assign(m_sizeY, 0.4);
891  rdosBegin = rdos.begin();
892  charge = chListRecreated.begin();
893  chargeEnd = chListRecreated.end();
894  tot = totListRecreated.begin();
895  ATH_MSG_VERBOSE(" Putting together the n. " << rdos.size() << " rdos into a matrix." );
896  Identifier pixidentif=pCluster.identify();
897  input.etaModule=(int)pixelID.eta_module(pixidentif);
898  input.ClusterPixLayer=(int)pixelID.layer_disk(pixidentif);
899  input.ClusterPixBarrelEC=(int)pixelID.barrel_ec(pixidentif);
900  for (;( charge != chargeEnd) and (rdosBegin!= rdosEnd); ++rdosBegin, ++charge, ++tot){
901  Identifier rId = *rdosBegin;
902  unsigned int absrow = pixelID.phi_index(rId)-rowWeightedPosition+centralIndexX;
903  unsigned int abscol = pixelID.eta_index(rId)-columnWeightedPosition+centralIndexY;
904  if (absrow > m_sizeX){
905  ATH_MSG_WARNING(" problem with index: " << absrow << " min: " << 0 << " max: " << m_sizeX);
906  return input;
907  }
908  if (abscol > m_sizeY){
909  ATH_MSG_WARNING(" problem with index: " << abscol << " min: " << 0 << " max: " << m_sizeY);
910  return input;
911  }
912  InDetDD::SiCellId cellId = element->cellIdFromIdentifier(*rdosBegin);
913  InDetDD::SiDiodesParameters diodeParameters = design->parameters(cellId);
914  double pitchY = diodeParameters.width().xEta();
915  if (not m_useToT) {
916  input.matrixOfToT[absrow][abscol]=*charge;
917  } else {
918  input.matrixOfToT[absrow][abscol]=(double)(*tot);
919  // in case to RunI setup to make IBL studies
920  if(m_doRunI){
921  if (m_addIBL and (input.ClusterPixLayer==0) and (input.ClusterPixBarrelEC==0)){
922  input.matrixOfToT[absrow][abscol]*=3;
923  }
924  }else{
925  // for RunII IBL is always present
926  if ( (input.ClusterPixLayer==0) and (input.ClusterPixBarrelEC==0)){
927  input.matrixOfToT[absrow][abscol]*=3;
928  }
929  }
930 
931  }
932  if (std::abs(pitchY-0.4)>1e-5){
933  input.vectorOfPitchesY[abscol]=pitchY;
934  }
935  }//end iteration on rdos
936  ATH_MSG_VERBOSE(" eta module: " << input.etaModule );
937  ATH_MSG_VERBOSE(" Layer number: " << input.ClusterPixLayer << " Barrel / endcap: " << input.ClusterPixBarrelEC );
938  input.useTrackInfo=false;
939  const Amg::Vector2D& prdLocPos = pCluster.localPosition();
940  InDetDD::SiLocalPosition centroid(prdLocPos);
941  Amg::Vector3D globalPos = element->globalPosition(centroid);
942  Amg::Vector3D my_track = globalPos-beamSpotPosition;
943  const Amg::Vector3D &my_normal = element->normal();
944  const Amg::Vector3D &my_phiax = element->phiAxis();
945  const Amg::Vector3D &my_etaax = element->etaAxis();
946  float trkphicomp = my_track.dot(my_phiax);
947  float trketacomp = my_track.dot(my_etaax);
948  float trknormcomp = my_track.dot(my_normal);
949  double bowphi = std::atan2(trkphicomp,trknormcomp);
950  double boweta = std::atan2(trketacomp,trknormcomp);
951  tanl = m_pixelLorentzAngleTool->getTanLorentzAngle(element->identifyHash(), Gaudi::Hive::currentContext());
952  if(bowphi > M_PI_2) bowphi -= M_PI;
953  if(bowphi < -M_PI_2) bowphi += M_PI;
954  int readoutside = design->readoutSide();
955  double angle = std::atan(std::tan(bowphi)-readoutside*tanl);
956  input.phi=angle;
957  ATH_MSG_VERBOSE(" Angle theta bef corr: " << boweta );
958  if (boweta>M_PI_2) boweta-=M_PI;
959  if (boweta<-M_PI_2) boweta+=M_PI;
960  input.theta=boweta;
961  ATH_MSG_VERBOSE(" Angle phi: " << angle << " theta: " << boweta );
962  input.rowWeightedPosition=rowWeightedPosition;
963  input.columnWeightedPosition=columnWeightedPosition;
964  ATH_MSG_VERBOSE(" RowWeightedPosition: " << rowWeightedPosition << " ColWeightedPosition: " << columnWeightedPosition );
965  return input;
966  }//end create NNinput function
967 
968  size_t
970  return (m_sizeX * m_sizeY) + m_sizeY + (useTrackInfo ? 4 : 5);
971  }
972 }//end InDet namespace
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
InDet::NnClusterizationFactory::m_sizeX
Gaudi::Property< unsigned int > m_sizeX
Definition: NnClusterizationFactory.h:298
norm_etaModule
double norm_etaModule(const double input)
Definition: NnNormalization.cxx:101
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
TTrainedNetwork::calculateOutputValues
std::vector< Double_t > calculateOutputValues(std::vector< Double_t > &input) const
Definition: InnerDetector/InDetCalibAlgs/PixelCalibAlgs/NNClusteringCalibration_RunI/TTrainedNetwork.cxx:99
PixelID::phi_index
int phi_index(const Identifier &id) const
Definition: PixelID.h:639
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:27
get_generator_info.result
result
Definition: get_generator_info.py:21
InDet::NnClusterizationFactory::m_addIBL
Gaudi::Property< bool > m_addIBL
Definition: NnClusterizationFactory.h:283
InDet::NnClusterizationFactory::m_nParticleGroup
static constexpr std::array< unsigned int, kNNetworkTypes > m_nParticleGroup
Definition: NnClusterizationFactory.h:216
InDet::NnClusterizationFactory::m_chargeDataKey
SG::ReadCondHandleKey< PixelChargeCalibCondData > m_chargeDataKey
Definition: NnClusterizationFactory.h:241
InDet::NnClusterizationFactory::estimateNumberOfParticles
std::vector< double > estimateNumberOfParticles(const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition) const
Definition: NnClusterizationFactory.cxx:254
CondAttrListCollection.h
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
SG::ReadCondHandle
Definition: ReadCondHandle.h:40
Trk::locX
@ locX
Definition: ParamDefs.h:37
InDet::NnClusterizationFactory::m_outputNodesPos1
Gaudi::Property< std::size_t > m_outputNodesPos1
Definition: NnClusterizationFactory.h:259
norm_rawToT
double norm_rawToT(const double input)
Definition: NnNormalization.cxx:16
InDetDD::PixelModuleDesign
Definition: PixelModuleDesign.h:45
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:38
TTrainedNetworkCollection
Definition: TTrainedNetworkCollection.h:14
AtlasDetectorID::HelperType::Pixel
@ Pixel
InDet::NnClusterizationFactory::m_NNId
std::vector< std::vector< unsigned int > > m_NNId
Definition: NnClusterizationFactory.h:220
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
PixelCluster.h
PixelID::barrel_ec
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
Definition: PixelID.h:600
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
InDet::NnClusterizationFactory::initialize
virtual StatusCode initialize() override
Definition: NnClusterizationFactory.cxx:67
hist_file_dump.d
d
Definition: hist_file_dump.py:142
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
InDet
Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
norm_pitch
double norm_pitch(const double input, bool addIBL=false)
Definition: NnNormalization.cxx:32
InDetDD::SiCellId::isValid
bool isValid() const
Test if its in a valid state.
Definition: SiCellId.h:136
InDet::NnClusterizationFactory::estimatePositionsTTN
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
Definition: NnClusterizationFactory.cxx:413
M_PI
#define M_PI
Definition: ActiveFraction.h:11
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:206
Trk::PrepRawData::rdoList
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
InDetDD::PixelReadoutTechnology::FEI3
@ FEI3
norm_phi
double norm_phi(const double input)
Definition: NnNormalization.cxx:71
InDet::NNinput
Definition: NnClusterizationFactory.h:69
keylayer_zslicemap.row
row
Definition: keylayer_zslicemap.py:155
InDet::NnClusterizationFactory::m_maxSubClusters
Gaudi::Property< unsigned int > m_maxSubClusters
Definition: NnClusterizationFactory.h:271
InDetDD::SiCellId::phiIndex
int phiIndex() const
Get phi index. Equivalent to strip().
Definition: SiCellId.h:122
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
InDet::NnClusterizationFactory::eigenInput
InputVector eigenInput(NNinput &input) const
Definition: NnClusterizationFactory.cxx:212
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
MuonR4::to_string
std::string to_string(const SectorProjector proj)
Definition: MsTrackSeeder.cxx:66
InDet::NnClusterizationFactory::m_nnNames
static const std::array< std::regex, kNNetworkTypes > m_nnNames
Definition: NnClusterizationFactory.h:217
norm_theta
double norm_theta(const double input)
Definition: NnNormalization.cxx:79
InDet::NnClusterizationFactory::addTrackInfoToInput
void addTrackInfoToInput(NNinput &input, const Trk::Surface &pixelSurface, const Trk::TrackParameters &trackParsAtSurface, const double tanl) const
Definition: NnClusterizationFactory.cxx:740
InDet::NnClusterizationFactory::estimatePositionsLWTNN
std::vector< Amg::Vector2D > estimatePositionsLWTNN(NnClusterizationFactory::InputVector &input, NNinput &rawInput, const InDet::PixelCluster &pCluster, int numberSubClusters, std::vector< Amg::MatrixX > &errors) const
Definition: NnClusterizationFactory.cxx:474
ParamDefs.h
InDet::PixelCluster::totList
const std::vector< int > & totList() const
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:202
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
InDetDD::PixelDiodeType::GANGED
@ GANGED
InDetDD::SolidStateDetectorElementBase::identifyHash
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
PixelID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: PixelID.h:360
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
InDet::NnClusterizationFactory::m_assembleInput
std::vector< double >(InDet::NnClusterizationFactory::* m_assembleInput)(NNinput &input) const
Definition: NnClusterizationFactory.h:224
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
InDetDD::SiLocalPosition
Definition: SiLocalPosition.h:31
InDet::NnClusterizationFactory::assembleInputRunI
std::vector< double > assembleInputRunI(NNinput &input) const
Definition: NnClusterizationFactory.cxx:176
InDetDD::SiLocalPosition::xPhi
double xPhi() const
position along phi direction:
Definition: SiLocalPosition.h:123
InDet::NnClusterizationFactory::m_useTTrainedNetworks
Gaudi::Property< bool > m_useTTrainedNetworks
Definition: NnClusterizationFactory.h:289
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
InDet::NnClusterizationFactory::m_readKeyJSON
SG::ReadCondHandleKey< LWTNNCollection > m_readKeyJSON
Definition: NnClusterizationFactory.h:251
InDet::NnClusterizationFactory::correctedRMSX
static double correctedRMSX(double posPixels)
Definition: NnClusterizationFactory.cxx:555
InDet::NnClusterizationFactory::getPositionsFromOutput
std::vector< Amg::Vector2D > getPositionsFromOutput(std::vector< double > &output, const NNinput &input, const InDet::PixelCluster &pCluster) const
Definition: NnClusterizationFactory.cxx:649
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
InDetDD::SiCellId::etaIndex
int etaIndex() const
Get eta index.
Definition: SiCellId.h:114
PixelID::wafer_hash
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition: PixelID.h:383
norm_layerNumber
double norm_layerNumber(const double input)
Definition: NnNormalization.cxx:57
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
InDet::NnClusterizationFactory::getErrorMatrixFromOutput
void getErrorMatrixFromOutput(std::vector< double > &outputX, std::vector< double > &outputY, std::vector< Amg::MatrixX > &errorMatrix, int nParticles) const
Definition: NnClusterizationFactory.cxx:578
InDetDD::SiLocalPosition::xEta
double xEta() const
position along eta direction:
Definition: SiLocalPosition.h:118
mergePhysValFiles.errors
list errors
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:42
beamspotman.n
n
Definition: beamspotman.py:727
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:71
PixelChargeCalibCondData
Definition: PixelChargeCalibCondData.h:24
python.CaloAddPedShiftConfig.str
str
Definition: CaloAddPedShiftConfig.py:42
back_posY
double back_posY(const double input)
Definition: NnNormalization.cxx:122
InDet::NnClusterizationFactory::m_readKeyWithTrack
SG::ReadCondHandleKey< TTrainedNetworkCollection > m_readKeyWithTrack
Definition: NnClusterizationFactory.h:247
TTrainedNetwork::calculateNormalized
DVec calculateNormalized(const DVec &input) const
Definition: Tracking/TrkUtilityPackages/TrkNeuralNetworkUtils/src/TTrainedNetwork.cxx:267
norm_ToT
double norm_ToT(const double input)
Definition: NnNormalization.cxx:24
PixelID::eta_index
int eta_index(const Identifier &id) const
Definition: PixelID.h:645
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
InDet::NnClusterizationFactory::kPositionNN
@ kPositionNN
Definition: NnClusterizationFactory.h:207
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
Trk::ParametersBase
Definition: ParametersBase.h:55
InDet::NnClusterizationFactory::s_nnTypeNames
static constexpr std::array< std::string_view, kNNetworkTypes > s_nnTypeNames
Definition: NnClusterizationFactory.h:211
norm_layerType
double norm_layerType(const double input)
Definition: NnNormalization.cxx:64
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
InDet::NnClusterizationFactory::estimateNumberOfParticlesTTN
std::vector< double > estimateNumberOfParticlesTTN(const TTrainedNetworkCollection &nn_collection, const std::vector< double > &inputData) const
Definition: NnClusterizationFactory.cxx:302
SiLocalPosition.h
InDet::SiCluster::detectorElement
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...
TTrainedNetwork.h
norm_phiBS
double norm_phiBS(const double input)
Definition: NnNormalization.cxx:86
Trk::PrepRawData::identify
Identifier identify() const
return the identifier
InDet::NnClusterizationFactory::m_readKeyWithoutTrack
SG::ReadCondHandleKey< TTrainedNetworkCollection > m_readKeyWithoutTrack
Definition: NnClusterizationFactory.h:244
PixelID::layer_disk
int layer_disk(const Identifier &id) const
Definition: PixelID.h:607
InDet::NnClusterizationFactory::m_useRecenteringNNWithTracks
Gaudi::Property< bool > m_useRecenteringNNWithTracks
Definition: NnClusterizationFactory.h:295
InDet::NnClusterizationFactory::NnClusterizationFactory
NnClusterizationFactory(const std::string &name, const std::string &n, const IInterface *p)
Definition: NnClusterizationFactory.cxx:61
PixelID::eta_module
int eta_module(const Identifier &id) const
Definition: PixelID.h:632
errorHalfIntervalY
double errorHalfIntervalY(const int nParticles)
Definition: NnNormalization.cxx:144
PixelCalibrationConfig.tot
tot
Definition: PixelCalibrationConfig.py:28
TauJetParameters::discriminant
@ discriminant
Definition: TauJetParameters.h:166
InDet::NnClusterizationFactory::m_nParticleNNId
unsigned int m_nParticleNNId
Definition: NnClusterizationFactory.h:219
InDet::NnClusterizationFactory::m_useToT
Gaudi::Property< bool > m_useToT
Definition: NnClusterizationFactory.h:280
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
Trk::PrepRawData::localPosition
const Amg::Vector2D & localPosition() const
return the local position reference
InDet::NnClusterizationFactory::correctedRMSY
double correctedRMSY(double posPixels, std::vector< float > &pitches) const
Definition: NnClusterizationFactory.cxx:563
charge
double charge(const T &p)
Definition: AtlasPID.h:997
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
InDet::NnClusterizationFactory::m_correctLorShiftBarrelWithoutTracks
Gaudi::Property< double > m_correctLorShiftBarrelWithoutTracks
Definition: NnClusterizationFactory.h:274
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
InDet::NnClusterizationFactory::estimateNumberOfParticlesLWTNN
std::vector< double > estimateNumberOfParticlesLWTNN(NnClusterizationFactory::InputVector &input) const
Definition: NnClusterizationFactory.cxx:325
InDet::NNinput::vectorOfPitchesY
std::vector< float > vectorOfPitchesY
Definition: NnClusterizationFactory.h:76
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
InDet::NnClusterizationFactory::m_pixelLorentzAngleTool
ToolHandle< ISiLorentzAngleTool > m_pixelLorentzAngleTool
Definition: NnClusterizationFactory.h:238
SiDetectorElement.h
InDet::NnClusterizationFactory::kNumberParticlesNN
@ kNumberParticlesNN
Definition: NnClusterizationFactory.h:206
back_posX
double back_posX(const double input, const bool recenter=false)
Definition: NnNormalization.cxx:113
InDetDD::SiCellId
Definition: SiCellId.h:29
InDet::PixelCluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:49
errorHalfIntervalX
double errorHalfIntervalX(const int nParticles)
Definition: NnNormalization.cxx:140
python.PyAthena.v
v
Definition: PyAthena.py:154
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
a
TList * a
Definition: liststreamerinfos.cxx:10
InDet::NnClusterizationFactory::m_outputNodesPos3
Gaudi::Property< std::vector< std::size_t > > m_outputNodesPos3
Definition: NnClusterizationFactory.h:267
NnClusterizationFactory.h
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
InDet::NnClusterizationFactory::m_correctLorShiftBarrelWithTracks
Gaudi::Property< double > m_correctLorShiftBarrelWithTracks
Definition: NnClusterizationFactory.h:277
InDet::NnClusterizationFactory::m_sizeY
Gaudi::Property< unsigned int > m_sizeY
Definition: NnClusterizationFactory.h:301
InDetDD::PixelDiodeTree::DiodeProxy
Helper class to access parameters of a diode.
Definition: PixelDiodeTree.h:183
InDet::NnClusterizationFactory::m_calculateOutput
ReturnType(::TTrainedNetwork::* m_calculateOutput)(const InputType &input) const
Definition: NnClusterizationFactory.h:235
InDet::NnClusterizationFactory::assembleInputRunII
std::vector< double > assembleInputRunII(NNinput &input) const
Definition: NnClusterizationFactory.cxx:154
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
PixelModuleDesign.h
InDet::NnClusterizationFactory::m_useRecenteringNNWithouTracks
Gaudi::Property< bool > m_useRecenteringNNWithouTracks
Definition: NnClusterizationFactory.h:292
InDet::NnClusterizationFactory::kNNetworkTypes
@ kNNetworkTypes
Definition: NnClusterizationFactory.h:210
InDet::NnClusterizationFactory::m_nnOrder
Gaudi::Property< std::vector< std::string > > m_nnOrder
Definition: NnClusterizationFactory.h:193
InDet::NnClusterizationFactory::calculateVectorDimension
size_t calculateVectorDimension(const bool useTrackInfo) const
Definition: NnClusterizationFactory.cxx:969
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
InDetDD::SiDiodesParameters::width
const SiLocalPosition & width() const
width of the diodes:
Definition: SiDiodesParameters.h:96
InDet::NnClusterizationFactory::m_outputNodesPos2
Gaudi::Property< std::vector< std::size_t > > m_outputNodesPos2
Definition: NnClusterizationFactory.h:263
PixelChargeCalibCondData::getCharge
float getCharge(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float ToT) const
Definition: PixelChargeCalibCondData.cxx:223
InDet::NnClusterizationFactory::m_doRunI
Gaudi::Property< bool > m_doRunI
Definition: NnClusterizationFactory.h:286
NnNormalization.h
InDetDD::PixelDiodeTree::makeCellIndex
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.
Definition: PixelDiodeTree.h:320
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
InDet::NnClusterizationFactory::kErrorYNN
@ kErrorYNN
Definition: NnClusterizationFactory.h:209
InDet::NnClusterizationFactory::InputVector
std::vector< Eigen::VectorXd > InputVector
Definition: NnClusterizationFactory.h:126
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:79
InDet::NnClusterizationFactory::estimatePositions
std::vector< Amg::Vector2D > estimatePositions(const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition, std::vector< Amg::MatrixX > &errors, int numberSubClusters) const
Definition: NnClusterizationFactory.cxx:356
PixelID
Definition: PixelID.h:67
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
InDet::NnClusterizationFactory::createInput
NNinput createInput(const InDet::PixelCluster &pCluster, Amg::Vector3D &beamSpotPosition, double &tanl) const
Definition: NnClusterizationFactory.cxx:759
norm_thetaBS
double norm_thetaBS(const double input)
Definition: NnNormalization.cxx:94
AtlasDetectorID
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
Definition: AtlasDetectorID.h:52
InDet::NnClusterizationFactory::kErrorXNN
@ kErrorXNN
Definition: NnClusterizationFactory.h:208
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65
InDet::PixelCluster::chargeList
const std::vector< float > & chargeList() const
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:210
InDetDD::SiDiodesParameters
Definition: SiDiodesParameters.h:25
Identifier
Definition: IdentifierFieldParser.cxx:14