CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/CalibMuon/CSCCalibration/src/CSCConditions.cc

Go to the documentation of this file.
00001 #include "CalibMuon/CSCCalibration/interface/CSCConditions.h"
00002 
00003 #include "CalibMuon/CSCCalibration/interface/CSCChannelMapperRecord.h"
00004 #include "CalibMuon/CSCCalibration/interface/CSCIndexerRecord.h"
00005 
00006 #include "CalibMuon/CSCCalibration/interface/CSCChannelMapperBase.h"
00007 #include "CalibMuon/CSCCalibration/interface/CSCIndexerBase.h"
00008 
00009 #include "FWCore/Framework/interface/EventSetup.h"
00010 #include "FWCore/Framework/interface/Event.h"
00011 #include "FWCore/Framework/interface/ESWatcher.h"
00012 #include "FWCore/Framework/interface/ESHandle.h"
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 #include "FWCore/Framework/interface/MakerMacros.h"
00015 
00016 #include "CondFormats/DataRecord/interface/CSCDBChipSpeedCorrectionRcd.h"
00017 #include "CondFormats/DataRecord/interface/CSCChamberTimeCorrectionsRcd.h"
00018 #include "CondFormats/DataRecord/interface/CSCDBGasGainCorrectionRcd.h"
00019 #include "CondFormats/DataRecord/interface/CSCDBPedestalsRcd.h"
00020 #include "CondFormats/DataRecord/interface/CSCDBNoiseMatrixRcd.h"
00021 #include "CondFormats/DataRecord/interface/CSCDBCrosstalkRcd.h"
00022 
00023 #include "CondFormats/CSCObjects/interface/CSCDBGains.h"
00024 #include "CondFormats/CSCObjects/interface/CSCDBPedestals.h"
00025 #include "CondFormats/CSCObjects/interface/CSCDBCrosstalk.h"
00026 #include "CondFormats/CSCObjects/interface/CSCDBChipSpeedCorrection.h"
00027 #include "CondFormats/CSCObjects/interface/CSCChamberTimeCorrections.h"
00028 #include "CondFormats/CSCObjects/interface/CSCDBGasGainCorrection.h"
00029 
00030 #include "CondFormats/DataRecord/interface/CSCBadChambersRcd.h"
00031 
00032 #include "CondFormats/CSCObjects/interface/CSCBadStrips.h"
00033 #include "CondFormats/CSCObjects/interface/CSCBadWires.h"
00034 #include "CondFormats/CSCObjects/interface/CSCBadChambers.h"
00035 
00036 CSCConditions::CSCConditions( const edm::ParameterSet& ps )
00037 : theGains(), theCrosstalk(), thePedestals(), theNoiseMatrix(),
00038   theBadStrips(), theBadWires(), theBadChambers(),
00039   theChipCorrections(), theChamberTimingCorrections(), theGasGainCorrections(),
00040   indexer_(0), mapper_(0),
00041   readBadChannels_(false), readBadChambers_(false),
00042   useTimingCorrections_(false), useGasGainCorrections_(false), theAverageGain( -1.0 )
00043 {
00044   readBadChannels_ = ps.getParameter<bool>("readBadChannels");
00045   readBadChambers_ = ps.getParameter<bool>("readBadChambers");
00046   useTimingCorrections_ = ps.getParameter<bool>("CSCUseTimingCorrections");
00047   useGasGainCorrections_ = ps.getParameter<bool>("CSCUseGasGainCorrections");
00048 
00049   // set size to hold all layers, using enum defined in .h
00050   badStripWords.resize( MAX_LAYERS, 0 );
00051   badWireWords.resize( MAX_LAYERS, 0 );
00052 }
00053 
00054 
00055 CSCConditions::~CSCConditions(){}
00056 
00057 void CSCConditions::initializeEvent(const edm::EventSetup & es)
00058 {
00059   // Algorithms
00060   es.get<CSCIndexerRecord>().get( indexer_ );
00061   es.get<CSCChannelMapperRecord>().get( mapper_ );
00062 
00063   // Strip gains
00064   es.get<CSCDBGainsRcd>().get( theGains );
00065   // Strip X-talk
00066   es.get<CSCDBCrosstalkRcd>().get( theCrosstalk );
00067   // Strip pedestals
00068   es.get<CSCDBPedestalsRcd>().get( thePedestals );
00069   // Strip autocorrelation noise matrix
00070   es.get<CSCDBNoiseMatrixRcd>().get( theNoiseMatrix );
00071 
00072   if ( useTimingCorrections()){
00073     // Buckeye chip speeds
00074     es.get<CSCDBChipSpeedCorrectionRcd>().get( theChipCorrections );
00075     // Cable lengths from chambers to peripheral crate and additional chamber level timing correction
00076     es.get<CSCChamberTimeCorrectionsRcd>().get( theChamberTimingCorrections );
00077   }
00078 
00079   if ( readBadChannels() ) {
00080   // Bad strip channels
00081     es.get<CSCBadStripsRcd>().get( theBadStrips );
00082   // Bad wiregroup channels
00083     es.get<CSCBadWiresRcd>().get( theBadWires );
00084 
00085     //@@    if( badStripsWatcher_.check( es ) ) {
00086       fillBadStripWords();
00087     //@@    }
00088     //@@    if( badWiresWatcher_.check( es ) ) {
00089       fillBadWireWords();
00090     //@    }
00091 
00092   }
00093 
00094   // Has GainsRcd changed?
00095   if( gainsWatcher_.check( es ) ) { // Yes...
00096     theAverageGain = -1.0; // ...reset, so next access will recalculate it
00097   }
00098 
00099   if ( readBadChambers() ) {
00100   // Entire bad chambers
00101     es.get<CSCBadChambersRcd>().get( theBadChambers );
00102   }
00103 
00104   if ( useGasGainCorrections()){
00105     es.get<CSCDBGasGainCorrectionRcd>().get( theGasGainCorrections );
00106   }
00107 
00108 //  print();
00109 }
00110 
00111 void CSCConditions::fillBadStripWords(){
00112   //@@ NOT YET THOUGHT THROUGH FOR UNGANGED ME11A
00113 
00114   // reset existing values
00115   badStripWords.assign( MAX_LAYERS, 0 );
00116   if ( readBadChannels() ) {
00117     // unpack what we've read from theBadStrips
00118 
00119     // chambers is a vector<BadChamber>
00120     // channels is a vector<BadChannel>
00121     // Each BadChamber contains its index (1-468 or 540 w. ME42), the no. of bad channels,
00122     // and the index within vector<BadChannel> where this chamber's bad channels start.
00123 
00124     for ( size_t i=0; i<theBadStrips->chambers.size(); ++i ) { // loop over bad chambers
00125       int indexc = theBadStrips->chambers[i].chamber_index;
00126       int start =  theBadStrips->chambers[i].pointer;  // where this chamber's bad channels start in vector<BadChannel>
00127       int nbad  =  theBadStrips->chambers[i].bad_channels;
00128 
00129       CSCDetId id = indexer_->detIdFromChamberIndex( indexc ); // We need this to build layer index (1-2808)
00130 
00131       for ( int j=start-1; j<start-1+nbad; ++j ) { // bad channels in this chamber
00132         short lay  = theBadStrips->channels[j].layer;    // value 1-6
00133         short chan = theBadStrips->channels[j].channel;  // value 1-80
00134     //    short f1 = theBadStrips->channels[j].flag1;
00135     //    short f2 = theBadStrips->channels[j].flag2;
00136     //    short f3 = theBadStrips->channels[j].flag3;
00137         int indexl = indexer_->layerIndex( id.endcap(), id.station(), id.ring(), id.chamber(), lay );
00138         badStripWords[indexl-1].set( chan-1, 1 ); // set bit 0-79 in 80-bit bitset representing this layer
00139       } // j
00140     } // i
00141 
00142   }
00143 }
00144 
00145 void CSCConditions::fillBadWireWords(){
00146   // reset existing values
00147   badWireWords.assign( MAX_LAYERS, 0 );
00148   if ( readBadChannels() ) {
00149     // unpack what we've read from theBadWires
00150 
00151     for ( size_t i=0; i<theBadWires->chambers.size(); ++i ) { // loop over bad chambers
00152       int indexc = theBadWires->chambers[i].chamber_index;
00153       int start =  theBadWires->chambers[i].pointer;  // where this chamber's bad channels start in vector<BadChannel>
00154       int nbad  =  theBadWires->chambers[i].bad_channels;
00155 
00156       CSCDetId id = indexer_->detIdFromChamberIndex( indexc ); // We need this to build layer index (1-2808)
00157 
00158       for ( int j=start-1; j<start-1+nbad; ++j ) { // bad channels in this chamber
00159         short lay  = theBadWires->channels[j].layer;    // value 1-6
00160         short chan = theBadWires->channels[j].channel;  // value 1-80
00161     //    short f1 = theBadWires->channels[j].flag1;
00162     //    short f2 = theBadWires->channels[j].flag2;
00163     //    short f3 = theBadWires->channels[j].flag3;
00164         int indexl = indexer_->layerIndex( id.endcap(), id.station(), id.ring(), id.chamber(), lay );
00165         badWireWords[indexl-1].set( chan-1, 1 ); // set bit 0-111 in 112-bit bitset representing this layer
00166       } // j
00167     } // i
00168 
00169   }
00170 }
00171 
00172 bool CSCConditions::isInBadChamber( const CSCDetId& id ) const {
00173   //@@ NOT YET THOUGHT THROUGH FOR UNGANGED ME11A
00174 
00175   if ( readBadChambers() )  {
00176     CSCDetId idraw  = mapper_->rawCSCDetId( id );
00177     int index = indexer_->chamberIndex( idraw );
00178     return theBadChambers->isInBadChamber( index );
00179   }
00180   else return false;
00181 }
00182 
00183 float CSCConditions::gain(const CSCDetId & id, int geomChannel) const
00184 {
00185   assert(theGains.isValid());
00186   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00187   int iraw        = mapper_->rawStripChannel( id, geomChannel );
00188   int index       = indexer_->stripChannelIndex( idraw, iraw ) - 1; // NOTE THE MINUS ONE!
00189   return float( theGains->gain(index) ) /theGains->scale();
00190 }
00191 
00192 float CSCConditions::pedestal(const CSCDetId & id, int geomChannel) const
00193 {
00194   assert(thePedestals.isValid());
00195   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00196   int iraw        = mapper_->rawStripChannel( id, geomChannel );
00197   int index       = indexer_->stripChannelIndex( idraw, iraw ) - 1; // NOTE THE MINUS ONE!
00198   return float( thePedestals->pedestal(index) )/thePedestals->scale_ped();
00199 }
00200 
00201 
00202 float CSCConditions::pedestalSigma(const CSCDetId& id, int geomChannel) const
00203 {
00204   assert(thePedestals.isValid());
00205   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00206   int iraw        = mapper_->rawStripChannel( id, geomChannel );
00207   int index       = indexer_->stripChannelIndex( idraw, iraw ) - 1; // NOTE THE MINUS ONE!
00208   return float( thePedestals->pedestal_rms(index) )/thePedestals->scale_rms();
00209 }
00210 
00211 
00212 float CSCConditions::crosstalkIntercept(const CSCDetId& id, int geomChannel, bool leftRight) const
00213 {
00214   assert(theCrosstalk.isValid());
00215   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00216   int iraw        = mapper_->rawStripChannel( id, geomChannel );
00217   int index       = indexer_->stripChannelIndex( idraw, iraw ) - 1; // NOTE THE MINUS ONE!
00218   // resistive fraction is at the peak, where t=0
00219   return leftRight ? float ( theCrosstalk->rinter(index) )/theCrosstalk->iscale()
00220                    : float ( theCrosstalk->linter(index) )/theCrosstalk->iscale() ;
00221 }
00222 
00223 
00224 float CSCConditions::crosstalkSlope(const CSCDetId& id, int geomChannel, bool leftRight) const
00225 {
00226   assert(theCrosstalk.isValid());
00227   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00228   int iraw        = mapper_->rawStripChannel( id, geomChannel );
00229   int index       = indexer_->stripChannelIndex( idraw, iraw ) - 1; // NOTE THE MINUS ONE!
00230   // resistive fraction is at the peak, where t=0
00231   return leftRight ? float ( theCrosstalk->rslope(index) )/theCrosstalk->sscale()
00232                    : float ( theCrosstalk->lslope(index) )/theCrosstalk->sscale() ;
00233 }
00234 
00235 const CSCDBNoiseMatrix::Item & CSCConditions::noiseMatrix(const CSCDetId& id, int geomChannel) const
00236 {
00237   //@@ BEWARE - THIS FUNCTION DOES NOT APPLy SCALE FACTOR USED IN PACKING VALUES IN CONDITIONS DATA
00238   //@@ MAY BE AN ERROR? WHO WOULD WANT ACCESS WITHOUT IT?
00239 
00240   assert(theNoiseMatrix.isValid());
00241   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00242   int iraw        = mapper_->rawStripChannel( id, geomChannel );
00243   int index       = indexer_->stripChannelIndex( idraw, iraw ) - 1; // NOTE THE MINUS ONE!
00244   return theNoiseMatrix->item(index);
00245 }
00246 
00247 void CSCConditions::noiseMatrixElements( const CSCDetId& id, int geomChannel, std::vector<float>& me ) const {
00248   assert(me.size() > 11 );
00249   const CSCDBNoiseMatrix::Item& item = noiseMatrix(id, geomChannel); // i.e. the function above
00250   me[0] = float ( item.elem33 )/theNoiseMatrix->scale();
00251   me[1] = float ( item.elem34 )/theNoiseMatrix->scale();
00252   me[2] = float ( item.elem35 )/theNoiseMatrix->scale();
00253   me[3] = float ( item.elem44 )/theNoiseMatrix->scale();
00254   me[4] = float ( item.elem45 )/theNoiseMatrix->scale();
00255   me[5] = float ( item.elem46 )/theNoiseMatrix->scale();
00256   me[6] = float ( item.elem55 )/theNoiseMatrix->scale();
00257   me[7] = float ( item.elem56 )/theNoiseMatrix->scale();
00258   me[8] = float ( item.elem57 )/theNoiseMatrix->scale();
00259   me[9] = float ( item.elem66 )/theNoiseMatrix->scale();
00260   me[10] = float ( item.elem67 )/theNoiseMatrix->scale();
00261   me[11] = float ( item.elem77 )/theNoiseMatrix->scale();
00262 }
00263 
00264 void CSCConditions::crossTalk( const CSCDetId& id, int geomChannel, std::vector<float>& ct ) const {
00265   assert(theCrosstalk.isValid());
00266   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00267   int iraw        = mapper_->rawStripChannel( id, geomChannel );
00268   int index       = indexer_->stripChannelIndex( idraw, iraw ) - 1; // NOTE THE MINUS ONE!
00269 
00270   ct[0] = float ( theCrosstalk->lslope(index) )/theCrosstalk->sscale();
00271   ct[1] = float ( theCrosstalk->linter(index) )/theCrosstalk->iscale();
00272   ct[2] = float ( theCrosstalk->rslope(index) )/theCrosstalk->sscale();
00273   ct[3] = float ( theCrosstalk->rinter(index) )/theCrosstalk->iscale();
00274 }
00275 
00276 float CSCConditions::chipCorrection(const CSCDetId & id, int geomChannel) const
00277 {
00278   if ( useTimingCorrections() ){
00279     assert(theChipCorrections.isValid());
00280     CSCDetId idraw  = mapper_->rawCSCDetId( id );
00281     int iraw        = mapper_->rawStripChannel( id, geomChannel);
00282     int ichip       = indexer_->chipIndex(iraw); // converts 1-80 to 1-5 (chip#, CFEB#)
00283     int index       = indexer_->chipIndex(idraw, ichip) - 1; // NOTE THE MINUS ONE!
00284     return float ( theChipCorrections->value(index) )/theChipCorrections->scale();
00285   }
00286   else
00287     return 0;
00288 }
00289 float CSCConditions::chamberTimingCorrection(const CSCDetId & id) const
00290 {
00291   if ( useTimingCorrections() ){
00292     assert(theChamberTimingCorrections.isValid());
00293     CSCDetId idraw  = mapper_->rawCSCDetId( id );
00294     int index = indexer_->chamberIndex(idraw) - 1; // NOTE THE MINUS ONE!
00295     return float (
00296       theChamberTimingCorrections->item(index).cfeb_tmb_skew_delay*1./theChamberTimingCorrections->precision()
00297                    + theChamberTimingCorrections->item(index).cfeb_timing_corr*1./theChamberTimingCorrections->precision()
00298                    + (theChamberTimingCorrections->item(index).cfeb_cable_delay*25. )
00299 );
00300   }
00301   else
00302     return 0;
00303 }
00304 float CSCConditions::anodeBXoffset(const CSCDetId & id) const
00305 {
00306   if ( useTimingCorrections() ){
00307     assert(theChamberTimingCorrections.isValid());
00308     CSCDetId idraw  = mapper_->rawCSCDetId( id );
00309     int index = indexer_->chamberIndex(idraw) - 1; // NOTE THE MINUS ONE!
00310     return float ( theChamberTimingCorrections->item(index).anode_bx_offset*1./theChamberTimingCorrections->precision() );
00311   }
00312   else
00313     return 0;
00314 }
00315 
00316 const std::bitset<80>& CSCConditions::badStripWord( const CSCDetId& id ) const {
00317   //@@ NOT YET THOUGHT THROUGH FOR UNGANGED ME11A
00318 
00319   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00320   return badStripWords[indexer_->layerIndex(idraw) - 1];
00321 }
00322 
00323 const std::bitset<112>& CSCConditions::badWireWord( const CSCDetId& id ) const {
00324   //@@ NEED TO THINK ABOUT THIS SINCE ME11A & ME11B SHARE A COMMON WIRE PLANE
00325   //@@ SHOULD WE JUST USE ME11B?
00326 
00327   CSCDetId idraw  = mapper_->rawCSCDetId( id );
00328   return badWireWords[indexer_->layerIndex(idraw) - 1];
00329 }
00330 
00335 float CSCConditions::averageGain() const {
00336 
00337   const float loEdge = 5.0; // consider gains above this
00338   const float hiEdge = 10.0; // consider gains below this
00339   const float loLimit = 6.0; // lowest acceptable average gain
00340   const float hiLimit = 9.0; // highest acceptable average gain
00341   const float expectedAverage = 7.5; // default average gain
00342 
00343   if ( theAverageGain > 0. ) return theAverageGain; // only recalculate if necessary
00344 
00345   int  n_strip   = 0;
00346   float gain_tot = 0.;
00347 
00348   CSCDBGains::GainContainer::const_iterator it;
00349   for ( it=theGains->gains.begin(); it!=theGains->gains.end(); ++it ) {
00350     float the_gain = float( it->gain_slope )/theGains->scale();
00351     if (the_gain > loEdge && the_gain < hiEdge ) {
00352       gain_tot += the_gain;
00353       ++n_strip;
00354     }
00355   }
00356 
00357   // Average gain
00358   if ( n_strip > 0 ) {
00359     theAverageGain = gain_tot / n_strip;
00360   }
00361 
00362   // Average gain has been around 7.5 in real data
00363   if ( theAverageGain < loLimit || theAverageGain > hiLimit ) {
00364     //    LogTrace("CSC") << "Average CSC strip gain = "
00365     //                    << theAverageGain << "  is reset to expected value " << expectedAverage;
00366     theAverageGain = expectedAverage;
00367   }
00368 
00369   return theAverageGain;
00370 }
00371 //
00372 float CSCConditions::gasGainCorrection( const CSCDetId & id, int geomChannel, int iwiregroup ) const
00373 {
00374   if ( useGasGainCorrections() ){
00375     assert(theGasGainCorrections.isValid());
00376     CSCDetId idraw  = mapper_->rawCSCDetId( id );
00377     int iraw        = mapper_->rawStripChannel( id, geomChannel );
00378     int index       = indexer_->gasGainIndex(idraw, iraw, iwiregroup) - 1; // NOTE THE MINUS ONE!
00379     return float ( theGasGainCorrections->value(index) );
00380   } else {
00381     return 1.;
00382   }
00383 }
00384 
00385 int CSCConditions::channelFromStrip( const CSCDetId& id, int geomStrip) const
00386 { return mapper_->channelFromStrip(id, geomStrip); }
00387 
00388 int CSCConditions::rawStripChannel( const CSCDetId& id, int geomChannel) const
00389 { return mapper_->rawStripChannel( id, geomChannel); }
00390 
00391 
00392 void CSCConditions::print() const
00393   //@@ HAS NOT BEEN UPDATED THROUGH SEVERAL VERSIONS OF THE CONDITIONS DATA
00394 {
00395 /*
00396   std::cout << "SIZES: GAINS: " << theGains->gains.size()
00397             << "   PEDESTALS: " << thePedestals->pedestals.size()
00398             << "   NOISES "  << theNoiseMatrix->matrix.size() << std::endl;;
00399 
00400   std::map< int,std::vector<CSCDBGains::Item> >::const_iterator layerGainsItr = theGains->gains.begin(),
00401       lastGain = theGains->gains.end();
00402   for( ; layerGainsItr != lastGain; ++layerGainsItr)
00403   {
00404     std::cout << "GAIN " << layerGainsItr->first
00405               << " STRIPS " << layerGainsItr->second.size() << " "
00406               << layerGainsItr->second[0].gain_slope
00407               << " " << layerGainsItr->second[0].gain_intercept << std::endl;
00408   }
00409 
00410   std::map< int,std::vector<CSCDBPedestals::Item> >::const_iterator pedestalItr = thePedestals->pedestals.begin(),
00411                                                                   lastPedestal = thePedestals->pedestals.end();
00412   for( ; pedestalItr != lastPedestal; ++pedestalItr)
00413   {
00414     std::cout << "PEDS " << pedestalItr->first << " "
00415               << " STRIPS " << pedestalItr->second.size() << " ";
00416     for(int i = 1; i < 80; ++i)
00417     {
00418        std::cout << pedestalItr->second[i-1].rms << " " ;
00419      }
00420      std::cout << std::endl;
00421   }
00422 
00423   std::map< int,std::vector<CSCDBCrosstalk::Item> >::const_iterator crosstalkItr = theCrosstalk->crosstalk.begin(),
00424                                                                   lastCrosstalk = theCrosstalk->crosstalk.end();
00425   for( ; crosstalkItr != lastCrosstalk; ++crosstalkItr)
00426   {
00427     std::cout << "XTALKS " << crosstalkItr->first
00428       << " STRIPS " << crosstalkItr->second.size() << " "
00429      << crosstalkItr->second[5].xtalk_slope_left << " "
00430      << crosstalkItr->second[5].xtalk_slope_right << " "
00431      << crosstalkItr->second[5].xtalk_intercept_left << " "
00432      << crosstalkItr->second[5].xtalk_intercept_right << std::endl;
00433   }
00434 */
00435 }