CMS 3D CMS Logo

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