CMS 3D CMS Logo

HitPatternHelper.cc
Go to the documentation of this file.
1 //
2 // Created by J.Li on 1/23/21.
3 //
4 
8 
10 
11 #include <algorithm>
12 #include <cmath>
13 
14 namespace hph {
15 
16  Setup::Setup(const edm::ParameterSet& iConfig, const tt::Setup& setupTT)
17  : iConfig_(iConfig),
18  setupTT_(setupTT),
19  layerIds_(),
20  layermap_(),
21  nEtaRegions_(tmtt::KFbase::nEta_ / 2),
22  nKalmanLayers_(tmtt::KFbase::nKFlayer_) {
23  for (const tt::SensorModule& sm : setupTT_.sensorModules()) {
24  layerIds_.push_back(std::make_pair(sm.layerId(), sm.barrel()));
25  }
26  sort(layerIds_.begin(), layerIds_.end(), smallerID);
27  layerIds_.erase(unique(layerIds_.begin(), layerIds_.end(), equalID), layerIds_.end()); //Keep only unique layerIds
28  // Converting tmtt::KFbase::layerMap_ to a format that is acceptatble by HitPatternHelper
29  for (int i = 0; i < nEtaRegions_; i++) {
30  for (int j = 0; j < (int)layerIds_.size(); j++) {
31  int layer;
32  if (layerIds_[j].second) {
34  } else {
36  }
37  if (layer < nKalmanLayers_) {
38  layermap_[i][layer].push_back(layerIds_[j].first);
39  }
40  }
41  }
42  }
43 
44  HitPatternHelper::HitPatternHelper(const Setup* setup, int hitpattern, double cot, double z0)
45  : hitpattern_(hitpattern),
46  numExpLayer_(0),
47  numMissingLayer_(0),
48  numMissingPS_(0),
49  numMissing2S_(0),
50  numPS_(0),
51  num2S_(0),
52  numMissingInterior1_(0),
53  numMissingInterior2_(0),
54  cot_(cot),
55  z0_(z0),
56  setup_(setup),
57  binary_(11, 0),
58  hphDebug_(setup_->hphDebug()),
59  useNewKF_(setup_->useNewKF()),
60  chosenRofZ_(setup_->chosenRofZ()),
61  deltaTanL_(setup_->deltaTanL()),
62  etaRegions_(setup_->etaRegions()),
63  nKalmanLayers_(setup_->nKalmanLayers()),
64  layermap_(setup_->layermap()) {
65  //Calculating eta sector based on cot and z0
66  float kfzRef = z0_ + chosenRofZ_ * cot_;
67  int kf_eta_reg = 0;
68  for (int iEtaSec = 1; iEtaSec < ((int)etaRegions_.size() - 1); iEtaSec++) { // Doesn't apply eta < 2.4 cut.
69  float etaMax = etaRegions_[iEtaSec];
70  float zRefMax = chosenRofZ_ / tan(2. * atan(exp(-etaMax)));
71  if (kfzRef > zRefMax) {
72  kf_eta_reg = iEtaSec;
73  }
74  }
75  etaSector_ = kf_eta_reg;
76  if (kf_eta_reg < ((int)etaRegions_.size() - 1) / 2) {
77  kf_eta_reg = ((int)etaRegions_.size() - 1) / 2 - 1 - kf_eta_reg;
78  } else {
79  kf_eta_reg = kf_eta_reg - (int)(etaRegions_.size() - 1) / 2;
80  }
81  //Looping over sensor modules to make predictions on which layers particles are expected to hit
82  for (const tt::SensorModule& sm : setup_->sensorModules()) {
83  double d = (z0_ - sm.z() + sm.r() * cot_) / (sm.cosTilt() - sm.sinTilt() * cot_);
84  double d_p =
85  (z0_ - sm.z() + sm.r() * (cot_ + deltaTanL_ / 2)) / (sm.cosTilt() - sm.sinTilt() * (cot_ + deltaTanL_ / 2));
86  double d_m =
87  (z0_ - sm.z() + sm.r() * (cot_ - deltaTanL_ / 2)) / (sm.cosTilt() - sm.sinTilt() * (cot_ - deltaTanL_ / 2));
88  if (useNewKF_ &&
89  (abs(d_p) < sm.numColumns() * sm.pitchCol() / 2. || abs(d_m) < sm.numColumns() * sm.pitchCol() / 2.)) {
90  layers_.push_back(sm);
91  }
92  if (!useNewKF_ && abs(d) < sm.numColumns() * sm.pitchCol() / 2.) {
93  layers_.push_back(sm);
94  }
95  }
96  //layers_ constains all the sensor modules that particles are expected to hit
97  sort(layers_.begin(), layers_.end(), smallerID);
98  layers_.erase(unique(layers_.begin(), layers_.end(), equalID), layers_.end()); //Keep only one sensor per layer
99 
100  numExpLayer_ = layers_.size();
101 
102  int nbits = floor(log2(hitpattern_)) + 1;
103  int lay_i = 0;
104  bool seq = false;
105  for (int i = 0; i < nbits; i++) {
106  lay_i = ((1 << i) & hitpattern_) >> i; //0 or 1 in ith bit (right to left)
107 
108  if (lay_i && !seq)
109  seq = true; //sequence starts when first 1 found
110  if (!lay_i && seq) {
111  numMissingInterior1_++; //This is the same as the "tmp_trk_nlaymiss_interior" calculated in Trackquality.cc
112  }
113  if (!lay_i) {
114  bool realhit = false;
115  if (layermap_[kf_eta_reg][i].empty())
116  continue;
117  for (int j : layermap_[kf_eta_reg][i]) {
118  int k = findLayer(j);
119  if (k > 0)
120  realhit = true;
121  }
122  if (realhit)
123  numMissingInterior2_++; //This variable doesn't make sense for new KF because it uses the layermap from Old KF
124  }
125  }
126 
127  if (hphDebug_) {
128  if (useNewKF_) {
129  edm::LogVerbatim("TrackTriggerHPH") << "Running with New KF";
130  } else {
131  edm::LogVerbatim("TrackTriggerHPH") << "Running with Old KF";
132  }
133  edm::LogVerbatim("TrackTriggerHPH") << "======================================================";
134  edm::LogVerbatim("TrackTriggerHPH")
135  << "Looking at hitpattern " << std::bitset<7>(hitpattern_) << "; Looping over KF layers:";
136  }
137 
138  if (useNewKF_) {
139  //New KF uses sensor modules to determine the hitmask already
140  for (int i = 0; i < numExpLayer_; i++) {
141  if (hphDebug_) {
142  edm::LogVerbatim("TrackTriggerHPH") << "--------------------------";
143  edm::LogVerbatim("TrackTriggerHPH") << "Looking at KF layer " << i;
144  if (layers_[i].layerId() < 10) {
145  edm::LogVerbatim("TrackTriggerHPH") << "KF expects L" << layers_[i].layerId();
146  } else {
147  edm::LogVerbatim("TrackTriggerHPH") << "KF expects D" << layers_[i].layerId() - 10;
148  }
149  }
150 
151  if (((1 << i) & hitpattern_) >> i) {
152  if (hphDebug_) {
153  edm::LogVerbatim("TrackTriggerHPH") << "Layer found in hitpattern";
154  }
155 
156  binary_[ReducedId(layers_[i].layerId())] = 1;
157  if (layers_[i].psModule()) {
158  numPS_++;
159  } else {
160  num2S_++;
161  }
162  } else {
163  if (hphDebug_) {
164  edm::LogVerbatim("TrackTriggerHPH") << "Layer missing in hitpattern";
165  }
166 
167  if (layers_[i].psModule()) {
168  numMissingPS_++;
169  } else {
170  numMissing2S_++;
171  }
172  }
173  }
174 
175  } else {
176  //Old KF uses the hard coded layermap to determien hitmask
177  for (int i = 0; i < nKalmanLayers_; i++) { //Loop over each digit of hitpattern
178 
179  if (hphDebug_) {
180  edm::LogVerbatim("TrackTriggerHPH") << "--------------------------";
181  edm::LogVerbatim("TrackTriggerHPH") << "Looking at KF layer " << i;
182  }
183 
184  if (layermap_[kf_eta_reg][i].empty()) {
185  if (hphDebug_) {
186  edm::LogVerbatim("TrackTriggerHPH") << "KF does not expect this layer";
187  }
188 
189  continue;
190  }
191 
192  for (int j :
193  layermap_[kf_eta_reg][i]) { //Find out which layer the Old KF is dealing with when hitpattern is encoded
194 
195  if (hphDebug_) {
196  if (j < 10) {
197  edm::LogVerbatim("TrackTriggerHPH") << "KF expects L" << j;
198  } else {
199  edm::LogVerbatim("TrackTriggerHPH") << "KF expects D" << j - 10;
200  }
201  }
202 
203  int k = findLayer(j);
204  if (k < 0) {
205  //k<0 means even though layer j is predicted by Old KF, this prediction is rejected because it contradicts
206  if (hphDebug_) { //a more accurate prediction made with the help of information from sensor modules
207  edm::LogVerbatim("TrackTriggerHPH") << "Rejected by sensor modules";
208  }
209 
210  continue;
211  }
212 
213  if (hphDebug_) {
214  edm::LogVerbatim("TrackTriggerHPH") << "Confirmed by sensor modules";
215  }
216  //prediction is accepted
217  if (((1 << i) & hitpattern_) >> i) {
218  if (hphDebug_) {
219  edm::LogVerbatim("TrackTriggerHPH") << "Layer found in hitpattern";
220  }
221 
222  binary_[ReducedId(j)] = 1;
223  if (layers_[k].psModule()) {
224  numPS_++;
225  } else {
226  num2S_++;
227  }
228  } else {
229  if (hphDebug_) {
230  edm::LogVerbatim("TrackTriggerHPH") << "Layer missing in hitpattern";
231  }
232 
233  if (layers_[k].psModule()) {
234  numMissingPS_++;
235  } else {
236  numMissing2S_++;
237  }
238  }
239  }
240  }
241  }
242 
243  if (hphDebug_) {
244  edm::LogVerbatim("TrackTriggerHPH") << "------------------------------";
245  edm::LogVerbatim("TrackTriggerHPH") << "numPS = " << numPS_ << ", num2S = " << num2S_
246  << ", missingPS = " << numMissingPS_ << ", missing2S = " << numMissing2S_;
247  edm::LogVerbatim("TrackTriggerHPH") << "======================================================";
248  }
249  }
250 
251  int HitPatternHelper::ReducedId(int layerId) {
252  if (hphDebug_ && (layerId > 15 || layerId < 1)) {
253  edm::LogVerbatim("TrackTriggerHPH") << "Warning: invalid layer id !";
254  }
255  if (layerId <= 6) {
256  layerId = layerId - 1;
257  return layerId;
258  } else {
259  layerId = layerId - 5;
260  return layerId;
261  }
262  };
263 
264  int HitPatternHelper::findLayer(int layerId) {
265  for (int i = 0; i < (int)layers_.size(); i++) {
266  if (layerId == (int)layers_[i].layerId()) {
267  return i;
268  }
269  }
270  return -1;
271  }
272 
273 } // namespace hph
Log< level::Info, true > LogVerbatim
static constexpr std::pair< unsigned, unsigned > layerMap_[nEta_/2][nGPlayer_+1]
Definition: KFbase.h:61
Class to process and provide run-time constants used by Track Trigger emulators.
Definition: Setup.h:44
static auto equalID(tt::SensorModule lhs, tt::SensorModule rhs)
std::vector< int > binary_
U second(std::pair< T, U > const &p)
static auto smallerID(tt::SensorModule lhs, tt::SensorModule rhs)
const std::vector< SensorModule > & sensorModules() const
Definition: Setup.h:126
std::vector< double > etaRegions_
def unique(seq, keepstr=True)
Definition: tier0.py:24
std::vector< tt::SensorModule > layers_
static unsigned int calcLayerIdReduced(unsigned int layerId)
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static auto smallerID(std::pair< int, bool > lhs, std::pair< int, bool > rhs)
d
Definition: ztail.py:151
std::vector< std::pair< int, bool > > layerIds_
int findLayer(int layerId)
=== This is the base class for the linearised chi-squared track fit algorithms.
Definition: Array2D.h:16
std::vector< tt::SensorModule > sensorModules() const
const tt::Setup setupTT_
int ReducedId(int layerId)
std::map< int, std::map< int, std::vector< int > > > layermap_
static auto equalID(std::pair< int, bool > lhs, std::pair< int, bool > rhs)
std::map< int, std::map< int, std::vector< int > > > layermap_