CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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.41 2011/06/07 08:40:49 gowdy 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   cond::DbConnection conn;
00096   //conn.configure( cond::CmsDefaults );
00097   conn.configuration().setAuthenticationPath(auth_path);
00098   //conn.configuration().setMessageLevel( coral::Debug );
00099   conn.configure();
00100   cond::DbSession session = conn.createSession();
00101   session.open(connect);
00102   out.clear();
00103   try{
00104     cond::MetaData metadata_svc(session);
00105     cond::DbScopedTransaction tr(session);
00106      tr.start(true);
00107      std::string token;
00108      if(!metadata_svc.hasTag(tag)){
00109        //std::cout << "no such tag in the Pool database!" << std::endl;
00110        return -1;
00111      }
00112      token=metadata_svc.getToken(tag);
00113      cond::IOVProxy iov(session, token);
00114      unsigned int counter=0;
00115      
00116      for (cond::IOVProxy::const_iterator ioviterator=iov.begin(); ioviterator!=iov.end(); ioviterator++) {
00117        out.push_back(ioviterator->since());
00118        ++counter;
00119      }
00120      tr.commit();
00121   }
00122   catch(cond::Exception& er){
00123     std::cout<<er.what()<<std::endl;
00124   }catch(std::exception& er){
00125     std::cout<<er.what()<<std::endl;
00126   }
00127   return out.size();
00128 }
00129 
00130 
00131 
00132 std::vector<std::string> HcalO2OManager::getListOfOmdsTags(){
00133   std::vector<std::string> alltags;
00134   static ConnectionManager conn;
00135   conn.connect();
00136   std::string query = "select ";
00137   query            += "       channel_map_id,subdet,ieta,iphi,depth ";
00138   query            += "from ";
00139   query            += "       cms_hcl_hcal_cond.hcal_channels ";
00140   query            += "where ";
00141   query            += "       subdet='HB' or subdet='HE' or subdet='HF' or subdet='HO' ";
00142   int _n_tags = 0;
00143   try {
00144     oracle::occi::Statement* stmt = conn.getStatement(query);
00145     oracle::occi::ResultSet *rs = stmt->executeQuery();
00146     while (rs->next()) {
00147       _n_tags++;
00148       //alltags.push_back(rs->getString(1));
00149     }
00150   }
00151   catch (SQLException& e) {
00152     std::cerr << ::toolbox::toString("Oracle  exception : %s",e.getMessage().c_str()) << std::endl;
00153     XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,::toolbox::toString("Oracle  exception : %s",e.getMessage().c_str()));
00154   }
00155   conn.disconnect();
00156   return alltags;
00157 }
00158 
00159 
00160 
00161 int HcalO2OManager::getListOfOmdsIovs(std::vector<uint32_t> & out, std::string tagname){
00162   out.clear();
00163   static ConnectionManager conn;
00164   conn.connect();
00165   std::string query = " ";
00166   //query += "select iov, ";
00167   //query += "       i.cond_iov_record_id, ";
00168   //query += "       time ";
00169   //query += "from ( ";
00170   query += "      select iovs.interval_of_validity_begin as iov, ";
00171   query += "             min(iovs.record_insertion_time) time ";
00172   query += "      from cms_hcl_core_iov_mgmnt.cond_tags tags ";
00173   query += "      inner join cms_hcl_core_iov_mgmnt.cond_iov2tag_maps i2t ";
00174   query += "      on tags.cond_tag_id=i2t.cond_tag_id ";
00175   query += "      inner join cms_hcl_core_iov_mgmnt.cond_iovs iovs ";
00176   query += "      on i2t.cond_iov_record_id=iovs.cond_iov_record_id ";
00177   query += "where ";
00178   query += "      tags.tag_name=:1 ";
00179   query += "group by iovs.interval_of_validity_begin ";
00180   //query += "     ) ";
00181   //query += "inner join cms_hcl_core_iov_mgmnt.cond_iovs i ";
00182   //query += "on time=i.record_insertion_time ";
00183   query += "order by time asc ";
00184   int _n_iovs = 0;
00185   try {
00186     oracle::occi::Statement* stmt = conn.getStatement(query);
00187     //_____  set bind variables
00188     stmt->setString(1,tagname);
00189     oracle::occi::ResultSet *rs = stmt->executeQuery();
00190     while (rs->next()) {
00191       _n_iovs++;
00192       out.push_back(rs->getInt(1));
00193     }
00194   }
00195   catch (SQLException& e) {
00196     std::cerr << ::toolbox::toString("Oracle  exception : %s",e.getMessage().c_str()) << std::endl;
00197     XCEPT_RAISE(hcal::exception::ConfigurationDatabaseException,::toolbox::toString("Oracle  exception : %s",e.getMessage().c_str()));
00198   }
00199   conn.disconnect();
00200   return out.size();
00201 }
00202 
00203 
00204 void HcalO2OManager::getListOfNewIovs_test( void ){
00205   std::vector<uint32_t> omds, orcon, out;
00206   orcon.push_back(1);
00207   orcon.push_back(100);
00208   //orcon.push_back(80000);
00209   //orcon.push_back(90000);
00210   //orcon.push_back(100000);
00211   //orcon.push_back(199000);
00212   //orcon.push_back(199001);
00213   //orcon.push_back(199002);
00214   //orcon.push_back(199003);
00215   omds.push_back(1);
00216   omds.push_back(100);
00217   //omds.push_back(80000);
00218   //omds.push_back(90000);
00219   //omds.push_back(100000);
00220   //omds.push_back(199000);
00221   //omds.push_back(199001);
00222   //omds.push_back(199002);
00223   //omds.push_back(199004);
00224   if (getListOfNewIovs(out, omds, orcon) == -1){
00225     std::cout << "HcalO2OManager::getListOfNewIovs_test(): O2O is not possible" << std::endl;
00226   }
00227   else if (getListOfNewIovs(out, omds, orcon) == 0){
00228     std::cout << "HcalO2OManager::getListOfNewIovs_test(): O2O is not needed, the tag is up to date" << std::endl;
00229   }
00230   else{
00231     std::cout << "HcalO2OManager::getListOfNewIovs_test(): O2O is possible" << std::endl;
00232     std::cout << "HcalO2OManager::getListOfNewIovs_test(): " << out.size() << " IOVs to be copied to ORCON" << std::endl;
00233     std::copy (out.begin(),
00234                out.end(),
00235                std::ostream_iterator<uint32_t>(std::cout,"\n")
00236                );
00237   }
00238 }
00239 
00240 
00241 int HcalO2OManager::getListOfNewIovs(std::vector<uint32_t> & iovs,
00242                                      const std::vector<uint32_t> & omds_iovs,
00243                                      const std::vector<uint32_t> & orcon_iovs){
00244   int result = -1; // default fail
00245   iovs.clear();
00246 
00247   // OMDS tag may not have the first IOV=1
00248   int _orcon_index_offset = 0;
00249   if (omds_iovs.size() > 0 &&
00250       orcon_iovs.size() > 0 &&
00251       orcon_iovs[0] == 1 &&
00252       omds_iovs[0] != 1){
00253     std::cout << std::endl << "HcalO2OManager: First IOV in the OMDS tag is not 1," << std::endl;
00254     std::cout << "HcalO2OManager: while it must be 1 in the offline tag." << std::endl;
00255     std::cout << "HcalO2OManager: O2O will assume that IOV=1 in the offline tag" << std::endl;
00256     std::cout << "HcalO2OManager: is filled with some safe default." << std::endl;
00257     std::cout << "HcalO2OManager: IOV=1 will be ignored, and O2O will proceeed" << std::endl;
00258     std::cout << "HcalO2OManager: as long as other inconsistencies are not detected." << std::endl << std::endl;
00259     _orcon_index_offset = 1; // skip the first IOV in ORCON because it
00260     //                       // is 1 while OMDS doesn't have IOV=1
00261   } 
00262   if (omds_iovs.size()+_orcon_index_offset < orcon_iovs.size()){
00263     std::cout << "HcalO2OManager: too many IOVs in the Pool tag, cannot sync, exiting..." << std::endl;
00264     return result;
00265   }
00266 
00267   // loop over all OMDS IOVs
00268   unsigned int _index = 0;
00269 
00270   bool enforce_strict_matching = false; // set to true if the strict IOV matching is desired, see description in the comments below
00271 
00272  // use this to keep track of how well the existing OMDS and offline IOV sets match
00273   unsigned int _sync_status = 0;
00274   for (std::vector<uint32_t>::const_iterator _iov = orcon_iovs.begin();
00275        _iov != orcon_iovs.end();
00276        ++_iov){
00277     _index = (int)(_iov - orcon_iovs.begin());
00278 
00279     // special case when the first Pool IOV = 1 (must always be true)
00280     // but OMDS IOVs do not start with IOV = 1
00281     // This can be a ligitimate mismatch when the OMDS tag is created for
00282     // current conditions without regard to the history
00283     // In such cases, when creating a copy of this tag in offline,
00284     // O2O copies the first IOV from OMDS and assigns it as IOV=1.
00285     // With later sync passes, O2O must skip the first offline IOV = 1
00286     if (_orcon_index_offset == 1 && _index == 0) continue;
00287 
00288     // current pair of OMDS-offline IOVs does not match
00289     // There are several options in such case:
00290     //
00291     //   - with strict matching, the program should quit, as it is not possible
00292     //     to keep the tag in sync between OMDS and offline because
00293     //     offline tags do not allow fixes, only updates
00294     //
00295     //   - intermediate solution is to find the latest IOV in the offline tag
00296     //     and append any IOVs from the OMDS tag that come after it
00297     //
00298 
00299     if (omds_iovs[_index-_orcon_index_offset] != orcon_iovs[_index]){
00300 
00301       std::cout << std::endl;
00302       std::cout << "HcalO2OManager: existing IOVs do not match, cannot sync in the strict sense." << std::endl;
00303       std::cout << "HcalO2OManager: mismatched pair is (OMDS/offline): " << omds_iovs[_index-_orcon_index_offset] << "/" << orcon_iovs[_index] << std::endl;
00304       std::cout << "HcalO2OManager: In the strict sense, the SYNCHRONIZATION OF THIS TAG HAS FAILED!" << std::endl;
00305       std::cout << "HcalO2OManager: As an interim solution, I will still copy to the offline tag" << std::endl;
00306       std::cout << "HcalO2OManager: those IOV from the OMDS tag that are newer than the last IOV" << std::endl;
00307       std::cout << "HcalO2OManager: currently in the offline tag. " << std::endl;
00308 
00309       _sync_status = 1; // dunno what for, may be handy in future
00310 
00311       // existing IOVs do not match
00312 
00313       if (enforce_strict_matching){
00314         return result;
00315       }
00316       else{
00317         break; // _index now contains the last "valid" OMDS IOV
00318       }
00319 
00320     }
00321     ++_index;
00322   }
00323 
00324 
00325   //
00326   //_____ loop over remaining OMDS IOVs
00327   //
00328   //std::cout << "HcalO2OManager: DEBUG: " << std::endl;
00329   int _counter = 0; // count output IOVs
00330   uint32_t _lastOrconIov = orcon_iovs[orcon_iovs.size()-1];
00331 
00332   for (;_index < omds_iovs.size();++_index){
00333 
00334     uint32_t _aIov = omds_iovs[_index];
00335 
00336     if (_index == 0 && _aIov > _lastOrconIov){ // can only copy later IOVs
00337       iovs.push_back(_aIov);
00338       ++_counter;
00339     }
00340     else if (omds_iovs[_index]>omds_iovs[_index-1] &&
00341              _aIov > _lastOrconIov){  // can only copy later IOVs
00342       iovs.push_back(omds_iovs[_index]);
00343       ++_counter;
00344     }
00345     else{
00346       if (enforce_strict_matching){
00347         return result;
00348       }
00349       else{
00350         continue;
00351       }
00352     }
00353   }
00354   //if (_counter != 0) result = _counter;
00355   result = _counter;
00356   return result;
00357 }
00358 
00359 
00360 // get list of IOVs to update for a given tag, or report impossible
00361 // return:
00362 // list of IOVs as first argument,
00363 // number of IOVs to update as return value
00364 // -1 if tag is inconsistent with the update
00365 // 0 if everything's up to date already
00366 int HcalO2OManager::getListOfUpdateIovs(std::vector<uint32_t> & _iovs,
00367                                         std::string _tag,
00368                                         std::string pool_connect_string,
00369                                         std::string pool_auth_path
00370                                         ){
00371   //std::cout << "DEBUG: " << pool_connect_string << std::endl;
00372   std::vector<uint32_t> omds_iovs;
00373   std::vector<uint32_t> pool_iovs;
00374   getListOfOmdsIovs(omds_iovs, _tag);
00375   getListOfPoolIovs(pool_iovs, _tag, pool_connect_string, pool_auth_path);
00376   int n_iovs = getListOfNewIovs(_iovs,
00377                                 omds_iovs,
00378                                 pool_iovs);
00379   if (n_iovs == -1){
00380     std::cout << "HcalO2OManager: O2O is not possible" << std::endl;
00381   }
00382   else if (n_iovs == 0){
00383     std::cout << "HcalO2OManager: O2O is not needed, the tag is up to date" << std::endl;
00384   }
00385   else{
00386     edm::LogInfo("HcalO2OManager") << "These IOVs are to be updated:" << std::endl;
00387     for (std::vector<uint32_t>::const_iterator iov = _iovs.begin();
00388          iov != _iovs.end();
00389          ++iov){
00390       std::cout << "O2O_IOV_LIST: " << *iov << std::endl;
00391     }
00392   }
00393   return n_iovs;
00394 }