CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
LatencyHistosUsingDb.cc
Go to the documentation of this file.
1 
7 #include <iostream>
8 
9 #define MAXFEDCOARSE 15
10 
11 using namespace sistrip;
12 
13 // -----------------------------------------------------------------------------
16  DQMStore* bei,
17  SiStripConfigDb* const db,
19  : CommissioningHistograms(pset.getParameter<edm::ParameterSet>("LatencyParameters"), bei, sistrip::APV_LATENCY),
20  CommissioningHistosUsingDb(db, tTopoToken, sistrip::APV_LATENCY),
21  SamplingHistograms(pset.getParameter<edm::ParameterSet>("LatencyParameters"), bei, sistrip::APV_LATENCY) {
22  LogTrace(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
23  << " Constructing object...";
24 }
25 
26 // -----------------------------------------------------------------------------
29  LogTrace(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
30  << " Destructing object...";
31 }
32 
33 // -----------------------------------------------------------------------------
36  if (!db()) {
37  edm::LogWarning(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
38  << " NULL pointer to SiStripConfigDb interface!"
39  << " Aborting upload...";
40  return;
41  }
42 
45  bool upload = update(devices, feds);
46  // Check if new PLL settings are valid
47  if (!upload) {
48  edm::LogWarning(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
49  << " Found invalid PLL settings (coarse > 15)"
50  << " Aborting update to database...";
51  return;
52  }
53 
54  if (doUploadConf()) {
55  // Update APV descriptions with new Latency settings
56  LogTrace(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
57  << " Uploading APV settings to DB...";
59  LogTrace(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
60  << " Upload of APV settings to DB finished!";
61  // Update FED descriptions
62  LogTrace(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
63  << " Uploading FED delays to DB...";
65  LogTrace(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
66  << " Upload of FED delays to DB finished!";
67  } else {
68  edm::LogWarning(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
69  << " TEST only! No APV settings will be uploaded to DB...";
70  }
71 }
72 
73 // -----------------------------------------------------------------------------
77  // Obtain the latency from the analysis object
78  if (data().empty() || !data().begin()->second->isValid()) {
79  edm::LogVerbatim(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
80  << " Updated NO Latency settings. No analysis result available !";
81  return false;
82  }
83 
84  // Compute the minimum coarse delay
85  uint16_t minCoarseDelay = 256;
86  SiStripConfigDb::DeviceDescriptionsV::const_iterator idevice;
87  for (idevice = devices.begin(); idevice != devices.end(); idevice++) {
88  // Check device type
89  if ((*idevice)->getDeviceType() == PLL) {
90  // Cast to retrieve appropriate description object
91  pllDescription* desc = dynamic_cast<pllDescription*>(*idevice);
92  if (desc) {
93  /*
94  // add 1 to aim at 1 and not 0 (just to avoid a special 0 value for security)
95  int delayCoarse = desc->getDelayCoarse() - 1;
96  delayCoarse = delayCoarse < 0 ? 0 : delayCoarse;
97  minCoarseDelay = minCoarseDelay < delayCoarse ? minCoarseDelay : delayCoarse;
98 */
99  int delayCoarse = desc->getDelayCoarse();
100  minCoarseDelay = minCoarseDelay < delayCoarse ? minCoarseDelay : delayCoarse;
101  }
102  }
103  }
104 
105  // Compute latency and PLL shift from the sampling measurement
106  SamplingAnalysis* anal = nullptr;
107  for (CommissioningHistograms::Analysis it = data().begin(); it != data().end(); ++it) {
108  if (dynamic_cast<SamplingAnalysis*>(it->second) &&
109  dynamic_cast<SamplingAnalysis*>(it->second)->granularity() == sistrip::TRACKER)
110  anal = dynamic_cast<SamplingAnalysis*>(it->second);
111  }
112  if (!anal)
113  return false;
114  uint16_t globalLatency = uint16_t(ceil(anal->maximum() / (-25.)));
115  float globalShift = anal->maximum() - (globalLatency * (-25));
116 
117  // Compute latency and PLL shift per partition... this is an option
118  uint16_t latency = globalLatency;
119  float shift[5] = {0.};
120  for (CommissioningHistograms::Analysis it = data().begin(); it != data().end(); ++it) {
121  if (dynamic_cast<SamplingAnalysis*>(it->second) &&
122  dynamic_cast<SamplingAnalysis*>(it->second)->granularity() == sistrip::PARTITION) {
123  anal = dynamic_cast<SamplingAnalysis*>(it->second);
124  latency = uint16_t(ceil(anal->maximum() / (-25.))) > latency ? uint16_t(ceil(anal->maximum() / (-25.))) : latency;
125  }
126  }
127  for (CommissioningHistograms::Analysis it = data().begin(); it != data().end(); ++it) {
128  if (dynamic_cast<SamplingAnalysis*>(it->second) &&
129  dynamic_cast<SamplingAnalysis*>(it->second)->granularity() == sistrip::PARTITION) {
130  anal = dynamic_cast<SamplingAnalysis*>(it->second);
131  shift[SiStripFecKey(anal->fecKey()).fecCrate()] = anal->maximum() - (latency * (-25));
132  }
133  }
134  if (!perPartition_) {
135  latency = globalLatency;
136  for (int i = 0; i < 5; i++)
137  shift[i] = globalShift;
138  }
139 
140  // Take into account the minimum coarse delay to bring the coarse delay down
141  // the same quantity is subtracted to the coarse delay of each APV
142  latency -= minCoarseDelay;
143 
144  // Iterate through devices and update device descriptions
145  uint16_t updatedAPV = 0;
146  uint16_t updatedPLL = 0;
147  std::vector<SiStripFecKey> invalid;
148  for (idevice = devices.begin(); idevice != devices.end(); idevice++) {
149  // Check device type
150  if ((*idevice)->getDeviceType() != APV25) {
151  continue;
152  }
153  // Cast to retrieve appropriate description object
154  apvDescription* desc = dynamic_cast<apvDescription*>(*idevice);
155  if (!desc) {
156  continue;
157  }
158  // Retrieve device addresses from device description
160  // Do it!
161  std::stringstream ss;
162  ss << "[LatencyHistosUsingDb::" << __func__ << "]"
163  << " Updating latency APV settings for crate/FEC/slot/ring/CCU/i2cAddr " << addr.fecCrate_ << "/"
164  << addr.fecSlot_ << "/" << addr.fecRing_ << "/" << addr.ccuAddr_ << "/" << addr.ccuChan_ << "/" << addr.i2cAddr_
165  << " from " << static_cast<uint16_t>(desc->getLatency());
166  desc->setLatency(latency);
167  ss << " to " << static_cast<uint16_t>(desc->getLatency());
168  LogTrace(mlDqmClient_) << ss.str();
169  updatedAPV++;
170  }
171 
172  // Change also the PLL delay
173  for (idevice = devices.begin(); idevice != devices.end(); idevice++) {
174  // Check device type
175  if ((*idevice)->getDeviceType() != PLL) {
176  continue;
177  }
178  // Cast to retrieve appropriate description object
179  pllDescription* desc = dynamic_cast<pllDescription*>(*idevice);
180  if (!desc) {
181  continue;
182  }
183  if (desc->getDelayCoarse() >= 15) {
184  continue;
185  }
186  // Retrieve device addresses from device description
188  // Construct key from device description
189  uint32_t fec_key =
190  SiStripFecKey(addr.fecCrate_, addr.fecSlot_, addr.fecRing_, addr.ccuAddr_, addr.ccuChan_, 0).key();
191  SiStripFecKey fec_path = SiStripFecKey(fec_key);
192  // Do it!
193  float delay = desc->getDelayCoarse() * 25 + desc->getDelayFine() * 25. / 24. + shift[addr.fecCrate_];
194  int delayCoarse = int(delay / 25);
195  int delayFine = int(round((delay - 25 * delayCoarse) * 24. / 25.));
196  if (delayFine == 24) {
197  delayFine = 0;
198  ++delayCoarse;
199  }
200  delayCoarse -= minCoarseDelay;
201  // maximum coarse setting
202  if (delayCoarse > 15) {
203  invalid.push_back(fec_key);
204  delayCoarse = sistrip::invalid_;
205  }
206  // Update PLL settings
207  if (delayCoarse != sistrip::invalid_ && delayFine != sistrip::invalid_) {
208  std::stringstream ss;
209  ss << "[LatencyHistosUsingDb::" << __func__ << "]"
210  << " Updating coarse/fine PLL settings"
211  << " for Crate/FEC/slot/ring/CCU " << fec_path.fecCrate() << "/" << fec_path.fecSlot() << "/"
212  << fec_path.fecRing() << "/" << fec_path.ccuAddr() << "/" << fec_path.ccuChan() << " from "
213  << static_cast<uint16_t>(desc->getDelayCoarse()) << "/" << static_cast<uint16_t>(desc->getDelayFine());
214  desc->setDelayCoarse(delayCoarse);
215  desc->setDelayFine(delayFine);
216  updatedPLL++;
217  ss << " to " << static_cast<uint16_t>(desc->getDelayCoarse()) << "/"
218  << static_cast<uint16_t>(desc->getDelayFine());
219  LogTrace(mlDqmClient_) << ss.str();
220  }
221  }
222 
223  // Retrieve FED ids from cabling
224  auto ids = cabling()->fedIds();
225 
226  // loop over the FED ids to determine min and max values of coarse delay
227  uint16_t minDelay = 256;
228  uint16_t maxDelay = 0;
229  uint16_t fedDelayCoarse = 0;
230  for (auto ifed = feds.begin(); ifed != feds.end(); ifed++) {
231  // If FED id not found in list (from cabling), then continue
232  if (find(ids.begin(), ids.end(), (*ifed)->getFedId()) == ids.end()) {
233  continue;
234  }
235  auto conns = cabling()->fedConnections((*ifed)->getFedId());
236  // loop over the connections for that FED
237  for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
238  // check that this is a tracker module
239  if (DetId(iconn->detId()).det() != DetId::Tracker)
240  continue;
241  // build the Fed9UAddress for that channel. Used to update the description.
242  Fed9U::Fed9UAddress fedChannel = Fed9U::Fed9UAddress(iconn->fedCh());
243  // retreive the current value for the delays
244  fedDelayCoarse = (*ifed)->getCoarseDelay(fedChannel);
245  // update min and max
246  minDelay = minDelay < fedDelayCoarse ? minDelay : fedDelayCoarse;
247  maxDelay = maxDelay > fedDelayCoarse ? maxDelay : fedDelayCoarse;
248  }
249  }
250 
251  // compute the FED coarse global offset
252  int offset = (10 - minDelay) * 25; // try to ensure 10BX room for later fine delay scan
253  if (maxDelay + (offset / 25) > MAXFEDCOARSE)
254  offset = (MAXFEDCOARSE - maxDelay) * 25; // otherwise, take the largest possible
255 
256  // loop over the FED ids
257  for (SiStripConfigDb::FedDescriptionsV::const_iterator ifed = feds.begin(); ifed != feds.end(); ifed++) {
258  // If FED id not found in list (from cabling), then continue
259  if (find(ids.begin(), ids.end(), (*ifed)->getFedId()) == ids.end()) {
260  continue;
261  }
262  auto conns = cabling()->fedConnections((*ifed)->getFedId());
263  // loop over the connections for that FED
264  for (auto iconn = conns.begin(); iconn != conns.end(); iconn++) {
265  // check that this is a tracker module
266  if (DetId(iconn->detId()).det() != DetId::Tracker)
267  continue;
268  // build the Fed9UAddress for that channel. Used to update the description.
269  Fed9U::Fed9UAddress fedChannel = Fed9U::Fed9UAddress(iconn->fedCh());
270  // retreive the current value for the delays
271  int fedDelayCoarse = (*ifed)->getCoarseDelay(fedChannel);
272  int fedDelayFine = (*ifed)->getFineDelay(fedChannel);
273  // compute the FED delay
274  // this is done by substracting the best (PLL) delay to the present value (from the db)
275  int fedDelay = int(fedDelayCoarse * 25. - fedDelayFine * 24. / 25. - round(shift[iconn->fecCrate()]) + offset);
276  fedDelayCoarse = (fedDelay / 25) + 1;
277  fedDelayFine = fedDelayCoarse * 25 - fedDelay;
278  if (fedDelayFine == 25) {
279  fedDelayFine = 0;
280  --fedDelayCoarse;
281  }
282  // update the FED delay
283  std::stringstream ss;
284  ss << "[LatencyHistosUsingDb::" << __func__ << "]"
285  << " Updating the FED delay"
286  << " for loop FED id/ch " << (*ifed)->getFedId() << "/" << iconn->fedCh() << " from "
287  << (*ifed)->getCoarseDelay(fedChannel) << "/" << (*ifed)->getFineDelay(fedChannel) << " to ";
288  (*ifed)->setDelay(fedChannel, fedDelayCoarse, fedDelayFine);
289  ss << (*ifed)->getCoarseDelay(fedChannel) << "/" << (*ifed)->getFineDelay(fedChannel);
290  LogTrace(mlDqmClient_) << ss.str();
291  }
292  }
293 
294  // Summary output
295  edm::LogVerbatim(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "]"
296  << " Updated FED delays for " << ids.size() << " FEDs!";
297 
298  // Check if invalid settings were found
299  if (!invalid.empty()) {
300  std::stringstream ss;
301  ss << "[LatencyHistosUsingDb::" << __func__ << "]"
302  << " Found PLL coarse setting of 15"
303  << " (not allowed!) for following channels"
304  << " (Crate/FEC/slot/ring/CCU/LLD): ";
305  std::vector<SiStripFecKey>::iterator ikey = invalid.begin();
306  std::vector<SiStripFecKey>::iterator jkey = invalid.end();
307  for (; ikey != jkey; ++ikey) {
308  ss << ikey->fecCrate() << "/" << ikey->fecSlot() << "/" << ikey->fecRing() << "/" << ikey->ccuAddr() << "/"
309  << ikey->ccuChan() << ", ";
310  }
311  edm::LogWarning(mlDqmClient_) << ss.str();
312  return false;
313  }
314 
315  // Summary output
316  edm::LogVerbatim(mlDqmClient_) << "[LatencyHistosUsingDb::" << __func__ << "] "
317  << "Updated settings for " << updatedAPV << " APV devices and " << updatedPLL
318  << " PLL devices.";
319  return true;
320 }
321 
322 // -----------------------------------------------------------------------------
325  SamplingAnalysis* anal = dynamic_cast<SamplingAnalysis*>(analysis->second);
326  if (!anal) {
327  return;
328  }
329 
330  SiStripFecKey fec_key(anal->fecKey()); //@@ analysis->first
331  SiStripFedKey fed_key(anal->fedKey());
332 
333  uint16_t latency = static_cast<uint16_t>((anal->maximum() / (-25.)) + 0.5);
334 
335  ApvLatencyAnalysisDescription* tmp;
336  tmp = new ApvLatencyAnalysisDescription(latency,
337  0,
338  0,
339  0,
340  0,
341  0,
342  0,
343  db()->dbParams().partitions().begin()->second.partitionName(),
344  db()->dbParams().partitions().begin()->second.runNumber(),
345  anal->isValid(),
346  "",
347  fed_key.fedId(),
348  fed_key.feUnit(),
349  fed_key.feChan(),
350  fed_key.fedApv());
351 
352  // Add comments
353  typedef std::vector<std::string> Strings;
354  Strings errors = anal->getErrorCodes();
355  Strings::const_iterator istr = errors.begin();
356  Strings::const_iterator jstr = errors.end();
357  for (; istr != jstr; ++istr) {
358  tmp->addComments(*istr);
359  }
360 
361  // Store description
362  desc.push_back(tmp);
363 }
364 
367  perPartition_ = this->pset().getParameter<bool>("OptimizePerPartition");
368 }
Log< level::Info, true > LogVerbatim
constexpr int32_t ceil(float num)
Analysis for latency run.
const uint32_t & fedKey() const
Analyses & data(bool getMaskedData=false)
const uint16_t & fecRing() const
A container class for generic run and event-related info, information required by the commissioning a...
Definition: SiStripFedKey.h:56
const edm::ParameterSet & pset() const
virtual bool isValid() const
FedDescriptionsRange getFedDescriptions(std::string partition="")
std::vector< std::string > Strings
Definition: MsgTools.h:18
bool update(SiStripConfigDb::DeviceDescriptionsRange, SiStripConfigDb::FedDescriptionsRange)
tuple db
Definition: EcalCondDB.py:153
FedDescriptions::range FedDescriptionsRange
static const char mlDqmClient_[]
void uploadConfigurations() override
const uint16_t & fecSlot() const
void configure(const edm::ParameterSet &, const edm::EventSetup &) override
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
#define LogTrace(id)
const uint32_t & key() const
Definition: SiStripKey.h:120
Utility class that identifies a position within the strip tracker control structure, down to the level of an APV25.
Definition: SiStripFecKey.h:45
U second(std::pair< T, U > const &p)
const_iterator_range partitions() const
#define MAXFEDCOARSE
FedsConstIterRange fedIds() const
DeviceDescriptions::range DeviceDescriptionsRange
An interface class to the DeviceFactory.
const uint32_t & fecKey() const
DeviceAddress deviceAddress(const deviceDescription &)
const uint16_t & fecCrate() const
Definition: DetId.h:17
void create(SiStripConfigDb::AnalysisDescriptionsV &, Analysis) override
const SiStripDbParams & dbParams() const
void configure(const edm::ParameterSet &, const edm::EventSetup &) override
void uploadFedDescriptions(std::string partition="")
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
const uint16_t & ccuAddr() const
static const uint16_t invalid_
Definition: Constants.h:16
LatencyHistosUsingDb(const edm::ParameterSet &pset, DQMStore *, SiStripConfigDb *const, edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken)
ConnsConstIterRange fedConnections(uint16_t fed_id) const
std::vector< AnalysisDescription * > AnalysisDescriptionsV
static unsigned int const shift
const uint16_t & ccuChan() const
const float & maximum() const
SiStripConfigDb *const db() const
DeviceDescriptionsRange getDeviceDescriptions(std::string partition="")
Log< level::Warning, false > LogWarning
void uploadDeviceDescriptions(std::string partition="")
tmp
align.sh
Definition: createJobs.py:716
SiStripFedCabling *const cabling() const
const VString & getErrorCodes() const