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