CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/src/DQM/SiStripCommissioningSources/src/OptoScanTask.cc

Go to the documentation of this file.
00001 #include "DQM/SiStripCommissioningSources/interface/OptoScanTask.h"
00002 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00003 #include "DataFormats/SiStripCommon/interface/SiStripHistoTitle.h"
00004 #include "DQMServices/Core/interface/DQMStore.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include <algorithm>
00007 #include <math.h>
00008 
00009 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00010 #include <iomanip>
00011 
00012 
00013 using namespace sistrip;
00014 
00015 
00016 // -----------------------------------------------------------------------------
00017 //
00018 OptoScanTask::OptoScanTask( DQMStore * dqm,
00019                             const FedChannelConnection & conn ) :
00020   CommissioningTask( dqm, conn, "OptoScanTask" ),
00021   opto_() {
00022 }
00023 
00024 
00025 // -----------------------------------------------------------------------------
00026 //
00027 OptoScanTask::~OptoScanTask() {
00028 }
00029 
00030 
00031 // -----------------------------------------------------------------------------
00032 //
00033 void OptoScanTask::book() {
00034 
00035   uint16_t nbins = 50;
00036   uint16_t gains = 4;
00037 
00038   // Resize "histo sets"
00039   opto_.resize( gains );
00040   for ( uint16_t igain = 0; igain < opto_.size(); igain++ ) {
00041     opto_[igain].resize(3);
00042   }
00043 
00044   for ( uint16_t igain = 0; igain < opto_.size(); igain++ ) {
00045     for ( uint16_t ihisto = 0; ihisto < 3; ihisto++ ) {
00046 
00047       // Extra info
00048       std::stringstream extra_info;
00049       extra_info << sistrip::extrainfo::gain_ << igain;
00050       if ( ihisto == 0 || ihisto == 1 ) {
00051         extra_info << sistrip::extrainfo::digital_ << ihisto;
00052       } else {
00053         extra_info << sistrip::extrainfo::baselineRms_;
00054       }
00055 
00056       // Title
00057       std::string title = SiStripHistoTitle( sistrip::EXPERT_HISTO, 
00058                                              sistrip::OPTO_SCAN, 
00059                                              sistrip::FED_KEY, 
00060                                              fedKey(),
00061                                              sistrip::LLD_CHAN, 
00062                                              connection().lldChannel(),
00063                                              extra_info.str() ).title();
00064 
00065       // Book histo
00066       opto_[igain][ihisto].histo( dqm()->bookProfile( title, title, 
00067                                                       nbins, 0.5, nbins*1.+0.5, // range is bias setting (1-50)
00068                                                       1024, -0.5, 1023.5 ) );
00069 
00070       opto_[igain][ihisto].vNumOfEntries_.resize(nbins,0);
00071       opto_[igain][ihisto].vSumOfContents_.resize(nbins,0);
00072       opto_[igain][ihisto].vSumOfSquares_.resize(nbins,0);
00073 
00074     } // end loop on histos
00075   } // end loop on gains
00076 
00077 }
00078 
00079 
00080 // -----------------------------------------------------------------------------
00081 //
00082 void OptoScanTask::fill( const SiStripEventSummary & summary,
00083                          const edm::DetSet<SiStripRawDigi> & digis ) {
00084 
00085   //@@ if scope mode length is in trigger fed, then 
00086   //@@ can add check here on number of digis
00087   if ( digis.data.empty() ) {
00088     edm::LogWarning(mlDqmSource_)
00089       << "[OptoScanTask::" << __func__ << "]"
00090       << " Unexpected number of digis! " 
00091       << digis.data.size(); 
00092   } else {
00093 
00094     // Retrieve opt bias and gain setting from SiStripEventSummary
00095     uint16_t gain = summary.lldGain();
00096     uint16_t bias = summary.lldBias();
00097 
00098     if ( gain >= opto_.size() ) { 
00099       opto_.resize( gain );
00100       for ( uint16_t igain = 0; igain < opto_.size(); igain++ ) { 
00101         if ( opto_[gain].size() != 3 ) { opto_[gain].resize( 3 ); }
00102       }
00103       edm::LogWarning(mlDqmSource_)  
00104         << "[OptoScanTask::" << __func__ << "]"
00105         << " Unexpected gain value! " << gain;
00106     }
00107 
00108     if ( bias > 50 ) { return; } // only use bias settings 1-50
00109 
00110     // Find digital "0" and digital "1" levels from tick marks within scope mode data
00111     std::vector<float> baseline;
00112     std::pair<float,float> digital_range;
00113     digital_range.first  = sistrip::invalid_;
00114     digital_range.second = sistrip::invalid_;
00115     float baseline_rms   = sistrip::invalid_;
00116 
00117     locateTicks( digis, digital_range, baseline, baseline_rms );
00118 
00119     uint16_t bin = bias - 1; // fill "bins" (0-49), not bias (1-50)
00120 
00121     // Digital "0"
00122     if ( digital_range.first < 1. * sistrip::valid_ ) {
00123       updateHistoSet( opto_[gain][0], bin, digital_range.first );
00124     }
00125 
00126     // Digital "1"
00127     if ( digital_range.second < 1. * sistrip::valid_ ) {
00128       updateHistoSet( opto_[gain][1], bin, digital_range.second );
00129     }
00130 
00131     // Baseline rms
00132     if ( baseline_rms < 1. * sistrip::valid_ ) {
00133       updateHistoSet( opto_[gain][2], bin, baseline_rms );
00134     }
00135 
00136   }
00137 
00138 }
00139 
00140 
00141 // -----------------------------------------------------------------------------
00142 //
00143 void OptoScanTask::update() {
00144 
00145   for ( uint16_t igain = 0; igain < opto_.size(); igain++ ) { 
00146     for ( uint16_t ihisto = 0; ihisto < opto_[igain].size(); ihisto++ ) { 
00147       updateHistoSet( opto_[igain][ihisto] );
00148     }
00149   }
00150 
00151 }
00152 
00153 
00154 // -----------------------------------------------------------------------------
00155 //
00156 void OptoScanTask::locateTicks( const edm::DetSet<SiStripRawDigi> & digis, 
00157                                 std::pair<float,float> & range, 
00158                                 std::vector<float> & baseline,
00159                                 float & baseline_rms ) {
00160 
00161   // Copy ADC values and sort 
00162   std::vector<uint16_t> adc; 
00163   adc.reserve( digis.data.size() ); 
00164   for ( uint16_t iadc = 0; iadc < digis.data.size(); iadc++ ) {
00165     // only take the adc from the first APV (multiplexing alternates the digis)
00166     // this was asked by Karl et al
00167     if (iadc % 2 == 0) {
00168       adc.push_back( digis.data[iadc].adc() );
00169      }
00170   }
00171   sort( adc.begin(), adc.end() );
00172 
00173   // To make sure we have a tickmark, which comes every 70 bxs,
00174   // fully contained in the scope 'frame' we are analyzing
00175   // standard length is 280, sufficient to contain a full apv frame
00176   // in this run there is no frame though, just baseline and tickmarks
00177   if ( adc.size() > 70 ) {
00178 
00179     // Define tick mark top" level as "max" ADC values
00180     range.second = adc.back();
00181 
00182     // Construct vector to hold "baseline samples" (exclude tick mark samples)
00183     std::vector<uint16_t> truncated; 
00184     std::vector<uint16_t>::const_iterator ii = adc.begin();
00185     // remove twice the expected number of tick samples, otherwise you bias the baseline mean and rms
00186     std::vector<uint16_t>::const_iterator jj = adc.end() - 4 * ( ( adc.size() / 70 ) + 1 );
00187     truncated.resize( jj - ii );
00188     std::copy( ii, jj, truncated.begin() );
00189     if ( truncated.empty() ) { return; }
00190 
00191     // Calc mean baseline level
00192     float b_mean = 0.;
00193     std::vector<uint16_t>::const_iterator iii = truncated.begin();
00194     std::vector<uint16_t>::const_iterator jjj = truncated.end();
00195     for ( ; iii != jjj; ++iii ) { b_mean += *iii; }
00196     b_mean /= ( 1. * truncated.size() );
00197     range.first = b_mean;
00198 
00199     // Calc baseline noise
00200     float b_rms = 0.;
00201     std::vector<uint16_t>::const_iterator iiii = truncated.begin();
00202     std::vector<uint16_t>::const_iterator jjjj = truncated.end();
00203     for ( ; iiii != jjjj; ++iiii ) { b_rms += fabs( *iiii - b_mean ); }
00204     // Set baseline "noise" (requires any possible APV frames are filtered from the data!)
00205     baseline_rms = sqrt ( b_rms / ( 1. * truncated.size() ) );
00206 
00207   } else {
00208     edm::LogWarning(mlDqmSource_)
00209       << "[OptoScanTask::" << __func__ << "]"
00210       << " Insufficient ADC values: " << adc.size();
00211   }
00212 
00213 }