00001 #ifndef CondTolls_L1Trigger_DataReader_h 00002 #define CondTolls_L1Trigger_DataReader_h 00003 00004 #include "FWCore/Framework/interface/DataProxy.h" 00005 #include "FWCore/Framework/interface/DataKey.h" 00006 00007 #include "DataFormats/Provenance/interface/RunID.h" 00008 #include "CondFormats/L1TObjects/interface/L1TriggerKey.h" 00009 00010 #include "CondTools/L1Trigger/interface/DataManager.h" 00011 #include "CondTools/L1Trigger/interface/Interval.h" 00012 00013 #include "CondCore/DBCommon/interface/TypedRef.h" 00014 #include "CondCore/PluginSystem/interface/DataProxy.h" 00015 00016 00017 #include <string> 00018 #include <vector> 00019 #include <map> 00020 00021 namespace l1t 00022 { 00023 00024 /* This class is used to read L1 trigger configuration data from pool DB. It will provide 00025 * service for managing connections and loading all the data. This class should be 00026 * used with l1t::DataWriter 00027 * 00028 * This class provides two different access method. One is used when user knows exact types to load 00029 * from DB at compile time. In such case she or he should use methods readKey (...) and readPayload (...). 00030 * 00031 * In case user is running in DataProxyProvider mode and does not know all the types at compile time, 00032 * she or he should use methods that returns DataProxy. It is assumed that these proxies should be then passed 00033 * to frameork, although this requirement is not enforced. 00034 * 00035 * For all payload read operations user has to provide a valid L1TriggerKey. It is expected that this key comes 00036 * from readKey method, although, if user is able to guarante that key is valid it can use any other source. 00037 * 00038 * Validity of all data is controled by validity of L1TriggerKey. 00039 */ 00040 class DataReader : public DataManager 00041 { 00042 public: 00043 /* Constructors. This system will use pool db that is configured via provided parameters. 00044 * connect - connection string to pool db, e.g. sqlite_file:test.db 00045 * catalog - catalog that should be used for this connection. e.g. file:test.xml 00046 */ 00047 //explicit DataReader (const std::string & connect, const std::string & catalog); 00048 explicit DataReader (const std::string& connectString, 00049 const std::string& authenticationPath ); 00050 virtual ~DataReader (); 00051 00052 /* Returns key for givent tag ant IOV time moment. This key then can be used 00053 * to load all other data 00054 */ 00055 L1TriggerKey readKey (const std::string & tag, const edm::RunNumber_t & run); 00056 /* Reads payload from the DB. This one requires L1 key to figure out which record is considered 00057 * valid 00058 */ 00059 00060 L1TriggerKey readKey (const std::string & payloadToken); 00061 00062 template<typename T> 00063 T readPayload (const L1TriggerKey & key, const std::string & record); 00064 00065 // Read payload by payload token 00066 template<typename T> 00067 void readPayload ( const std::string & payloadToken, T& payload ); 00068 00069 //void readPayload ( const std::string & payloadToken, L1TriggerKey& payload ); 00070 00071 /* Returns proxy that should provided objects of given type for given object. This will not 00072 * take any information about IOV moment. You can set this information via updateToken. 00073 * Also, one should note that when object is returned by this method it is not valid 00074 * until updateToken is called for this record and type. 00075 * 00076 * Such strange behavior requirements comes from the fact how DataProxyProvider works. This method 00077 * is designed, but not limited, to be used by DataProxyProvider (e.g. L1TDBESSource) 00078 */ 00079 std::pair<boost::shared_ptr<edm::eventsetup::DataProxy>, edm::eventsetup::DataKey> 00080 payload (const std::string & record, const std::string & type); 00081 00082 /* Returns proxy that is responsible for creating L1TriggerKey record and type itself. 00083 * All requirements and notes are the same as in payload (...) method. 00084 */ 00085 std::pair<boost::shared_ptr<edm::eventsetup::DataProxy>, edm::eventsetup::DataKey> key (); 00086 00087 /* Returns IOV interval for given key tag and IOV time moment. May return invalid() interval if time is 00088 * not found. 00089 */ 00090 std::pair<edm::RunNumber_t, edm::RunNumber_t> interval (const std::string & tag, const edm::RunNumber_t & run); 00091 00092 /* Returns pair that indictates that this interval is invalid. 00093 * At the moment it will return interval of (-1, -2), this is not always good 00094 * so one should thing about better approach 00095 */ 00096 static std::pair<edm::RunNumber_t, edm::RunNumber_t> invalid (); 00097 00098 /* Instructs previusly returned proxy (from method payload (...)) to load data 00099 * associated with given tag and IOV value. Thus, record and type parameters are used to identify 00100 * which proxy to update. Correct record and type is selected from DB based on proovided key 00101 */ 00102 void updateToken (const std::string & record, const std::string & type, 00103 const L1TriggerKey & key); 00104 00105 /* Updates key proxy (returned by method key (...)) to start producing new key with given tag and 00106 * run number. This will not effect objects loaded with method payload (...). So one has to call other version 00107 * of updateToken to make sure than payload is returned correctly 00108 */ 00109 void updateToken (const std::string & tag, const edm::RunNumber_t run); 00110 00111 protected: 00112 /* Loads all IOV intervals that are valid in DB for given tag. 00113 */ 00114 IntervalManager<edm::RunNumber_t, std::string> loadIntervals (const std::string & tag); 00115 00116 /* Returns payload token for given tag and run number 00117 */ 00118 std::string payloadToken (const std::string & tag, const edm::RunNumber_t run) const; 00119 00120 /* Helper method that does the actual work for method payload (...) and key (...) 00121 */ 00122 std::pair<boost::shared_ptr<edm::eventsetup::DataProxy>, edm::eventsetup::DataKey> 00123 createPayload (const std::string & record, const std::string & type); 00124 00125 /* Stores a list of intervals associated with each tag. 00126 * Most of the time it should be tag, but this system supports any number of them 00127 */ 00128 std::map<std::string, IntervalManager<edm::RunNumber_t, std::string> > intervals; 00129 00130 /* I am using DataProxy. Its construtor takes a last parameteres as an iterator 00131 * to map of string of string. Technically it needs only the second string. 00132 * The problem that I have here is that I have to make sure that DataProxy that I am 00133 * returning will die before map whos iterator it uses. Thus we have map here. 00134 */ 00135 std::map<std::string, std::string> typeToToken; 00136 }; 00137 00138 /* Template functions implementation */ 00139 00140 template<typename T> 00141 T DataReader::readPayload (const L1TriggerKey & key, const std::string & record) 00142 { 00143 /* pool->connect (); */ 00144 //connection->connect( session ) ; 00145 /* pool->startTransaction (false); */ 00146 cond::PoolTransaction& pool = connection->poolTransaction() ; 00147 pool.start( false ) ; 00148 00149 // Convert type to class name. 00150 std::string typeName = 00151 edm::eventsetup::heterocontainer::HCTypeTagTemplate<T, edm::eventsetup::DataKey>::className (); 00152 std::string token = key.get (record, typeName); 00153 assert (!token.empty ()); 00154 00155 cond::TypedRef<T> ref (pool, token); 00156 00157 pool.commit (); 00158 /* pool->disconnect (); */ 00159 //connection->disconnect (); 00160 return T (*ref); 00161 } 00162 00163 template<typename T> 00164 void DataReader::readPayload( const std::string& payloadToken, T& payload ) 00165 { 00166 cond::PoolTransaction& pool = connection->poolTransaction() ; 00167 pool.start( true ) ; 00168 00169 cond::TypedRef<T> ref (pool, payloadToken); 00170 00171 pool.commit (); 00172 payload = *ref ; 00173 } 00174 00175 } 00176 00177 #endif