11#include "data_types.hpp"
12#include "int_arith.hpp"
13#include "int_types.hpp"
14#include "introspect.hpp"
16#include "npint_ops.hpp"
17#include "processor.hpp"
18#include "read_integers.hpp"
19#include "time_tagged_events.hpp"
69 [[nodiscard]]
constexpr auto channel() const noexcept ->
u8np {
98 [[nodiscard]]
constexpr auto is_special() const noexcept ->
bool {
153 throw std::invalid_argument(
154 "pqt2_picoharp300_event channel must be in the range 0-14");
165 return make_from_fields(15_u8np, 0_u32np);
180 if (marker_bits == 0_u8np)
181 throw std::invalid_argument(
182 "pqt2_picoharp300_event marker_bits must not be zero");
183 return make_from_fields(15_u8np,
185 (
u32np(marker_bits) & 0x0f_u32np));
197 return stream <<
"pqt2_picoharp(channel="
198 << unsigned(event.channel().value())
199 <<
", timetag=" <<
event.timetag() <<
")";
229template <i32 OverflowPeriod,
bool IsOverflowAlwaysSingle>
269 [[nodiscard]]
constexpr auto is_special() const noexcept ->
bool {
286 if (IsOverflowAlwaysSingle)
341 not IsOverflowAlwaysSingle,
342 "multiple time tag overflow is not available in HydraHarp V1 format");
343 return make_from_fields(
true, 63_u8np,
count);
353 return make_from_fields(
true, 63_u8np, 1_u32np);
365 return make_from_fields(
true, 0_u8np,
timetag);
379 if (marker_bits == 0_u8np || (marker_bits & ~0x0f_u8np) != 0_u8np)
380 throw std::invalid_argument(
381 "basic_pqt2_event marker_bits must be in range 1-15");
382 return make_from_fields(
true, marker_bits & 0x3f_u8np,
timetag);
393 static constexpr auto version = IsOverflowAlwaysSingle ? 1 : 2;
394 return stream <<
"pqt2_hydraharpv" << version
395 <<
"(special=" <<
event.is_special()
396 <<
", channel=" << unsigned(event.channel().value())
397 <<
", timetag=" <<
event.timetag() <<
")";
401 static constexpr auto make_from_fields(
bool special,
u8np channel,
407 std::byte(((
u8np(
u8(special)) << 7) |
438template <
typename DataTypes,
typename PQT2Event,
typename Downstream>
445 static_assert(
sizeof(
typename DataTypes::abstime_type) >= 4);
446 static_assert(std::in_range<typename DataTypes::channel_type>(63));
448 using abstime_type =
typename DataTypes::abstime_type;
450 abstime_type timetag_base = 0;
452 Downstream downstream;
454 LIBTCSPC_NOINLINE
void issue_warning(
char const *message) {
459 explicit decode_pqt2(Downstream downstream)
460 : downstream(std::move(downstream)) {}
467 return downstream.introspect_graph().push_entry_point(
this);
470 template <
typename Event>
471 requires std::convertible_to<std::remove_cvref_t<Event>, PQT2Event>
472 void handle(Event &&event) {
473 if (event.is_timetag_overflow()) {
474 timetag_base += abstime_type(PQT2Event::overflow_period) *
475 event.timetag_overflow_count().value();
476 return downstream.handle(
485 if (not event.is_special() || event.is_sync_event()) {
486 abstime_type
const timetag =
487 timetag_base +
event.timetag().value();
489 timetag,
event.is_special() ? -1 :
event.channel().value()});
490 }
else if (event.is_external_marker()) {
491 abstime_type
const timetag =
492 timetag_base +
event.external_marker_timetag().value();
493 for_each_set_bit(
u32np(event.external_marker_bits()), [&](
int b) {
494 downstream.handle(marker_event<DataTypes>{timetag, b});
497 issue_warning(
"invalid special event encountered");
501 template <
typename Event>
503 not std::convertible_to<std::remove_cvref_t<Event>, PQT2Event> and
505 void handle(Event &&event) {
506 downstream.handle(std::forward<Event>(event));
509 void flush() { downstream.flush(); }
536template <
typename DataTypes = default_data_types,
typename Downstream>
539 Downstream>(std::move(downstream));
567template <
typename DataTypes = default_data_types,
typename Downstream>
570 Downstream>(std::move(downstream));
599template <
typename DataTypes = default_data_types,
typename Downstream>
601 return internal::decode_pqt2<DataTypes, pqt2_generic_event, Downstream>(
602 std::move(downstream));
Value type representing a directed acyclic graph of processors.
Definition introspect.hpp:198
Value type representing metadata of a processor.
Definition introspect.hpp:58
Concept that is satisfied when a processor handles the given event types.
Definition processor.hpp:118
Concept that is satisfied when a processor handles the given event types and flush.
Definition processor.hpp:143
basic_pqt2_event< 33554432, false > pqt2_generic_event
Binary record interpretation for HydraHarp V2, MultiHarp, TimeHarp 260, and PicoHarp 330 "Generic" T2...
Definition picoquant_t2.hpp:432
basic_pqt2_event< 33552000, true > pqt2_hydraharpv1_event
Binary record interpretation for HydraHarp V1 T2 format.
Definition picoquant_t2.hpp:422
npint< u32 > u32np
Non-promoted unsigned 32-bit integer.
Definition npint.hpp:306
constexpr auto read_u8_at(std::span< T, N > bytes) noexcept -> u8np
Read an 8-bit unsigned integer from bytes at offset.
Definition read_integers.hpp:77
constexpr auto read_u32le_at(std::span< T, N > bytes) noexcept -> u32np
Read a little-endian 32-bit unsigned integer from bytes at offset.
Definition read_integers.hpp:102
npint< u8 > u8np
Non-promoted unsigned 8-bit integer.
Definition npint.hpp:292
auto decode_pqt2_hydraharpv1(Downstream downstream)
Create a processor that decodes PicoQuant HydraHarp V1 T2 events.
Definition picoquant_t2.hpp:568
auto decode_pqt2_generic(Downstream downstream)
Create a processor that decodes PicoQuant HydraHarp V2, MultiHarp, TimeHarp 260, and PicoHarp 330 "Ge...
Definition picoquant_t2.hpp:600
auto decode_pqt2_picoharp300(Downstream downstream)
Create a processor that decodes PicoQuant PicoHarp 300 T2 events.
Definition picoquant_t2.hpp:537
auto count(access_tracker< count_access > &&tracker, Downstream downstream)
Create a processor that counts events of a given type.
Definition count.hpp:313
std::int32_t i32
Short name for int32_t.
Definition int_types.hpp:42
std::uint8_t u8
Short name for uint8_t.
Definition int_types.hpp:24
libtcspc namespace.
Definition acquire.hpp:29
Implementation for binary record interpretation for HydraHarp, MultiHarp, TimeHarp 260,...
Definition picoquant_t2.hpp:230
static constexpr auto make_nonspecial(u32np timetag, u8np channel) -> basic_pqt2_event
Make an event representing a non-special (photon) event.
Definition picoquant_t2.hpp:323
constexpr auto is_timetag_overflow() const noexcept -> bool
Determine if this event represents a time tag overflow.
Definition picoquant_t2.hpp:276
static constexpr auto make_external_marker(u32np timetag, u8np marker_bits) -> basic_pqt2_event
Make an event representing an external marker.
Definition picoquant_t2.hpp:377
friend auto operator<<(std::ostream &stream, basic_pqt2_event const &event) -> std::ostream &
Stream insertion operator.
Definition picoquant_t2.hpp:391
std::array< std::byte, 4 > bytes
Definition picoquant_t2.hpp:234
friend auto operator==(basic_pqt2_event const &lhs, basic_pqt2_event const &rhs) noexcept -> bool=default
Equality comparison operator.
constexpr auto timetag_overflow_count() const noexcept -> u32np
Read the time tag overflow count if this event represents a time tag overflow.
Definition picoquant_t2.hpp:284
constexpr auto timetag() const noexcept -> u32np
Read the time tag if this event is a non-special event.
Definition picoquant_t2.hpp:254
constexpr auto is_external_marker() const noexcept -> bool
Determine if this event represents external markers.
Definition picoquant_t2.hpp:301
constexpr auto external_marker_timetag() const noexcept -> u32np
Read the time tag if this event is an external marker event.
Definition picoquant_t2.hpp:261
static constexpr i32 overflow_period
Definition picoquant_t2.hpp:242
static constexpr auto make_sync(u32np timetag) noexcept -> basic_pqt2_event
Make an event representing a sync event.
Definition picoquant_t2.hpp:363
constexpr auto is_special() const noexcept -> bool
Determine if this event is a special event.
Definition picoquant_t2.hpp:269
constexpr auto external_marker_bits() const noexcept -> u8np
Read the marker bits (mask) if this event represents external markers.
Definition picoquant_t2.hpp:309
constexpr auto is_sync_event() const noexcept -> bool
Determine if this event represents a sync event.
Definition picoquant_t2.hpp:294
constexpr auto channel() const noexcept -> u8np
Read the channel if this event is a non-special event.
Definition picoquant_t2.hpp:247
static constexpr auto make_timetag_overflow(u32np count) -> basic_pqt2_event
Make an event representing a time tag overflow.
Definition picoquant_t2.hpp:338
static constexpr auto make_timetag_overflow() noexcept -> basic_pqt2_event
Make an event representing a single time tag overflow.
Definition picoquant_t2.hpp:351
Event indicating a detected count.
Definition time_tagged_events.hpp:236
Event indicating a timing marker.
Definition time_tagged_events.hpp:320
Binary record interpretation for PicoHarp 300 T2 Format.
Definition picoquant_t2.hpp:52
constexpr auto is_special() const noexcept -> bool
Determine if this event is a special event.
Definition picoquant_t2.hpp:98
static constexpr i32 overflow_period
The time tag overflow period of this event type.
Definition picoquant_t2.hpp:64
static constexpr auto is_sync_event() noexcept -> bool
Determine if this event represents a sync event.
Definition picoquant_t2.hpp:121
static constexpr auto timetag_overflow_count() noexcept -> u32np
Read the time tag overflow count if this event represents a time tag overflow.
Definition picoquant_t2.hpp:113
constexpr auto external_marker_bits() const noexcept -> u8np
Read the marker bits (mask) if this event represents external markers.
Definition picoquant_t2.hpp:136
static constexpr auto make_timetag_overflow() noexcept -> pqt2_picoharp300_event
Make an event representing a time tag overflow.
Definition picoquant_t2.hpp:163
static constexpr auto make_external_marker(u32np timetag, u8np marker_bits) -> pqt2_picoharp300_event
Make an event representing an external marker.
Definition picoquant_t2.hpp:178
constexpr auto external_marker_timetag() const noexcept -> u32np
Read the time tag if this event is an external marker event.
Definition picoquant_t2.hpp:86
friend auto operator<<(std::ostream &stream, pqt2_picoharp300_event const &event) -> std::ostream &
Stream insertion operator.
Definition picoquant_t2.hpp:194
constexpr auto is_timetag_overflow() const noexcept -> bool
Determine if this event represents a time tag overflow.
Definition picoquant_t2.hpp:105
constexpr auto channel() const noexcept -> u8np
Read the channel if this event is a non-special event.
Definition picoquant_t2.hpp:69
constexpr auto timetag() const noexcept -> u32np
Read the time tag if this event is a non-special event (not external marker event).
Definition picoquant_t2.hpp:77
constexpr auto is_external_marker() const noexcept -> bool
Determine if this event represents external markers.
Definition picoquant_t2.hpp:128
friend auto operator==(pqt2_picoharp300_event const &lhs, pqt2_picoharp300_event const &rhs) noexcept -> bool=default
Equality comparison operator.
std::array< std::byte, 4 > bytes
Bytes of the 32-bit raw device event.
Definition picoquant_t2.hpp:56
static constexpr auto make_nonspecial(u32np timetag, u8np channel) -> pqt2_picoharp300_event
Make an event representing a non-special (photon) event.
Definition picoquant_t2.hpp:150
Event indicating latest abstime reached.
Definition time_tagged_events.hpp:41
An event type indicating a warning.
Definition core.hpp:31