CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/CaloOnlineTools/HcalOnlineDb/src/HcalO2OManager.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     HcalOnlineDb
00004 // Class  :     HcalO2OManager
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Gena Kukartsev
00010 //         Created:  Sun Aug 16 20:44:05 CEST 2009
00011 // $Id: HcalO2OManager.cc,v 1.38 2010/08/06 20:24:13 wmtan Exp $
00012 //
00013 
00014 
00015 #include "CaloOnlineTools/HcalOnlineDb/interface/HcalO2OManager.h"
00016 
00017 #include "FWCore/PluginManager/interface/PluginManager.h"
00018 #include "FWCore/PluginManager/interface/standard.h"
00019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00020 
00021 #include "CondCore/DBCommon/interface/DbConnection.h"    
00022 #include "CondCore/DBCommon/interface/DbSession.h"       
00023 #include "CondCore/DBCommon/interface/DbScopedTransaction.h"
00024 
00025 #include "CondCore/DBCommon/interface/Exception.h"
00026 #include "CondCore/MetaDataService/interface/MetaData.h"
00027 #include "CondCore/IOVService/interface/IOVService.h"
00028 
00029 #include "CondCore/IOVService/interface/IOVProxy.h"
00030 
00031 #include "CaloOnlineTools/HcalOnlineDb/interface/ConnectionManager.h"
00032 #include "CaloOnlineTools/HcalOnlineDb/interface/ConfigurationDatabaseException.hh"
00033 #include "xgi/Utils.h"
00034 #include "toolbox/string.h"
00035 #include "OnlineDB/Oracle/interface/Oracle.h"
00036 
00037 
00038 using namespace oracle::occi;
00039 
00040 
00041 
00042 HcalO2OManager::HcalO2OManager()
00043 {
00044   edmplugin::PluginManager::configure(edmplugin::standard::config());
00045 }
00046 
00047 
00048 HcalO2OManager::~HcalO2OManager()
00049 {
00050 }
00051 
00052 
00053 // inspired by cmscond_list_iov
00054 //
00055 std::vector<std::string> HcalO2OManager::getListOfPoolTags(std::string connect, std::string auth_path){
00056   //edmplugin::PluginManager::configure(edmplugin::standard::config()); // in the constructor for now
00057   //
00058   // FIXME: how to add auth_path authentication to this? See v1.25 for the functionality using old API
00059   std::cout << "===> WARNING! auth_path is specified as " << auth_path;
00060   std::cout << " but is not used explicitely. Is it being used at all?"  << std::endl;
00061   cond::DbConnection conn;
00062   //conn.configure( cond::CmsDefaults );
00063   conn.configuration().setAuthenticationPath(auth_path);
00064   //conn.configuration().setMessageLevel( coral::Debug );
00065   conn.configure();
00066   cond::DbSession session = conn.createSession();
00067   session.open(connect);
00068   std::vector<std::string> alltags;
00069   try{
00070     cond::MetaData metadata_svc(session);
00071     cond::DbScopedTransaction tr(session);
00072     tr.start(true);
00073     metadata_svc.listAllTags(alltags);
00074     tr.commit();
00075   }catch(cond::Exception& er){
00076     std::cout<<er.what()<<std::endl;
00077   }catch(std::exception& er){
00078     std::cout<<er.what()<<std::endl;
00079   }
00080   return alltags;
00081 }
00082 
00083 
00084 
00085 // inspired by cmscond_list_iov
00086 //
00087 int HcalO2OManager::getListOfPoolIovs(std::vector<uint32_t> & out,
00088                                       std::string tag, 
00089                                       std::string connect,
00090                                       std::string auth_path){
00091   //edmplugin::PluginManager::configure(edmplugin::standard::config()); // in the constructor for now
00092   // FIXME: how to add auth_path authentication to this? See v1.25 for the functionality using old API  
00093   std::cout << "===> WARNING! auth_path is specified as " << auth_path;
00094   std::cout << " but is not used explicitely. Is it being used at all?"  << std::endl;
00095   bool details=false;
00096   cond::DbConnection conn;
00097   //conn.configure( cond::CmsDefaults );
00098   conn.configuration().setAuthenticationPath(auth_path);
00099   //conn.configuration().setMessageLevel( coral::Debug );
00100   conn.configure();
00101   cond::DbSession session = conn.createSession();
00102   session.open(connect);
00103   out.clear();
00104   try{
00105     cond::MetaData metadata_svc(session);
00106     cond::DbScopedTransaction tr(session);
00107      tr.start(true);
00108      std::string token;
00109      if(!metadata_svc.hasTag(tag)){
00110        //std::cout << "no such tag in the Pool database!" << std::endl;
00111        return -1;
00112      }
00113      token=metadata_svc.getToken(tag);
00114      cond::IOVProxy iov(session, token, !details, details);
00115      unsigned int counter=0;
00116      std::string payloadContainer=iov.payloadContainerName();
00117      
00118      for (cond::IOVProxy::const_iterator ioviterator=iov.begin(); ioviterator!=iov.end(); ioviterator++) {
00119        out.push_back(ioviterator->since());
00120        ++counter;
00121      }
00122      tr.commit();
00123   }
00124   catch(cond::Exception& er){
00125     std::cout<<er.what()<<std::endl;
00126   }catch(std::exception& er){
00127     std::cout<<er.what()<<std::endl;
00128   }
00129   return out.size();
00130 }
00131 
00132 
00133 
00134 std::vector<std::string> HcalO2OManager::getListOfOmdsTags(){
00135   std::vector<std::string> alltags;
00136   static ConnectionManager conn;
00137   conn.connect();
00138   std::string query = "select ";
00139   query            += "       channel_map_id,subdet,ieta,iphi,depth ";
00140   query            += "from ";
00141   query            += "       cms_hcl_hcal_cond.hcal_channels ";
00142   query            += "where ";
00143   query            += "       subdet='HB' or subdet='HE' or subdet='HF' or subdet='HO' ";
00144   int _n_tags = 0;
00145   try {
00146     oracle::occi::Statement* stmt = conn.getStatement(query);
00147     oracle::occi::ResultSet *rs = stmt->executeQuery();
00148     while (rs->next()) {
00149       _n_tags++;
00150       //alltags.push_back(rs->getString(1));
00151     }
00152   }
00153   catch (SQLException& e) {
00154     std::cerr << ::toolbox::toString("Oracle  exception : %s",e.getMessage().c_str()) << std::endl;
00155     XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,::toolbox::toString("Oracle  exception : %s",e.getMessage().c_str()));
00156   }
00157   conn.disconnect();
00158   return alltags;
00159 }
00160 
00161 
00162 
00163 int HcalO2OManager::getListOfOmdsIovs(std::vector<uint32_t> & out, std::string tagname){
00164   out.clear();
00165   static ConnectionManager conn;
00166   conn.connect();
00167   std::string query = " ";
00168   //query += "select iov, ";
00169   //query += "       i.cond_iov_record_id, ";
00170   //query += "       time ";
00171   //query += "from ( ";
00172   query += "      select iovs.interval_of_validity_begin as iov, ";
00173   query += "             min(iovs.record_insertion_time) time ";
00174   query += "      from cms_hcl_core_iov_mgmnt.cond_tags tags ";
00175   query += "      inner join cms_hcl_core_iov_mgmnt.cond_iov2tag_maps i2t ";
00176   query += "      on tags.cond_tag_id=i2t.cond_tag_id ";
00177   query += "      inner join cms_hcl_core_iov_mgmnt.cond_iovs iovs ";
00178   query += "      on i2t.cond_iov_record_id=iovs.cond_iov_record_id ";
00179   query += "where ";
00180   query += "      tags.tag_name=:1 ";
00181   query += "group by iovs.interval_of_validity_begin ";
00182   //query += "     ) ";
00183   //query += "inner join cms_hcl_core_iov_mgmnt.cond_iovs i ";
00184   //query += "on time=i.record_insertion_time ";
00185   query += "order by time asc ";
00186   int _n_iovs = 0;
00187   try {
00188     oracle::occi::Statement* stmt = conn.getStatement(query);
00189     //_____  set bind variables
00190     stmt->setString(1,tagname);
00191     oracle::occi::ResultSet *rs = stmt->executeQuery();
00192     while (rs->next()) {
00193       _n_iovs++;
00194       out.push_back(rs->getInt(1));
00195     }
00196   }
00197   catch (SQLException& e) {
00198     std::cerr << ::toolbox::toString("Oracle  exception : %s",e.getMessage().c_str()) << std::endl;
00199     XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,::toolbox::toString("Oracle  exception : %s",e.getMessage().c_str()));
00200   }
00201   conn.disconnect();
00202   return out.size();
00203 }
00204 
00205 
00206 void HcalO2OManager::getListOfNewIovs_test( void ){
00207   std::vector<uint32_t> omds, orcon, out;
00208   orcon.push_back(1);
00209   orcon.push_back(100);
00210   //orcon.push_back(80000);
00211   //orcon.push_back(90000);
00212   //orcon.push_back(100000);
00213   //orcon.push_back(199000);
00214   //orcon.push_back(199001);
00215   //orcon.push_back(199002);
00216   //orcon.push_back(199003);
00217   omds.push_back(1);
00218   omds.push_back(100);
00219   //omds.push_back(80000);
00220   //omds.push_back(90000);
00221   //omds.push_back(100000);
00222   //omds.push_back(199000);
00223   //omds.push_back(199001);
00224   //omds.push_back(199002);
00225   //omds.push_back(199004);
00226   if (getListOfNewIovs(out, omds, orcon) == -1){
00227     std::cout << "HcalO2OManager::getListOfNewIovs_test(): O2O is not possible" << std::endl;
00228   }
00229   else if (getListOfNewIovs(out, omds, orcon) == 0){
00230     std::cout << "HcalO2OManager::getListOfNewIovs_test(): O2O is not needed, the tag is up to date" << std::endl;
00231   }
00232   else{
00233     std::cout << "HcalO2OManager::getListOfNewIovs_test(): O2O is possible" << std::endl;
00234     std::cout << "HcalO2OManager::getListOfNewIovs_test(): " << out.size() << " IOVs to be copied to ORCON" << std::endl;
00235     std::copy (out.begin(),
00236                out.end(),
00237                std::ostream_iterator<uint32_t>(std::cout,"\n")
00238                );
00239   }
00240 }
00241 
00242 
00243 int HcalO2OManager::getListOfNewIovs(std::vector<uint32_t> & iovs,
00244                                      const std::vector<uint32_t> & omds_iovs,
00245                                      const std::vector<uint32_t> & orcon_iovs){
00246   int result = -1; // default fail
00247   iovs.clear();
00248 
00249   // OMDS tag may not have the first IOV=1
00250   int _orcon_index_offset = 0;
00251   if (omds_iovs.size() > 0 &&
00252       orcon_iovs.size() > 0 &&
00253       orcon_iovs[0] == 1 &&
00254       omds_iovs[0] != 1){
00255     std::cout << std::endl << "HcalO2OManager: First IOV in the OMDS tag is not 1," << std::endl;
00256     std::cout << "HcalO2OManager: while it must be 1 in the offline tag." << std::endl;
00257     std::cout << "HcalO2OManager: O2O will assume that IOV=1 in the offline tag" << std::endl;
00258     std::cout << "HcalO2OManager: is filled with some safe default." << std::endl;
00259     std::cout << "HcalO2OManager: IOV=1 will be ignored, and O2O will proceeed" << std::endl;
00260     std::cout << "HcalO2OManager: as long as other inconsistencies are not detected." << std::endl << std::endl;
00261     _orcon_index_offset = 1; // skip the first IOV in ORCON because it
00262     //                       // is 1 while OMDS doesn't have IOV=1
00263   } 
00264   if (omds_iovs.size()+_orcon_index_offset < orcon_iovs.size()){
00265     std::cout << "HcalO2OManager: too many IOVs in the Pool tag, cannot sync, exiting..." << std::endl;
00266     return result;
00267   }
00268 
00269   // loop over all OMDS IOVs
00270   unsigned int _index = 0;
00271 
00272   bool enforce_strict_matching = false; // set to true if the strict IOV matching is desired, see description in the comments below
00273 
00274  // use this to keep track of how well the existing OMDS and offline IOV sets match
00275   unsigned int _sync_status = 0;
00276   for (std::vector<uint32_t>::const_iterator _iov = orcon_iovs.begin();
00277        _iov != orcon_iovs.end();
00278        ++_iov){
00279     _index = (int)(_iov - orcon_iovs.begin());
00280 
00281     // special case when the first Pool IOV = 1 (must always be true)
00282     // but OMDS IOVs do not start with IOV = 1
00283     // This can be a ligitimate mismatch when the OMDS tag is created for
00284     // current conditions without regard to the history
00285     // In such cases, when creating a copy of this tag in offline,
00286     // O2O copies the first IOV from OMDS and assigns it as IOV=1.
00287     // With later sync passes, O2O must skip the first offline IOV = 1
00288     if (_orcon_index_offset == 1 && _index == 0) continue;
00289 
00290     // current pair of OMDS-offline IOVs does not match
00291     // There are several options in such case:
00292     //
00293     //   - with strict matching, the program should quit, as it is not possible
00294     //     to keep the tag in sync between OMDS and offline because
00295     //     offline tags do not allow fixes, only updates
00296     //
00297     //   - intermediate solution is to find the latest IOV in the offline tag
00298     //     and append any IOVs from the OMDS tag that come after it
00299     //
00300 
00301     if (omds_iovs[_index-_orcon_index_offset] != orcon_iovs[_index]){
00302 
00303       std::cout << std::endl;
00304       std::cout << "HcalO2OManager: existing IOVs do not match, cannot sync in the strict sense." << std::endl;
00305       std::cout << "HcalO2OManager: mismatched pair is (OMDS/offline): " << omds_iovs[_index-_orcon_index_offset] << "/" << orcon_iovs[_index] << std::endl;
00306       std::cout << "HcalO2OManager: In the strict sense, the SYNCHRONIZATION OF THIS TAG HAS FAILED!" << std::endl;
00307       std::cout << "HcalO2OManager: As an interim solution, I will still copy to the offline tag" << std::endl;
00308       std::cout << "HcalO2OManager: those IOV from the OMDS tag that are newer than the last IOV" << std::endl;
00309       std::cout << "HcalO2OManager: currently in the offline tag. " << std::endl;
00310 
00311       _sync_status = 1; // dunno what for, may be handy in future
00312 
00313       // existing IOVs do not match
00314 
00315       if (enforce_strict_matching){
00316         return result;
00317       }
00318       else{
00319         break; // _index now contains the last "valid" OMDS IOV
00320       }
00321 
00322     }
00323     ++_index;
00324   }
00325 
00326 
00327   //
00328   //_____ loop over remaining OMDS IOVs
00329   //
00330   //std::cout << "HcalO2OManager: DEBUG: " << std::endl;
00331   int _counter = 0; // count output IOVs
00332   uint32_t _lastOrconIov = orcon_iovs[orcon_iovs.size()-1];
00333 
00334   for (;_index < omds_iovs.size();++_index){
00335 
00336     uint32_t _aIov = omds_iovs[_index];
00337 
00338     if (_index == 0 && _aIov > _lastOrconIov){ // can only copy later IOVs
00339       iovs.push_back(_aIov);
00340       ++_counter;
00341     }
00342     else if (omds_iovs[_index]>omds_iovs[_index-1] &&
00343              _aIov > _lastOrconIov){  // can only copy later IOVs
00344       iovs.push_back(omds_iovs[_index]);
00345       ++_counter;
00346     }
00347     else{
00348       if (enforce_strict_matching){
00349         return result;
00350       }
00351       else{
00352         continue;
00353       }
00354     }
00355   }
00356   //if (_counter != 0) result = _counter;
00357   result = _counter;
00358   return result;
00359 }
00360 
00361 
00362 // get list of IOVs to update for a given tag, or report impossible
00363 // return:
00364 // list of IOVs as first argument,
00365 // number of IOVs to update as return value
00366 // -1 if tag is inconsistent with the update
00367 // 0 if everything's up to date already
00368 int HcalO2OManager::getListOfUpdateIovs(std::vector<uint32_t> & _iovs,
00369                                         std::string _tag,
00370                                         std::string pool_connect_string,
00371                                         std::string pool_auth_path
00372                                         ){
00373   //std::cout << "DEBUG: " << pool_connect_string << std::endl;
00374   std::vector<uint32_t> omds_iovs;
00375   std::vector<uint32_t> pool_iovs;
00376   getListOfOmdsIovs(omds_iovs, _tag);
00377   getListOfPoolIovs(pool_iovs, _tag, pool_connect_string, pool_auth_path);
00378   int n_iovs = getListOfNewIovs(_iovs,
00379                                 omds_iovs,
00380                                 pool_iovs);
00381   if (n_iovs == -1){
00382     std::cout << "HcalO2OManager: O2O is not possible" << std::endl;
00383   }
00384   else if (n_iovs == 0){
00385     std::cout << "HcalO2OManager: O2O is not needed, the tag is up to date" << std::endl;
00386   }
00387   else{
00388     edm::LogInfo("HcalO2OManager") << "These IOVs are to be updated:" << std::endl;
00389     for (std::vector<uint32_t>::const_iterator iov = _iovs.begin();
00390          iov != _iovs.end();
00391          ++iov){
00392       std::cout << "O2O_IOV_LIST: " << *iov << std::endl;
00393     }
00394   }
00395   return n_iovs;
00396 }