The Gaudi Framework  master (b9786168)
Loading...
Searching...
No Matches
EventIDBase.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#pragma once
12
24
25#include <cstdint>
26#include <iomanip>
27#include <iostream>
28#include <tuple>
29
30#include <GaudiKernel/compose.h>
31namespace details {
32 template <typename lambda>
33 struct arg_helper : public arg_helper<decltype( &lambda::operator() )> {};
34 template <typename T, typename Ret, typename Arg>
35 struct arg_helper<Ret ( T::* )( Arg ) const> {
36 using type = Arg;
37 };
38
39 // given a unary lambda whose argument is of type Arg_t,
40 // argument_t<lambda> will be equal to Arg_t
41 template <typename lambda>
43
44 template <typename Fun>
45 auto add_deref( Fun f ) {
46 return compose( f, [=]( auto*... p ) { return f( *p... ); } );
47 }
48
49 template <typename Proj, typename Cmp = std::greater<>>
50 auto make_cmp( Proj p, Cmp cmp = {} ) {
51 static_assert( std::is_reference_v<argument_t<Proj>>, "must be a reference" );
52 static_assert( std::is_const_v<std::remove_reference_t<argument_t<Proj>>>, "must be const" );
53 return [=]( argument_t<Proj> lhs, argument_t<Proj> rhs ) { return cmp( p( lhs ), p( rhs ) ); };
54 }
55} // namespace details
56
64
66public:
67 typedef unsigned int number_type;
68 typedef uint64_t event_number_t;
69
70 static const number_type UNDEFNUM;
72
73 friend class EventIDRange;
74
75public:
77
82
83 EventIDBase( std::tuple<number_type, number_type, event_number_t> run_lumi_ev,
84 std::tuple<number_type, number_type> time_stamp, number_type bunch_crossing_id );
85
86 // Use default copy constructor.
87 virtual ~EventIDBase() = default;
89
92
95
98
101
104
107
109 void set_run_number( number_type runNumber ) {
110 m_run_number = runNumber;
111 if ( m_event_number != UNDEFEVT ) setRE();
112 if ( m_lumi_block != UNDEFNUM ) setRL();
113 }
114
116 void set_event_number( event_number_t eventNumber ) {
117 m_event_number = eventNumber;
118 if ( m_run_number != UNDEFNUM ) setRE();
119 if ( m_lumi_block != UNDEFNUM ) setLE();
120 }
121
123 void set_time_stamp( number_type timeStamp ) {
124 m_time_stamp = timeStamp;
125 setTS();
126 }
127
129 void set_time_stamp_ns_offset( number_type timeStampNs ) { m_time_stamp_ns_offset = timeStampNs; }
130
132 void set_lumi_block( number_type lumiBlock ) {
133 m_lumi_block = lumiBlock;
134 if ( m_run_number != UNDEFNUM ) setRL();
135 if ( m_event_number != UNDEFEVT ) setLE();
136 }
137
140
142 friend bool operator==( const EventIDBase& lhs, const EventIDBase& rhs );
143 friend bool operator<( const EventIDBase& lhs, const EventIDBase& rhs );
144 friend bool operator>( const EventIDBase& lhs, const EventIDBase& rhs ) { return rhs < lhs; }
145 friend bool operator!=( const EventIDBase& lhs, const EventIDBase& rhs ) { return !( lhs == rhs ); }
146 friend bool operator<=( const EventIDBase& lhs, const EventIDBase& rhs ) { return !( lhs > rhs ); }
147 friend bool operator>=( const EventIDBase& lhs, const EventIDBase& rhs ) { return !( lhs < rhs ); }
148
149 friend EventIDBase min( const EventIDBase& lhs, const EventIDBase& rhs );
150 friend EventIDBase max( const EventIDBase& lhs, const EventIDBase& rhs );
151
152 bool isRunEvent() const { return m_type & RunEvent; }
153 bool isTimeStamp() const { return m_type & TimeStamp; }
154 bool isLumiEvent() const { return m_type & LumiEvent; }
155 bool isRunLumi() const { return m_type & RunLumi; }
156 bool isValid() const { return m_type != Invalid; }
157
159 friend std::ostream& operator<<( std::ostream& os, const EventIDBase& rhs );
160
161 static auto SortByTimeStamp() {
162 return ::details::add_deref( ::details::make_cmp(
163 []( const EventIDBase& e ) { return std::tie( e.m_time_stamp, e.m_time_stamp_ns_offset ); } ) );
164 }
165
166 static auto SortByRunEvent() {
167 return ::details::add_deref(
168 ::details::make_cmp( []( const EventIDBase& e ) { return std::tie( e.m_run_number, e.m_event_number ); } ) );
169 }
170
171 static auto SortByLumiEvent() {
172 return ::details::add_deref(
173 ::details::make_cmp( []( const EventIDBase& e ) { return std::tie( e.m_lumi_block, e.m_event_number ); } ) );
174 }
175
176 static auto SortByRunLumi() {
177 return ::details::add_deref(
178 ::details::make_cmp( []( const EventIDBase& e ) { return std::tie( e.m_run_number, e.m_lumi_block ); } ) );
179 }
180
181private:
182 enum Type { Invalid = 0, RunEvent = 1 << 1, TimeStamp = 1 << 2, LumiEvent = 1 << 3, RunLumi = 1 << 4 };
183
184 unsigned m_type{ Invalid };
185
186 void setRE() { m_type |= RunEvent; }
187 void setTS() { m_type |= TimeStamp; }
188 void setLE() { m_type |= LumiEvent; }
189 void setRL() { m_type |= RunLumi; }
190
193
196
199
202
206
209
210 friend EventIDBase min( const EventIDBase& lhs, const EventIDBase& rhs ) {
211
212 //"min" is easy b/c the numbers denoting invalidty for TS or Run/Event/LB are the
213 // largest possible numbers, so naturally larger than any valid number
214
215 return EventIDBase( std::min( std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ),
216 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number ) ),
217 std::min( std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset ),
218 std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset ) ),
219 lhs.bunch_crossing_id() // bcid doesn't really matter here
220 );
221 }
222
223 friend EventIDBase max( const EventIDBase& lhs, const EventIDBase& rhs ) {
224
225 //"max" is much trickier because we need to handle invalid number explicilty by
226 // checking if a EventIDBase is TS or Run/Lumi
227
228 std::tuple<EventIDBase::number_type, EventIDBase::number_type, EventIDBase::event_number_t> run_lumi_ev;
229 std::tuple<EventIDBase::number_type, EventIDBase::number_type> time_stamp;
230
231 if ( lhs.isTimeStamp() && rhs.isTimeStamp() ) { // both time-stamp, compare them
232 time_stamp = std::max( std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset ),
233 std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset ) );
234 } else if ( lhs.isTimeStamp() ) { // only lhs time-stamp: Use it
235 time_stamp = std::tie( lhs.m_time_stamp, lhs.m_time_stamp_ns_offset );
236 } else { // otherwise use rhs time-stamp which might be UNDEFNUM (in case both input values are Run-Lumi only)
237 time_stamp = std::tie( rhs.m_time_stamp, rhs.m_time_stamp_ns_offset );
238 }
239
240 if ( lhs.isRunLumi() && rhs.isRunLumi() ) { // both run-lumi, compare them
241 run_lumi_ev = std::max( std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ),
242 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number ) );
243
244 } else if ( lhs.isRunLumi() ) { // only lhs run-lumi: Use it
245 run_lumi_ev = std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number );
246 } else { // otherwise use rhs run-lumi which might be UNDEFNUM (in case both input values are TS-only)
247 run_lumi_ev = std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number );
248 }
249
250 return EventIDBase( run_lumi_ev, time_stamp, lhs.bunch_crossing_id() );
251 }
252
253 friend bool operator<( const EventIDBase& lhs, const EventIDBase& rhs ) {
254 // first try ordering by timestamp if both are non-zero
255 // then try ordering by run/lumi/event
256 // this assumes that both EventIDBase have the same set of values defined.
257
258 if ( lhs.isTimeStamp() && rhs.isTimeStamp() ) {
259 return lhs.m_time_stamp < rhs.m_time_stamp;
260 } else {
261 return std::tie( lhs.m_run_number, lhs.m_lumi_block, lhs.m_event_number ) <
262 std::tie( rhs.m_run_number, rhs.m_lumi_block, rhs.m_event_number );
263 }
264 }
265
266 friend bool operator==( const EventIDBase& lhs, const EventIDBase& rhs ) {
267 // We assume that equality via run/event/lumi numbers is sufficient
268 return ( lhs.m_run_number == rhs.m_run_number && lhs.m_event_number == rhs.m_event_number &&
269 lhs.m_lumi_block == rhs.m_lumi_block );
270 }
271
272 friend std::ostream& operator<<( std::ostream& os, const EventIDBase& rhs ) {
273 if ( rhs.m_type == EventIDBase::Invalid ) return os << "[INVALID]";
274
275 const char* separator = "";
276 os << "[";
277 if ( rhs.m_run_number != EventIDBase::UNDEFNUM ) {
278 os << rhs.m_run_number;
279 separator = ",";
280 }
281
283 os << separator << rhs.m_event_number;
284 separator = ",";
285 }
286
287 if ( rhs.isTimeStamp() ) {
288 os << separator << "t:" << rhs.m_time_stamp;
289 if ( rhs.m_time_stamp_ns_offset != 0 ) {
290 os << "." << std::setfill( '0' ) << std::setw( 9 ) << rhs.m_time_stamp_ns_offset;
291 }
292 separator = ",";
293 }
294
295 if ( rhs.isLumiEvent() || rhs.isRunLumi() ) {
296 os << separator << "l:" << rhs.m_lumi_block;
297 separator = ",";
298 }
299
300 if ( rhs.m_bunch_crossing_id != 0 ) { os << separator << "b:" << rhs.m_bunch_crossing_id; }
301 os << "]";
302 return os;
303 }
304};
number_type lumi_block() const
luminosity block identifier, 32 bit unsigned
friend bool operator>(const EventIDBase &lhs, const EventIDBase &rhs)
unsigned m_type
friend bool operator==(const EventIDBase &lhs, const EventIDBase &rhs)
Comparison operators.
void set_run_number(number_type runNumber)
set run number
bool isTimeStamp() const
static const event_number_t UNDEFEVT
Definition EventIDBase.h:71
bool isRunLumi() const
number_type m_bunch_crossing_id
bunch crossing ID, 32 bit unsigned
friend EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
friend bool operator!=(const EventIDBase &lhs, const EventIDBase &rhs)
void set_time_stamp(number_type timeStamp)
set time stamp
number_type m_lumi_block
luminosity block number: the number which uniquely tags a luminosity block within a run
void set_time_stamp_ns_offset(number_type timeStampNs)
set time stamp in ns
number_type run_number() const
run number - 32 bit unsigned
Definition EventIDBase.h:91
number_type time_stamp_ns_offset() const
time stamp ns - ns time offset for time_stamp, 32 bit unsigned
friend class EventIDRange
Definition EventIDBase.h:73
void set_lumi_block(number_type lumiBlock)
set luminosity block identifier
static auto SortByRunLumi()
void set_event_number(event_number_t eventNumber)
set event number
event_number_t m_event_number
event number
friend EventIDBase min(const EventIDBase &lhs, const EventIDBase &rhs)
uint64_t event_number_t
Definition EventIDBase.h:68
bool isValid() const
static auto SortByRunEvent()
friend bool operator<=(const EventIDBase &lhs, const EventIDBase &rhs)
friend std::ostream & operator<<(std::ostream &os, const EventIDBase &rhs)
Extraction operators.
friend bool operator>=(const EventIDBase &lhs, const EventIDBase &rhs)
number_type m_run_number
run number
number_type m_time_stamp_ns_offset
time stamp ns - ns time offset for time_stamp, 32 bit unsigned
static auto SortByTimeStamp()
void set_bunch_crossing_id(number_type bcid)
set bunch crossing ID
number_type m_time_stamp
posix time in seconds since 1970/01/01
unsigned int number_type
Definition EventIDBase.h:67
number_type bunch_crossing_id() const
bunch crossing ID, 32 bit unsigned
static const number_type UNDEFNUM
Definition EventIDBase.h:70
event_number_t event_number() const
event number - 64 bit unsigned
Definition EventIDBase.h:94
bool isRunEvent() const
friend bool operator<(const EventIDBase &lhs, const EventIDBase &rhs)
virtual ~EventIDBase()=default
number_type time_stamp() const
time stamp - posix time in seconds from 1970, 32 bit unsigned
Definition EventIDBase.h:97
bool isLumiEvent() const
static auto SortByLumiEvent()
auto compose(lambda_ts &&... lambdas)
Definition compose.h:45
auto make_cmp(Proj p, Cmp cmp={})
Definition EventIDBase.h:50
auto add_deref(Fun f)
Definition EventIDBase.h:45
typename arg_helper< lambda >::type argument_t
Definition EventIDBase.h:42