Back to home page

Project CMSSW displayed by LXR

 
 

    


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   //  LogTrace("RPCLinkSynchroStat") <<" SIZE OF LINKS IS: " << theLinkStatMap.size() << endl;
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);  // ensure one count per LB per BX
0195   }
0196 
0197   for (auto ic = slis.begin(); ic != slis.end(); ++ic) {
0198     if (theUseFirstHitOnly) {
0199       theLinkStatMap[ic->idx].second.increment(ic->counts.firstHit());  // first hit only
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     // DUMP LINKNAME
0219     str << std::setw(20) << board.name();
0220 
0221     // DUMP COUNTS
0222     str << " " << counts.print();
0223 
0224     //PATHS
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     // DUMP CHAMBERS
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 }