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