CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DQM/SiStripCommissioningDbClients/src/FineDelayHistosUsingDb.cc

Go to the documentation of this file.
00001 // Last commit: $Id: FineDelayHistosUsingDb.cc,v 1.18 2009/11/10 14:49:02 lowette Exp $
00002 
00003 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00004 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00005 #include "DQM/SiStripCommissioningDbClients/interface/FineDelayHistosUsingDb.h"
00006 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00007 #include "DataFormats/SiStripCommon/interface/SiStripFecKey.h"
00008 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00009 #include "FWCore/Framework/interface/ESHandle.h"
00010 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00011 #include "Geometry/CommonDetUnit/interface/GeomDetType.h"
00012 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00013 #include <Geometry/CommonTopologies/interface/Topology.h>
00014 #include <CondFormats/DataRecord/interface/SiStripFedCablingRcd.h>
00015 #include <CondFormats/SiStripObjects/interface/SiStripFedCabling.h>
00016 #include <CondFormats/SiStripObjects/interface/FedChannelConnection.h>
00017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00018 #include <iostream>
00019 
00020 using namespace sistrip;
00021 
00022 // -----------------------------------------------------------------------------
00024 FineDelayHistosUsingDb::FineDelayHistosUsingDb( const edm::ParameterSet & pset,
00025                                                 DQMStore* bei,
00026                                                 SiStripConfigDb* const db ) 
00027   : CommissioningHistograms( pset.getParameter<edm::ParameterSet>("FineDelayParameters"),
00028                              bei,
00029                              sistrip::FINE_DELAY ),
00030     CommissioningHistosUsingDb( db,
00031                              sistrip::FINE_DELAY ),
00032     SamplingHistograms( pset.getParameter<edm::ParameterSet>("FineDelayParameters"),
00033                         bei,
00034                         sistrip::FINE_DELAY ),
00035     tracker_(0)
00036 {
00037   LogTrace(mlDqmClient_) 
00038     << "[FineDelayHistosUsingDb::" << __func__ << "]"
00039     << " Constructing object...";
00040   delays_.clear();
00041 }
00042 
00043 // -----------------------------------------------------------------------------
00045 FineDelayHistosUsingDb::~FineDelayHistosUsingDb() {
00046   LogTrace(mlDqmClient_) 
00047     << "[FineDelayHistosUsingDb::" << __func__ << "]"
00048     << " Destructing object...";
00049 }
00050 
00051 // -----------------------------------------------------------------------------
00053 void FineDelayHistosUsingDb::configure( const edm::ParameterSet& pset, 
00054                                         const edm::EventSetup& setup ) {
00055   // get geometry
00056   edm::ESHandle<TrackerGeometry> estracker;
00057   setup.get<TrackerDigiGeometryRecord>().get(estracker);
00058   tracker_=&(* estracker);
00059   SamplingHistograms::configure(pset,setup);
00060   cosmic_ = this->pset().getParameter<bool>("cosmic");
00061 }
00062 
00063 // -----------------------------------------------------------------------------
00065 void FineDelayHistosUsingDb::uploadConfigurations() {
00066   
00067   if ( !db() ) {
00068     edm::LogWarning(mlDqmClient_) 
00069       << "[FineDelayHistosUsingDb::" << __func__ << "]"
00070       << " NULL pointer to SiStripConfigDb interface!"
00071       << " Aborting upload...";
00072     return;
00073   }
00074   
00075   // Retrieve and update PLL device descriptions
00076   db()->clearDeviceDescriptions(); 
00077   SiStripConfigDb::DeviceDescriptionsRange devices = db()->getDeviceDescriptions( PLL ); 
00078   bool upload = update( devices );
00079     
00080   // Check if new PLL settings are valid 
00081   if ( !upload ) {
00082     edm::LogWarning(mlDqmClient_) 
00083       << "[FineDelayHistosUsingDb::" << __func__ << "]"
00084       << " Found invalid PLL settings (coarse > 15)"
00085       << " Aborting update to database...";
00086     return;
00087   }
00088     
00089   // Upload PLL device descriptions
00090   if ( doUploadConf() ) { 
00091     LogTrace(mlDqmClient_) 
00092       << "[FineDelayHistosUsingDb::" << __func__ << "]"
00093       << " Uploading PLL settings to DB...";
00094     db()->uploadDeviceDescriptions(); 
00095     LogTrace(mlDqmClient_) 
00096       << "[FineDelayHistosUsingDb::" << __func__ << "]"
00097       << " Upload of PLL settings to DB finished!";
00098   } else {
00099     edm::LogWarning(mlDqmClient_) 
00100       << "[FineDelayHistosUsingDb::" << __func__ << "]"
00101       << " TEST only! No PLL settings will be uploaded to DB...";
00102   }
00103 
00104   // Update FED descriptions with new ticker thresholds
00105   db()->clearFedDescriptions(); 
00106   SiStripConfigDb::FedDescriptionsRange feds = db()->getFedDescriptions(); 
00107   update( feds );
00108     
00109   // Update FED descriptions with new ticker thresholds
00110   if ( doUploadConf() ) { 
00111     LogTrace(mlDqmClient_) 
00112       << "[FineDelayHistosUsingDb::" << __func__ << "]"
00113       << " Uploading FED ticker thresholds to DB...";
00114     db()->uploadFedDescriptions(); 
00115     LogTrace(mlDqmClient_) 
00116       << "[FineDelayHistosUsingDb::" << __func__ << "]"
00117       << " Upload of FED ticker thresholds to DB finished!";
00118   } else {
00119     edm::LogWarning(mlDqmClient_) 
00120       << "[FineDelayHistosUsingDb::" << __func__ << "]"
00121       << " TEST only! No FED ticker thresholds will be uploaded to DB...";
00122   }
00123 
00124 }
00125 
00126 void FineDelayHistosUsingDb::computeDelays() {
00127   // do nothing if delays_ map is already filled
00128   if(delays_.size()>0) return;
00129 
00130   // the point from which track should originate
00131   float x = 0.; float y = 0.; float z = 0.;
00132   if(cosmic_) { y = 385.; z=20.; } // mean entry point of cosmics
00133   GlobalPoint referenceP_ = GlobalPoint(x,y,z);
00134   const double c = 30; // cm/ns
00135   
00136   // the reference parameters (best delay in ns, initial Latency)
00137   float bestDelay_ = 0.;
00138   if(data().size()) {
00139     Analyses::const_iterator iter = data().begin();
00140     bestDelay_ = dynamic_cast<SamplingAnalysis*>(iter->second)->maximum();
00141   }
00142 
00143   // Retrieve FED ids from cabling
00144   std::vector<uint16_t> ids = cabling()->feds() ;
00145   
00146   // loop over the FED ids
00147   for (std::vector<uint16_t>::const_iterator ifed = ids.begin(); ifed != ids.end(); ++ifed) {
00148     const std::vector<FedChannelConnection>& conns = cabling()->connections(*ifed);
00149     // loop over the connections for that FED 
00150     for ( std::vector<FedChannelConnection>::const_iterator iconn = conns.begin(); iconn != conns.end(); iconn++ ) {
00151       // check that this is a tracker module
00152       if(DetId(iconn->detId()).det()!=DetId::Tracker) continue;
00153       // retrieve the position of that module in the tracker using the geometry
00154       // and use it to compute the distance to the reference point set in the configuration
00155       if(tracker_) {
00156         float dist = tracker_->idToDetUnit(DetId(iconn->detId()))->toLocal(referenceP_).mag(); 
00157         float tof  = dist/c ;
00158         // compute the PLL delay shift for the module as delay + tof 
00159         float delay = bestDelay_+tof;
00160         // store that in the map
00161         delays_[SiStripFecKey( iconn->fecCrate(),
00162                                iconn->fecSlot(),
00163                                iconn->fecRing(),
00164                                iconn->ccuAddr(),
00165                                iconn->ccuChan(), 0 ).key()] = delay;
00166         edm::LogVerbatim(mlDqmClient_)
00167             << "[FineDelayHistosUsingDb::" << __func__ << "] Computed Delay to be added to PLL: "
00168             << bestDelay_ << " " << tof << " " << delay << std::endl;
00169       } else {
00170         edm::LogError(mlDqmClient_)
00171           << "[FineDelayHistosUsingDb::" << __func__ << "]"
00172           << " Tracker geometry not initialized. Impossible to compute the delays.";
00173       }
00174     }
00175   }
00176 }
00177 
00178 // -----------------------------------------------------------------------------
00180 bool FineDelayHistosUsingDb::update( SiStripConfigDb::DeviceDescriptionsRange devices ) {
00181 
00182   // do the core computation of delays per FED connection
00183   computeDelays();
00184 
00185   // Iterate through devices and update device descriptions
00186   uint16_t updated = 0;
00187   std::vector<SiStripFecKey> invalid;
00188   SiStripConfigDb::DeviceDescriptionsV::const_iterator idevice;
00189   for ( idevice = devices.begin(); idevice != devices.end(); idevice++ ) {
00190     
00191     // Check device type
00192     if ( (*idevice)->getDeviceType() != PLL ) { continue; }
00193     
00194     // Cast to retrieve appropriate description object
00195     pllDescription* desc = dynamic_cast<pllDescription*>( *idevice ); 
00196     if ( !desc ) { continue; }
00197     
00198     // Retrieve device addresses from device description
00199     const SiStripConfigDb::DeviceAddress& addr = db()->deviceAddress(*desc);
00200 
00201     // Construct key from device description
00202     uint32_t fec_key = SiStripFecKey( addr.fecCrate_,
00203                                       addr.fecSlot_, 
00204                                       addr.fecRing_,
00205                                       addr.ccuAddr_, 
00206                                       addr.ccuChan_,
00207                                       0 ).key();
00208     SiStripFecKey fec_path = SiStripFecKey( fec_key );
00209     
00210     // extract the delay from the map
00211     float delay = desc->getDelayCoarse()*25+desc->getDelayFine()*25./24. + delays_[fec_key];
00212     int delayCoarse = int(delay/25);
00213     int delayFine   = int(round((delay-25*delayCoarse)*24./25.));
00214     if(delayFine==24) { delayFine=0; ++delayCoarse; }
00215     //  maximum coarse setting
00216     if ( delayCoarse > 15 ) { invalid.push_back(fec_key); delayCoarse = sistrip::invalid_; }
00217                     
00218     // Update PLL settings
00219     if ( delayCoarse != sistrip::invalid_ && 
00220          delayFine != sistrip::invalid_ ) { 
00221       
00222       std::stringstream ss;
00223       ss << "[FineDelayHistosUsingDb::" << __func__ << "]"
00224          << " Updating coarse/fine PLL settings"
00225          << " for Crate/FEC/slot/ring/CCU "
00226          << fec_path.fecCrate() << "/"
00227          << fec_path.fecSlot() << "/"
00228          << fec_path.fecRing() << "/"
00229          << fec_path.ccuAddr() << "/"
00230          << fec_path.ccuChan() 
00231          << " from "
00232          << static_cast<uint16_t>( desc->getDelayCoarse() ) << "/" 
00233          << static_cast<uint16_t>( desc->getDelayFine() );
00234       desc->setDelayCoarse(delayCoarse);
00235       desc->setDelayFine(delayFine);
00236       updated++;
00237       ss << " to "
00238          << static_cast<uint16_t>( desc->getDelayCoarse() ) << "/" 
00239          << static_cast<uint16_t>( desc->getDelayFine() );
00240       LogTrace(mlDqmClient_) << ss.str();
00241 
00242     } else {
00243       LogTrace(mlDqmClient_) 
00244         << "[FineDelayHistosUsingDb::" << __func__ << "]"
00245         << " Unexpected PLL delay settings for Crate/FEC/slot/ring/CCU " 
00246         << fec_path.fecCrate() << "/"
00247         << fec_path.fecSlot() << "/"
00248         << fec_path.fecRing() << "/"
00249         << fec_path.ccuAddr() << "/"
00250         << fec_path.ccuChan();
00251     }
00252 
00253   }
00254 
00255   // Check if invalid settings were found
00256   if ( !invalid.empty() ) {
00257     std::stringstream ss;
00258     ss << "[FineDelayHistosUsingDb::" << __func__ << "]"
00259        << " Found PLL coarse setting of 15" 
00260        << " (not allowed!) for following channels"
00261        << " (Crate/FEC/slot/ring/CCU/LLD): ";
00262     std::vector<SiStripFecKey>::iterator ikey = invalid.begin();
00263     std::vector<SiStripFecKey>::iterator jkey = invalid.end();
00264     for ( ; ikey != jkey; ++ikey ) {
00265       ss << ikey->fecCrate() << "/"
00266          << ikey->fecSlot() << "/"
00267          << ikey->fecRing() << "/"
00268          << ikey->ccuAddr() << "/"
00269          << ikey->ccuChan() << ", ";
00270     }
00271     edm::LogWarning(mlDqmClient_) << ss.str();
00272     return false;
00273   }
00274   
00275   edm::LogVerbatim(mlDqmClient_) 
00276     << "[FineDelayHistosUsingDb::" << __func__ << "]"
00277     << " Updated PLL settings for " 
00278     << updated << " modules";
00279   return true;
00280 }
00281 
00282 // -----------------------------------------------------------------------------
00284 void FineDelayHistosUsingDb::update( SiStripConfigDb::FedDescriptionsRange feds ) {
00285 
00286   // do the core computation of delays per FED connection
00287   computeDelays();
00288 
00289   // Retrieve FED ids from cabling
00290   std::vector<uint16_t> ids = cabling()->feds() ;
00291   
00292   // loop over the FED ids
00293   for ( SiStripConfigDb::FedDescriptionsV::const_iterator ifed = feds.begin(); ifed != feds.end(); ifed++ ) {
00294     // If FED id not found in list (from cabling), then continue
00295     if ( find( ids.begin(), ids.end(), (*ifed)->getFedId() ) == ids.end() ) { continue; }
00296     const std::vector<FedChannelConnection>& conns = cabling()->connections((*ifed)->getFedId());
00297     // loop over the connections for that FED 
00298     for ( std::vector<FedChannelConnection>::const_iterator iconn = conns.begin(); iconn != conns.end(); iconn++ ) {
00299       // check that this is a tracker module
00300       if(DetId(iconn->detId()).det()!=DetId::Tracker) continue;
00301       // build the Fed9UAddress for that channel. Used to update the description.
00302       Fed9U::Fed9UAddress fedChannel = Fed9U::Fed9UAddress(iconn->fedCh()); 
00303       // retreive the current value for the delays
00304       int fedDelayCoarse = (*ifed)->getCoarseDelay(fedChannel);
00305       int fedDelayFine = (*ifed)->getFineDelay(fedChannel);
00306       int fedDelay = int(fedDelayCoarse*25. - fedDelayFine*24./25.);
00307       // extract the delay from the map
00308       int delay = int(round( delays_[SiStripFecKey( iconn->fecCrate(),
00309                                                     iconn->fecSlot(),
00310                                                     iconn->fecRing(),
00311                                                     iconn->ccuAddr(),
00312                                                     iconn->ccuChan(), 0 ).key()]));
00313       // compute the FED delay
00314       // this is done by substracting the best (PLL) delay to the present value (from the db)
00315       fedDelay -= delay;
00316       fedDelayCoarse = (fedDelay/25)+1;
00317       fedDelayFine = fedDelayCoarse*25-fedDelay;
00318       if(fedDelayFine==25) { fedDelayFine = 0; --fedDelayCoarse; }
00319       // update the FED delay
00320       std::stringstream ss;
00321       ss << "[FineDelayHistosUsingDb::" << __func__ << "]"
00322          << " Updating the FED delay"
00323          << " for loop FED id/ch "
00324          << (*ifed)->getFedId() << "/" << iconn->fedCh()
00325          << " from "
00326          << (*ifed)->getCoarseDelay( fedChannel) << "/" << (*ifed)->getFineDelay( fedChannel)
00327          << " to ";
00328       (*ifed)->setDelay(fedChannel, fedDelayCoarse, fedDelayFine);
00329       ss << (*ifed)->getCoarseDelay(fedChannel) << "/" << (*ifed)->getFineDelay( fedChannel) << std::endl;
00330       LogTrace(mlDqmClient_) << ss.str();
00331     }
00332   }
00333 
00334   edm::LogVerbatim(mlDqmClient_)
00335     << "[FineDelayHistosUsingDb::" << __func__ << "]"
00336     << " Updated FED delay for " << ids.size() << " FEDs!";
00337 
00338 }
00339 
00340 // -----------------------------------------------------------------------------
00342 void FineDelayHistosUsingDb::create( SiStripConfigDb::AnalysisDescriptionsV& desc,
00343                                      Analysis analysis ) {
00344 
00345   SamplingAnalysis* anal = dynamic_cast<SamplingAnalysis*>( analysis->second );
00346   if ( !anal ) { return; }
00347   
00348   SiStripFecKey fec_key( anal->fecKey() ); //@@ analysis->first
00349   SiStripFedKey fed_key( anal->fedKey() );
00350 
00351   FineDelayAnalysisDescription* tmp;
00352   tmp = new FineDelayAnalysisDescription( anal->maximum(),
00353                                           anal->error(),
00354                                           0,
00355                                           0,
00356                                           0,
00357                                           0,
00358                                           0,
00359                                           0, 
00360                                           db()->dbParams().partitions().begin()->second.partitionName(),
00361                                           db()->dbParams().partitions().begin()->second.runNumber(),
00362                                           anal->isValid(),
00363                                           "",
00364                                           fed_key.fedId(),
00365                                           fed_key.feUnit(),
00366                                           fed_key.feChan(),
00367                                           fed_key.fedApv() );
00368     
00369   // Add comments
00370   typedef std::vector<std::string> Strings;
00371   Strings errors = anal->getErrorCodes();
00372   Strings::const_iterator istr = errors.begin();
00373   Strings::const_iterator jstr = errors.end();
00374   for ( ; istr != jstr; ++istr ) { tmp->addComments( *istr ); }
00375     
00376   // Store description
00377   desc.push_back( tmp );
00378 
00379 }