CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/DQM/SiStripCommissioningDbClients/src/ApvTimingHistosUsingDb.cc

Go to the documentation of this file.
00001 // Last commit: $Id: ApvTimingHistosUsingDb.cc,v 1.31 2010/04/21 14:26:25 dstrom Exp $
00002 
00003 #include "DQM/SiStripCommissioningDbClients/interface/ApvTimingHistosUsingDb.h"
00004 #include "CondFormats/SiStripObjects/interface/ApvTimingAnalysis.h"
00005 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00006 #include "DataFormats/SiStripCommon/interface/SiStripFecKey.h"
00007 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include <iostream>
00010 
00011 using namespace sistrip;
00012 
00013 // -----------------------------------------------------------------------------
00015 ApvTimingHistosUsingDb::ApvTimingHistosUsingDb( const edm::ParameterSet & pset,
00016                                                 DQMStore* bei,
00017                                                 SiStripConfigDb* const db ) 
00018   : CommissioningHistograms( pset.getParameter<edm::ParameterSet>("ApvTimingParameters"),
00019                              bei,
00020                              sistrip::APV_TIMING ),
00021     CommissioningHistosUsingDb( db,
00022                                 sistrip::APV_TIMING ),
00023     ApvTimingHistograms( pset.getParameter<edm::ParameterSet>("ApvTimingParameters"),
00024                          bei )
00025 {
00026   LogTrace(mlDqmClient_) 
00027     << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00028     << " Constructing object...";
00029   skipFecUpdate_ = this->pset().getParameter<bool>("SkipFecUpdate");
00030   skipFedUpdate_ = this->pset().getParameter<bool>("SkipFedUpdate");
00031   if (skipFecUpdate_)
00032     LogTrace(mlDqmClient_)
00033       << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00034       << " Skipping update of FEC parameters.";
00035   if (skipFedUpdate_)
00036     LogTrace(mlDqmClient_)
00037       << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00038       << " Skipping update of FED parameters.";
00039 }
00040 
00041 // -----------------------------------------------------------------------------
00043 ApvTimingHistosUsingDb::~ApvTimingHistosUsingDb() {
00044   LogTrace(mlDqmClient_) 
00045     << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00046     << " Destructing object...";
00047 }
00048 
00049 // -----------------------------------------------------------------------------
00051 void ApvTimingHistosUsingDb::uploadConfigurations() {
00052   LogTrace(mlDqmClient_) 
00053     << "[ApvTimingHistosUsingDb::" << __func__ << "]";
00054   
00055   if ( !db() ) {
00056     edm::LogError(mlDqmClient_) 
00057       << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00058       << " NULL pointer to SiStripConfigDb interface!"
00059       << " Aborting upload...";
00060     return;
00061   }
00062   
00063   if ( !skipFecUpdate_ ) {
00064 
00065     // Retrieve and update PLL device descriptions
00066     SiStripConfigDb::DeviceDescriptionsRange devices = db()->getDeviceDescriptions( PLL ); 
00067     bool upload = update( devices );
00068     
00069     // Check if new PLL settings are valid 
00070     if ( !upload ) {
00071       edm::LogError(mlDqmClient_) 
00072         << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00073         << " Found invalid PLL settings (coarse > 15)"
00074         << " Aborting update to database...";
00075       return;
00076     }
00077     
00078     // Upload PLL device descriptions
00079     if ( doUploadConf() ) { 
00080       edm::LogVerbatim(mlDqmClient_) 
00081         << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00082         << " Uploading PLL settings to DB...";
00083       db()->uploadDeviceDescriptions(); 
00084       edm::LogVerbatim(mlDqmClient_) 
00085         << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00086         << " Upload of PLL settings to DB finished!";
00087     } else {
00088       edm::LogWarning(mlDqmClient_) 
00089         << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00090         << " TEST only! No PLL settings will be uploaded to DB...";
00091     }
00092     
00093   } else {
00094     LogTrace(mlDqmClient_) 
00095       << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00096       << " No upload of PLL settings to DB, as defined by .cfg file!";
00097   }
00098   
00099   if ( !skipFedUpdate_ ) {
00100     
00101     // Update FED descriptions with new ticker thresholds
00102     SiStripConfigDb::FedDescriptionsRange feds = db()->getFedDescriptions(); 
00103     update( feds );
00104     
00105     // Update FED descriptions with new ticker thresholds
00106     if ( doUploadConf() ) { 
00107       edm::LogVerbatim(mlDqmClient_) 
00108         << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00109         << " Uploading FED ticker thresholds to DB...";
00110       db()->uploadFedDescriptions(); 
00111       edm::LogVerbatim(mlDqmClient_) 
00112         << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00113         << " Upload of FED ticker thresholds to DB finished!";
00114     } else {
00115       edm::LogWarning(mlDqmClient_) 
00116         << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00117         << " TEST only! No FED ticker thresholds will be uploaded to DB...";
00118     }
00119     
00120   } else {
00121     LogTrace(mlDqmClient_) 
00122       << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00123       << " No Upload of FED ticker thresholds to DB, as defined by .cfg file!";
00124   }
00125 
00126 }
00127 
00128 // -----------------------------------------------------------------------------
00130 bool ApvTimingHistosUsingDb::update( SiStripConfigDb::DeviceDescriptionsRange devices ) {
00131   
00132   // Iterate through devices and update device descriptions
00133   uint16_t updated = 0;
00134   std::vector<SiStripFecKey> invalid;
00135   SiStripConfigDb::DeviceDescriptionsV::const_iterator idevice;
00136 
00137   for ( idevice = devices.begin(); idevice != devices.end(); idevice++ ) {
00138 
00139     // Check device type
00140     if ( (*idevice)->getDeviceType() != PLL ) { continue; }
00141     
00142     // Cast to retrieve appropriate description object
00143     pllDescription* desc = dynamic_cast<pllDescription*>( *idevice ); 
00144     if ( !desc ) { continue; }
00145     
00146     // Retrieve device addresses from device description
00147     const SiStripConfigDb::DeviceAddress& addr = db()->deviceAddress(*desc);
00148     SiStripFecKey fec_path;
00149     
00150     // PLL delay settings
00151     uint32_t coarse = sistrip::invalid_; 
00152     uint32_t fine = sistrip::invalid_; 
00153 
00154     // Iterate through LLD channels
00155     for ( uint16_t ichan = 0; ichan < sistrip::CHANS_PER_LLD; ichan++ ) {
00156       
00157       // Construct key from device description
00158       SiStripFecKey fec_key( addr.fecCrate_,
00159                              addr.fecSlot_, 
00160                              addr.fecRing_,
00161                              addr.ccuAddr_, 
00162                              addr.ccuChan_,
00163                              ichan+1 );
00164       fec_path = fec_key;
00165       
00166       // Locate appropriate analysis object
00167       Analyses::const_iterator iter = data().find( fec_key.key() );
00168       if ( iter != data().end() ) { 
00169         
00170         ApvTimingAnalysis* anal = dynamic_cast<ApvTimingAnalysis*>( iter->second );
00171         if ( !anal ) { 
00172           edm::LogError(mlDqmClient_)
00173             << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00174             << " NULL pointer to analysis object!";
00175           continue; 
00176         }
00177         
00178         // Calculate coarse and fine delays
00179         int32_t delay = static_cast<int32_t>( rint( anal->delay() )*24./25 );
00180         // first set course delay
00181         coarse = static_cast<uint16_t>( desc->getDelayCoarse() + (delay/24) ) 
00182              + ( static_cast<uint16_t>( desc->getDelayFine() ) + (delay%24) ) / 24;
00183         delay = delay % 24; // only bother with fine delay now
00184         if ( ( static_cast<uint16_t>( desc->getDelayFine() ) + delay ) % 24 < 0 ) {
00185           coarse -= 1;
00186           delay += 24;
00187         }
00188         fine = ( static_cast<uint16_t>( desc->getDelayFine() ) + delay ) % 24;
00189         
00190         // Record PPLs maximum coarse setting
00191         if ( coarse > 15 ) { invalid.push_back(fec_key); }
00192         
00193       } else {
00194         if ( deviceIsPresent(fec_key) ) { 
00195           edm::LogWarning(mlDqmClient_) 
00196             << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00197             << " Unable to find FEC key with params crate/FEC/ring/CCU/module/LLD: " 
00198             << fec_key.fecCrate() << "/"
00199             << fec_key.fecSlot() << "/"
00200             << fec_key.fecRing() << "/"
00201             << fec_key.ccuAddr() << "/" 
00202             << fec_key.ccuChan() << "/"
00203             << fec_key.channel();
00204         }
00205       }
00206       
00207       // Exit LLD channel loop if coarse and fine delays are known
00208       if ( coarse != sistrip::invalid_ && 
00209            fine != sistrip::invalid_ ) { break; }
00210       
00211     } // lld channel loop
00212     
00213     // Update PLL settings
00214     if ( coarse != sistrip::invalid_ && 
00215          fine != sistrip::invalid_ ) { 
00216       
00217       std::stringstream ss;
00218       if ( edm::isDebugEnabled() ) {
00219         ss << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00220            << " Updating coarse/fine PLL settings"
00221            << " for crate/FEC/ring/CCU/module "
00222            << fec_path.fecCrate() << "/"
00223            << fec_path.fecSlot() << "/"
00224            << fec_path.fecRing() << "/"
00225            << fec_path.ccuAddr() << "/"
00226            << fec_path.ccuChan() 
00227            << " from "
00228            << static_cast<uint16_t>( desc->getDelayCoarse() ) << "/" 
00229            << static_cast<uint16_t>( desc->getDelayFine() );
00230       }
00231       desc->setDelayCoarse(coarse);
00232       desc->setDelayFine(fine);
00233       updated++;
00234       if ( edm::isDebugEnabled() ) {
00235         ss << " to "
00236            << static_cast<uint16_t>( desc->getDelayCoarse() ) << "/" 
00237            << static_cast<uint16_t>( desc->getDelayFine() );
00238         LogTrace(mlDqmClient_) << ss.str();
00239       }
00240       
00241     } else {
00242       edm::LogWarning(mlDqmClient_) 
00243         << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00244         << " Invalid PLL delay settings course/fine = "
00245         << coarse << "/" << fine
00246         << " for crate/FEC/ring/CCU/module " 
00247         << fec_path.fecCrate() << "/"
00248         << fec_path.fecSlot() << "/"
00249         << fec_path.fecRing() << "/"
00250         << fec_path.ccuAddr() << "/"
00251         << fec_path.ccuChan();
00252     }
00253     
00254   }
00255 
00256   // Check if invalid settings were found
00257   if ( !invalid.empty() ) {
00258     std::stringstream ss;
00259     ss << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00260        << " Found PLL coarse setting of >15" 
00261        << " (not allowed!) for "
00262        << invalid.size()
00263        << " channels";
00264     ss << " (Example is crate/FEC/ring/CCU/module/LLD: "
00265        << invalid.front().fecCrate() << "/"
00266        << invalid.front().fecSlot() << "/"
00267        << invalid.front().fecRing() << "/"
00268        << invalid.front().ccuAddr() << "/"
00269        << invalid.front().ccuChan() << "/"
00270        << invalid.front().channel();
00271     edm::LogWarning(mlDqmClient_) << ss.str();
00272     return false;
00273   }
00274   
00275   edm::LogVerbatim(mlDqmClient_) 
00276     << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00277     << " Updated PLL settings for " 
00278     << updated << " modules";
00279   return true;
00280     
00281 }
00282 
00283 // -----------------------------------------------------------------------------
00285 void ApvTimingHistosUsingDb::update( SiStripConfigDb::FedDescriptionsRange feds ) {
00286   
00287   // Retrieve FED ids from cabling
00288   std::vector<uint16_t> ids = cabling()->feds();
00289   
00290   // Iterate through feds and update fed descriptions
00291   uint16_t updated = 0;
00292   SiStripConfigDb::FedDescriptionsV::const_iterator ifed;
00293   for ( ifed = feds.begin(); ifed != feds.end(); ifed++ ) {
00294     
00295     // If FED id not found in list (from cabling), then continue
00296     if ( find( ids.begin(), ids.end(), (*ifed)->getFedId() ) == ids.end() ) { continue; } 
00297     
00298     for ( uint16_t ichan = 0; ichan < sistrip::FEDCH_PER_FED; ichan++ ) {
00299 
00300       // Build FED and FEC keys
00301       const FedChannelConnection& conn = cabling()->connection( (*ifed)->getFedId(), ichan );
00302       if ( conn.fecCrate() == sistrip::invalid_ ||
00303            conn.fecSlot() == sistrip::invalid_ ||
00304            conn.fecRing() == sistrip::invalid_ ||
00305            conn.ccuAddr() == sistrip::invalid_ ||
00306            conn.ccuChan() == sistrip::invalid_ ||
00307            conn.lldChannel() == sistrip::invalid_ ) { continue; }
00308       SiStripFedKey fed_key( conn.fedId(), 
00309                              SiStripFedKey::feUnit( conn.fedCh() ),
00310                              SiStripFedKey::feChan( conn.fedCh() ) );
00311       SiStripFecKey fec_key( conn.fecCrate(), 
00312                              conn.fecSlot(), 
00313                              conn.fecRing(), 
00314                              conn.ccuAddr(), 
00315                              conn.ccuChan(), 
00316                              conn.lldChannel() );
00317       
00318       // Locate appropriate analysis object 
00319       Analyses::const_iterator iter = data().find( fec_key.key() );
00320       if ( iter != data().end() ) { 
00321         
00322         ApvTimingAnalysis* anal = dynamic_cast<ApvTimingAnalysis*>( iter->second );
00323         if ( !anal ) { 
00324           edm::LogError(mlDqmClient_)
00325             << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00326             << " NULL pointer to analysis object!";
00327           continue; 
00328         }
00329         
00330         // Update frame finding threshold
00331         Fed9U::Fed9UAddress addr( ichan );
00332         uint16_t old_threshold = static_cast<uint16_t>( (*ifed)->getFrameThreshold( addr ) );
00333         if ( anal->isValid() ) {
00334           (*ifed)->setFrameThreshold( addr, anal->frameFindingThreshold() );
00335           updated++;
00336         }
00337         uint16_t new_threshold = static_cast<uint16_t>( (*ifed)->getFrameThreshold( addr ) );
00338         
00339         // Debug
00340         std::stringstream ss;
00341         ss << "[ApvTimingHistosUsingDb::" << __func__ << "]";
00342         if ( anal->isValid() ) {
00343           ss << " Updating the frame-finding threshold"
00344              << " from " << old_threshold
00345              << " to " << new_threshold
00346              << " using tick mark base/peak/height "
00347              << anal->base() << "/"
00348              << anal->peak() << "/"
00349              << anal->height();
00350         } else {
00351           ss << " Cannot update the frame-finding threshold"
00352              << " from " << old_threshold
00353              << " to a new value using invalid analysis ";
00354         }
00355         ss << " for crate/FEC/ring/CCU/module/LLD "
00356            << fec_key.fecCrate() << "/"
00357            << fec_key.fecSlot() << "/"
00358            << fec_key.fecRing() << "/"
00359            << fec_key.ccuAddr() << "/"
00360            << fec_key.ccuChan() 
00361            << fec_key.channel() 
00362            << " and FED id/ch "
00363            << fed_key.fedId() << "/"
00364            << fed_key.fedChannel();
00365         anal->print(ss);
00366         //LogTrace(mlDqmClient_) << ss.str();
00367         
00368       } else {
00369         if ( deviceIsPresent(fec_key) ) { 
00370           std::stringstream ss;
00371           ss << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00372              << " Unable to find analysis object and update ticker thresholds"
00373              << " for key/crate/FEC/ring/CCU/module/LLD " 
00374              << std::hex << std::setw(8) << std::setfill('0') << fec_key.key() << std::dec
00375              << fec_key.fecCrate() << "/"
00376              << fec_key.fecSlot() << "/"
00377              << fec_key.fecRing() << "/"
00378              << fec_key.ccuAddr() << "/"
00379              << fec_key.ccuChan() << "/"
00380              << fec_key.channel()
00381              << " and FED key/id/ch "
00382              << std::hex << std::setw(8) << std::setfill('0') << fed_key.key() << std::dec
00383              << fed_key.fedId() << "/"
00384              << fed_key.fedChannel();
00385           edm::LogWarning(mlDqmClient_) << ss.str();
00386         }
00387       }
00388     }
00389   }
00390 
00391   edm::LogVerbatim(mlDqmClient_) 
00392     << "[ApvTimingHistosUsingDb::" << __func__ << "]"
00393     << " Updated ticker thresholds for " << updated 
00394     << " channels on " << ids.size() << " FEDs!";
00395   
00396 }
00397 
00398 // -----------------------------------------------------------------------------
00400 void ApvTimingHistosUsingDb::create( SiStripConfigDb::AnalysisDescriptionsV& desc,
00401                                      Analysis analysis ) {
00402 
00403   ApvTimingAnalysis* anal = dynamic_cast<ApvTimingAnalysis*>( analysis->second );
00404   if ( !anal ) { return; }
00405   
00406   SiStripFecKey fec_key( anal->fecKey() );
00407   SiStripFedKey fed_key( anal->fedKey() );
00408   
00409   for ( uint16_t iapv = 0; iapv < 2; ++iapv ) {
00410     
00411 //     std::stringstream ss;
00412 //     if ( anal->isValid() ) { ss << " TEST VALID "; } 
00413 //     else { ss << " TEST INVALID "; }
00414 //     ss << std::hex << anal->fecKey() << std::dec << " "
00415 //        << anal->base() << " "
00416 //        << anal->peak() << " "
00417 //        << anal->height() << " "
00418 //        << ( anal->base() + anal->height() * ApvTimingAnalysis::frameFindingThreshold_ ) << " "
00419 //        << anal->frameFindingThreshold();
00420 //     edm::LogError("TEST") << ss.str();
00421     
00422     // Create description
00423     TimingAnalysisDescription* tmp;
00424     tmp = new TimingAnalysisDescription( anal->time(),
00425                                          anal->refTime(),
00426                                          anal->delay(),
00427                                          anal->height(),
00428                                          anal->base(),
00429                                          anal->peak(),
00430                                          anal->frameFindingThreshold(),
00431                                          anal->optimumSamplingPoint(),
00432                                          ApvTimingAnalysis::tickMarkHeightThreshold_,
00433                                          true, //@@ APV timing analysis (not FED timing)
00434                                          fec_key.fecCrate(),
00435                                          fec_key.fecSlot(),
00436                                          fec_key.fecRing(),
00437                                          fec_key.ccuAddr(),
00438                                          fec_key.ccuChan(),
00439                                          SiStripFecKey::i2cAddr( fec_key.lldChan(), !iapv ), 
00440                                          db()->dbParams().partitions().begin()->second.partitionName(),
00441                                          db()->dbParams().partitions().begin()->second.runNumber(),
00442                                          anal->isValid(),
00443                                          "",
00444                                          fed_key.fedId(),
00445                                          fed_key.feUnit(),
00446                                          fed_key.feChan(),
00447                                          fed_key.fedApv() );
00448     
00449     // Add comments
00450     typedef std::vector<std::string> Strings;
00451     Strings errors = anal->getErrorCodes();
00452     Strings::const_iterator istr = errors.begin();
00453     Strings::const_iterator jstr = errors.end();
00454     for ( ; istr != jstr; ++istr ) { tmp->addComments( *istr ); }
00455     
00456     // Store description
00457     desc.push_back( tmp );
00458     
00459   }
00460 
00461 }