CMS 3D CMS Logo

LatencyHistosUsingDb.cc

Go to the documentation of this file.
00001 // Last commit: $Id: LatencyHistosUsingDb.cc,v 1.16 2008/10/22 10:39:26 delaer Exp $
00002 
00003 #include "DQM/SiStripCommissioningDbClients/interface/LatencyHistosUsingDb.h"
00004 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00005 #include "DataFormats/SiStripCommon/interface/SiStripFecKey.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "DataFormats/DetId/interface/DetId.h"
00008 #include <iostream>
00009 
00010 #define MAXFEDCOARSE 15
00011 
00012 using namespace sistrip;
00013 
00014 // -----------------------------------------------------------------------------
00016 LatencyHistosUsingDb::LatencyHistosUsingDb( DQMOldReceiver* mui,
00017                                             SiStripConfigDb* const db )
00018   : CommissioningHistograms( mui, APV_LATENCY ),
00019     CommissioningHistosUsingDb( db, mui, APV_LATENCY ),
00020     SamplingHistograms( mui, APV_LATENCY )
00021 {
00022   LogTrace(mlDqmClient_) 
00023     << "[LatencyHistosUsingDb::" << __func__ << "]"
00024     << " Constructing object...";
00025 }
00026 
00027 // -----------------------------------------------------------------------------
00029 LatencyHistosUsingDb::LatencyHistosUsingDb( DQMStore* bei,
00030                                             SiStripConfigDb* const db ) 
00031   : CommissioningHistosUsingDb( db ),
00032     SamplingHistograms( bei, APV_LATENCY )
00033 {
00034   LogTrace(mlDqmClient_) 
00035     << "[LatencyHistosUsingDb::" << __func__ << "]"
00036     << " Constructing object...";
00037 }
00038 
00039 // -----------------------------------------------------------------------------
00041 LatencyHistosUsingDb::~LatencyHistosUsingDb() {
00042   LogTrace(mlDqmClient_) 
00043     << "[LatencyHistosUsingDb::" << __func__ << "]"
00044     << " Destructing object...";
00045 }
00046 
00047 // -----------------------------------------------------------------------------
00049 void LatencyHistosUsingDb::uploadConfigurations() {
00050   
00051   if ( !db() ) {
00052     edm::LogWarning(mlDqmClient_) 
00053       << "[LatencyHistosUsingDb::" << __func__ << "]"
00054       << " NULL pointer to SiStripConfigDb interface!"
00055       << " Aborting upload...";
00056     return;
00057   }
00058 
00059   SiStripConfigDb::DeviceDescriptionsRange devices = db()->getDeviceDescriptions(); 
00060   SiStripConfigDb::FedDescriptionsRange feds = db()->getFedDescriptions();
00061   bool upload = update( devices, feds );
00062   // Check if new PLL settings are valid
00063   if ( !upload ) {
00064     edm::LogWarning(mlDqmClient_)
00065       << "[LatencyHistosUsingDb::" << __func__ << "]"
00066       << " Found invalid PLL settings (coarse > 15)"
00067       << " Aborting update to database...";
00068     return;
00069   }
00070   
00071   if ( doUploadConf() ) { 
00072     // Update APV descriptions with new Latency settings
00073     LogTrace(mlDqmClient_) 
00074       << "[LatencyHistosUsingDb::" << __func__ << "]"
00075       << " Uploading APV settings to DB...";
00076     db()->uploadDeviceDescriptions(); 
00077     LogTrace(mlDqmClient_) 
00078       << "[LatencyHistosUsingDb::" << __func__ << "]"
00079       << " Upload of APV settings to DB finished!";
00080     // Update FED descriptions 
00081     LogTrace(mlDqmClient_)
00082       << "[LatencyHistosUsingDb::" << __func__ << "]"
00083       << " Uploading FED delays to DB...";
00084     db()->uploadFedDescriptions();
00085     LogTrace(mlDqmClient_)
00086       << "[LatencyHistosUsingDb::" << __func__ << "]"
00087       << " Upload of FED delays to DB finished!";
00088   } else {
00089     edm::LogWarning(mlDqmClient_) 
00090       << "[LatencyHistosUsingDb::" << __func__ << "]"
00091       << " TEST only! No APV settings will be uploaded to DB...";
00092   }
00093 
00094 }
00095 
00096 // -----------------------------------------------------------------------------
00098 bool LatencyHistosUsingDb::update( SiStripConfigDb::DeviceDescriptionsRange devices, 
00099                                    SiStripConfigDb::FedDescriptionsRange feds ) {
00100   
00101   // Obtain the latency from the analysis object
00102   if(!data().size() || !data().begin()->second->isValid() ) {
00103     edm::LogVerbatim(mlDqmClient_) 
00104       << "[LatencyHistosUsingDb::" << __func__ << "]"
00105       << " Updated NO Latency settings. No analysis result available !" ;
00106     return false;
00107   }
00108 
00109   // Compute the minimum coarse delay
00110   uint16_t minCoarseDelay = 256;
00111   SiStripConfigDb::DeviceDescriptionsV::const_iterator idevice;
00112   for ( idevice = devices.begin(); idevice != devices.end(); idevice++ ) {
00113     // Check device type
00114     if ( (*idevice)->getDeviceType() == PLL ) {
00115       // Cast to retrieve appropriate description object
00116       pllDescription* desc = dynamic_cast<pllDescription*>( *idevice );
00117       if ( desc ) { 
00118         // add 1 to aim at 1 and not 0 (just to avoid a special 0 value for security)
00119         int delayCoarse = desc->getDelayCoarse() - 1;
00120         minCoarseDelay = minCoarseDelay < delayCoarse ? minCoarseDelay : delayCoarse;
00121       }
00122     }
00123   }
00124 
00125   // Compute latency and PLL shift from the sampling measurement
00126   SamplingAnalysis* anal = NULL;
00127   for( CommissioningHistograms::Analysis it = data().begin(); it!=data().end();++it) {
00128     if(dynamic_cast<SamplingAnalysis*>( it->second ) && 
00129        dynamic_cast<SamplingAnalysis*>( it->second )->granularity()==sistrip::TRACKER)
00130       anal = dynamic_cast<SamplingAnalysis*>( it->second );
00131   }
00132   if(!anal) return false;
00133   uint16_t latency = uint16_t(ceil(anal->maximum()/(-25.)));
00134   float shift = anal->maximum()-(latency*(-25));
00135 
00136   // Take into account the minimum coarse delay to bring the coarse delay down
00137   // the same quantity is subtracted to the coarse delay of each APV 
00138   latency -= minCoarseDelay;
00139   
00140   // Iterate through devices and update device descriptions
00141   uint16_t updatedAPV = 0;
00142   uint16_t updatedPLL = 0;
00143   std::vector<SiStripFecKey> invalid;
00144   for ( idevice = devices.begin(); idevice != devices.end(); idevice++ ) {
00145     // Check device type
00146     if ( (*idevice)->getDeviceType() != APV25 ) { continue; }
00147     // Cast to retrieve appropriate description object
00148     apvDescription* desc = dynamic_cast<apvDescription*>( *idevice );
00149     if ( !desc ) { continue; }
00150     // Retrieve device addresses from device description
00151     const SiStripConfigDb::DeviceAddress& addr = db()->deviceAddress(*desc);
00152     // Do it!
00153     std::stringstream ss;
00154     ss << "[LatencyHistosUsingDb::" << __func__ << "]"
00155        << " Updating latency APV settings for crate/FEC/slot/ring/CCU/i2cAddr "
00156        << addr.fecCrate_ << "/"
00157        << addr.fecSlot_ << "/"
00158        << addr.fecRing_ << "/"
00159        << addr.ccuAddr_ << "/"
00160        << addr.ccuChan_ << "/"
00161        << addr.i2cAddr_
00162        << " from "
00163        << static_cast<uint16_t>(desc->getLatency());
00164     desc->setLatency(latency);
00165     ss << " to "
00166        << static_cast<uint16_t>(desc->getLatency());
00167     LogTrace(mlDqmClient_) << ss.str();
00168     updatedAPV++;
00169   }
00170 
00171   // Change also the PLL delay
00172   for ( idevice = devices.begin(); idevice != devices.end(); idevice++ ) {
00173     // Check device type
00174     if ( (*idevice)->getDeviceType() != PLL ) { continue; }
00175     // Cast to retrieve appropriate description object
00176     pllDescription* desc = dynamic_cast<pllDescription*>( *idevice );
00177     if ( !desc ) { continue; }
00178     if ( desc->getDelayCoarse() >= 15 ) { continue; }
00179     // Retrieve device addresses from device description
00180     const SiStripConfigDb::DeviceAddress& addr = db()->deviceAddress(*desc);
00181     // Construct key from device description
00182     uint32_t fec_key = SiStripFecKey( addr.fecCrate_,
00183                                       addr.fecSlot_,
00184                                       addr.fecRing_,
00185                                       addr.ccuAddr_,
00186                                       addr.ccuChan_,
00187                                       0 ).key();
00188     SiStripFecKey fec_path = SiStripFecKey( fec_key );    
00189     // Do it!
00190     float delay = desc->getDelayCoarse()*25+desc->getDelayFine()*25./24. + shift;
00191     int delayCoarse = int(delay/25);
00192     int delayFine   = int(round((delay-25*delayCoarse)*24./25.));
00193     if(delayFine==24) { delayFine=0; ++delayCoarse; }
00194     delayCoarse -= minCoarseDelay;
00195     //  maximum coarse setting
00196     if ( delayCoarse > 15 ) { invalid.push_back(fec_key); delayCoarse = sistrip::invalid_; }
00197     // Update PLL settings
00198     if ( delayCoarse != sistrip::invalid_ &&
00199          delayFine != sistrip::invalid_ ) {
00200       std::stringstream ss;
00201       ss << "[LatencyHistosUsingDb::" << __func__ << "]"
00202          << " Updating coarse/fine PLL settings"
00203          << " for Crate/FEC/slot/ring/CCU "
00204          << fec_path.fecCrate() << "/"
00205          << fec_path.fecSlot() << "/"
00206          << fec_path.fecRing() << "/"
00207          << fec_path.ccuAddr() << "/"
00208          << fec_path.ccuChan()
00209          << " from "
00210          << static_cast<uint16_t>( desc->getDelayCoarse() ) << "/"
00211          << static_cast<uint16_t>( desc->getDelayFine() );
00212       desc->setDelayCoarse(delayCoarse);
00213       desc->setDelayFine(delayFine);
00214       updatedPLL++;
00215       ss << " to "
00216          << static_cast<uint16_t>( desc->getDelayCoarse() ) << "/"
00217          << static_cast<uint16_t>( desc->getDelayFine() );
00218       LogTrace(mlDqmClient_) << ss.str();
00219     }
00220   }
00221   
00222   // Retrieve FED ids from cabling
00223   std::vector<uint16_t> ids = cabling()->feds() ;
00224 
00225   // loop over the FED ids to determine min and max values of coarse delay
00226   uint16_t minDelay = 256;
00227   uint16_t maxDelay = 0;
00228   uint16_t fedDelayCoarse = 0;
00229   for ( SiStripConfigDb::FedDescriptionsV::const_iterator ifed = feds.begin(); ifed != feds.end(); ifed++ ) {
00230     // If FED id not found in list (from cabling), then continue
00231     if ( find( ids.begin(), ids.end(), (*ifed)->getFedId() ) == ids.end() ) { continue; }
00232     const std::vector<FedChannelConnection>& conns = cabling()->connections((*ifed)->getFedId());
00233     // loop over the connections for that FED
00234     for ( std::vector<FedChannelConnection>::const_iterator iconn = conns.begin(); iconn != conns.end(); iconn++ ) {
00235       // check that this is a tracker module
00236       if(DetId(iconn->detId()).det()!=DetId::Tracker) continue;
00237       // build the Fed9UAddress for that channel. Used to update the description.
00238       Fed9U::Fed9UAddress fedChannel = Fed9U::Fed9UAddress(iconn->fedCh());
00239       // retreive the current value for the delays
00240       fedDelayCoarse = (*ifed)->getCoarseDelay(fedChannel);
00241       // update min and max
00242       minDelay = minDelay<fedDelayCoarse ? minDelay : fedDelayCoarse;
00243       maxDelay = maxDelay>fedDelayCoarse ? maxDelay : fedDelayCoarse;
00244     }
00245   }
00246 
00247   // compute the FED coarse global offset
00248   int offset = (10-minDelay)*25;  // try to ensure 10BX room for later fine delay scan
00249   if(maxDelay+(offset/25)>MAXFEDCOARSE) offset = (MAXFEDCOARSE-maxDelay)*25; // otherwise, take the largest possible
00250 
00251   // loop over the FED ids
00252   for ( SiStripConfigDb::FedDescriptionsV::const_iterator ifed = feds.begin(); ifed != feds.end(); ifed++ ) {
00253     // If FED id not found in list (from cabling), then continue
00254     if ( find( ids.begin(), ids.end(), (*ifed)->getFedId() ) == ids.end() ) { continue; }
00255     const std::vector<FedChannelConnection>& conns = cabling()->connections((*ifed)->getFedId());
00256     // loop over the connections for that FED
00257     for ( std::vector<FedChannelConnection>::const_iterator iconn = conns.begin(); iconn != conns.end(); iconn++ ) {
00258       // check that this is a tracker module
00259       if(DetId(iconn->detId()).det()!=DetId::Tracker) continue;
00260       // build the Fed9UAddress for that channel. Used to update the description.
00261       Fed9U::Fed9UAddress fedChannel = Fed9U::Fed9UAddress(iconn->fedCh());
00262       // retreive the current value for the delays
00263       int fedDelayCoarse = (*ifed)->getCoarseDelay(fedChannel);
00264       int fedDelayFine = (*ifed)->getFineDelay(fedChannel);
00265       // compute the FED delay
00266       // this is done by substracting the best (PLL) delay to the present value (from the db)
00267       int fedDelay = int(fedDelayCoarse*25. - fedDelayFine*24./25. - round(shift) + offset);
00268       fedDelayCoarse = (fedDelay/25)+1;
00269       fedDelayFine = fedDelayCoarse*25-fedDelay;
00270       if(fedDelayFine==25) { fedDelayFine = 0; --fedDelayCoarse; }
00271       // update the FED delay
00272       std::stringstream ss;
00273       ss << "[LatencyHistosUsingDb::" << __func__ << "]"
00274          << " Updating the FED delay"
00275          << " for loop FED id/ch "
00276          << (*ifed)->getFedId() << "/" << iconn->fedCh()
00277          << " from "
00278          << (*ifed)->getCoarseDelay( fedChannel) << "/" << (*ifed)->getFineDelay( fedChannel)
00279          << " to ";
00280       (*ifed)->setDelay(fedChannel, fedDelayCoarse, fedDelayFine);
00281       ss << (*ifed)->getCoarseDelay(fedChannel) << "/" << (*ifed)->getFineDelay( fedChannel);
00282       LogTrace(mlDqmClient_) << ss.str();
00283     }
00284   }
00285 
00286   // Summary output
00287   edm::LogVerbatim(mlDqmClient_)
00288     << "[LatencyHistosUsingDb::" << __func__ << "]"
00289     << " Updated FED delays for " << ids.size() << " FEDs!";
00290   
00291   // Check if invalid settings were found
00292   if ( !invalid.empty() ) {
00293     std::stringstream ss;
00294     ss << "[LatencyHistosUsingDb::" << __func__ << "]"
00295        << " Found PLL coarse setting of 15"
00296        << " (not allowed!) for following channels"
00297        << " (Crate/FEC/slot/ring/CCU/LLD): ";
00298     std::vector<SiStripFecKey>::iterator ikey = invalid.begin();
00299     std::vector<SiStripFecKey>::iterator jkey = invalid.end();
00300     for ( ; ikey != jkey; ++ikey ) {
00301       ss << ikey->fecCrate() << "/"
00302          << ikey->fecSlot() << "/"
00303          << ikey->fecRing() << "/"
00304          << ikey->ccuAddr() << "/"
00305          << ikey->ccuChan() << ", ";
00306     }
00307     edm::LogWarning(mlDqmClient_) << ss.str();
00308     return false;
00309   }
00310 
00311   // Summary output
00312   edm::LogVerbatim(mlDqmClient_) 
00313     << "[LatencyHistosUsingDb::" << __func__ << "] "
00314     << "Updated settings for " << updatedAPV << " APV devices and " << updatedPLL << " PLL devices.";
00315   return true;
00316 }
00317 
00318 // -----------------------------------------------------------------------------
00320 void LatencyHistosUsingDb::create( SiStripConfigDb::AnalysisDescriptionsV& desc,
00321                                    Analysis analysis ) {
00322 
00323 #ifdef USING_NEW_DATABASE_MODEL
00324   
00325   SamplingAnalysis* anal = dynamic_cast<SamplingAnalysis*>( analysis->second );
00326   if ( !anal ) { return; }
00327   
00328   SiStripFecKey fec_key( anal->fecKey() ); //@@ analysis->first
00329   SiStripFedKey fed_key( anal->fedKey() );
00330   
00331   uint16_t latency = static_cast<uint16_t>( ( anal->maximum() / (-25.) ) + 0.5 );
00332 
00333   ApvLatencyAnalysisDescription* tmp;
00334   tmp = new ApvLatencyAnalysisDescription( latency, 
00335                                            0,
00336                                            0,
00337                                            0,
00338                                            0,
00339                                            0,
00340                                            0, 
00341                                            db()->dbParams().partitions().begin()->second.partitionName(),
00342                                            db()->dbParams().partitions().begin()->second.runNumber(),
00343                                            anal->isValid(),
00344                                            "",
00345                                            fed_key.fedId(),
00346                                            fed_key.feUnit(),
00347                                            fed_key.feChan(),
00348                                            fed_key.fedApv() );
00349     
00350   // Add comments
00351   typedef std::vector<std::string> Strings;
00352   Strings errors = anal->getErrorCodes();
00353   Strings::const_iterator istr = errors.begin();
00354   Strings::const_iterator jstr = errors.end();
00355   for ( ; istr != jstr; ++istr ) { tmp->addComments( *istr ); }
00356     
00357   // Store description
00358   desc.push_back( tmp );
00359     
00360 #endif
00361   
00362 }
00363 

Generated on Tue Jun 9 17:33:31 2009 for CMSSW by  doxygen 1.5.4