CMS 3D CMS Logo

PixelDigitizerAlgorithm.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <cmath>
3 
6 
11 
12 // Geometry
20 
21 using namespace edm;
22 using namespace sipixelobjects;
23 
25  if (use_ineff_from_db_) // load gain calibration service fromdb...
26  theSiPixelGainCalibrationService_->setESObjects(es);
27 
28  if (use_deadmodule_DB_)
29  siPixelBadModule_ = &es.getData(siPixelBadModuleToken_);
30 
31  if (use_LorentzAngle_DB_) // Get Lorentz angle from DB record
32  siPixelLorentzAngle_ = &es.getData(siPixelLorentzAngleToken_);
33 
34  geom_ = &es.getData(geomToken_);
35  if (useChargeReweighting_) {
36  theSiPixelChargeReweightingAlgorithm_->init(es);
37  }
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  geomToken_(iC.esConsumes()) {
62  pixelFlag_ = true;
63  LogDebug("PixelDigitizerAlgorithm") << "Algorithm constructed "
64  << "Configuration parameters:"
65  << "Threshold/Gain = "
66  << "threshold in electron Endcap = " << theThresholdInE_Endcap_
67  << "threshold in electron Barrel = " << theThresholdInE_Barrel_ << " "
69  << " The delta cut-off is set to " << tMax_ << " pix-inefficiency "
71 }
72 
73 PixelDigitizerAlgorithm::~PixelDigitizerAlgorithm() { LogDebug("PixelDigitizerAlgorithm") << "Algorithm deleted"; }
74 
75 //
76 // -- Select the Hit for Digitization
77 //
78 bool PixelDigitizerAlgorithm::select_hit(const PSimHit& hit, double tCorr, double& sigScale) const {
79  // in case of signal-shape emulation do not apply [TofLower,TofUpper] selection
80  double toa = hit.tof() - tCorr;
81  return apply_timewalk_ || (toa >= theTofLowerCut_ && toa < theTofUpperCut_);
82 }
83 
84 // ======================================================================
85 //
86 // Add Cross-talk contribution
87 //
88 // ======================================================================
90  if (!pixelFlag_)
91  return;
92 
93  const Phase2TrackerTopology* topol = &pixdet->specificTopology();
94 
95  // cross-talk calculation valid for the case of 25x100 pixels
96  const float pitch_first = 0.0025;
97  const float pitch_second = 0.0100;
98 
99  // 0.5 um tolerance when comparing the pitch to accommodate the small changes in different TK geometrie (temporary fix)
100  const double pitch_tolerance(0.0005);
101 
102  if (std::abs(topol->pitch().first - pitch_first) > pitch_tolerance ||
103  std::abs(topol->pitch().second - pitch_second) > pitch_tolerance)
104  return;
105 
106  uint32_t detID = pixdet->geographicalId().rawId();
107  signal_map_type& theSignal = _signal[detID];
108  signal_map_type signalNew;
109 
110  int numRows = topol->nrows();
111  int numColumns = topol->ncolumns();
112 
113  for (auto& s : theSignal) {
114  float signalInElectrons = s.second.ampl(); // signal in electrons
115 
116  auto hitChan = PixelDigi::channelToPixel(s.first);
117 
118  float signalInElectrons_odd_row_Xtalk_next_row = signalInElectrons * odd_row_interchannelCoupling_next_row_;
119  float signalInElectrons_even_row_Xtalk_next_row = signalInElectrons * even_row_interchannelCoupling_next_row_;
120  float signalInElectrons_odd_column_Xtalk_next_column =
122  float signalInElectrons_even_column_Xtalk_next_column =
124 
125  // subtract the charge which will be shared
126  s.second.set(signalInElectrons - signalInElectrons_odd_row_Xtalk_next_row -
127  signalInElectrons_even_row_Xtalk_next_row - signalInElectrons_odd_column_Xtalk_next_column -
128  signalInElectrons_even_column_Xtalk_next_column);
129 
130  if (hitChan.first != 0) {
131  auto XtalkPrev = std::make_pair(hitChan.first - 1, hitChan.second);
132  int chanXtalkPrev = pixelFlag_ ? PixelDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second)
133  : Phase2TrackerDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second);
134  if (hitChan.first % 2 == 1)
135  signalNew.emplace(chanXtalkPrev,
136  digitizerUtility::Ph2Amplitude(signalInElectrons_even_row_Xtalk_next_row, nullptr, -1.0));
137  else
138  signalNew.emplace(chanXtalkPrev,
139  digitizerUtility::Ph2Amplitude(signalInElectrons_odd_row_Xtalk_next_row, nullptr, -1.0));
140  }
141  if (hitChan.first < numRows - 1) {
142  auto XtalkNext = std::make_pair(hitChan.first + 1, hitChan.second);
143  int chanXtalkNext = pixelFlag_ ? PixelDigi::pixelToChannel(XtalkNext.first, XtalkNext.second)
144  : Phase2TrackerDigi::pixelToChannel(XtalkNext.first, XtalkNext.second);
145  if (hitChan.first % 2 == 1)
146  signalNew.emplace(chanXtalkNext,
147  digitizerUtility::Ph2Amplitude(signalInElectrons_odd_row_Xtalk_next_row, nullptr, -1.0));
148  else
149  signalNew.emplace(chanXtalkNext,
150  digitizerUtility::Ph2Amplitude(signalInElectrons_even_row_Xtalk_next_row, nullptr, -1.0));
151  }
152 
153  if (hitChan.second != 0) {
154  auto XtalkPrev = std::make_pair(hitChan.first, hitChan.second - 1);
155  int chanXtalkPrev = pixelFlag_ ? PixelDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second)
156  : Phase2TrackerDigi::pixelToChannel(XtalkPrev.first, XtalkPrev.second);
157  if (hitChan.second % 2 == 1)
158  signalNew.emplace(
159  chanXtalkPrev,
160  digitizerUtility::Ph2Amplitude(signalInElectrons_even_column_Xtalk_next_column, nullptr, -1.0));
161  else
162  signalNew.emplace(
163  chanXtalkPrev,
164  digitizerUtility::Ph2Amplitude(signalInElectrons_odd_column_Xtalk_next_column, nullptr, -1.0));
165  }
166  if (hitChan.second < numColumns - 1) {
167  auto XtalkNext = std::make_pair(hitChan.first, hitChan.second + 1);
168  int chanXtalkNext = pixelFlag_ ? PixelDigi::pixelToChannel(XtalkNext.first, XtalkNext.second)
169  : Phase2TrackerDigi::pixelToChannel(XtalkNext.first, XtalkNext.second);
170  if (hitChan.second % 2 == 1)
171  signalNew.emplace(
172  chanXtalkNext,
173  digitizerUtility::Ph2Amplitude(signalInElectrons_odd_column_Xtalk_next_column, nullptr, -1.0));
174  else
175  signalNew.emplace(
176  chanXtalkNext,
177  digitizerUtility::Ph2Amplitude(signalInElectrons_even_column_Xtalk_next_column, nullptr, -1.0));
178  }
179  }
180  for (auto const& l : signalNew) {
181  int chan = l.first;
182  auto iter = theSignal.find(chan);
183  if (iter != theSignal.end()) {
184  iter->second += l.second.ampl();
185  } else {
186  theSignal.emplace(chan, digitizerUtility::Ph2Amplitude(l.second.ampl(), nullptr, -1.0));
187  }
188  }
189 }
190 
192  : x_(pset.getParameter<std::vector<double>>("charge")), y_(pset.getParameter<std::vector<double>>("delay")) {
193  if (x_.size() != y_.size())
194  throw cms::Exception("Configuration")
195  << "Timewalk model error: the number of charge values does not match the number of delay values!";
196 }
197 
199  auto it = std::lower_bound(x_.begin(), x_.end(), x);
200  if (it == x_.begin())
201  return y_.front();
202  if (it == x_.end())
203  return y_.back();
204  int index = std::distance(x_.begin(), it);
205  double x_high = *it;
206  double x_low = *(--it);
207  double p = (x - x_low) / (x_high - x_low);
208  return p * y_[index] + (1 - p) * y_[index - 1];
209 }
210 
212  threshold_values = pset.getParameter<std::vector<double>>("ThresholdValues");
213  const auto& curve_psetvec = pset.getParameter<std::vector<edm::ParameterSet>>("Curves");
214  if (threshold_values.size() != curve_psetvec.size())
215  throw cms::Exception("Configuration")
216  << "Timewalk model error: the number of threshold values does not match the number of curves.";
217  for (const auto& curve_pset : curve_psetvec)
218  curves.emplace_back(curve_pset);
219 }
220 
221 double PixelDigitizerAlgorithm::TimewalkModel::operator()(double q_in, double q_threshold) const {
222  auto index = find_closest_index(threshold_values, q_threshold);
223  return curves[index](q_in);
224 }
225 
226 std::size_t PixelDigitizerAlgorithm::TimewalkModel::find_closest_index(const std::vector<double>& vec,
227  double value) const {
228  auto it = std::lower_bound(vec.begin(), vec.end(), value);
229  if (it == vec.begin())
230  return 0;
231  else if (it == vec.end())
232  return vec.size() - 1;
233  else {
234  auto it_upper = it;
235  auto it_lower = --it;
236  auto closest = (value - *it_lower > *it_upper - value) ? it_upper : it_lower;
237  return std::distance(vec.begin(), closest);
238  }
239 }
240 //
241 // -- Compare Signal with Threshold
242 //
244  float charge,
245  float thr) const {
246  if (charge < thr)
247  return false;
248  if (apply_timewalk_ && hitInfo) {
249  float corrected_time = hitInfo->time();
250  double time = corrected_time + timewalk_model_(charge, thr);
251  return (time >= theTofLowerCut_ && time < theTofUpperCut_);
252  } else
253  return true;
254 }
255 //
256 // -- Read Bad Channels from the Condidion DB and kill channels/module accordingly
257 //
259  throw cms::Exception("PixelDigitizerAlgorithm") << "Trying to kill modules from the pixel digitizer."
260  << " This method is not yet implemented!";
261 }
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
edm::ESGetToken< SiPixelQuality, SiPixelQualityRcd > siPixelBadModuleToken_
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
void init(const edm::EventSetup &es) override
static std::pair< int, int > channelToPixel(int ch)
Definition: PixelDigi.h:69
virtual int ncolumns() const =0
int closest(std::vector< int > const &vec, int value)
void module_killing_DB(const Phase2TrackerGeomDetUnit *pixdet) override
virtual int nrows() const =0
std::map< int, digitizerUtility::Ph2Amplitude, std::less< int > > signal_map_type
const TimewalkModel timewalk_model_
static int pixelToChannel(int row, int col)
Definition: PixelDigi.h:75
void add_cross_talk(const Phase2TrackerGeomDetUnit *pixdet) override
double operator()(double q_in, double q_threshold) const
static PackedDigiType pixelToChannel(unsigned int row, unsigned int col)
TimewalkCurve(const edm::ParameterSet &pset)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Definition: value.py:1
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:64
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
chan
lumi = TPaveText(lowX+0.38, lowY+0.061, lowX+0.45, lowY+0.161, "NDC") lumi.SetBorderSize( 0 ) lumi...
bool isAboveThreshold(const digitizerUtility::SimHitInfo *hitInfo, float charge, float thr) const override
std::size_t find_closest_index(const std::vector< double > &vec, double value) const
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
#define LogDebug(id)