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 
24 
26  peakTimeFinder_( new CSCFindPeakTime( ps ) ){
27 
28  useCalib = ps.getParameter<bool>("CSCUseCalibrations");
29  stripWireDeltaTime = ps.getParameter<int>("CSCstripWireDeltaTime"); //@@ Non-standard CSC*s*trip...
30  useTimingCorrections= ps.getParameter<bool>("CSCUseTimingCorrections");
31  useGasGainCorrections = ps.getParameter<bool>("CSCUseGasGainCorrections");
32 
34 
35 }
36 
37 
39  delete xMatchGatti_;
40 }
41 
42 
44  const CSCWireHit& wHit, const CSCStripHit& sHit)
45 {
46  // Cache layer info for ease of access
47  layer_ = layer;
49  specs_ = layer->chamber()->specs();
50  id_ = id;
51 
52  const float sqrt_12 = 3.4641;
53 
54  float tpeak = -99.f;
55 
58 
59  // Find wire hit position and wire properties
60  wgroups = wHit.wgroups();
61 
62  int wg_left = wgroups[0];;
63  int wg_right = wgroups[wgroups.size()-1];
64 
65  int Nwires1 = layergeom_->numberOfWiresPerGroup( wg_left );
66  int Nwires2 = layergeom_->numberOfWiresPerGroup( wg_right );
67 
68  float Mwire1 = layergeom_->middleWireOfGroup( wg_left );
69  float Mwire2 = layergeom_->middleWireOfGroup( wg_right );
70 
71  int centerWire_left = (int) (Mwire1 - Nwires1 / 2. + 0.5);
72  int centerWire_right = (int) (Mwire2 + Nwires2 / 2.);
73 
74  float centerWire = (centerWire_left + centerWire_right) / 2.;
75 
76  //---- WGs around dead HV segment regions may need special treatment...
77  //---- This is not addressed here.
78 
79  float sigmaWire = 0.;
80  if(wHit.deadWG()>0 || wgroups.size()>2){
81  //---- worst possible case; take most conservative approach
82  for(unsigned int iWG=0;iWG<wgroups.size();iWG++){
83  sigmaWire+=layergeom_->yResolution( wgroups[iWG] );
84  }
85  }
86  else if(2==wgroups.size()){
87  //---- 2 WGs - get the larger error (overestimation if a single track is passing
88  //---- between the WGs; underestimation if there are two separate signal sources)
89  if(layergeom_->yResolution( wgroups[0] ) > layergeom_->yResolution( wgroups[1] )){
90  sigmaWire = layergeom_->yResolution( wgroups[0]);
91  }
92  else{
93  sigmaWire = layergeom_->yResolution( wgroups[1]);
94  }
95  }
96  else if(1==wgroups.size()){
97  //---- simple - just 1 WG
98  sigmaWire = layergeom_->yResolution( wgroups[0]);
99  }
100 
101  // Find strips position and properties
102 
104  int tmax = sHit.tmax();
105  int nStrip = strips.size();
106  int idCenterStrip = nStrip/2;
107  int centerStrip = strips[idCenterStrip];
108 
109  // Retrieve strip pulseheights from the CSCStripHit
110  const std::vector<float>& adc = sHit.s_adc();
111  const std::vector<float>& adcRaw = sHit.s_adcRaw();
112 
113  std::vector<float> adc2;
114  std::vector<float> adc2Raw;
115 
116  LogTrace("CSCMake2DRecHit") << "[CSCMake2DRecHit] dump of adc values to be added to rechit follows...";
117 
118  for ( int iStrip = 0; iStrip < nStrip; ++iStrip) {
119 
120  adc2.clear();
121  adc2Raw.clear();
122  adc2.reserve(4);
123  adc2Raw.reserve(4);
124  for ( int t = 0; t < 4; ++t ){
125  adc2.push_back(adc[t+iStrip*4]);
126  adc2Raw.push_back(adcRaw[t+iStrip*4]);
127  }
128  //After CMSSW_5_0: ADC value is pedestal-subtracted and electronics-gain corrected
129  adcMap.put( strips[iStrip], adc2.begin(), adc2.end() );
130  // Up to CMSSW_5_0, Rechit takes _raw_ adc values
131  // adcMap.put( strips[iStrip], adc2Raw.begin(), adc2Raw.end() );
132 
133  LogTrace("CSCMake2DRecHit") << "[CSCMake2DRecHit] strip = " << strips[iStrip] <<
134  " adcs= " << adc2Raw[0] << " " << adc2Raw[1] << " " << adc2Raw[2] << " " << adc2Raw[3];
135 
136  }
137 
138  //The tpeak finding for both edge and non-edge strips has been moved to here
139  //tpeak will be a const argument for xMatchGatti_->findXOnStrip
140  float adcArray[4];
141  for ( int t = 0; t < 4; ++t ) {
142  int k = t+4*(idCenterStrip);
143  adcArray[t] = adc[k];
144  }
145  tpeak = peakTimeFinder_->peakTime( tmax, adcArray, tpeak );
146  // Just for completeness, the start time of the pulse is 133 ns earlier, according to Stan :)
147  float t_zero = tpeak - 133.f;
148  LogTrace("CSCRecHit") << "[CSCMake2DRecHit] " <<
149  id << " strip=" << centerStrip << ", t_zero=" << t_zero << ", tpeak=" << tpeak;
150 
151 
152  float positionWithinTheStrip= -99.;
153  float sigmaWithinTheStrip = -99.;
154  int quality = -1;
155  LocalPoint lp0(0., 0.);
156 
157  float stripWidth = -99.f;
158  // If at the edge, then used 1 strip cluster only
159  if ( centerStrip == 1 || centerStrip == specs_->nStrips() || nStrip < 2 ) {
160  lp0 = layergeom_->stripWireIntersection( centerStrip, centerWire);
161  positionWithinTheStrip = 0.f;
162  stripWidth = layergeom_->stripPitch(lp0);
163  sigmaWithinTheStrip = stripWidth / sqrt_12;
164  quality = 2;
165  }
166  else {
167  // If not at the edge, used cluster of size ClusterSize:
168  LocalPoint lp11 = layergeom_->stripWireIntersection( centerStrip, centerWire);
169  stripWidth = layergeom_->stripPitch( lp11 );
170 
171  //---- Calculate local position within the strip
172  float xWithinChamber = lp11.x();
173  quality = 0;
174  if(layergeom_->inside(lp11 )){// save time; this hit is to be discarded anyway - see isHitInFiducial(...)
175 
176  xMatchGatti_->findXOnStrip( id, layer_, sHit, centerStrip,
177  xWithinChamber,
178  stripWidth, tpeak, positionWithinTheStrip,
179  sigmaWithinTheStrip, quality);
180  }
181  lp0 = LocalPoint( xWithinChamber, layergeom_->yOfWire(centerWire, xWithinChamber) );
182  }
183 
184 
185 
186  // compute the errors in local x and y
187  LocalError localerr = layergeom_->localError( centerStrip,
188  sigmaWithinTheStrip, sigmaWire );
189 
190  // Before storing the recHit, take the opportunity to change its time
192  float chipCorrection = recoConditions_->chipCorrection(id,centerStrip);
193  float phaseCorrection = (sHit.stripsl1a()[0]>> (15-0) & 0x1)*25.;
194  float chamberCorrection = recoConditions_->chamberTimingCorrection(id);
195 
196  GlobalPoint gp0 = layer_->toGlobal(lp0);
197  float tofCorrection = gp0.mag()/29.9792458;
198  float signalPropagationSpeed[11] = {0.0, -78, -76, -188, -262, -97, -99, -90, -99, -99, -113};
199  float position = lp0.y()/sin(layergeom_->stripAngle(centerStrip));
200  float yCorrection = position/signalPropagationSpeed[id_.iChamberType()];
201  //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);
202  //printf("\t tpeak before = %5.2f \t chipCorr %5.2f phaseCorr %5.2f chamberCorr %5.2f tofCorr %5.2f \n",
203  // tpeak,chipCorrection, phaseCorrection,chamberCorrection,tofCorrection);
204  //printf("localy = %5.2f, yCorr = %5.2f \n",lp0.y(),yCorrection);
205  tpeak = tpeak + chipCorrection + phaseCorrection + chamberCorrection-tofCorrection+yCorrection;
206  //printf("\t tpeak after = %5.2f\n",tpeak);
207  }
208 
209  // Calculate wire time to the half bx level using time bins on
210  // Store wire time with a precision of 0.01 as an int (multiply by 100)
211  // Convert from bx to ns (multiply by 25)
212  int scaledWireTime = 100*findWireBx(wHit.timeBinsOn(), tpeak,id)*25;
213 
214 
215  //Get the gas-gain correction for this rechit
216  float gasGainCorrection = -999.f;
217  if (useGasGainCorrections) {
218  gasGainCorrection = recoConditions_->gasGainCorrection(id,centerStrip,centerWire);
219  }
220 
229  float energyDeposit = -999.f;
230  if (gasGainCorrection < -998.f) {
231  // if the user has chosen not to use the gas gain correction, set the energy to a different nonsense value
232  energyDeposit = -998.f;
233 
234  } else if (gasGainCorrection < 0.f) {
235  // if the gas gain correction from the database is a bad value, set the energy to yet another nonsense value
236  energyDeposit = -997.f;
237 
238  } else {
239  // gas-gain correction is OK, correct the 3x3 ADC sum
240  if (adcMap.size()==12) {
241  energyDeposit =
242  adcMap[0] * gasGainCorrection + adcMap[1] * gasGainCorrection + adcMap[2] * gasGainCorrection +
243  adcMap[4] * gasGainCorrection + adcMap[5] * gasGainCorrection + adcMap[6] * gasGainCorrection +
244  adcMap[8] * gasGainCorrection + adcMap[9] * gasGainCorrection + adcMap[10]* gasGainCorrection ;
245 
246  } else if (adcMap.size()==4) {
247  // if this is an edge strip, set the energy to yet another nonsense value
248  energyDeposit = -996.f;
249  }
250 
251  }
252 
254 
256  CSCRecHit2D::ChannelContainer const & L1A_and_strips = sHit.stripsTotal();
257  CSCRecHit2D::ChannelContainer const & BX_and_wgroups = wHit.wgroupsBXandWire();
259  // (sigmaWithinTheStrip/stripWidth) is in strip widths just like positionWithinTheStrip is!
260 
261 
262  CSCRecHit2D rechit( id, lp0, localerr, L1A_and_strips,
263  //adcMap, wgroups, tpeak, positionWithinTheStrip,
264  adcMap, BX_and_wgroups, tpeak, positionWithinTheStrip,
265  sigmaWithinTheStrip/stripWidth, quality, sHit.deadStrip(), wHit.deadWG(), scaledWireTime,
266  energyDeposit);
267 
269  // rechit.print();
270 
271  LogTrace("CSCRecHit") << "[CSCMake2DRecHit] rechit created in layer " << id << "... \n" << rechit;
272 
273  return rechit;
274 
275 }
276 
277 
278 bool CSCMake2DRecHit::isHitInFiducial( const CSCLayer* layer, const CSCRecHit2D& rh ) {
279 
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 
294 
296  xMatchGatti_->setConditions( reco );
297  // And cache for use here
299 }
300 
301 float CSCMake2DRecHit::findWireBx(const std::vector <int>& timeBinsOn, float tpeak ,const CSCDetId& id) {
302  // Determine the wire Bx from the vector of time bins on for the wire digi with peak time as an intial estimate.
303  // Assumes that a single hit should create either one time bin on or two consecutive time bins on
304  // so algorithm looks for bin on nearest to peak time and checks if it has a bin on consecutive with it
305  float anode_bx_offset = recoConditions_->anodeBXoffset(id);
306  float wireBx=-1;
307  float timeGuess=tpeak/25.f + anode_bx_offset;
308  float diffMin=9999.f;
309  int bestMatch=-9;
310  for (int j=0; j<(int)timeBinsOn.size(); j++) {
311  auto diff=timeGuess-timeBinsOn[j];
312  // Find bin on closest to peak time
313  if (std::abs(diff)< std::abs(diffMin)) {
314  diffMin=diff;
315  bestMatch=j;
316  wireBx=timeBinsOn[j];
317  }
318  }
319  int side= diffMin>0 ? 1 : -1; // diffMin/fabs(diffMin);
320  bool unchanged=true;
321  // First check if bin on the same side as peak time is on
322  if ((bestMatch+side)>-1 && (bestMatch+side)<(int)timeBinsOn.size()) { // Make sure one next to it within vector limits
323  if (timeBinsOn[bestMatch]==(timeBinsOn[bestMatch+side]-side)) { // See if next bin on in vector is consecutive in time
324  // Set time to the average of the two bins
325  wireBx=wireBx+ 0.5f*side;
326  unchanged=false;
327  }
328  }
329  // If no match is found then check the other side
330  if ((bestMatch-side)>-1 && (bestMatch-side)<(int)timeBinsOn.size() && unchanged) { // Make sure one next to it exists
331  if (timeBinsOn[bestMatch]==(timeBinsOn[bestMatch-side]+side)) { // See if nextbin on is consecutive in time
332  wireBx=wireBx- 0.5f*side;
333  unchanged=false;
334  }
335  }
336  return wireBx - anode_bx_offset; // expect collision muons to be centered near 0 bx
337 }
int adc(sample_type sample)
get the ADC sample (12 bits)
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:41
const ChannelContainer & stripsl1a() const
L1A.
Definition: CSCStripHit.h:56
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:32
std::vector< int > timeBinsOn() const
Vector of time bins ON for central wire digi, lower of center pair if even number.
Definition: CSCWireHit.h:56
const StripHitADCContainer & s_adcRaw() const
the raw ADC counts for each of the strip within cluster
Definition: CSCStripHit.h:62
size_t size() const
return number of contained object
Definition: RangeMap.h:129
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
const StripHitADCContainer & s_adc() const
L1A.
Definition: CSCStripHit.h:59
int numberOfWiresPerGroup(int wireGroup) const
T y() const
Definition: PV3DBase.h:63
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:47
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:71
void setConditions(const CSCRecoConditions *reco)
Cache pointer to conditions data.
T mag() const
Definition: PV3DBase.h:67
CSCXonStrip_MatchGatti * xMatchGatti_
float yOfWire(float wire, float x=0.) const
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:42
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]
unsigned short iChamberType() const
Definition: CSCDetId.h:107
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:116
int k[5][pyjets_maxn]
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:47
const CSCRecoConditions * recoConditions_
const ChannelContainer & stripsTotal() const
The strips used in cluster to produce strip hit (total content)
Definition: CSCStripHit.h:50
float anodeBXoffset(const CSCDetId &detId) const
const CSCLayerGeometry * layergeom_
def bestMatch(object, matchCollection)
Definition: deltar.py:139
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:53
LocalPoint stripWireIntersection(int strip, float wire) const
fixed size matrix
static int position[264][3]
Definition: ReadPGInfo.cc:509
const std::unique_ptr< CSCFindPeakTime > peakTimeFinder_
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:50
float chamberTimingCorrection(const CSCDetId &id) const
CSCMake2DRecHit(const edm::ParameterSet &)
T x() const
Definition: PV3DBase.h:62
float stripAngle(int strip) const
const CSCChamber * chamber() const
Definition: CSCLayer.h:52
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:47
short int deadWG() const
a dead WG in the cluster?
Definition: CSCWireHit.h:53
std::vector< int > ChannelContainer
Definition: CSCRecHit2D.h:22