File indexing completed on 2025-01-18 09:57:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef GAUDIKERNEL_EVENTIDBASE_H
0012 #define GAUDIKERNEL_EVENTIDBASE_H 1
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <cstdint>
0027 #include <iomanip>
0028 #include <iostream>
0029 #include <tuple>
0030
0031 #include "GaudiKernel/compose.h"
0032 namespace details {
0033 template <typename lambda>
0034 struct arg_helper : public arg_helper<decltype( &lambda::operator() )> {};
0035 template <typename T, typename Ret, typename Arg>
0036 struct arg_helper<Ret ( T::* )( Arg ) const> {
0037 using type = Arg;
0038 };
0039
0040
0041
0042 template <typename lambda>
0043 using argument_t = typename arg_helper<lambda>::type;
0044
0045 template <typename Fun>
0046 auto add_deref( Fun f ) {
0047 return compose( f, [=]( auto*... p ) { return f( *p... ); } );
0048 }
0049
0050 template <typename Proj, typename Cmp = std::greater<>>
0051 auto make_cmp( Proj p, Cmp cmp = {} ) {
0052 static_assert( std::is_reference_v<argument_t<Proj>>, "must be a reference" );
0053 static_assert( std::is_const_v<std::remove_reference_t<argument_t<Proj>>>, "must be const" );
0054 return [=]( argument_t<Proj> lhs, argument_t<Proj> rhs ) { return cmp( p( lhs ), p( rhs ) ); };
0055 }
0056 }
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 class EventIDBase {
0067 public:
0068 typedef unsigned int number_type;
0069 typedef uint64_t event_number_t;
0070
0071 static const number_type UNDEFNUM;
0072 static const event_number_t UNDEFEVT;
0073
0074 friend class EventIDRange;
0075
0076 public:
0077
0078
0079 EventIDBase(){};
0080 EventIDBase( number_type run_number, event_number_t event_number, number_type time_stamp = UNDEFNUM,
0081 number_type time_stamp_ns_offset = 0, number_type lumi_block = UNDEFNUM,
0082 number_type bunch_crossing_id = 0 );
0083
0084 EventIDBase( std::tuple<number_type, number_type, event_number_t> run_lumi_ev,
0085 std::tuple<number_type, number_type> time_stamp, number_type bunch_crossing_id );
0086
0087
0088 virtual ~EventIDBase() = default;
0089
0090
0091
0092 number_type run_number() const { return m_run_number; }
0093
0094
0095 event_number_t event_number() const { return m_event_number; }
0096
0097
0098 number_type time_stamp() const { return m_time_stamp; }
0099
0100
0101 number_type time_stamp_ns_offset() const { return m_time_stamp_ns_offset; }
0102
0103
0104 number_type lumi_block() const { return m_lumi_block; }
0105
0106
0107 number_type bunch_crossing_id() const { return m_bunch_crossing_id; }
0108
0109
0110 void set_run_number( number_type runNumber ) {
0111 m_run_number = runNumber;
0112 if ( m_event_number != UNDEFEVT ) setRE();
0113 if ( m_lumi_block != UNDEFNUM ) setRL();
0114 }
0115
0116
0117 void set_event_number( event_number_t eventNumber ) {
0118 m_event_number = eventNumber;
0119 if ( m_run_number != UNDEFNUM ) setRE();
0120 if ( m_lumi_block != UNDEFNUM ) setLE();
0121 }
0122
0123
0124 void set_time_stamp( number_type timeStamp ) {
0125 m_time_stamp = timeStamp;
0126 setTS();
0127 }
0128
0129
0130 void set_time_stamp_ns_offset( number_type timeStampNs ) { m_time_stamp_ns_offset = timeStampNs; }
0131
0132
0133 void set_lumi_block( number_type lumiBlock ) {
0134 m_lumi_block = lumiBlock;
0135 if ( m_run_number != UNDEFNUM ) setRL();
0136 if ( m_event_number != UNDEFEVT ) setLE();
0137 }
0138
0139
0140 void set_bunch_crossing_id( number_type bcid ) { m_bunch_crossing_id = bcid; }
0141
0142
0143 friend bool operator==( const EventIDBase& lhs, const EventIDBase& rhs );
0144 friend bool operator<( const EventIDBase& lhs, const EventIDBase& rhs );
0145 friend bool operator>( const EventIDBase& lhs, const EventIDBase& rhs ) { return rhs < lhs; }
0146 friend bool operator!=( const EventIDBase& lhs, const EventIDBase& rhs ) { return !( lhs == rhs ); }
0147 friend bool operator<=( const EventIDBase& lhs, const EventIDBase& rhs ) { return !( lhs > rhs ); }
0148 friend bool operator>=( const EventIDBase& lhs, const EventIDBase& rhs ) { return !( lhs < rhs ); }
0149
0150 friend EventIDBase min( const EventIDBase& lhs, const EventIDBase& rhs );
0151 friend EventIDBase max( const EventIDBase& lhs, const EventIDBase& rhs );
0152
0153 bool isRunEvent() const { return m_type & RunEvent; }
0154 bool isTimeStamp() const { return m_type & TimeStamp; }
0155 bool isLumiEvent() const { return m_type & LumiEvent; }
0156 bool isRunLumi() const { return m_type & RunLumi; }
0157 bool isValid() const { return m_type != Invalid; }
0158
0159
0160 friend std::ostream& operator<<( std::ostream& os, const EventIDBase& rhs );
0161
0162 static auto SortByTimeStamp() {
0163 return ::details::add_deref( ::details::make_cmp(
0164 []( const EventIDBase& e ) { return std::tie( e.m_time_stamp, e.m_time_stamp_ns_offset ); } ) );
0165 };
0166
0167 static auto SortByRunEvent() {
0168 return ::details::add_deref(
0169 ::details::make_cmp( []( const EventIDBase& e ) { return std::tie( e.m_run_number, e.m_event_number ); } ) );
0170 };
0171
0172 static auto SortByLumiEvent() {
0173 return ::details::add_deref(
0174 ::details::make_cmp( []( const EventIDBase& e ) { return std::tie( e.m_lumi_block, e.m_event_number ); } ) );
0175 };
0176
0177 static auto SortByRunLumi() {
0178 return ::details::add_deref(
0179 ::details::make_cmp( []( const EventIDBase& e ) { return std::tie( e.m_run_number, e.m_lumi_block ); } ) );
0180 };
0181
0182 private:
0183 enum Type { Invalid = 0, RunEvent = 1 << 1, TimeStamp = 1 << 2, LumiEvent = 1 << 3, RunLumi = 1 << 4 };
0184
0185 unsigned m_type{ Invalid };
0186
0187 void setRE() { m_type |= RunEvent; }
0188 void setTS() { m_type |= TimeStamp; }
0189 void setLE() { m_type |= LumiEvent; }
0190 void setRL() { m_type |= RunLumi; }
0191
0192
0193 number_type m_run_number{ UNDEFNUM };
0194
0195
0196 event_number_t m_event_number{ UNDEFEVT };
0197
0198
0199 number_type m_time_stamp{ UNDEFNUM };
0200
0201
0202 number_type m_time_stamp_ns_offset{ UNDEFNUM };
0203
0204
0205
0206 number_type m_lumi_block{ UNDEFNUM };
0207
0208
0209 number_type m_bunch_crossing_id{ UNDEFNUM };
0210 };
0211
0212 inline EventIDBase min( const EventIDBase& lhs, const EventIDBase& rhs ) {
0213
0214
0215
0216
0217 return EventIDBase( std::min( std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ),
0218 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number ) ),
0219 std::min( std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset ),
0220 std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset ) ),
0221 lhs.bunch_crossing_id()
0222 );
0223 }
0224
0225 inline EventIDBase max( const EventIDBase& lhs, const EventIDBase& rhs ) {
0226
0227
0228
0229
0230 std::tuple<EventIDBase::number_type, EventIDBase::number_type, EventIDBase::event_number_t> run_lumi_ev;
0231 std::tuple<EventIDBase::number_type, EventIDBase::number_type> time_stamp;
0232
0233 if ( lhs.isTimeStamp() && rhs.isTimeStamp() ) {
0234 time_stamp = std::max( std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset ),
0235 std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset ) );
0236 } else if ( lhs.isTimeStamp() ) {
0237 time_stamp = std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset );
0238 } else {
0239 time_stamp = std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset );
0240 }
0241
0242 if ( lhs.isRunLumi() && rhs.isRunLumi() ) {
0243 run_lumi_ev = std::max( std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ),
0244 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number ) );
0245
0246 } else if ( lhs.isRunLumi() ) {
0247 run_lumi_ev = std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number );
0248 } else {
0249 run_lumi_ev = std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number );
0250 }
0251
0252 return EventIDBase( run_lumi_ev, time_stamp, lhs.bunch_crossing_id() );
0253 }
0254
0255 inline bool operator<( const EventIDBase& lhs, const EventIDBase& rhs ) {
0256
0257
0258
0259
0260 if ( lhs.isTimeStamp() && rhs.isTimeStamp() ) {
0261 return lhs.m_time_stamp < rhs.m_time_stamp;
0262 } else {
0263 return std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ) <
0264 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number );
0265 }
0266 }
0267
0268 inline bool operator==( const EventIDBase& lhs, const EventIDBase& rhs ) {
0269
0270 return ( lhs.m_run_number == rhs.m_run_number && lhs.m_event_number == rhs.m_event_number &&
0271 lhs.m_lumi_block == rhs.m_lumi_block );
0272 }
0273
0274 inline std::ostream& operator<<( std::ostream& os, const EventIDBase& rhs ) {
0275 if ( rhs.m_type == EventIDBase::Invalid ) return os << "[INVALID]";
0276
0277 const char* separator = "";
0278 os << "[";
0279 if ( rhs.m_run_number != EventIDBase::UNDEFNUM ) {
0280 os << rhs.m_run_number;
0281 separator = ",";
0282 }
0283
0284 if ( rhs.m_event_number != EventIDBase::UNDEFEVT ) {
0285 os << separator << rhs.m_event_number;
0286 separator = ",";
0287 }
0288
0289 if ( rhs.isTimeStamp() ) {
0290 os << separator << "t:" << rhs.m_time_stamp;
0291 if ( rhs.m_time_stamp_ns_offset != 0 ) {
0292 os << "." << std::setfill( '0' ) << std::setw( 9 ) << rhs.m_time_stamp_ns_offset;
0293 }
0294 separator = ",";
0295 }
0296
0297 if ( rhs.isLumiEvent() || rhs.isRunLumi() ) {
0298 os << separator << "l:" << rhs.m_lumi_block;
0299 separator = ",";
0300 }
0301
0302 if ( rhs.m_bunch_crossing_id != 0 ) { os << separator << "b:" << rhs.m_bunch_crossing_id; }
0303 os << "]";
0304 return os;
0305 }
0306
0307 #endif