Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:08:33

0001 
0002 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0003 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
0004 #include "DQM/SiStripCommissioningDbClients/interface/FineDelayHistosUsingDb.h"
0005 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
0006 #include "DataFormats/SiStripCommon/interface/SiStripFecKey.h"
0007 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
0008 #include "FWCore/Framework/interface/ESHandle.h"
0009 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0010 #include "Geometry/CommonDetUnit/interface/GeomDetType.h"
0011 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0012 #include <Geometry/CommonTopologies/interface/Topology.h>
0013 #include <CondFormats/DataRecord/interface/SiStripFedCablingRcd.h>
0014 #include <CondFormats/SiStripObjects/interface/SiStripFedCabling.h>
0015 #include <CondFormats/SiStripObjects/interface/FedChannelConnection.h>
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017 #include <iostream>
0018 
0019 using namespace sistrip;
0020 
0021 // -----------------------------------------------------------------------------
0022 /** */
0023 FineDelayHistosUsingDb::FineDelayHistosUsingDb(const edm::ParameterSet& pset,
0024                                                DQMStore* bei,
0025                                                SiStripConfigDb* const db,
0026                                                edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> tTopoToken,
0027                                                edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> tkGeomToken)
0028     : CommissioningHistograms(pset.getParameter<edm::ParameterSet>("FineDelayParameters"), bei, sistrip::FINE_DELAY),
0029       CommissioningHistosUsingDb(db, tTopoToken, sistrip::FINE_DELAY),
0030       SamplingHistograms(pset.getParameter<edm::ParameterSet>("FineDelayParameters"), bei, sistrip::FINE_DELAY),
0031       tkGeomToken_{tkGeomToken},
0032       tracker_(nullptr) {
0033   LogTrace(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0034                          << " Constructing object...";
0035   delays_.clear();
0036 }
0037 
0038 // -----------------------------------------------------------------------------
0039 /** */
0040 FineDelayHistosUsingDb::~FineDelayHistosUsingDb() {
0041   LogTrace(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0042                          << " Destructing object...";
0043 }
0044 
0045 // -----------------------------------------------------------------------------
0046 /** */
0047 void FineDelayHistosUsingDb::configure(const edm::ParameterSet& pset, const edm::EventSetup& setup) {
0048   CommissioningHistosUsingDb::configure(pset, setup);
0049   tracker_ = &setup.getData(tkGeomToken_);
0050   SamplingHistograms::configure(pset, setup);
0051   cosmic_ = this->pset().getParameter<bool>("cosmic");
0052 }
0053 
0054 // -----------------------------------------------------------------------------
0055 /** */
0056 void FineDelayHistosUsingDb::uploadConfigurations() {
0057   if (!db()) {
0058     edm::LogWarning(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0059                                   << " NULL pointer to SiStripConfigDb interface!"
0060                                   << " Aborting upload...";
0061     return;
0062   }
0063 
0064   // Retrieve and update PLL device descriptions
0065   db()->clearDeviceDescriptions();
0066   SiStripConfigDb::DeviceDescriptionsRange devices = db()->getDeviceDescriptions(PLL);
0067   bool upload = update(devices);
0068 
0069   // Check if new PLL settings are valid
0070   if (!upload) {
0071     edm::LogWarning(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0072                                   << " Found invalid PLL settings (coarse > 15)"
0073                                   << " Aborting update to database...";
0074     return;
0075   }
0076 
0077   // Upload PLL device descriptions
0078   if (doUploadConf()) {
0079     LogTrace(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0080                            << " Uploading PLL settings to DB...";
0081     db()->uploadDeviceDescriptions();
0082     LogTrace(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0083                            << " Upload of PLL settings to DB finished!";
0084   } else {
0085     edm::LogWarning(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0086                                   << " TEST only! No PLL settings will be uploaded to DB...";
0087   }
0088 
0089   // Update FED descriptions with new ticker thresholds
0090   db()->clearFedDescriptions();
0091   SiStripConfigDb::FedDescriptionsRange feds = db()->getFedDescriptions();
0092   update(feds);
0093 
0094   // Update FED descriptions with new ticker thresholds
0095   if (doUploadConf()) {
0096     LogTrace(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0097                            << " Uploading FED ticker thresholds to DB...";
0098     db()->uploadFedDescriptions();
0099     LogTrace(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0100                            << " Upload of FED ticker thresholds to DB finished!";
0101   } else {
0102     edm::LogWarning(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0103                                   << " TEST only! No FED ticker thresholds will be uploaded to DB...";
0104   }
0105 }
0106 
0107 void FineDelayHistosUsingDb::computeDelays() {
0108   // do nothing if delays_ map is already filled
0109   if (!delays_.empty())
0110     return;
0111 
0112   // the point from which track should originate
0113   float x = 0.;
0114   float y = 0.;
0115   float z = 0.;
0116   if (cosmic_) {
0117     y = 385.;
0118     z = 20.;
0119   }  // mean entry point of cosmics
0120   GlobalPoint referenceP_ = GlobalPoint(x, y, z);
0121   const double c = 30;  // cm/ns
0122 
0123   // the reference parameters (best delay in ns, initial Latency)
0124   float bestDelay_ = 0.;
0125   if (!data().empty()) {
0126     Analyses::const_iterator iter = data().begin();
0127     bestDelay_ = dynamic_cast<SamplingAnalysis*>(iter->second)->maximum();
0128   }
0129 
0130   // Retrieve FED ids from cabling
0131   auto ids = cabling()->fedIds();
0132 
0133   // loop over the FED ids
0134   for (auto ifed = ids.begin(); ifed != ids.end(); ++ifed) {
0135     auto conns = cabling()->fedConnections(*ifed);
0136     // loop over the connections for that FED
0137     for (auto iconn = conns.begin(); iconn != conns.end(); ++iconn) {
0138       // check that this is a tracker module
0139       if (DetId(iconn->detId()).det() != DetId::Tracker)
0140         continue;
0141       // retrieve the position of that module in the tracker using the geometry
0142       // and use it to compute the distance to the reference point set in the configuration
0143       if (tracker_) {
0144         float dist = tracker_->idToDetUnit(DetId(iconn->detId()))->toLocal(referenceP_).mag();
0145         float tof = dist / c;
0146         // compute the PLL delay shift for the module as delay + tof
0147         float delay = bestDelay_ + tof;
0148         // store that in the map
0149         delays_[SiStripFecKey(
0150                     iconn->fecCrate(), iconn->fecSlot(), iconn->fecRing(), iconn->ccuAddr(), iconn->ccuChan(), 0)
0151                     .key()] = delay;
0152         edm::LogVerbatim(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__
0153                                        << "] Computed Delay to be added to PLL: " << bestDelay_ << " " << tof << " "
0154                                        << delay << std::endl;
0155       } else {
0156         edm::LogError(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0157                                     << " Tracker geometry not initialized. Impossible to compute the delays.";
0158       }
0159     }
0160   }
0161 }
0162 
0163 // -----------------------------------------------------------------------------
0164 /** */
0165 bool FineDelayHistosUsingDb::update(SiStripConfigDb::DeviceDescriptionsRange devices) {
0166   // do the core computation of delays per FED connection
0167   computeDelays();
0168 
0169   // Iterate through devices and update device descriptions
0170   uint16_t updated = 0;
0171   std::vector<SiStripFecKey> invalid;
0172   SiStripConfigDb::DeviceDescriptionsV::const_iterator idevice;
0173   for (idevice = devices.begin(); idevice != devices.end(); idevice++) {
0174     // Check device type
0175     if ((*idevice)->getDeviceType() != PLL) {
0176       continue;
0177     }
0178 
0179     // Cast to retrieve appropriate description object
0180     pllDescription* desc = dynamic_cast<pllDescription*>(*idevice);
0181     if (!desc) {
0182       continue;
0183     }
0184 
0185     // Retrieve device addresses from device description
0186     const SiStripConfigDb::DeviceAddress& addr = db()->deviceAddress(*desc);
0187 
0188     // Construct key from device description
0189     uint32_t fec_key =
0190         SiStripFecKey(addr.fecCrate_, addr.fecSlot_, addr.fecRing_, addr.ccuAddr_, addr.ccuChan_, 0).key();
0191     SiStripFecKey fec_path = SiStripFecKey(fec_key);
0192 
0193     // extract the delay from the map
0194     float delay = desc->getDelayCoarse() * 25 + desc->getDelayFine() * 25. / 24. + delays_[fec_key];
0195     int delayCoarse = int(delay / 25);
0196     int delayFine = int(round((delay - 25 * delayCoarse) * 24. / 25.));
0197     if (delayFine == 24) {
0198       delayFine = 0;
0199       ++delayCoarse;
0200     }
0201     //  maximum coarse setting
0202     if (delayCoarse > 15) {
0203       invalid.push_back(fec_key);
0204       delayCoarse = sistrip::invalid_;
0205     }
0206 
0207     // Update PLL settings
0208     if (delayCoarse != sistrip::invalid_ && delayFine != sistrip::invalid_) {
0209       std::stringstream ss;
0210       ss << "[FineDelayHistosUsingDb::" << __func__ << "]"
0211          << " Updating coarse/fine PLL settings"
0212          << " for Crate/FEC/slot/ring/CCU " << fec_path.fecCrate() << "/" << fec_path.fecSlot() << "/"
0213          << fec_path.fecRing() << "/" << fec_path.ccuAddr() << "/" << fec_path.ccuChan() << " from "
0214          << static_cast<uint16_t>(desc->getDelayCoarse()) << "/" << static_cast<uint16_t>(desc->getDelayFine());
0215       desc->setDelayCoarse(delayCoarse);
0216       desc->setDelayFine(delayFine);
0217       updated++;
0218       ss << " to " << static_cast<uint16_t>(desc->getDelayCoarse()) << "/"
0219          << static_cast<uint16_t>(desc->getDelayFine());
0220       LogTrace(mlDqmClient_) << ss.str();
0221 
0222     } else {
0223       LogTrace(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0224                              << " Unexpected PLL delay settings for Crate/FEC/slot/ring/CCU " << fec_path.fecCrate()
0225                              << "/" << fec_path.fecSlot() << "/" << fec_path.fecRing() << "/" << fec_path.ccuAddr()
0226                              << "/" << fec_path.ccuChan();
0227     }
0228   }
0229 
0230   // Check if invalid settings were found
0231   if (!invalid.empty()) {
0232     std::stringstream ss;
0233     ss << "[FineDelayHistosUsingDb::" << __func__ << "]"
0234        << " Found PLL coarse setting of 15"
0235        << " (not allowed!) for following channels"
0236        << " (Crate/FEC/slot/ring/CCU/LLD): ";
0237     std::vector<SiStripFecKey>::iterator ikey = invalid.begin();
0238     std::vector<SiStripFecKey>::iterator jkey = invalid.end();
0239     for (; ikey != jkey; ++ikey) {
0240       ss << ikey->fecCrate() << "/" << ikey->fecSlot() << "/" << ikey->fecRing() << "/" << ikey->ccuAddr() << "/"
0241          << ikey->ccuChan() << ", ";
0242     }
0243     edm::LogWarning(mlDqmClient_) << ss.str();
0244     return false;
0245   }
0246 
0247   edm::LogVerbatim(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0248                                  << " Updated PLL settings for " << updated << " modules";
0249   return true;
0250 }
0251 
0252 // -----------------------------------------------------------------------------
0253 /** */
0254 void FineDelayHistosUsingDb::update(SiStripConfigDb::FedDescriptionsRange feds) {
0255   // do the core computation of delays per FED connection
0256   computeDelays();
0257 
0258   // Retrieve FED ids from cabling
0259   auto ids = cabling()->fedIds();
0260 
0261   // loop over the FED ids
0262   for (SiStripConfigDb::FedDescriptionsV::const_iterator ifed = feds.begin(); ifed != feds.end(); ifed++) {
0263     // If FED id not found in list (from cabling), then continue
0264     if (find(ids.begin(), ids.end(), (*ifed)->getFedId()) == ids.end()) {
0265       continue;
0266     }
0267     auto conns = cabling()->fedConnections((*ifed)->getFedId());
0268     // loop over the connections for that FED
0269     for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
0270       // check that this is a tracker module
0271       if (DetId(iconn->detId()).det() != DetId::Tracker)
0272         continue;
0273       // build the Fed9UAddress for that channel. Used to update the description.
0274       Fed9U::Fed9UAddress fedChannel = Fed9U::Fed9UAddress(iconn->fedCh());
0275       // retreive the current value for the delays
0276       int fedDelayCoarse = (*ifed)->getCoarseDelay(fedChannel);
0277       int fedDelayFine = (*ifed)->getFineDelay(fedChannel);
0278       int fedDelay = int(fedDelayCoarse * 25. - fedDelayFine * 24. / 25.);
0279       // extract the delay from the map
0280       int delay = int(round(
0281           delays_[SiStripFecKey(
0282                       iconn->fecCrate(), iconn->fecSlot(), iconn->fecRing(), iconn->ccuAddr(), iconn->ccuChan(), 0)
0283                       .key()]));
0284       // compute the FED delay
0285       // this is done by substracting the best (PLL) delay to the present value (from the db)
0286       fedDelay -= delay;
0287       fedDelayCoarse = (fedDelay / 25) + 1;
0288       fedDelayFine = fedDelayCoarse * 25 - fedDelay;
0289       if (fedDelayFine == 25) {
0290         fedDelayFine = 0;
0291         --fedDelayCoarse;
0292       }
0293       // update the FED delay
0294       std::stringstream ss;
0295       ss << "[FineDelayHistosUsingDb::" << __func__ << "]"
0296          << " Updating the FED delay"
0297          << " for loop FED id/ch " << (*ifed)->getFedId() << "/" << iconn->fedCh() << " from "
0298          << (*ifed)->getCoarseDelay(fedChannel) << "/" << (*ifed)->getFineDelay(fedChannel) << " to ";
0299       (*ifed)->setDelay(fedChannel, fedDelayCoarse, fedDelayFine);
0300       ss << (*ifed)->getCoarseDelay(fedChannel) << "/" << (*ifed)->getFineDelay(fedChannel) << std::endl;
0301       LogTrace(mlDqmClient_) << ss.str();
0302     }
0303   }
0304 
0305   edm::LogVerbatim(mlDqmClient_) << "[FineDelayHistosUsingDb::" << __func__ << "]"
0306                                  << " Updated FED delay for " << ids.size() << " FEDs!";
0307 }
0308 
0309 // -----------------------------------------------------------------------------
0310 /** */
0311 void FineDelayHistosUsingDb::create(SiStripConfigDb::AnalysisDescriptionsV& desc, Analysis analysis) {
0312   SamplingAnalysis* anal = dynamic_cast<SamplingAnalysis*>(analysis->second);
0313   if (!anal) {
0314     return;
0315   }
0316 
0317   SiStripFecKey fec_key(anal->fecKey());  //@@ analysis->first
0318   SiStripFedKey fed_key(anal->fedKey());
0319 
0320   FineDelayAnalysisDescription* tmp;
0321   tmp = new FineDelayAnalysisDescription(anal->maximum(),
0322                                          anal->error(),
0323                                          0,
0324                                          0,
0325                                          0,
0326                                          0,
0327                                          0,
0328                                          0,
0329                                          db()->dbParams().partitions().begin()->second.partitionName(),
0330                                          db()->dbParams().partitions().begin()->second.runNumber(),
0331                                          anal->isValid(),
0332                                          "",
0333                                          fed_key.fedId(),
0334                                          fed_key.feUnit(),
0335                                          fed_key.feChan(),
0336                                          fed_key.fedApv());
0337 
0338   // Add comments
0339   typedef std::vector<std::string> Strings;
0340   Strings errors = anal->getErrorCodes();
0341   Strings::const_iterator istr = errors.begin();
0342   Strings::const_iterator jstr = errors.end();
0343   for (; istr != jstr; ++istr) {
0344     tmp->addComments(*istr);
0345   }
0346 
0347   // Store description
0348   desc.push_back(tmp);
0349 }