CMS 3D CMS Logo

CSCMake2DRecHit.cc
Go to the documentation of this file.
1 // This is CSCMake2DRecHit
2 
8 
11 
15 
18 
19 #include <iostream>
20 #include <algorithm>
21 #include <cmath>
22 #include <string>
23 
25  useCalib = ps.getParameter<bool>("CSCUseCalibrations");
26  stripWireDeltaTime = ps.getParameter<int>("CSCstripWireDeltaTime"); //@@ Non-standard CSC*s*trip...
27  useTimingCorrections = ps.getParameter<bool>("CSCUseTimingCorrections");
28  useGasGainCorrections = ps.getParameter<bool>("CSCUseGasGainCorrections");
29 
31 }
32 
34 
36  const CSCLayer* layer,
37  const CSCWireHit& wHit,
38  const CSCStripHit& sHit) {
39  // Cache layer info for ease of access
40  layer_ = layer;
42  specs_ = layer->chamber()->specs();
43  id_ = id;
44 
45  static constexpr float inv_sqrt_12 = 0.2886751;
46 
47  float tpeak = -99.f;
48 
51 
52  // Find wire hit position and wire properties
53  wgroups = wHit.wgroups();
54 
55  int wg_left = wgroups[0];
56  ;
57  int wg_right = wgroups[wgroups.size() - 1];
58 
59  int Nwires1 = layergeom_->numberOfWiresPerGroup(wg_left);
60  int Nwires2 = layergeom_->numberOfWiresPerGroup(wg_right);
61 
62  float Mwire1 = layergeom_->middleWireOfGroup(wg_left);
63  float Mwire2 = layergeom_->middleWireOfGroup(wg_right);
64 
65  int centerWire_left = (int)(Mwire1 - Nwires1 / 2. + 0.5);
66  int centerWire_right = (int)(Mwire2 + Nwires2 / 2.);
67 
68  float centerWire = (centerWire_left + centerWire_right) / 2.;
69 
70  //---- WGs around dead HV segment regions may need special treatment...
71  //---- This is not addressed here.
72 
73  float sigmaWire = 0.;
74  if (wHit.deadWG() > 0 || wgroups.size() > 2) {
75  //---- worst possible case; take most conservative approach
76  for (unsigned int iWG = 0; iWG < wgroups.size(); iWG++) {
77  sigmaWire += layergeom_->yResolution(wgroups[iWG]);
78  }
79  } else if (2 == wgroups.size()) {
80  //---- 2 WGs - get the larger error (overestimation if a single track is passing
81  //---- between the WGs; underestimation if there are two separate signal sources)
82  if (layergeom_->yResolution(wgroups[0]) > layergeom_->yResolution(wgroups[1])) {
83  sigmaWire = layergeom_->yResolution(wgroups[0]);
84  } else {
85  sigmaWire = layergeom_->yResolution(wgroups[1]);
86  }
87  } else if (1 == wgroups.size()) {
88  //---- simple - just 1 WG
89  sigmaWire = layergeom_->yResolution(wgroups[0]);
90  }
91 
92  // Find strips position and properties
93 
95  int tmax = sHit.tmax();
96  int nStrip = strips.size();
97  int idCenterStrip = nStrip / 2;
98  int centerStrip = strips[idCenterStrip];
99 
100  // Retrieve strip pulseheights from the CSCStripHit
101  const std::vector<float>& adc = sHit.s_adc();
102  const std::vector<float>& adcRaw = sHit.s_adcRaw();
103 
104  std::vector<float> adc2;
105  std::vector<float> adc2Raw;
106 
107  LogTrace("CSCMake2DRecHit") << "[CSCMake2DRecHit] dump of adc values to be added to rechit follows...";
108 
109  for (int iStrip = 0; iStrip < nStrip; ++iStrip) {
110  adc2.clear();
111  adc2Raw.clear();
112  adc2.reserve(4);
113  adc2Raw.reserve(4);
114  for (int t = 0; t < 4; ++t) {
115  adc2.push_back(adc[t + iStrip * 4]);
116  adc2Raw.push_back(adcRaw[t + iStrip * 4]);
117  }
118  //After CMSSW_5_0: ADC value is pedestal-subtracted and electronics-gain corrected
119  adcMap.put(strips[iStrip], adc2.begin(), adc2.end());
120  // Up to CMSSW_5_0, Rechit takes _raw_ adc values
121  // adcMap.put( strips[iStrip], adc2Raw.begin(), adc2Raw.end() );
122 
123  LogTrace("CSCMake2DRecHit") << "[CSCMake2DRecHit] strip = " << strips[iStrip] << " adcs= " << adc2Raw[0] << " "
124  << adc2Raw[1] << " " << adc2Raw[2] << " " << adc2Raw[3];
125  }
126 
127  //The tpeak finding for both edge and non-edge strips has been moved to here
128  //tpeak will be a const argument for xMatchGatti_->findXOnStrip
129  float adcArray[4];
130  for (int t = 0; t < 4; ++t) {
131  int k = t + 4 * (idCenterStrip);
132  adcArray[t] = adc[k];
133  }
134  tpeak = peakTimeFinder_->peakTime(tmax, adcArray, tpeak);
135  // Just for completeness, the start time of the pulse is 133 ns earlier, according to Stan :)
136  LogTrace("CSCRecHit") << "[CSCMake2DRecHit] " << id << " strip=" << centerStrip << ", t_zero=" << tpeak - 133.f
137  << ", tpeak=" << tpeak;
138 
139  float positionWithinTheStrip = -99.;
140  float sigmaWithinTheStrip = -99.;
141  int quality = -1;
142  LocalPoint lp0(0., 0.);
143  int wglo = wg_left;
144  int wghi = wg_right;
145 
146  // First wire of first wiregroup in cluster
147  wglo = layergeom_->middleWireOfGroup(wglo) + 0.5 - 0.5 * layergeom_->numberOfWiresPerGroup(wglo);
148  // Last wire in last wiregroup of cluster (OK if only 1 wiregroup too)
149  wghi = layergeom_->middleWireOfGroup(wghi) - 0.5 + 0.5 * layergeom_->numberOfWiresPerGroup(wghi);
150 
151  float stripWidth = -99.f;
152  // If at the edge, then used 1 strip cluster only
153  if (centerStrip == 1 || centerStrip == specs_->nStrips() || nStrip < 2) {
154  lp0 = (layergeom_->possibleRecHitPosition(float(centerStrip) - 0.5, wglo, wghi)).first;
155  positionWithinTheStrip = 0.f;
156  stripWidth = layergeom_->stripPitch(lp0);
157  sigmaWithinTheStrip = stripWidth * inv_sqrt_12;
158  quality = 2;
159  } else {
160  // If not at the edge, used cluster of size ClusterSize:
161  LocalPoint lp11 = (layergeom_->possibleRecHitPosition(float(centerStrip) - 0.5, wglo, wghi)).first;
162  float ymiddle = lp11.y();
163  stripWidth = layergeom_->stripPitch(lp11);
164 
165  //---- Calculate local position within the strip
166  float xWithinChamber = lp11.x();
167  quality = 0;
168  //check if strip wire intersect is within the sensitive area of chamber
169  if (layergeom_->inside(lp11)) {
171  layer_,
172  sHit,
173  centerStrip,
174  xWithinChamber,
175  stripWidth,
176  tpeak,
177  positionWithinTheStrip,
178  sigmaWithinTheStrip,
179  quality);
180  }
181  lp0 = LocalPoint(xWithinChamber, ymiddle);
182  }
183 
184  // compute the errors in local x and y
185  LocalError localerr = layergeom_->localError(centerStrip, sigmaWithinTheStrip, sigmaWire);
186 
187  // Before storing the recHit, take the opportunity to change its time
188  if (useTimingCorrections) {
189  float chipCorrection = recoConditions_->chipCorrection(id, centerStrip);
190  float phaseCorrection = (sHit.stripsl1a()[0] >> (15 - 0) & 0x1) * 25.;
191  float chamberCorrection = recoConditions_->chamberTimingCorrection(id);
192 
193  GlobalPoint gp0 = layer_->toGlobal(lp0);
194  float tofCorrection = gp0.mag() / 29.9792458;
195  float signalPropagationSpeed[11] = {0.0, -78, -76, -188, -262, -97, -99, -90, -99, -99, -113};
196  float position = lp0.y() / sin(layergeom_->stripAngle(centerStrip));
197  float yCorrection = position / signalPropagationSpeed[id_.iChamberType()];
198  //printf("RecHit in e:%d s:%d r:%d c:%d l:%d strip:%d \n",id.endcap(),id.station(), id.ring(),id.chamber(),id.layer(),centerStrip);
199  //printf("\t tpeak before = %5.2f \t chipCorr %5.2f phaseCorr %5.2f chamberCorr %5.2f tofCorr %5.2f \n",
200  // tpeak,chipCorrection, phaseCorrection,chamberCorrection,tofCorrection);
201  //printf("localy = %5.2f, yCorr = %5.2f \n",lp0.y(),yCorrection);
202  tpeak = tpeak + chipCorrection + phaseCorrection + chamberCorrection - tofCorrection + yCorrection;
203  //printf("\t tpeak after = %5.2f\n",tpeak);
204  }
205 
206  // Calculate wire time to the half bx level using time bins on
207  // Store wire time with a precision of 0.01 as an int (multiply by 100)
208  // Convert from bx to ns (multiply by 25)
209  int scaledWireTime = 100 * findWireBx(wHit.timeBinsOn(), tpeak, id) * 25;
210 
211  //Get the gas-gain correction for this rechit
212  float gasGainCorrection = -999.f;
213  if (useGasGainCorrections) {
214  gasGainCorrection = recoConditions_->gasGainCorrection(id, centerStrip, centerWire);
215  }
216 
225  float energyDeposit = -999.f;
226  if (gasGainCorrection < -998.f) {
227  // if the user has chosen not to use the gas gain correction, set the energy to a different nonsense value
228  energyDeposit = -998.f;
229 
230  } else if (gasGainCorrection < 0.f) {
231  // if the gas gain correction from the database is a bad value, set the energy to yet another nonsense value
232  energyDeposit = -997.f;
233 
234  } else {
235  // gas-gain correction is OK, correct the 3x3 ADC sum
236  if (adcMap.size() == 12) {
237  energyDeposit = adcMap[0] * gasGainCorrection + adcMap[1] * gasGainCorrection + adcMap[2] * gasGainCorrection +
238  adcMap[4] * gasGainCorrection + adcMap[5] * gasGainCorrection + adcMap[6] * gasGainCorrection +
239  adcMap[8] * gasGainCorrection + adcMap[9] * gasGainCorrection + adcMap[10] * gasGainCorrection;
240 
241  } else if (adcMap.size() == 4) {
242  // if this is an edge strip, set the energy to yet another nonsense value
243  energyDeposit = -996.f;
244  }
245  }
246 
248 
250  CSCRecHit2D::ChannelContainer const& L1A_and_strips = sHit.stripsTotal();
251  CSCRecHit2D::ChannelContainer const& BX_and_wgroups = wHit.wgroupsBXandWire();
253  // (sigmaWithinTheStrip/stripWidth) is in strip widths just like positionWithinTheStrip is!
254 
255  CSCRecHit2D rechit(id,
256  lp0,
257  localerr,
258  L1A_and_strips,
259  //adcMap, wgroups, tpeak, positionWithinTheStrip,
260  adcMap,
261  BX_and_wgroups,
262  tpeak,
263  positionWithinTheStrip,
264  sigmaWithinTheStrip / stripWidth,
265  quality,
266  sHit.deadStrip(),
267  wHit.deadWG(),
268  scaledWireTime,
269  energyDeposit);
270 
272  // rechit.print();
273 
274  LogTrace("CSCRecHit") << "[CSCMake2DRecHit] rechit created in layer " << id << "... \n" << rechit;
275 
276  return rechit;
277 }
278 
280  bool isInFiducial = true;
281  const CSCLayerGeometry* layergeom_ = layer->geometry();
282  LocalPoint rhPosition = rh.localPosition();
283  // is the rechit within the chamber?
284  //(the problem occurs in ME11a/b otherwise it is OK)
285  // we could use also
286  //bool inside( const Local3DPoint&, const LocalError&, float scale=1.f ) const;
287  if (!layergeom_->inside(rhPosition)) {
288  isInFiducial = false;
289  }
290 
291  return isInFiducial;
292 }
293 
296  // And cache for use here
298 }
299 
300 float CSCMake2DRecHit::findWireBx(const std::vector<int>& timeBinsOn, float tpeak, const CSCDetId& id) {
301  // Determine the wire Bx from the vector of time bins on for the wire digi with peak time as an intial estimate.
302  // Assumes that a single hit should create either one time bin on or two consecutive time bins on
303  // so algorithm looks for bin on nearest to peak time and checks if it has a bin on consecutive with it
304  float anode_bx_offset = recoConditions_->anodeBXoffset(id);
305  float wireBx = -1;
306  float timeGuess = tpeak / 25.f + anode_bx_offset;
307  float diffMin = 9999.f;
308  int bestMatch = -9;
309  for (int j = 0; j < (int)timeBinsOn.size(); j++) {
310  auto diff = timeGuess - timeBinsOn[j];
311  // Find bin on closest to peak time
312  if (std::abs(diff) < std::abs(diffMin)) {
313  diffMin = diff;
314  bestMatch = j;
315  wireBx = timeBinsOn[j];
316  }
317  }
318  int side = diffMin > 0 ? 1 : -1; // diffMin/fabs(diffMin);
319  bool unchanged = true;
320  // First check if bin on the same side as peak time is on
321  if ((bestMatch + side) > -1 &&
322  (bestMatch + side) < (int)timeBinsOn.size()) { // Make sure one next to it within vector limits
323  if (timeBinsOn[bestMatch] ==
324  (timeBinsOn[bestMatch + side] - side)) { // See if next bin on in vector is consecutive in time
325  // Set time to the average of the two bins
326  wireBx = wireBx + 0.5f * side;
327  unchanged = false;
328  }
329  }
330  // If no match is found then check the other side
331  if ((bestMatch - side) > -1 && (bestMatch - side) < (int)timeBinsOn.size() &&
332  unchanged) { // Make sure one next to it exists
333  if (timeBinsOn[bestMatch] == (timeBinsOn[bestMatch - side] + side)) { // See if nextbin on is consecutive in time
334  wireBx = wireBx - 0.5f * side;
335  }
336  }
337  return wireBx - anode_bx_offset; // expect collision muons to be centered near 0 bx
338 }
const StripHitADCContainer & s_adc() const
L1A.
Definition: CSCStripHit.h:56
const CSCLayer * layer_
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
float chamberTimingCorrection(const CSCDetId &id) const
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:30
const ChannelContainer & strips() const
L1A.
Definition: CSCStripHit.h:50
float middleWireOfGroup(int wireGroup) const
float chipCorrection(const CSCDetId &detId, int channel) const
All other functions are accessed by geometrical strip label (i.e. strip number according to local coo...
const ChannelContainer & stripsl1a() const
L1A.
Definition: CSCStripHit.h:53
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
short int deadWG() const
a dead WG in the cluster?
Definition: CSCWireHit.h:54
const CSCChamberSpecs * specs_
unsigned short iChamberType() const
Definition: CSCDetId.h:96
float findWireBx(const std::vector< int > &timeBinsOn, float tpeak, const CSCDetId &id)
float stripAngle(int strip) const
void setConditions(const CSCRecoConditions *reco)
Pass pointer to conditions data onwards.
size_t size() const
return number of contained object
Definition: RangeMap.h:124
short int deadStrip() const
is a neighbouring string a dead strip?
Definition: CSCStripHit.h:68
ChannelContainer wgroupsBXandWire() const
The BX + wire group number.
Definition: CSCWireHit.h:48
#define LogTrace(id)
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:44
constexpr std::array< uint8_t, layerIndexSize > layer
float yResolution(int wireGroup=1) const
std::vector< int > timeBinsOn() const
Vector of time bins ON for central wire digi, lower of center pair if even number.
Definition: CSCWireHit.h:57
void setConditions(const CSCRecoConditions *reco)
Cache pointer to conditions data.
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
std::pair< LocalPoint, float > possibleRecHitPosition(float s, int w1, int w2) const
CSCXonStrip_MatchGatti * xMatchGatti_
float stripPitch() const
const StripHitADCContainer & s_adcRaw() const
the raw ADC counts for each of the strip within cluster
Definition: CSCStripHit.h:59
ChannelContainer wgroups() const
The wire groups used for forming the cluster.
Definition: CSCWireHit.h:42
int nStrips() const
T mag() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float gasGainCorrection(const CSCDetId &id, int strip, int wireGroup) const
returns gas-gain correction
double f[11][100]
bool isHitInFiducial(const CSCLayer *layer, const CSCRecHit2D &rh)
Test if rechit is in fiducial volume.
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
void put(ID id, CI begin, CI end)
insert an object range with specified identifier
Definition: RangeMap.h:111
LocalPoint localPosition() const override
Definition: CSCRecHit2D.h:56
static const double tmax[3]
const CSCRecoConditions * recoConditions_
int numberOfWiresPerGroup(int wireGroup) const
const CSCLayerGeometry * layergeom_
def bestMatch(object, matchCollection)
Definition: deltar.py:138
const ChannelContainer & stripsTotal() const
The strips used in cluster to produce strip hit (total content)
Definition: CSCStripHit.h:47
void findXOnStrip(const CSCDetId &id, const CSCLayer *layer, const CSCStripHit &stripHit, int centralStrip, float &xWithinChamber, float &stripWidth, const float &tpeak, float &xWithinStrip, float &sigma, int &quality_flag)
Returns fitted local x position and its estimated error.
float anodeBXoffset(const CSCDetId &detId) const
CSCRecHit2D hitFromStripAndWire(const CSCDetId &id, const CSCLayer *layer, const CSCWireHit &wHit, const CSCStripHit &sHit)
Make 2D hits when have both wire and strip hit available in same layer.
fixed size matrix
int tmax() const
Strip hit maximum time bin.
Definition: CSCStripHit.h:44
static int position[264][3]
Definition: ReadPGInfo.cc:289
strips
#turn off noise in all subdetectors simHcalUnsuppressedDigis.doNoise = False mix.digitizers.hcal.doNoise = False simEcalUnsuppressedDigis.doNoise = False mix.digitizers.ecal.doNoise = False simEcalUnsuppressedDigis.doESNoise = False simSiPixelDigis.AddNoise = False mix.digitizers.pixel.AddNoise = False simSiStripDigis.Noise = False mix.digitizers.strip.AddNoise = False
Definition: DigiDM_cff.py:32
const std::unique_ptr< CSCFindPeakTime > peakTimeFinder_
string quality
LocalError localError(int strip, float sigmaStrip, float sigmaWire) const
bool inside(const Local3DPoint &, const LocalError &, float scale=1.f) const override
CSCMake2DRecHit(const edm::ParameterSet &)
uint16_t *__restrict__ uint16_t const *__restrict__ adc
std::vector< int > ChannelContainer
Definition: CSCRecHit2D.h:20