CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCHitFromStripOnly.cc
Go to the documentation of this file.
1 // This is CSCHitFromStripOnly.cc
2 
8 
10 
13 
16 
17 #include <algorithm>
18 #include <string>
19 #include <vector>
20 //#include <iostream>
21 
22 CSCHitFromStripOnly::CSCHitFromStripOnly( const edm::ParameterSet& ps ) : recoConditions_(0), calcped_(0), ganged_(0) {
23 
24  useCalib = ps.getParameter<bool>("CSCUseCalibrations");
25  bool useStaticPedestals = ps.getParameter<bool>("CSCUseStaticPedestals");
26  int noOfTimeBinsForDynamicPed = ps.getParameter<int>("CSCNoOfTimeBinsForDynamicPedestal");
27 
28  theThresholdForAPeak = ps.getParameter<double>("CSCStripPeakThreshold");
29  theThresholdForCluster = ps.getParameter<double>("CSCStripClusterChargeCut");
30 
31  LogTrace("CSCRecHit") << "[CSCHitFromStripOnly] CSCUseStaticPedestals = " << useStaticPedestals;
32  if ( !useStaticPedestals ) LogTrace("CSCRecHit") << "[CSCHitFromStripOnly] CSCNoOfTimeBinsForDynamicPedestal = "
33  << noOfTimeBinsForDynamicPed;
34 
35  if ( useStaticPedestals ) {
37  }
38  else {
39  if ( noOfTimeBinsForDynamicPed == 1 ) {
41  }
42  else {
43  calcped_ = new CSCDynamicPedestal2(); // NORMAL DEFAULT!
44  }
45  }
46 
47 }
48 
49 
51  delete calcped_;
52 }
53 
54 
55 /* runStrip
56  *
57  * Search for strip with ADC output exceeding theThresholdForAPeak. For each of these strips,
58  * build a cluster of strip of size theClusterSize (typically 3 strips). Finally, make
59  * a Strip Hit out of these clusters by finding the center-of-mass position of the hit
60  */
61 std::vector<CSCStripHit> CSCHitFromStripOnly::runStrip( const CSCDetId& id, const CSCLayer* layer,
62  const CSCStripDigiCollection::Range& rstripd )
63 {
64 
65  std::vector<CSCStripHit> hitsInLayer;
66 
67  // cache layer info for ease of access
68  id_ = id;
69  layer_ = layer;
70  nstrips_ = layer->chamber()->specs()->nStrips();
71 
72  setGanged(false);
73  if ( id_.ring() == 4 && layer_->chamber()->specs()->gangedStrips() ) setGanged(true); //@@ ONLY ME1/1A CAN BE GANGED
74 
75  LogTrace("CSCHitFromStripOnly") << "[CSCHitFromStripOnly::runStrip] id= " << id_ <<
76  " nstrips= " << nstrips_ << " ganged strips? " << ganged();
77 
78  tmax_cluster = 5;
79 
80  // Get gain correction weights for all strips in layer, and cache in gainWeight.
81  // They're used in fillPulseHeights below.
82  // When ME11a is ganged we only need the first 16 values of the 48 filled,
83  // but 17-48 are just duplicates of 1-16 anyway
84 
85  if ( useCalib ) {
87 
88  // *** START DUMP gainWeight
89  // std::cout << "gainWeight for id= " << id_ << " nstrips= " << nstrips_ << std::endl;
90  // for ( size_t i = 0; i!=10; ++i ) {
91  // for ( size_t j = 0; j!=8; ++j ) {
92  // std::cout << gainWeight[i*8 + j] << " ";
93  // }
94  // std::cout << std::endl;
95  // }
96  // *** END DUMP gainWeight
97 
98  }
99 
100  // Store pulseheights from SCA and find maxima (potential hits)
101  fillPulseHeights( rstripd );
102  findMaxima(id);
103 
104  // Make a Strip Hit out of each strip local maximum
105  for ( size_t imax = 0; imax != theMaxima.size(); ++imax ) {
106 
107  // Initialize parameters entering the CSCStripHit
109  theStrips.clear();
110  strips_adc.clear();
111  strips_adcRaw.clear();
112 
113  // makeCluster calls findHitOnStripPosition to determine the centroid position
114 
115  // Remember, the array starts at 0, but the stripId starts at 1...
116  float strippos = makeCluster( theMaxima[imax]+1 );
117 
118  //if ( strippos < 0 || tmax_cluster < 3 ){
119  // the strippos (as calculated here) is not used later on in
121  // with the negative charges allowed it can become negative
122  if ( tmax_cluster < 3 ){
123  theClosestMaximum.push_back(99); // to keep proper vector size
124  continue;
125  }
126  //---- If two maxima are too close the error assigned will be width/sqrt(12) - see CSCXonStrip_MatchGatti.cc
127  int maximum_to_left = 99; //---- If there is one maximum - the distance is set to 99 (strips)
128  int maximum_to_right = 99;
129  if(imax<theMaxima.size()-1){
130  maximum_to_right = theMaxima.at(imax+1) - theMaxima.at(imax);
131  }
132  if(imax>0 ){
133  maximum_to_left = theMaxima.at(imax-1) - theMaxima.at(imax);
134  }
135  if(fabs(maximum_to_right) < fabs(maximum_to_left)){
136  theClosestMaximum.push_back(maximum_to_right);
137  }
138  else{
139  theClosestMaximum.push_back(maximum_to_left);
140  }
141 
142  //---- Check if a neighbouring strip is a dead strip
143  //bool deadStrip = isNearDeadStrip(id, theMaxima.at(imax));
144  bool deadStripL = isDeadStrip(id, theMaxima.at(imax)-1, nstrips_);
145  bool deadStripR = isDeadStrip(id, theMaxima.at(imax)+1, nstrips_);
146  short int aDeadStrip = 0;
147  if(!deadStripL && !deadStripR){
148  aDeadStrip = 0;
149  }
150  else if(deadStripL && deadStripR){
151  aDeadStrip = 255;
152  }
153  else{
154  if(deadStripL){
155  aDeadStrip = theMaxima.at(imax)-1;
156  }
157  else{
158  aDeadStrip = theMaxima.at(imax)+1;
159  }
160  }
161 
164  std::vector<int> theL1AStrips;
165  for(int ila=0; ila<(int)theStrips.size(); ila++){
166  bool stripMatchCounter=false;
167  for ( auto itl1 = rstripd.first; itl1 != rstripd.second; ++itl1 ) {
168  int stripNproto = (*itl1).getStrip();
169  if( !ganged() ){
170  if(theStrips[ila]==stripNproto){
171  stripMatchCounter=true;
172  auto sz = (*itl1).getOverlappedSample().size();
173  int L1AbitOnPlace=0;
174  for(auto iBit=0UL; iBit<sz; iBit++){
175  L1AbitOnPlace |= ( (*itl1).getL1APhase(iBit) << (15-iBit));
176  }
177  theL1AStrips.push_back(theStrips[ila] | L1AbitOnPlace);
178  }
179  } else{
180  for(int tripl=0; tripl<3; ++tripl){
181  if(theStrips[ila]==(stripNproto+tripl*16)){
182  stripMatchCounter=true;
183  auto sz = (*itl1).getOverlappedSample().size();
184  int L1AbitOnPlace=0;
185  for(auto iBit=0UL; iBit<sz; iBit++){
186  L1AbitOnPlace |= ( (*itl1).getL1APhase(iBit) << (15-iBit));
187  }
188  theL1AStrips.push_back(theStrips[ila] | L1AbitOnPlace);
189  }
190  }
191  }
192  }
193  if(!stripMatchCounter){
194  theL1AStrips.push_back(theStrips[ila]);
195  }
196  }
198 
199  CSCStripHit striphit( id, strippos, tmax_cluster, theL1AStrips, strips_adc, strips_adcRaw,
200  theConsecutiveStrips.at(imax), theClosestMaximum.at(imax), aDeadStrip);
201  hitsInLayer.push_back( striphit );
202  }
203 
205  /*
206  for(std::vector<CSCStripHit>::const_iterator itSHit=hitsInLayer.begin(); itSHit!=hitsInLayer.end(); ++itSHit){
207  (*itSHit).print();
208  }
209  */
210 
211  return hitsInLayer;
212 }
213 
214 
215 /* makeCluster
216  *
217  */
218 float CSCHitFromStripOnly::makeCluster( int centerStrip ) {
219 
220  float strippos = -1.;
222  std::vector<CSCStripHitData> stripDataV;
223 
224  // We only want to use strip position in terms of strip # for the strip hit. //@@ What other choice is there?
225 
226  // If the cluster size is such that you go beyond the edge of detector, shrink cluster appropriately
227  for ( int i = 1; i < theClusterSize/2 + 1; ++i ) {
228 
229  if ( centerStrip - i < 1 || centerStrip + i > int(nstrips_) ) {
230 
231  // Shrink cluster size, but keep it an odd number of strips.
232  clusterSize = 2*i - 1;
233  }
234  }
235  for ( int i = -clusterSize/2; i <= clusterSize/2; ++i ) {
236  CSCStripHitData data = makeStripData(centerStrip, i);
237  stripDataV.push_back( data );
238  theStrips.push_back( centerStrip + i );
239  }
240  strippos = findHitOnStripPosition( stripDataV, centerStrip );
241 
242  LogTrace("CSCHitFromStripOnly") << "[CSCHitFromStripOnly::makeCluster] centerStrip= " << centerStrip <<
243  " strippos=" << strippos;
244 
245  return strippos;
246 }
247 
248 
253 
254  CSCStripHitData prelimData;
255  int thisStrip = centerStrip+offset;
256 
257  int tmax = thePulseHeightMap[centerStrip-1].tmax();
258  tmax_cluster = tmax;
259 
260  std::vector<float> adc(4);
261  std::vector<float> adcRaw(4);
262 
263  // Fill adc & adcRaw
264 
265  int istart = tmax-1;
266  int istop = std::min( tmax+2, 7 ) ; // there are only time bins 0-7
267  adc[3] = 0.1; // in case it isn't filled
268 
269  if ( tmax > 2 && tmax < 7 ) { // for time bins 3-6
270  int ibin = thisStrip-1;
271  if (thePulseHeightMap[ibin].valid()) {
272  std::copy( thePulseHeightMap[ibin].ph().begin()+istart,
273  thePulseHeightMap[ibin].ph().begin()+istop+1, adc.begin() );
274 
275  std::copy( thePulseHeightMap[ibin].phRaw().begin()+istart,
276  thePulseHeightMap[ibin].phRaw().begin()+istop+1, adcRaw.begin() );
277  }
278  }
279  else {
280  adc[0] = 0.1;
281  adc[1] = 0.1;
282  adc[2] = 0.1;
283  adc[3] = 0.1;
284  adcRaw = adc;
285  LogTrace("CSCRecHit") << "[CSCHitFromStripOnly::makeStripData] Tmax out of range: contact CSC expert!";
286  }
287 
288  if ( offset == 0 ) {
289  prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc);
290  } else {
291  int sign = offset>0 ? 1 : -1;
292  // If there's another maximum that would like to use part of this cluster,
293  // it gets shared in proportion to the height of the maxima
294  for ( int i = 1; i <= clusterSize/2; ++i ) {
295 
296  // Find the direction of the offset
297  int testStrip = thisStrip + sign*i;
298  std::vector<int>::iterator otherMax = find(theMaxima.begin(), theMaxima.end(), testStrip-1);
299 
300  // No other maxima found, so just store
301  if ( otherMax == theMaxima.end() ) {
302  prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc); }
303  else {
304 
305  // Another maximum found - share
306  std::vector<float> adc1(4);
307  std::vector<float> adcRaw1(4);
308  std::vector<float> adc2(4);
309  std::vector<float> adcRaw2(4);
310  // In case we only copy (below) into 3 of the 4 bins i.e. when istart=5, istop=7
311  adc1[3] = 0.1;
312  adc2[3] = 0.1;
313  adcRaw1[3] = 0.1;
314  adcRaw2[3] = 0.1;
315 
316  // Fill adcN with content of time bins tmax-1 to tmax+2 (if it exists!)
317  if ( tmax > 2 && tmax < 7 ) { // for time bin tmax from 3-6
318  int ibin = testStrip-1;
319  int jbin = centerStrip-1;
320  if (thePulseHeightMap[ibin].valid()) {
321  std::copy(thePulseHeightMap[ibin].ph().begin()+istart,
322  thePulseHeightMap[ibin].ph().begin()+istop+1, adc1.begin());
323  std::copy(thePulseHeightMap[ibin].phRaw().begin()+istart,
324  thePulseHeightMap[ibin].phRaw().begin()+istop+1, adcRaw1.begin());
325  }
326 
327  if (thePulseHeightMap[jbin].valid()) {
328  std::copy(thePulseHeightMap[jbin].ph().begin()+istart,
329  thePulseHeightMap[jbin].ph().begin()+istop+1, adc2.begin());
330 
331  std::copy(thePulseHeightMap[jbin].phRaw().begin()+istart,
332  thePulseHeightMap[jbin].phRaw().begin()+istop+1, adcRaw2.begin());
333  }
334  }
335  else {
336  adc1.assign(4, 0.1);
337  adcRaw1 = adc1;
338  adc2.assign(4, 0.1);
339  adcRaw2 = adc2;
340  }
341 
342  // Scale shared strip B ('adc') by ratio of peak of ADC counts from central strip A ('adc2')
343  // to sum of A and neighbouring maxima C ('adc1')
344 
345  for (size_t k = 0; k < 4; ++k){
346  if(adc1[k]>0 && adc2[k]>0) adc[k] = adc[k] * adc2[k] / ( adc1[k]+adc2[k] );
347  if(adcRaw1[k]>0 && adcRaw2[k]>0) adcRaw[k] = adcRaw[k] * adcRaw2[k] / ( adcRaw1[k]+adcRaw2[k] );
348  }
349  prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc);
350  }
351  }
352  }
353  return prelimData;
354 }
355 
356 
357 /* fillPulseHeights
358  *
359  */
361 
362  // Loop over strip digis in one CSCLayer and fill PulseHeightMap with pedestal-subtracted
363  // SCA pulse heights.
364 
365 
366  for (auto & ph : thePulseHeightMap) ph.reset();
367 
368  // for storing sca pulseheights once they may no longer be integer (e.g. after ped subtraction)
369  for ( CSCStripDigiCollection::const_iterator it = rstripd.first; it != rstripd.second; ++it ) {
370  int thisChannel = (*it).getStrip();
371  auto & stripData = thePulseHeightMap[thisChannel-1];
372  auto & scaRaw = stripData.phRaw_;
373  auto & sca = stripData.ph_;
374 
375  auto const & scaOri = (*it).getADCCounts();
376  assert(scaOri.size()==8);
377  // Fill sca from scaRaw, implicitly converting to float
378  std::copy( scaOri.begin(), scaOri.end(), scaRaw.begin());
379  std::copy( scaRaw.begin(), scaRaw.end(), sca.begin());
380 
381  //@@ Find bin with largest pulseheight (_before_ ped subtraction - shouldn't matter, right?)
382  int tmax = std::max_element( sca.begin(), sca.end() ) - sca.begin(); // counts from 0
383 
384  // get pedestal - calculated as appropriate - for this sca pulse
385  float ped = calcped_->pedestal(sca, recoConditions_, id_, thisChannel );
386 
387  // subtract the pedestal (from BOTH sets of sca pulseheights)
388  std::for_each( sca.begin(), sca.end(), CSCSubtractPedestal( ped ) );
389  std::for_each( scaRaw.begin(), scaRaw.end(), CSCSubtractPedestal( ped ) );
390 
391  //@@ Max in first 3 or last time bins is unacceptable, if so set to zero (why?)
392  float phmax = 0.f;
393  if ( tmax > 2 && tmax < 7 ) {
394  phmax = sca[tmax];
395  }
396  stripData.phmax_ = phmax;
397  stripData.tmax_ = tmax;
398 
399 
400  // Fill the map, possibly apply gains from cond data, and unfold ME1A channels
401  // (To apply gains use CSCStripData::op*= which scales only the non-raw sca ph's;
402  // but note that both sca & scaRaw are pedestal-subtracted.)
403 
404  // From StripDigi, thisChannel labels strip channel. Values phmax, tmax, scaRaw, sca belong to thisChannel
405  if ( useCalib ) stripData *= gainWeight[thisChannel-1];
406 
407  // for ganged ME1a need to duplicate values on istrip=thisChannel to iStrip+16 and iStrip+32
408  if ( ganged() ) {
409  for ( int j = 1; j < 3; ++j ) {
410  thePulseHeightMap[thisChannel-1+16*j] = stripData;
411  }
412  }
413 
414  }
415 }
416 
417 
418 /* findMaxima
419  *
420  * fills vector 'theMaxima' with the local maxima in the pulseheight distribution
421  * of the strips. The threshold defining a maximum is a configurable parameter.
422  * A typical value is 30.
423  */
425 
426  theMaxima.clear();
427  theConsecutiveStrips.clear();
428  theClosestMaximum.clear();
429  for ( size_t i=0; i!=thePulseHeightMap.size(); ++i ) {
430 
431  // sum 3 strips so that hits between strips are not suppressed
432  float heightCluster = 0.;
433 
434  bool maximumFound = false;
435  // Left edge of chamber
436  if( !isDeadStrip(id, i+1, nstrips_) ){ // Is it i or i+1
437  if ( i == 0 ) {
438  heightCluster = thePulseHeightMap[i].phmax()+thePulseHeightMap[i+1].phmax();
439  // Have found a strip Hit if...
440  if(thePulseHeightMap[i].phmax() >= thePulseHeightMap[i+1].phmax() &&
441  isPeakOK(i,heightCluster)){
442  theMaxima.push_back(i);
443  maximumFound = true;
444  }
445  // Right edge of chamber
446  } else if ( i == thePulseHeightMap.size()-1) {
447  heightCluster = thePulseHeightMap[i-1].phmax()+thePulseHeightMap[i].phmax();
448  // Have found a strip Hit if...
449  if(thePulseHeightMap[i].phmax() > thePulseHeightMap[i-1].phmax() &&
450  isPeakOK(i,heightCluster)){
451  theMaxima.push_back(i);
452  maximumFound = true;
453  }
454  // Any other strips
455  } else {
456  heightCluster = thePulseHeightMap[i-1].phmax()+thePulseHeightMap[i].phmax()+thePulseHeightMap[i+1].phmax();
457  // Have found a strip Hit if...
458  if(thePulseHeightMap[i].phmax() > thePulseHeightMap[i-1].phmax() &&
459  thePulseHeightMap[i].phmax() >= thePulseHeightMap[i+1].phmax() &&
460  isPeakOK(i,heightCluster)){
461  theMaxima.push_back(i);
462  maximumFound = true;
463  }
464  }
465  }
466  //---- Consecutive strips with charge (real cluster); if too wide - measurement is not accurate
467  if(maximumFound){
468  int numberOfConsecutiveStrips = 1;
469  float testThreshold = 10.;//---- ADC counts;
470  //---- this is not XTalk corrected so it is correct in first approximation only
471  int j = 0;
472  for(int l = 0; l<8; ++l){
473  if(j<0) edm::LogWarning("FailedStripCountingWrongConsecutiveStripNumber") << "This should never occur!!! Contact CSC expert!";
474  ++j;
475  bool signalPresent = false;
476  for(int k = 0; k<2; ++k){
477  j*= -1;//---- check from left and right
478  int anotherConsecutiveStrip = i+j;
479  if(anotherConsecutiveStrip>=0 && anotherConsecutiveStrip<int( thePulseHeightMap.size() )){
480  if(thePulseHeightMap[anotherConsecutiveStrip].phmax()>testThreshold){
481  ++numberOfConsecutiveStrips;
482  signalPresent = true;
483  }
484  }
485  }
486  if(!signalPresent){
487  break;
488  }
489  }
490  theConsecutiveStrips.push_back(numberOfConsecutiveStrips);
491  }
492  }
493 }
494 //
495 
496 bool CSCHitFromStripOnly::isPeakOK(int iStrip, float heightCluster){
497  int i = iStrip;
498  bool peakOK = ( thePulseHeightMap[i].phmax()>theThresholdForAPeak &&
499  heightCluster > theThresholdForCluster &&
500  // ... and proper peak time; note that the values below are used elsewhere in this file;
501  // they should become parameters or at least constants defined in appropriate place
502  thePulseHeightMap[i].tmax() > 2 && thePulseHeightMap[i].tmax() < 7);
503  return peakOK;
504 }
505 
506 
507 /* findHitOnStripPosition
508  *
509  */
510 float CSCHitFromStripOnly::findHitOnStripPosition( const std::vector<CSCStripHitData>& data, const int& centerStrip ) {
511 
512  float strippos = -1.;
513 
514  if ( data.size() < 1 ) return strippos;
515 
516  // biggestStrip is strip with largest pulse height
517  // Use pointer subtraction
518 
519  int biggestStrip = max_element(data.begin(), data.end()) - data.begin();
520  strippos = data[biggestStrip].strip() * 1.;
521 
522  // If more than one strip: use centroid to find center of cluster
523  // but only use time bin == tmax (otherwise, bias centroid).
524  float sum = 0.;
525  float sum_w= 0.;
526 
527  // std::vector<float> w(4);
528  // std::vector<float> wRaw(4);
529 
530  for ( size_t i = 0; i != data.size(); ++i ) {
531  auto const & w = data[i].ph();
532  auto const & wRaw = data[i].phRaw();
533 
534  // (Require ADC to be > 0.)
535  // No later studies suggest that this only do harm
536  /*
537  for ( size_t j = 0; j != w.size(); ++j ) {
538  if ( w[j] < 0. ) w[j] = 0.001;
539  }
540  */
541 
542 
543  // Fill the data members
544  std::copy( w.begin(), w.end(), std::back_inserter(strips_adc));
545  std::copy( wRaw.begin(), wRaw.end(), std::back_inserter(strips_adcRaw));
546 
547  if ( data[i].strip() < 1 ){
548  LogTrace("CSCRecHit") << "[CSCHitFromStripOnly::findHitOnStripPosition] problem in indexing of strip, strip= "
549  << data[i].strip();
550  }
551  sum_w += w[1];
552  sum += w[1] * data[i].strip();
553  }
554 
555  if ( sum_w > 0.) strippos = sum / sum_w;
556 
557  return strippos;
558 }
559 
560 bool CSCHitFromStripOnly::isNearDeadStrip(const CSCDetId& id, int centralStrip, int nstrips){
561 
562  //@@ Tim says: not sure I understand this properly... but just moved code to CSCRecoConditions
563  // where it can handle the conversion from strip to channel etc.
564  return recoConditions_->nearBadStrip( id, centralStrip, nstrips );
565 
566 }
567 
568 bool CSCHitFromStripOnly::isDeadStrip(const CSCDetId& id, int centralStrip, int nstrips ){
569  return recoConditions_->badStrip( id, centralStrip, nstrips );
570 
571 }
572 
573 // Define space for static
int adc(sample_type sample)
get the ADC sample (12 bits)
int nStrips() const
const CSCLayer * layer_
CSCPedestalChoice * calcped_
bool isNearDeadStrip(const CSCDetId &id, int centralStrip, int nstrips)
Is either neighbour &#39;bad&#39;?
T getParameter(std::string const &) const
void findMaxima(const CSCDetId &id)
Find local maxima.
int i
Definition: DBlmapReader.cc:9
std::vector< int > theConsecutiveStrips
const double w
Definition: UKUtility.cc:23
bool isDeadStrip(const CSCDetId &id, int centralStrip, int nstrips)
Is the strip &#39;bad&#39;?
double sign(double x)
assert(m_qm.get())
std::vector< CSCStripHit > runStrip(const CSCDetId &id, const CSCLayer *layer, const CSCStripDigiCollection::Range &rstripd)
std::vector< int > theStrips
std::vector< int > theClosestMaximum
bool nearBadStrip(const CSCDetId &id, int geomStrip, int nstrips) const
Is a neighbour bad?
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
float findHitOnStripPosition(const std::vector< CSCStripHitData > &data, const int &centerStrip)
Find position of hit in strip cluster in terms of strip #.
CSCHitFromStripOnly(const edm::ParameterSet &ps)
static const int theClusterSize
PulseHeightMap thePulseHeightMap
bool badStrip(const CSCDetId &id, int geomStrip, int nstrips) const
Is the strip bad?
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:42
const CSCRecoConditions * recoConditions_
int j
Definition: DBlmapReader.cc:9
virtual float pedestal(const std::vector< float > &sca, const CSCRecoConditions *cond=0, const CSCDetId id=0, int ichan=0)=0
bool gangedStrips() const
T min(T a, T b)
Definition: MathUtil.h:58
float makeCluster(int centerStrip)
Make clusters using local maxima.
#define LogTrace(id)
int ring() const
Definition: CSCDetId.h:88
static const double tmax[3]
std::vector< CSCStripDigi >::const_iterator const_iterator
std::vector< float > strips_adcRaw
std::vector< int > theMaxima
void stripWeights(const CSCDetId &id, short int nstrips, float *weights) const
bool isPeakOK(int iStrip, float heightCluster)
#define begin
Definition: vmac.h:30
std::vector< float > strips_adc
std::pair< const_iterator, const_iterator > Range
void fillPulseHeights(const CSCStripDigiCollection::Range &rstripd)
Store SCA pulseheight information from strips in digis of one layer.
CSCStripHitData makeStripData(int centerStrip, int offset)
const CSCChamber * chamber() const
Definition: CSCLayer.h:52