Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-05 04:10:01

0001 
0002 #include "OnlineDB/SiStripESSources/interface/SiStripCondObjBuilderFromDb.h"
0003 #include "OnlineDB/SiStripESSources/interface/SiStripFedCablingBuilderFromDb.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "DataFormats/SiStripCommon/interface/SiStripFecKey.h"
0006 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
0007 #include "CondFormats/SiStripObjects/interface/SiStripPedestals.h"
0008 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
0009 #include "CondFormats/SiStripObjects/interface/SiStripThreshold.h"
0010 #include "CondFormats/SiStripObjects/interface/SiStripApvGain.h"
0011 #include "CondFormats/SiStripObjects/interface/SiStripLatency.h"
0012 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0013 #include "CondFormats/SiStripObjects/interface/FedChannelConnection.h"
0014 #include "CalibFormats/SiStripObjects/interface/SiStripFecCabling.h"
0015 #include "CalibFormats/SiStripObjects/interface/SiStripDetCabling.h"
0016 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0017 #include "CalibFormats/SiStripObjects/interface/SiStripQuality.h"
0018 #include "CalibTracker/SiStripCommon/interface/SiStripDetInfoFileReader.h"
0019 
0020 #include <cstdlib>
0021 #include <iostream>
0022 #include <sstream>
0023 #include <iomanip>
0024 #include "Fed9UUtils.hh"
0025 
0026 using namespace std;
0027 using namespace sistrip;
0028 
0029 // -----------------------------------------------------------------------------
0030 /** */
0031 SiStripCondObjBuilderFromDb::SiStripCondObjBuilderFromDb(const edm::ParameterSet& pset, const edm::ActivityRegistry&)
0032     : m_skippedDevices(pset.getUntrackedParameter<edm::VParameterSet>("SkippedDevices", edm::VParameterSet())),
0033       m_whitelistedDevices(pset.getUntrackedParameter<edm::VParameterSet>("WhitelistedDevices", edm::VParameterSet())),
0034       m_tickmarkThreshold(static_cast<float>(pset.getUntrackedParameter<double>("TickmarkThreshold", 50.))),
0035       m_gaincalibrationfactor(static_cast<float>(pset.getUntrackedParameter<double>("GainNormalizationFactor", 640.))),
0036       m_defaultpedestalvalue(static_cast<float>(pset.getUntrackedParameter<double>("DefaultPedestal", 0.))),
0037       m_defaultnoisevalue(static_cast<float>(pset.getUntrackedParameter<double>("DefaultNoise", 0.))),
0038       m_defaultthresholdhighvalue(static_cast<float>(pset.getUntrackedParameter<double>("DefaultThresholdHigh", 0.))),
0039       m_defaultthresholdlowvalue(static_cast<float>(pset.getUntrackedParameter<double>("DefaultThresholdLow", 0.))),
0040       m_defaultapvmodevalue(static_cast<uint16_t>(pset.getUntrackedParameter<uint32_t>("DefaultAPVMode", 37))),
0041       m_defaultapvlatencyvalue(static_cast<uint16_t>(pset.getUntrackedParameter<uint32_t>("DefaultAPVLatency", 142))),
0042       m_defaulttickheightvalue(static_cast<float>(pset.getUntrackedParameter<double>("DefaultTickHeight", 690.))),
0043       m_useanalysis(static_cast<bool>(pset.getUntrackedParameter<bool>("UseAnalysis", false))),
0044       m_usefed(static_cast<bool>(pset.getUntrackedParameter<bool>("UseFED", false))),
0045       m_usefec(static_cast<bool>(pset.getUntrackedParameter<bool>("UseFEC", false))),
0046       m_debug(static_cast<bool>(pset.getUntrackedParameter<bool>("DebugMode", false))),
0047       m_detInfo(SiStripDetInfoFileReader::read(pset.getParameter<edm::FileInPath>("SiStripDetInfoFile").fullPath())),
0048       tTopo(buildTrackerTopology()) {
0049   LogTrace(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0050                          << " Constructing object...";
0051   for (const auto& pset : m_skippedDevices) {
0052     skippedDevices.emplace_back(pset);
0053   }
0054   for (const auto& pset : m_whitelistedDevices) {
0055     whitelistedDevices.emplace_back(pset);
0056   }
0057 }
0058 
0059 // -----------------------------------------------------------------------------
0060 /** */
0061 SiStripCondObjBuilderFromDb::SiStripCondObjBuilderFromDb() : tTopo(buildTrackerTopology()) {
0062   LogTrace(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0063                          << " Constructing object...";
0064 }
0065 
0066 // -----------------------------------------------------------------------------
0067 /** */
0068 SiStripCondObjBuilderFromDb::~SiStripCondObjBuilderFromDb() {
0069   LogTrace(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0070                          << " Destructing object...";
0071   delete tTopo;
0072 }
0073 
0074 // -----------------------------------------------------------------------------
0075 
0076 /** */
0077 void SiStripCondObjBuilderFromDb::checkUpdate() {
0078   if (!(dbParams_ == dbParams())) {
0079     dbParams_ = dbParams();
0080     buildCondObj();
0081   }
0082 }
0083 // -----------------------------------------------------------------------------
0084 TrackerTopology* SiStripCondObjBuilderFromDb::buildTrackerTopology() {
0085   TrackerTopology::PixelBarrelValues pxbVals_;
0086   TrackerTopology::PixelEndcapValues pxfVals_;
0087   TrackerTopology::TECValues tecVals_;
0088   TrackerTopology::TIBValues tibVals_;
0089   TrackerTopology::TIDValues tidVals_;
0090   TrackerTopology::TOBValues tobVals_;
0091 
0092   pxbVals_.layerStartBit_ = 16;
0093   pxbVals_.ladderStartBit_ = 8;
0094   pxbVals_.moduleStartBit_ = 2;
0095   pxbVals_.layerMask_ = 0xF;
0096   pxbVals_.ladderMask_ = 0xFF;
0097   pxbVals_.moduleMask_ = 0x3F;
0098   pxfVals_.sideStartBit_ = 23;
0099   pxfVals_.diskStartBit_ = 16;
0100   pxfVals_.bladeStartBit_ = 10;
0101   pxfVals_.panelStartBit_ = 8;
0102   pxfVals_.moduleStartBit_ = 2;
0103   pxfVals_.sideMask_ = 0x3;
0104   pxfVals_.diskMask_ = 0xF;
0105   pxfVals_.bladeMask_ = 0x3F;
0106   pxfVals_.panelMask_ = 0x3;
0107   pxfVals_.moduleMask_ = 0x3F;
0108   tecVals_.sideStartBit_ = 18;
0109   tecVals_.wheelStartBit_ = 14;
0110   tecVals_.petal_fw_bwStartBit_ = 12;
0111   tecVals_.petalStartBit_ = 8;
0112   tecVals_.ringStartBit_ = 5;
0113   tecVals_.moduleStartBit_ = 2;
0114   tecVals_.sterStartBit_ = 0;
0115   tecVals_.sideMask_ = 0x3;
0116   tecVals_.wheelMask_ = 0xF;
0117   tecVals_.petal_fw_bwMask_ = 0x3;
0118   tecVals_.petalMask_ = 0xF;
0119   tecVals_.ringMask_ = 0x7;
0120   tecVals_.moduleMask_ = 0x7;
0121   tecVals_.sterMask_ = 0x3;
0122   tibVals_.layerStartBit_ = 14;
0123   tibVals_.str_fw_bwStartBit_ = 12;
0124   tibVals_.str_int_extStartBit_ = 10;
0125   tibVals_.strStartBit_ = 4;
0126   tibVals_.moduleStartBit_ = 2;
0127   tibVals_.sterStartBit_ = 0;
0128   tibVals_.layerMask_ = 0x7;
0129   tibVals_.str_fw_bwMask_ = 0x3;
0130   tibVals_.str_int_extMask_ = 0x3;
0131   tibVals_.strMask_ = 0x3F;
0132   tibVals_.moduleMask_ = 0x3;
0133   tibVals_.sterMask_ = 0x3;
0134   tidVals_.sideStartBit_ = 13;
0135   tidVals_.wheelStartBit_ = 11;
0136   tidVals_.ringStartBit_ = 9;
0137   tidVals_.module_fw_bwStartBit_ = 7;
0138   tidVals_.moduleStartBit_ = 2;
0139   tidVals_.sterStartBit_ = 0;
0140   tidVals_.sideMask_ = 0x3;
0141   tidVals_.wheelMask_ = 0x3;
0142   tidVals_.ringMask_ = 0x3;
0143   tidVals_.module_fw_bwMask_ = 0x3;
0144   tidVals_.moduleMask_ = 0x1F;
0145   tidVals_.sterMask_ = 0x3;
0146   tobVals_.layerStartBit_ = 14;
0147   tobVals_.rod_fw_bwStartBit_ = 12;
0148   tobVals_.rodStartBit_ = 5;
0149   tobVals_.moduleStartBit_ = 2;
0150   tobVals_.sterStartBit_ = 0;
0151   tobVals_.layerMask_ = 0x7;
0152   tobVals_.rod_fw_bwMask_ = 0x3;
0153   tobVals_.rodMask_ = 0x7F;
0154   tobVals_.moduleMask_ = 0x7;
0155   tobVals_.sterMask_ = 0x3;
0156 
0157   return new TrackerTopology(pxbVals_, pxfVals_, tecVals_, tibVals_, tidVals_, tobVals_);
0158 }
0159 // -----------------------------------------------------------------------------
0160 /** */
0161 bool SiStripCondObjBuilderFromDb::checkForCompatibility(std::stringstream& input,
0162                                                         std::stringstream& output,
0163                                                         std::string& label) {
0164   // DEPRECATED. Superseded by SiStripCondObjBuilderFromDb::getConfigString(const std::type_info& typeInfo).
0165 
0166   //get current config DB parameter
0167 
0168   SiStripDbParams::const_iterator_range partitionsRange = dbParams().partitions();
0169 
0170   SiStripDbParams::SiStripPartitions::const_iterator ipart = partitionsRange.begin();
0171   SiStripDbParams::SiStripPartitions::const_iterator ipartEnd = partitionsRange.end();
0172   for (; ipart != ipartEnd; ++ipart) {
0173     SiStripPartition partition = ipart->second;
0174     output << "@ "
0175            << " Partition " << partition.partitionName();
0176     if (label != "Cabling" && label != "ApvLatency")
0177       output << " FedVer " << partition.fedVersion().first << "." << partition.fedVersion().second;
0178     if (label == "Cabling")
0179       output << " CabVer " << partition.cabVersion().first << "." << partition.cabVersion().second << " MaskVer "
0180              << partition.maskVersion().first << "." << partition.maskVersion().second;
0181     if (label == "ApvTiming")
0182       output << " ApvTimingVer " << partition.apvTimingVersion().first << "." << partition.apvTimingVersion().second;
0183     if (label == "ApvLatency")
0184       output << " FecVersion " << partition.fecVersion().first << "." << partition.fecVersion().second;
0185   }
0186 
0187   if (!strcmp(output.str().c_str(), input.str().c_str()))
0188     return false;
0189 
0190   return true;
0191 }
0192 // -----------------------------------------------------------------------------
0193 /** */
0194 std::string SiStripCondObjBuilderFromDb::getConfigString(const std::type_info& typeInfo) {
0195   // create config line used by fast O2O
0196 
0197   std::stringstream output;
0198 
0199   SiStripDbParams::const_iterator_range partitionsRange = dbParams().partitions();
0200   SiStripDbParams::SiStripPartitions::const_iterator ipart = partitionsRange.begin();
0201   SiStripDbParams::SiStripPartitions::const_iterator ipartEnd = partitionsRange.end();
0202   for (; ipart != ipartEnd; ++ipart) {
0203     SiStripPartition partition = ipart->second;
0204     output << "%%"
0205            << "Partition: " << partition.partitionName();
0206 
0207     // Make everything depend on cabVersion and maskVersion!
0208     output << " CablingVersion: " << partition.cabVersion().first << "." << partition.cabVersion().second;
0209     output << " MaskVersion: " << partition.maskVersion().first << "." << partition.maskVersion().second;
0210 
0211     if (typeInfo == typeid(SiStripFedCabling)) {
0212       // Do nothing. FedCabling only depends on cabVersion and maskVersion.
0213     } else if (typeInfo == typeid(SiStripLatency)) {
0214       // Latency is FEC related, add fecVersion.
0215       output << " FecVersion: " << partition.fecVersion().first << "." << partition.fecVersion().second;
0216     } else {
0217       // BadStrip, Noises, Pedestals and Thresholds are FED related, add fecVersion.
0218       output << " FedVersion: " << partition.fedVersion().first << "." << partition.fedVersion().second;
0219       if (typeInfo == typeid(SiStripApvGain)) {
0220         // Not used in O2O.
0221         output << " ApvTimingVersion: " << partition.apvTimingVersion().first << "."
0222                << partition.apvTimingVersion().second;
0223       }
0224     }
0225   }
0226 
0227   return output.str();
0228 }
0229 // -----------------------------------------------------------------------------
0230 /** */
0231 void SiStripCondObjBuilderFromDb::buildCondObj() {
0232   LogTrace(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]";
0233 
0234   // Check if DB connection is made
0235   if (db_) {
0236     // Check if DB connection is made
0237     if (db_->deviceFactory() || db_->databaseCache()) {
0238       // Build FEC cabling object
0239       SiStripFecCabling fec_cabling;
0240 
0241       SiStripFedCablingBuilderFromDb::buildFecCabling(&*db_, fec_cabling, sistrip::CABLING_FROM_CONNS);
0242       fed_cabling_ = new SiStripFedCabling;
0243 
0244       SiStripFedCablingBuilderFromDb::getFedCabling(fec_cabling, *fed_cabling_);
0245       SiStripDetCabling det_cabling(*fed_cabling_, tTopo);
0246       buildStripRelatedObjects(&*db_, det_cabling);
0247 
0248       if (m_useanalysis)
0249         buildAnalysisRelatedObjects(&*db_, v_trackercon);
0250       if (m_usefed)
0251         buildFEDRelatedObjects(&*db_, v_trackercon);
0252       if (m_usefec)
0253         buildFECRelatedObjects(&*db_, v_trackercon);
0254 
0255     } else {
0256       edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0257                                     << " NULL pointer to DeviceFactory returned by SiStripConfigDb!"
0258                                     << " Cannot build Pedestals object!";
0259     }
0260   } else {
0261     edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0262                                   << " NULL pointer to SiStripConfigDb returned by DB \"service\"!"
0263                                   << " Cannot build Pedestals object!";
0264   }
0265 }
0266 
0267 // -----------------------------------------------------------------------------
0268 /** */
0269 //Retrieve FedDescriptions from configuration database
0270 bool SiStripCondObjBuilderFromDb::retrieveFedDescriptions(SiStripConfigDb* const db) {
0271   SiStripConfigDb::FedDescriptionsRange descriptions = db->getFedDescriptions();
0272   if (descriptions.empty()) {
0273     edm::LogWarning(mlESSources_) << "SiStripCondObjBuilderFromDb::" << __func__ << "]"
0274                                   << " No FED descriptions found!";
0275 
0276     return false;
0277   }
0278   return true;
0279 }
0280 
0281 // -----------------------------------------------------------------------------
0282 /** */
0283 // Retrieve gain from configuration database
0284 bool SiStripCondObjBuilderFromDb::retrieveTimingAnalysisDescriptions(SiStripConfigDb* const db) {
0285   SiStripConfigDb::AnalysisDescriptionsRange anal_descriptions =
0286       db->getAnalysisDescriptions(CommissioningAnalysisDescription::T_ANALYSIS_TIMING);
0287   if (anal_descriptions.empty()) {
0288     edm::LogWarning(mlESSources_) << "SiStripCondObjBuilderFromDb::" << __func__ << "]"
0289                                   << " Unable to build SiStripApvGain object!"
0290                                   << " No timing-scan analysis descriptions found!";
0291     return false;
0292   }
0293   return true;
0294 }
0295 
0296 // -----------------------------------------------------------------------------
0297 /** */
0298 // Retrieve list of active DetIds
0299 vector<uint32_t> SiStripCondObjBuilderFromDb::retrieveActiveDetIds(const SiStripDetCabling& det_cabling) {
0300   vector<uint32_t> det_ids;
0301   det_cabling.addActiveDetectorsRawIds(det_ids);
0302   if (det_ids.empty()) {
0303     edm::LogWarning(mlESSources_) << "SiStripCondObjBuilderFromDb::" << __func__ << "]"
0304                                   << " Unable to build Pedestals object!"
0305                                   << " No DetIds found!";
0306     return det_ids;
0307   }
0308   LogTrace(mlESSources_) << "\n\nSiStripCondObjBuilderFromDb::" << __func__ << "]"
0309                          << " Found " << det_ids.size() << " active DetIds";
0310   return det_ids;
0311 }
0312 
0313 // -----------------------------------------------------------------------------
0314 /** */
0315 //build connections per DetId
0316 vector<const FedChannelConnection*> SiStripCondObjBuilderFromDb::buildConnections(const SiStripDetCabling& det_cabling,
0317                                                                                   uint32_t det_id) {
0318   vector<const FedChannelConnection*> conns = det_cabling.getConnections(det_id);
0319   if (conns.empty()) {
0320     edm::LogWarning(mlESSources_) << "SiStripCondObjBuilderFromDb::" << __func__ << "]"
0321                                   << " Unable to build condition object!"
0322                                   << " No FED channel connections found for detid " << det_id;
0323   }
0324   return conns;
0325 }
0326 
0327 // -----------------------------------------------------------------------------
0328 /** */
0329 //retrieve number of APV pairs per detid
0330 uint16_t SiStripCondObjBuilderFromDb::retrieveNumberAPVPairs(uint32_t det_id) {
0331   uint16_t nApvPairs;
0332   nApvPairs = m_detInfo.getNumberOfApvsAndStripLength(det_id).first / 2;
0333   return nApvPairs;
0334 }
0335 
0336 // -----------------------------------------------------------------------------
0337 /** */
0338 //set default values for Cabling Objects Peds, Noise, thresh, Quality
0339 void SiStripCondObjBuilderFromDb::setDefaultValuesCabling(uint16_t apvPair) {
0340   uint16_t istrip = apvPair * sistrip::STRIPS_PER_FEDCH;
0341   std::cout << "Found disabled FedConnection!  APVPair: " << apvPair << " Strips: " << sistrip::STRIPS_PER_FEDCH
0342             << std::endl;
0343   inputQuality.push_back(quality_->encode(istrip, sistrip::STRIPS_PER_FEDCH));
0344   for (; istrip < (apvPair + 1) * sistrip::STRIPS_PER_FEDCH; ++istrip) {
0345     pedestals_->setData(m_defaultpedestalvalue, inputPedestals);
0346     noises_->setData(m_defaultnoisevalue, inputNoises);
0347     threshold_->setData(istrip, m_defaultthresholdlowvalue, m_defaultthresholdhighvalue, inputThreshold);
0348   }
0349 }
0350 
0351 // -----------------------------------------------------------------------------
0352 /** */
0353 void SiStripCondObjBuilderFromDb::setDefaultValuesApvTiming(uint32_t detid, uint32_t apvPair) {
0354   float height = m_defaulttickheightvalue / m_gaincalibrationfactor;
0355 
0356   if (gain_last_) {
0357     auto range = gain_last_->getRange(detid);
0358     if (apvPair * 2 < range.second - range.first) {
0359       height = gain_last_->getApvGain(apvPair * 2, range);
0360       edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0361                                     << " [ApvGain] Read gain value from last IOV for DetId: " << detid
0362                                     << " ApvPair: " << apvPair << ", value=" << height;
0363     } else {
0364       edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0365                                     << " [ApvGain] Unable to read gain value from last IOV for DetId: " << detid
0366                                     << " ApvPair: " << apvPair << ", use dummy value=" << height;
0367     }
0368   } else {
0369     edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0370                                   << " [ApvGain] NULL pointer for last stored gain object in DB!!! "
0371                                   << "Will use dummy value=" << height << " for DetId: " << detid
0372                                   << " ApvPair: " << apvPair;
0373   }
0374 
0375   inputApvGain.push_back(height);  // APV0
0376   inputApvGain.push_back(height);  // APV1
0377 }
0378 
0379 // -----------------------------------------------------------------------------
0380 /** */
0381 void SiStripCondObjBuilderFromDb::setDefaultValuesApvLatency(SiStripLatency& latency_,
0382                                                              const FedChannelConnection& ipair,
0383                                                              uint32_t detid,
0384                                                              uint16_t apvnr) {
0385   std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]: Set Default Latency for Detid: " << detid
0386             << " ApvNr: " << apvnr << std::endl;
0387   if (!latency_.put(detid, apvnr, m_defaultapvmodevalue, m_defaultapvlatencyvalue)) {
0388     std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]: Unable to fill Latency for Detid: " << detid
0389               << " ApvNr: " << apvnr << std::endl;
0390   }
0391   if (!latency_.put(detid, ++apvnr, m_defaultapvmodevalue, m_defaultapvlatencyvalue)) {
0392     std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]: Unable to fill Latency for Detid: " << detid
0393               << " ApvNr: " << apvnr << std::endl;
0394   }
0395 }
0396 
0397 // -----------------------------------------------------------------------------
0398 /** */
0399 bool SiStripCondObjBuilderFromDb::setValuesApvTiming(SiStripConfigDb* const db, FedChannelConnection& ipair) {
0400   SiStripConfigDb::AnalysisDescriptionsRange anal_descriptions =
0401       db->getAnalysisDescriptions(CommissioningAnalysisDescription::T_ANALYSIS_TIMING);
0402   SiStripConfigDb::AnalysisDescriptionsV::const_iterator iii = anal_descriptions.begin();
0403   SiStripConfigDb::AnalysisDescriptionsV::const_iterator jjj = anal_descriptions.end();
0404 
0405   while (iii != jjj) {
0406     CommissioningAnalysisDescription* tmp = *iii;
0407     uint16_t fed_id = tmp->getFedId();
0408     uint16_t fed_ch = SiStripFedKey::fedCh(tmp->getFeUnit(), tmp->getFeChan());
0409     if (fed_id == ipair.fedId() && fed_ch == ipair.fedCh()) {
0410       break;
0411     }
0412     iii++;
0413   }
0414 
0415   TimingAnalysisDescription* anal = nullptr;
0416   if (iii != jjj) {
0417     anal = dynamic_cast<TimingAnalysisDescription*>(*iii);
0418   }
0419   if (!anal) {
0420     edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0421                                   << " [ApvGain] Unable to find Timing Analysis Description from DB for DetId: "
0422                                   << ipair.detId() << " ApvPair:" << ipair.apvPairNumber();
0423     return false;
0424   }
0425 
0426   bool is_whitelist = false;
0427   for (const auto& desc : whitelistedDevices) {
0428     if (desc.isConsistent(ipair)) {
0429       is_whitelist = true;
0430       if (std::find(whitelistedDetIds.begin(), whitelistedDetIds.end(), ipair.detId()) == whitelistedDetIds.end()) {
0431         whitelistedDetIds.push_back(ipair.detId());
0432       }
0433       break;
0434     }
0435   }
0436 
0437   if (!is_whitelist) {
0438     // check if this should be skipped only if it is not in the whitelist
0439     for (const auto& desc : skippedDevices) {
0440       if (desc.isConsistent(ipair)) {
0441         edm::LogInfo(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0442                                    << " [ApvGain] Skip module with DetId:" << ipair.detId()
0443                                    << " ApvPair:" << ipair.apvPairNumber() << " according to \n"
0444                                    << desc.dump();
0445         if (std::find(skippedDetIds.begin(), skippedDetIds.end(), ipair.detId()) == skippedDetIds.end()) {
0446           skippedDetIds.push_back(ipair.detId());
0447         }
0448         return false;
0449       }
0450     }
0451   }
0452 
0453   if (anal->getHeight() > m_tickmarkThreshold) {
0454     float tick_height = (anal->getHeight() / m_gaincalibrationfactor);
0455     inputApvGain.push_back(tick_height);  // APV0
0456     inputApvGain.push_back(tick_height);  // APV1
0457   } else {
0458     edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0459                                   << " [ApvGain] Low tickmark height for DetId:" << ipair.detId()
0460                                   << " ApvPair:" << ipair.apvPairNumber() << ", height=" << anal->getHeight();
0461     return false;
0462   }
0463 
0464   return true;
0465 }
0466 
0467 // -----------------------------------------------------------------------------
0468 /** */
0469 bool SiStripCondObjBuilderFromDb::setValuesApvLatency(SiStripLatency& latency_,
0470                                                       SiStripConfigDb* const db,
0471                                                       FedChannelConnection& ipair,
0472                                                       uint32_t detid,
0473                                                       uint16_t apvnr,
0474                                                       SiStripConfigDb::DeviceDescriptionsRange apvs) {
0475   m_detInfo.getNumberOfApvsAndStripLength(detid);
0476 
0477   SiStripConfigDb::DeviceDescriptionsV::const_iterator iapv = apvs.begin();
0478   SiStripConfigDb::DeviceDescriptionsV::const_iterator japv = apvs.end();
0479   if (iapv == japv)
0480     return false;
0481   for (; iapv != japv; ++iapv) {
0482     apvDescription* apv = dynamic_cast<apvDescription*>(*iapv);
0483     if (!apv) {
0484       continue;
0485     }
0486     if ((apv->getCrateId()) != (ipair.fecCrate()))
0487       continue;
0488     if ((apv->getFecSlot()) != (ipair.fecSlot()))
0489       continue;
0490     if ((apv->getRingSlot()) != (ipair.fecRing()))
0491       continue;
0492     if ((apv->getCcuAddress()) != (ipair.ccuAddr()))
0493       continue;
0494     if ((apv->getChannel()) != (ipair.ccuChan()))
0495       continue;
0496     // Insert latency values into latency object
0497     if ((apv->getAddress()) == (ipair.i2cAddr(0))) {
0498       if (!latency_.put(
0499               detid, apvnr, static_cast<uint16_t>(apv->getLatency()), static_cast<uint16_t>(apv->getApvMode()))) {
0500         std::cout << "UNABLE APVLatency Put: Detid " << dec << detid << " APVNr.: " << apvnr
0501                   << " Latency Value: " << dec << static_cast<uint16_t>(apv->getLatency()) << " APV Mode: " << dec
0502                   << static_cast<uint16_t>(apv->getApvMode()) << std::endl;
0503         return false;
0504       } else {
0505         ++apvnr;
0506       }
0507     }
0508     if ((apv->getAddress()) == (ipair.i2cAddr(1))) {
0509       if (!latency_.put(
0510               detid, apvnr, static_cast<uint16_t>(apv->getLatency()), static_cast<uint16_t>(apv->getApvMode()))) {
0511         std::cout << "UNABLE APVLatency Put: Detid " << dec << detid << " APVNr.: " << apvnr
0512                   << " Latency Value: " << dec << static_cast<uint16_t>(apv->getLatency()) << " APV Mode: " << dec
0513                   << static_cast<uint16_t>(apv->getApvMode()) << std::endl;
0514         continue;
0515         return false;
0516       } else {
0517         ++apvnr;
0518       }
0519     }
0520   }
0521   return true;
0522 }
0523 
0524 // -----------------------------------------------------------------------------
0525 /** */
0526 //bool SiStripCondObjBuilderFromDb::setValuesCabling(SiStripConfigDb* const db, FedChannelConnection &ipair, uint32_t detid){
0527 bool SiStripCondObjBuilderFromDb::setValuesCabling(SiStripConfigDb::FedDescriptionsRange& descriptions,
0528                                                    FedChannelConnection& ipair,
0529                                                    uint32_t detid) {
0530   //SiStripConfigDb::FedDescriptionsRange descriptions = db->getFedDescriptions();
0531   SiStripConfigDb::FedDescriptionsV::const_iterator description = descriptions.begin();
0532   while (description != descriptions.end()) {
0533     if ((*description)->getFedId() == ipair.fedId()) {
0534       break;
0535     }
0536     description++;
0537   }
0538   if (description == descriptions.end()) {
0539     return false;
0540   }
0541   // Retrieve Fed9UStrips object from FED description
0542   const Fed9U::Fed9UStrips& strips = (*description)->getFedStrips();
0543 
0544   // Retrieve StripDescriptions for each APV
0545   uint16_t jstrip = ipair.apvPairNumber() * sistrip::STRIPS_PER_FEDCH;
0546   for (uint16_t iapv = 2 * ipair.fedCh(); iapv < 2 * ipair.fedCh() + 2; iapv++) {
0547     // Get StripDescriptions for the given APV
0548     Fed9U::Fed9UAddress addr;
0549     addr.setFedApv(iapv);
0550     vector<Fed9U::Fed9UStripDescription> strip = strips.getApvStrips(addr);
0551 
0552     vector<Fed9U::Fed9UStripDescription>::const_iterator istrip = strip.begin();
0553 
0554     for (; istrip != strip.end(); istrip++) {
0555       pedestals_->setData(istrip->getPedestal(), inputPedestals);
0556       noises_->setData(istrip->getNoise(), inputNoises);
0557       threshold_->setData(jstrip, istrip->getLowThresholdFactor(), istrip->getHighThresholdFactor(), inputThreshold);
0558       if (istrip->getDisable()) {
0559         std::cout << "Found disabled strip! Detid: " << detid << " APVNr: " << iapv << " Strips: " << jstrip
0560                   << std::endl;
0561 
0562         inputQuality.push_back(quality_->encode(jstrip, 1));
0563       }
0564       jstrip++;
0565     }
0566   }
0567   return true;
0568 }
0569 
0570 // -----------------------------------------------------------------------------
0571 /** */
0572 //store objects
0573 void SiStripCondObjBuilderFromDb::storePedestals(uint32_t det_id) {
0574   if (!pedestals_->put(det_id, inputPedestals)) {
0575     std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0576               << " Unable to insert values into SiStripPedestals object!"
0577               << " DetId already exists!" << std::endl;
0578   }
0579   inputPedestals.clear();
0580 }
0581 
0582 // -----------------------------------------------------------------------------
0583 /** */
0584 void SiStripCondObjBuilderFromDb::storeNoise(uint32_t det_id) {
0585   // Insert noise values into Noises object
0586 
0587   if (!noises_->put(det_id, inputNoises)) {
0588     std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0589               << " Unable to insert values into SiStripNoises object!"
0590               << " DetId already exists!" << std::endl;
0591   }
0592   inputNoises.clear();
0593 }
0594 
0595 // -----------------------------------------------------------------------------
0596 /** */
0597 void SiStripCondObjBuilderFromDb::storeThreshold(uint32_t det_id) {
0598   // Insert threshold values into Threshold object
0599   if (!threshold_->put(det_id, inputThreshold)) {
0600     std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0601               << " Unable to insert values into SiStripThreshold object!"
0602               << " DetId already exists!" << std::endl;
0603   }
0604   inputThreshold.clear();
0605 }
0606 
0607 // -----------------------------------------------------------------------------
0608 /** */
0609 void SiStripCondObjBuilderFromDb::storeQuality(uint32_t det_id) {
0610   // Insert quality values into Quality object
0611   if (!inputQuality.empty()) {
0612     quality_->compact(det_id, inputQuality);
0613     if (!quality_->put(det_id, inputQuality)) {
0614       std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0615                 << " Unable to insert values into SiStripQuality object!"
0616                 << " DetId already exists!" << std::endl;
0617     }
0618   }
0619   inputQuality.clear();
0620 }
0621 
0622 // -----------------------------------------------------------------------------
0623 /** */
0624 void SiStripCondObjBuilderFromDb::storeTiming(uint32_t det_id) {
0625   // Insert tick height values into Gain object
0626   SiStripApvGain::Range range(inputApvGain.begin(), inputApvGain.end());
0627   if (!gain_->put(det_id, range)) {
0628     edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0629                                   << " [ApvGain] Unable to insert values into SiStripApvGain object!"
0630                                   << " DetId already exists!";
0631   }
0632   inputApvGain.clear();
0633 }
0634 
0635 // -----------------------------------------------------------------------------
0636 /** */
0637 void SiStripCondObjBuilderFromDb::buildStripRelatedObjects(SiStripConfigDb* const db,
0638                                                            const SiStripDetCabling& det_cabling) {
0639   //variables needed in this function
0640   uint16_t nApvPairs;
0641   vector<uint32_t>::const_iterator det_id;
0642   vector<uint32_t> det_ids;
0643 
0644   edm::LogInfo(mlESSources_) << "\n[SiStripCondObjBuilderFromDb::" << __func__ << "] first call to this method";
0645 
0646   //Check if FedDescriptions exist, if not return
0647   if (!retrieveFedDescriptions(db)) {
0648     std::cout << "Found no FedDescription!" << std::endl;
0649     return;
0650   }
0651   // Retrieve list of active DetIds
0652   det_cabling.addActiveDetectorsRawIds(det_ids);
0653   if (det_ids.empty()) {
0654     std::cout << "SiStripCondObjBuilderFromDb::" << __func__ << "]"
0655               << " Unable to build Pedestals object!"
0656               << " No DetIds found!" << std::endl;
0657     return;
0658   }
0659   std::cout << "\n\nSiStripCondObjBuilderFromDb::" << __func__ << "]"
0660             << " Found " << det_ids.size() << " active DetIds";
0661 
0662   // Loop Active DetIds
0663   det_id = det_ids.begin();
0664   for (; det_id != det_ids.end(); det_id++) {
0665     std::stringstream ssMessage;
0666 
0667     // Ignore NULL DetIds
0668     if (!(*det_id)) {
0669       continue;
0670     }
0671     if (*det_id == sistrip::invalid32_) {
0672       continue;
0673     }
0674 
0675     //build connections per DetId
0676     const vector<const FedChannelConnection*>& conns = buildConnections(det_cabling, *det_id);
0677 
0678     vector<const FedChannelConnection*>::const_iterator ipair = conns.begin();
0679     if (conns.empty())
0680       continue;
0681 
0682     //retrieve number of APV pairs per detid
0683     nApvPairs = retrieveNumberAPVPairs(*det_id);
0684 
0685     //loop connections and check if APVPair is connected
0686     vector<vector<const FedChannelConnection*>::const_iterator> listConns(nApvPairs, conns.end());
0687 
0688     for (; ipair != conns.end(); ++ipair) {
0689       // Check if the ApvPair is connected
0690       if (!(*ipair))
0691         continue;
0692       if ((*ipair)->fedId() != sistrip::invalid_ && (*ipair)->apvPairNumber() < 3) {
0693         // (*ipair)->print(ssMessage);
0694         // ssMessage<< std::endl;
0695         listConns[ipair - conns.begin()] = ipair;
0696       } else {
0697         std::cout << "\n impossible to assign connection position in listConns " << std::endl;
0698         // (*ipair)->print(ssMessage);
0699         // ssMessage << std::endl;
0700       }
0701     }
0702 
0703     // get data
0704     // vector< vector<const FedChannelConnection *>::const_iterator >::const_iterator ilistConns=listConns.begin();
0705     for (uint16_t apvPair = 0; apvPair < listConns.size(); ++apvPair) {
0706       ipair = listConns[apvPair];
0707       if (ipair == conns.end()) {
0708         // Fill object with default values
0709         std::cout << "\n "
0710                   << " Unable to find FED connection for detid : " << std::dec << *det_id << " APV pair number "
0711                   << apvPair << " Writing default values" << std::endl;
0712         //  (*ipair)->print(ssMessage); // this will crash!
0713         //If no connection was found, add 100 to apvpair
0714         apvPair += 100;
0715         std::cout << " Put apvPair+100:" << apvPair << " into vector!" << std::endl;
0716         // use dummy FedChannelConnection since it's not used in this case
0717         FedChannelConnection dummy;
0718         p_apvpcon = std::make_pair(apvPair, dummy);
0719         v_apvpcon.push_back(p_apvpcon);
0720         apvPair = apvPair - 100;
0721         continue;
0722       }
0723       p_apvpcon = std::make_pair(apvPair, **ipair);
0724       v_apvpcon.push_back(p_apvpcon);
0725     }  //conns loop
0726     p_detcon = std::make_pair(*det_id, v_apvpcon);
0727     v_trackercon.push_back(p_detcon);
0728     v_apvpcon.clear();
0729   }  // det id loop
0730 }
0731 
0732 // -----------------------------------------------------------------------------
0733 /** */
0734 void SiStripCondObjBuilderFromDb::buildAnalysisRelatedObjects(SiStripConfigDb* const db, const trackercon& _tc) {
0735   trackercon tc = _tc;
0736   std::cout << "Entering [SiStripCondObjBuilderFromDb::" << __func__ << "]" << std::endl;
0737   //data container
0738   gain_ = new SiStripApvGain();
0739 
0740   //check if Timing analysis description is found, otherwise quit
0741   if (!retrieveTimingAnalysisDescriptions(&*db_)) {
0742     edm::LogWarning(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0743                                   << " NULL pointer to AnalysisDescriptions returned by SiStripConfigDb!"
0744                                   << " Cannot build Analysis object! QUIT";
0745     throw cms::Exception("Cannot build Analysis object!");
0746   }
0747 
0748   // Get all detIds from the ideal geometry to build the payload
0749   for (const auto& it : m_detInfo.getAllData()) {
0750     // check if det id is correct and if it is actually cabled in the detector
0751     if (it.first == 0 || it.first == sistrip::invalid32_) {
0752       edm::LogError("DetIdNotGood") << "@SUB=analyze"
0753                                     << "Invalid detid: " << it.first << "  ... neglecting!" << std::endl;
0754       continue;
0755     }
0756 
0757     uint32_t detid = it.first;
0758     bool update_ = true;
0759     i_trackercon det_iter =
0760         std::find_if(tc.begin(), tc.end(), [detid](const pair_detcon& p) { return p.first == detid; });
0761     if (det_iter == tc.end()) {
0762       update_ = false;  // do not update if it is not connected in cabling
0763     }
0764 
0765     if (update_) {
0766       //loop connections
0767       for (i_apvpairconn connections = det_iter->second.begin(); connections != det_iter->second.end(); connections++) {
0768         uint32_t apvPair = (*connections).first;
0769         FedChannelConnection ipair = (*connections).second;
0770 
0771         //no connection for apvPair found
0772         if (apvPair >= 100) {
0773           setDefaultValuesApvTiming(detid, apvPair - 100);
0774           continue;
0775         }
0776 
0777         //fill data
0778         if (!setValuesApvTiming(db, ipair)) {
0779           // either not found in analysis table or low tickmark height
0780           setDefaultValuesApvTiming(detid, apvPair);
0781         }
0782       }  //connections
0783 
0784     } else {
0785       uint32_t nApvPairs = it.second.nApvs / 2;
0786       for (uint32_t apvPair = 0; apvPair < nApvPairs; ++apvPair) {
0787         setDefaultValuesApvTiming(detid, apvPair);
0788       }
0789     }
0790 
0791     storeTiming(detid);
0792 
0793   }  // end loop detids
0794 
0795   //print out skipped modules
0796   std::stringstream ss;
0797   for (const auto& id : whitelistedDetIds) {
0798     ss << "\n" << id;
0799   }
0800   edm::LogInfo(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0801                              << " [ApvGainSummary] " << whitelistedDetIds.size()
0802                              << " modules are in the whitelist, updates will be ensured: " << ss.str();
0803 
0804   ss.str("");  // clear it!
0805   for (const auto& skip : skippedDetIds) {
0806     ss << "\n" << skip;
0807   }
0808   edm::LogInfo(mlESSources_) << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0809                              << " [ApvGainSummary] Skipped " << skippedDetIds.size() << " modules: " << ss.str();
0810 }
0811 
0812 // -----------------------------------------------------------------------------
0813 /** */
0814 void SiStripCondObjBuilderFromDb::buildFECRelatedObjects(SiStripConfigDb* const db, const trackercon& _tc) {
0815   trackercon tc = _tc;
0816   std::cout << "Entering [SiStripCondObjBuilderFromDb::" << __func__ << "]" << std::endl;
0817   //data container
0818   latency_ = new SiStripLatency();
0819 
0820   i_trackercon detids_end = tc.end();
0821 
0822   // get APV DeviceDescriptions
0823   SiStripConfigDb::DeviceDescriptionsRange apvs = db->getDeviceDescriptions(APV25);
0824   ;
0825 
0826   //loop detids
0827   for (i_trackercon detids = tc.begin(); detids != detids_end; detids++) {
0828     uint32_t detid = (*detids).first;
0829     uint16_t apvnr = 1;
0830     i_apvpairconn connections_end = ((*detids).second).end();
0831 
0832     //loop connections
0833     for (i_apvpairconn connections = ((*detids).second).begin(); connections != connections_end; connections++) {
0834       uint32_t apvPair = (*connections).first;
0835       FedChannelConnection ipair = (*connections).second;
0836 
0837       //no connection for apvPair found
0838       if (apvPair >= 100) {
0839         //setDefaultValuesApvLatency((*latency_),ipair, detid, apvnr);
0840         std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "] No FEDConnection for DetId " << detid
0841                   << " ApvPair " << apvPair - 100 << " found, skipping Latency Insertion!" << std::endl;
0842         continue;
0843       }
0844 
0845       //fill data
0846       if (!setValuesApvLatency((*latency_), db, ipair, detid, apvnr, apvs)) {
0847         std::cout << "\n "
0848                   << " Unable to find FEC Description"
0849                   << " Skipping Insertion for DetId: " << detid << std::endl;
0850         //setDefaultValuesApvLatency((*latency_),ipair, detid, apvnr);
0851       }
0852       apvnr += 2;
0853     }  //connections
0854        // compact Latency Object
0855 
0856   }  //detids
0857   latency_->compress();
0858   std::stringstream ss;
0859   // latency debug output
0860   latency_->printSummary(ss, tTopo);
0861   latency_->printDebug(ss, tTopo);
0862   std::cout << ss.str() << std::endl;
0863 }
0864 
0865 // -----------------------------------------------------------------------------
0866 /** */
0867 void SiStripCondObjBuilderFromDb::buildFEDRelatedObjects(SiStripConfigDb* const db, const trackercon& _tc) {
0868   trackercon tc = _tc;
0869   std::cout << "Entering [SiStripCondObjBuilderFromDb::" << __func__ << "]" << std::endl;
0870 
0871   //data containers
0872   pedestals_ = new SiStripPedestals();
0873   noises_ = new SiStripNoises();
0874   threshold_ = new SiStripThreshold();
0875   quality_ = new SiStripQuality(m_detInfo);
0876 
0877   i_trackercon detids_end = tc.end();
0878 
0879   //Build FED Descriptions out of db object
0880   SiStripConfigDb::FedDescriptionsRange descriptions = db->getFedDescriptions();
0881 
0882   //loop detids
0883   for (i_trackercon detids = tc.begin(); detids != detids_end; detids++) {
0884     uint32_t detid = (*detids).first;
0885     i_apvpairconn connections_end = ((*detids).second).end();
0886 
0887     //loop connections
0888     for (i_apvpairconn connections = ((*detids).second).begin(); connections != connections_end; connections++) {
0889       uint32_t apvPair = (*connections).first;
0890       FedChannelConnection ipair = (*connections).second;
0891 
0892       //no connection for apvPair found
0893       if (apvPair >= 100) {
0894         std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0895                   << " Unable to find FED description for FED id: " << ipair.fedId() << " detid : " << detid
0896                   << " APV pair number " << apvPair << " Writing default values" << std::endl;
0897         setDefaultValuesCabling((apvPair - 100));
0898         continue;
0899       }
0900       //  if(!setValuesCabling(db, ipair, detid)){
0901       if (!setValuesCabling(descriptions, ipair, detid)) {
0902         std::cout << "[SiStripCondObjBuilderFromDb::" << __func__ << "]"
0903                   << " Unable to find FED description for FED id: " << ipair.fedId() << " detid : " << detid
0904                   << " APV pair number " << apvPair << " Writing default values" << std::endl;
0905         setDefaultValuesCabling(apvPair);
0906       }
0907     }  //connections
0908     storePedestals(detid);
0909     storeNoise(detid);
0910     storeThreshold(detid);
0911     storeQuality(detid);
0912   }  //detids
0913 }
0914 
0915 SiStripCondObjBuilderFromDb::SkipDeviceDescription::SkipDeviceDescription()
0916     : fec_(sistrip::invalid_), fed_(sistrip::invalid_), detid_(sistrip::invalid32_) {}
0917 
0918 SiStripCondObjBuilderFromDb::SkipDeviceDescription::SkipDeviceDescription(const edm::ParameterSet& pset)
0919     : fec_(pset.getUntrackedParameter<uint32_t>("fecCrate", sistrip::invalid_),
0920            pset.getUntrackedParameter<uint32_t>("fecSlot", sistrip::invalid_),
0921            pset.getUntrackedParameter<uint32_t>("fecRing", sistrip::invalid_),
0922            pset.getUntrackedParameter<uint32_t>("ccuAddr", sistrip::invalid_),
0923            pset.getUntrackedParameter<uint32_t>("ccuChan", sistrip::invalid_),
0924            pset.getUntrackedParameter<uint32_t>("lldChan", sistrip::invalid_),
0925            pset.getUntrackedParameter<uint32_t>("i2cAddr", sistrip::invalid_)),
0926       fed_(pset.getUntrackedParameter<uint32_t>("fedId", sistrip::invalid_),
0927            pset.getUntrackedParameter<uint32_t>("feUnit", sistrip::invalid_),
0928            pset.getUntrackedParameter<uint32_t>("feChan", sistrip::invalid_),
0929            pset.getUntrackedParameter<uint32_t>("fedApv", sistrip::invalid_)),
0930       detid_(pset.getUntrackedParameter<uint32_t>("detid", sistrip::invalid32_)) {
0931   if (!fec_.isValid() && !fed_.isValid() && detid_ == sistrip::invalid32_) {
0932     throw cms::Exception("InvalidPSet") << "None of FEC coordinates/FED coordinates/detids are valid in this PSet!\n"
0933                                         << pset.dump(2);
0934   }
0935 }
0936 
0937 bool SiStripCondObjBuilderFromDb::SkipDeviceDescription::isConsistent(const FedChannelConnection& fc) const {
0938   auto comp = [](uint16_t desc, uint16_t device) { return desc == 0 || desc == device; };
0939 
0940   // use FEC coordinates first if provided
0941   if (fec_.isValid()) {
0942     return comp(fec_.fecCrate(), fc.fecCrate()) && comp(fec_.fecSlot(), fc.fecSlot()) &&
0943            comp(fec_.fecRing(), fc.fecRing()) && comp(fec_.ccuAddr(), fc.ccuAddr()) &&
0944            comp(fec_.ccuChan(), fc.ccuChan()) && comp(fec_.lldChan(), fc.lldChannel()) &&
0945            (comp(fec_.i2cAddr(), fc.i2cAddr(0)) ||
0946             comp(fec_.i2cAddr(), fc.i2cAddr(1)));  // do not distinguish between APV1 and APV2
0947   }
0948 
0949   // then try FED coordinates
0950   if (fed_.isValid()) {
0951     return comp(fed_.fedId(), fc.fedId()) && comp(fed_.feUnit(), SiStripFedKey::feUnit(fc.fedCh())) &&
0952            comp(fed_.feChan(), SiStripFedKey::feChan(fc.fedCh()));
0953     // no fedApv in FedChannelConnection -- and we do not distinguish between APV1 and APV2
0954   }
0955 
0956   // last try detids (will skip all APVs on the module)
0957   if (detid_ != sistrip::invalid32_) {
0958     return detid_ == fc.detId();
0959   }
0960 
0961   return false;
0962 }
0963 
0964 std::string SiStripCondObjBuilderFromDb::SkipDeviceDescription::dump() const {
0965   std::stringstream ss;
0966   fec_.terse(ss);
0967   ss << "\n";
0968   fed_.terse(ss);
0969   ss << "\n";
0970   ss << "detid=" << detid_;
0971   return ss.str();
0972 }