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