CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/CalibMuon/CSCCalibration/src/CSCConditions.cc

Go to the documentation of this file.
00001 #include "CalibMuon/CSCCalibration/interface/CSCConditions.h"
00002 #include "FWCore/Framework/interface/EventSetup.h"
00003 #include "FWCore/Framework/interface/Event.h"
00004 #include "FWCore/Framework/interface/ESWatcher.h"
00005 #include "FWCore/Framework/interface/ESHandle.h"
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007 #include "FWCore/Framework/interface/MakerMacros.h"
00008 #include "CondFormats/DataRecord/interface/CSCDBPedestalsRcd.h"
00009 #include "CondFormats/DataRecord/interface/CSCDBNoiseMatrixRcd.h"
00010 #include "CondFormats/DataRecord/interface/CSCDBCrosstalkRcd.h"
00011 #include "CondFormats/CSCObjects/interface/CSCDBGains.h"
00012 #include "CondFormats/CSCObjects/interface/CSCDBPedestals.h"
00013 #include "CondFormats/CSCObjects/interface/CSCDBCrosstalk.h"
00014 #include "CondFormats/CSCObjects/interface/CSCBadStrips.h"
00015 #include "CondFormats/CSCObjects/interface/CSCBadWires.h"
00016 #include "CondFormats/CSCObjects/interface/CSCBadChambers.h"
00017 #include "CondFormats/CSCObjects/interface/CSCDBChipSpeedCorrection.h"
00018 #include "CondFormats/CSCObjects/interface/CSCChamberTimeCorrections.h"
00019 #include "DataFormats/MuonDetId/interface/CSCIndexer.h"
00020 
00021 CSCConditions::CSCConditions( const edm::ParameterSet& ps ) 
00022 : theGains(),
00023   theCrosstalk(),
00024   thePedestals(),
00025   theNoiseMatrix(),
00026   theBadStrips(),
00027   theBadWires(),
00028   theBadChambers(),
00029   theChipCorrections(),
00030   theChamberTimingCorrections(),
00031   readBadChannels_(false), readBadChambers_(false),useTimingCorrections_(false),
00032   theAverageGain( -1.0 )
00033 {
00034   readBadChannels_ = ps.getParameter<bool>("readBadChannels");
00035   readBadChambers_ = ps.getParameter<bool>("readBadChambers");
00036   useTimingCorrections_ = ps.getParameter<bool>("CSCUseTimingCorrections");
00037   // set size to hold all layers, using enum defined in .h
00038   badStripWords.resize( MAX_LAYERS, 0 );
00039   badWireWords.resize( MAX_LAYERS, 0 );
00040 }
00041 
00042 
00043 CSCConditions::~CSCConditions()
00044 {
00045 }
00046 
00047 void CSCConditions::initializeEvent(const edm::EventSetup & es)
00048 {
00049   // Strip gains
00050   es.get<CSCDBGainsRcd>().get( theGains );
00051   // Strip X-talk
00052   es.get<CSCDBCrosstalkRcd>().get( theCrosstalk );
00053   // Strip pedestals
00054   es.get<CSCDBPedestalsRcd>().get( thePedestals );
00055   // Strip autocorrelation noise matrix
00056   es.get<CSCDBNoiseMatrixRcd>().get(theNoiseMatrix);
00057 
00058   if ( useTimingCorrections()){
00059     // Buckeye chip speeds
00060     es.get<CSCDBChipSpeedCorrectionRcd>().get( theChipCorrections );
00061     // Cable lengths from chambers to peripheral crate and additional chamber level timing correction
00062     es.get<CSCChamberTimeCorrectionsRcd>().get( theChamberTimingCorrections );
00063   }
00064 
00065   if ( readBadChannels() ) {
00066   // Bad strip channels
00067     es.get<CSCBadStripsRcd>().get( theBadStrips );
00068   // Bad wiregroup channels
00069     es.get<CSCBadWiresRcd>().get( theBadWires );
00070 
00071     //@@    if( badStripsWatcher_.check( es ) ) { 
00072       fillBadStripWords();
00073     //@@    }
00074     //@@    if( badWiresWatcher_.check( es ) ) { 
00075       fillBadWireWords();
00076     //@    }
00077 
00078   }
00079 
00080   // Has GainsRcd changed?
00081   if( gainsWatcher_.check( es ) ) { // Yes...
00082     theAverageGain = -1.0; // ...reset, so next access will recalculate it
00083   }
00084  
00085   if ( readBadChambers() ) {
00086   // Entire bad chambers
00087     es.get<CSCBadChambersRcd>().get( theBadChambers );
00088   }
00089 
00090 //  print();
00091 }
00092 
00093 void CSCConditions::fillBadStripWords(){
00094   // reset existing values
00095   badStripWords.assign( MAX_LAYERS, 0 );
00096   if ( readBadChannels() ) {
00097     // unpack what we've read from theBadStrips
00098 
00099     // chambers is a vector<BadChamber>
00100     // channels is a vector<BadChannel>
00101     // Each BadChamber contains its index (1-468 or 540 w. ME42), the no. of bad channels, 
00102     // and the index within vector<BadChannel> where this chamber's bad channels start.
00103 
00104     CSCIndexer indexer;
00105 
00106     for ( size_t i=0; i<theBadStrips->chambers.size(); ++i ) { // loop over bad chambers
00107       int indexc = theBadStrips->chambers[i].chamber_index;
00108       int start =  theBadStrips->chambers[i].pointer;  // where this chamber's bad channels start in vector<BadChannel>
00109       int nbad  =  theBadStrips->chambers[i].bad_channels;
00110 
00111       CSCDetId id = indexer.detIdFromChamberIndex( indexc ); // We need this to build layer index (1-2808)
00112 
00113       for ( int j=start-1; j<start-1+nbad; ++j ) { // bad channels in this chamber
00114         short lay  = theBadStrips->channels[j].layer;    // value 1-6
00115         short chan = theBadStrips->channels[j].channel;  // value 1-80
00116     //    short f1 = theBadStrips->channels[j].flag1;
00117     //    short f2 = theBadStrips->channels[j].flag2;
00118     //    short f3 = theBadStrips->channels[j].flag3;
00119         int indexl = indexer.layerIndex( id.endcap(), id.station(), id.ring(), id.chamber(), lay );
00120         badStripWords[indexl-1].set( chan-1, 1 ); // set bit 0-79 in 80-bit bitset representing this layer
00121       } // j
00122     } // i
00123 
00124   } 
00125 }
00126 
00127 void CSCConditions::fillBadWireWords(){
00128   // reset existing values
00129   badWireWords.assign( MAX_LAYERS, 0 );
00130   if ( readBadChannels() ) {
00131     // unpack what we've read from theBadWires
00132     CSCIndexer indexer;
00133 
00134     for ( size_t i=0; i<theBadWires->chambers.size(); ++i ) { // loop over bad chambers
00135       int indexc = theBadWires->chambers[i].chamber_index;
00136       int start =  theBadWires->chambers[i].pointer;  // where this chamber's bad channels start in vector<BadChannel>
00137       int nbad  =  theBadWires->chambers[i].bad_channels;
00138 
00139       CSCDetId id = indexer.detIdFromChamberIndex( indexc ); // We need this to build layer index (1-2808)
00140 
00141       for ( int j=start-1; j<start-1+nbad; ++j ) { // bad channels in this chamber
00142         short lay  = theBadWires->channels[j].layer;    // value 1-6
00143         short chan = theBadWires->channels[j].channel;  // value 1-80
00144     //    short f1 = theBadWires->channels[j].flag1;
00145     //    short f2 = theBadWires->channels[j].flag2;
00146     //    short f3 = theBadWires->channels[j].flag3;
00147         int indexl = indexer.layerIndex( id.endcap(), id.station(), id.ring(), id.chamber(), lay );
00148         badWireWords[indexl-1].set( chan-1, 1 ); // set bit 0-111 in 112-bit bitset representing this layer
00149       } // j
00150     } // i
00151 
00152   } 
00153 }
00154 
00155 bool CSCConditions::isInBadChamber( const CSCDetId& id ) const {
00156   if ( readBadChambers() )  return theBadChambers->isInBadChamber( id );
00157   else return false;
00158 }
00159 
00160 void CSCConditions::print() const
00161   //@@ NEEDS THOROUGH UPDATING
00162 {
00163 /*
00164   std::cout << "SIZES: GAINS: " << theGains->gains.size()
00165             << "   PEDESTALS: " << thePedestals->pedestals.size()
00166             << "   NOISES "  << theNoiseMatrix->matrix.size() << std::endl;;
00167 
00168   std::map< int,std::vector<CSCDBGains::Item> >::const_iterator layerGainsItr = theGains->gains.begin(), 
00169       lastGain = theGains->gains.end();
00170   for( ; layerGainsItr != lastGain; ++layerGainsItr)
00171   {
00172     std::cout << "GAIN " << layerGainsItr->first 
00173               << " STRIPS " << layerGainsItr->second.size() << " "
00174               << layerGainsItr->second[0].gain_slope 
00175               << " " << layerGainsItr->second[0].gain_intercept << std::endl;
00176   }
00177 
00178   std::map< int,std::vector<CSCDBPedestals::Item> >::const_iterator pedestalItr = thePedestals->pedestals.begin(), 
00179                                                                   lastPedestal = thePedestals->pedestals.end();
00180   for( ; pedestalItr != lastPedestal; ++pedestalItr)
00181   {
00182     std::cout << "PEDS " << pedestalItr->first << " " 
00183               << " STRIPS " << pedestalItr->second.size() << " ";
00184     for(int i = 1; i < 80; ++i)
00185     {
00186        std::cout << pedestalItr->second[i-1].rms << " " ;
00187      }
00188      std::cout << std::endl;
00189   }
00190 
00191   std::map< int,std::vector<CSCDBCrosstalk::Item> >::const_iterator crosstalkItr = theCrosstalk->crosstalk.begin(),
00192                                                                   lastCrosstalk = theCrosstalk->crosstalk.end();
00193   for( ; crosstalkItr != lastCrosstalk; ++crosstalkItr)
00194   {
00195     std::cout << "XTALKS " << crosstalkItr->first 
00196       << " STRIPS " << crosstalkItr->second.size() << " "  
00197      << crosstalkItr->second[5].xtalk_slope_left << " " 
00198      << crosstalkItr->second[5].xtalk_slope_right << " " 
00199      << crosstalkItr->second[5].xtalk_intercept_left << " " 
00200      << crosstalkItr->second[5].xtalk_intercept_right << std::endl;
00201   }
00202 */
00203 }
00204 
00205 float CSCConditions::gain(const CSCDetId & detId, int channel) const
00206 {
00207   assert(theGains.isValid());
00208   return float( theGains->item(detId, channel).gain_slope )/theGains->factor_gain;
00209 }
00210 
00211 
00212 float CSCConditions::pedestal(const CSCDetId & detId, int channel) const
00213 {
00214   assert(thePedestals.isValid());
00215   return float ( thePedestals->item(detId, channel).ped )/thePedestals->factor_ped;
00216 }
00217 
00218 
00219 float CSCConditions::pedestalSigma(const CSCDetId&detId, int channel) const
00220 {
00221   assert(thePedestals.isValid());
00222   return float ( thePedestals->item(detId, channel).rms )/thePedestals->factor_rms;
00223 }
00224 
00225 
00226 float CSCConditions::crosstalkIntercept(const CSCDetId&detId, int channel, bool leftRight) const
00227 {
00228   assert(theCrosstalk.isValid());
00229   const CSCDBCrosstalk::Item & item = theCrosstalk->item(detId, channel);
00230 
00231   // resistive fraction is at the peak, where t=0
00232   return leftRight ? float ( item.xtalk_intercept_right )/theCrosstalk->factor_intercept 
00233                    : float ( item.xtalk_intercept_left )/theCrosstalk->factor_intercept ;
00234 }
00235 
00236 
00237 float CSCConditions::crosstalkSlope(const CSCDetId&detId, int channel, bool leftRight) const
00238 {
00239   assert(theCrosstalk.isValid());
00240   const CSCDBCrosstalk::Item & item = theCrosstalk->item(detId, channel);
00241 
00242   // resistive fraction is at the peak, where t=0
00243   return leftRight ? float ( item.xtalk_slope_right )/theCrosstalk->factor_slope
00244                    : float ( item.xtalk_slope_left )/theCrosstalk->factor_slope ;
00245 }
00246 
00247 const CSCDBNoiseMatrix::Item & CSCConditions::noiseMatrix(const CSCDetId& detId, int channel) const
00248 {
00249   assert(theNoiseMatrix.isValid());
00250   return theNoiseMatrix->item(detId, channel);
00251 }
00252 
00253 void CSCConditions::noiseMatrixElements( const CSCDetId& id, int channel, std::vector<float>& me ) const {
00254   assert(me.size()>11);
00255   const CSCDBNoiseMatrix::Item& item = noiseMatrix(id, channel);
00256   me[0] = float ( item.elem33 )/theNoiseMatrix->factor_noise;
00257   me[1] = float ( item.elem34 )/theNoiseMatrix->factor_noise;
00258   me[2] = float ( item.elem35 )/theNoiseMatrix->factor_noise;
00259   me[3] = float ( item.elem44 )/theNoiseMatrix->factor_noise;
00260   me[4] = float ( item.elem45 )/theNoiseMatrix->factor_noise;
00261   me[5] = float ( item.elem46 )/theNoiseMatrix->factor_noise;
00262   me[6] = float ( item.elem55 )/theNoiseMatrix->factor_noise;
00263   me[7] = float ( item.elem56 )/theNoiseMatrix->factor_noise;
00264   me[8] = float ( item.elem57 )/theNoiseMatrix->factor_noise;
00265   me[9] = float ( item.elem66 )/theNoiseMatrix->factor_noise;
00266   me[10] = float ( item.elem67 )/theNoiseMatrix->factor_noise;
00267   me[11] = float ( item.elem77 )/theNoiseMatrix->factor_noise;
00268 }
00269 
00270 void CSCConditions::crossTalk( const CSCDetId& id, int channel, std::vector<float>& ct ) const {
00271   assert(theCrosstalk.isValid());
00272   const CSCDBCrosstalk::Item & item = theCrosstalk->item(id, channel);
00273   ct[0] = float ( item.xtalk_slope_left )/theCrosstalk->factor_slope;
00274   ct[1] = float ( item.xtalk_intercept_left )/theCrosstalk->factor_intercept;
00275   ct[2] = float ( item.xtalk_slope_right )/theCrosstalk->factor_slope;
00276   ct[3] = float ( item.xtalk_intercept_right )/theCrosstalk->factor_intercept;
00277 }
00278 
00279 float CSCConditions::chipCorrection(const CSCDetId & detId, int stripChannel) const
00280 {
00281   if ( useTimingCorrections() ){
00282     assert(theChipCorrections.isValid());
00283     CSCIndexer indexer;
00284     int chip = indexer.chipIndex(stripChannel); //Converts 1-80(64) in a layer to 1-5(4), expects ME1/1a to be channel 65-80
00285     //printf("CSCCondition  e:%d s:%d r:%d c:%d l:%d strip:%d chip: %d\n",detId.endcap(),detId.station(), detId.ring(),detId.chamber(),detId.layer(),stripChannel,chip);
00286     return float ( theChipCorrections->item(detId,chip).speedCorr )/theChipCorrections->factor_speedCorr;
00287   }
00288   else
00289     return 0;
00290 }
00291 float CSCConditions::chamberTimingCorrection(const CSCDetId & detId) const
00292 {
00293   if ( useTimingCorrections() ){
00294     assert(theChamberTimingCorrections.isValid());
00295     return float ( theChamberTimingCorrections->item(detId).cfeb_tmb_skew_delay*1./theChamberTimingCorrections->factor_precision
00296                    + theChamberTimingCorrections->item(detId).cfeb_timing_corr*1./theChamberTimingCorrections->factor_precision
00297                    + (theChamberTimingCorrections->item(detId).cfeb_cable_delay*25.)
00298 );
00299   }
00300   else
00301     return 0;
00302 }
00303 float CSCConditions::anodeBXoffset(const CSCDetId & detId) const
00304 {
00305   if ( useTimingCorrections() ){
00306     assert(theChamberTimingCorrections.isValid());
00307     return float ( theChamberTimingCorrections->item(detId).anode_bx_offset*1./theChamberTimingCorrections->factor_precision);
00308   }
00309   else
00310     return 0;
00311 }
00312 
00313 const std::bitset<80>& CSCConditions::badStripWord( const CSCDetId& id ) const {
00314   CSCIndexer indexer;
00315   return badStripWords[indexer.layerIndex(id) - 1];
00316 }
00317 
00318 const std::bitset<112>& CSCConditions::badWireWord( const CSCDetId& id ) const {
00319   CSCIndexer indexer;
00320   return badWireWords[indexer.layerIndex(id) - 1]; 
00321 }
00322 
00327 float CSCConditions::averageGain() const {
00328 
00329   const float loEdge = 5.0; // consider gains above this
00330   const float hiEdge = 10.0; // consider gains below this
00331   const float loLimit = 6.0; // lowest acceptable average gain
00332   const float hiLimit = 9.0; // highest acceptable average gain
00333   const float expectedAverage = 7.5; // default average gain
00334 
00335   if ( theAverageGain > 0. ) return theAverageGain; // only recalculate if necessary
00336 
00337   int  n_strip   = 0;
00338   float gain_tot = 0.;
00339 
00340   CSCDBGains::GainContainer::const_iterator it;
00341   for ( it=theGains->gains.begin(); it!=theGains->gains.end(); ++it ) {
00342     float the_gain = float( it->gain_slope )/theGains->factor_gain;
00343     if (the_gain > loEdge && the_gain < hiEdge ) {
00344       gain_tot += the_gain;
00345       ++n_strip;
00346     }
00347   }
00348 
00349   // Average gain
00350   if ( n_strip > 0 ) {
00351     theAverageGain = gain_tot / n_strip;
00352   }
00353 
00354   // Average gain has been around 7.5 in real data
00355   if ( theAverageGain < loLimit || theAverageGain > hiLimit ) {
00356     //    LogTrace("CSC") << "Average CSC strip gain = "
00357     //                    << theAverageGain << "  is reset to expected value " << expectedAverage;
00358     theAverageGain = expectedAverage;
00359   }
00360 
00361   return theAverageGain;
00362 }