Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 
0002 #include "OnlineDB/SiStripConfigDb/interface/SiStripConfigDb.h"
0003 #include "DataFormats/SiStripCommon/interface/SiStripEnumsAndStrings.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 
0006 using namespace std;
0007 using namespace sistrip;
0008 
0009 // -----------------------------------------------------------------------------
0010 /** T_UNKNOWN,
0011     T_ANALYSIS_FASTFEDCABLING,
0012     T_ANALYSIS_TIMING,
0013     T_ANALYSIS_OPTOSCAN,
0014     T_ANALYSIS_VPSPSCAN,
0015     T_ANALYSIS_PEDESTAL,
0016     T_ANALYSIS_APVLATENCY,
0017     T_ANALYSIS_FINEDELAY,
0018     T_ANALYSIS_CALIBRATION.
0019 */
0020 SiStripConfigDb::AnalysisDescriptionsRange SiStripConfigDb::getAnalysisDescriptions(AnalysisType analysis_type,
0021                                                                                     std::string partition) {
0022   // Check
0023   if ((!dbParams_.usingDbCache() && !deviceFactory(__func__)) ||
0024       (dbParams_.usingDbCache() && !databaseCache(__func__))) {
0025     return analyses_.emptyRange();
0026   }
0027 
0028   try {
0029     if (!dbParams_.usingDbCache()) {
0030       SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
0031       SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
0032       for (; iter != jter; ++iter) {
0033         if (partition.empty() || partition == iter->second.partitionName()) {
0034           if (iter->second.partitionName() == SiStripPartition::defaultPartitionName_) {
0035             continue;
0036           }
0037 
0038           AnalysisDescriptionsRange range = analyses_.find(iter->second.partitionName());
0039           if (range == analyses_.emptyRange()) {
0040             AnalysisDescriptionsV tmp1;
0041             if (analysis_type == AnalysisDescription::T_ANALYSIS_FASTFEDCABLING) {
0042               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0043                                                                  iter->second.fastCablingVersion().first,
0044                                                                  iter->second.fastCablingVersion().second,
0045                                                                  analysis_type);
0046             } else if (analysis_type == AnalysisDescription::T_ANALYSIS_TIMING) {
0047               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0048                                                                  iter->second.apvTimingVersion().first,
0049                                                                  iter->second.apvTimingVersion().second,
0050                                                                  analysis_type);
0051             } else if (analysis_type == AnalysisDescription::T_ANALYSIS_OPTOSCAN) {
0052               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0053                                                                  iter->second.optoScanVersion().first,
0054                                                                  iter->second.optoScanVersion().second,
0055                                                                  analysis_type);
0056             } else if (analysis_type == AnalysisDescription::T_ANALYSIS_VPSPSCAN) {
0057               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0058                                                                  iter->second.vpspScanVersion().first,
0059                                                                  iter->second.vpspScanVersion().second,
0060                                                                  analysis_type);
0061             } else if (analysis_type == AnalysisDescription::T_ANALYSIS_CALIBRATION) {
0062               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0063                                                                  iter->second.apvCalibVersion().first,
0064                                                                  iter->second.apvCalibVersion().second,
0065                                                                  analysis_type);
0066             } else if (analysis_type == AnalysisDescription::T_ANALYSIS_PEDESTALS) {
0067               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0068                                                                  iter->second.pedestalsVersion().first,
0069                                                                  iter->second.pedestalsVersion().second,
0070                                                                  analysis_type);
0071             } else if (analysis_type == AnalysisDescription::T_ANALYSIS_PEDSFULLNOISE) {
0072               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0073                                                                  iter->second.pedestalsVersion().first,
0074                                                                  iter->second.pedestalsVersion().second,
0075                                                                  analysis_type);
0076             } else if (analysis_type == AnalysisDescription::T_ANALYSIS_APVLATENCY) {
0077               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0078                                                                  iter->second.apvLatencyVersion().first,
0079                                                                  iter->second.apvLatencyVersion().second,
0080                                                                  analysis_type);
0081             } else if (analysis_type == AnalysisDescription::T_ANALYSIS_FINEDELAY) {
0082               tmp1 = deviceFactory(__func__)->getAnalysisHistory(iter->second.partitionName(),
0083                                                                  iter->second.fineDelayVersion().first,
0084                                                                  iter->second.fineDelayVersion().second,
0085                                                                  analysis_type);
0086             } else {
0087               std::stringstream ss;
0088               ss << "[SiStripConfigDb::" << __func__ << "]"
0089                  << " Unexpected analysis type \"" << analysisType(analysis_type) << "\"! Aborting download...";
0090               edm::LogWarning(mlConfigDb_) << ss.str();
0091               return analyses_.emptyRange();
0092             }
0093 
0094             // Make local copy
0095             AnalysisDescriptionsV tmp2;
0096             CommissioningAnalysisFactory::vectorCopy(tmp1, tmp2);
0097 
0098             // Add to cache
0099             analyses_.loadNext(iter->second.partitionName(), tmp2);
0100 
0101             // Some debug
0102             AnalysisDescriptionsRange anals = analyses_.find(iter->second.partitionName());
0103             std::stringstream ss;
0104             ss << "[SiStripConfigDb::" << __func__ << "]"
0105                << " Downloaded " << anals.size() << " analysis descriptions of type \"" << analysisType(analysis_type)
0106                << "\" to local cache for partition \"" << iter->second.partitionName() << "\"" << std::endl;
0107             ss << "[SiStripConfigDb::" << __func__ << "]"
0108                << " Cache holds analysis descriptions for " << analyses_.size() << " partitions.";
0109             LogTrace(mlConfigDb_) << ss.str();
0110           }
0111         }
0112       }
0113 
0114     } else {  // Use database cache
0115       std::stringstream ss;
0116       ss << "[SiStripConfigDb::" << __func__ << "]"
0117          << " No database cache for analysis objects!";
0118       edm::LogWarning(mlConfigDb_) << ss.str();
0119     }
0120 
0121   } catch (...) {
0122     handleException(__func__);
0123   }
0124 
0125   // Create range object
0126   uint16_t np = 0;
0127   uint16_t nc = 0;
0128   AnalysisDescriptionsRange anals = analyses_.emptyRange();
0129   if (!partition.empty()) {
0130     anals = analyses_.find(partition);
0131     np = 1;
0132     nc = anals.size();
0133   } else {
0134     if (!analyses_.empty()) {
0135       anals =
0136           AnalysisDescriptionsRange(analyses_.find(dbParams_.partitions().begin()->second.partitionName()).begin(),
0137                                     analyses_.find((--(dbParams_.partitions().end()))->second.partitionName()).end());
0138     } else {
0139       anals = analyses_.emptyRange();
0140     }
0141     np = analyses_.size();
0142     nc = anals.size();
0143   }
0144 
0145   stringstream ss;
0146   ss << "[SiStripConfigDb::" << __func__ << "]"
0147      << " Found " << nc << " analysis descriptions";
0148   if (!dbParams_.usingDbCache()) {
0149     ss << " in " << np << " database partition(s)";
0150   } else {
0151     ss << " from shared memory name '" << dbParams_.sharedMemory() << "'";
0152   }
0153   if (analyses_.empty()) {
0154     edm::LogWarning(mlConfigDb_) << ss.str();
0155   } else {
0156     LogTrace(mlConfigDb_) << ss.str();
0157   }
0158 
0159   return anals;
0160 }
0161 
0162 // -----------------------------------------------------------------------------
0163 //
0164 void SiStripConfigDb::addAnalysisDescriptions(std::string partition, AnalysisDescriptionsV& anals) {
0165   if (!deviceFactory(__func__)) {
0166     return;
0167   }
0168 
0169   if (partition.empty()) {
0170     stringstream ss;
0171     ss << "[SiStripConfigDb::" << __func__ << "]"
0172        << " Partition string is empty,"
0173        << " therefore cannot add analysis descriptions to local cache!";
0174     edm::LogWarning(mlConfigDb_) << ss.str();
0175     return;
0176   }
0177 
0178   if (anals.empty()) {
0179     stringstream ss;
0180     ss << "[SiStripConfigDb::" << __func__ << "]"
0181        << " Vector of analysis descriptions is empty,"
0182        << " therefore cannot add analysis descriptions to local cache!";
0183     edm::LogWarning(mlConfigDb_) << ss.str();
0184     return;
0185   }
0186 
0187   SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
0188   SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
0189   for (; iter != jter; ++iter) {
0190     if (partition == iter->second.partitionName()) {
0191       break;
0192     }
0193   }
0194   if (iter == dbParams_.partitions().end()) {
0195     stringstream ss;
0196     ss << "[SiStripConfigDb::" << __func__ << "]"
0197        << " Partition \"" << partition << "\" not found in partition list, "
0198        << " therefore cannot add analysis descriptions!";
0199     edm::LogWarning(mlConfigDb_) << ss.str();
0200     return;
0201   }
0202 
0203   AnalysisDescriptionsRange range = analyses_.find(partition);
0204   if (range == analyses_.emptyRange()) {
0205     // Make local copy
0206     AnalysisDescriptionsV tmp;
0207     CommissioningAnalysisFactory::vectorCopy(anals, tmp);
0208 
0209     // Add to local cache
0210     analyses_.loadNext(partition, tmp);
0211 
0212     // Some debug
0213     std::stringstream ss;
0214     ss << "[SiStripConfigDb::" << __func__ << "]"
0215        << " Added " << anals.size() << " analysis descriptions to local cache for partition \"" << partition << "\"."
0216        << " (Cache holds analysis descriptions for " << analyses_.size() << " partitions.)";
0217     LogTrace(mlConfigDb_) << ss.str();
0218   } else {
0219     stringstream ss;
0220     ss << "[SiStripConfigDb::" << __func__ << "]"
0221        << " Partition \"" << partition << "\" already found in local cache, "
0222        << " therefore cannot add analysis descriptions!";
0223     edm::LogWarning(mlConfigDb_) << ss.str();
0224     return;
0225   }
0226 }
0227 
0228 // -----------------------------------------------------------------------------
0229 //
0230 void SiStripConfigDb::uploadAnalysisDescriptions(bool calibration_for_physics, std::string partition) {
0231   if (dbParams_.usingDbCache()) {
0232     edm::LogWarning(mlConfigDb_) << "[SiStripConfigDb::" << __func__ << "]"
0233                                  << " Using database cache! No uploads allowed!";
0234     return;
0235   }
0236 
0237   if (!deviceFactory(__func__)) {
0238     return;
0239   }
0240 
0241   if (analyses_.empty()) {
0242     edm::LogWarning(mlConfigDb_) << "[SiStripConfigDb::" << __func__ << "]"
0243                                  << " Found no cached analysis descriptions, therefore no upload!";
0244     return;
0245   }
0246 
0247   if (calibration_for_physics && !allowCalibUpload_) {
0248     edm::LogWarning(mlConfigDb_) << "[SiStripConfigDb::" << __func__ << "]"
0249                                  << " Attempting to upload calibration constants"
0250                                  << " without uploading any hardware descriptions!"
0251                                  << " Aborting upload...";
0252     return;
0253   } else {
0254     allowCalibUpload_ = false;
0255   }
0256 
0257   try {
0258     SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
0259     SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
0260     for (; iter != jter; ++iter) {
0261       if (partition.empty() || partition == iter->second.partitionName()) {
0262         AnalysisDescriptionsRange range = analyses_.find(iter->second.partitionName());
0263         if (range != analyses_.emptyRange()) {
0264           AnalysisDescriptionsV anals(range.begin(), range.end());  /// list of all analysis type
0265 
0266           vector<AnalysisType>
0267               analysis_type;  // check how many different analysis type we have --> more than one analysis table could be uploaded in the same job
0268           for (auto element : anals) {
0269             if (std::find(analysis_type.begin(), analysis_type.end(), element->getType()) == analysis_type.end() and
0270                 element->getType() != AnalysisDescription::T_UNKNOWN) {
0271               analysis_type.push_back(element->getType());
0272             } else if (element->getType() == AnalysisDescription::T_UNKNOWN) {
0273               edm::LogWarning(mlConfigDb_) << "[SiStripConfigDb::" << __func__ << "]"
0274                                            << " Analysis type is UNKNOWN. Aborting upload!";
0275               return;
0276             }
0277           }
0278 
0279           vector<AnalysisDescriptionsV> analysisToUpload;  // in case there are more than one analysis type to be uploaded
0280           for (auto type : analysis_type) {
0281             AnalysisDescriptionsV ana_temp;
0282             for (auto element : anals) {
0283               if (element->getType() == type)
0284                 ana_temp.push_back(element);
0285             }
0286             analysisToUpload.push_back(ana_temp);
0287           }
0288 
0289           // perform the upload
0290           for (auto analysis : analysisToUpload) {
0291             uint32_t version = deviceFactory(__func__)->uploadAnalysis(iter->second.runNumber(),
0292                                                                        iter->second.partitionName(),
0293                                                                        analysis.front()->getType(),
0294                                                                        analysis,
0295                                                                        calibration_for_physics);
0296             // Update current state with analysis descriptions
0297             if (calibration_for_physics) {
0298               deviceFactory(__func__)->uploadAnalysisState(version);
0299             }
0300           }
0301 
0302           // Some debug
0303           std::stringstream ss;
0304           ss << "[SiStripConfigDb::" << __func__ << "]"
0305              << " Uploaded " << anals.size() << " device descriptions to database for partition \""
0306              << iter->second.partitionName() << "\".";
0307           LogTrace(mlConfigDb_) << ss.str();
0308 
0309         } else {
0310           stringstream ss;
0311           ss << "[SiStripConfigDb::" << __func__ << "]"
0312              << " Vector of device descriptions is empty for partition \"" << iter->second.partitionName()
0313              << "\", therefore aborting upload for this partition!";
0314           edm::LogWarning(mlConfigDb_) << ss.str();
0315           continue;
0316         }
0317 
0318       } else {
0319         //    stringstream ss;
0320         //    ss << "[SiStripConfigDb::" << __func__ << "]"
0321         //       << " Cannot find partition \"" << partition
0322         //       << "\" in cached partitions list: \""
0323         //       << dbParams_.partitionNames( dbParams_.partitionNames() )
0324         //       << "\", therefore aborting upload for this partition!";
0325         //    edm::LogWarning(mlConfigDb_) << ss.str();
0326       }
0327     }
0328   } catch (...) {
0329     handleException(__func__);
0330   }
0331 
0332   allowCalibUpload_ = true;
0333 }
0334 
0335 // -----------------------------------------------------------------------------
0336 //
0337 void SiStripConfigDb::clearAnalysisDescriptions(std::string partition) {
0338   LogTrace(mlConfigDb_) << "[SiStripConfigDb::" << __func__ << "]";
0339 
0340   if (analyses_.empty()) {
0341     stringstream ss;
0342     ss << "[SiStripConfigDb::" << __func__ << "]"
0343        << " Found no cached analysis descriptions!";
0344     //edm::LogWarning(mlConfigDb_) << ss.str();
0345     return;
0346   }
0347 
0348   // Reproduce temporary cache for "all partitions except specified one" (or clear all if none specified)
0349   AnalysisDescriptions temporary_cache;
0350   if (partition.empty()) {
0351     temporary_cache = AnalysisDescriptions();
0352   } else {
0353     SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
0354     SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
0355     for (; iter != jter; ++iter) {
0356       if (partition != iter->second.partitionName()) {
0357         AnalysisDescriptionsRange range = analyses_.find(iter->second.partitionName());
0358         if (range != analyses_.emptyRange()) {
0359           temporary_cache.loadNext(partition, AnalysisDescriptionsV(range.begin(), range.end()));
0360         } else {
0361           //      stringstream ss;
0362           //      ss << "[SiStripConfigDb::" << __func__ << "]"
0363           //         << " Cannot find partition \"" << iter->second.partitionName()
0364           //         << "\" in local cache!";
0365           //      edm::LogWarning(mlConfigDb_) << ss.str();
0366         }
0367       }
0368     }
0369   }
0370 
0371   // Delete objects in local cache for specified partition (or all if not specified)
0372   AnalysisDescriptionsRange anals = analyses_.emptyRange();
0373   if (partition.empty()) {
0374     if (!analyses_.empty()) {
0375       anals =
0376           AnalysisDescriptionsRange(analyses_.find(dbParams_.partitions().begin()->second.partitionName()).begin(),
0377                                     analyses_.find((--(dbParams_.partitions().end()))->second.partitionName()).end());
0378     } else {
0379       anals = analyses_.emptyRange();
0380     }
0381   } else {
0382     SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
0383     SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
0384     for (; iter != jter; ++iter) {
0385       if (partition == iter->second.partitionName()) {
0386         break;
0387       }
0388     }
0389     anals = analyses_.find(iter->second.partitionName());
0390   }
0391 
0392   if (anals != analyses_.emptyRange()) {
0393     AnalysisDescriptionsV::const_iterator ianal = anals.begin();
0394     AnalysisDescriptionsV::const_iterator janal = anals.end();
0395     for (; ianal != janal; ++ianal) {
0396       if (*ianal) {
0397         delete *ianal;
0398       }
0399     }
0400   } else {
0401     stringstream ss;
0402     ss << "[SiStripConfigDb::" << __func__ << "]";
0403     if (partition.empty()) {
0404       ss << " Found no analysis descriptions in local cache!";
0405     } else {
0406       ss << " Found no analysis descriptions in local cache for partition \"" << partition << "\"!";
0407     }
0408     edm::LogWarning(mlConfigDb_) << ss.str();
0409   }
0410 
0411   // Overwrite local cache with temporary cache
0412   analyses_ = temporary_cache;
0413 }
0414 
0415 // -----------------------------------------------------------------------------
0416 //
0417 void SiStripConfigDb::printAnalysisDescriptions(std::string partition) {
0418   std::stringstream ss;
0419   ss << "[SiStripConfigDb::" << __func__ << "]"
0420      << " Contents of AnalysisDescriptions container:" << std::endl;
0421   ss << " Number of partitions: " << analyses_.size() << std::endl;
0422 
0423   // Loop through partitions
0424   uint16_t cntr = 0;
0425   AnalysisDescriptions::const_iterator ianal = analyses_.begin();
0426   AnalysisDescriptions::const_iterator janal = analyses_.end();
0427   for (; ianal != janal; ++ianal) {
0428     cntr++;
0429     if (partition.empty() || partition == ianal->first) {
0430       ss << "  Partition number : " << cntr << " (out of " << analyses_.size() << ")" << std::endl;
0431       ss << "  Partition name   : \"" << ianal->first << "\"" << std::endl;
0432       ss << "  Num of analyses  : " << ianal->second.size() << std::endl;
0433 
0434       // Extract FEC crate, slot, etc
0435       std::map<uint32_t, vector<uint32_t> > analyses;
0436       AnalysisDescriptionsV::const_iterator iter = ianal->second.begin();
0437       AnalysisDescriptionsV::const_iterator jter = ianal->second.end();
0438       for (; iter != jter; ++iter) {
0439         if (*iter) {
0440           DeviceAddress addr = deviceAddress(**iter);
0441           uint32_t key = SiStripFecKey(addr.fecCrate_, addr.fecSlot_, addr.fecRing_, 0, 0, 0, 0).key();
0442           uint32_t data = SiStripFecKey(addr.fecCrate_,
0443                                         addr.fecSlot_,
0444                                         addr.fecRing_,
0445                                         addr.ccuAddr_,
0446                                         addr.ccuChan_,
0447                                         addr.lldChan_,
0448                                         addr.i2cAddr_)
0449                               .key();
0450           if (find(analyses[key].begin(), analyses[key].end(), data) == analyses[key].end()) {
0451             analyses[key].push_back(data);
0452           }
0453         }
0454       }
0455 
0456       // Sort contents
0457       std::map<uint32_t, std::vector<uint32_t> > tmp;
0458       std::map<uint32_t, std::vector<uint32_t> >::const_iterator ii = analyses.begin();
0459       std::map<uint32_t, std::vector<uint32_t> >::const_iterator jj = analyses.end();
0460       for (; ii != jj; ++ii) {
0461         std::vector<uint32_t> temp = ii->second;
0462         std::sort(temp.begin(), temp.end());
0463         std::vector<uint32_t>::const_iterator iii = temp.begin();
0464         std::vector<uint32_t>::const_iterator jjj = temp.end();
0465         for (; iii != jjj; ++iii) {
0466           tmp[ii->first].push_back(*iii);
0467         }
0468       }
0469       analyses.clear();
0470       analyses = tmp;
0471 
0472       // Print FEC crate, slot, etc...
0473       std::map<uint32_t, std::vector<uint32_t> >::const_iterator ianal = analyses.begin();
0474       std::map<uint32_t, std::vector<uint32_t> >::const_iterator janal = analyses.end();
0475       for (; ianal != janal; ++ianal) {
0476         SiStripFecKey key(ianal->first);
0477         ss << "  Found " << std::setw(3) << ianal->second.size() << " analyses for FEC crate/slot/ring "
0478            << key.fecCrate() << "/" << key.fecSlot() << "/" << key.fecRing();
0479         //<< " (ccu/module/lld/i2c): ";
0480         //  if ( !ianal->second.empty() ) {
0481         //    uint16_t first = ianal->second.front();
0482         //    uint16_t last = ianal->second.front();
0483         //    std::vector<uint32_t>::const_iterator chan = ianal->second.begin();
0484         //    for ( ; chan != ianal->second.end(); chan++ ) {
0485         //      if ( chan != ianal->second.begin() ) {
0486         //        if ( *chan != last+1 ) {
0487         //      ss << std::setw(2) << first << "->" << std::setw(2) << last << ", ";
0488         //      if ( chan != ianal->second.end() ) { first = *(chan+1); }
0489         //        }
0490         //      }
0491         //      last = *chan;
0492         //    }
0493         //    if ( first != last ) { ss << std::setw(2) << first << "->" << std::setw(2) << last; }
0494         ss << std::endl;
0495       }
0496     }
0497   }
0498 
0499   LogTrace(mlConfigDb_) << ss.str();
0500 }
0501 
0502 // -----------------------------------------------------------------------------
0503 //
0504 SiStripConfigDb::DeviceAddress SiStripConfigDb::deviceAddress(const AnalysisDescription& desc) {
0505   DeviceAddress addr;
0506   try {
0507     addr.fecCrate_ = static_cast<uint16_t>(desc.getCrate() + sistrip::FEC_CRATE_OFFSET);
0508     addr.fecSlot_ = static_cast<uint16_t>(desc.getSlot());
0509     addr.fecRing_ = static_cast<uint16_t>(desc.getRing() + sistrip::FEC_RING_OFFSET);
0510     addr.ccuAddr_ = static_cast<uint16_t>(desc.getCcuAdr());
0511     addr.ccuChan_ = static_cast<uint16_t>(desc.getCcuChan());
0512     addr.lldChan_ = static_cast<uint16_t>(SiStripFecKey::lldChan(desc.getI2cAddr()));
0513     addr.i2cAddr_ = static_cast<uint16_t>(desc.getI2cAddr());
0514     addr.fedId_ = static_cast<uint16_t>(desc.getFedId());  //@@ offset required? crate/slot needed?
0515     addr.feUnit_ = static_cast<uint16_t>(desc.getFeUnit());
0516     addr.feChan_ = static_cast<uint16_t>(desc.getFeChan());
0517   } catch (...) {
0518     handleException(__func__);
0519   }
0520 
0521   return addr;
0522 }
0523 
0524 // -----------------------------------------------------------------------------
0525 //
0526 std::string SiStripConfigDb::analysisType(AnalysisType analysis_type) const {
0527   if (analysis_type == AnalysisDescription::T_ANALYSIS_FASTFEDCABLING) {
0528     return "FAST_CABLING";
0529   } else if (analysis_type == AnalysisDescription::T_ANALYSIS_TIMING) {
0530     return "APV_TIMING";
0531   } else if (analysis_type == AnalysisDescription::T_ANALYSIS_OPTOSCAN) {
0532     return "OPTO_SCAN";
0533   } else if (analysis_type == AnalysisDescription::T_ANALYSIS_PEDESTALS) {
0534     return "PEDESTALS";
0535   } else if (analysis_type == AnalysisDescription::T_ANALYSIS_PEDSFULLNOISE) {
0536     return "PEDSFULLNOISE";
0537   } else if (analysis_type == AnalysisDescription::T_ANALYSIS_APVLATENCY) {
0538     return "APV_LATENCY";
0539   } else if (analysis_type == AnalysisDescription::T_ANALYSIS_FINEDELAY) {
0540     return "FINE_DELAY";
0541   } else if (analysis_type == AnalysisDescription::T_ANALYSIS_CALIBRATION) {
0542     return "CALIBRATION";
0543   } else if (analysis_type == AnalysisDescription::T_UNKNOWN) {
0544     return "UNKNOWN ANALYSIS TYPE";
0545   } else {
0546     return "UNDEFINED ANALYSIS TYPE";
0547   }
0548 }