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 
144  float stripWidth = -99.f;
145  // If at the edge, then used 1 strip cluster only
146  if (centerStrip == 1 || centerStrip == specs_->nStrips() || nStrip < 2) {
147  lp0 = layergeom_->stripWireIntersection(centerStrip, centerWire);
148  positionWithinTheStrip = 0.f;
149  stripWidth = layergeom_->stripPitch(lp0);
150  sigmaWithinTheStrip = stripWidth * inv_sqrt_12;
151  quality = 2;
152  } else {
153  // If not at the edge, used cluster of size ClusterSize:
154  LocalPoint lp11 = layergeom_->stripWireIntersection(centerStrip, centerWire);
155  stripWidth = layergeom_->stripPitch(lp11);
156 
157  //---- Calculate local position within the strip
158  float xWithinChamber = lp11.x();
159  quality = 0;
160  if (layergeom_->inside(lp11)) { // save time; this hit is to be discarded anyway - see isHitInFiducial(...)
161 
163  layer_,
164  sHit,
165  centerStrip,
166  xWithinChamber,
167  stripWidth,
168  tpeak,
169  positionWithinTheStrip,
170  sigmaWithinTheStrip,
171  quality);
172  }
173  lp0 = LocalPoint(xWithinChamber, layergeom_->yOfWire(centerWire, xWithinChamber));
174  }
175 
176  // compute the errors in local x and y
177  LocalError localerr = layergeom_->localError(centerStrip, sigmaWithinTheStrip, sigmaWire);
178 
179  // Before storing the recHit, take the opportunity to change its time
180  if (useTimingCorrections) {
181  float chipCorrection = recoConditions_->chipCorrection(id, centerStrip);
182  float phaseCorrection = (sHit.stripsl1a()[0] >> (15 - 0) & 0x1) * 25.;
183  float chamberCorrection = recoConditions_->chamberTimingCorrection(id);
184 
185  GlobalPoint gp0 = layer_->toGlobal(lp0);
186  float tofCorrection = gp0.mag() / 29.9792458;
187  float signalPropagationSpeed[11] = {0.0, -78, -76, -188, -262, -97, -99, -90, -99, -99, -113};
188  float position = lp0.y() / sin(layergeom_->stripAngle(centerStrip));
189  float yCorrection = position / signalPropagationSpeed[id_.iChamberType()];
190  //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);
191  //printf("\t tpeak before = %5.2f \t chipCorr %5.2f phaseCorr %5.2f chamberCorr %5.2f tofCorr %5.2f \n",
192  // tpeak,chipCorrection, phaseCorrection,chamberCorrection,tofCorrection);
193  //printf("localy = %5.2f, yCorr = %5.2f \n",lp0.y(),yCorrection);
194  tpeak = tpeak + chipCorrection + phaseCorrection + chamberCorrection - tofCorrection + yCorrection;
195  //printf("\t tpeak after = %5.2f\n",tpeak);
196  }
197 
198  // Calculate wire time to the half bx level using time bins on
199  // Store wire time with a precision of 0.01 as an int (multiply by 100)
200  // Convert from bx to ns (multiply by 25)
201  int scaledWireTime = 100 * findWireBx(wHit.timeBinsOn(), tpeak, id) * 25;
202 
203  //Get the gas-gain correction for this rechit
204  float gasGainCorrection = -999.f;
205  if (useGasGainCorrections) {
206  gasGainCorrection = recoConditions_->gasGainCorrection(id, centerStrip, centerWire);
207  }
208 
217  float energyDeposit = -999.f;
218  if (gasGainCorrection < -998.f) {
219  // if the user has chosen not to use the gas gain correction, set the energy to a different nonsense value
220  energyDeposit = -998.f;
221 
222  } else if (gasGainCorrection < 0.f) {
223  // if the gas gain correction from the database is a bad value, set the energy to yet another nonsense value
224  energyDeposit = -997.f;
225 
226  } else {
227  // gas-gain correction is OK, correct the 3x3 ADC sum
228  if (adcMap.size() == 12) {
229  energyDeposit = adcMap[0] * gasGainCorrection + adcMap[1] * gasGainCorrection + adcMap[2] * gasGainCorrection +
230  adcMap[4] * gasGainCorrection + adcMap[5] * gasGainCorrection + adcMap[6] * gasGainCorrection +
231  adcMap[8] * gasGainCorrection + adcMap[9] * gasGainCorrection + adcMap[10] * gasGainCorrection;
232 
233  } else if (adcMap.size() == 4) {
234  // if this is an edge strip, set the energy to yet another nonsense value
235  energyDeposit = -996.f;
236  }
237  }
238 
240 
242  CSCRecHit2D::ChannelContainer const& L1A_and_strips = sHit.stripsTotal();
243  CSCRecHit2D::ChannelContainer const& BX_and_wgroups = wHit.wgroupsBXandWire();
245  // (sigmaWithinTheStrip/stripWidth) is in strip widths just like positionWithinTheStrip is!
246 
247  CSCRecHit2D rechit(id,
248  lp0,
249  localerr,
250  L1A_and_strips,
251  //adcMap, wgroups, tpeak, positionWithinTheStrip,
252  adcMap,
253  BX_and_wgroups,
254  tpeak,
255  positionWithinTheStrip,
256  sigmaWithinTheStrip / stripWidth,
257  quality,
258  sHit.deadStrip(),
259  wHit.deadWG(),
260  scaledWireTime,
261  energyDeposit);
262 
264  // rechit.print();
265 
266  LogTrace("CSCRecHit") << "[CSCMake2DRecHit] rechit created in layer " << id << "... \n" << rechit;
267 
268  return rechit;
269 }
270 
272  bool isInFiducial = true;
273  const CSCLayerGeometry* layergeom_ = layer->geometry();
274  LocalPoint rhPosition = rh.localPosition();
275  // is the rechit within the chamber?
276  //(the problem occurs in ME11a/b otherwise it is OK)
277  // we could use also
278  //bool inside( const Local3DPoint&, const LocalError&, float scale=1.f ) const;
279  if (!layergeom_->inside(rhPosition)) {
280  isInFiducial = false;
281  }
282 
283  return isInFiducial;
284 }
285 
288  // And cache for use here
290 }
291 
292 float CSCMake2DRecHit::findWireBx(const std::vector<int>& timeBinsOn, float tpeak, const CSCDetId& id) {
293  // Determine the wire Bx from the vector of time bins on for the wire digi with peak time as an intial estimate.
294  // Assumes that a single hit should create either one time bin on or two consecutive time bins on
295  // so algorithm looks for bin on nearest to peak time and checks if it has a bin on consecutive with it
296  float anode_bx_offset = recoConditions_->anodeBXoffset(id);
297  float wireBx = -1;
298  float timeGuess = tpeak / 25.f + anode_bx_offset;
299  float diffMin = 9999.f;
300  int bestMatch = -9;
301  for (int j = 0; j < (int)timeBinsOn.size(); j++) {
302  auto diff = timeGuess - timeBinsOn[j];
303  // Find bin on closest to peak time
304  if (std::abs(diff) < std::abs(diffMin)) {
305  diffMin = diff;
306  bestMatch = j;
307  wireBx = timeBinsOn[j];
308  }
309  }
310  int side = diffMin > 0 ? 1 : -1; // diffMin/fabs(diffMin);
311  bool unchanged = true;
312  // First check if bin on the same side as peak time is on
313  if ((bestMatch + side) > -1 &&
314  (bestMatch + side) < (int)timeBinsOn.size()) { // Make sure one next to it within vector limits
315  if (timeBinsOn[bestMatch] ==
316  (timeBinsOn[bestMatch + side] - side)) { // See if next bin on in vector is consecutive in time
317  // Set time to the average of the two bins
318  wireBx = wireBx + 0.5f * side;
319  unchanged = false;
320  }
321  }
322  // If no match is found then check the other side
323  if ((bestMatch - side) > -1 && (bestMatch - side) < (int)timeBinsOn.size() &&
324  unchanged) { // Make sure one next to it exists
325  if (timeBinsOn[bestMatch] == (timeBinsOn[bestMatch - side] + side)) { // See if nextbin on is consecutive in time
326  wireBx = wireBx - 0.5f * side;
327  }
328  }
329  return wireBx - anode_bx_offset; // expect collision muons to be centered near 0 bx
330 }
int nStrips() const
const CSCLayer * layer_
float gasGainCorrection(const CSCDetId &id, int strip, int wireGroup) const
returns gas-gain correction
T getParameter(std::string const &) const
ChannelContainer wgroups() const
The wire groups used for forming the cluster.
Definition: CSCWireHit.h:42
const ChannelContainer & stripsl1a() const
L1A.
Definition: CSCStripHit.h:53
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:30
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
const StripHitADCContainer & s_adcRaw() const
the raw ADC counts for each of the strip within cluster
Definition: CSCStripHit.h:59
size_t size() const
return number of contained object
Definition: RangeMap.h:124
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
const StripHitADCContainer & s_adc() const
L1A.
Definition: CSCStripHit.h:56
int numberOfWiresPerGroup(int wireGroup) const
T y() const
Definition: PV3DBase.h:60
LocalPoint localPosition() const override
Definition: CSCRecHit2D.h:56
float stripPitch() const
const CSCChamberSpecs * specs_
float findWireBx(const std::vector< int > &timeBinsOn, float tpeak, const CSCDetId &id)
ChannelContainer wgroupsBXandWire() const
The BX + wire group number.
Definition: CSCWireHit.h:48
void setConditions(const CSCRecoConditions *reco)
Pass pointer to conditions data onwards.
LocalError localError(int strip, float sigmaStrip, float sigmaWire) const
short int deadStrip() const
is a neighbouring string a dead strip?
Definition: CSCStripHit.h:68
void setConditions(const CSCRecoConditions *reco)
Cache pointer to conditions data.
T mag() const
Definition: PV3DBase.h:64
CSCXonStrip_MatchGatti * xMatchGatti_
float yOfWire(float wire, float x=0.) const
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:39
float middleWireOfGroup(int wireGroup) const
float yResolution(int wireGroup=1) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
unsigned short iChamberType() const
Definition: CSCDetId.h:96
bool inside(const Local3DPoint &, const LocalError &, float scale=1.f) const override
bool isHitInFiducial(const CSCLayer *layer, const CSCRecHit2D &rh)
Test if rechit is in fiducial volume.
#define LogTrace(id)
void put(ID id, CI begin, CI end)
insert an object range with specified identifier
Definition: RangeMap.h:111
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...
static const double tmax[3]
int tmax() const
Strip hit maximum time bin.
Definition: CSCStripHit.h:44
const CSCRecoConditions * recoConditions_
const ChannelContainer & stripsTotal() const
The strips used in cluster to produce strip hit (total content)
Definition: CSCStripHit.h:47
float anodeBXoffset(const CSCDetId &detId) const
const CSCLayerGeometry * layergeom_
def bestMatch(object, matchCollection)
Definition: deltar.py:138
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.
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.
const ChannelContainer & strips() const
L1A.
Definition: CSCStripHit.h:50
LocalPoint stripWireIntersection(int strip, float wire) const
fixed size matrix
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_
float chamberTimingCorrection(const CSCDetId &id) const
CSCMake2DRecHit(const edm::ParameterSet &)
T x() const
Definition: PV3DBase.h:59
float stripAngle(int strip) const
const CSCChamber * chamber() const
Definition: CSCLayer.h:49
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:44
#define constexpr
short int deadWG() const
a dead WG in the cluster?
Definition: CSCWireHit.h:54
std::vector< int > ChannelContainer
Definition: CSCRecHit2D.h:20