Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:23:19

0001 
0002 #include "OnlineDB/SiStripESSources/interface/SiStripFedCablingBuilderFromDb.h"
0003 #include "CalibFormats/SiStripObjects/interface/SiStripFecCabling.h"
0004 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0005 #include "CondFormats/SiStripObjects/interface/FedChannelConnection.h"
0006 #include "DataFormats/SiStripCommon/interface/SiStripEnumsAndStrings.h"
0007 #include "DataFormats/SiStripCommon/interface/SiStripFecKey.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "FWCore/ServiceRegistry/interface/Service.h"
0010 #include "OnlineDB/SiStripConfigDb/interface/SiStripConfigDb.h"
0011 #include <cstdlib>
0012 #include <iostream>
0013 #include <sstream>
0014 #include <iomanip>
0015 
0016 using namespace std;
0017 using namespace sistrip;
0018 
0019 // -----------------------------------------------------------------------------
0020 /** */
0021 SiStripFedCablingBuilderFromDb::SiStripFedCablingBuilderFromDb(const edm::ParameterSet& pset)
0022     : SiStripFedCablingESProducer(pset), db_(nullptr), source_(sistrip::UNDEFINED_CABLING_SOURCE) {
0023   findingRecord<SiStripFedCablingRcd>();
0024 
0025   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0026                        << " Constructing object...";
0027 
0028   // Defined cabling "source" (connections, devices, detids)
0029   string source = pset.getUntrackedParameter<string>("CablingSource", "UNDEFINED");
0030   source_ = SiStripEnumsAndStrings::cablingSource(source);
0031 
0032   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0033                        << " CablingSource configurable set to \"" << source << "\""
0034                        << ". CablingSource member data set to: \"" << SiStripEnumsAndStrings::cablingSource(source_)
0035                        << "\"";
0036 }
0037 
0038 // -----------------------------------------------------------------------------
0039 /** */
0040 SiStripFedCablingBuilderFromDb::~SiStripFedCablingBuilderFromDb() {
0041   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0042                        << " Destructing object...";
0043 }
0044 
0045 // -----------------------------------------------------------------------------
0046 /** */
0047 SiStripFedCabling* SiStripFedCablingBuilderFromDb::make(const SiStripFedCablingRcd&) {
0048   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0049                        << " Constructing FED cabling...";
0050 
0051   // Create FED cabling object
0052   SiStripFedCabling* fed_cabling = new SiStripFedCabling();
0053 
0054   // Build and retrieve SiStripConfigDb object using service
0055   db_ = edm::Service<SiStripConfigDb>().operator->();
0056 
0057   // Check pointer
0058   if (db_) {
0059     edm::LogVerbatim(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0060                                  << " Pointer to SiStripConfigDb: 0x" << std::setw(8) << std::setfill('0') << std::hex
0061                                  << db_ << std::dec;
0062   } else {
0063     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0064                               << " NULL pointer to SiStripConfigDb returned by DB \"service\"!"
0065                               << " Cannot build FED cabling object!";
0066     return fed_cabling;
0067   }
0068 
0069   // Check if DB connection is made
0070   if (db_->deviceFactory() || db_->databaseCache()) {
0071     // Build FEC cabling object
0072     SiStripFecCabling fec_cabling;
0073     buildFecCabling(db_, fec_cabling, source_);
0074 
0075     // Populate FED cabling object
0076     getFedCabling(fec_cabling, *fed_cabling);
0077 
0078     // Call virtual method that writes FED cabling object to conditions DB
0079     writeFedCablingToCondDb(*fed_cabling);
0080 
0081     // Prints FED cabling
0082     //stringstream ss;
0083     //ss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0084     //<< " Printing cabling map..." << endl
0085     //<< *fed_cabling;
0086     //LogTrace(mlCabling_) << ss.str();
0087 
0088   } else {
0089     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0090                               << " NULL pointers to DeviceFactory and DatabaseCache returned by SiStripConfigDb!"
0091                               << " Cannot build FED cabling object!";
0092   }
0093 
0094   return fed_cabling;
0095 }
0096 
0097 // -----------------------------------------------------------------------------
0098 /** */
0099 void SiStripFedCablingBuilderFromDb::buildFecCabling(SiStripConfigDb* const db,
0100                                                      SiStripFecCabling& fec_cabling,
0101                                                      const sistrip::CablingSource& source) {
0102   if (source == sistrip::CABLING_FROM_CONNS) {
0103     buildFecCablingFromFedConnections(db, fec_cabling);
0104   } else if (source == sistrip::CABLING_FROM_DEVICES) {
0105     buildFecCablingFromDevices(db, fec_cabling);
0106   } else if (source == sistrip::CABLING_FROM_DETIDS) {
0107     buildFecCablingFromDetIds(db, fec_cabling);
0108   } else if (source == sistrip::UNDEFINED_CABLING_SOURCE) {
0109     LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0110                          << " Unexpected value for CablingSource: \"" << SiStripEnumsAndStrings::cablingSource(source)
0111                          << "\" Querying DB in order to build cabling from one of connections, devices or DetIds...";
0112     buildFecCabling(db, fec_cabling);
0113     return;
0114 
0115   } else {
0116     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0117                               << " Cannot build SiStripFecCabling object!"
0118                               << " sistrip::CablingSource has value: " << SiStripEnumsAndStrings::cablingSource(source);
0119     return;
0120   }
0121 
0122   // Debug
0123   const NumberOfDevices& devs = fec_cabling.countDevices();
0124   std::stringstream ss;
0125   ss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0126      << " Built SiStripFecCabling object with following devices:" << endl
0127      << devs;
0128   edm::LogVerbatim(mlCabling_) << ss.str() << endl;
0129 }
0130 
0131 // -----------------------------------------------------------------------------
0132 /** */
0133 void SiStripFedCablingBuilderFromDb::buildFecCabling(SiStripConfigDb* const db, SiStripFecCabling& fec_cabling) {
0134   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0135                        << " Building cabling object...";
0136 
0137   if (!db->getFedConnections().empty()) {
0138     buildFecCablingFromFedConnections(db, fec_cabling);
0139   } else if (!db->getDeviceDescriptions().empty()) {
0140     buildFecCablingFromDevices(db, fec_cabling);
0141   } else if (!db->getDcuDetIds().empty()) {
0142     buildFecCablingFromDetIds(db, fec_cabling);
0143   } else {
0144     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0145                               << " Cannot build SiStripFecCabling object!"
0146                               << " FedConnections, DeviceDescriptions and DcuDetIds vectors are all empty!";
0147     return;
0148   }
0149 
0150   // Debug
0151   const NumberOfDevices& devices = fec_cabling.countDevices();
0152   std::stringstream ss;
0153   ss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0154      << " Built SiStripFecCabling object with following devices:" << std::endl
0155      << devices;
0156   edm::LogVerbatim(mlCabling_) << ss.str() << endl;
0157 }
0158 
0159 // -----------------------------------------------------------------------------
0160 /** 
0161     Populates the SiStripFecCabling conditions object that is
0162     available via the EventSetup interface. The object contains the
0163     full FedChannel-Dcu-DetId mapping information.
0164     
0165     The map is built using information cached by the SiStripConfigDb
0166     object, comprising: 1) the FED channel connections, as found in
0167     the "module.xml" file or database; 2) and Dcu-DetId mapping, as
0168     found in the "dcuinfo.xml" file or DCU-DetId static table. If any
0169     information is missing, the method provides "dummy" values.
0170     
0171     Methodology:
0172     
0173     1) The FEC cabling object is built using FED channel connection
0174     objects.
0175     
0176     2) If the DcuId for a module is null (as defined within the
0177     connection description), a "dummy" DCU id is provided, based on
0178     the control key.
0179     
0180     3) The cached Dcu-DetId map is queried for a matching DcuId. If
0181     found, the DetId and ApvPairs are updated. The number of APV pairs
0182     is checked.
0183     
0184     4) If the DCU is not found in the cached map, a "random" DetId is
0185     assigned (using the remaining "unassigned" DetIds within the
0186     cached map). The DetId is only assigned if the number of APV pairs
0187     is consistent with the entry in the cached map.
0188     
0189     5) If no appropriate match is found, the DetId is assigned a
0190     "dummy" value using an incremented counter (starting from 0xFFFF).
0191     
0192     6) All Dcu-DetId mappings are accumulated in a new map, and this
0193     modified map is returned by the method.
0194 */
0195 void SiStripFedCablingBuilderFromDb::buildFecCablingFromFedConnections(SiStripConfigDb* const db,
0196                                                                        SiStripFecCabling& fec_cabling) {
0197   edm::LogVerbatim(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0198                                << " Building FEC cabling from FED connections descriptions...";
0199 
0200   // ---------- Some initialization ----------
0201 
0202   //fec_cabling.clear(); //@@ Need to add method to "clear" FecCabling?
0203 
0204   // ---------- Retrieve connection descriptions from database ----------
0205 
0206   SiStripConfigDb::FedConnectionsRange conns = db->getFedConnections();
0207   if (conns.empty()) {
0208     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0209                               << " Unable to build FEC cabling!"
0210                               << " No entries in FedConnections vector!";
0211     return;
0212   }
0213 
0214   // ---------- Retrieve DCU-DetId vector from database ----------
0215 
0216   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0217                        << " Retrieving DCU-DetId vector from database...";
0218   SiStripConfigDb::DcuDetIdsRange range = db->getDcuDetIds();
0219   const SiStripConfigDb::DcuDetIdsV dcu_detid_vector(range.begin(), range.end());
0220   if (!dcu_detid_vector.empty()) {
0221     LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0222                          << " Found " << dcu_detid_vector.size()
0223                          << " entries in DCU-DetId vector retrieved from database!";
0224   } else {
0225     edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0226                                 << " No entries in DCU-DetId vector retrieved from database!";
0227   }
0228 
0229   // ---------- Populate FEC cabling object with retrieved info ----------
0230 
0231   SiStripConfigDb::FedConnectionsV::const_iterator ifed = conns.begin();
0232   SiStripConfigDb::FedConnectionsV::const_iterator jfed = conns.end();
0233   for (; ifed != jfed; ++ifed) {
0234     if (!(*ifed)) {
0235       edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0236                                   << " NULL pointer to FedConnection!";
0237       continue;
0238     }
0239 
0240     //uint16_t fec_id    = static_cast<uint16_t>( (*ifed)->getFecHardwareId() );
0241     uint16_t fec_crate =
0242         static_cast<uint16_t>((*ifed)->getFecCrateId() + sistrip::FEC_CRATE_OFFSET);  //@@ temporary offset!
0243     uint16_t fec_slot = static_cast<uint16_t>((*ifed)->getFecSlot());
0244     uint16_t fec_ring =
0245         static_cast<uint16_t>((*ifed)->getRingSlot() + sistrip::FEC_RING_OFFSET);  //@@ temporary offset!
0246     uint16_t ccu_addr = static_cast<uint16_t>((*ifed)->getCcuAddress());
0247     uint16_t ccu_chan = static_cast<uint16_t>((*ifed)->getI2cChannel());
0248     uint16_t apv0 = static_cast<uint16_t>((*ifed)->getApvAddress());
0249     uint16_t apv1 = apv0 + 1;  //@@ needs implementing!
0250     uint32_t dcu_id = static_cast<uint32_t>((*ifed)->getDcuHardId());
0251     uint32_t det_id = 0;  //@@ static_cast<uint32_t>( (*ifed)->getDetId() );
0252     uint16_t npairs = 0;  //@@ static_cast<uint16_t>( (*ifed)->getApvPairs() );
0253     uint16_t fed_id = static_cast<uint16_t>((*ifed)->getFedId());
0254     uint16_t fed_ch = static_cast<uint16_t>((*ifed)->getFedChannel());
0255     uint16_t length = 0;  //@@ static_cast<uint16_t>( (*ifed)->getFiberLength() );
0256 
0257     FedChannelConnection conn(
0258         fec_crate, fec_slot, fec_ring, ccu_addr, ccu_chan, apv0, apv1, dcu_id, det_id, npairs, fed_id, fed_ch, length);
0259 
0260     uint16_t fed_crate = sistrip::invalid_;
0261     uint16_t fed_slot = sistrip::invalid_;
0262     fed_crate = static_cast<uint16_t>((*ifed)->getFedCrateId());
0263     fed_slot = static_cast<uint16_t>((*ifed)->getFedSlot());
0264     conn.fedCrate(fed_crate);
0265     conn.fedSlot(fed_slot);
0266 
0267     fec_cabling.addDevices(conn);
0268   }
0269 
0270   // ---------- Assign DCU and DetIds and then FED cabling ----------
0271 
0272   assignDcuAndDetIds(fec_cabling, dcu_detid_vector);
0273 }
0274 
0275 // -----------------------------------------------------------------------------
0276 /** 
0277     Builds the SiStripFedCabling conditions object that is available
0278     via the EventSetup interface. The object contains the full
0279     FedChannel-Dcu-DetId mapping information.
0280     
0281     This method is typically used when the FED connections (ie,
0282     "module.xml" file) does not exist, such as prior to the FED
0283     cabling or "bare connection" procedure.
0284 
0285     The map is built using information cached by the SiStripConfigDb
0286     object, comprising: 1) the hardware device descriptions, as found
0287     in the "fec.xml" file; 2) and Dcu-DetId mapping, as found in the
0288     "dcuinfo.xml" file. If any information is missing, the method
0289     provides "dummy" values.
0290     
0291     Methodology:
0292 
0293     The FEC cabling object is built using the hardware device
0294     descriptions (ie, from "fec.xml"). 
0295 
0296     Given that the FED channel connections are not known, APV pairs
0297     are cabled to "random" FED ids and channels. FED ids are retrieved
0298     from any FED descriptions cached by the SiStripConfigDb object
0299     (ie, from "fed.xml"). A check is made to ensure sufficient FEDs
0300     exist to cable the entire control system. If not, the shortfall is
0301     met by generating FED ids using an incremented counter (starting
0302     from 50).
0303 
0304     If the DcuId (provided by the hardware device descriptions) is
0305     null, a dummy value is provided, based on the control key.
0306     
0307     The Dcu-DetId map (ie, from "dcuinfo.xml") is queried for a
0308     matching DcuId. If found, the DetId and ApvPairs are updated. If
0309     not, a "random" DetId within the Dcu-DetId map is assigned. Note
0310     that a check is made on the number of APV pairs before the DetId
0311     is assigned. If no appropriate match is found, the DetId is
0312     assigned a value using an incremented counter (starting from
0313     0xFFFF).
0314 
0315     All Dcu-DetId mappings are accumulated in a new map, and this
0316     modified map is returned by the method.
0317 */
0318 void SiStripFedCablingBuilderFromDb::buildFecCablingFromDevices(SiStripConfigDb* const db,
0319                                                                 SiStripFecCabling& fec_cabling) {
0320   edm::LogVerbatim(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0321                                << " Building FEC cabling object from device descriptions...";
0322 
0323   // ---------- Some initialization ----------
0324 
0325   // fec_cabling.clear(); //@@ Need to add method to "clear" FecCabling?
0326 
0327   // ---------- Retrieve APV descriptions from database ----------
0328 
0329   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0330                        << " Retrieving APV descriptions from database...";
0331   SiStripConfigDb::DeviceDescriptionsRange apv_desc = db->getDeviceDescriptions(APV25);
0332   if (!apv_desc.empty()) {
0333     LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0334                          << " Retrieved " << apv_desc.size() << " APV descriptions from database!";
0335   } else {
0336     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0337                               << " Unable to build FEC cabling!"
0338                               << " No APV descriptions found!";
0339     return;
0340   }
0341 
0342   // ---------- Retrieve DCU descriptions from database ----------
0343 
0344   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0345                        << " Retrieving DCU descriptions from database...";
0346   SiStripConfigDb::DeviceDescriptionsRange dcu_desc = db->getDeviceDescriptions(DCU);
0347 
0348   if (!dcu_desc.empty()) {
0349     uint16_t feh = 0;
0350     uint16_t ccu = 0;
0351     SiStripConfigDb::DeviceDescriptionsV::const_iterator idcu;
0352     for (idcu = dcu_desc.begin(); idcu != dcu_desc.end(); idcu++) {
0353       dcuDescription* dcu = dynamic_cast<dcuDescription*>(*idcu);
0354       if (!dcu) {
0355         continue;
0356       }
0357       if (dcu->getDcuType() == "FEH") {
0358         feh++;
0359       } else {
0360         ccu++;
0361       }
0362     }
0363 
0364     LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0365                          << " Retrieved " << feh << " DCU-FEH descriptions from database!"
0366                          << " (and a further " << ccu << " DCUs for CCU modules, etc...)";
0367 
0368   } else {
0369     edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0370                                 << " No DCU descriptions found!";
0371   }
0372 
0373   // ---------- Retrieve DCU-DetId vector from database ----------
0374 
0375   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0376                        << " Retrieving DCU-DetId vector from database...";
0377   SiStripConfigDb::DcuDetIdsRange range = db->getDcuDetIds();
0378   const SiStripConfigDb::DcuDetIdsV dcu_detid_vector(range.begin(), range.end());
0379   if (!dcu_detid_vector.empty()) {
0380     LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0381                          << " Found " << dcu_detid_vector.size()
0382                          << " entries in DCU-DetId vector retrieved from database!";
0383   } else {
0384     edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0385                                 << " No entries in DCU-DetId vector retrieved from database!";
0386   }
0387 
0388   // ---------- Retrieve FED ids from database ----------
0389 
0390   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0391                        << " Retrieving FED ids from database...";
0392   SiStripConfigDb::FedIdsRange fed_ids = db->getFedIds();
0393 
0394   if (!fed_ids.empty()) {
0395     LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0396                          << " Retrieved " << fed_ids.size() << " FED ids from database!";
0397   } else {
0398     edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0399                                 << " No FED ids found!";
0400   }
0401 
0402   // ---------- Populate FEC cabling object with retrieved info ----------
0403 
0404   edm::LogVerbatim(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0405                                << " Building FEC cabling object from APV and DCU descriptions...";
0406 
0407   SiStripConfigDb::DeviceDescriptionsV::const_iterator iapv;
0408   for (iapv = apv_desc.begin(); iapv != apv_desc.end(); iapv++) {
0409     if (!(*iapv)) {
0410       edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0411                                   << " NULL pointer to DeviceDescription (of type APV25)!";
0412       continue;
0413     }
0414 
0415     SiStripConfigDb::DeviceAddress addr = db->deviceAddress(**iapv);
0416     FedChannelConnection conn(addr.fecCrate_ + sistrip::FEC_CRATE_OFFSET,  //@@ temp
0417                               addr.fecSlot_,
0418                               addr.fecRing_ + sistrip::FEC_RING_OFFSET,  //@@ temp
0419                               addr.ccuAddr_,
0420                               addr.ccuChan_,
0421                               addr.i2cAddr_);
0422     fec_cabling.addDevices(conn);
0423   }
0424 
0425   SiStripConfigDb::DeviceDescriptionsV::const_iterator idcu;
0426   for (idcu = dcu_desc.begin(); idcu != dcu_desc.end(); idcu++) {
0427     if (!(*idcu)) {
0428       edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0429                                   << " NULL pointer to DeviceDescription (of type DCU)!";
0430       continue;
0431     }
0432 
0433     SiStripConfigDb::DeviceAddress addr = db->deviceAddress(**idcu);
0434     dcuDescription* dcu = dynamic_cast<dcuDescription*>(*idcu);
0435     if (!dcu) {
0436       continue;
0437     }
0438     if (dcu->getDcuType() != "FEH") {
0439       continue;
0440     }
0441     FedChannelConnection conn(addr.fecCrate_ + sistrip::FEC_CRATE_OFFSET,  //@@ temp,
0442                               addr.fecSlot_,
0443                               addr.fecRing_ + sistrip::FEC_RING_OFFSET,  //@@ temp,
0444                               addr.ccuAddr_,
0445                               addr.ccuChan_,
0446                               0,
0447                               0,  // APV I2C addresses not used
0448                               dcu->getDcuHardId());
0449     fec_cabling.dcuId(conn);
0450   }
0451 
0452   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0453                        << " Finished building FEC cabling object from APV and DCU descriptions!";
0454 
0455   NumberOfDevices devs1 = fec_cabling.countDevices();
0456   std::stringstream ss1;
0457   ss1 << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0458       << " Number of devices in FEC cabling object:" << std::endl;
0459   devs1.print(ss1);
0460   LogTrace(mlCabling_) << ss1.str();
0461 
0462   // ---------- Counters used in assigning "dummy" FED ids and channels ----------
0463 
0464   std::vector<uint16_t>::const_iterator ifed = fed_ids.begin();
0465   uint16_t fed_ch = 0;
0466 
0467   // ---------- Assign "dummy" FED crates/slots/ids/chans to constructed modules ----------
0468 
0469   std::vector<uint32_t> used_keys;
0470 
0471   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0472                        << " Randomly assigning FED ids/channels to APV pairs in front-end modules...";
0473 
0474   if (fed_ids.empty()) {
0475     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0476                               << " No FED ids retrieved from database! Unable to cable system!";
0477   } else {
0478     bool complete = false;
0479     std::vector<SiStripFecCrate>::const_iterator icrate = fec_cabling.crates().begin();
0480     std::vector<SiStripFecCrate>::const_iterator jcrate = fec_cabling.crates().end();
0481     while (!complete && icrate != jcrate) {
0482       std::vector<SiStripFec>::const_iterator ifec = icrate->fecs().begin();
0483       std::vector<SiStripFec>::const_iterator jfec = icrate->fecs().end();
0484       while (!complete && ifec != jfec) {
0485         std::vector<SiStripRing>::const_iterator iring = ifec->rings().begin();
0486         std::vector<SiStripRing>::const_iterator jring = ifec->rings().end();
0487         while (!complete && iring != jring) {
0488           std::vector<SiStripCcu>::const_iterator iccu = iring->ccus().begin();
0489           std::vector<SiStripCcu>::const_iterator jccu = iring->ccus().end();
0490           while (!complete && iccu != jccu) {
0491             std::vector<SiStripModule>::const_iterator imod = iccu->modules().begin();
0492             std::vector<SiStripModule>::const_iterator jmod = iccu->modules().end();
0493             while (!complete && imod != jmod) {
0494               // Set number of APV pairs based on devices found
0495               const_cast<SiStripModule&>(*imod).nApvPairs(0);
0496 
0497               used_keys.push_back(
0498                   SiStripFecKey(imod->fecCrate(), imod->fecSlot(), imod->fecRing(), imod->ccuAddr(), imod->ccuChan())
0499                       .key());
0500 
0501               //          // Add middle LLD channel if missing (to guarantee all FED channels are cabled!)
0502               //          if ( imod->nApvPairs() == 2 ) {
0503               //        const_cast<SiStripModule&>(*imod).nApvPairs(3);
0504               //        FedChannelConnection temp( imod->fecCrate(),
0505               //                       imod->fecSlot(),
0506               //                       imod->fecRing(),
0507               //                       imod->ccuAddr(),
0508               //                       imod->ccuChan(),
0509               //                       SiStripFecKey::i2cAddr(2,true),
0510               //                       SiStripFecKey::i2cAddr(2,false) );
0511               //        const_cast<SiStripModule&>(*imod).addDevices( temp );
0512               //          }
0513               //          const_cast<SiStripModule&>(*imod).nApvPairs(0);
0514 
0515               // Iterate through APV pairs
0516               for (uint16_t ipair = 0; ipair < imod->nApvPairs(); ipair++) {
0517                 // Check FED id and channel
0518                 if (ifed == fed_ids.end()) {
0519                   fed_ch++;
0520                   ifed = fed_ids.begin();
0521                 }
0522                 if (fed_ch == 96) {
0523                   edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0524                                               << " Insufficient FED channels to cable all devices in control system!";
0525                   complete = true;
0526                   break;
0527                 }
0528 
0529                 // Set "dummy" FED id and channel
0530                 pair<uint16_t, uint16_t> addr = imod->activeApvPair(imod->lldChannel(ipair));
0531                 SiStripModule::FedChannel fed_channel((*ifed) / 16 + 1,  // 16 FEDs per crate, numbering starts from 1
0532                                                       (*ifed) % 16 + 2,  // FED slot starts from 2
0533                                                       *ifed,
0534                                                       fed_ch);
0535                 const_cast<SiStripModule&>(*imod).fedCh(addr.first, fed_channel);
0536                 ifed++;
0537               }
0538 
0539               imod++;
0540             }
0541             iccu++;
0542           }
0543           iring++;
0544         }
0545         ifec++;
0546       }
0547       icrate++;
0548     }
0549   }
0550 
0551   std::sort(used_keys.begin(), used_keys.end());
0552 
0553   NumberOfDevices devs2 = fec_cabling.countDevices();
0554   std::stringstream ss2;
0555   ss2 << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0556       << " Number of devices in FEC cabling object:" << std::endl;
0557   devs2.print(ss2);
0558   LogTrace(mlCabling_) << ss2.str();
0559 
0560   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0561                        << " Finished randomly assigning FED ids/channels to APV pairs in front-end modules...";
0562 
0563   // ---------- Assign "dummy" devices to remaining FED ids/chans ----------
0564 
0565   LogTrace(mlCabling_)
0566       << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0567       << " Assigning APV pairs in dummy front-end modules to any remaining \"uncabled\" FED ids/channels...";
0568 
0569   if (fed_ids.empty()) {
0570     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0571                               << " No FED ids retrieved from database! Unable to cable system!";
0572   } else {
0573     uint16_t module = 0;
0574     bool complete = false;
0575     while (!complete) {
0576       for (uint16_t lld = sistrip::LLD_CHAN_MIN; lld < sistrip::LLD_CHAN_MAX + 1; lld++) {
0577         // Check FED id and channel
0578         if (ifed == fed_ids.end()) {
0579           fed_ch++;
0580           ifed = fed_ids.begin();
0581         }
0582         if (fed_ch == 96) {
0583           LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0584                                << " All FED channels are now cabled!";
0585           complete = true;
0586           break;
0587         }
0588 
0589         // commented because key is not used
0590         //uint32_t key = SiStripFecKey( fecCrate( module ),
0591         //                fecSlot( module ),
0592         //                fecRing( module ),
0593         //                ccuAddr( module ),
0594         //                ccuChan( module ) ).key();
0595 
0596         //if ( std::find( used_keys.begin(), used_keys.end(), key ) != used_keys.end() ) { break; }
0597 
0598         FedChannelConnection temp(fecCrate(module),
0599                                   fecSlot(module),
0600                                   fecRing(module),
0601                                   ccuAddr(module),
0602                                   ccuChan(module),
0603                                   SiStripFecKey::i2cAddr(lld, true),
0604                                   SiStripFecKey::i2cAddr(lld, false),
0605                                   sistrip::invalid32_,
0606                                   sistrip::invalid32_,
0607                                   3,  // npairs
0608                                   *ifed,
0609                                   fed_ch);
0610         uint16_t fed_crate = (*ifed) / 16 + 1;  // 16 FEDs per crate, numbering starts from 1
0611         uint16_t fed_slot = (*ifed) % 16 + 2;   // FED slot starts from 2
0612         temp.fedCrate(fed_crate);
0613         temp.fedSlot(fed_slot);
0614         fec_cabling.addDevices(temp);
0615         ifed++;
0616       }
0617       module++;
0618     }
0619   }
0620 
0621   LogTrace(mlCabling_)
0622       << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0623       << " Finished assigning APV pairs in dummy front-end modules to any remaining \"uncabled\" FED ids/channels...";
0624 
0625   NumberOfDevices devs3 = fec_cabling.countDevices();
0626   std::stringstream ss3;
0627   ss3 << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0628       << " Number of devices in FEC cabling object:" << std::endl;
0629   devs3.print(ss3);
0630   LogTrace(mlCabling_) << ss3.str();
0631 
0632   // ---------- Assign DCU and DetIds and then FED cabling ----------
0633 
0634   assignDcuAndDetIds(fec_cabling, dcu_detid_vector);
0635 }
0636 
0637 // -----------------------------------------------------------------------------
0638 /**
0639    Builds the SiStripFedCabling conditions object that is available
0640    via the EventSetup interface. The object contains the full
0641    FedChannel-Dcu-DetId mapping information.
0642     
0643    This method is typically used when only the Dcu-DetId map (ie,
0644    from "dcuinfo.xml") exists and the FED connections (ie,
0645    "module.xml" file) and device descriptions (ie, from "fec.xml")
0646    are both missing.
0647     
0648    The map is built using the Dcu-DetId map that is cached by the
0649    SiStripConfigDb object. As a minimum, the map should contain
0650    values within both the DetId and APpvPair fields, but if any
0651    information is missing, the method provides "dummy" values.
0652     
0653    Methodology:
0654 
0655    The FEC cabling object is built using the Dcu-DetId map (ie,
0656    from "dcuinfo.xml"). For each entry, the DcuId, DetId and ApvPairs
0657    values are retrieved. For each ApvPair, a FED channel connection
0658    object is created using "dummy" hardware addresses.
0659 
0660    If the DcuId (provided by the hardware device descriptions) is
0661    null, a dummy value is provided, based on the control key.
0662     
0663    If the DetId is null, a value is assigned using an incremented
0664    counter (starting from 0xFFFF). 
0665 
0666    If the number of APV pairs is null, a value of 2 or 3 is randomly
0667    assigned.
0668 
0669    Given that the FED channel connections are not known, APV pairs
0670    are cabled to "random" FED ids and channels. 
0671 
0672    All Dcu-DetId mappings are accumulated in a new map, and this
0673    modified map is returned by the method.
0674 */
0675 void SiStripFedCablingBuilderFromDb::buildFecCablingFromDetIds(SiStripConfigDb* const db,
0676                                                                SiStripFecCabling& fec_cabling) {
0677   edm::LogVerbatim(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0678                                << " Building FEC cabling object from DetIds...";
0679 
0680   // ---------- Some initialization ----------
0681 
0682   // fec_cabling.clear();
0683 
0684   // chans_per_ring = chans_per_ccu * ccus_per_ring = 100 (TOB gives lower limit of 60)
0685   uint32_t chans_per_ccu = 10;
0686   uint32_t ccus_per_ring = 10;
0687   uint32_t rings_per_fec = 8;
0688   uint32_t fecs_per_crate = 11;
0689 
0690   // ---------- Retrieve necessary descriptions from database ----------
0691 
0692   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0693                        << " Retrieving DCU-DetId vector from database...";
0694   SiStripConfigDb::DcuDetIdsRange range = db->getDcuDetIds();
0695   const SiStripConfigDb::DcuDetIdsV dcu_detid_vector(range.begin(), range.end());
0696   if (!dcu_detid_vector.empty()) {
0697     LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0698                          << " Found " << dcu_detid_vector.size()
0699                          << " entries in DCU-DetId vector retrieved from database!";
0700   } else {
0701     edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0702                                 << " No entries in DCU-DetId vector retrieved from database!"
0703                                 << " Unable to build FEC cabling!";
0704     return;
0705   }
0706 
0707   // ---------- Populate FEC cabling object with DCU, DetId and "dummy" control info ----------
0708 
0709   uint32_t imodule = 0;
0710   SiStripConfigDb::DcuDetIdsV::const_iterator iter;
0711   for (iter = dcu_detid_vector.begin(); iter != dcu_detid_vector.end(); iter++) {
0712     if (!(iter->second)) {
0713       edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0714                                   << " NULL pointer to TkDcuInfo!";
0715       continue;
0716     }
0717 
0718     uint16_t fec_crate = (imodule / (chans_per_ccu * ccus_per_ring * rings_per_fec * fecs_per_crate)) + 1;
0719     uint16_t fec_slot = (imodule / (chans_per_ccu * ccus_per_ring * rings_per_fec)) % fecs_per_crate + 2;
0720     uint16_t fec_ring = (imodule / (chans_per_ccu * ccus_per_ring)) % rings_per_fec + 1;
0721     uint16_t ccu_addr = (imodule / (chans_per_ccu)) % ccus_per_ring + 1;
0722     uint16_t ccu_chan = (imodule) % chans_per_ccu + 16;
0723 
0724     uint32_t dcu_id = iter->second->getDcuHardId();  //
0725     uint32_t det_id = iter->second->getDetId();
0726     uint16_t npairs = iter->second->getApvNumber() / 2;
0727     uint16_t length = (uint16_t)iter->second->getFibreLength();  //@@ should be double!
0728 
0729     // --- Check if DCU, DetId and nApvPairs are null ---
0730 
0731     if (!dcu_id) {
0732       dcu_id = SiStripFecKey(fec_crate, fec_slot, fec_ring, ccu_addr, ccu_chan).key();
0733     }
0734     if (!det_id) {
0735       det_id = 0xFFFF + imodule;
0736     }
0737     if (!npairs) {
0738       npairs = rand() / 2 ? 2 : 3;
0739     }
0740 
0741     // --- Construct FedChannelConnection objects ---
0742 
0743     for (uint16_t ipair = 0; ipair < npairs; ipair++) {
0744       uint16_t iapv = (ipair == 1 && npairs == 2 ? 36 : 32 + 2 * ipair);
0745       FedChannelConnection conn(fec_crate,
0746                                 fec_slot,
0747                                 fec_ring,
0748                                 ccu_addr,
0749                                 ccu_chan,
0750                                 iapv,
0751                                 iapv + 1,
0752                                 dcu_id,
0753                                 det_id,
0754                                 npairs,
0755                                 0,
0756                                 0,  // FED id and channel
0757                                 length,
0758                                 true,
0759                                 true,
0760                                 true,
0761                                 true);
0762       fec_cabling.addDevices(conn);
0763     }
0764 
0765     imodule++;
0766   }
0767 
0768   // ---------- Assign "dummy" FED ids/chans to Modules of FEC cabling object ----------
0769 
0770   uint32_t fed_id = 50;
0771   uint32_t fed_ch = 0;
0772   for (vector<SiStripFecCrate>::const_iterator icrate = fec_cabling.crates().begin();
0773        icrate != fec_cabling.crates().end();
0774        icrate++) {
0775     for (vector<SiStripFec>::const_iterator ifec = icrate->fecs().begin(); ifec != icrate->fecs().end(); ifec++) {
0776       for (vector<SiStripRing>::const_iterator iring = ifec->rings().begin(); iring != ifec->rings().end(); iring++) {
0777         for (vector<SiStripCcu>::const_iterator iccu = iring->ccus().begin(); iccu != iring->ccus().end(); iccu++) {
0778           for (vector<SiStripModule>::const_iterator imod = iccu->modules().begin(); imod != iccu->modules().end();
0779                imod++) {
0780             if (96 - fed_ch < imod->nApvPairs()) {
0781               fed_id++;
0782               fed_ch = 0;
0783             }  // move to next FED
0784             for (uint16_t ipair = 0; ipair < imod->nApvPairs(); ipair++) {
0785               pair<uint16_t, uint16_t> addr = imod->activeApvPair((*imod).lldChannel(ipair));
0786               SiStripModule::FedChannel fed_channel(
0787                   (fed_id - 50) / 16 + 1,  // 16 FEDs per crate, numbering starts from 1
0788                   (fed_id - 50) % 16 + 2,  // FED slot starts from 2
0789                   fed_id,
0790                   fed_ch);
0791               const_cast<SiStripModule&>(*imod).fedCh(addr.first, fed_channel);
0792               fed_ch++;
0793             }
0794           }
0795         }
0796       }
0797     }
0798   }
0799 }
0800 
0801 // -----------------------------------------------------------------------------
0802 /** */
0803 void SiStripFedCablingBuilderFromDb::assignDcuAndDetIds(SiStripFecCabling& fec_cabling,
0804                                                         const std::vector<std::pair<uint32_t, TkDcuInfo*> >& _in) {
0805   std::vector<std::pair<uint32_t, TkDcuInfo*> > in = _in;
0806   // ---------- Check if entries found in DCU-DetId vector ----------
0807 
0808   if (in.empty()) {
0809     edm::LogError(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0810                               << " No entries in DCU-DetId vector!";
0811   }
0812 
0813   // ---------- Assign DCU and DetId to Modules in FEC cabling object ----------
0814 
0815   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0816                        << " Assigning DCU ids and DetIds to constructed modules...";
0817 
0818   uint16_t channels = 0;
0819   uint16_t six = 0;
0820   uint16_t four = 0;
0821   uint16_t unknown = 0;
0822   uint16_t missing = 0;
0823 
0824   for (vector<SiStripFecCrate>::const_iterator icrate = fec_cabling.crates().begin();
0825        icrate != fec_cabling.crates().end();
0826        icrate++) {
0827     for (vector<SiStripFec>::const_iterator ifec = icrate->fecs().begin(); ifec != icrate->fecs().end(); ifec++) {
0828       for (vector<SiStripRing>::const_iterator iring = ifec->rings().begin(); iring != ifec->rings().end(); iring++) {
0829         for (vector<SiStripCcu>::const_iterator iccu = iring->ccus().begin(); iccu != iring->ccus().end(); iccu++) {
0830           for (vector<SiStripModule>::const_iterator imod = iccu->modules().begin(); imod != iccu->modules().end();
0831                imod++) {
0832             SiStripModule& module = const_cast<SiStripModule&>(*imod);
0833 
0834             //@@ TEMP FIX UNTIL LAURENT DEBUGS FedChannelConnectionDescription CLASS
0835             module.nApvPairs(0);
0836 
0837             // --- Check for null DCU ---
0838 
0839             if (!module.dcuId()) {
0840               SiStripFecKey path(
0841                   icrate->fecCrate(), ifec->fecSlot(), iring->fecRing(), iccu->ccuAddr(), imod->ccuChan());
0842               uint32_t module_key = path.key();
0843               module.dcuId(module_key);  // Assign DCU id equal to control key
0844               stringstream ss;
0845               ss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0846                  << " Found NULL DcuId! Setting 'dummy' value based control key 0x" << hex << setw(8) << setfill('0')
0847                  << module_key << dec;
0848               edm::LogWarning(mlCabling_) << ss.str();
0849             }
0850 
0851             // --- Check for null DetId ---
0852 
0853             if (!module.detId()) {
0854               // --- Search for DcuId in map ---
0855 
0856               SiStripConfigDb::DcuDetIdsV::iterator iter = in.end();
0857               iter = SiStripConfigDb::findDcuDetId(in.begin(), in.end(), module.dcuId());
0858               if (iter != in.end()) {
0859                 if (!(iter->second)) {
0860                   edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0861                                               << " NULL pointer to TkDcuInfo!";
0862                   continue;
0863                 }
0864 
0865                 // --- Assign DetId and set nApvPairs based on APVs found in given Module ---
0866 
0867                 module.detId(iter->second->getDetId());
0868                 module.nApvPairs(0);
0869 
0870                 // count expected channels
0871                 uint16_t pairs = iter->second->getApvNumber() / 2;
0872                 channels += pairs;
0873                 if (pairs == 2) {
0874                   four++;
0875                 } else if (pairs == 3) {
0876                   six++;
0877                 } else {
0878                   unknown++;
0879                 }
0880 
0881                 // --- Check number of APV pairs is valid and consistent with cached map ---
0882 
0883                 if (module.nApvPairs() != 2 && module.nApvPairs() != 3) {
0884                   missing += (iter->second->getApvNumber() / 2 - module.nApvPairs());
0885                   stringstream ss1;
0886                   ss1 << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]" << std::endl
0887                       << " Module with DCU id 0x" << hex << setw(8) << setfill('0') << module.dcuId() << dec
0888                       << " and DetId 0x" << hex << setw(8) << setfill('0') << module.detId() << dec
0889                       << " has unexpected number of APV pairs (" << module.nApvPairs() << ")." << std::endl
0890                       << " Some APV pairs may have not been detected by the FEC scan." << std::endl
0891                       << " Setting to value found in static map (" << iter->second->getApvNumber() / 2 << ")...";
0892                   edm::LogWarning(mlCabling_) << ss1.str();
0893                   module.nApvPairs(iter->second->getApvNumber() / 2);
0894 
0895                 } else if (module.nApvPairs() < iter->second->getApvNumber() / 2) {
0896                   missing += (iter->second->getApvNumber() / 2 - module.nApvPairs());
0897                   stringstream ss2;
0898                   ss2 << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]" << std::endl
0899                       << " Module with DCU id 0x" << hex << setw(8) << setfill('0') << module.dcuId() << dec
0900                       << " and DetId 0x" << hex << setw(8) << setfill('0') << module.detId() << dec
0901                       << " has number of APV pairs (" << module.nApvPairs()
0902                       << ") that does not match value found in DCU-DetId vector (" << iter->second->getApvNumber() / 2
0903                       << ")." << std::endl
0904                       << " Some APV pairs may have not been detected by"
0905                       << " the FEC scan or the DCU-DetId vector may be incorrect." << std::endl
0906                       << " Setting to value found in static map (" << iter->second->getApvNumber() / 2 << ")...";
0907                   edm::LogWarning(mlCabling_) << ss2.str();
0908                   module.nApvPairs(iter->second->getApvNumber() / 2);
0909                 }
0910 
0911                 // --- Check for null fibre length ---
0912 
0913                 if (!module.length()) {
0914                   module.length(static_cast<uint16_t>(iter->second->getFibreLength()));
0915                 }
0916 
0917                 // --- Remove TkDcuInfo object from cached map ---
0918 
0919                 in.erase(iter);
0920 
0921               }  // Set for DCU in static table
0922             }    // Check for null DetId
0923 
0924           }  // Module loop
0925         }    // CCU loop
0926       }      // FEC ring loop
0927     }        // FEC loop
0928   }          // FEC crate loop
0929 
0930   std::stringstream sss;
0931   sss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]" << std::endl
0932       << " Connections in DCU-DetId map : " << channels << std::endl
0933       << " 4-APV modules                : " << four << std::endl
0934       << " 6-APV modules                : " << six << std::endl
0935       << " Unknown number of APV pairs  : " << unknown << std::endl
0936       << " Total found APV pairs        : " << (channels - missing) << std::endl
0937       << " Total missing APV pairs      : " << missing << std::endl;
0938   edm::LogVerbatim(mlCabling_) << sss.str();
0939 
0940   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0941                        << " Finished assigning DCU ids and DetIds to constructed modules...";
0942 
0943   // ---------- "Randomly" assign DetIds to Modules with DCU ids not found in static table ----------
0944 
0945   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0946                        << " Assigning \"random\" DetIds to modules with DCU ids not found in static table...";
0947 
0948   uint32_t detid = 0x10000;  // Incremented "dummy" DetId
0949   for (vector<SiStripFecCrate>::const_iterator icrate = fec_cabling.crates().begin();
0950        icrate != fec_cabling.crates().end();
0951        icrate++) {
0952     for (vector<SiStripFec>::const_iterator ifec = icrate->fecs().begin(); ifec != icrate->fecs().end(); ifec++) {
0953       for (vector<SiStripRing>::const_iterator iring = ifec->rings().begin(); iring != ifec->rings().end(); iring++) {
0954         for (vector<SiStripCcu>::const_iterator iccu = iring->ccus().begin(); iccu != iring->ccus().end(); iccu++) {
0955           for (vector<SiStripModule>::const_iterator imod = iccu->modules().begin(); imod != iccu->modules().end();
0956                imod++) {
0957             SiStripModule& module = const_cast<SiStripModule&>(*imod);
0958 
0959             // --- Check for null DetId and search for DCU in cached map ---
0960 
0961             if (!module.detId()) {
0962               SiStripConfigDb::DcuDetIdsV::iterator iter = in.end();
0963               iter = SiStripConfigDb::findDcuDetId(in.begin(), in.end(), module.dcuId());
0964               if (iter != in.end()) {
0965                 // --- Search for "random" module with consistent number of APV pairs ---
0966 
0967                 SiStripConfigDb::DcuDetIdsV::iterator idcu;
0968                 if (in.empty()) {
0969                   idcu = in.end();
0970                 } else {
0971                   idcu = in.begin();
0972                   while (idcu != in.end()) {
0973                     if (idcu->second) {
0974                       if (static_cast<uint32_t>(idcu->second->getApvNumber()) ==
0975                           static_cast<uint32_t>(2 * module.nApvPairs())) {
0976                         break;
0977                       }
0978                     }
0979                     idcu++;
0980                   }
0981                 }
0982 
0983                 // --- Assign "random" DetId if number of APV pairs is consistent ---
0984 
0985                 if (idcu != in.end()) {
0986                   if (!(idcu->second)) {
0987                     edm::LogWarning(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0988                                                 << " NULL pointer to TkDcuInfo!";
0989                     continue;
0990                   }
0991 
0992                   module.detId(idcu->second->getDetId());
0993                   in.erase(idcu);
0994 
0995                   stringstream ss;
0996                   ss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
0997                      << " Did not find module with DCU id 0x" << hex << setw(8) << setfill('0') << module.dcuId() << dec
0998                      << " in DCU-DetId vector!" << endl
0999                      << " Assigned 'random' DetId 0x" << hex << setw(8) << setfill('0') << module.detId() << dec;
1000                   edm::LogWarning(mlCabling_) << ss.str();
1001 
1002                 } else {  // --- Else, assign "dummy" DetId based on counter ---
1003 
1004                   // If no match found, then assign DetId using incremented counter
1005                   module.detId(detid);
1006                   detid++;
1007 
1008                   stringstream ss;
1009                   if (in.empty()) {
1010                     ss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
1011                        << " Did not find module with DCU id 0x" << hex << setw(8) << setfill('0') << module.dcuId()
1012                        << dec << " in DCU-DetId vector!"
1013                        << " Could not assign 'random' DetId as DCU-DetID map is empty!"
1014                        << " Assigned DetId based on incremented counter, with value 0x" << hex << setw(8)
1015                        << setfill('0') << module.detId() << dec;
1016                   } else {
1017                     ss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
1018                        << " Did not find module with DCU id 0x" << hex << setw(8) << setfill('0') << module.dcuId()
1019                        << dec << " in DCU-DetId vector!"
1020                        << " Could not assign 'random' DetId as no modules had appropriate number of APV pairs ("
1021                        << module.nApvPairs() << "). Assigned DetId based on incremented counter, with value 0x" << hex
1022                        << setw(8) << setfill('0') << module.detId() << dec;
1023                   }
1024                   edm::LogWarning(mlCabling_) << ss.str();
1025                 }
1026               }
1027             }
1028 
1029           }  // Module loop
1030         }    // CCU loop
1031       }      // FEC ring loop
1032     }        // FEC loop
1033   }          // FEC crate loop
1034 
1035   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
1036                        << " Finished assigning \"random\" DetIds to modules with DCU ids not found in static table...";
1037 
1038   LogTrace(mlCabling_) << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
1039                        << " Assigning \"random\" DetIds to modules with DCU ids not found in static table...";
1040 
1041   // ---------- Check for unassigned DetIds ----------
1042 
1043   if (!in.empty()) {
1044     stringstream ss;
1045     ss << "[SiStripFedCablingBuilderFromDb::" << __func__ << "]"
1046        << " Not all DetIds have been assigned to a DcuId! " << in.size() << " DetIds are unassigned!";
1047     edm::LogWarning(mlCabling_) << ss.str();
1048   }
1049 }
1050 
1051 // -----------------------------------------------------------------------------
1052 /** */
1053 void SiStripFedCablingBuilderFromDb::getFedCabling(const SiStripFecCabling& fec_cabling,
1054                                                    SiStripFedCabling& fed_cabling) {
1055   vector<FedChannelConnection> conns;
1056   fec_cabling.connections(conns);
1057   fed_cabling.buildFedCabling(conns);
1058 }
1059 
1060 // -----------------------------------------------------------------------------
1061 /** */
1062 void SiStripFedCablingBuilderFromDb::getFecCabling(const SiStripFedCabling& fed_cabling,
1063                                                    SiStripFecCabling& fec_cabling) {
1064   fec_cabling.buildFecCabling(fed_cabling);
1065 }
1066 
1067 // -----------------------------------------------------------------------------
1068 //
1069 void SiStripFedCablingBuilderFromDb::setIntervalFor(const edm::eventsetup::EventSetupRecordKey& key,
1070                                                     const edm::IOVSyncValue& iov_sync,
1071                                                     edm::ValidityInterval& iov_validity) {
1072   edm::ValidityInterval infinity(iov_sync.beginOfTime(), iov_sync.endOfTime());
1073   iov_validity = infinity;
1074 }