CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/OnlineDB/SiStripConfigDb/src/AnalysisDescriptions.cc

Go to the documentation of this file.
00001 // Last commit: $Id: AnalysisDescriptions.cc,v 1.13 2009/04/06 16:57:28 lowette Exp $
00002 // Latest tag:  $Name: V07-01-09-02 $
00003 // Location:    $Source: /local/reps/CMSSW/CMSSW/OnlineDB/SiStripConfigDb/src/AnalysisDescriptions.cc,v $
00004 
00005 #include "OnlineDB/SiStripConfigDb/interface/SiStripConfigDb.h"
00006 #include "DataFormats/SiStripCommon/interface/SiStripEnumsAndStrings.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 
00009 using namespace std;
00010 using namespace sistrip;
00011 
00012 // -----------------------------------------------------------------------------
00023 SiStripConfigDb::AnalysisDescriptionsRange SiStripConfigDb::getAnalysisDescriptions( AnalysisType analysis_type,
00024                                                                                      std::string partition ) {
00025   
00026   // Check
00027   if ( ( !dbParams_.usingDbCache() && !deviceFactory(__func__) ) ||
00028        (  dbParams_.usingDbCache() && !databaseCache(__func__) ) ) { 
00029     return analyses_.emptyRange();
00030   }
00031   
00032   try { 
00033 
00034     if ( !dbParams_.usingDbCache() ) { 
00035       
00036       SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
00037       SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
00038       for ( ; iter != jter; ++iter ) {
00039         
00040         if ( partition == "" || partition == iter->second.partitionName() ) {
00041           
00042           if ( iter->second.partitionName() == SiStripPartition::defaultPartitionName_ ) { continue; }
00043 
00044           AnalysisDescriptionsRange range = analyses_.find( iter->second.partitionName() );
00045           if ( range == analyses_.emptyRange() ) {
00046     
00047             AnalysisDescriptionsV tmp1;
00048             if ( analysis_type == AnalysisDescription::T_ANALYSIS_FASTFEDCABLING ) {
00049               tmp1 = deviceFactory(__func__)->getAnalysisHistory( iter->second.partitionName(), 
00050                                                                   iter->second.fastCablingVersion().first,
00051                                                                   iter->second.fastCablingVersion().second,
00052                                                                   analysis_type );
00053             } else if ( analysis_type == AnalysisDescription::T_ANALYSIS_TIMING ) {
00054               tmp1 = deviceFactory(__func__)->getAnalysisHistory( iter->second.partitionName(), 
00055                                                                   iter->second.apvTimingVersion().first,
00056                                                                   iter->second.apvTimingVersion().second,
00057                                                                   analysis_type );
00058             } else if ( analysis_type == AnalysisDescription::T_ANALYSIS_OPTOSCAN ) {
00059               tmp1 = deviceFactory(__func__)->getAnalysisHistory( iter->second.partitionName(), 
00060                                                                   iter->second.optoScanVersion().first,
00061                                                                   iter->second.optoScanVersion().second,
00062                                                                   analysis_type );
00063             } else if ( analysis_type == AnalysisDescription::T_ANALYSIS_VPSPSCAN ) {
00064               tmp1 = deviceFactory(__func__)->getAnalysisHistory( iter->second.partitionName(), 
00065                                                                   iter->second.vpspScanVersion().first,
00066                                                                   iter->second.vpspScanVersion().second,
00067                                                                   analysis_type );
00068             } else if ( analysis_type == AnalysisDescription::T_ANALYSIS_CALIBRATION ) {
00069               tmp1 = deviceFactory(__func__)->getAnalysisHistory( iter->second.partitionName(), 
00070                                                                   iter->second.apvCalibVersion().first,
00071                                                                   iter->second.apvCalibVersion().second,
00072                                                                   analysis_type );
00073             } else if ( analysis_type == AnalysisDescription::T_ANALYSIS_PEDESTALS ) { 
00074               tmp1 = deviceFactory(__func__)->getAnalysisHistory( iter->second.partitionName(), 
00075                                                                   iter->second.pedestalsVersion().first,
00076                                                                   iter->second.pedestalsVersion().second,
00077                                                                   analysis_type );
00078             } else if ( analysis_type == AnalysisDescription::T_ANALYSIS_APVLATENCY ) {
00079               tmp1 = deviceFactory(__func__)->getAnalysisHistory( iter->second.partitionName(), 
00080                                                                   iter->second.apvLatencyVersion().first,
00081                                                                   iter->second.apvLatencyVersion().second,
00082                                                                   analysis_type );
00083             } else if ( analysis_type == AnalysisDescription::T_ANALYSIS_FINEDELAY ) {
00084               tmp1 = deviceFactory(__func__)->getAnalysisHistory( iter->second.partitionName(), 
00085                                                                   iter->second.fineDelayVersion().first,
00086                                                                   iter->second.fineDelayVersion().second,
00087                                                                   analysis_type );
00088             } else {
00089               std::stringstream ss;
00090               ss << "[SiStripConfigDb::" << __func__ << "]"
00091                  << " Unexpected analysis type \"" 
00092                  << analysisType( analysis_type ) 
00093                  << "\"! Aborting download...";
00094               edm::LogWarning(mlConfigDb_) << ss.str();
00095               return analyses_.emptyRange();
00096             }
00097             
00098             // Make local copy 
00099             AnalysisDescriptionsV tmp2;
00100             CommissioningAnalysisFactory::vectorCopy( tmp1, tmp2 );
00101             
00102             // Add to cache
00103             analyses_.loadNext( iter->second.partitionName(), tmp2 );
00104             
00105             // Some debug
00106             AnalysisDescriptionsRange anals = analyses_.find( iter->second.partitionName() );
00107             std::stringstream ss;
00108             ss << "[SiStripConfigDb::" << __func__ << "]"
00109                << " Downloaded " << anals.size() 
00110                << " analysis descriptions of type \""
00111                << analysisType( analysis_type )
00112                << "\" to local cache for partition \""
00113                << iter->second.partitionName() << "\"" << std::endl;
00114             ss << "[SiStripConfigDb::" << __func__ << "]"
00115                << " Cache holds analysis descriptions for " 
00116                << analyses_.size() << " partitions.";
00117             LogTrace(mlConfigDb_) << ss.str();
00118 
00119           }
00120         }
00121       }
00122 
00123     } else { // Use database cache
00124       std::stringstream ss;
00125       ss << "[SiStripConfigDb::" << __func__ << "]"
00126          << " No database cache for analysis objects!";
00127       edm::LogWarning(mlConfigDb_) << ss.str();
00128     }
00129     
00130   } catch (...) { handleException( __func__ ); }
00131   
00132   // Create range object
00133   uint16_t np = 0;
00134   uint16_t nc = 0;
00135   AnalysisDescriptionsRange anals = analyses_.emptyRange();
00136   if ( partition != "" ) { 
00137     anals = analyses_.find( partition );
00138     np = 1;
00139     nc = anals.size();
00140   } else { 
00141     if ( !analyses_.empty() ) {
00142       anals = AnalysisDescriptionsRange( analyses_.find( dbParams_.partitions().begin()->second.partitionName() ).begin(),
00143                                          analyses_.find( (--(dbParams_.partitions().end()))->second.partitionName() ).end() );
00144     } else { anals = analyses_.emptyRange(); }
00145     np = analyses_.size();
00146     nc = anals.size();
00147   }
00148   
00149   stringstream ss; 
00150   ss << "[SiStripConfigDb::" << __func__ << "]"
00151      << " Found " << nc << " analysis descriptions";
00152   if ( !dbParams_.usingDbCache() )  { ss << " in " << np << " database partition(s)"; } 
00153   else { ss << " from shared memory name '" << dbParams_.sharedMemory() << "'"; } 
00154   if ( analyses_.empty() ) { edm::LogWarning(mlConfigDb_) << ss.str(); }
00155   else { LogTrace(mlConfigDb_) << ss.str(); }
00156   
00157   return anals;
00158   
00159 }
00160 
00161 // -----------------------------------------------------------------------------
00162 // 
00163 void SiStripConfigDb::addAnalysisDescriptions( std::string partition, AnalysisDescriptionsV& anals ) {
00164 
00165   if ( !deviceFactory(__func__) ) { return; }
00166 
00167   if ( partition.empty() ) { 
00168     stringstream ss; 
00169     ss << "[SiStripConfigDb::" << __func__ << "]" 
00170        << " Partition string is empty,"
00171        << " therefore cannot add analysis descriptions to local cache!"; 
00172     edm::LogWarning(mlConfigDb_) << ss.str(); 
00173     return; 
00174   }
00175   
00176   if ( anals.empty() ) { 
00177     stringstream ss; 
00178     ss << "[SiStripConfigDb::" << __func__ << "]" 
00179        << " Vector of analysis descriptions is empty,"
00180        << " therefore cannot add analysis descriptions to local cache!"; 
00181     edm::LogWarning(mlConfigDb_) << ss.str(); 
00182     return; 
00183   }
00184 
00185   SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
00186   SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
00187   for ( ; iter != jter; ++iter ) { if ( partition == iter->second.partitionName() ) { break; } }
00188   if ( iter == dbParams_.partitions().end() ) { 
00189     stringstream ss; 
00190     ss << "[SiStripConfigDb::" << __func__ << "]" 
00191        << " Partition \"" << partition
00192        << "\" not found in partition list, "
00193        << " therefore cannot add analysis descriptions!";
00194     edm::LogWarning(mlConfigDb_) << ss.str(); 
00195     return; 
00196   }
00197   
00198   AnalysisDescriptionsRange range = analyses_.find( partition );
00199   if ( range == analyses_.emptyRange() ) {
00200     
00201     // Make local copy 
00202     AnalysisDescriptionsV tmp;
00203     CommissioningAnalysisFactory::vectorCopy( anals, tmp );
00204     
00205     // Add to local cache
00206     analyses_.loadNext( partition, tmp );
00207 
00208     // Some debug
00209     std::stringstream ss;
00210     ss << "[SiStripConfigDb::" << __func__ << "]"
00211        << " Added " << anals.size() 
00212        << " analysis descriptions to local cache for partition \""
00213        << partition << "\"."
00214        << " (Cache holds analysis descriptions for " 
00215        << analyses_.size() << " partitions.)";
00216     LogTrace(mlConfigDb_) << ss.str();
00217     
00218   } else {
00219     stringstream ss; 
00220     ss << "[SiStripConfigDb::" << __func__ << "]" 
00221        << " Partition \"" << partition
00222        << "\" already found in local cache, "
00223        << " therefore cannot add analysis descriptions!";
00224     edm::LogWarning(mlConfigDb_) << ss.str(); 
00225     return; 
00226   }
00227   
00228 }
00229 
00230 // -----------------------------------------------------------------------------
00231 // 
00232 void SiStripConfigDb::uploadAnalysisDescriptions( bool calibration_for_physics,
00233                                                   std::string partition ) {
00234 
00235   if ( dbParams_.usingDbCache() ) {
00236     edm::LogWarning(mlConfigDb_)
00237       << "[SiStripConfigDb::" << __func__ << "]" 
00238       << " Using database cache! No uploads allowed!"; 
00239     return;
00240   }
00241   
00242   if ( !deviceFactory(__func__) ) { return; }
00243 
00244   if ( analyses_.empty() ) { 
00245     edm::LogWarning(mlConfigDb_) 
00246       << "[SiStripConfigDb::" << __func__ << "]" 
00247       << " Found no cached analysis descriptions, therefore no upload!"; 
00248     return; 
00249   }
00250   
00251   if ( calibration_for_physics && !allowCalibUpload_ ) {
00252     edm::LogWarning(mlConfigDb_)
00253       << "[SiStripConfigDb::" << __func__ << "]"
00254       << " Attempting to upload calibration constants"
00255       << " without uploading any hardware descriptions!"
00256       << " Aborting upload...";
00257     return;
00258   } else { allowCalibUpload_ = false; }
00259   
00260   try { 
00261 
00262     SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
00263     SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
00264     for ( ; iter != jter; ++iter ) {
00265       
00266       if ( partition == "" || partition == iter->second.partitionName() ) {
00267         
00268         AnalysisDescriptionsRange range = analyses_.find( iter->second.partitionName() );
00269         if ( range != analyses_.emptyRange() ) {
00270           
00271           AnalysisDescriptionsV anals( range.begin(), range.end() );
00272           
00273           AnalysisType analysis_type = AnalysisDescription::T_UNKNOWN;
00274           if ( anals.front() ) { analysis_type = anals.front()->getType(); }
00275           if ( analysis_type == AnalysisDescription::T_UNKNOWN ) {
00276             edm::LogWarning(mlConfigDb_)
00277               << "[SiStripConfigDb::" << __func__ << "]"
00278               << " Analysis type is UNKNOWN. Aborting upload!";
00279             return;
00280           }
00281           
00282           uint32_t version = deviceFactory(__func__)->uploadAnalysis( iter->second.runNumber(), 
00283                                                                       iter->second.partitionName(), 
00284                                                                       analysis_type,
00285                                                                       anals,
00286                                                                       calibration_for_physics );
00287 
00288           // Update current state with analysis descriptions
00289           if ( calibration_for_physics ) { deviceFactory(__func__)->uploadAnalysisState( version ); }
00290           
00291           // Some debug
00292           std::stringstream ss;
00293           ss << "[SiStripConfigDb::" << __func__ << "]"
00294              << " Uploaded " << anals.size() 
00295              << " device descriptions to database for partition \""
00296              << iter->second.partitionName() << "\".";
00297           LogTrace(mlConfigDb_) << ss.str();
00298           
00299         } else {
00300           stringstream ss; 
00301           ss << "[SiStripConfigDb::" << __func__ << "]" 
00302              << " Vector of device descriptions is empty for partition \"" 
00303              << iter->second.partitionName()
00304              << "\", therefore aborting upload for this partition!";
00305           edm::LogWarning(mlConfigDb_) << ss.str(); 
00306           continue; 
00307         }
00308         
00309       } else {
00310         //        stringstream ss; 
00311         //        ss << "[SiStripConfigDb::" << __func__ << "]" 
00312         //           << " Cannot find partition \"" << partition
00313         //           << "\" in cached partitions list: \""
00314         //           << dbParams_.partitionNames( dbParams_.partitionNames() ) 
00315         //           << "\", therefore aborting upload for this partition!";
00316         //        edm::LogWarning(mlConfigDb_) << ss.str(); 
00317       }
00318       
00319     }
00320     
00321   } catch (...) { handleException( __func__ ); }
00322   
00323   allowCalibUpload_ = true;
00324   
00325 }
00326 
00327 // -----------------------------------------------------------------------------
00328 // 
00329 void SiStripConfigDb::clearAnalysisDescriptions( std::string partition ) {
00330   LogTrace(mlConfigDb_) << "[SiStripConfigDb::" << __func__ << "]";
00331   
00332   if ( analyses_.empty() ) { 
00333     stringstream ss; 
00334     ss << "[SiStripConfigDb::" << __func__ << "]" 
00335        << " Found no cached analysis descriptions!"; 
00336     //edm::LogWarning(mlConfigDb_) << ss.str(); 
00337     return; 
00338   }
00339   
00340   // Reproduce temporary cache for "all partitions except specified one" (or clear all if none specified)
00341   AnalysisDescriptions temporary_cache;
00342   if ( partition == ""  ) { temporary_cache = AnalysisDescriptions(); }
00343   else {
00344     SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
00345     SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
00346     for ( ; iter != jter; ++iter ) {
00347       if ( partition != iter->second.partitionName() ) {
00348         AnalysisDescriptionsRange range = analyses_.find( iter->second.partitionName() );
00349         if ( range != analyses_.emptyRange() ) {
00350           temporary_cache.loadNext( partition, AnalysisDescriptionsV( range.begin(), range.end() ) );
00351         } else {
00352           //      stringstream ss; 
00353           //      ss << "[SiStripConfigDb::" << __func__ << "]" 
00354           //         << " Cannot find partition \"" << iter->second.partitionName()
00355           //         << "\" in local cache!";
00356           //      edm::LogWarning(mlConfigDb_) << ss.str(); 
00357         }
00358       }
00359     }
00360   }
00361   
00362   // Delete objects in local cache for specified partition (or all if not specified) 
00363   AnalysisDescriptionsRange anals = analyses_.emptyRange();
00364   if ( partition == "" ) { 
00365     if ( !analyses_.empty() ) {
00366       anals = AnalysisDescriptionsRange( analyses_.find( dbParams_.partitions().begin()->second.partitionName() ).begin(),
00367                                          analyses_.find( (--(dbParams_.partitions().end()))->second.partitionName() ).end() );
00368     } else { anals = analyses_.emptyRange(); }
00369   } else {
00370     SiStripDbParams::SiStripPartitions::const_iterator iter = dbParams_.partitions().begin();
00371     SiStripDbParams::SiStripPartitions::const_iterator jter = dbParams_.partitions().end();
00372     for ( ; iter != jter; ++iter ) { if ( partition == iter->second.partitionName() ) { break; } }
00373     anals = analyses_.find( iter->second.partitionName() );
00374   }
00375   
00376   if ( anals != analyses_.emptyRange() ) {
00377     AnalysisDescriptionsV::const_iterator ianal = anals.begin();
00378     AnalysisDescriptionsV::const_iterator janal = anals.end();
00379     for ( ; ianal != janal; ++ianal ) { if ( *ianal ) { delete *ianal; } }
00380   } else {
00381     stringstream ss; 
00382     ss << "[SiStripConfigDb::" << __func__ << "]";
00383     if ( partition == "" ) { ss << " Found no analysis descriptions in local cache!"; }
00384     else { ss << " Found no analysis descriptions in local cache for partition \"" << partition << "\"!"; }
00385     edm::LogWarning(mlConfigDb_) << ss.str(); 
00386   }
00387   
00388   // Overwrite local cache with temporary cache
00389   analyses_ = temporary_cache; 
00390 
00391 }
00392 
00393 // -----------------------------------------------------------------------------
00394 // 
00395 void SiStripConfigDb::printAnalysisDescriptions( std::string partition ) {
00396   
00397   std::stringstream ss;
00398   ss << "[SiStripConfigDb::" << __func__ << "]"
00399      << " Contents of AnalysisDescriptions container:" << std::endl;
00400   ss << " Number of partitions: " << analyses_.size() << std::endl;
00401   
00402   // Loop through partitions
00403   uint16_t cntr = 0;
00404   AnalysisDescriptions::const_iterator ianal = analyses_.begin();
00405   AnalysisDescriptions::const_iterator janal = analyses_.end();
00406   for ( ; ianal != janal; ++ianal ) {
00407 
00408     cntr++;
00409     if ( partition == "" || partition == ianal->first ) {
00410       
00411       ss << "  Partition number : " << cntr << " (out of " << analyses_.size() << ")" << std::endl;
00412       ss << "  Partition name   : \"" << ianal->first << "\"" << std::endl;
00413       ss << "  Num of analyses  : " << ianal->second.size() << std::endl;
00414       
00415       // Extract FEC crate, slot, etc
00416       std::map< uint32_t, vector<uint32_t> > analyses;
00417       AnalysisDescriptionsV::const_iterator iter = ianal->second.begin();
00418       AnalysisDescriptionsV::const_iterator jter = ianal->second.end();
00419       for ( ; iter != jter; ++iter ) { 
00420         if ( *iter ) { 
00421           DeviceAddress addr = deviceAddress( **iter );
00422           uint32_t key  = SiStripFecKey( addr.fecCrate_, 
00423                                          addr.fecSlot_, 
00424                                          addr.fecRing_, 
00425                                          0, 
00426                                          0, 
00427                                          0, 
00428                                          0 ).key();
00429           uint32_t data = SiStripFecKey( addr.fecCrate_, 
00430                                          addr.fecSlot_, 
00431                                          addr.fecRing_, 
00432                                          addr.ccuAddr_, 
00433                                          addr.ccuChan_, 
00434                                          addr.lldChan_, 
00435                                          addr.i2cAddr_ ).key();
00436           if ( find( analyses[key].begin(), analyses[key].end(), data ) == analyses[key].end() ) { 
00437             analyses[key].push_back( data );
00438           }
00439         }
00440       }
00441       
00442       // Sort contents
00443       std::map< uint32_t, std::vector<uint32_t> > tmp;
00444       std::map< uint32_t, std::vector<uint32_t> >::const_iterator ii = analyses.begin();
00445       std::map< uint32_t, std::vector<uint32_t> >::const_iterator jj = analyses.end();
00446       for ( ; ii != jj; ++ii ) {
00447         std::vector<uint32_t> temp = ii->second;
00448         std::sort( temp.begin(), temp.end() );
00449         std::vector<uint32_t>::const_iterator iii = temp.begin();
00450         std::vector<uint32_t>::const_iterator jjj = temp.end();
00451         for ( ; iii != jjj; ++iii ) { tmp[ii->first].push_back( *iii ); }
00452       }
00453       analyses.clear();
00454       analyses = tmp;
00455       
00456       // Print FEC crate, slot, etc...
00457       std::map< uint32_t, std::vector<uint32_t> >::const_iterator ianal = analyses.begin();
00458       std::map< uint32_t, std::vector<uint32_t> >::const_iterator janal = analyses.end();
00459       for ( ; ianal != janal; ++ianal ) {
00460         SiStripFecKey key(ianal->first);
00461         ss << "  Found " << std::setw(3) << ianal->second.size()
00462            << " analyses for FEC crate/slot/ring " 
00463            << key.fecCrate() << "/"
00464            << key.fecSlot() << "/"
00465            << key.fecRing();
00466         //<< " (ccu/module/lld/i2c): ";
00467         //      if ( !ianal->second.empty() ) { 
00468         //        uint16_t first = ianal->second.front();
00469         //        uint16_t last = ianal->second.front();
00470         //        std::vector<uint32_t>::const_iterator chan = ianal->second.begin();
00471         //        for ( ; chan != ianal->second.end(); chan++ ) { 
00472         //          if ( chan != ianal->second.begin() ) {
00473         //            if ( *chan != last+1 ) { 
00474         //              ss << std::setw(2) << first << "->" << std::setw(2) << last << ", ";
00475         //              if ( chan != ianal->second.end() ) { first = *(chan+1); }
00476         //            } 
00477         //          }
00478         //          last = *chan;
00479         //        }
00480         //        if ( first != last ) { ss << std::setw(2) << first << "->" << std::setw(2) << last; }
00481         ss << std::endl;
00482       }
00483 
00484     }
00485     
00486   }
00487   
00488   LogTrace(mlConfigDb_) << ss.str();
00489 
00490 }
00491 
00492 // -----------------------------------------------------------------------------
00493 // 
00494 SiStripConfigDb::DeviceAddress SiStripConfigDb::deviceAddress( const AnalysisDescription& desc ) {
00495   
00496   DeviceAddress addr;
00497   try {
00498     addr.fecCrate_ = static_cast<uint16_t>( desc.getCrate() + sistrip::FEC_CRATE_OFFSET );
00499     addr.fecSlot_  = static_cast<uint16_t>( desc.getSlot() );
00500     addr.fecRing_  = static_cast<uint16_t>( desc.getRing() + sistrip::FEC_RING_OFFSET );
00501     addr.ccuAddr_  = static_cast<uint16_t>( desc.getCcuAdr() );
00502     addr.ccuChan_  = static_cast<uint16_t>( desc.getCcuChan() );
00503     addr.lldChan_  = static_cast<uint16_t>( SiStripFecKey::lldChan( desc.getI2cAddr() ) );
00504     addr.i2cAddr_  = static_cast<uint16_t>( desc.getI2cAddr() );
00505     addr.fedId_    = static_cast<uint16_t>( desc.getFedId() ); //@@ offset required? crate/slot needed?
00506     addr.feUnit_   = static_cast<uint16_t>( desc.getFeUnit() );
00507     addr.feChan_   = static_cast<uint16_t>( desc.getFeChan() );
00508   } catch (...) { handleException( __func__ ); }
00509   
00510   return addr;
00511 }
00512 
00513 // -----------------------------------------------------------------------------
00514 //
00515 std::string SiStripConfigDb::analysisType( AnalysisType analysis_type ) const {
00516   if      ( analysis_type == AnalysisDescription::T_ANALYSIS_FASTFEDCABLING ) { return "FAST_CABLING"; }
00517   else if ( analysis_type == AnalysisDescription::T_ANALYSIS_TIMING )         { return "APV_TIMING"; }
00518   else if ( analysis_type == AnalysisDescription::T_ANALYSIS_OPTOSCAN )       { return "OPTO_SCAN"; }
00519   else if ( analysis_type == AnalysisDescription::T_ANALYSIS_PEDESTALS )      { return "PEDESTALS"; }
00520   else if ( analysis_type == AnalysisDescription::T_ANALYSIS_APVLATENCY )     { return "APV_LATENCY"; }
00521   else if ( analysis_type == AnalysisDescription::T_ANALYSIS_FINEDELAY )      { return "FINE_DELAY"; }
00522   else if ( analysis_type == AnalysisDescription::T_ANALYSIS_CALIBRATION )    { return "CALIBRATION"; }
00523   else if ( analysis_type == AnalysisDescription::T_UNKNOWN )                 { return "UNKNOWN ANALYSIS TYPE"; }
00524   else { return "UNDEFINED ANALYSIS TYPE"; }
00525 }