CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/DQM/SiStripCommissioningDbClients/src/FastFedCablingHistosUsingDb.cc

Go to the documentation of this file.
00001 // Last commit: $Id: FastFedCablingHistosUsingDb.cc,v 1.23 2009/11/10 14:49:02 lowette Exp $
00002 
00003 #include "DQM/SiStripCommissioningDbClients/interface/FastFedCablingHistosUsingDb.h"
00004 #include "CondFormats/SiStripObjects/interface/FastFedCablingAnalysis.h"
00005 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00006 #include "DataFormats/SiStripCommon/interface/SiStripFecKey.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include <iostream>
00009 
00010 using namespace sistrip;
00011 
00012 // -----------------------------------------------------------------------------
00014 FastFedCablingHistosUsingDb::FastFedCablingHistosUsingDb( const edm::ParameterSet & pset,
00015                                                           DQMStore* bei,
00016                                                           SiStripConfigDb* const db ) 
00017   : CommissioningHistograms( pset.getParameter<edm::ParameterSet>("FastFedCablingParameters"),
00018                              bei,
00019                              sistrip::FAST_CABLING ),
00020     CommissioningHistosUsingDb( db,
00021                                 sistrip::FAST_CABLING ),
00022     FastFedCablingHistograms( pset.getParameter<edm::ParameterSet>("FastFedCablingParameters"),
00023                               bei )
00024 {
00025   LogTrace(mlDqmClient_) 
00026     << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00027     << " Constructing object...";
00028 }
00029 
00030 // -----------------------------------------------------------------------------
00032 FastFedCablingHistosUsingDb::~FastFedCablingHistosUsingDb() {
00033   LogTrace(mlDqmClient_)
00034     << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00035     << " Destructing object...";
00036 }
00037 
00038 // -----------------------------------------------------------------------------
00040 void FastFedCablingHistosUsingDb::uploadConfigurations() {
00041   LogTrace(mlDqmClient_) 
00042     << "[FastFedCablingHistosUsingDb::" << __func__ << "]";
00043   
00044   if ( !db() ) {
00045     edm::LogError(mlDqmClient_) 
00046       << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00047       << " NULL pointer to SiStripConfigDb interface!"
00048       << " Aborting upload...";
00049     return;
00050   }
00051 
00052   SiStripDbParams::SiStripPartitions::const_iterator ip = db()->dbParams().partitions().begin();
00053   SiStripDbParams::SiStripPartitions::const_iterator jp = db()->dbParams().partitions().end();
00054   for ( ; ip != jp; ++ip ) {
00055     
00056     // Retrieve descriptions
00057     db()->clearFedConnections(); 
00058     SiStripConfigDb::FedDescriptionsRange feds = db()->getFedDescriptions( ip->second.partitionName() ); 
00059     SiStripConfigDb::DeviceDescriptionsRange dcus = db()->getDeviceDescriptions( DCU, ip->second.partitionName() ); 
00060     SiStripConfigDb::DcuDetIdsRange detids = db()->getDcuDetIds( ip->second.partitionName() ); 
00061     
00062     // Update FED connection descriptions
00063     SiStripConfigDb::FedConnectionsV conns;
00064     update( conns, feds, dcus, detids );
00065     
00066     if ( doUploadConf() ) { 
00067       edm::LogVerbatim(mlDqmClient_) 
00068         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00069         << " Uploading FED connections for partition \"" 
00070         << ip->second.partitionName() << "\" to DB...";
00071       db()->clearFedConnections( ip->second.partitionName() ); 
00072       db()->addFedConnections( ip->second.partitionName(), conns ); 
00073       db()->uploadFedConnections( ip->second.partitionName() ); 
00074       edm::LogVerbatim(mlDqmClient_) 
00075         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00076         << " Completed database upload of " << conns.size() 
00077         << " ConnectionDescriptions!";
00078     } else {
00079       edm::LogWarning(mlDqmClient_) 
00080         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00081         << " TEST only! No FED connections will be uploaded to DB...";
00082     }
00083     
00084     // Update FED descriptions with enabled/disabled channels
00085     update( feds );
00086     if ( doUploadConf() ) { 
00087       edm::LogVerbatim(mlDqmClient_) 
00088         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00089         << " Uploading FED descriptions to DB...";
00090       db()->uploadFedDescriptions( ip->second.partitionName() ); 
00091       edm::LogVerbatim(mlDqmClient_) 
00092         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00093         << " Completed database upload of " << feds.size()
00094         << " Fed9UDescriptions (with connected channels enabled)!";
00095     } else {
00096       edm::LogWarning(mlDqmClient_) 
00097         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00098         << " TEST only! No FED descriptions will be uploaded to DB...";
00099     }
00100     
00101     // Some debug on good / dirty / missing connections
00102     connections( dcus, detids );
00103     
00104   }
00105   
00106 }
00107 
00108 // -----------------------------------------------------------------------------
00110 void FastFedCablingHistosUsingDb::update( SiStripConfigDb::FedConnectionsV& conns,
00111                                           SiStripConfigDb::FedDescriptionsRange feds,
00112                                           SiStripConfigDb::DeviceDescriptionsRange dcus, 
00113                                           SiStripConfigDb::DcuDetIdsRange detids ) {
00114   
00115   // Update FED-FEC mapping in base class, based on analysis results
00116   Analyses::iterator ianal = data().begin();
00117   Analyses::iterator janal = data().end();
00118   for ( ; ianal != janal; ++ianal ) {
00119     
00120     FastFedCablingAnalysis* anal = dynamic_cast<FastFedCablingAnalysis*>( ianal->second );
00121     if ( !anal ) { 
00122       edm::LogError(mlDqmClient_)
00123         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00124         << " NULL pointer to analysis object!";
00125       continue; 
00126     }
00127     
00128     if ( !anal->isValid() || anal->dcuId() == sistrip::invalid32_ ) { continue; }
00129     
00130     SiStripFecKey fec_key( anal->fecKey() );
00131     SiStripFedKey fed_key( anal->fedKey() );
00132 
00133     ConnectionDescription* conn = new ConnectionDescription();
00134     conn->setFedId( fed_key.fedId() );
00135     conn->setFedChannel( fed_key.fedChannel() );
00136     conn->setFecHardwareId( "" ); //@@
00137     conn->setFecCrateId( fec_key.fecCrate() );
00138     conn->setFecSlot( fec_key.fecSlot() );
00139     conn->setRingSlot( fec_key.fecRing() );
00140     conn->setCcuAddress( fec_key.ccuAddr() );
00141     conn->setI2cChannel( fec_key.ccuChan() );
00142     conn->setApvAddress( SiStripFecKey::i2cAddr(anal->lldCh(),true) );
00143     conn->setDcuHardId( anal->dcuHardId() );
00144     
00145     // Retrieve FED crate and slot numbers
00146     bool found = false;
00147     SiStripConfigDb::FedDescriptionsV::const_iterator ifed = feds.begin();
00148     while ( ifed != feds.end() && !found ) {
00149       if ( *ifed ) {
00150         uint16_t fed_id = static_cast<uint16_t>( (*ifed)->getFedId() );
00151         if ( fed_key.fedId() == fed_id ) {
00152           conn->setFedCrateId( static_cast<uint16_t>( (*ifed)->getCrateNumber() ) );
00153           conn->setFedSlot( static_cast<uint16_t>( (*ifed)->getSlotNumber() ) );
00154           found = true;
00155         }
00156       } else {
00157         edm::LogError(mlDqmClient_)
00158           << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00159           << " NULL pointer to Fed9UDescription object!";
00160         continue; 
00161       }
00162       ++ifed;
00163     }
00164     if ( !found ) {
00165       edm::LogError(mlDqmClient_)
00166         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00167         << " Could not find FED id " << fed_key.fedId()
00168         << " in vector of FED descriptions!"
00169         << " Unable to set FED crate and slot for this FED!";
00170     }
00171     
00172     conns.push_back(conn);
00173 
00174   }  
00175 
00176   if (0) {
00177     SiStripConfigDb::FedConnectionsV::iterator ifed = conns.begin();
00178     for ( ; ifed != conns.end(); ifed++ ) { (*ifed)->display(); }
00179   }
00180 
00181 }
00182 
00183 // -----------------------------------------------------------------------------
00185 void FastFedCablingHistosUsingDb::update( SiStripConfigDb::FedDescriptionsRange feds ) {
00186 
00187   // Iterate through feds and disable all channels 
00188   SiStripConfigDb::FedDescriptionsV::const_iterator ifed = feds.begin();
00189   SiStripConfigDb::FedDescriptionsV::const_iterator jfed = feds.end();
00190   try {
00191     for ( ; ifed != jfed; ++ifed ) {
00192       for ( uint16_t ichan = 0; ichan < sistrip::FEDCH_PER_FED; ichan++ ) {
00193         Fed9U::Fed9UAddress addr( ichan );
00194         Fed9U::Fed9UAddress addr0( ichan, static_cast<Fed9U::u8>(0) );
00195         Fed9U::Fed9UAddress addr1( ichan, static_cast<Fed9U::u8>(1) );
00196         (*ifed)->setFedFeUnitDisable( addr, true );
00197         (*ifed)->setApvDisable( addr0, true );
00198         (*ifed)->setApvDisable( addr1, true );
00199       }
00200     }
00201   } catch( ICUtils::ICException& e ) {
00202     edm::LogWarning(mlDqmClient_) << e.what();
00203   }
00204   
00205   // Counters for number of connected / enabled channels
00206   uint16_t connected = 0;
00207   std::map< uint16_t, std::vector<uint16_t> > enabled;
00208 
00209   // Iterate through feds and enable connected channels
00210   for ( ifed = feds.begin(); ifed != feds.end(); ifed++ ) {
00211     for ( uint16_t ichan = 0; ichan < sistrip::FEDCH_PER_FED; ichan++ ) {
00212       
00213       // Retrieve FEC key from FED-FEC map
00214       SiStripFedKey fed( static_cast<uint16_t>( (*ifed)->getFedId() ),
00215                          SiStripFedKey::feUnit(ichan),
00216                          SiStripFedKey::feChan(ichan) );
00217       uint32_t fed_key = fed.key();
00218       
00219       // Retrieve analysis for given FED id and channel
00220       Analyses::const_iterator iter = data().find( fed_key );
00221       if ( iter == data().end() ) { continue; }
00222       
00223       if ( !iter->second->isValid() ) { continue; }
00224       
00225       FastFedCablingAnalysis* anal = dynamic_cast<FastFedCablingAnalysis*>( iter->second );
00226       if ( !anal ) { 
00227         edm::LogError(mlDqmClient_)
00228           << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00229           << " NULL pointer to OptoScanAnalysis object!";
00230         continue; 
00231       }
00232       
00233       // Retrieve FED id and channel 
00234       SiStripFedKey key( anal->fedKey() );
00235       uint16_t fed_id = key.fedId();
00236       uint16_t fed_ch = key.fedChannel();
00237       
00238       // Enable front-end unit and channel
00239       Fed9U::Fed9UAddress addr( fed_ch );
00240       Fed9U::Fed9UAddress addr0( fed_ch, static_cast<Fed9U::u8>(0) );
00241       Fed9U::Fed9UAddress addr1( fed_ch, static_cast<Fed9U::u8>(1) );
00242       (*ifed)->setFedFeUnitDisable( addr, false );
00243       (*ifed)->setApvDisable( addr0, false );
00244       (*ifed)->setApvDisable( addr1, false );
00245       connected++;
00246       enabled[fed_id].push_back(fed_ch);
00247       
00248     }
00249   }
00250       
00251   // Some debug 
00252   std::stringstream sss;
00253   if ( !feds.empty() ) {
00254     sss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00255         << " Enabled a total of " << connected 
00256         << " FED channels and disabled " << feds.size() * 96 - connected 
00257         << " FED channels (" << 100 * connected / ( feds.size() * 96 )
00258         << "% of total)";
00259     edm::LogVerbatim(mlDqmClient_) << sss.str();
00260   } else {
00261     sss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00262         << " Found no FEDs! (and therefore no connected channels)";
00263     edm::LogWarning(mlDqmClient_) << sss.str();
00264   }
00265   
00266   // Some debug 
00267   std::stringstream ss;
00268   ss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00269      << " Dump of enabled FED channels:" 
00270      << std::endl;
00271   std::map< uint16_t, std::vector<uint16_t> >::const_iterator fed = enabled.begin();
00272   for ( ; fed != enabled.end(); fed++ ) {
00273     ss << " Enabled " << fed->second.size()
00274        << " channels for FED id " 
00275        << std::setw(3) << fed->first << ": ";
00276     if ( !fed->second.empty() ) { 
00277       uint16_t first = fed->second.front();
00278       uint16_t last = fed->second.front();
00279       std::vector<uint16_t>::const_iterator chan = fed->second.begin();
00280       for ( ; chan != fed->second.end(); chan++ ) { 
00281         if ( chan != fed->second.begin() ) {
00282           if ( *chan != last+1 ) { 
00283             ss << std::setw(2) << first << "->" << std::setw(2) << last << ", ";
00284             if ( chan != fed->second.end() ) { first = *(chan+1); }
00285           } 
00286         }
00287         last = *chan;
00288       }
00289       if ( first != last ) { ss << std::setw(2) << first << "->" << std::setw(2) << last; }
00290       ss << std::endl;
00291     }
00292   }
00293   LogTrace(mlDqmClient_) << ss.str();
00294   
00295 }
00296 
00297 // -----------------------------------------------------------------------------
00298 // 
00299 void FastFedCablingHistosUsingDb::addDcuDetIds() {
00300 
00301   if ( !cabling() ) {
00302     edm::LogError(mlDqmClient_) 
00303       << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00304       << " NULL pointer to SiStripFedCabling object!";
00305     return;
00306   }
00307 
00308   // retrieve descriptions for dcu id and det id 
00309   SiStripConfigDb::DeviceDescriptionsRange dcus = db()->getDeviceDescriptions( DCU ); 
00310   SiStripConfigDb::DcuDetIdsRange detids = db()->getDcuDetIds(); 
00311   
00312   if ( dcus.empty() ) { 
00313     edm::LogError(mlCabling_)
00314       << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00315       << " No DCU descriptions found!";
00316     return;
00317   }
00318   
00319   if ( detids.empty() ) { 
00320     edm::LogWarning(mlCabling_)
00321       << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00322       << " DCU-DetId map is empty!";
00323   }
00324   
00325   Analyses::iterator ianal = data().begin();
00326   Analyses::iterator janal = data().end();
00327   for ( ; ianal != janal; ++ianal ) { 
00328 
00329     // check if analysis is valid (ie, dcu id and lld channel have been identified)
00330     if ( !ianal->second->isValid() ) { continue; }
00331     
00332     // retrieve analysis object
00333     FastFedCablingAnalysis* anal = dynamic_cast<FastFedCablingAnalysis*>( ianal->second );
00334     
00335     if ( !anal ) {
00336       edm::LogError(mlDqmClient_) 
00337         << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00338         << " NULL pointer to FastFedCablingAnalysis object!";
00339       return;
00340     }
00341 
00342     // find dcu that matches analysis result 
00343     bool found = false;
00344     SiStripConfigDb::DeviceDescriptionsV::const_iterator idcu = dcus.begin();
00345     SiStripConfigDb::DeviceDescriptionsV::const_iterator jdcu = dcus.end();
00346     while ( !found && idcu != jdcu ) {
00347       dcuDescription* dcu = dynamic_cast<dcuDescription*>( *idcu );
00348       if ( dcu ) { 
00349         if ( dcu->getDcuType() == "FEH" ) { 
00350           if ( dcu->getDcuHardId() == anal->dcuHardId() ) {
00351             found = true; 
00352             anal->dcuId( dcu->getDcuHardId() ); 
00353             const SiStripConfigDb::DeviceAddress& addr = db()->deviceAddress(*dcu);
00354             uint32_t fec_key = SiStripFecKey( addr.fecCrate_,
00355                                               addr.fecSlot_,
00356                                               addr.fecRing_,
00357                                               addr.ccuAddr_,
00358                                               addr.ccuChan_,
00359                                               anal->lldCh() ).key();
00360             anal->fecKey( fec_key );
00361             SiStripConfigDb::DcuDetIdsV::const_iterator idet = detids.end();
00362             idet = SiStripConfigDb::findDcuDetId( detids.begin(), detids.end(), dcu->getDcuHardId() );
00363             if ( idet != detids.end() ) { anal->detId( idet->second->getDetId() ); }
00364           }
00365         }
00366       }
00367       idcu++;
00368     }
00369 
00370   }
00371 
00372 }
00373 
00374 // -----------------------------------------------------------------------------
00376 void FastFedCablingHistosUsingDb::create( SiStripConfigDb::AnalysisDescriptionsV& desc,
00377                                           Analysis analysis ) {
00378 
00379   FastFedCablingAnalysis* anal = dynamic_cast<FastFedCablingAnalysis*>( analysis->second );
00380   if ( !anal ) { return; }
00381   
00382   if ( !anal->isValid() || anal->dcuId() == sistrip::invalid32_ ) { return; } //@@ only store valid descriptions!
00383   
00384   SiStripFecKey fec_key( anal->fecKey() );
00385   SiStripFedKey fed_key( anal->fedKey() );
00386     
00387   for ( uint16_t iapv = 0; iapv < 2; ++iapv ) {
00388     
00389     // Create description
00390     FastFedCablingAnalysisDescription* tmp;
00391     tmp = new FastFedCablingAnalysisDescription( anal->highLevel(),
00392                                                  anal->highRms(),
00393                                                  anal->lowLevel(),
00394                                                  anal->lowRms(),
00395                                                  anal->max(),
00396                                                  anal->min(),
00397                                                  anal->dcuId(),
00398                                                  anal->lldCh(),
00399                                                  anal->isDirty(),
00400                                                  FastFedCablingAnalysis::threshold_,
00401                                                  FastFedCablingAnalysis::dirtyThreshold_,
00402                                                  fec_key.fecCrate(),
00403                                                  fec_key.fecSlot(),
00404                                                  fec_key.fecRing(),
00405                                                  fec_key.ccuAddr(),
00406                                                  fec_key.ccuChan(),
00407                                                  SiStripFecKey::i2cAddr( fec_key.lldChan(), !iapv ), 
00408                                                  db()->dbParams().partitions().begin()->second.partitionName(),
00409                                                  db()->dbParams().partitions().begin()->second.runNumber(),
00410                                                  anal->isValid(),
00411                                                  "",
00412                                                  fed_key.fedId(),
00413                                                  fed_key.feUnit(),
00414                                                  fed_key.feChan(),
00415                                                  fed_key.fedApv() );
00416       
00417     // Add comments
00418     typedef std::vector<std::string> Strings;
00419     Strings errors = anal->getErrorCodes();
00420     Strings::const_iterator istr = errors.begin();
00421     Strings::const_iterator jstr = errors.end();
00422     for ( ; istr != jstr; ++istr ) { tmp->addComments( *istr ); }
00423 
00424     // Store description
00425     desc.push_back( tmp );
00426       
00427   }
00428 
00429 }
00430 
00431 // -----------------------------------------------------------------------------
00432 // prints debug info on good, dirty, missing connections, and missing devices
00433 void FastFedCablingHistosUsingDb::connections( SiStripConfigDb::DeviceDescriptionsRange dcus, 
00434                                                SiStripConfigDb::DcuDetIdsRange detids ) {
00435   
00436   // strings
00437   std::vector<std::string> valid;
00438   std::vector<std::string> dirty;
00439   std::vector<std::string> trimdac;
00440   std::vector<std::string> missing;
00441   std::vector<std::string> devices;
00442   uint32_t missing_pairs = 0;
00443 
00444   // iterate through analyses
00445   std::vector<uint32_t> found_dcus;
00446   Analyses::iterator ianal = data().begin();
00447   Analyses::iterator janal = data().end();
00448   for ( ; ianal != janal; ++ianal ) {
00449 
00450     // extract fast fed cabling object
00451     FastFedCablingAnalysis* anal = dynamic_cast<FastFedCablingAnalysis*>( ianal->second );
00452     if ( !anal ) { continue; }
00453     
00454     // construct strings for various categories of connections
00455     std::stringstream ss;
00456     SiStripFedKey( anal->fedKey() ).terse(ss); ss << " ";
00457     SiStripFecKey( anal->fecKey() ).terse(ss); ss << " "; 
00458     ss << "DcuId= " << std::hex << std::setw(8) << std::setfill('0') << anal->dcuId() << std::dec << " ";
00459     ss << "DetId= " << std::hex << std::setw(8) << std::setfill('0') << anal->detId() << std::dec;
00460     if ( anal->isValid() &&
00461          !(anal->isDirty()) &&
00462          !(anal->badTrimDac()) ) { valid.push_back( ss.str() ); }
00463     if ( anal->isDirty() ) { dirty.push_back( ss.str() ); }
00464     if ( anal->badTrimDac() ) { trimdac.push_back( ss.str() ); }
00465     
00466     // record "found" dcus
00467     found_dcus.push_back( anal->dcuHardId() );
00468 
00469   }
00470   
00471   // iterate through dcu devices
00472   SiStripConfigDb::DeviceDescriptionsV::const_iterator idcu = dcus.begin();
00473   SiStripConfigDb::DeviceDescriptionsV::const_iterator jdcu = dcus.end();
00474   for ( ; idcu != jdcu; ++idcu ) {
00475     
00476     // extract dcu description
00477     dcuDescription* dcu = dynamic_cast<dcuDescription*>( *idcu );
00478     if ( !dcu ) { continue; }
00479     if ( dcu->getDcuType() != "FEH" ) { continue; }
00480     SiStripConfigDb::DeviceAddress dcu_addr = db()->deviceAddress( *dcu );
00481     
00482     // continue if dcu has been "found"
00483     std::vector<uint32_t>::const_iterator iter = find( found_dcus.begin(), found_dcus.end(), dcu->getDcuHardId() );
00484     if ( iter != found_dcus.end() ) { continue; }
00485     
00486     // find detid for "missing" dcu
00487     SiStripConfigDb::DcuDetIdsV::const_iterator idet = detids.end();
00488     idet = SiStripConfigDb::findDcuDetId( detids.begin(), detids.end(), dcu->getDcuHardId() );
00489     if ( idet == detids.end() ) { continue; }
00490     if ( idet->second ) { continue; }
00491     
00492     // retrieve number of apv pairs
00493     uint16_t npairs = idet->second->getApvNumber()/2; 
00494   
00495     // retrieve apvs for given dcu
00496     vector<bool> addrs; 
00497     addrs.resize(6,false);
00498     SiStripConfigDb::DeviceDescriptionsRange apvs = db()->getDeviceDescriptions( APV25 );
00499     SiStripConfigDb::DeviceDescriptionsV::const_iterator iapv = apvs.begin();
00500     SiStripConfigDb::DeviceDescriptionsV::const_iterator japv = apvs.end();
00501     for ( ; iapv != japv; ++iapv ) {
00502       apvDescription* apv = dynamic_cast<apvDescription*>( *iapv );
00503       if ( !apv ) { continue; }
00504       SiStripConfigDb::DeviceAddress apv_addr = db()->deviceAddress( *apv );
00505       if ( apv_addr.fecCrate_ == dcu_addr.fecCrate_ &&
00506            apv_addr.fecSlot_  == dcu_addr.fecSlot_ &&
00507            apv_addr.fecRing_  == dcu_addr.fecRing_ &&
00508            apv_addr.ccuAddr_  == dcu_addr.ccuAddr_ &&
00509            apv_addr.ccuChan_  == dcu_addr.ccuChan_ ) {
00510         uint16_t pos = apv_addr.i2cAddr_ - 32;
00511         if ( pos < 6 ) { addrs[pos] = true; }
00512       }
00513     }
00514     
00515     // construct strings for missing fibres
00516     uint16_t pairs = 0;
00517     if ( addrs[0] || addrs[1] ) {
00518       pairs++;
00519       std::stringstream ss;
00520       SiStripFecKey( dcu_addr.fecCrate_,
00521                      dcu_addr.fecSlot_,
00522                      dcu_addr.fecRing_,
00523                      dcu_addr.ccuAddr_,
00524                      dcu_addr.ccuChan_,
00525                      1 ).terse(ss); 
00526       ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00527       ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00528       missing.push_back( ss.str() ); 
00529     } 
00530     if ( addrs[2] || addrs[3] ) {
00531       pairs++;
00532       std::stringstream ss;
00533       SiStripFecKey( dcu_addr.fecCrate_,
00534                      dcu_addr.fecSlot_,
00535                      dcu_addr.fecRing_,
00536                      dcu_addr.ccuAddr_,
00537                      dcu_addr.ccuChan_,
00538                      2 ).terse(ss); 
00539       ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00540       ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00541       missing.push_back( ss.str() ); 
00542     } 
00543     if ( addrs[4] || addrs[5] ) {
00544       pairs++;
00545       std::stringstream ss;
00546       SiStripFecKey( dcu_addr.fecCrate_,
00547                      dcu_addr.fecSlot_,
00548                      dcu_addr.fecRing_,
00549                      dcu_addr.ccuAddr_,
00550                      dcu_addr.ccuChan_,
00551                      3 ).terse(ss); 
00552       ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00553       ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00554       missing.push_back( ss.str() ); 
00555     }
00556     
00557     if ( pairs != npairs ) {
00558       
00559       missing_pairs = npairs - pairs;
00560       
00561       if ( !addrs[0] ) { 
00562         std::stringstream ss;
00563         SiStripFecKey( dcu_addr.fecCrate_,
00564                        dcu_addr.fecSlot_,
00565                        dcu_addr.fecRing_,
00566                        dcu_addr.ccuAddr_,
00567                        dcu_addr.ccuChan_,
00568                        1, 32 ).terse(ss); 
00569         ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00570         ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00571         devices.push_back( ss.str() ); 
00572       }
00573       
00574       if ( !addrs[1] ) { 
00575         std::stringstream ss;
00576         SiStripFecKey( dcu_addr.fecCrate_,
00577                        dcu_addr.fecSlot_,
00578                        dcu_addr.fecRing_,
00579                        dcu_addr.ccuAddr_,
00580                        dcu_addr.ccuChan_,
00581                        1, 33 ).terse(ss); 
00582         ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00583         ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00584         devices.push_back( ss.str() ); 
00585       }
00586       
00587       if ( !addrs[2] && npairs == 3 ) {
00588         std::stringstream ss;
00589         SiStripFecKey( dcu_addr.fecCrate_,
00590                        dcu_addr.fecSlot_,
00591                        dcu_addr.fecRing_,
00592                        dcu_addr.ccuAddr_,
00593                        dcu_addr.ccuChan_,
00594                        2, 34 ).terse(ss); 
00595         ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00596         ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00597         devices.push_back( ss.str() ); 
00598       }
00599       
00600       if ( !addrs[3] && npairs == 3 ) {
00601         std::stringstream ss;
00602         SiStripFecKey( dcu_addr.fecCrate_,
00603                        dcu_addr.fecSlot_,
00604                        dcu_addr.fecRing_,
00605                        dcu_addr.ccuAddr_,
00606                        dcu_addr.ccuChan_,
00607                        2, 35 ).terse(ss); 
00608         ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00609         ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00610         devices.push_back( ss.str() ); 
00611       }
00612       
00613       if ( !addrs[4] ) { 
00614         std::stringstream ss;
00615         SiStripFecKey( dcu_addr.fecCrate_,
00616                        dcu_addr.fecSlot_,
00617                        dcu_addr.fecRing_,
00618                        dcu_addr.ccuAddr_,
00619                        dcu_addr.ccuChan_,
00620                        3, 36 ).terse(ss); 
00621         ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00622         ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00623         devices.push_back( ss.str() ); 
00624       }
00625       
00626       if ( !addrs[5] ) { 
00627         std::stringstream ss;
00628         SiStripFecKey( dcu_addr.fecCrate_,
00629                        dcu_addr.fecSlot_,
00630                        dcu_addr.fecRing_,
00631                        dcu_addr.ccuAddr_,
00632                        dcu_addr.ccuChan_,
00633                        3, 37 ).terse(ss); 
00634         ss << " DcuId=" << std::hex << std::setw(8) << std::setfill('0') << dcu->getDcuHardId() << std::dec;
00635         ss << " DetId=" << std::hex << std::setw(8) << std::setfill('0') << idet->first << std::dec;
00636         devices.push_back( ss.str() ); 
00637       }
00638       
00639     }
00640 
00641   }
00642 
00643   // summary
00644   { 
00645     std::stringstream ss;
00646     ss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00647        << " Summary of connections: " << std::endl
00648        << " \"Good\" connections     : " << valid.size() << std::endl
00649        << " \"Dirty\" connections    : " << dirty.size() << std::endl
00650        << " \"Bad\" TrimDAQ settings : " << trimdac.size() << std::endl
00651        << " (\"Missing\" connections : " << missing.size() << ")" << std::endl
00652        << " (\"Missing\" APV pairs   : " << missing_pairs << ")" << std::endl
00653        << " (\"Missing\" APVs        : " << devices.size() << ")" << std::endl;
00654     edm::LogVerbatim(mlCabling_) << ss.str();
00655   }
00656 
00657   // good connections
00658   if ( !valid.empty() ) { 
00659     std::stringstream ss;
00660     ss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00661        << " List of \"good\" connections: " << std::endl;
00662     std::vector<std::string>::const_iterator istr = valid.begin();
00663     std::vector<std::string>::const_iterator jstr = valid.end();
00664     for ( ; istr != jstr; ++istr ) { ss << *istr << std::endl; }
00665     LogTrace(mlCabling_) << ss.str();
00666   }
00667 
00668   // dirty connections
00669   if ( !dirty.empty() ) { 
00670     std::stringstream ss;
00671     ss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00672        << " List of \"dirty\" connections: " << std::endl;
00673     std::vector<std::string>::const_iterator istr = dirty.begin();
00674     std::vector<std::string>::const_iterator jstr = dirty.end();
00675     for ( ; istr != jstr; ++istr ) { ss << *istr << std::endl; }
00676     edm::LogWarning(mlCabling_) << ss.str();
00677   }
00678 
00679   // TrimDAC connections
00680   if ( !trimdac.empty() ) { 
00681     std::stringstream ss;
00682     ss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00683        << " List of \"bad\" TrimDAC settings: " << std::endl;
00684     std::vector<std::string>::const_iterator istr = trimdac.begin();
00685     std::vector<std::string>::const_iterator jstr = trimdac.end();
00686     for ( ; istr != jstr; ++istr ) { ss << *istr << std::endl; }
00687     edm::LogWarning(mlCabling_) << ss.str();
00688   }
00689 
00690   // missing connections
00691   if ( !missing.empty() ) { 
00692     std::stringstream ss;
00693     ss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00694        << " List of \"missing\" connections: " << std::endl;
00695     std::vector<std::string>::const_iterator istr = missing.begin();
00696     std::vector<std::string>::const_iterator jstr = missing.end();
00697     for ( ; istr != jstr; ++istr ) { ss << *istr << std::endl; }
00698     edm::LogError(mlCabling_) << ss.str();
00699   }
00700 
00701   // missing devices
00702   if ( !devices.empty() ) { 
00703     std::stringstream ss;
00704     ss << "[FastFedCablingHistosUsingDb::" << __func__ << "]"
00705        << " List of \"missing\" APVs: " << std::endl;
00706     std::vector<std::string>::const_iterator istr = devices.begin();
00707     std::vector<std::string>::const_iterator jstr = devices.end();
00708     for ( ; istr != jstr; ++istr ) { ss << *istr << std::endl; }
00709     edm::LogError(mlCabling_) << ss.str();
00710   }
00711 
00712 }