File indexing completed on 2025-07-06 08:36:42
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 friend EventIDBase min( const EventIDBase& lhs, const EventIDBase& rhs ) {
0212
0213
0214
0215
0216 return EventIDBase( std::min( std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ),
0217 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number ) ),
0218 std::min( std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset ),
0219 std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset ) ),
0220 lhs.bunch_crossing_id()
0221 );
0222 }
0223
0224 friend EventIDBase max( const EventIDBase& lhs, const EventIDBase& rhs ) {
0225
0226
0227
0228
0229 std::tuple<EventIDBase::number_type, EventIDBase::number_type, EventIDBase::event_number_t> run_lumi_ev;
0230 std::tuple<EventIDBase::number_type, EventIDBase::number_type> time_stamp;
0231
0232 if ( lhs.isTimeStamp() && rhs.isTimeStamp() ) {
0233 time_stamp = std::max( std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset ),
0234 std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset ) );
0235 } else if ( lhs.isTimeStamp() ) {
0236 time_stamp = std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset );
0237 } else {
0238 time_stamp = std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset );
0239 }
0240
0241 if ( lhs.isRunLumi() && rhs.isRunLumi() ) {
0242 run_lumi_ev = std::max( std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ),
0243 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number ) );
0244
0245 } else if ( lhs.isRunLumi() ) {
0246 run_lumi_ev = std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number );
0247 } else {
0248 run_lumi_ev = std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number );
0249 }
0250
0251 return EventIDBase( run_lumi_ev, time_stamp, lhs.bunch_crossing_id() );
0252 }
0253
0254 friend bool operator<( const EventIDBase& lhs, const EventIDBase& rhs ) {
0255
0256
0257
0258
0259 if ( lhs.isTimeStamp() && rhs.isTimeStamp() ) {
0260 return lhs.m_time_stamp < rhs.m_time_stamp;
0261 } else {
0262 return std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ) <
0263 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number );
0264 }
0265 }
0266
0267 friend bool operator==( const EventIDBase& lhs, const EventIDBase& rhs ) {
0268
0269 return ( lhs.m_run_number == rhs.m_run_number && lhs.m_event_number == rhs.m_event_number &&
0270 lhs.m_lumi_block == rhs.m_lumi_block );
0271 }
0272
0273 friend std::ostream& operator<<( std::ostream& os, const EventIDBase& rhs ) {
0274 if ( rhs.m_type == EventIDBase::Invalid ) return os << "[INVALID]";
0275
0276 const char* separator = "";
0277 os << "[";
0278 if ( rhs.m_run_number != EventIDBase::UNDEFNUM ) {
0279 os << rhs.m_run_number;
0280 separator = ",";
0281 }
0282
0283 if ( rhs.m_event_number != EventIDBase::UNDEFEVT ) {
0284 os << separator << rhs.m_event_number;
0285 separator = ",";
0286 }
0287
0288 if ( rhs.isTimeStamp() ) {
0289 os << separator << "t:" << rhs.m_time_stamp;
0290 if ( rhs.m_time_stamp_ns_offset != 0 ) {
0291 os << "." << std::setfill( '0' ) << std::setw( 9 ) << rhs.m_time_stamp_ns_offset;
0292 }
0293 separator = ",";
0294 }
0295
0296 if ( rhs.isLumiEvent() || rhs.isRunLumi() ) {
0297 os << separator << "l:" << rhs.m_lumi_block;
0298 separator = ",";
0299 }
0300
0301 if ( rhs.m_bunch_crossing_id != 0 ) { os << separator << "b:" << rhs.m_bunch_crossing_id; }
0302 os << "]";
0303 return os;
0304 }
0305 };
0306
0307 #endif