Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:02:41

0001 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0002 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
0003 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include <iostream>
0006 #include <iomanip>
0007 
0008 using namespace sistrip;
0009 
0010 // -----------------------------------------------------------------------------
0011 //
0012 SiStripFedCabling::SiStripFedCabling(ConnsConstIterRange input)
0013     : feds_(), registry_(), connections_(), detected_(), undetected_() {
0014   LogTrace(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
0015                        << " Constructing object from connection range...";
0016   buildFedCabling(input);
0017 }
0018 
0019 // -----------------------------------------------------------------------------
0020 //
0021 SiStripFedCabling::SiStripFedCabling(const SiStripFedCabling& input)
0022     : feds_(input.feds_),
0023       registry_(input.registry_),
0024       connections_(input.connections_),
0025       detected_(input.detected_),
0026       undetected_(input.undetected_) {
0027   LogTrace(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
0028                        << " Copy constructing object...";
0029 }
0030 
0031 // -----------------------------------------------------------------------------
0032 //
0033 SiStripFedCabling::SiStripFedCabling() : feds_(), registry_(), connections_(), detected_(), undetected_() {
0034   LogTrace(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
0035                        << " Default constructing object...";
0036 }
0037 
0038 // -----------------------------------------------------------------------------
0039 //
0040 SiStripFedCabling::~SiStripFedCabling() {
0041   LogTrace(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
0042                        << " Destructing object...";
0043 }
0044 
0045 // -----------------------------------------------------------------------------
0046 //
0047 void SiStripFedCabling::buildFedCabling(ConnsConstIterRange input) {
0048   // Check input
0049   if (input.empty()) {
0050     edm::LogError(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
0051                               << " Input vector of FedChannelConnections is of zero size!"
0052                               << " Unable to populate FED cabling object!";
0053     return;
0054   }
0055 
0056   std::stringstream ss;
0057   ss << "[SiStripFedCabling::" << __func__ << "]"
0058      << " Building FED cabling from " << input.size() << " connections...";
0059   LogTrace(mlCabling_) << ss.str();
0060 
0061   // Sort input vector by FED id and channel
0062   Conns temp(input.size());
0063   std::copy(input.begin(), input.end(), temp.begin());
0064   std::sort(temp.begin(), temp.end());
0065 
0066   // Strip FED ids
0067   uint16_t min_id = static_cast<uint16_t>(FEDNumbering::MINSiStripFEDID);
0068   uint16_t max_id = static_cast<uint16_t>(FEDNumbering::MAXSiStripFEDID);
0069   uint16_t nfeds = max_id - min_id + 1;
0070 
0071   // Initialise containers
0072   connections_.clear();
0073   connections_.reserve(96 * nfeds);
0074   registry_.clear();
0075   feds_.clear();
0076   registry_.resize(nfeds, ConnsRange::emptyPair());
0077 
0078   // Populate container
0079   ConnsIter ii = temp.begin();
0080   ConnsIter jj = temp.end();
0081   for (; ii != jj; ++ii) {
0082     uint16_t fed_id = ii->fedId();
0083     uint16_t fed_ch = ii->fedCh();
0084     uint16_t index = fed_id - min_id;
0085 
0086     if (fed_id < min_id || fed_id > max_id) {
0087       continue;
0088     }
0089     if (index >= registry_.size()) {
0090       continue;
0091     }
0092     if (!ii->isConnected()) {
0093       continue;
0094     }
0095 
0096     FedsConstIter iter = find(feds_.begin(), feds_.end(), fed_id);
0097     if (iter == feds_.end()) {
0098       feds_.push_back(fed_id);
0099     }
0100 
0101     if (registry_[index] == ConnsRange::emptyPair()) {
0102       ConnsPair conns_pair;
0103       conns_pair.first = std::distance(connections_.begin(), connections_.end());
0104       connections_.insert(connections_.end(), 96, FedChannelConnection());
0105       conns_pair.second = std::distance(connections_.begin(), connections_.end());
0106       registry_[index] = conns_pair;
0107     }
0108 
0109     ConnsRange conns = range(registry_[index]);
0110     ConnsConstIter iconn = conns.begin() + fed_ch;
0111     FedChannelConnection& conn = const_cast<FedChannelConnection&>(*iconn);
0112     conn = *ii;
0113   }
0114 }
0115 
0116 // -----------------------------------------------------------------------------
0117 //
0118 SiStripFedCabling::ConnsRange::ConnsRange(const Conns& c, ConnsPair p)
0119     : vector_(c.begin(), c.end()), range_(c.begin() + p.first, c.begin() + p.second) {
0120   if (p.first > p.second || p.first == sistrip::invalid32_ || p.second == sistrip::invalid32_ || p.first > c.size() ||
0121       p.second > c.size()) {
0122     range_ = ConnsConstIterRange(c.end(), c.end());
0123   }
0124 }
0125 
0126 // -----------------------------------------------------------------------------
0127 //
0128 SiStripFedCabling::ConnsRange::ConnsRange(const Conns& c) : vector_(c.begin(), c.end()), range_(c.end(), c.end()) { ; }
0129 
0130 // -----------------------------------------------------------------------------
0131 //
0132 void SiStripFedCabling::ConnsRange::print(std::stringstream& ss) const {
0133   ss << "[SiStripFedCabling::ConnsRange::" << __func__ << "] Debug info:" << std::endl
0134      << " Vector  : " << std::endl
0135      << "  size   : " << vector_.size() << std::endl
0136      << "  begin  : " << std::hex << std::setfill('0') << std::setw(8) << &*vector_.begin() << std::dec << std::endl
0137      << "  end    : " << std::hex << std::setfill('0') << std::setw(8) << &*vector_.end() << std::dec << std::endl
0138      << " Range   : " << std::endl
0139      << "  size   : " << range_.size() << std::endl
0140      << "  begin  : " << std::hex << std::setfill('0') << std::setw(8) << &*range_.begin() << std::dec
0141      << " (dist=" << std::distance(vector_.begin(), range_.begin()) << ")" << std::endl
0142      << "  end    : " << std::hex << std::setfill('0') << std::setw(8) << &*range_.end() << std::dec
0143      << " (dist=" << std::distance(vector_.begin(), range_.end()) << ")" << std::endl
0144      << " Offsets : " << std::endl
0145      << "  first  : " << connsPair().first << std::endl
0146      << "  second : " << connsPair().second << std::endl;
0147 }
0148 
0149 // -----------------------------------------------------------------------------
0150 //
0151 std::ostream& operator<<(std::ostream& os, const SiStripFedCabling::ConnsRange& input) {
0152   std::stringstream ss;
0153   input.print(ss);
0154   os << ss.str();
0155   return os;
0156 }
0157 
0158 // -----------------------------------------------------------------------------
0159 // Returns connection info for FE devices connected to given FED
0160 SiStripFedCabling::ConnsConstIterRange SiStripFedCabling::fedConnections(uint16_t fed_id) const {
0161   uint16_t index = fed_id - FEDNumbering::MINSiStripFEDID;
0162   if (index < registry_.size()) {
0163     return range(registry_[index]).range();
0164   } else {
0165     return range(registry_[index]).invalid();
0166   }
0167 }
0168 
0169 // -----------------------------------------------------------------------------
0170 // Returns connection info for FE devices connected to given FED id and channel
0171 FedChannelConnection SiStripFedCabling::fedConnection(uint16_t fed_id, uint16_t fed_ch) const {
0172   ConnsConstIterRange conns = fedConnections(fed_id);
0173   if (!conns.empty() && conns.size() == 96 && fed_ch < 96) {
0174     return *(conns.begin() + fed_ch);
0175   } else {
0176     return FedChannelConnection();
0177   }
0178 }
0179 
0180 // -----------------------------------------------------------------------------
0181 //
0182 void SiStripFedCabling::printDebug(std::stringstream& ss, const TrackerTopology* /*trackerTopo*/) const {
0183   uint16_t total = 0;
0184   uint16_t nfeds = 0;
0185   uint16_t cntr = 0;
0186 
0187   if (feds_.empty()) {
0188     ss << "[SiStripFedCabling::" << __func__ << "]"
0189        << " No FEDs found! Unable to  print cabling map!";
0190     return;
0191   } else {
0192     ss << "[SiStripFedCabling::" << __func__ << "]"
0193        << " Printing cabling map for " << feds_.size() << " FEDs with following ids: ";
0194   }
0195 
0196   std::vector<uint16_t>::const_iterator ii = feds_.begin();
0197   std::vector<uint16_t>::const_iterator jj = feds_.end();
0198   for (; ii != jj; ++ii) {
0199     ss << *ii << " ";
0200   }
0201   ss << std::endl << std::endl;
0202 
0203   std::vector<uint16_t>::const_iterator ifed = feds_.begin();
0204   std::vector<uint16_t>::const_iterator jfed = feds_.end();
0205   for (; ifed != jfed; ++ifed) {
0206     uint16_t index = *ifed - FEDNumbering::MINSiStripFEDID;
0207     if (index < registry_.size()) {
0208       ConnsRange conns = range(registry_[index]);
0209 
0210       ss << " Printing cabling information for FED id " << *ifed << " (found " << conns.size()
0211          << " FedChannelConnection objects...)" << std::endl;
0212 
0213       uint16_t ichan = 0;
0214       uint16_t connected = 0;
0215       ConnsConstIter iconn = conns.begin();
0216       ConnsConstIter jconn = conns.end();
0217       for (; iconn != jconn; ++iconn) {
0218         if (iconn->fedId() != sistrip::invalid_) {
0219           connected++;
0220           ss << *iconn << std::endl;
0221         } else {
0222           ss << "  (FedId/Ch " << *ifed << "/" << ichan << ": unconnected channel...)" << std::endl;
0223           cntr++;
0224         }
0225         ichan++;
0226       }
0227 
0228       ss << " Found " << connected << " connected channels for FED id " << *ifed << std::endl << std::endl;
0229       if (connected) {
0230         nfeds++;
0231         total += connected;
0232       }
0233     }
0234   }
0235 
0236   float percent = (100. * cntr) / (96. * nfeds);
0237   percent = static_cast<uint16_t>(10. * percent);
0238   percent /= 10.;
0239   ss << " Found " << total << " APV pairs that are connected to a total of " << nfeds << " FEDs" << std::endl
0240      << " " << detected_.size() << " APV pairs have been detected, but are not connected" << std::endl
0241      << " " << undetected_.size() << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
0242      << " " << cntr << " FED channels out of a possible " << (96 * nfeds) << " (" << nfeds << " FEDs) are unconnected ("
0243      << percent << "%)" << std::endl
0244      << std::endl;
0245 }
0246 
0247 // -----------------------------------------------------------------------------
0248 //
0249 void SiStripFedCabling::terse(std::stringstream& ss) const {
0250   ss << "[SiStripFedCabling::" << __func__ << "]";
0251 
0252   if (feds_.empty()) {
0253     ss << " No FEDs found! Unable to print cabling map!";
0254     return;
0255   }
0256 
0257   ss << " Printing cabling map for " << feds_.size() << " FEDs: " << std::endl << std::endl;
0258 
0259   std::vector<uint16_t>::const_iterator ifed = feds_.begin();
0260   std::vector<uint16_t>::const_iterator jfed = feds_.end();
0261   for (; ifed != jfed; ++ifed) {
0262     uint16_t index = *ifed - FEDNumbering::MINSiStripFEDID;
0263     if (index < registry_.size()) {
0264       ConnsRange conns = range(registry_[index]);
0265 
0266       ss << " Printing cabling information for FED id " << *ifed << " (found " << conns.size()
0267          << " FedChannelConnection objects...)" << std::endl;
0268 
0269       uint16_t connected = 0;
0270       ConnsConstIter iconn = conns.begin();
0271       ConnsConstIter jconn = conns.end();
0272       for (; iconn != jconn; ++iconn) {
0273         if (iconn->fedId() != sistrip::invalid_) {
0274           connected++;
0275           iconn->terse(ss);
0276           ss << std::endl;
0277         }
0278       }
0279 
0280       ss << " Found " << connected << " connected channels for FED id " << *ifed << std::endl << std::endl;
0281     }
0282   }
0283 }
0284 
0285 // -----------------------------------------------------------------------------
0286 //
0287 void SiStripFedCabling::printSummary(std::stringstream& ss, const TrackerTopology* /*trackerTopo*/) const {
0288   ss << "[SiStripFedCabling::" << __func__ << "]";
0289 
0290   if (feds_.empty()) {
0291     ss << " No FEDs found!";
0292     return;
0293   }
0294 
0295   ss << " Found " << feds_.size() << " FEDs"
0296      << " with number of connected channels per front-end unit: " << std::endl
0297      << " FedId FeUnit1 FeUnit2 FeUnit3 FeUnit4 FeUnit5 FeUnit6 FeUnit7 FeUnit8 Total" << std::endl;
0298 
0299   uint16_t total = 0;
0300   uint16_t nfeds = 0;
0301 
0302   // iterate through fed ids
0303   std::vector<uint16_t>::const_iterator ii = feds_.begin();
0304   std::vector<uint16_t>::const_iterator jj = feds_.end();
0305   for (; ii != jj; ++ii) {
0306     // check number of connection objects
0307     uint16_t index = *ii - FEDNumbering::MINSiStripFEDID;
0308     if (index < registry_.size()) {
0309       ConnsRange conns = range(registry_[index]);
0310 
0311       if (conns.size() < 96) {
0312         edm::LogError(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
0313                                   << " Unexpected size for FedChannelConnection vector! " << conns.size();
0314         return;
0315       }
0316 
0317       // count connected channels at level of fe unit
0318       std::vector<uint16_t> connected;
0319       connected.resize(8, 0);
0320       for (uint16_t ichan = 0; ichan < 96; ++ichan) {
0321         ConnsConstIter iconn = conns.begin() + ichan;
0322         if (iconn->fedId() < sistrip::valid_) {
0323           uint16_t unit = SiStripFedKey::feUnit(ichan);
0324           if (unit > 8) {
0325             continue;
0326           }
0327           connected[unit - 1]++;
0328         }
0329       }
0330 
0331       // increment counters
0332       uint16_t tot = 0;
0333       ss << " " << std::setw(5) << *ii;
0334       if (!connected.empty()) {
0335         nfeds++;
0336       }
0337       for (uint16_t unit = 0; unit < 8; ++unit) {
0338         ss << " " << std::setw(7) << connected[unit];
0339         if (!connected.empty()) {
0340           tot += connected[unit];
0341         }
0342       }
0343       ss << " " << std::setw(5) << tot << std::endl;
0344       total += tot;
0345     }
0346   }
0347 
0348   // print out
0349   float percent = (100. * total) / (96. * nfeds);
0350   percent = static_cast<uint16_t>(10. * percent);
0351   percent /= 10.;
0352   ss << " Found: " << std::endl
0353      << " " << nfeds << " out of " << feds_.size() << " FEDs with at least one connected channel " << std::endl
0354      << " " << feds_.size() - nfeds << " out of " << feds_.size() << " FEDs with no connected channels." << std::endl
0355      << " " << total << " connected channels in total" << std::endl
0356      << " " << detected_.size() << " APV pairs have been detected, but are not connected" << std::endl
0357      << " " << undetected_.size() << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
0358      << " " << percent << "% of FED channels are connected" << std::endl;
0359 }