Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:58:19

0001 //
0002 // Author:      Domenico Giordano
0003 // Created:     Wed Sep 26 17:42:12 CEST 2007
0004 //
0005 #include "CalibFormats/SiStripObjects/interface/SiStripDetCabling.h"
0006 #include "CalibFormats/SiStripObjects/interface/SiStripQuality.h"
0007 #include "CalibFormats/SiStripObjects/interface/SiStripDetInfo.h"
0008 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0009 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0010 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "FWCore/Utilities/interface/typelookup.h"
0013 
0014 // Needed only for output
0015 #include "DataFormats/DetId/interface/DetId.h"
0016 
0017 SiStripQuality::SiStripQuality(SiStripDetInfo iInfo)
0018     : info_(std::move(iInfo)),
0019       toCleanUp(false),
0020       SiStripDetCabling_(nullptr),
0021       printDebug_(false),
0022       useEmptyRunInfo_(false) {}
0023 
0024 SiStripQuality SiStripQuality::difference(const SiStripQuality &other) const {
0025   SiStripBadStrip::RegistryIterator rbegin = other.getRegistryVectorBegin();
0026   SiStripBadStrip::RegistryIterator rend = other.getRegistryVectorEnd();
0027   std::vector<unsigned int> ovect, vect;
0028   uint32_t detid;
0029   unsigned short Nstrips;
0030 
0031   SiStripQuality retValue(*this);
0032   for (SiStripBadStrip::RegistryIterator rp = rbegin; rp != rend; ++rp) {
0033     detid = rp->detid;
0034     Nstrips = info_.getNumberOfApvsAndStripLength(detid).first * 128;
0035 
0036     SiStripBadStrip::Range orange =
0037         SiStripBadStrip::Range(other.getDataVectorBegin() + rp->ibegin, other.getDataVectorBegin() + rp->iend);
0038 
0039     // Is this detid already in the collections owned by this class?
0040     SiStripBadStrip::Range range = retValue.getRange(detid);
0041     if (range.first != range.second) {  // yes, it is
0042 
0043       vect.clear();
0044       ovect.clear();
0045 
0046       // if other full det is bad, remove det from this
0047       SiStripBadStrip::data data_ = decode(*(orange.first));
0048       if (orange.second - orange.first != 1 || data_.firstStrip != 0 || data_.range < Nstrips) {
0049         ovect.insert(ovect.end(), orange.first, orange.second);
0050         vect.insert(vect.end(), range.first, range.second);
0051         retValue.subtract(vect, ovect);
0052       }
0053       SiStripBadStrip::Range newrange(vect.begin(), vect.end());
0054       if (!retValue.put_replace(detid, newrange))
0055         edm::LogError("SiStripQuality") << "[" << __PRETTY_FUNCTION__ << "] " << std::endl;
0056     }
0057   }
0058   retValue.cleanUp();
0059   retValue.fillBadComponents();
0060   return retValue;
0061 }
0062 
0063 void SiStripQuality::add(const SiStripDetVOff *Voff) {
0064   std::vector<unsigned int> vect;
0065   short firstStrip = 0;
0066   short range = 0;
0067 
0068   // Get vector of Voff dets
0069   std::vector<uint32_t> vdets;
0070   Voff->getDetIds(vdets);
0071   std::vector<uint32_t>::const_iterator iter = vdets.begin();
0072   std::vector<uint32_t>::const_iterator iterEnd = vdets.end();
0073 
0074   for (; iter != iterEnd; ++iter) {
0075     vect.clear();
0076     range = (short)(info_.getNumberOfApvsAndStripLength(*iter).first * 128.);
0077     LogTrace("SiStripQuality") << "[add Voff] add detid " << *iter << " first strip " << firstStrip << " range "
0078                                << range << std::endl;
0079     vect.push_back(encode(firstStrip, range));
0080     SiStripBadStrip::Range Range(vect.begin(), vect.end());
0081     add(*iter, Range);
0082   }
0083 }
0084 
0085 void SiStripQuality::add(const RunInfo *runInfo) {
0086   bool allFedsEmpty = runInfo->m_fed_in.empty();
0087   if (allFedsEmpty) {
0088     std::stringstream ss;
0089     ss << "WARNING: the full list of feds in RunInfo is empty. ";
0090     if (useEmptyRunInfo_) {
0091       ss << " SiStripQuality will still use it and all tracker will be off." << std::endl;
0092     } else {
0093       ss << " SiStripQuality will not use it." << std::endl;
0094     }
0095     edm::LogInfo("SiStripQuality") << ss.str();
0096   }
0097 
0098   if (!allFedsEmpty || useEmptyRunInfo_) {
0099     // Take the list of active feds from fedCabling
0100     auto ids = SiStripDetCabling_->fedCabling()->fedIds();
0101 
0102     std::vector<uint16_t> activeFedsFromCabling(ids.begin(), ids.end());
0103     // Take the list of active feds from RunInfo
0104     std::vector<int> activeFedsFromRunInfo;
0105     // Take only Tracker feds (remove all non Tracker)
0106     std::remove_copy_if(
0107         runInfo->m_fed_in.begin(), runInfo->m_fed_in.end(), std::back_inserter(activeFedsFromRunInfo), [&](int x) {
0108           return !((x >= int(FEDNumbering::MINSiStripFEDID)) && (x <= int(FEDNumbering::MAXSiStripFEDID)));
0109         });
0110 
0111     // Compare the two. If a fedId from RunInfo is not present in the fedCabling
0112     // we need to get all the corresponding fedChannels and then the single apv
0113     // pairs and use them to turn off the corresponding strips (apvNumber*256).
0114     // set_difference returns the set of elements that are in the first and not
0115     // in the second
0116     std::sort(activeFedsFromCabling.begin(), activeFedsFromCabling.end());
0117     std::sort(activeFedsFromRunInfo.begin(), activeFedsFromRunInfo.end());
0118     std::vector<int> differentFeds;
0119     // Take the feds active for cabling but not for runInfo
0120     std::set_difference(activeFedsFromCabling.begin(),
0121                         activeFedsFromCabling.end(),
0122                         activeFedsFromRunInfo.begin(),
0123                         activeFedsFromRunInfo.end(),
0124                         std::back_inserter(differentFeds));
0125 
0126     // IGNORE for time being.
0127     // printActiveFedsInfo(activeFedsFromCabling, activeFedsFromRunInfo,
0128     // differentFeds, printDebug_);
0129 
0130     // Feds in the differentFeds vector are now to be turned off as they are off
0131     // according to RunInfo but were not off in cabling and thus are still
0132     // active for the SiStripQuality. The "true" means that the strips are to be
0133     // set as bad.
0134     turnOffFeds(differentFeds, true, printDebug_);
0135 
0136     // Consistency check
0137     // -----------------
0138     std::vector<int> check;
0139     std::set_difference(activeFedsFromRunInfo.begin(),
0140                         activeFedsFromRunInfo.end(),
0141                         activeFedsFromCabling.begin(),
0142                         activeFedsFromCabling.end(),
0143                         std::back_inserter(check));
0144     // This must not happen
0145     if (!check.empty()) {
0146       // throw cms::Exception("LogicError")
0147       edm::LogInfo("SiStripQuality") << "The cabling should always include the active feds in runInfo and "
0148                                         "possibly have some more"
0149                                      << "there are instead " << check.size() << " feds only active in runInfo";
0150       // The "false" means that we are only printing the output, but not setting
0151       // the strips as bad. The second bool means that we always want the debug
0152       // output in this case.
0153       turnOffFeds(check, false, true);
0154     }
0155   }
0156 }
0157 
0158 void SiStripQuality::add(const SiStripDetCabling *cab) {
0159   SiStripDetCabling_ = cab;
0160   addInvalidConnectionFromCabling();
0161   addNotConnectedConnectionFromCabling();
0162 }
0163 
0164 void SiStripQuality::addNotConnectedConnectionFromCabling() {
0165   auto allData = info_.getAllData();
0166   auto iter = allData.begin();
0167   auto iterEnd = allData.end();
0168   std::vector<unsigned int> vect;
0169   short firstStrip = 0;
0170   short range = 0;
0171   for (; iter != iterEnd; ++iter)
0172     if (!SiStripDetCabling_->IsConnected(iter->first)) {
0173       vect.clear();
0174       range = iter->second.nApvs * 128;
0175       LogTrace("SiStripQuality") << "[addNotConnectedConnectionFromCabling] add detid " << iter->first << std::endl;
0176       vect.push_back(encode(firstStrip, range));
0177       SiStripBadStrip::Range Range(vect.begin(), vect.end());
0178       add(iter->first, Range);
0179     }
0180 }
0181 
0182 void SiStripQuality::addInvalidConnectionFromCabling() {
0183   std::vector<uint32_t> connected_detids;
0184   SiStripDetCabling_->addActiveDetectorsRawIds(connected_detids);
0185   std::vector<uint32_t>::const_iterator itdet = connected_detids.begin();
0186   std::vector<uint32_t>::const_iterator itdetEnd = connected_detids.end();
0187   for (; itdet != itdetEnd; ++itdet) {
0188     // LogTrace("SiStripQuality") << "[addInvalidConnectionFromCabling] looking
0189     // at detid " <<*itdet << std::endl;
0190     const std::vector<const FedChannelConnection *> &fedconns = SiStripDetCabling_->getConnections(*itdet);
0191     std::vector<const FedChannelConnection *>::const_iterator itconns = fedconns.begin();
0192     std::vector<const FedChannelConnection *>::const_iterator itconnsEnd = fedconns.end();
0193 
0194     unsigned short nApvPairs = SiStripDetCabling_->nApvPairs(*itdet);
0195     short ngoodConn = 0, goodConn = 0;
0196     for (; itconns != itconnsEnd; ++itconns) {
0197       // LogTrace("SiStripQuality") << "[addInvalidConnectionFromCabling]
0198       // apvpair " << (*itconns)->apvPairNumber() << " napvpair " <<
0199       // (*itconns)->nApvPairs()<< " detid " << (*itconns)->detId() <<
0200       // std::endl;
0201       if ((*itconns == nullptr) || ((*itconns)->nApvPairs() == sistrip::invalid_))
0202         continue;
0203       ngoodConn++;
0204       goodConn = goodConn | (0x1 << (*itconns)->apvPairNumber());
0205     }
0206 
0207     if (ngoodConn != nApvPairs) {
0208       std::vector<unsigned int> vect;
0209       for (size_t idx = 0; idx < nApvPairs; ++idx) {
0210         if (!(goodConn & (0x1 << idx))) {
0211           short firstStrip = idx * 256;
0212           short range = 256;
0213           LogTrace("SiStripQuality") << "[addInvalidConnectionFromCabling] add detid " << *itdet << "firstStrip "
0214                                      << firstStrip << std::endl;
0215           vect.push_back(encode(firstStrip, range));
0216         }
0217       }
0218       if (!vect.empty()) {
0219         SiStripBadStrip::Range Range(vect.begin(), vect.end());
0220         add(*itdet, Range);
0221       }
0222     }
0223   }
0224 }
0225 
0226 void SiStripQuality::add(const SiStripBadStrip *base) {
0227   SiStripBadStrip::RegistryIterator basebegin = base->getRegistryVectorBegin();
0228   SiStripBadStrip::RegistryIterator baseend = base->getRegistryVectorEnd();
0229 
0230   // the Registry already contains data
0231   // Loop on detids
0232   for (SiStripBadStrip::RegistryIterator basep = basebegin; basep != baseend; ++basep) {
0233     uint32_t detid = basep->detid;
0234     LogTrace("SiStripQuality") << "add detid " << detid << std::endl;
0235 
0236     SiStripBadStrip::Range baserange =
0237         SiStripBadStrip::Range(base->getDataVectorBegin() + basep->ibegin, base->getDataVectorBegin() + basep->iend);
0238 
0239     add(detid, baserange);
0240   }
0241 }
0242 
0243 void SiStripQuality::add(uint32_t detid, const SiStripBadStrip::Range &baserange) {
0244   std::vector<unsigned int> vect, tmp;
0245 
0246   unsigned short Nstrips = info_.getNumberOfApvsAndStripLength(detid).first * 128;
0247 
0248   // Is this detid already in the collections owned by this class?
0249   SiStripBadStrip::Range range = getRange(detid);
0250 
0251   // Append bad strips
0252   tmp.clear();
0253   if (range.first == range.second) {
0254     LogTrace("SiStripQuality") << "new detid" << std::endl;
0255     // It's a new detid
0256     tmp.insert(tmp.end(), baserange.first, baserange.second);
0257     std::stable_sort(tmp.begin(), tmp.end());
0258     LogTrace("SiStripQuality") << "ordered" << std::endl;
0259   } else {
0260     LogTrace("SiStripQuality") << "already exists" << std::endl;
0261     // alredy existing detid
0262 
0263     // if full det is bad go to next detid
0264     SiStripBadStrip::data data_ = decode(*(range.first));
0265     if (range.second - range.first == 1 && data_.firstStrip == 0 && data_.range >= Nstrips) {
0266       LogTrace("SiStripQuality") << "full det is bad.. " << range.second - range.first << " "
0267                                  << decode(*(range.first)).firstStrip << " " << decode(*(range.first)).range << " "
0268                                  << decode(*(range.first)).flag << "\n"
0269                                  << std::endl;
0270       return;
0271     }
0272 
0273     tmp.insert(tmp.end(), baserange.first, baserange.second);
0274     tmp.insert(tmp.end(), range.first, range.second);
0275     std::stable_sort(tmp.begin(), tmp.end());
0276     LogTrace("SiStripQuality") << "ordered" << std::endl;
0277   }
0278   // Compact data
0279   compact(tmp, vect, Nstrips);
0280   SiStripBadStrip::Range newrange(vect.begin(), vect.end());
0281   if (!put_replace(detid, newrange))
0282     edm::LogError("SiStripQuality") << "[" << __PRETTY_FUNCTION__ << "] " << std::endl;
0283 }
0284 
0285 void SiStripQuality::compact(uint32_t detid, std::vector<unsigned int> &vect) {
0286   std::vector<unsigned int> tmp = vect;
0287   vect.clear();
0288   std::stable_sort(tmp.begin(), tmp.end());
0289   unsigned short Nstrips = info_.getNumberOfApvsAndStripLength(detid).first * 128;
0290   compact(tmp, vect, Nstrips);
0291 }
0292 
0293 bool SiStripQuality::put_replace(uint32_t DetId, Range input) {
0294   // put in SiStripQuality::v_badstrips of DetId
0295   Registry::iterator p = std::lower_bound(indexes.begin(), indexes.end(), DetId, SiStripBadStrip::StrictWeakOrdering());
0296 
0297   size_t sd = input.second - input.first;
0298   DetRegistry detregistry;
0299   detregistry.detid = DetId;
0300   detregistry.ibegin = v_badstrips.size();
0301   detregistry.iend = v_badstrips.size() + sd;
0302 
0303   v_badstrips.insert(v_badstrips.end(), input.first, input.second);
0304 
0305   if (p != indexes.end() && p->detid == DetId) {
0306     LogTrace("SiStripQuality") << "[SiStripQuality::put_replace]  Replacing "
0307                                   "SiStripQuality for already stored DetID "
0308                                << DetId << std::endl;
0309     toCleanUp = true;
0310     *p = detregistry;
0311   } else {
0312     indexes.insert(p, detregistry);
0313   }
0314 
0315   return true;
0316 }
0317 
0318 /*
0319 Method to reduce the granularity of badcomponents:
0320 if in an apv there are more than ratio*128 bad strips,
0321 the full apv is declared as bad.
0322 Method needed to help the
0323  */
0324 void SiStripQuality::ReduceGranularity(double threshold) {
0325   SiStripBadStrip::RegistryIterator rp = getRegistryVectorBegin();
0326   SiStripBadStrip::RegistryIterator rend = getRegistryVectorEnd();
0327   SiStripBadStrip::data data_;
0328   uint16_t BadStripPerApv[6], ipos;
0329   std::vector<unsigned int> vect;
0330 
0331   for (; rp != rend; ++rp) {
0332     uint32_t detid = rp->detid;
0333 
0334     BadStripPerApv[0] = 0;
0335     BadStripPerApv[1] = 0;
0336     BadStripPerApv[2] = 0;
0337     BadStripPerApv[3] = 0;
0338     BadStripPerApv[4] = 0;
0339     BadStripPerApv[5] = 0;
0340 
0341     SiStripBadStrip::Range sqrange =
0342         SiStripBadStrip::Range(getDataVectorBegin() + rp->ibegin, getDataVectorBegin() + rp->iend);
0343 
0344     for (int it = 0; it < sqrange.second - sqrange.first; it++) {
0345       data_ = decode(*(sqrange.first + it));
0346       LogTrace("SiStripQuality") << "[SiStripQuality::ReduceGranularity] detid " << detid << " first strip "
0347                                  << data_.firstStrip << " lastStrip " << data_.firstStrip + data_.range - 1 << " range "
0348                                  << data_.range;
0349       ipos = data_.firstStrip / 128;
0350       while (ipos <= (data_.firstStrip + data_.range - 1) / 128) {
0351         BadStripPerApv[ipos] +=
0352             std::min(data_.firstStrip + data_.range, (ipos + 1) * 128) - std::max(data_.firstStrip * 1, ipos * 128);
0353         LogTrace("SiStripQuality") << "[SiStripQuality::ReduceGranularity] ipos " << ipos << " Counter "
0354                                    << BadStripPerApv[ipos] << " min "
0355                                    << std::min(data_.firstStrip + data_.range, (ipos + 1) * 128) << " max "
0356                                    << std::max(data_.firstStrip * 1, ipos * 128) << " added "
0357                                    << std::min(data_.firstStrip + data_.range, (ipos + 1) * 128) -
0358                                           std::max(data_.firstStrip * 1, ipos * 128);
0359         ipos++;
0360       }
0361     }
0362 
0363     LogTrace("SiStripQuality") << "[SiStripQuality::ReduceGranularity] Total for detid " << detid << " values "
0364                                << BadStripPerApv[0] << " " << BadStripPerApv[1] << " " << BadStripPerApv[2] << " "
0365                                << BadStripPerApv[3] << " " << BadStripPerApv[4] << " " << BadStripPerApv[5];
0366 
0367     vect.clear();
0368     for (size_t i = 0; i < 6; ++i) {
0369       if (BadStripPerApv[i] >= threshold * 128) {
0370         vect.push_back(encode(i * 128, 128));
0371       }
0372     }
0373     if (!vect.empty()) {
0374       SiStripBadStrip::Range Range(vect.begin(), vect.end());
0375       add(detid, Range);
0376     }
0377   }
0378 }
0379 
0380 void SiStripQuality::compact(std::vector<unsigned int> &tmp, std::vector<unsigned int> &vect, unsigned short &Nstrips) {
0381   SiStripBadStrip::data fs_0, fs_1;
0382   vect.clear();
0383 
0384   ContainerIterator it = tmp.begin();
0385   fs_0 = decode(*it);
0386 
0387   // Check if at the module end
0388   if (fs_0.firstStrip + fs_0.range >= Nstrips) {
0389     vect.push_back(encode(fs_0.firstStrip, Nstrips - fs_0.firstStrip));
0390     return;
0391   }
0392 
0393   ++it;
0394   for (; it != tmp.end(); ++it) {
0395     fs_1 = decode(*it);
0396 
0397     if (fs_0.firstStrip + fs_0.range >= fs_1.firstStrip + fs_1.range) {
0398       // fs_0 includes fs_1, go ahead
0399     } else if (fs_0.firstStrip + fs_0.range >= fs_1.firstStrip) {
0400       // contiguous or superimposed intervals
0401       // Check if at the module end
0402       if (fs_1.firstStrip + fs_1.range >= Nstrips) {
0403         vect.push_back(encode(fs_0.firstStrip, Nstrips - fs_0.firstStrip));
0404         return;
0405       } else {
0406         // create new fs_0
0407         fs_0.range = fs_1.firstStrip + fs_1.range - fs_0.firstStrip;
0408       }
0409     } else {
0410       // separated intervals
0411       vect.push_back(encode(fs_0.firstStrip, fs_0.range));
0412       fs_0 = fs_1;
0413     }
0414   }
0415   vect.push_back(encode(fs_0.firstStrip, fs_0.range));
0416 }
0417 
0418 void SiStripQuality::subtract(std::vector<unsigned int> &A, const std::vector<unsigned int> &B) {
0419   ContainerIterator it = B.begin();
0420   ContainerIterator itend = B.end();
0421   for (; it != itend; ++it) {
0422     subtraction(A, *it);
0423   }
0424 }
0425 
0426 void SiStripQuality::subtraction(std::vector<unsigned int> &A, const unsigned int &B) {
0427   SiStripBadStrip::data fs_A, fs_B, fs_m, fs_M;
0428   std::vector<unsigned int> tmp;
0429 
0430   fs_B = decode(B);
0431   ContainerIterator jt = A.begin();
0432   ContainerIterator jtend = A.end();
0433   for (; jt != jtend; ++jt) {
0434     fs_A = decode(*jt);
0435     if (B < *jt) {
0436       fs_m = fs_B;
0437       fs_M = fs_A;
0438     } else {
0439       fs_m = fs_A;
0440       fs_M = fs_B;
0441     }
0442     // A) Verify the range to be subtracted crosses the new range
0443     if (fs_m.firstStrip + fs_m.range > fs_M.firstStrip) {
0444       if (*jt < B) {
0445         tmp.push_back(encode(fs_A.firstStrip, fs_B.firstStrip - fs_A.firstStrip));
0446       }
0447       if (fs_A.firstStrip + fs_A.range > fs_B.firstStrip + fs_B.range) {
0448         tmp.push_back(
0449             encode(fs_B.firstStrip + fs_B.range, fs_A.firstStrip + fs_A.range - (fs_B.firstStrip + fs_B.range)));
0450       }
0451     } else {
0452       tmp.push_back(*jt);
0453     }
0454   }
0455   A = tmp;
0456 }
0457 
0458 bool SiStripQuality::cleanUp(bool force) {
0459   if (!toCleanUp && !force)
0460     return false;
0461 
0462   toCleanUp = false;
0463 
0464   std::vector<unsigned int> v_badstrips_tmp = v_badstrips;
0465   std::vector<DetRegistry> indexes_tmp = indexes;
0466 
0467   LogTrace("SiStripQuality") << "[SiStripQuality::cleanUp] before cleanUp v_badstrips.size()= " << v_badstrips.size()
0468                              << " indexes.size()=" << indexes.size() << std::endl;
0469 
0470   v_badstrips.clear();
0471   indexes.clear();
0472 
0473   SiStripBadStrip::RegistryIterator basebegin = indexes_tmp.begin();
0474   SiStripBadStrip::RegistryIterator baseend = indexes_tmp.end();
0475 
0476   for (SiStripBadStrip::RegistryIterator basep = basebegin; basep != baseend; ++basep) {
0477     if (basep->ibegin != basep->iend) {
0478       SiStripBadStrip::Range range(v_badstrips_tmp.begin() + basep->ibegin, v_badstrips_tmp.begin() + basep->iend);
0479       if (!put(basep->detid, range))
0480         edm::LogError("SiStripQuality") << "[" << __PRETTY_FUNCTION__ << "] " << std::endl;
0481     }
0482   }
0483 
0484   LogTrace("SiStripQuality") << "[SiStripQuality::cleanUp] after cleanUp v_badstrips.size()= " << v_badstrips.size()
0485                              << " indexes.size()=" << indexes.size() << std::endl;
0486   return true;
0487 }
0488 
0489 void SiStripQuality::fillBadComponents() {
0490   BadComponentVect.clear();
0491 
0492   for (SiStripBadStrip::RegistryIterator basep = indexes.begin(); basep != indexes.end(); ++basep) {
0493     SiStripBadStrip::Range range(v_badstrips.begin() + basep->ibegin, v_badstrips.begin() + basep->iend);
0494 
0495     // Fill BadModules, BadFibers, BadApvs vectors
0496     unsigned short resultA = 0, resultF = 0;
0497     BadComponent result;
0498 
0499     SiStripBadStrip::data fs;
0500     unsigned short Nstrips = info_.getNumberOfApvsAndStripLength(basep->detid).first * 128;
0501 
0502     // BadModules
0503     fs = decode(*(range.first));
0504     if (basep->iend - basep->ibegin == 1 && fs.firstStrip == 0 && fs.range == Nstrips) {
0505       result.detid = basep->detid;
0506       result.BadModule = true;
0507       result.BadFibers = (1 << (Nstrips / 256)) - 1;
0508       result.BadApvs = (1 << (Nstrips / 128)) - 1;
0509 
0510       BadComponentVect.push_back(result);
0511 
0512     } else {
0513       // Bad Fibers and  Apvs
0514       for (SiStripBadStrip::ContainerIterator it = range.first; it != range.second; ++it) {
0515         fs = decode(*it);
0516 
0517         // BadApvs
0518         for (short apvNb = 0; apvNb < 6; ++apvNb) {
0519           if (fs.firstStrip <= apvNb * 128 && (apvNb + 1) * 128 <= fs.firstStrip + fs.range) {
0520             resultA = resultA | (1 << apvNb);
0521           }
0522         }
0523         // BadFibers
0524         for (short fiberNb = 0; fiberNb < 3; ++fiberNb) {
0525           if (fs.firstStrip <= fiberNb * 256 && (fiberNb + 1) * 256 <= fs.firstStrip + fs.range) {
0526             resultF = resultF | (1 << fiberNb);
0527           }
0528         }
0529       }
0530       if (resultA != 0) {
0531         result.detid = basep->detid;
0532         result.BadModule = false;
0533         result.BadFibers = resultF;
0534         result.BadApvs = resultA;
0535         BadComponentVect.push_back(result);
0536       }
0537     }
0538   }
0539 }
0540 
0541 //--------------------------------------------------------------//
0542 
0543 bool SiStripQuality::IsModuleUsable(uint32_t detid) const {
0544   std::vector<BadComponent>::const_iterator p = std::lower_bound(
0545       BadComponentVect.begin(), BadComponentVect.end(), detid, SiStripQuality::BadComponentStrictWeakOrdering());
0546   if (p != BadComponentVect.end() && p->detid == detid)
0547     if (p->BadModule)
0548       return false;
0549 
0550   if (SiStripDetCabling_ != nullptr)
0551     if (!SiStripDetCabling_->IsConnected(detid))
0552       return false;
0553 
0554   return true;
0555 }
0556 
0557 bool SiStripQuality::IsModuleBad(uint32_t detid) const {
0558   std::vector<BadComponent>::const_iterator p = std::lower_bound(
0559       BadComponentVect.begin(), BadComponentVect.end(), detid, SiStripQuality::BadComponentStrictWeakOrdering());
0560   if (p != BadComponentVect.end() && p->detid == detid)
0561     return p->BadModule;
0562   return false;
0563 }
0564 
0565 bool SiStripQuality::IsFiberBad(uint32_t detid, short fiberNb) const {
0566   std::vector<BadComponent>::const_iterator p = std::lower_bound(
0567       BadComponentVect.begin(), BadComponentVect.end(), detid, SiStripQuality::BadComponentStrictWeakOrdering());
0568   if (p != BadComponentVect.end() && p->detid == detid)
0569     return ((p->BadFibers >> fiberNb) & 0x1);
0570   return false;
0571 }
0572 
0573 bool SiStripQuality::IsApvBad(uint32_t detid, short apvNb) const {
0574   std::vector<BadComponent>::const_iterator p = std::lower_bound(
0575       BadComponentVect.begin(), BadComponentVect.end(), detid, SiStripQuality::BadComponentStrictWeakOrdering());
0576   if (p != BadComponentVect.end() && p->detid == detid)
0577     return ((p->BadApvs >> apvNb) & 0x1);
0578   return false;
0579 }
0580 
0581 bool SiStripQuality::IsStripBad(uint32_t detid, short strip) const {
0582   SiStripBadStrip::Range range = getRange(detid);
0583   return IsStripBad(range, strip);
0584 }
0585 
0586 bool SiStripQuality::IsStripBad(const Range &range, short strip) const {
0587   bool result = false;
0588   SiStripBadStrip::data fs;
0589   for (SiStripBadStrip::ContainerIterator it = range.first; it != range.second; ++it) {
0590     fs = decode(*it);
0591     if ((fs.firstStrip <= strip) & (strip < fs.firstStrip + fs.range)) {
0592       result = true;
0593       break;
0594     }
0595   }
0596   return result;
0597 }
0598 
0599 int SiStripQuality::nBadStripsOnTheLeft(const Range &range, short strip) const {
0600   int result = 0;
0601   SiStripBadStrip::data fs;
0602   for (SiStripBadStrip::ContainerIterator it = range.first; it != range.second; ++it) {
0603     fs = decode(*it);
0604     if (fs.firstStrip <= strip && strip < fs.firstStrip + fs.range) {
0605       result = strip - fs.firstStrip + 1;
0606       break;
0607     }
0608   }
0609   return result;
0610 }
0611 
0612 int SiStripQuality::nBadStripsOnTheRight(const Range &range, short strip) const {
0613   int result = 0;
0614   SiStripBadStrip::data fs;
0615   for (SiStripBadStrip::ContainerIterator it = range.first; it != range.second; ++it) {
0616     fs = decode(*it);
0617     if (fs.firstStrip <= strip && strip < fs.firstStrip + fs.range) {
0618       result = fs.firstStrip + fs.range - strip;
0619       break;
0620     }
0621   }
0622   return result;
0623 }
0624 
0625 short SiStripQuality::getBadApvs(uint32_t detid) const {
0626   std::vector<BadComponent>::const_iterator p = std::lower_bound(
0627       BadComponentVect.begin(), BadComponentVect.end(), detid, SiStripQuality::BadComponentStrictWeakOrdering());
0628   if (p != BadComponentVect.end() && p->detid == detid)
0629     return p->BadApvs;
0630   return 0;
0631 }
0632 
0633 short SiStripQuality::getBadFibers(uint32_t detid) const {
0634   std::vector<BadComponent>::const_iterator p = std::lower_bound(
0635       BadComponentVect.begin(), BadComponentVect.end(), detid, SiStripQuality::BadComponentStrictWeakOrdering());
0636   if (p != BadComponentVect.end() && p->detid == detid)
0637     return p->BadFibers;
0638   return 0;
0639 }
0640 
0641 void SiStripQuality::printDetInfo(const TrackerTopology *const tTopo,
0642                                   uint32_t detId,
0643                                   uint32_t apvPairNumber,
0644                                   std::stringstream &ss) {
0645   std::string subDetName;
0646   DetId detid(detId);
0647   int layer = tTopo->layer(detid);
0648   int stereo = 0;
0649   switch (detid.subdetId()) {
0650     case StripSubdetector::TIB: {
0651       stereo = tTopo->tibIsStereo(detid);
0652       subDetName = "TIB";
0653       break;
0654     }
0655     case StripSubdetector::TOB: {
0656       stereo = tTopo->tobIsStereo(detid);
0657       subDetName = "TOB";
0658       break;
0659     }
0660     case StripSubdetector::TEC: {
0661       stereo = tTopo->tecIsStereo(detid);
0662       subDetName = "TEC";
0663       break;
0664     }
0665     case StripSubdetector::TID: {
0666       stereo = tTopo->tidIsStereo(detid);
0667       subDetName = "TID";
0668       break;
0669     }
0670   }
0671   ss << detId << " and apv = " << apvPairNumber << " of subDet = " << subDetName << ", layer = " << layer
0672      << " stereo = " << stereo << std::endl;
0673 }
0674 
0675 void SiStripQuality::printActiveFedsInfo(const std::vector<uint16_t> &activeFedsFromCabling,
0676                                          const std::vector<int> &activeFedsFromRunInfo,
0677                                          const std::vector<int> &differentFeds,
0678                                          const bool printDebug) {
0679   std::ostringstream ss;
0680 
0681   if (printDebug) {
0682     ss << "activeFedsFromCabling:" << std::endl;
0683     std::copy(activeFedsFromCabling.begin(), activeFedsFromCabling.end(), std::ostream_iterator<uint16_t>(ss, " "));
0684     ss << std::endl;
0685     ss << "activeFedsFromRunInfo:" << std::endl;
0686     std::copy(activeFedsFromRunInfo.begin(), activeFedsFromRunInfo.end(), std::ostream_iterator<int>(ss, " "));
0687     ss << std::endl;
0688   }
0689   if (differentFeds.size() != 440) {
0690     ss << "differentFeds : " << std::endl;
0691     std::copy(differentFeds.begin(), differentFeds.end(), std::ostream_iterator<int>(ss, " "));
0692     ss << std::endl;
0693   } else {
0694     ss << "There are 440 feds (all) active for Cabling but off for RunInfo. "
0695           "Tracker was probably not in this run"
0696        << std::endl;
0697   }
0698   edm::LogInfo("SiStripQuality") << ss.str() << std::endl;
0699 }
0700 
0701 void SiStripQuality::turnOffFeds(const std::vector<int> &fedsList, const bool turnOffStrips, const bool printDebug) {
0702   std::stringstream ss;
0703   if (printDebug) {
0704     ss << "associated to detIds : " << std::endl;
0705   }
0706 
0707   std::vector<int>::const_iterator fedIdIt = fedsList.begin();
0708   for (; fedIdIt != fedsList.end(); ++fedIdIt) {
0709     std::vector<FedChannelConnection>::const_iterator fedChIt =
0710         SiStripDetCabling_->fedCabling()->fedConnections(*fedIdIt).begin();
0711     for (; fedChIt != SiStripDetCabling_->fedCabling()->fedConnections(*fedIdIt).end(); ++fedChIt) {
0712       uint32_t detId = fedChIt->detId();
0713       if (detId == 0 || detId == 0xFFFFFFFF)
0714         continue;
0715       uint16_t apvPairNumber = fedChIt->apvPairNumber();
0716 
0717       if (printDebug) {
0718         printDetInfo(SiStripDetCabling_->trackerTopology(), detId, apvPairNumber, ss);
0719       }
0720 
0721       if (turnOffStrips) {
0722         // apvPairNumber == i it means that the i*256 strips are to be set off
0723         std::vector<unsigned int> vect;
0724         vect.push_back(encode(apvPairNumber * 256, 256));
0725         SiStripBadStrip::Range Range(vect.begin(), vect.end());
0726         add(detId, Range);
0727         LogTrace("SiStripQuality") << "[addOffForRunInfo] adding apvPairNumber " << apvPairNumber << " for detId "
0728                                    << detId << " off according to RunInfo" << std::endl;
0729       }
0730     }
0731   }
0732   if (printDebug) {
0733     edm::LogInfo("SiStripQuality") << ss.str() << std::endl;
0734   }
0735 }