CMS 3D CMS Logo

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