CMS 3D CMS Logo

SiStripFedCabling.cc
Go to the documentation of this file.
5 #include <iostream>
6 #include <iomanip>
7 
8 using namespace sistrip;
9 
10 // -----------------------------------------------------------------------------
11 //
13  : feds_(), registry_(), connections_(), detected_(), undetected_() {
14  LogTrace(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
15  << " Constructing object from connection range...";
17 }
18 
19 // -----------------------------------------------------------------------------
20 //
22  : feds_(input.feds_),
23  registry_(input.registry_),
24  connections_(input.connections_),
25  detected_(input.detected_),
26  undetected_(input.undetected_) {
27  LogTrace(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
28  << " Copy constructing object...";
29 }
30 
31 // -----------------------------------------------------------------------------
32 //
33 SiStripFedCabling::SiStripFedCabling() : feds_(), registry_(), connections_(), detected_(), undetected_() {
34  LogTrace(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
35  << " Default constructing object...";
36 }
37 
38 // -----------------------------------------------------------------------------
39 //
41  LogTrace(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
42  << " Destructing object...";
43 }
44 
45 // -----------------------------------------------------------------------------
46 //
48  // Check input
49  if (input.empty()) {
50  edm::LogError(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
51  << " Input vector of FedChannelConnections is of zero size!"
52  << " Unable to populate FED cabling object!";
53  return;
54  }
55 
56  std::stringstream ss;
57  ss << "[SiStripFedCabling::" << __func__ << "]"
58  << " Building FED cabling from " << input.size() << " connections...";
59  LogTrace(mlCabling_) << ss.str();
60 
61  // Sort input vector by FED id and channel
62  Conns temp(input.size());
63  std::copy(input.begin(), input.end(), temp.begin());
64  std::sort(temp.begin(), temp.end());
65 
66  // Strip FED ids
67  uint16_t min_id = static_cast<uint16_t>(FEDNumbering::MINSiStripFEDID);
68  uint16_t max_id = static_cast<uint16_t>(FEDNumbering::MAXSiStripFEDID);
69  uint16_t nfeds = max_id - min_id + 1;
70 
71  // Initialise containers
72  connections_.clear();
73  connections_.reserve(96 * nfeds);
74  registry_.clear();
75  feds_.clear();
76  registry_.resize(nfeds, ConnsRange::emptyPair());
77 
78  // Populate container
79  ConnsIter ii = temp.begin();
80  ConnsIter jj = temp.end();
81  for (; ii != jj; ++ii) {
82  uint16_t fed_id = ii->fedId();
83  uint16_t fed_ch = ii->fedCh();
84  uint16_t index = fed_id - min_id;
85 
86  if (fed_id < min_id || fed_id > max_id) {
87  continue;
88  }
89  if (index >= registry_.size()) {
90  continue;
91  }
92  if (!ii->isConnected()) {
93  continue;
94  }
95 
96  FedsConstIter iter = find(feds_.begin(), feds_.end(), fed_id);
97  if (iter == feds_.end()) {
98  feds_.push_back(fed_id);
99  }
100 
102  ConnsPair conns_pair;
103  conns_pair.first = std::distance(connections_.begin(), connections_.end());
104  connections_.insert(connections_.end(), 96, FedChannelConnection());
105  conns_pair.second = std::distance(connections_.begin(), connections_.end());
106  registry_[index] = conns_pair;
107  }
108 
109  ConnsRange conns = range(registry_[index]);
110  ConnsConstIter iconn = conns.begin() + fed_ch;
111  FedChannelConnection& conn = const_cast<FedChannelConnection&>(*iconn);
112  conn = *ii;
113  }
114 }
115 
116 // -----------------------------------------------------------------------------
117 //
119  : vector_(c.begin(), c.end()), range_(c.begin() + p.first, c.begin() + p.second) {
120  if (p.first > p.second || p.first == sistrip::invalid32_ || p.second == sistrip::invalid32_ || p.first > c.size() ||
121  p.second > c.size()) {
122  range_ = ConnsConstIterRange(c.end(), c.end());
123  }
124 }
125 
126 // -----------------------------------------------------------------------------
127 //
128 SiStripFedCabling::ConnsRange::ConnsRange(const Conns& c) : vector_(c.begin(), c.end()), range_(c.end(), c.end()) { ; }
129 
130 // -----------------------------------------------------------------------------
131 //
132 void SiStripFedCabling::ConnsRange::print(std::stringstream& ss) const {
133  ss << "[SiStripFedCabling::ConnsRange::" << __func__ << "] Debug info:" << std::endl
134  << " Vector : " << std::endl
135  << " size : " << vector_.size() << std::endl
136  << " begin : " << std::hex << std::setfill('0') << std::setw(8) << &*vector_.begin() << std::dec << std::endl
137  << " end : " << std::hex << std::setfill('0') << std::setw(8) << &*vector_.end() << std::dec << std::endl
138  << " Range : " << std::endl
139  << " size : " << range_.size() << std::endl
140  << " begin : " << std::hex << std::setfill('0') << std::setw(8) << &*range_.begin() << std::dec
141  << " (dist=" << std::distance(vector_.begin(), range_.begin()) << ")" << std::endl
142  << " end : " << std::hex << std::setfill('0') << std::setw(8) << &*range_.end() << std::dec
143  << " (dist=" << std::distance(vector_.begin(), range_.end()) << ")" << std::endl
144  << " Offsets : " << std::endl
145  << " first : " << connsPair().first << std::endl
146  << " second : " << connsPair().second << std::endl;
147 }
148 
149 // -----------------------------------------------------------------------------
150 //
151 std::ostream& operator<<(std::ostream& os, const SiStripFedCabling::ConnsRange& input) {
152  std::stringstream ss;
153  input.print(ss);
154  os << ss.str();
155  return os;
156 }
157 
158 // -----------------------------------------------------------------------------
159 // Returns connection info for FE devices connected to given FED
161  uint16_t index = fed_id - FEDNumbering::MINSiStripFEDID;
162  if (index < registry_.size()) {
163  return range(registry_[index]).range();
164  } else {
165  return range(registry_[index]).invalid();
166  }
167 }
168 
169 // -----------------------------------------------------------------------------
170 // Returns connection info for FE devices connected to given FED id and channel
171 FedChannelConnection SiStripFedCabling::fedConnection(uint16_t fed_id, uint16_t fed_ch) const {
172  ConnsConstIterRange conns = fedConnections(fed_id);
173  if (!conns.empty() && conns.size() == 96 && fed_ch < 96) {
174  return *(conns.begin() + fed_ch);
175  } else {
176  return FedChannelConnection();
177  }
178 }
179 
180 // -----------------------------------------------------------------------------
181 //
182 void SiStripFedCabling::printDebug(std::stringstream& ss, const TrackerTopology* /*trackerTopo*/) const {
183  uint16_t total = 0;
184  uint16_t nfeds = 0;
185  uint16_t cntr = 0;
186 
187  if (feds_.empty()) {
188  ss << "[SiStripFedCabling::" << __func__ << "]"
189  << " No FEDs found! Unable to print cabling map!";
190  return;
191  } else {
192  ss << "[SiStripFedCabling::" << __func__ << "]"
193  << " Printing cabling map for " << feds_.size() << " FEDs with following ids: ";
194  }
195 
196  std::vector<uint16_t>::const_iterator ii = feds_.begin();
197  std::vector<uint16_t>::const_iterator jj = feds_.end();
198  for (; ii != jj; ++ii) {
199  ss << *ii << " ";
200  }
201  ss << std::endl << std::endl;
202 
203  std::vector<uint16_t>::const_iterator ifed = feds_.begin();
204  std::vector<uint16_t>::const_iterator jfed = feds_.end();
205  for (; ifed != jfed; ++ifed) {
206  uint16_t index = *ifed - FEDNumbering::MINSiStripFEDID;
207  if (index < registry_.size()) {
208  ConnsRange conns = range(registry_[index]);
209 
210  ss << " Printing cabling information for FED id " << *ifed << " (found " << conns.size()
211  << " FedChannelConnection objects...)" << std::endl;
212 
213  uint16_t ichan = 0;
214  uint16_t connected = 0;
215  ConnsConstIter iconn = conns.begin();
216  ConnsConstIter jconn = conns.end();
217  for (; iconn != jconn; ++iconn) {
218  if (iconn->fedId() != sistrip::invalid_) {
219  connected++;
220  ss << *iconn << std::endl;
221  } else {
222  ss << " (FedId/Ch " << *ifed << "/" << ichan << ": unconnected channel...)" << std::endl;
223  cntr++;
224  }
225  ichan++;
226  }
227 
228  ss << " Found " << connected << " connected channels for FED id " << *ifed << std::endl << std::endl;
229  if (connected) {
230  nfeds++;
231  total += connected;
232  }
233  }
234  }
235 
236  float percent = (100. * cntr) / (96. * nfeds);
237  percent = static_cast<uint16_t>(10. * percent);
238  percent /= 10.;
239  ss << " Found " << total << " APV pairs that are connected to a total of " << nfeds << " FEDs" << std::endl
240  << " " << detected_.size() << " APV pairs have been detected, but are not connected" << std::endl
241  << " " << undetected_.size() << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
242  << " " << cntr << " FED channels out of a possible " << (96 * nfeds) << " (" << nfeds << " FEDs) are unconnected ("
243  << percent << "%)" << std::endl
244  << std::endl;
245 }
246 
247 // -----------------------------------------------------------------------------
248 //
249 void SiStripFedCabling::terse(std::stringstream& ss) const {
250  ss << "[SiStripFedCabling::" << __func__ << "]";
251 
252  if (feds_.empty()) {
253  ss << " No FEDs found! Unable to print cabling map!";
254  return;
255  }
256 
257  ss << " Printing cabling map for " << feds_.size() << " FEDs: " << std::endl << std::endl;
258 
259  std::vector<uint16_t>::const_iterator ifed = feds_.begin();
260  std::vector<uint16_t>::const_iterator jfed = feds_.end();
261  for (; ifed != jfed; ++ifed) {
262  uint16_t index = *ifed - FEDNumbering::MINSiStripFEDID;
263  if (index < registry_.size()) {
264  ConnsRange conns = range(registry_[index]);
265 
266  ss << " Printing cabling information for FED id " << *ifed << " (found " << conns.size()
267  << " FedChannelConnection objects...)" << std::endl;
268 
269  uint16_t connected = 0;
270  ConnsConstIter iconn = conns.begin();
271  ConnsConstIter jconn = conns.end();
272  for (; iconn != jconn; ++iconn) {
273  if (iconn->fedId() != sistrip::invalid_) {
274  connected++;
275  iconn->terse(ss);
276  ss << std::endl;
277  }
278  }
279 
280  ss << " Found " << connected << " connected channels for FED id " << *ifed << std::endl << std::endl;
281  }
282  }
283 }
284 
285 // -----------------------------------------------------------------------------
286 //
287 void SiStripFedCabling::printSummary(std::stringstream& ss, const TrackerTopology* /*trackerTopo*/) const {
288  ss << "[SiStripFedCabling::" << __func__ << "]";
289 
290  if (feds_.empty()) {
291  ss << " No FEDs found!";
292  return;
293  }
294 
295  ss << " Found " << feds_.size() << " FEDs"
296  << " with number of connected channels per front-end unit: " << std::endl
297  << " FedId FeUnit1 FeUnit2 FeUnit3 FeUnit4 FeUnit5 FeUnit6 FeUnit7 FeUnit8 Total" << std::endl;
298 
299  uint16_t total = 0;
300  uint16_t nfeds = 0;
301 
302  // iterate through fed ids
303  std::vector<uint16_t>::const_iterator ii = feds_.begin();
304  std::vector<uint16_t>::const_iterator jj = feds_.end();
305  for (; ii != jj; ++ii) {
306  // check number of connection objects
307  uint16_t index = *ii - FEDNumbering::MINSiStripFEDID;
308  if (index < registry_.size()) {
309  ConnsRange conns = range(registry_[index]);
310 
311  if (conns.size() < 96) {
312  edm::LogError(mlCabling_) << "[SiStripFedCabling::" << __func__ << "]"
313  << " Unexpected size for FedChannelConnection vector! " << conns.size();
314  return;
315  }
316 
317  // count connected channels at level of fe unit
318  std::vector<uint16_t> connected;
319  connected.resize(8, 0);
320  for (uint16_t ichan = 0; ichan < 96; ++ichan) {
321  ConnsConstIter iconn = conns.begin() + ichan;
322  if (iconn->fedId() < sistrip::valid_) {
323  uint16_t unit = SiStripFedKey::feUnit(ichan);
324  if (unit > 8) {
325  continue;
326  }
327  connected[unit - 1]++;
328  }
329  }
330 
331  // increment counters
332  uint16_t tot = 0;
333  ss << " " << std::setw(5) << *ii;
334  if (!connected.empty()) {
335  nfeds++;
336  }
337  for (uint16_t unit = 0; unit < 8; ++unit) {
338  ss << " " << std::setw(7) << connected[unit];
339  if (!connected.empty()) {
340  tot += connected[unit];
341  }
342  }
343  ss << " " << std::setw(5) << tot << std::endl;
344  total += tot;
345  }
346  }
347 
348  // print out
349  float percent = (100. * total) / (96. * nfeds);
350  percent = static_cast<uint16_t>(10. * percent);
351  percent /= 10.;
352  ss << " Found: " << std::endl
353  << " " << nfeds << " out of " << feds_.size() << " FEDs with at least one connected channel " << std::endl
354  << " " << feds_.size() - nfeds << " out of " << feds_.size() << " FEDs with no connected channels." << std::endl
355  << " " << total << " connected channels in total" << std::endl
356  << " " << detected_.size() << " APV pairs have been detected, but are not connected" << std::endl
357  << " " << undetected_.size() << " APV pairs are undetected (wrt DCU-DetId map)" << std::endl
358  << " " << percent << "% of FED channels are connected" << std::endl;
359 }
ConnsConstIter begin() const
Conns connections_
Container of connection objects.
Feds feds_
"Active" FEDs that have connected FE devices
const uint16_t & feUnit() const
static const uint32_t invalid32_
Definition: Constants.h:15
FedChannelConnection fedConnection(uint16_t fed_id, uint16_t fed_ch) const
Builds range of iterators from pair of offsets.
Log< level::Error, false > LogError
static const uint16_t valid_
Definition: Constants.h:17
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
Registry registry_
Container of "ranges" indexed by FED id.
Conns::iterator ConnsIter
ConnsConstIter end() const
sistrip classes
Conns undetected_
FE devices that are detected.
#define LogTrace(id)
static std::string const input
Definition: EdmProvDump.cc:50
U second(std::pair< T, U > const &p)
static const char mlCabling_[]
boost::iterator_range< ConnsConstIter > ConnsConstIterRange
Class containning control, module, detector and connection information, at the level of a FED channel...
Conns detected_
Connections to FE devices that are not detected.
std::ostream & operator<<(std::ostream &os, const SiStripFedCabling::ConnsRange &input)
Feds::const_iterator FedsConstIter
void printSummary(std::stringstream &, const TrackerTopology *trackerTopo) const
Basic3DVector unit() const
void buildFedCabling(ConnsConstIterRange connections)
ConnsRange range(ConnsPair) const
Builds range of iterators from pair of offsets.
ii
Definition: cuy.py:589
void printDebug(std::stringstream &, const TrackerTopology *trackerTopo) const
void terse(std::stringstream &) const
static const uint16_t invalid_
Definition: Constants.h:16
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
std::vector< FedChannelConnection > Conns
conn
Definition: getInfo.py:9
std::pair< uint32_t, uint32_t > ConnsPair
ConnsConstIterRange invalid() const
Conns::const_iterator ConnsConstIter
void print(std::stringstream &) const
ConnsConstIterRange fedConnections(uint16_t fed_id) const
ConnsConstIterRange range() const