File indexing completed on 2024-04-06 12:08:13
0001 #include "DQM/RPCMonitorDigi/interface/RPCLinkSynchroStat.h"
0002
0003 #include "CondFormats/RPCObjects/interface/LinkBoardSpec.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005
0006 #include <algorithm>
0007 #include <sstream>
0008 #include <iostream>
0009 #include <iomanip>
0010
0011 bool RPCLinkSynchroStat::LessLinkName::operator()(const BoardAndCounts& o1, const BoardAndCounts& o2) {
0012 return o1.first < o2.first;
0013 }
0014 bool RPCLinkSynchroStat::LessCountSum::operator()(const BoardAndCounts& o1, const BoardAndCounts& o2) {
0015 return o1.second.sum() < o2.second.sum();
0016 }
0017
0018 void RPCLinkSynchroStat::add(const std::string& lbName, const unsigned int* hits) {
0019 LinkBoard lb(lbName);
0020 SynchroCounts counts(hits);
0021 for (auto it = theLinkStatMap.begin(); it != theLinkStatMap.end(); ++it)
0022 if (it->first == lb)
0023 it->second += counts;
0024 }
0025
0026 int RPCLinkSynchroStat::LinkBoard::add(const ChamberAndPartition& part) {
0027 for (auto it = theChamberAndPartitions.begin(); it != theChamberAndPartitions.end(); ++it) {
0028 if ((*it) == part)
0029 return 1;
0030 }
0031 theChamberAndPartitions.push_back(part);
0032 return 0;
0033 }
0034
0035 int RPCLinkSynchroStat::LinkBoard::add(const LinkBoardElectronicIndex& ele) {
0036 for (auto it = theElePaths.begin(); it != theElePaths.end(); ++it) {
0037 if (it->dccId == ele.dccId && it->dccInputChannelNum == ele.dccInputChannelNum &&
0038 it->tbLinkInputNum == ele.tbLinkInputNum && it->lbNumInLink == ele.lbNumInLink)
0039 return 1;
0040 }
0041 theElePaths.push_back(ele);
0042 return 0;
0043 }
0044
0045 unsigned int RPCLinkSynchroStat::SynchroCounts::firstHit() const {
0046 for (unsigned int i = 0; i < 8; ++i)
0047 if (theCounts[i])
0048 return i;
0049 return 8;
0050 }
0051
0052 void RPCLinkSynchroStat::SynchroCounts::set(unsigned int bxDiff) {
0053 if (bxDiff < 8)
0054 theCounts[bxDiff] = 1;
0055 }
0056
0057 void RPCLinkSynchroStat::SynchroCounts::increment(unsigned int bxDiff) {
0058 if (bxDiff < 8)
0059 theCounts[bxDiff]++;
0060 }
0061
0062 RPCLinkSynchroStat::SynchroCounts& RPCLinkSynchroStat::SynchroCounts::operator+=(const SynchroCounts& rhs) {
0063 for (unsigned int i = 0; i < 8; ++i)
0064 theCounts[i] += rhs.theCounts[i];
0065 return *this;
0066 }
0067
0068 unsigned int RPCLinkSynchroStat::SynchroCounts::mom0() const {
0069 unsigned int result = 0;
0070 for (unsigned int i = 0; i < 8; ++i)
0071 result += theCounts[i];
0072 return result;
0073 }
0074
0075 double RPCLinkSynchroStat::SynchroCounts::mom1() const {
0076 double result = 0.;
0077 for (unsigned int i = 0; i < 8; ++i)
0078 result += i * theCounts[i];
0079 return result;
0080 }
0081
0082 double RPCLinkSynchroStat::SynchroCounts::mean() const {
0083 unsigned int sum = mom0();
0084 return sum == 0 ? 0. : mom1() / sum;
0085 }
0086
0087 double RPCLinkSynchroStat::SynchroCounts::rms() const {
0088 double result = 0.;
0089 int sum = mom0();
0090 if (sum == 0)
0091 return 0.;
0092 double mean = mom1() / sum;
0093 for (int i = 0; i < 8; ++i)
0094 result += theCounts[i] * (mean - i) * (mean - i);
0095 result /= sum;
0096 return sqrt(result);
0097 }
0098
0099 std::string RPCLinkSynchroStat::SynchroCounts::print() const {
0100 std::ostringstream str;
0101 str << " mean: " << std::setw(8) << mean();
0102 str << " rms: " << std::setw(8) << rms();
0103 str << " counts:";
0104 for (int i = 0; i < 8; ++i)
0105 str << " " << std::setw(4) << theCounts[i];
0106 return str.str();
0107 }
0108
0109 bool RPCLinkSynchroStat::SynchroCounts::operator==(const SynchroCounts& o) const {
0110 for (unsigned int idx = 0; idx < 8; ++idx)
0111 if (theCounts[idx] != o.theCounts[idx])
0112 return false;
0113 return true;
0114 }
0115
0116 RPCLinkSynchroStat::RPCLinkSynchroStat(bool useFirstFitOnly) : theUseFirstHitOnly(useFirstFitOnly) {
0117 for (unsigned int i1 = 0; i1 <= MAXDCCINDEX; ++i1) {
0118 for (unsigned int i2 = 0; i2 <= MAXRBCINDEX; i2++) {
0119 for (unsigned int i3 = 0; i3 <= MAXLINKINDEX; ++i3) {
0120 for (unsigned int i4 = 0; i4 <= MAXLBINDEX; ++i4) {
0121 theLinkStatNavi[i1][i2][i3][i4] = 0;
0122 }
0123 }
0124 }
0125 }
0126 theLinkStatMap.push_back(std::make_pair(LinkBoard("Dummy"), SynchroCounts()));
0127 }
0128
0129 void RPCLinkSynchroStat::init(const RPCReadOutMapping* theCabling, bool addChamberInfo) {
0130 if (!theCabling)
0131 return;
0132 std::vector<const DccSpec*> dccs = theCabling->dccList();
0133 for (auto it1 = dccs.begin(); it1 != dccs.end(); ++it1) {
0134 const std::vector<TriggerBoardSpec>& rmbs = (*it1)->triggerBoards();
0135 for (auto it2 = rmbs.begin(); it2 != rmbs.end(); ++it2) {
0136 const std::vector<LinkConnSpec>& links = it2->linkConns();
0137 for (auto it3 = links.begin(); it3 != links.end(); ++it3) {
0138 const std::vector<LinkBoardSpec>& lbs = it3->linkBoards();
0139 for (auto it4 = lbs.begin(); it4 != lbs.end(); ++it4) {
0140 LinkBoardElectronicIndex ele = {
0141 (*it1)->id(), it2->dccInputChannelNum(), it3->triggerBoardInputNumber(), it4->linkBoardNumInLink()};
0142 LinkBoard linkBoard(it4->linkBoardName());
0143 BoardAndCounts candid = std::make_pair(linkBoard, SynchroCounts());
0144 std::vector<BoardAndCounts>::iterator candid_place =
0145 lower_bound(theLinkStatMap.begin(), theLinkStatMap.end(), candid, LessLinkName());
0146 if (candid_place != theLinkStatMap.end() && candid.first == candid_place->first) {
0147 candid_place->first.add(ele);
0148 } else {
0149 candid_place = theLinkStatMap.insert(candid_place, candid);
0150 candid_place->first.add(ele);
0151 if (addChamberInfo) {
0152 const std::vector<FebConnectorSpec>& febs = it4->febs();
0153 for (std::vector<FebConnectorSpec>::const_iterator it5 = febs.begin(); it5 != febs.end(); ++it5) {
0154 std::string chamberName = it5->chamber().chamberLocationName();
0155 std::string partitionName = it5->feb().localEtaPartitionName();
0156 LinkBoard::ChamberAndPartition chamberAndPartition = std::make_pair(chamberName, partitionName);
0157 candid_place->first.add(chamberAndPartition);
0158 }
0159 }
0160 }
0161 }
0162 }
0163 }
0164 }
0165 for (unsigned int idx = 0; idx < theLinkStatMap.size(); ++idx) {
0166 const std::vector<LinkBoardElectronicIndex>& paths = theLinkStatMap[idx].first.paths();
0167 for (auto it = paths.begin(); it != paths.end(); ++it) {
0168 theLinkStatNavi[it->dccId - DCCINDEXSHIFT][it->dccInputChannelNum][it->tbLinkInputNum][it->lbNumInLink] = idx;
0169 }
0170 }
0171
0172 }
0173
0174 void RPCLinkSynchroStat::add(const RPCRawSynchro::ProdItem& vItem, std::vector<LinkBoardElectronicIndex>& problems) {
0175 std::vector<int> hits(theLinkStatMap.size(), 0);
0176 std::vector<ShortLinkInfo> slis;
0177 for (auto it = vItem.begin(); it != vItem.end(); ++it) {
0178 const LinkBoardElectronicIndex& path = it->first;
0179 unsigned int bxDiff = it->second;
0180 unsigned int eleCode = (path.dccId - DCCINDEXSHIFT) * 100000 + path.dccInputChannelNum * 1000 +
0181 path.tbLinkInputNum * 10 + path.lbNumInLink;
0182 unsigned int idx =
0183 theLinkStatNavi[path.dccId - DCCINDEXSHIFT][path.dccInputChannelNum][path.tbLinkInputNum][path.lbNumInLink];
0184 if (hits[idx] == 0) {
0185 ShortLinkInfo sli = {idx, std::vector<unsigned int>(1, eleCode), SynchroCounts()};
0186 slis.push_back(sli);
0187 hits[idx] = slis.size();
0188 } else {
0189 std::vector<unsigned int>& v = slis[hits[idx] - 1].hit_paths;
0190 std::vector<unsigned int>::iterator iv = lower_bound(v.begin(), v.end(), eleCode);
0191 if (iv == v.end() || (*iv) != eleCode)
0192 v.insert(iv, eleCode);
0193 }
0194 slis[hits[idx] - 1].counts.set(bxDiff);
0195 }
0196
0197 for (auto ic = slis.begin(); ic != slis.end(); ++ic) {
0198 if (theUseFirstHitOnly) {
0199 theLinkStatMap[ic->idx].second.increment(ic->counts.firstHit());
0200 } else {
0201 theLinkStatMap[ic->idx].second += ic->counts;
0202 }
0203 if (theLinkStatMap[ic->idx].first.paths().size() != ic->hit_paths.size()) {
0204 const std::vector<LinkBoardElectronicIndex>& paths = theLinkStatMap[ic->idx].first.paths();
0205 problems.insert(problems.end(), paths.begin(), paths.end());
0206 }
0207 }
0208 }
0209
0210 std::string RPCLinkSynchroStat::dumpDelays() {
0211 std::ostringstream str;
0212 std::vector<BoardAndCounts> sortedStat = theLinkStatMap;
0213 stable_sort(sortedStat.begin(), sortedStat.end(), LessCountSum());
0214 for (unsigned int idx = 0; idx < sortedStat.size(); ++idx) {
0215 const LinkBoard& board = sortedStat[idx].first;
0216 const SynchroCounts& counts = sortedStat[idx].second;
0217
0218
0219 str << std::setw(20) << board.name();
0220
0221
0222 str << " " << counts.print();
0223
0224
0225 str << " paths: ";
0226 const std::vector<LinkBoardElectronicIndex>& paths = board.paths();
0227 for (auto ip = paths.begin(); ip != paths.end(); ++ip)
0228 str << "{" << ip->dccId << "," << std::setw(2) << ip->dccInputChannelNum << "," << std::setw(2)
0229 << ip->tbLinkInputNum << "," << ip->lbNumInLink << "}";
0230
0231
0232 std::map<std::string, std::vector<std::string> > chMap;
0233 const std::vector<LinkBoard::ChamberAndPartition>& chamberAndPartitions = board.chamberAndPartitions();
0234 for (auto it = chamberAndPartitions.begin(); it != chamberAndPartitions.end(); ++it) {
0235 std::vector<std::string>& partitions = chMap[it->first];
0236 if (find(partitions.begin(), partitions.end(), it->second) == partitions.end())
0237 partitions.push_back(it->second);
0238 }
0239 str << " chambers: ";
0240 for (auto im = chMap.begin(); im != chMap.end(); ++im) {
0241 str << im->first << "(";
0242 for (std::vector<std::string>::const_iterator ip = im->second.begin(); ip != im->second.end(); ++ip) {
0243 str << *ip;
0244 if ((ip + 1) != (im->second.end()))
0245 str << ",";
0246 else
0247 str << ")";
0248 }
0249 }
0250
0251 str << std::endl;
0252 }
0253 LogTrace("RPCLinkSynchroStat") << "RPCLinkSynchroStat::dumpDelays, SIZE OF LINKS IS: " << theLinkStatMap.size()
0254 << std::endl;
0255 return str.str();
0256 }