CMS 3D CMS Logo

PixelDigitizerAlgorithm.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <cmath>
3 
6 
11 
12 // Geometry
21 
22 using namespace edm;
23 using namespace sipixelobjects;
24 
26  if (use_ineff_from_db_) // load gain calibration service fromdb...
27  theSiPixelGainCalibrationService_->setESObjects(es);
28 
29  if (use_deadmodule_DB_)
30  siPixelBadModule_ = &es.getData(siPixelBadModuleToken_);
31 
32  if (use_LorentzAngle_DB_) // Get Lorentz angle from DB record
33  siPixelLorentzAngle_ = &es.getData(siPixelLorentzAngleToken_);
34 
35  // gets the map and geometry from the DB (to kill ROCs)
36  fedCablingMap_ = &es.getData(fedCablingMapToken_);
37  geom_ = &es.getData(geomToken_);
38 }
39 
41  : Phase2TrackerDigitizerAlgorithm(conf.getParameter<ParameterSet>("AlgorithmCommon"),
42  conf.getParameter<ParameterSet>("PixelDigitizerAlgorithm"),
43  iC),
44  odd_row_interchannelCoupling_next_row_(conf.getParameter<ParameterSet>("PixelDigitizerAlgorithm")
45  .getParameter<double>("Odd_row_interchannelCoupling_next_row")),
46  even_row_interchannelCoupling_next_row_(conf.getParameter<ParameterSet>("PixelDigitizerAlgorithm")
47  .getParameter<double>("Even_row_interchannelCoupling_next_row")),
48  odd_column_interchannelCoupling_next_column_(
49  conf.getParameter<ParameterSet>("PixelDigitizerAlgorithm")
50  .getParameter<double>("Odd_column_interchannelCoupling_next_column")),
51  even_column_interchannelCoupling_next_column_(
52  conf.getParameter<ParameterSet>("PixelDigitizerAlgorithm")
53  .getParameter<double>("Even_column_interchannelCoupling_next_column")),
54  apply_timewalk_(conf.getParameter<ParameterSet>("PixelDigitizerAlgorithm").getParameter<bool>("ApplyTimewalk")),
55  timewalk_model_(
56  conf.getParameter<ParameterSet>("PixelDigitizerAlgorithm").getParameter<edm::ParameterSet>("TimewalkModel")),
57  fedCablingMapToken_(iC.esConsumes()),
58  geomToken_(iC.esConsumes()) {
63  pixelFlag_ = true;
64  LogDebug("PixelDigitizerAlgorithm") << "Algorithm constructed "
65  << "Configuration parameters:"
66  << "Threshold/Gain = "
67  << "threshold in electron Endcap = " << theThresholdInE_Endcap_
68  << "threshold in electron Barrel = " << theThresholdInE_Barrel_ << " "
70  << " The delta cut-off is set to " << tMax_ << " pix-inefficiency "
72 }
73 PixelDigitizerAlgorithm::~PixelDigitizerAlgorithm() { LogDebug("PixelDigitizerAlgorithm") << "Algorithm deleted"; }
74 //
75 // -- Select the Hit for Digitization
76 //
77 bool PixelDigitizerAlgorithm::select_hit(const PSimHit& hit, double tCorr, double& sigScale) const {
78  double time = hit.tof() - tCorr;
79  return (time >= theTofLowerCut_ && time < theTofUpperCut_);
80 }
81 
82 // ======================================================================
83 //
84 // Add Cross-talk contribution
85 //
86 // ======================================================================
88  if (!pixelFlag_)
89  return;
90 
91  const Phase2TrackerTopology* topol = &pixdet->specificTopology();
92 
93  // cross-talk calculation valid for the case of 25x100 pixels
94  const float pitch_first = 0.0025;
95  const float pitch_second = 0.0100;
96 
97  // 0.5 um tolerance when comparing the pitch to accommodate the small changes in different TK geometrie (temporary fix)
98  const double pitch_tolerance(0.0005);
99 
100  if (std::abs(topol->pitch().first - pitch_first) > pitch_tolerance ||
101  std::abs(topol->pitch().second - pitch_second) > pitch_tolerance)
102  return;
103 
104  uint32_t detID = pixdet->geographicalId().rawId();
105  signal_map_type& theSignal = _signal[detID];
106  signal_map_type signalNew;
107 
108  int numRows = topol->nrows();
109  int numColumns = topol->ncolumns();
110 
111  for (auto& s : theSignal) {
112  float signalInElectrons = s.second.ampl(); // signal in electrons
113 
114  auto hitChan = PixelDigi::channelToPixel(s.first);
115 
116  float signalInElectrons_odd_row_Xtalk_next_row = signalInElectrons * odd_row_interchannelCoupling_next_row_;
117  float signalInElectrons_even_row_Xtalk_next_row = signalInElectrons * even_row_interchannelCoupling_next_row_;
118  float signalInElectrons_odd_column_Xtalk_next_column =
120  float signalInElectrons_even_column_Xtalk_next_column =
122 
123  // subtract the charge which will be shared
124  s.second.set(signalInElectrons - signalInElectrons_odd_row_Xtalk_next_row -
125  signalInElectrons_even_row_Xtalk_next_row - signalInElectrons_odd_column_Xtalk_next_column -
126  signalInElectrons_even_column_Xtalk_next_column);
127 
128  if (hitChan.first != 0) {
129  auto XtalkPrev = std::make_pair(hitChan.first - 1, hitChan.second);
130  int chanXtalkPrev = pixelFlag_ ? PixelDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second)
131  : Phase2TrackerDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second);
132  if (hitChan.first % 2 == 1)
133  signalNew.emplace(chanXtalkPrev,
134  DigitizerUtility::Amplitude(signalInElectrons_even_row_Xtalk_next_row, nullptr, -1.0));
135  else
136  signalNew.emplace(chanXtalkPrev,
137  DigitizerUtility::Amplitude(signalInElectrons_odd_row_Xtalk_next_row, nullptr, -1.0));
138  }
139  if (hitChan.first < numRows - 1) {
140  auto XtalkNext = std::make_pair(hitChan.first + 1, hitChan.second);
141  int chanXtalkNext = pixelFlag_ ? PixelDigi::pixelToChannel(XtalkNext.first, XtalkNext.second)
142  : Phase2TrackerDigi::pixelToChannel(XtalkNext.first, XtalkNext.second);
143  if (hitChan.first % 2 == 1)
144  signalNew.emplace(chanXtalkNext,
145  DigitizerUtility::Amplitude(signalInElectrons_odd_row_Xtalk_next_row, nullptr, -1.0));
146  else
147  signalNew.emplace(chanXtalkNext,
148  DigitizerUtility::Amplitude(signalInElectrons_even_row_Xtalk_next_row, nullptr, -1.0));
149  }
150 
151  if (hitChan.second != 0) {
152  auto XtalkPrev = std::make_pair(hitChan.first, hitChan.second - 1);
153  int chanXtalkPrev = pixelFlag_ ? PixelDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second)
154  : Phase2TrackerDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second);
155  if (hitChan.second % 2 == 1)
156  signalNew.emplace(chanXtalkPrev,
157  DigitizerUtility::Amplitude(signalInElectrons_even_column_Xtalk_next_column, nullptr, -1.0));
158  else
159  signalNew.emplace(chanXtalkPrev,
160  DigitizerUtility::Amplitude(signalInElectrons_odd_column_Xtalk_next_column, nullptr, -1.0));
161  }
162  if (hitChan.second < numColumns - 1) {
163  auto XtalkNext = std::make_pair(hitChan.first, hitChan.second + 1);
164  int chanXtalkNext = pixelFlag_ ? PixelDigi::pixelToChannel(XtalkNext.first, XtalkNext.second)
165  : Phase2TrackerDigi::pixelToChannel(XtalkNext.first, XtalkNext.second);
166  if (hitChan.second % 2 == 1)
167  signalNew.emplace(chanXtalkNext,
168  DigitizerUtility::Amplitude(signalInElectrons_odd_column_Xtalk_next_column, nullptr, -1.0));
169  else
170  signalNew.emplace(chanXtalkNext,
171  DigitizerUtility::Amplitude(signalInElectrons_even_column_Xtalk_next_column, nullptr, -1.0));
172  }
173  }
174  for (auto const& l : signalNew) {
175  int chan = l.first;
176  auto iter = theSignal.find(chan);
177  if (iter != theSignal.end()) {
178  iter->second += l.second.ampl();
179  } else {
180  theSignal.emplace(chan, DigitizerUtility::Amplitude(l.second.ampl(), nullptr, -1.0));
181  }
182  }
183 }
184 
186  : x_(pset.getParameter<std::vector<double>>("charge")), y_(pset.getParameter<std::vector<double>>("delay")) {
187  if (x_.size() != y_.size())
188  throw cms::Exception("Configuration")
189  << "Timewalk model error: the number of charge values does not match the number of delay values!";
190 }
191 
193  auto it = std::lower_bound(x_.begin(), x_.end(), x);
194  if (it == x_.begin())
195  return y_.front();
196  if (it == x_.end())
197  return y_.back();
198  int index = std::distance(x_.begin(), it);
199  double x_high = *it;
200  double x_low = *(--it);
201  double p = (x - x_low) / (x_high - x_low);
202  return p * y_[index] + (1 - p) * y_[index - 1];
203 }
204 
206  threshold_values = pset.getParameter<std::vector<double>>("ThresholdValues");
207  const auto& curve_psetvec = pset.getParameter<std::vector<edm::ParameterSet>>("Curves");
208  if (threshold_values.size() != curve_psetvec.size())
209  throw cms::Exception("Configuration")
210  << "Timewalk model error: the number of threshold values does not match the number of curves.";
211  for (const auto& curve_pset : curve_psetvec)
212  curves.emplace_back(curve_pset);
213 }
214 
215 double PixelDigitizerAlgorithm::TimewalkModel::operator()(double q_in, double q_threshold) const {
216  auto index = find_closest_index(threshold_values, q_threshold);
217  return curves[index](q_in);
218 }
219 
220 std::size_t PixelDigitizerAlgorithm::TimewalkModel::find_closest_index(const std::vector<double>& vec,
221  double value) const {
222  auto it = std::lower_bound(vec.begin(), vec.end(), value);
223  if (it == vec.begin())
224  return 0;
225  else if (it == vec.end())
226  return vec.size() - 1;
227  else {
228  auto it_upper = it;
229  auto it_lower = --it;
230  auto closest = (value - *it_lower > *it_upper - value) ? it_upper : it_lower;
231  return std::distance(vec.begin(), closest);
232  }
233 }
234 //
235 // -- Compare Signal with Threshold
236 //
238  float charge,
239  float thr) const {
240  if (charge < thr)
241  return false;
242  if (apply_timewalk_ && hitInfo) {
243  float corrected_time = hitInfo->time();
244  double time = corrected_time + timewalk_model_(charge, thr);
245  return (time >= theTofLowerCut_ && time < theTofUpperCut_);
246  } else
247  return true;
248 }
249 //
250 // -- Read Bad Channels from the Condidion DB and kill channels/module accordingly
251 //
253  bool isbad = false;
254  uint32_t detID = pixdet->geographicalId().rawId();
255  int ncol = pixdet->specificTopology().ncolumns();
256  if (ncol < 0)
257  return;
258  std::vector<SiPixelQuality::disabledModuleType> disabledModules = siPixelBadModule_->getBadComponentList();
259 
261  for (const auto& mod : disabledModules) {
262  if (detID == mod.DetID) {
263  isbad = true;
264  badmodule = mod;
265  break;
266  }
267  }
268 
269  if (!isbad)
270  return;
271 
272  signal_map_type& theSignal = _signal[detID]; // check validity
273  if (badmodule.errorType == 0) { // this is a whole dead module.
274  for (auto& s : theSignal)
275  s.second.set(0.); // reset amplitude
276  } else { // all other module types: half-modules and single ROCs.
277  // Get Bad ROC position:
278  // follow the example of getBadRocPositions in CondFormats/SiPixelObjects/src/SiPixelQuality.cc
279  std::vector<GlobalPixel> badrocpositions;
280  for (size_t j = 0; j < static_cast<size_t>(ncol); j++) {
281  if (siPixelBadModule_->IsRocBad(detID, j)) {
282  std::vector<CablingPathToDetUnit> path = fedCablingMap_->pathToDetUnit(detID);
283  for (auto const& p : path) {
284  const PixelROC* myroc = fedCablingMap_->findItem(p);
285  if (myroc->idInDetUnit() == j) {
286  LocalPixel::RocRowCol local = {39, 25}; //corresponding to center of ROC row, col
287  GlobalPixel global = myroc->toGlobal(LocalPixel(local));
288  badrocpositions.push_back(global);
289  break;
290  }
291  }
292  }
293  }
294 
295  for (auto& s : theSignal) {
296  std::pair<int, int> ip;
297  if (pixelFlag_)
298  ip = PixelDigi::channelToPixel(s.first);
299  else
301 
302  for (auto const& p : badrocpositions) {
303  for (auto& k : badPixels_) {
304  if (p.row == k.getParameter<int>("row") && ip.first == k.getParameter<int>("row") &&
305  std::abs(ip.second - p.col) < k.getParameter<int>("col")) {
306  s.second.set(0.);
307  }
308  }
309  }
310  }
311  }
312 }
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
edm::ESGetToken< SiPixelQuality, SiPixelQualityRcd > siPixelBadModuleToken_
bool IsRocBad(const uint32_t &detid, const short &rocNb) const
void init(const edm::EventSetup &es) override
static std::pair< int, int > channelToPixel(int ch)
Definition: PixelDigi.h:69
virtual int ncolumns() const =0
void module_killing_DB(const Phase2TrackerGeomDetUnit *pixdet) override
virtual int nrows() const =0
std::vector< sipixelobjects::CablingPathToDetUnit > pathToDetUnit(uint32_t rawDetId) const final
identify pixel inside single ROC
Definition: LocalPixel.h:7
const TimewalkModel timewalk_model_
static int pixelToChannel(int row, int col)
Definition: PixelDigi.h:75
global coordinates (row and column in DetUnit, as in PixelDigi)
Definition: GlobalPixel.h:6
void add_cross_talk(const Phase2TrackerGeomDetUnit *pixdet) override
const std::vector< disabledModuleType > getBadComponentList() const
bool isAboveThreshold(const DigitizerUtility::SimHitInfo *hitInfo, float charge, float thr) const override
double operator()(double q_in, double q_threshold) const
GlobalPixel toGlobal(const LocalPixel &loc) const
Definition: PixelROC.h:55
static PackedDigiType pixelToChannel(unsigned int row, unsigned int col)
TimewalkCurve(const edm::ParameterSet &pset)
const sipixelobjects::PixelROC * findItem(const sipixelobjects::CablingPathToDetUnit &path) const final
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool getData(T &iHolder) const
Definition: EventSetup.h:122
Definition: value.py:1
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:64
std::map< int, DigitizerUtility::Amplitude, std::less< int > > signal_map_type
bool select_hit(const PSimHit &hit, double tCorr, double &sigScale) const override
TimewalkModel(const edm::ParameterSet &pset)
PixelDigitizerAlgorithm(const edm::ParameterSet &conf, edm::ConsumesCollector iC)
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
row and collumn in ROC representation
Definition: LocalPixel.h:13
chan
lumi = TPaveText(lowX+0.38, lowY+0.061, lowX+0.45, lowY+0.161, "NDC") lumi.SetBorderSize( 0 ) lumi...
std::size_t find_closest_index(const std::vector< double > &vec, double value) const
static std::pair< unsigned int, unsigned int > channelToPixel(unsigned int ch)
HLT enums.
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
edm::ESGetToken< SiPixelLorentzAngle, SiPixelLorentzAngleSimRcd > siPixelLorentzAngleToken_
virtual std::pair< float, float > pitch() const =0
T mod(const T &a, const T &b)
Definition: ecalDccMap.h:4
unsigned int idInDetUnit() const
id of this ROC in DetUnit etermined by token path
Definition: PixelROC.h:37
#define LogDebug(id)