CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/CondFormats/SiStripObjects/src/SiStripFedCabling.cc

Go to the documentation of this file.
00001 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
00002 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00003 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include <iostream>
00006 #include <iomanip>
00007 
00008 using namespace sistrip;
00009 
00010 
00011 // -----------------------------------------------------------------------------
00012 #ifndef SISTRIPCABLING_USING_NEW_STRUCTURE // ----------------------------------
00013 // -----------------------------------------------------------------------------
00014 
00015 
00016 // -----------------------------------------------------------------------------
00017 //
00018 SiStripFedCabling::SiStripFedCabling( const std::vector<FedChannelConnection>& input ) 
00019   : feds_(),
00020     connected_(),
00021     detected_(),
00022     undetected_()
00023 {
00024   LogTrace(mlCabling_)
00025     << "[SiStripFedCabling::" << __func__ << "]"
00026     << " Constructing object...";
00027   buildFedCabling( input );
00028 }
00029 
00030 // -----------------------------------------------------------------------------
00031 //
00032 SiStripFedCabling::SiStripFedCabling( const SiStripFedCabling& input ) 
00033   : feds_(),
00034     connected_(),
00035     detected_(),
00036     undetected_()
00037 {
00038   LogTrace(mlCabling_)
00039     << "[SiStripFedCabling::" << __func__ << "]"
00040     << " Constructing object...";
00041 
00042   std::vector<FedChannelConnection> v_fcc;
00043 
00044   // Retrieve FED ids from cabling map and iterate through                                                                                                                                                    
00045   const std::vector<uint16_t>& fedids = input.feds();
00046   std::vector<uint16_t>::const_iterator ifed=fedids.begin();
00047   for ( ; ifed != fedids.end(); ++ifed ) {
00048     //copy the vector of FedChannelConnection for the given ifed 
00049     v_fcc.insert(v_fcc.end(),input.connections(*ifed).begin(),input.connections(*ifed).end());
00050   }
00051 
00052   buildFedCabling( v_fcc );
00053   
00054 }
00055 
00056 // -----------------------------------------------------------------------------
00057 //
00058 SiStripFedCabling::SiStripFedCabling() 
00059   : feds_(),
00060     connected_(),
00061     detected_(),
00062     undetected_()
00063 {
00064   LogTrace(mlCabling_) 
00065     << "[SiStripFedCabling::" << __func__ << "]"
00066     << " Constructing object...";
00067 }
00068 
00069 // -----------------------------------------------------------------------------
00070 //
00071 SiStripFedCabling::~SiStripFedCabling() {
00072   LogTrace(mlCabling_)
00073     << "[SiStripFedCabling::" << __func__ << "]"
00074     << " Destructing object...";
00075 }
00076 
00077 // -----------------------------------------------------------------------------
00078 //
00079 void SiStripFedCabling::buildFedCabling( const std::vector<FedChannelConnection>& input ) {
00080   
00081   // Check input
00082   if ( input.empty() ) {
00083     edm::LogError(mlCabling_)
00084       << "[SiStripFedCabling::" << __func__ << "]"
00085       << " Input vector of FedChannelConnections is of zero size!"
00086       << " Unable to populate FED cabling object!"; 
00087     return;
00088   }
00089   
00090   std::stringstream ss;
00091   ss << "[SiStripFedCabling::" << __func__ << "]"
00092      << " Building FED cabling from " 
00093      << input.size()
00094      << " connections...";
00095   LogTrace(mlCabling_) << ss.str();
00096   
00097   // Clear containers
00098   connected_.clear(); 
00099   detected_.clear();
00100   undetected_.clear();
00101   
00102   // Iterate through FEDs
00103   for ( uint16_t iconn = 0; iconn < input.size(); iconn++ ) {
00104 
00105     if ( !input[iconn].isConnected() ) { continue; }
00106     
00107     uint16_t fed_id = input[iconn].fedId();
00108     uint16_t fed_ch = input[iconn].fedCh();
00109     
00110     // Check on FED ids and channels
00111     if ( fed_id > sistrip::CMS_FED_ID_MAX ) {
00112       if ( edm::isDebugEnabled() ) {
00113         edm::LogWarning(mlCabling_)
00114           << "[SiStripFedCabling::" << __func__ << "]"
00115           << " Unexpected FED id! " << fed_id; 
00116       } 
00117       continue;
00118     }
00119     if ( fed_ch >= sistrip::FEDCH_PER_FED ) {
00120       if ( edm::isDebugEnabled() ) {
00121         edm::LogWarning(mlCabling_)
00122           << "[SiStripFedCabling::" << __func__ << "]"
00123           << " Unexpected FED channel! " << fed_ch;
00124       } 
00125       continue;
00126     }
00127     
00128     // Resize container to accommodate all FED channels
00129     if ( connected_.size() <= fed_id ) { connected_.resize(fed_id+1); }
00130     if ( connected_[fed_id].size() != 96 ) { connected_[fed_id].resize(96); }
00131     
00132     // Fill appropriate container
00133     bool detected  = input[iconn].i2cAddr(0) || input[iconn].i2cAddr(1);
00134     bool connected = input[iconn].fedId(); //@@ should check also FeUnit/FeChan are not invalid ???
00135     if ( detected && connected ) {
00136       connected_[fed_id][fed_ch] = input[iconn];
00137     } else if ( detected && !connected ) {
00138       detected_.push_back( input[iconn] );
00139     } else if ( !detected && !connected ) {
00140       undetected_.push_back( input[iconn] );
00141     }
00142 
00143     if ( detected && connected ) {
00144       std::vector<uint16_t>::iterator id = find( feds_.begin(), feds_.end(), fed_id );
00145       if ( id == feds_.end() ) { feds_.push_back( fed_id ); }
00146     }
00147     
00148   }
00149   
00150 }
00151 
00152 // -----------------------------------------------------------------------------
00153 // Returns active FEDs
00154 const std::vector<uint16_t>& SiStripFedCabling::feds() const {
00155   return feds_;
00156 }
00157 
00158 // -----------------------------------------------------------------------------
00159 // Returns connection info for FE devices connected to given FED id and channel
00160 const FedChannelConnection& SiStripFedCabling::connection( uint16_t fed_id, 
00161                                                            uint16_t fed_chan ) const {
00162 
00163   //@@ should use connections(fed_id) method here!!!
00164   
00165   if ( !connected_.empty() ) {
00166     if ( fed_id < connected_.size() ) {
00167       if ( !connected_[fed_id].empty() ) {
00168         if ( fed_chan < connected_[fed_id].size() ) {
00169           return connected_[fed_id][fed_chan];
00170         } else {
00171           if ( edm::isDebugEnabled() ) {
00172             edm::LogWarning(mlCabling_)
00173               << "[SiStripFedCabling::" << __func__ << "]" 
00174               << " FED channel (" << fed_chan
00175               << ") is greater than or equal to vector size (" 
00176               << connected_[fed_chan].size() << ")!";
00177           }
00178         }
00179       } else {
00180         if ( edm::isDebugEnabled() ) {
00181           edm::LogWarning(mlCabling_)
00182             << "[SiStripFedCabling::" << __func__ << "]" 
00183             << " Cabling map is empty for FED id "
00184             << fed_id;
00185         }
00186       }
00187     } else {
00188       if ( edm::isDebugEnabled() ) {
00189         edm::LogWarning(mlCabling_) 
00190           << "[SiStripFedCabling::" << __func__ << "]" 
00191           << " FED id (" << fed_id
00192           << ") is greater than or equal to vector size (" 
00193           << connected_.size() << ")!";
00194       }
00195     }
00196   } else {
00197     edm::LogError(mlCabling_)
00198       << "[SiStripFedCabling::" << __func__ << "]" 
00199       << " Cabling map is empty!";
00200   }
00201   
00202   static FedChannelConnection conn; 
00203   return conn;
00204   
00205 }
00206 
00207 // -----------------------------------------------------------------------------
00208 // Returns connection info for FE devices connected to given FED 
00209 const std::vector<FedChannelConnection>& SiStripFedCabling::connections( uint16_t fed_id ) const {
00210   
00211   if ( !connected_.empty() ) {
00212     if ( fed_id < connected_.size() ) {
00213       if ( !connected_[fed_id].empty() ) {
00214         return connected_[fed_id];
00215       } else {
00216         if ( edm::isDebugEnabled() ) {
00217           edm::LogWarning(mlCabling_)
00218             << "[SiStripFedCabling::" << __func__ << "]" 
00219             << " Cabling map is empty for FED id "
00220             << fed_id;
00221         }
00222       }
00223     } else {
00224       if ( edm::isDebugEnabled() ) {
00225         edm::LogWarning(mlCabling_)
00226           << "[SiStripFedCabling::" << __func__ << "]" 
00227           << " FED id (" << fed_id
00228           << ") is greater than or equal to vector size (" 
00229           << connected_.size() << ")!";
00230       }
00231     }
00232   } else {
00233     edm::LogError(mlCabling_)
00234       << "[SiStripFedCabling::" << __func__ << "]" 
00235       << " Cabling map is empty!";
00236   }
00237   
00238   static FedChannelConnection conn; 
00239   static std::vector<FedChannelConnection> connections(96,conn); 
00240   return connections;
00241   
00242 }
00243 
00244 // -----------------------------------------------------------------------------
00245 // 
00246 void SiStripFedCabling::print( std::stringstream& ss ) const {
00247   
00248   const std::vector<uint16_t>& fed_ids = feds();
00249   if ( feds().empty() ) {
00250     ss << "[SiStripFedCabling::" << __func__ << "]"
00251        << " No FEDs found! Unable to  print cabling map!";
00252     return;
00253   } else {
00254     ss << "[SiStripFedCabling::" << __func__ << "]"
00255        << " Printing cabling map for " << fed_ids.size()
00256        << " FEDs with following ids: ";
00257   }
00258 
00259   std::vector<uint16_t>::const_iterator ii = fed_ids.begin(); 
00260   for ( ; ii != fed_ids.end(); ii++ ) { ss << *ii << " "; }
00261   ss << std::endl << std::endl;
00262   
00263   uint16_t total = 0;
00264   uint16_t nfeds = 0;
00265   uint16_t cntr = 0;
00266   
00267   std::vector<uint16_t>::const_iterator ifed = fed_ids.begin(); 
00268   for ( ; ifed != fed_ids.end(); ifed++ ) {
00269     const std::vector<FedChannelConnection>& conns = connections(*ifed);
00270     
00271     ss << " Printing cabling information for FED id " << *ifed 
00272        << " (found " << conns.size() 
00273        << " FedChannelConnection objects...)"
00274        << std::endl;
00275     
00276     uint16_t ichan = 0;
00277     uint16_t connected = 0;
00278     std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
00279     for ( ; iconn != conns.end(); iconn++ ) { 
00280       if ( iconn->fedId() != sistrip::invalid_ ) { 
00281         connected++; 
00282         ss << *iconn << std::endl;
00283       } else {
00284         ss << "  (FedId/Ch " << *ifed << "/" << ichan 
00285            << ": unconnected channel...)" << std::endl;
00286         cntr++;
00287       }
00288       ichan++;
00289     } 
00290     
00291     ss << " Found " << connected 
00292        << " connected channels for FED id " << *ifed << std::endl
00293        << std::endl;
00294     if ( connected ) { nfeds++; total += connected; }
00295     
00296   } // fed loop
00297   
00298   float percent = (100.*cntr) / (96.*nfeds);
00299   percent = static_cast<uint16_t>( 10.*percent );
00300   percent /= 10.;
00301   ss << " Found " << total 
00302      << " APV pairs that are connected to a total of " 
00303      << nfeds << " FEDs" << std::endl
00304      << " " << detected_.size() 
00305      << " APV pairs have been detected, but are not connected" << std::endl
00306      << " " << undetected_.size()
00307      << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
00308      << " " << cntr
00309      << " FED channels out of a possible " << (96*nfeds)
00310      << " (" << nfeds << " FEDs) are unconnected (" 
00311      << percent << "%)" << std::endl
00312      << std::endl;
00313   
00314 }
00315 
00316 // -----------------------------------------------------------------------------
00317 // 
00318 void SiStripFedCabling::terse( std::stringstream& ss ) const {
00319   
00320   ss << "[SiStripFedCabling::" << __func__ << "]";
00321     
00322   const std::vector<uint16_t>& fed_ids = feds();
00323   if ( feds().empty() ) {
00324     ss << " No FEDs found! Unable to print cabling map!";
00325     return;
00326   } 
00327   
00328   ss << " Printing cabling map for " << fed_ids.size()
00329      << " FEDs: " << std::endl << std::endl;
00330   
00331   std::vector<uint16_t>::const_iterator ifed = fed_ids.begin(); 
00332   for ( ; ifed != fed_ids.end(); ifed++ ) {
00333 
00334     const std::vector<FedChannelConnection>& conns = connections(*ifed);
00335     
00336     ss << " Printing cabling information for FED id " << *ifed 
00337        << " (found " << conns.size() 
00338        << " FedChannelConnection objects...)"
00339        << std::endl;
00340     
00341     uint16_t connected = 0;
00342     std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
00343     for ( ; iconn != conns.end(); iconn++ ) { 
00344       if ( iconn->fedId() < sistrip::valid_ ) { 
00345         connected++; 
00346         iconn->terse(ss); 
00347         ss << std::endl;
00348       } 
00349     }
00350 
00351     ss << " Found " << connected 
00352        << " connected channels for FED id " << *ifed << std::endl
00353        << std::endl;
00354     
00355   }
00356   
00357 }
00358 
00359 // -----------------------------------------------------------------------------
00360 // 
00361 void SiStripFedCabling::summary( std::stringstream& ss ) const {
00362 
00363   ss << "[SiStripFedCabling::" << __func__ << "]";
00364   
00365   const std::vector<uint16_t>& fed_ids = feds();
00366   if ( feds().empty() ) {
00367     ss << " No FEDs found!";
00368     return;
00369   } 
00370   
00371   ss << " Found " << feds().size() << " FEDs"
00372      << " with number of connected channels per front-end unit: " 
00373      << std::endl
00374      << " FedId FeUnit1 FeUnit2 FeUnit3 FeUnit4 FeUnit5 FeUnit6 FeUnit7 FeUnit8 Total" 
00375      << std::endl;
00376   
00377   uint16_t total = 0;
00378   uint16_t nfeds = 0;
00379   
00380   // iterate through fed ids
00381   std::vector<uint16_t>::const_iterator ii = fed_ids.begin(); 
00382   std::vector<uint16_t>::const_iterator jj = fed_ids.end(); 
00383   for ( ; ii != jj; ++ii ) { 
00384     
00385     // check number of connection objects
00386     const std::vector<FedChannelConnection>& conns = connections(*ii);
00387     if ( conns.size() < 96 ) { 
00388       edm::LogError(mlCabling_) 
00389         << "[SiStripFedCabling::" << __func__ << "]"
00390         << " Unexpected size for FedChannelConnection vector! " 
00391         << conns.size();
00392       return;
00393     }
00394 
00395     // count connected channels at level of fe unit
00396     std::vector<uint16_t> connected;
00397     connected.resize(8,0);
00398     for ( uint16_t ichan = 0; ichan < 96; ++ichan ) {
00399       if ( conns[ichan].fedId() < sistrip::valid_ ) { 
00400         uint16_t unit = SiStripFedKey::feUnit(ichan);
00401         if ( unit > 8 ) { continue; }
00402         connected[unit-1]++; 
00403       } 
00404     }
00405 
00406     // increment counters
00407     uint16_t tot = 0 ;
00408     ss << " " << std::setw(5) << *ii;
00409     if ( !connected.empty() ) { nfeds++; }
00410     for ( uint16_t unit = 0; unit < 8; ++unit ) {
00411       ss << " " << std::setw(7) << connected[unit];
00412       if ( !connected.empty() ) { tot += connected[unit]; }
00413     }
00414     ss << " " << std::setw(5) << tot << std::endl;
00415     total += tot;
00416     
00417   } 
00418   
00419   // print out
00420   float percent = (100.*total) / (96.*nfeds);
00421   percent = static_cast<uint16_t>( 10.*percent );
00422   percent /= 10.;
00423   ss << " Found: " << std::endl 
00424      << " " << nfeds << " out of " << feds().size() << " FEDs with at least one connected channel " << std::endl 
00425      << " " << feds().size() - nfeds << " out of " << feds().size() << " FEDs with no connected channels." << std::endl 
00426      << " " << total << " connected channels in total" << std::endl
00427      << " " << detected_.size()  << " APV pairs have been detected, but are not connected" << std::endl
00428      << " " << undetected_.size() << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
00429      << " " << percent << "% of FED channels are connected"  << std::endl;
00430   
00431 }
00432 
00433 // -----------------------------------------------------------------------------
00434 //
00435 std::ostream& operator<< ( std::ostream& os, const SiStripFedCabling& cabling ) {
00436   std::stringstream ss;
00437   cabling.print(ss);
00438   os << ss.str();
00439   return os;
00440 }
00441 
00442 
00443 // -----------------------------------------------------------------------------
00444 #else // SISTRIPCABLING_USING_NEW_STRUCTURE ------------------------------------
00445 #ifndef SISTRIPCABLING_USING_NEW_INTERFACE // ----------------------------------
00446 // -----------------------------------------------------------------------------
00447 
00448 
00449 // -----------------------------------------------------------------------------
00450 //
00451 SiStripFedCabling::SiStripFedCabling( const std::vector<FedChannelConnection>& input ) 
00452   : feds_(),
00453     registry_(),
00454     connections_(),
00455     detected_(),
00456     undetected_()
00457 {
00458   LogTrace(mlCabling_)
00459     << "[SiStripFedCabling::" << __func__ << "]"
00460     << " Constructing object...";
00461   buildFedCabling( input );
00462 }
00463 
00464 // -----------------------------------------------------------------------------
00465 //
00466 SiStripFedCabling::SiStripFedCabling( const SiStripFedCabling& input ) 
00467   : feds_( input.feds_ ),
00468     registry_( input.registry_ ),
00469     connections_( input.connections_ ),
00470     detected_( input.detected_ ),
00471     undetected_( input.undetected_ )
00472 {
00473   LogTrace(mlCabling_)
00474     << "[SiStripFedCabling::" << __func__ << "]"
00475     << " Constructing object...";
00476 }
00477 
00478 // -----------------------------------------------------------------------------
00479 //
00480 SiStripFedCabling::SiStripFedCabling() 
00481   : feds_(),
00482     registry_(),
00483     connections_(),
00484     detected_(),
00485     undetected_()
00486 {
00487   LogTrace(mlCabling_) 
00488     << "[SiStripFedCabling::" << __func__ << "]"
00489     << " Constructing object...";
00490 }
00491 
00492 // -----------------------------------------------------------------------------
00493 //
00494 SiStripFedCabling::~SiStripFedCabling() {
00495   LogTrace(mlCabling_)
00496     << "[SiStripFedCabling::" << __func__ << "]"
00497     << " Destructing object...";
00498 }
00499 
00500 // -----------------------------------------------------------------------------
00501 //
00502 void SiStripFedCabling::buildFedCabling( const std::vector<FedChannelConnection>& input ) {
00503   
00504   // Check input
00505   if ( input.empty() ) {
00506     edm::LogError(mlCabling_)
00507       << "[SiStripFedCabling::" << __func__ << "]"
00508       << " Input vector of FedChannelConnections is of zero size!"
00509       << " Unable to populate FED cabling object!"; 
00510     return;
00511   }
00512   
00513   std::stringstream ss;
00514   ss << "[SiStripFedCabling::" << __func__ << "]"
00515      << " Building FED cabling from " 
00516      << input.size()
00517      << " connections...";
00518   LogTrace(mlCabling_) << ss.str();
00519   
00520   // Sort input vector by FED id and channel
00521   Conns temp(input);
00522   std::sort( temp.begin(), temp.end() );
00523   
00524   // Strip FED ids
00525   uint16_t min_id = static_cast<uint16_t>( FEDNumbering::getSiStripFEDIds().first );
00526   uint16_t max_id = static_cast<uint16_t>( FEDNumbering::getSiStripFEDIds().second );
00527   uint16_t nfeds  = max_id - min_id + 1;
00528   
00529   // Initialise containers
00530   connections_.clear();
00531   connections_.reserve( 96 * nfeds );
00532   registry_.clear();
00533   feds_.clear();
00534   registry_.resize( nfeds, ConnsRange::emptyPair() );
00535   
00536   // Populate container
00537   ConnsIter ii = temp.begin(); 
00538   ConnsIter jj = temp.end(); 
00539   for ( ; ii != jj; ++ii ) {
00540     
00541     uint16_t fed_id = ii->fedId();
00542     uint16_t fed_ch = ii->fedCh();
00543     uint16_t index  = fed_id - min_id;
00544     
00545     if ( fed_id < min_id || fed_id > max_id ) { continue; }
00546     if ( index >= registry_.size() ) { continue; }
00547     if ( !ii->isConnected() ) { continue; }
00548     
00549     FedsConstIter iter = find( feds_.begin(), feds_.end(), fed_id );
00550     if ( iter == feds_.end() ) { feds_.push_back( fed_id ); }
00551     
00552     if ( registry_[index] == ConnsRange::emptyPair() ) {
00553       ConnsPair conns_pair;
00554       conns_pair.first = std::distance( connections_.begin(), connections_.end() );
00555       connections_.insert( connections_.end(), 96, FedChannelConnection() ); 
00556       conns_pair.second = std::distance( connections_.begin(), connections_.end() );
00557       registry_[index] = conns_pair;
00558     } 
00559 
00560     ConnsRange conns = range( registry_[index] );
00561     ConnsConstIter iconn = conns.begin() + fed_ch;
00562     FedChannelConnection& conn = const_cast<FedChannelConnection&>(*iconn);
00563     conn = *ii;
00564 
00565   }
00566   
00567 }
00568 
00569 // -----------------------------------------------------------------------------
00570 //
00571 SiStripFedCabling::ConnsRange::ConnsRange( const Conns& c, ConnsPair p ) :
00572   vector_( c.begin(), c.end() ),
00573   range_( c.begin()+p.first, c.begin()+p.second )
00574 {
00575   if ( p.first > p.second ||
00576        p.first == sistrip::invalid32_ ||
00577        p.second == sistrip::invalid32_ ||
00578        p.first > c.size() || 
00579        p.second > c.size() ) {
00580     range_ = ConnsConstIterRange( c.end(), c.end() );
00581   }
00582 }
00583 
00584 // -----------------------------------------------------------------------------
00585 //
00586 SiStripFedCabling::ConnsRange::ConnsRange( const Conns& c ) :
00587   vector_( c.begin(), c.end() ),
00588   range_( c.end(), c.end() )
00589 {;}  
00590 
00591 // -----------------------------------------------------------------------------
00592 //
00593 void SiStripFedCabling::ConnsRange::print( std::stringstream& ss ) const {
00594   ss << "[SiStripFedCabling::ConnsRange::" << __func__ << "] Debug info:" << std::endl
00595      << " Vector  : " << std::endl
00596      << "  size   : " << vector_.size() << std::endl
00597      << "  begin  : " 
00598      << std::hex << std::setfill('0') << std::setw(8)
00599      << &*vector_.begin()
00600      << std::dec << std::endl
00601      << "  end    : " 
00602      << std::hex << std::setfill('0') << std::setw(8)
00603      << &*vector_.end()
00604      << std::dec << std::endl
00605      << " Range   : " << std::endl
00606      << "  size   : "  << range_.size() << std::endl
00607      << "  begin  : " 
00608      << std::hex << std::setfill('0') << std::setw(8)
00609      << &*range_.begin() 
00610      << std::dec
00611      << " (dist=" << std::distance( vector_.begin(), range_.begin() ) << ")" 
00612      << std::endl
00613      << "  end    : " 
00614      << std::hex << std::setfill('0') << std::setw(8)
00615      << &*range_.end() 
00616      << std::dec
00617      << " (dist=" << std::distance( vector_.begin(), range_.end() ) << ")" 
00618      << std::endl
00619      << " Offsets : " << std::endl
00620      << "  first  : " << connsPair().first << std::endl
00621      << "  second : " << connsPair().second << std::endl;
00622 }
00623 
00624 // -----------------------------------------------------------------------------
00625 //
00626 std::ostream& operator<<( std::ostream& os, const SiStripFedCabling::ConnsRange& input ) {
00627   std::stringstream ss;
00628   input.print(ss);
00629   os << ss.str();
00630   return os;
00631 }
00632 
00633 // -----------------------------------------------------------------------------
00634 // Returns connection info for FE devices connected to given FED 
00635 const std::vector<FedChannelConnection>& SiStripFedCabling::connections( uint16_t fed_id ) const {
00636   
00637   // HORRIBLE!
00638   
00639   static FedChannelConnection conn; 
00640   static std::vector<FedChannelConnection> conns1(96,conn); 
00641   static std::vector<FedChannelConnection> conns2(96,conn); 
00642   
00643   if ( fed_id < FEDNumbering::getSiStripFEDIds().first ||
00644        fed_id > FEDNumbering::getSiStripFEDIds().second ) { return conns1; }
00645 
00646   uint16_t index = fed_id - FEDNumbering::getSiStripFEDIds().first;
00647   if ( index < registry_.size() ) { 
00648     ConnsRange conns = range( registry_[ index ] );
00649     conns2.resize( conns.size() );
00650     std::copy( conns.begin(), conns.end(), conns2.begin() );
00651     return conns2; 
00652   } else { return conns1; }
00653   
00654 }
00655 
00656 // -----------------------------------------------------------------------------
00657 // Returns active FEDs
00658 const std::vector<uint16_t>& SiStripFedCabling::feds() const {
00659   return feds_;
00660 }
00661 
00662 // -----------------------------------------------------------------------------
00663 // Returns connection info for FE devices connected to given FED id and channel
00664 const FedChannelConnection& SiStripFedCabling::connection( uint16_t fed_id, 
00665                                                            uint16_t fed_ch ) const {
00666   
00667   // HORRIBLE!
00668   
00669   static FedChannelConnection conn; 
00670   
00671   if ( fed_id < FEDNumbering::getSiStripFEDIds().first ||
00672        fed_id > FEDNumbering::getSiStripFEDIds().second ) { return conn; }
00673   
00674   uint16_t index = fed_id - FEDNumbering::getSiStripFEDIds().first;
00675   if ( index < registry_.size() ) { 
00676     ConnsRange conns = range( registry_[ index ] );
00677     if ( conns.size() != 96 ) { return conn; }
00678     else if ( fed_ch > 95 ) { return conn; }
00679     else { return *( conns.begin() + fed_ch ); }
00680   } else { return conn; }
00681   
00682 }
00683 
00684 // -----------------------------------------------------------------------------
00685 // 
00686 void SiStripFedCabling::print( std::stringstream& ss ) const {
00687 
00688   uint16_t total = 0;
00689   uint16_t nfeds = 0;
00690   uint16_t cntr = 0;
00691 
00692   if ( feds_.empty() ) {
00693     ss << "[SiStripFedCabling::" << __func__ << "]"
00694        << " No FEDs found! Unable to  print cabling map!";
00695     return;
00696   } else {
00697     ss << "[SiStripFedCabling::" << __func__ << "]"
00698        << " Printing cabling map for " << feds_.size()
00699        << " FEDs with following ids: ";
00700   }
00701   
00702   std::vector<uint16_t>::const_iterator ii = feds_.begin(); 
00703   std::vector<uint16_t>::const_iterator jj = feds_.end(); 
00704   for ( ; ii != jj; ++ii ) { ss << *ii << " "; }
00705   ss << std::endl << std::endl;
00706   
00707   std::vector<uint16_t>::const_iterator ifed = feds_.begin(); 
00708   std::vector<uint16_t>::const_iterator jfed = feds_.end(); 
00709   for ( ; ifed != jfed; ++ifed ) {
00710     
00711     uint16_t index = *ifed - FEDNumbering::getSiStripFEDIds().first;
00712     if ( index < registry_.size() ) { 
00713       ConnsRange conns = range( registry_[ index ] );
00714       
00715       ss << " Printing cabling information for FED id " << *ifed 
00716          << " (found " << conns.size() 
00717          << " FedChannelConnection objects...)"
00718          << std::endl;
00719       
00720       uint16_t ichan = 0;
00721       uint16_t connected = 0;
00722       ConnsConstIter iconn = conns.begin();
00723       ConnsConstIter jconn = conns.end();
00724       for ( ; iconn != jconn; ++iconn ) { 
00725         if ( iconn->fedId() != sistrip::invalid_ ) { 
00726           connected++; 
00727           ss << *iconn << std::endl;
00728         } else {
00729           ss << "  (FedId/Ch " << *ifed << "/" << ichan 
00730              << ": unconnected channel...)" << std::endl;
00731           cntr++;
00732         }
00733         ichan++;
00734       } 
00735       
00736       ss << " Found " << connected 
00737          << " connected channels for FED id " << *ifed << std::endl
00738          << std::endl;
00739       if ( connected ) { nfeds++; total += connected; }
00740       
00741     }
00742     
00743   }
00744   
00745   float percent = (100.*cntr) / (96.*nfeds);
00746   percent = static_cast<uint16_t>( 10.*percent );
00747   percent /= 10.;
00748   ss << " Found " << total 
00749      << " APV pairs that are connected to a total of " 
00750      << nfeds << " FEDs" << std::endl
00751      << " " << detected_.size() 
00752      << " APV pairs have been detected, but are not connected" << std::endl
00753      << " " << undetected_.size()
00754      << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
00755      << " " << cntr
00756      << " FED channels out of a possible " << (96*nfeds)
00757      << " (" << nfeds << " FEDs) are unconnected (" 
00758      << percent << "%)" << std::endl
00759      << std::endl;
00760   
00761 }
00762 
00763 // -----------------------------------------------------------------------------
00764 // 
00765 void SiStripFedCabling::terse( std::stringstream& ss ) const {
00766   
00767 
00768   ss << "[SiStripFedCabling::" << __func__ << "]";
00769     
00770   if ( feds_.empty() ) {
00771     ss << " No FEDs found! Unable to print cabling map!";
00772     return;
00773   } 
00774   
00775   ss << " Printing cabling map for " << feds_.size()
00776      << " FEDs: " << std::endl << std::endl;
00777   
00778   std::vector<uint16_t>::const_iterator ifed = feds_.begin(); 
00779   std::vector<uint16_t>::const_iterator jfed = feds_.end(); 
00780   for ( ; ifed != jfed; ++ifed ) {
00781     
00782     uint16_t index = *ifed - FEDNumbering::getSiStripFEDIds().first;
00783     if ( index < registry_.size() ) { 
00784       ConnsRange conns = range( registry_[ index ] ); 
00785       
00786       ss << " Printing cabling information for FED id " << *ifed 
00787          << " (found " << conns.size() 
00788          << " FedChannelConnection objects...)"
00789          << std::endl;
00790       
00791       uint16_t connected = 0;
00792       ConnsConstIter iconn = conns.begin();
00793       ConnsConstIter jconn = conns.end();
00794       for ( ; iconn != jconn; ++iconn ) { 
00795         if ( iconn->fedId() != sistrip::invalid_ ) { 
00796           connected++; 
00797           iconn->terse(ss); 
00798           ss << std::endl;
00799         }
00800       } 
00801       
00802       ss << " Found " << connected 
00803          << " connected channels for FED id " << *ifed << std::endl
00804          << std::endl;
00805       
00806     }
00807     
00808   }
00809   
00810 }
00811 
00812 // -----------------------------------------------------------------------------
00813 // 
00814 void SiStripFedCabling::summary( std::stringstream& ss ) const {
00815 
00816   ss << "[SiStripFedCabling::" << __func__ << "]";
00817   
00818   if ( feds_.empty() ) {
00819     ss << " No FEDs found!";
00820     return;
00821   } 
00822   
00823   ss << " Found " << feds_.size() << " FEDs"
00824      << " with number of connected channels per front-end unit: " 
00825      << std::endl
00826      << " FedId FeUnit1 FeUnit2 FeUnit3 FeUnit4 FeUnit5 FeUnit6 FeUnit7 FeUnit8 Total" 
00827      << std::endl;
00828   
00829   uint16_t total = 0;
00830   uint16_t nfeds = 0;
00831   
00832   // iterate through fed ids
00833   std::vector<uint16_t>::const_iterator ii = feds_.begin(); 
00834   std::vector<uint16_t>::const_iterator jj = feds_.end(); 
00835   for ( ; ii != jj; ++ii ) { 
00836 
00837     // check number of connection objects
00838     uint16_t index = *ii - FEDNumbering::getSiStripFEDIds().first;
00839     if ( index < registry_.size() ) { 
00840       ConnsRange conns = range( registry_[ index ] ); 
00841 
00842       if ( conns.size() < 96 ) { 
00843         edm::LogError(mlCabling_) 
00844           << "[SiStripFedCabling::" << __func__ << "]"
00845           << " Unexpected size for FedChannelConnection vector! " 
00846           << conns.size();
00847         return;
00848       }
00849 
00850       // count connected channels at level of fe unit
00851       std::vector<uint16_t> connected;
00852       connected.resize(8,0);
00853       for ( uint16_t ichan = 0; ichan < 96; ++ichan ) {
00854         ConnsConstIter iconn = conns.begin() + ichan;
00855         if ( iconn->fedId() < sistrip::valid_ ) { 
00856           uint16_t unit = SiStripFedKey::feUnit(ichan);
00857           if ( unit > 8 ) { continue; }
00858           connected[unit-1]++; 
00859         } 
00860       }
00861       
00862       // increment counters
00863       uint16_t tot = 0 ;
00864       ss << " " << std::setw(5) << *ii;
00865       if ( !connected.empty() ) { nfeds++; }
00866       for ( uint16_t unit = 0; unit < 8; ++unit ) {
00867         ss << " " << std::setw(7) << connected[unit];
00868         if ( !connected.empty() ) { tot += connected[unit]; }
00869       }
00870       ss << " " << std::setw(5) << tot << std::endl;
00871       total += tot;
00872       
00873     } 
00874   
00875   }
00876   
00877   // print out
00878   float percent = (100.*total) / (96.*nfeds);
00879   percent = static_cast<uint16_t>( 10.*percent );
00880   percent /= 10.;
00881   ss << " Found: " << std::endl 
00882      << " " << nfeds << " out of " << feds_.size()
00883      << " FEDs with at least one connected channel " << std::endl 
00884      << " " << feds_.size() - nfeds << " out of " << feds_.size()
00885      << " FEDs with no connected channels." << std::endl 
00886      << " " << total << " connected channels in total" << std::endl
00887      << " " << detected_.size() 
00888      << " APV pairs have been detected, but are not connected" << std::endl
00889      << " " << undetected_.size() 
00890      << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
00891      << " " << percent
00892      << "% of FED channels are connected"  << std::endl;
00893   
00894 }
00895 
00896 // -----------------------------------------------------------------------------
00897 //
00898 std::ostream& operator<< ( std::ostream& os, const SiStripFedCabling& cabling ) {
00899   std::stringstream ss;
00900   cabling.print(ss);
00901   os << ss.str();
00902   return os;
00903 }
00904 
00905 
00906 // -----------------------------------------------------------------------------
00907 #else // SISTRIPCABLING_USING_NEW_INTERFACE ------------------------------------
00908 // -----------------------------------------------------------------------------
00909 
00910 
00911 // -----------------------------------------------------------------------------
00912 // TO BE DEPRECATED! TO BE DEPRECATED! TO BE DEPRECATED! 
00913 SiStripFedCabling::SiStripFedCabling( const std::vector<FedChannelConnection>& input ) 
00914   : feds_(),
00915     registry_(),
00916     connections_(),
00917     detected_(),
00918     undetected_()
00919 {
00920   LogTrace(mlCabling_)
00921     << "[SiStripFedCabling::" << __func__ << "]"
00922     << " Constructing object for vector of connections...";
00923   buildFedCabling( ConnsConstIterRange( input.begin(), 
00924                                         input.end() ) );
00925 }
00926 
00927 // -----------------------------------------------------------------------------
00928 // TO BE DEPRECATED! TO BE DEPRECATED! TO BE DEPRECATED! 
00929 void SiStripFedCabling::buildFedCabling( const std::vector<FedChannelConnection>& input ) {
00930   buildFedCabling( ConnsConstIterRange( input.begin(), 
00931                                         input.end() ) );
00932 }
00933 
00934 // -----------------------------------------------------------------------------
00935 // TO BE DEPRECATED! TO BE DEPRECATED! TO BE DEPRECATED! 
00936 const std::vector<FedChannelConnection>& SiStripFedCabling::connections( uint16_t fed_id ) const {
00937   static std::vector<FedChannelConnection> output;
00938   output.clear();
00939   ConnsConstIterRange input = fedConnections( fed_id );
00940   if ( !input.empty() ) {
00941     output.resize( input.size() );
00942     std::copy( input.begin(), input.end(), output.begin() );
00943   } else { output.resize( 96, FedChannelConnection() ); }
00944   return output;
00945 }
00946 
00947 // -----------------------------------------------------------------------------
00948 // TO BE DEPRECATED! TO BE DEPRECATED! TO BE DEPRECATED! 
00949 const FedChannelConnection& SiStripFedCabling::connection( uint16_t fed_id, 
00950                                                            uint16_t fed_ch ) const {
00951   static FedChannelConnection output;
00952   output = fedConnection( fed_id, fed_ch );
00953   return output;
00954 }
00955 
00956 // -----------------------------------------------------------------------------
00957 // TO BE DEPRECATED! TO BE DEPRECATED! TO BE DEPRECATED! 
00958 const std::vector<uint16_t>& SiStripFedCabling::feds() const {
00959   return feds_;
00960 }
00961 
00962 // -----------------------------------------------------------------------------
00963 // TO BE DEPRECATED! TO BE DEPRECATED! TO BE DEPRECATED! 
00964 const std::vector<FedChannelConnection>& SiStripFedCabling::detected() const { 
00965   return detected_;
00966 }
00967 
00968 // -----------------------------------------------------------------------------
00969 // TO BE DEPRECATED! TO BE DEPRECATED! TO BE DEPRECATED! 
00970 const std::vector<FedChannelConnection>& SiStripFedCabling::undetected() const{ 
00971   return undetected_;
00972 }
00973 
00974 // -----------------------------------------------------------------------------
00975 //
00976 SiStripFedCabling::SiStripFedCabling( ConnsConstIterRange input ) 
00977   : feds_(),
00978     registry_(),
00979     connections_(),
00980     detected_(),
00981     undetected_()
00982 {
00983   LogTrace(mlCabling_)
00984     << "[SiStripFedCabling::" << __func__ << "]"
00985     << " Constructing object from connection range...";
00986   buildFedCabling( input );
00987 }
00988 
00989 // -----------------------------------------------------------------------------
00990 //
00991 SiStripFedCabling::SiStripFedCabling( const SiStripFedCabling& input ) 
00992   : feds_( input.feds_ ),
00993     registry_( input.registry_ ),
00994     connections_( input.connections_ ),
00995     detected_( input.detected_ ),
00996     undetected_( input.undetected_ )
00997 {
00998   LogTrace(mlCabling_)
00999     << "[SiStripFedCabling::" << __func__ << "]"
01000     << " Copy constructing object...";
01001 }
01002 
01003 // -----------------------------------------------------------------------------
01004 //
01005 SiStripFedCabling::SiStripFedCabling() 
01006   : feds_(),
01007     registry_(),
01008     connections_(),
01009     detected_(),
01010     undetected_()
01011 {
01012   LogTrace(mlCabling_) 
01013     << "[SiStripFedCabling::" << __func__ << "]"
01014     << " Default constructing object...";
01015 }
01016 
01017 // -----------------------------------------------------------------------------
01018 //
01019 SiStripFedCabling::~SiStripFedCabling() {
01020   LogTrace(mlCabling_)
01021     << "[SiStripFedCabling::" << __func__ << "]"
01022     << " Destructing object...";
01023 }
01024 
01025 // -----------------------------------------------------------------------------
01026 //
01027 void SiStripFedCabling::buildFedCabling( ConnsConstIterRange input ) {
01028   
01029   // Check input
01030   if ( input.empty() ) {
01031     edm::LogError(mlCabling_)
01032       << "[SiStripFedCabling::" << __func__ << "]"
01033       << " Input vector of FedChannelConnections is of zero size!"
01034       << " Unable to populate FED cabling object!"; 
01035     return;
01036   }
01037   
01038   std::stringstream ss;
01039   ss << "[SiStripFedCabling::" << __func__ << "]"
01040      << " Building FED cabling from " 
01041      << input.size()
01042      << " connections...";
01043   LogTrace(mlCabling_) << ss.str();
01044   
01045   // Sort input vector by FED id and channel
01046   Conns temp( input.size() );
01047   std::copy( input.begin(), input.end(), temp.begin() );
01048   std::sort( temp.begin(), temp.end() );
01049   
01050   // Strip FED ids
01051   uint16_t min_id = static_cast<uint16_t>( FEDNumbering::MINSiStripFEDID );
01052   uint16_t max_id = static_cast<uint16_t>( FEDNumbering::MAXSiStripFEDID );
01053   uint16_t nfeds  = max_id - min_id + 1;
01054   
01055   // Initialise containers
01056   connections_.clear();
01057   connections_.reserve( 96 * nfeds );
01058   registry_.clear();
01059   feds_.clear();
01060   registry_.resize( nfeds, ConnsRange::emptyPair() );
01061   
01062   // Populate container
01063   ConnsIter ii = temp.begin(); 
01064   ConnsIter jj = temp.end(); 
01065   for ( ; ii != jj; ++ii ) {
01066     
01067     uint16_t fed_id = ii->fedId();
01068     uint16_t fed_ch = ii->fedCh();
01069     uint16_t index  = fed_id - min_id;
01070     
01071     if ( fed_id < min_id || fed_id > max_id ) { continue; }
01072     if ( index >= registry_.size() ) { continue; }
01073     if ( !ii->isConnected() ) { continue; }
01074     
01075     FedsConstIter iter = find( feds_.begin(), feds_.end(), fed_id );
01076     if ( iter == feds_.end() ) { feds_.push_back( fed_id ); }
01077     
01078     if ( registry_[index] == ConnsRange::emptyPair() ) {
01079       ConnsPair conns_pair;
01080       conns_pair.first = std::distance( connections_.begin(), connections_.end() );
01081       connections_.insert( connections_.end(), 96, FedChannelConnection() ); 
01082       conns_pair.second = std::distance( connections_.begin(), connections_.end() );
01083       registry_[index] = conns_pair;
01084     } 
01085 
01086     ConnsRange conns = range( registry_[index] );
01087     ConnsConstIter iconn = conns.begin() + fed_ch;
01088     FedChannelConnection& conn = const_cast<FedChannelConnection&>(*iconn);
01089     conn = *ii;
01090 
01091   }
01092   
01093 }
01094 
01095 // -----------------------------------------------------------------------------
01096 //
01097 SiStripFedCabling::ConnsRange::ConnsRange( const Conns& c, ConnsPair p ) :
01098   vector_( c.begin(), c.end() ),
01099   range_( c.begin()+p.first, c.begin()+p.second )
01100 {
01101   if ( p.first > p.second ||
01102        p.first == sistrip::invalid32_ ||
01103        p.second == sistrip::invalid32_ ||
01104        p.first > c.size() || 
01105        p.second > c.size() ) {
01106     range_ = ConnsConstIterRange( c.end(), c.end() );
01107   }
01108 }
01109 
01110 // -----------------------------------------------------------------------------
01111 //
01112 SiStripFedCabling::ConnsRange::ConnsRange( const Conns& c ) :
01113   vector_( c.begin(), c.end() ),
01114   range_( c.end(), c.end() )
01115 {;}  
01116 
01117 // -----------------------------------------------------------------------------
01118 //
01119 void SiStripFedCabling::ConnsRange::print( std::stringstream& ss ) const {
01120   ss << "[SiStripFedCabling::ConnsRange::" << __func__ << "] Debug info:" << std::endl
01121      << " Vector  : " << std::endl
01122      << "  size   : " << vector_.size() << std::endl
01123      << "  begin  : " 
01124      << std::hex << std::setfill('0') << std::setw(8)
01125      << &*vector_.begin()
01126      << std::dec << std::endl
01127      << "  end    : " 
01128      << std::hex << std::setfill('0') << std::setw(8)
01129      << &*vector_.end()
01130      << std::dec << std::endl
01131      << " Range   : " << std::endl
01132      << "  size   : "  << range_.size() << std::endl
01133      << "  begin  : " 
01134      << std::hex << std::setfill('0') << std::setw(8)
01135      << &*range_.begin() 
01136      << std::dec
01137      << " (dist=" << std::distance( vector_.begin(), range_.begin() ) << ")" 
01138      << std::endl
01139      << "  end    : " 
01140      << std::hex << std::setfill('0') << std::setw(8)
01141      << &*range_.end() 
01142      << std::dec
01143      << " (dist=" << std::distance( vector_.begin(), range_.end() ) << ")" 
01144      << std::endl
01145      << " Offsets : " << std::endl
01146      << "  first  : " << connsPair().first << std::endl
01147      << "  second : " << connsPair().second << std::endl;
01148 }
01149 
01150 // -----------------------------------------------------------------------------
01151 //
01152 std::ostream& operator<<( std::ostream& os, const SiStripFedCabling::ConnsRange& input ) {
01153   std::stringstream ss;
01154   input.print(ss);
01155   os << ss.str();
01156   return os;
01157 }
01158 
01159 // -----------------------------------------------------------------------------
01160 // Returns connection info for FE devices connected to given FED 
01161 SiStripFedCabling::ConnsConstIterRange SiStripFedCabling::fedConnections( uint16_t fed_id ) const {
01162   uint16_t index = fed_id - FEDNumbering::MINSiStripFEDID;
01163   if ( index < registry_.size() ) { 
01164     return range( registry_[ index ] ).range();
01165   } else { return range( registry_[ index ] ).invalid(); }
01166 }
01167 
01168 // -----------------------------------------------------------------------------
01169 // Returns connection info for FE devices connected to given FED id and channel
01170 FedChannelConnection SiStripFedCabling::fedConnection( uint16_t fed_id, 
01171                                                        uint16_t fed_ch ) const {
01172   ConnsConstIterRange conns = fedConnections( fed_id );
01173   if ( !conns.empty() && conns.size() == 96 && fed_ch < 96 ) {
01174     return *( conns.begin() + fed_ch ); 
01175   } else { return FedChannelConnection(); }
01176 }
01177 
01178 // -----------------------------------------------------------------------------
01179 // 
01180 void SiStripFedCabling::printDebug( std::stringstream& ss ) const {
01181 
01182   uint16_t total = 0;
01183   uint16_t nfeds = 0;
01184   uint16_t cntr = 0;
01185 
01186   if ( feds_.empty() ) {
01187     ss << "[SiStripFedCabling::" << __func__ << "]"
01188        << " No FEDs found! Unable to  print cabling map!";
01189     return;
01190   } else {
01191     ss << "[SiStripFedCabling::" << __func__ << "]"
01192        << " Printing cabling map for " << feds_.size()
01193        << " FEDs with following ids: ";
01194   }
01195   
01196   std::vector<uint16_t>::const_iterator ii = feds_.begin(); 
01197   std::vector<uint16_t>::const_iterator jj = feds_.end(); 
01198   for ( ; ii != jj; ++ii ) { ss << *ii << " "; }
01199   ss << std::endl << std::endl;
01200   
01201   std::vector<uint16_t>::const_iterator ifed = feds_.begin(); 
01202   std::vector<uint16_t>::const_iterator jfed = feds_.end(); 
01203   for ( ; ifed != jfed; ++ifed ) {
01204     
01205     uint16_t index = *ifed - FEDNumbering::MINSiStripFEDID;
01206     if ( index < registry_.size() ) { 
01207       ConnsRange conns = range( registry_[ index ] );
01208       
01209       ss << " Printing cabling information for FED id " << *ifed 
01210          << " (found " << conns.size() 
01211          << " FedChannelConnection objects...)"
01212          << std::endl;
01213       
01214       uint16_t ichan = 0;
01215       uint16_t connected = 0;
01216       ConnsConstIter iconn = conns.begin();
01217       ConnsConstIter jconn = conns.end();
01218       for ( ; iconn != jconn; ++iconn ) { 
01219         if ( iconn->fedId() != sistrip::invalid_ ) { 
01220           connected++; 
01221           ss << *iconn << std::endl;
01222         } else {
01223           ss << "  (FedId/Ch " << *ifed << "/" << ichan 
01224              << ": unconnected channel...)" << std::endl;
01225           cntr++;
01226         }
01227         ichan++;
01228       } 
01229       
01230       ss << " Found " << connected 
01231          << " connected channels for FED id " << *ifed << std::endl
01232          << std::endl;
01233       if ( connected ) { nfeds++; total += connected; }
01234       
01235     }
01236     
01237   }
01238   
01239   float percent = (100.*cntr) / (96.*nfeds);
01240   percent = static_cast<uint16_t>( 10.*percent );
01241   percent /= 10.;
01242   ss << " Found " << total 
01243      << " APV pairs that are connected to a total of " 
01244      << nfeds << " FEDs" << std::endl
01245      << " " << detected_.size() 
01246      << " APV pairs have been detected, but are not connected" << std::endl
01247      << " " << undetected_.size()
01248      << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
01249      << " " << cntr
01250      << " FED channels out of a possible " << (96*nfeds)
01251      << " (" << nfeds << " FEDs) are unconnected (" 
01252      << percent << "%)" << std::endl
01253      << std::endl;
01254   
01255 }
01256 
01257 // -----------------------------------------------------------------------------
01258 // 
01259 void SiStripFedCabling::terse( std::stringstream& ss ) const {
01260   
01261 
01262   ss << "[SiStripFedCabling::" << __func__ << "]";
01263     
01264   if ( feds_.empty() ) {
01265     ss << " No FEDs found! Unable to print cabling map!";
01266     return;
01267   } 
01268   
01269   ss << " Printing cabling map for " << feds_.size()
01270      << " FEDs: " << std::endl << std::endl;
01271   
01272   std::vector<uint16_t>::const_iterator ifed = feds_.begin(); 
01273   std::vector<uint16_t>::const_iterator jfed = feds_.end(); 
01274   for ( ; ifed != jfed; ++ifed ) {
01275     
01276     uint16_t index = *ifed - FEDNumbering::MINSiStripFEDID;
01277     if ( index < registry_.size() ) { 
01278       ConnsRange conns = range( registry_[ index ] ); 
01279       
01280       ss << " Printing cabling information for FED id " << *ifed 
01281          << " (found " << conns.size() 
01282          << " FedChannelConnection objects...)"
01283          << std::endl;
01284       
01285       uint16_t connected = 0;
01286       ConnsConstIter iconn = conns.begin();
01287       ConnsConstIter jconn = conns.end();
01288       for ( ; iconn != jconn; ++iconn ) { 
01289         if ( iconn->fedId() != sistrip::invalid_ ) { 
01290           connected++; 
01291           iconn->terse(ss); 
01292           ss << std::endl;
01293         }
01294       } 
01295       
01296       ss << " Found " << connected 
01297          << " connected channels for FED id " << *ifed << std::endl
01298          << std::endl;
01299       
01300     }
01301     
01302   }
01303   
01304 }
01305 
01306 // -----------------------------------------------------------------------------
01307 //
01308 void SiStripFedCabling::printSummary( std::stringstream& ss ) const {
01309 
01310   ss << "[SiStripFedCabling::" << __func__ << "]";
01311   
01312   if ( feds_.empty() ) {
01313     ss << " No FEDs found!";
01314     return;
01315   } 
01316   
01317   ss << " Found " << feds_.size() << " FEDs"
01318      << " with number of connected channels per front-end unit: " 
01319      << std::endl
01320      << " FedId FeUnit1 FeUnit2 FeUnit3 FeUnit4 FeUnit5 FeUnit6 FeUnit7 FeUnit8 Total" 
01321      << std::endl;
01322   
01323   uint16_t total = 0;
01324   uint16_t nfeds = 0;
01325   
01326   // iterate through fed ids
01327   std::vector<uint16_t>::const_iterator ii = feds_.begin(); 
01328   std::vector<uint16_t>::const_iterator jj = feds_.end(); 
01329   for ( ; ii != jj; ++ii ) { 
01330 
01331     // check number of connection objects
01332     uint16_t index = *ii - FEDNumbering::MINSiStripFEDID;
01333     if ( index < registry_.size() ) { 
01334       ConnsRange conns = range( registry_[ index ] ); 
01335 
01336       if ( conns.size() < 96 ) { 
01337         edm::LogError(mlCabling_) 
01338           << "[SiStripFedCabling::" << __func__ << "]"
01339           << " Unexpected size for FedChannelConnection vector! " 
01340           << conns.size();
01341         return;
01342       }
01343 
01344       // count connected channels at level of fe unit
01345       std::vector<uint16_t> connected;
01346       connected.resize(8,0);
01347       for ( uint16_t ichan = 0; ichan < 96; ++ichan ) {
01348         ConnsConstIter iconn = conns.begin() + ichan;
01349         if ( iconn->fedId() < sistrip::valid_ ) { 
01350           uint16_t unit = SiStripFedKey::feUnit(ichan);
01351           if ( unit > 8 ) { continue; }
01352           connected[unit-1]++; 
01353         } 
01354       }
01355       
01356       // increment counters
01357       uint16_t tot = 0 ;
01358       ss << " " << std::setw(5) << *ii;
01359       if ( !connected.empty() ) { nfeds++; }
01360       for ( uint16_t unit = 0; unit < 8; ++unit ) {
01361         ss << " " << std::setw(7) << connected[unit];
01362         if ( !connected.empty() ) { tot += connected[unit]; }
01363       }
01364       ss << " " << std::setw(5) << tot << std::endl;
01365       total += tot;
01366       
01367     } 
01368   
01369   }
01370   
01371   // print out
01372   float percent = (100.*total) / (96.*nfeds);
01373   percent = static_cast<uint16_t>( 10.*percent );
01374   percent /= 10.;
01375   ss << " Found: " << std::endl 
01376      << " " << nfeds << " out of " << feds_.size()
01377      << " FEDs with at least one connected channel " << std::endl 
01378      << " " << feds_.size() - nfeds << " out of " << feds_.size()
01379      << " FEDs with no connected channels." << std::endl 
01380      << " " << total << " connected channels in total" << std::endl
01381      << " " << detected_.size() 
01382      << " APV pairs have been detected, but are not connected" << std::endl
01383      << " " << undetected_.size() 
01384      << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
01385      << " " << percent
01386      << "% of FED channels are connected"  << std::endl;
01387   
01388 }
01389 
01390 // -----------------------------------------------------------------------------
01391 //
01392 std::ostream& operator<< ( std::ostream& os, const SiStripFedCabling& cabling ) {
01393   std::stringstream ss;
01394   cabling.print(ss);
01395   os << ss.str();
01396   return os;
01397 }
01398 
01399 
01400 // -----------------------------------------------------------------------------
01401 #endif // SISTRIPCABLING_USING_NEW_INTERFACE -----------------------------------
01402 #endif // SISTRIPCABLING_USING_NEW_STRUCTURE -----------------------------------
01403 // -----------------------------------------------------------------------------