00001
00002
00003 #include "RecoLocalMuon/CSCRecHitD/src/CSCHitFromStripOnly.h"
00004 #include "RecoLocalMuon/CSCRecHitD/src/CSCStripData.h"
00005 #include "RecoLocalMuon/CSCRecHitD/src/CSCStripHitData.h"
00006 #include "RecoLocalMuon/CSCRecHitD/src/CSCStripHit.h"
00007 #include "RecoLocalMuon/CSCRecHitD/src/CSCPedestalChoice.h"
00008
00009 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00010
00011 #include "Geometry/CSCGeometry/interface/CSCLayer.h"
00012 #include "Geometry/CSCGeometry/interface/CSCChamberSpecs.h"
00013
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015 #include "FWCore/Utilities/interface/Exception.h"
00016
00017 #include <algorithm>
00018 #include <string>
00019 #include <vector>
00020
00021
00022 CSCHitFromStripOnly::CSCHitFromStripOnly( const edm::ParameterSet& ps ) : recoConditions_(0), calcped_(0) {
00023
00024 useCalib = ps.getParameter<bool>("CSCUseCalibrations");
00025 bool useStaticPedestals = ps.getParameter<bool>("CSCUseStaticPedestals");
00026 int noOfTimeBinsForDynamicPed = ps.getParameter<int>("CSCNoOfTimeBinsForDynamicPedestal");
00027
00028 theThresholdForAPeak = ps.getParameter<double>("CSCStripPeakThreshold");
00029 theThresholdForCluster = ps.getParameter<double>("CSCStripClusterChargeCut");
00030
00031 LogTrace("CSCRecHit") << "[CSCHitFromStripOnly] CSCUseStaticPedestals = " << useStaticPedestals;
00032 if ( !useStaticPedestals ) LogTrace("CSCRecHit") << "[CSCHitFromStripOnly] CSCNoOfTimeBinsForDynamicPedestal = "
00033 << noOfTimeBinsForDynamicPed;
00034
00035 if ( useStaticPedestals ) {
00036 calcped_ = new CSCStaticPedestal();
00037 }
00038 else {
00039 if ( noOfTimeBinsForDynamicPed == 1 ) {
00040 calcped_ = new CSCDynamicPedestal1();
00041 }
00042 else {
00043 calcped_ = new CSCDynamicPedestal2();
00044 }
00045 }
00046
00047 }
00048
00049
00050 CSCHitFromStripOnly::~CSCHitFromStripOnly() {
00051 delete calcped_;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061 std::vector<CSCStripHit> CSCHitFromStripOnly::runStrip( const CSCDetId& id, const CSCLayer* layer,
00062 const CSCStripDigiCollection::Range& rstripd )
00063 {
00064
00065 std::vector<CSCStripHit> hitsInLayer;
00066
00067
00068 id_ = id;
00069 layer_ = layer;
00070 nstrips_ = layer->chamber()->specs()->nStrips();
00071
00072 tmax_cluster = 5;
00073
00074
00075
00076 if ( useCalib ) {
00077 recoConditions_->stripWeights( id, gainWeight );
00078 }
00079
00080
00081 fillPulseHeights( rstripd );
00082 findMaxima(id);
00083
00084
00085 for ( size_t imax = 0; imax != theMaxima.size(); ++imax ) {
00086
00087
00088 clusterSize = theClusterSize;
00089 theStrips.clear();
00090 strips_adc.clear();
00091 strips_adcRaw.clear();
00092
00093
00094
00095
00096 float strippos = makeCluster( theMaxima[imax]+1 );
00097
00098
00099
00101
00102 if ( tmax_cluster < 3 ){
00103 theClosestMaximum.push_back(99);
00104 continue;
00105 }
00106
00107 int maximum_to_left = 99;
00108 int maximum_to_right = 99;
00109 if(imax<theMaxima.size()-1){
00110 maximum_to_right = theMaxima.at(imax+1) - theMaxima.at(imax);
00111 }
00112 if(imax>0 ){
00113 maximum_to_left = theMaxima.at(imax-1) - theMaxima.at(imax);
00114 }
00115 if(fabs(maximum_to_right) < fabs(maximum_to_left)){
00116 theClosestMaximum.push_back(maximum_to_right);
00117 }
00118 else{
00119 theClosestMaximum.push_back(maximum_to_left);
00120 }
00121
00122
00123
00124 bool deadStripL = isDeadStrip(id, theMaxima.at(imax)-1);
00125 bool deadStripR = isDeadStrip(id, theMaxima.at(imax)+1);
00126 short int aDeadStrip = 0;
00127 if(!deadStripL && !deadStripR){
00128 aDeadStrip = 0;
00129 }
00130 else if(deadStripL && deadStripR){
00131 aDeadStrip = 255;
00132 }
00133 else{
00134 if(deadStripL){
00135 aDeadStrip = theMaxima.at(imax)-1;
00136 }
00137 else{
00138 aDeadStrip = theMaxima.at(imax)+1;
00139 }
00140 }
00141
00142
00145 std::vector<int> theL1AStrips;
00146 for(int ila=0; ila<(int)theStrips.size(); ila++){
00147 bool stripMatchCounter=false;
00148 for ( CSCStripDigiCollection::const_iterator itl1 = rstripd.first; itl1 != rstripd.second; ++itl1 ) {
00149 int stripNproto = (*itl1).getStrip();
00150 if(id_.ring() != 4){
00151 if(theStrips[ila]==stripNproto){
00152 stripMatchCounter=true;
00153 std::vector<int> L1AP=(*itl1).getL1APhase();
00154 int L1AbitOnPlace=0;
00155 for(int iBit=0; iBit<(int)L1AP.size(); iBit++){
00156 L1AbitOnPlace=L1AbitOnPlace|(L1AP[iBit] << (15-iBit));
00157 }
00158 theL1AStrips.push_back(theStrips[ila] | L1AbitOnPlace);
00159 }
00160 }
00161 else{
00162 for(int tripl=0; tripl<3; ++tripl){
00163 if(theStrips[ila]==(stripNproto+tripl*16)){
00164 stripMatchCounter=true;
00165 std::vector<int> L1AP=(*itl1).getL1APhase();
00166 int L1AbitOnPlace=0;
00167 for(int iBit=0; iBit<(int)L1AP.size(); iBit++){
00168 L1AbitOnPlace=L1AbitOnPlace|(L1AP[iBit] << (15-iBit));
00169 }
00170 theL1AStrips.push_back(theStrips[ila] | L1AbitOnPlace);
00171 }
00172 }
00173 }
00174 }
00175 if(!stripMatchCounter){
00176 theL1AStrips.push_back(theStrips[ila]);
00177 }
00178 }
00180
00181 CSCStripHit striphit( id, strippos, tmax_cluster, theL1AStrips, strips_adc, strips_adcRaw,
00182 theConsecutiveStrips.at(imax), theClosestMaximum.at(imax), aDeadStrip);
00183 hitsInLayer.push_back( striphit );
00184 }
00185
00187
00188
00189
00190
00191
00192 return hitsInLayer;
00193 }
00194
00195
00196
00197
00198
00199 float CSCHitFromStripOnly::makeCluster( int centerStrip ) {
00200
00201 float strippos = -1.;
00202 clusterSize = theClusterSize;
00203 std::vector<CSCStripHitData> stripDataV;
00204
00205
00206
00207
00208 for ( int i = 1; i < theClusterSize/2 + 1; ++i ) {
00209
00210 if ( centerStrip - i < 1 || centerStrip + i > int(nstrips_) ) {
00211
00212
00213 clusterSize = 2*i - 1;
00214 }
00215 }
00216 for ( int i = -clusterSize/2; i <= clusterSize/2; ++i ) {
00217 CSCStripHitData data = makeStripData(centerStrip, i);
00218 stripDataV.push_back( data );
00219 theStrips.push_back( centerStrip + i );
00220 }
00221 strippos = findHitOnStripPosition( stripDataV, centerStrip );
00222
00223 return strippos;
00224 }
00225
00226
00230 CSCStripHitData CSCHitFromStripOnly::makeStripData(int centerStrip, int offset) {
00231
00232 CSCStripHitData prelimData;
00233 int thisStrip = centerStrip+offset;
00234
00235 int tmax = thePulseHeightMap[centerStrip-1].tmax();
00236 tmax_cluster = tmax;
00237
00238 std::vector<float> adc(4);
00239 std::vector<float> adcRaw(4);
00240
00241
00242
00243 int istart = tmax-1;
00244 int istop = std::min( tmax+2, 7 ) ;
00245 adc[3] = 0.1;
00246
00247 if ( tmax > 2 && tmax < 7 ) {
00248 int ibin = thisStrip-1;
00249
00250 std::copy( thePulseHeightMap[ibin].ph().begin()+istart,
00251 thePulseHeightMap[ibin].ph().begin()+istop+1, adc.begin() );
00252
00253 std::copy( thePulseHeightMap[ibin].phRaw().begin()+istart,
00254 thePulseHeightMap[ibin].phRaw().begin()+istop+1, adcRaw.begin() );
00255 }
00256 else {
00257 adc[0] = 0.1;
00258 adc[1] = 0.1;
00259 adc[2] = 0.1;
00260 adc[3] = 0.1;
00261 adcRaw = adc;
00262 LogTrace("CSCRecHit") << "[CSCHitFromStripOnly::makeStripData] Tmax out of range: contact CSC expert!";
00263 }
00264
00265 if ( offset == 0 ) {
00266 prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc);
00267 } else {
00268 int sign = offset>0 ? 1 : -1;
00269
00270
00271 for ( int i = 1; i <= clusterSize/2; ++i ) {
00272
00273
00274 int testStrip = thisStrip + sign*i;
00275 std::vector<int>::iterator otherMax = find(theMaxima.begin(), theMaxima.end(), testStrip-1);
00276
00277
00278 if ( otherMax == theMaxima.end() ) {
00279 prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc); }
00280 else {
00281
00282
00283 std::vector<float> adc1(4);
00284 std::vector<float> adcRaw1(4);
00285 std::vector<float> adc2(4);
00286 std::vector<float> adcRaw2(4);
00287
00288 adc1[3] = 0.1;
00289 adc2[3] = 0.1;
00290 adcRaw1[3] = 0.1;
00291 adcRaw2[3] = 0.1;
00292
00293
00294 if ( tmax > 2 && tmax < 7 ) {
00295 int ibin = testStrip-1;
00296 int jbin = centerStrip-1;
00297 std::copy(thePulseHeightMap[ibin].ph().begin()+istart,
00298 thePulseHeightMap[ibin].ph().begin()+istop+1, adc1.begin());
00299
00300 std::copy(thePulseHeightMap[ibin].phRaw().begin()+istart,
00301 thePulseHeightMap[ibin].phRaw().begin()+istop+1, adcRaw1.begin());
00302
00303 std::copy(thePulseHeightMap[jbin].ph().begin()+istart,
00304 thePulseHeightMap[jbin].ph().begin()+istop+1, adc2.begin());
00305
00306 std::copy(thePulseHeightMap[jbin].phRaw().begin()+istart,
00307 thePulseHeightMap[jbin].phRaw().begin()+istop+1, adcRaw2.begin());
00308 }
00309 else {
00310 adc1.assign(4, 0.1);
00311 adcRaw1 = adc1;
00312 adc2.assign(4, 0.1);
00313 adcRaw2 = adc2;
00314 }
00315
00316
00317
00318
00319 for (size_t k = 0; k < 4; ++k){
00320 if(adc1[k]>0 && adc2[k]>0) adc[k] = adc[k] * adc2[k] / ( adc1[k]+adc2[k] );
00321 if(adcRaw1[k]>0 && adcRaw2[k]>0) adcRaw[k] = adcRaw[k] * adcRaw2[k] / ( adcRaw1[k]+adcRaw2[k] );
00322 }
00323 prelimData = CSCStripHitData(thisStrip, tmax_cluster, adcRaw, adc);
00324 }
00325 }
00326 }
00327 return prelimData;
00328 }
00329
00330
00331
00332
00333
00334 void CSCHitFromStripOnly::fillPulseHeights( const CSCStripDigiCollection::Range& rstripd ) {
00335
00336
00337
00338
00339 thePulseHeightMap.clear();
00340 thePulseHeightMap.resize(100);
00341
00342
00343 std::vector<float> sca;
00344 sca.reserve(8);
00345 for ( CSCStripDigiCollection::const_iterator it = rstripd.first; it != rstripd.second; ++it ) {
00346 int thisChannel = (*it).getStrip();
00347 std::vector<int> scaRaw = (*it).getADCCounts();
00348 sca.clear();
00349
00350 std::copy( scaRaw.begin(), scaRaw.end(), std::back_inserter( sca ));
00351
00352
00353 int tmax = std::max_element( sca.begin(), sca.end() ) - sca.begin();
00354
00355
00356 float ped = calcped_->pedestal(sca, recoConditions_, id_, thisChannel );
00357
00358
00359 std::for_each( sca.begin(), sca.end(), CSCSubtractPedestal( ped ) );
00360 std::for_each( scaRaw.begin(), scaRaw.end(), CSCSubtractPedestal( ped ) );
00361
00362
00363 float phmax = 0.;
00364 if ( tmax > 2 && tmax < 7 ) {
00365 phmax = sca[tmax];
00366 }
00367
00368
00369
00370
00371
00372 if ( id_.ring() != 4 ) {
00373 thePulseHeightMap[thisChannel-1] = CSCStripData( thisChannel, phmax, tmax, scaRaw, sca );
00374 if ( useCalib ) thePulseHeightMap[thisChannel-1] *= gainWeight[thisChannel-1];
00375 }
00376 else {
00377 for ( int j = 0; j < 3; ++j ) {
00378 thePulseHeightMap[thisChannel-1+16*j] = CSCStripData( thisChannel+16*j, phmax, tmax, scaRaw, sca );
00379 if ( useCalib ) thePulseHeightMap[thisChannel-1+16*j] *= gainWeight[thisChannel-1];
00380 }
00381 }
00382
00383 }
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393 void CSCHitFromStripOnly::findMaxima(const CSCDetId& id) {
00394
00395 theMaxima.clear();
00396 theConsecutiveStrips.clear();
00397 theClosestMaximum.clear();
00398 for ( size_t i=0; i!=thePulseHeightMap.size(); ++i ) {
00399
00400
00401 float heightCluster = 0.;
00402
00403 bool maximumFound = false;
00404
00405 if(!isDeadStrip(id, i+1)){
00406 if ( i == 0 ) {
00407 heightCluster = thePulseHeightMap[i].phmax()+thePulseHeightMap[i+1].phmax();
00408
00409 if(thePulseHeightMap[i].phmax() >= thePulseHeightMap[i+1].phmax() &&
00410 isPeakOK(i,heightCluster)){
00411 theMaxima.push_back(i);
00412 maximumFound = true;
00413 }
00414
00415 } else if ( i == thePulseHeightMap.size()-1) {
00416 heightCluster = thePulseHeightMap[i-1].phmax()+thePulseHeightMap[i].phmax();
00417
00418 if(thePulseHeightMap[i].phmax() > thePulseHeightMap[i-1].phmax() &&
00419 isPeakOK(i,heightCluster)){
00420 theMaxima.push_back(i);
00421 maximumFound = true;
00422 }
00423
00424 } else {
00425 heightCluster = thePulseHeightMap[i-1].phmax()+thePulseHeightMap[i].phmax()+thePulseHeightMap[i+1].phmax();
00426
00427 if(thePulseHeightMap[i].phmax() > thePulseHeightMap[i-1].phmax() &&
00428 thePulseHeightMap[i].phmax() >= thePulseHeightMap[i+1].phmax() &&
00429 isPeakOK(i,heightCluster)){
00430 theMaxima.push_back(i);
00431 maximumFound = true;
00432 }
00433 }
00434 }
00435
00436 if(maximumFound){
00437 int numberOfConsecutiveStrips = 1;
00438 float testThreshold = 10.;
00439
00440 int j = 0;
00441 for(int l = 0; l<8; ++l){
00442 if(j<0) edm::LogWarning("FailedStripCountingWrongConsecutiveStripNumber") << "This should never occur!!! Contact CSC expert!";
00443 ++j;
00444 bool signalPresent = false;
00445 for(int k = 0; k<2; ++k){
00446 j*= -1;
00447 int anotherConsecutiveStrip = i+j;
00448 if(anotherConsecutiveStrip>=0 && anotherConsecutiveStrip<int( thePulseHeightMap.size() )){
00449 if(thePulseHeightMap[anotherConsecutiveStrip].phmax()>testThreshold){
00450 ++numberOfConsecutiveStrips;
00451 signalPresent = true;
00452 }
00453 }
00454 }
00455 if(!signalPresent){
00456 break;
00457 }
00458 }
00459 theConsecutiveStrips.push_back(numberOfConsecutiveStrips);
00460 }
00461 }
00462 }
00463
00464
00465 bool CSCHitFromStripOnly::isPeakOK(int iStrip, float heightCluster){
00466 int i = iStrip;
00467 bool peakOK = ( thePulseHeightMap[i].phmax()>theThresholdForAPeak &&
00468 heightCluster > theThresholdForCluster &&
00469
00470
00471 thePulseHeightMap[i].tmax() > 2 && thePulseHeightMap[i].tmax() < 7);
00472 return peakOK;
00473 }
00474
00475
00476
00477
00478
00479 float CSCHitFromStripOnly::findHitOnStripPosition( const std::vector<CSCStripHitData>& data, const int& centerStrip ) {
00480
00481 float strippos = -1.;
00482
00483 if ( data.size() < 1 ) return strippos;
00484
00485
00486
00487
00488 int biggestStrip = max_element(data.begin(), data.end()) - data.begin();
00489 strippos = data[biggestStrip].strip() * 1.;
00490
00491
00492
00493 float sum = 0.;
00494 float sum_w= 0.;
00495
00496 std::vector<float> w(4);
00497 std::vector<float> wRaw(4);
00498
00499 for ( size_t i = 0; i != data.size(); ++i ) {
00500 w = data[i].ph();
00501 wRaw = data[i].phRaw();
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 std::copy( w.begin(), w.end(), std::back_inserter(strips_adc));
00514 std::copy( wRaw.begin(), wRaw.end(), std::back_inserter(strips_adcRaw));
00515
00516 if ( data[i].strip() < 1 ){
00517 LogTrace("CSCRecHit") << "problem in indexing of strip, strip id is: " << data[i].strip();
00518 }
00519 sum_w += w[1];
00520 sum += w[1] * data[i].strip();
00521 }
00522
00523 if ( sum_w > 0.) strippos = sum / sum_w;
00524
00525 return strippos;
00526 }
00527
00528 bool CSCHitFromStripOnly::isNearDeadStrip(const CSCDetId& id, int centralStrip){
00529
00530
00531
00532 return recoConditions_->nearBadStrip( id, centralStrip );
00533
00534 }
00535
00536 bool CSCHitFromStripOnly::isDeadStrip(const CSCDetId& id, int centralStrip){
00537 return recoConditions_->badStrip( id, centralStrip );
00538
00539 }
00540
00541
00542 const int CSCHitFromStripOnly::theClusterSize;