9#include "arg_wrappers.hpp"
11#include "data_types.hpp"
12#include "int_arith.hpp"
13#include "introspect.hpp"
14#include "processor.hpp"
15#include "time_tagged_events.hpp"
34template <
typename DataTypes,
bool UseStartTimeAndChannel,
typename Downstream>
35class time_correlate_at_start_or_stop {
37 processor<Downstream, time_correlated_detection_event<DataTypes>>);
39 Downstream downstream;
42 explicit time_correlate_at_start_or_stop(Downstream downstream)
43 : downstream(std::move(downstream)) {}
45 [[nodiscard]]
auto introspect_node() const -> processor_info {
46 return processor_info(
this,
"time_correlate_at_start_or_stop");
49 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
50 return downstream.introspect_graph().push_entry_point(
this);
53 template <
typename DT>
54 void handle(std::array<detection_event<DT>, 2>
const &event) {
55 static_assert(std::is_same_v<
typename DT::abstime_type,
56 typename DataTypes::abstime_type>);
57 static_assert(std::is_same_v<
typename DT::channel_type,
58 typename DataTypes::channel_type>);
59 auto const &anchor = UseStartTimeAndChannel ?
event[0] :
event[1];
61 convert_with_check<typename DataTypes::difftime_type>(
62 subtract_with_check(event[1].abstime, event[0].abstime));
63 downstream.handle(time_correlated_detection_event<DataTypes>{
64 anchor.abstime, anchor.channel, difftime});
67 template <
typename DT>
69 void handle(std::array<detection_event<DT>, 2> &&event) {
70 handle(
static_cast<std::array<detection_event<DT>, 2
> const &>(event));
73 template <
typename OtherEvent>
74 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
75 void handle(OtherEvent &&event) {
76 downstream.handle(std::forward<OtherEvent>(event));
79 void flush() { downstream.flush(); }
82template <
typename DataTypes,
bool UseStartChannel,
typename Downstream>
83class time_correlate_at_midpoint {
85 processor<Downstream, time_correlated_detection_event<DataTypes>>);
87 Downstream downstream;
90 explicit time_correlate_at_midpoint(Downstream downstream)
91 : downstream(std::move(downstream)) {}
93 [[nodiscard]]
auto introspect_node() const -> processor_info {
94 return processor_info(
this,
"time_correlate_at_midpoint");
97 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
98 return downstream.introspect_graph().push_entry_point(
this);
101 template <
typename DT>
102 void handle(std::array<detection_event<DT>, 2>
const &event) {
103 static_assert(std::is_same_v<
typename DT::abstime_type,
104 typename DataTypes::abstime_type>);
105 static_assert(std::is_same_v<
typename DT::channel_type,
106 typename DataTypes::channel_type>);
107 auto const difftime =
108 subtract_with_check(event[1].abstime, event[0].abstime);
109 auto const abstime =
event[0].abstime + difftime / 2;
111 UseStartChannel ?
event[0].channel :
event[1].channel;
112 downstream.handle(time_correlated_detection_event<DataTypes>{
114 convert_with_check<typename DataTypes::difftime_type>(difftime)});
117 template <
typename DT>
119 void handle(std::array<detection_event<DT>, 2> &&event) {
120 handle(
static_cast<std::array<detection_event<DT>, 2
> const &>(event));
123 template <
typename OtherEvent>
124 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
125 void handle(OtherEvent &&event) {
126 downstream.handle(std::forward<OtherEvent>(event));
129 void flush() { downstream.flush(); }
132template <
typename DataTypes,
bool UseStartChannel,
typename Downstream>
133class time_correlate_at_fraction {
135 processor<Downstream, time_correlated_detection_event<DataTypes>>);
138 Downstream downstream;
141 explicit time_correlate_at_fraction(arg::fraction<double> fraction,
142 Downstream downstream)
143 : frac(fraction.value), downstream(std::move(downstream)) {
144 if (frac < 0.0 || frac > 1.0)
145 throw std::invalid_argument(
146 "time_correlate_at_fraction fraction must be in range [0.0, 1.0]");
149 [[nodiscard]]
auto introspect_node() const -> processor_info {
150 return processor_info(
this,
"time_correlate_at_fraction");
153 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
154 return downstream.introspect_graph().push_entry_point(
this);
157 template <
typename DT>
158 void handle(std::array<detection_event<DT>, 2>
const &event) {
159 static_assert(std::is_same_v<
typename DT::abstime_type,
160 typename DataTypes::abstime_type>);
161 static_assert(std::is_same_v<
typename DT::channel_type,
162 typename DataTypes::channel_type>);
163 auto const difftime =
164 subtract_with_check(event[1].abstime, event[0].abstime);
167 static_cast<typename DataTypes::abstime_type
>(
168 std::llround(
static_cast<double>(difftime) * frac));
170 UseStartChannel ?
event[0].channel :
event[1].channel;
171 downstream.handle(time_correlated_detection_event<DataTypes>{
173 convert_with_check<typename DataTypes::difftime_type>(difftime)});
176 template <
typename DT>
178 void handle(std::array<detection_event<DT>, 2> &&event) {
179 handle(
static_cast<std::array<detection_event<DT>, 2
> const &>(event));
182 template <
typename OtherEvent>
183 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
184 void handle(OtherEvent &&event) {
185 downstream.handle(std::forward<OtherEvent>(event));
188 void flush() { downstream.flush(); }
225template <
typename DataTypes = default_data_types,
typename Downstream>
227 return internal::time_correlate_at_start_or_stop<DataTypes,
true,
229 std::move(downstream));
263template <
typename DataTypes = default_data_types,
typename Downstream>
265 return internal::time_correlate_at_start_or_stop<DataTypes,
false,
267 std::move(downstream));
308template <
typename DataTypes = default_data_types,
309 bool UseStartChannel =
false,
typename Downstream>
311 return internal::time_correlate_at_midpoint<DataTypes, UseStartChannel,
313 std::move(downstream));
357template <
typename DataTypes = default_data_types,
358 bool UseStartChannel =
false,
typename Downstream>
360 Downstream downstream) {
361 return internal::time_correlate_at_fraction<DataTypes, UseStartChannel,
363 fraction, std::move(downstream));
368template <
typename DataTypes,
typename Downstream>
class negate_difftime {
370 processor<Downstream, time_correlated_detection_event<DataTypes>>);
372 Downstream downstream;
375 explicit negate_difftime(Downstream downstream)
376 : downstream(std::move(downstream)) {}
378 [[nodiscard]]
auto introspect_node() const -> processor_info {
379 return processor_info(
this,
"negate_difftime");
382 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
383 return downstream.introspect_graph().push_entry_point(
this);
386 template <
typename DT>
387 void handle(time_correlated_detection_event<DT>
const &event) {
388 static_assert(std::is_same_v<
typename DT::difftime_type,
389 typename DataTypes::difftime_type>);
391 std::is_signed_v<typename DT::difftime_type>,
392 "difftime_type of time_correlated_detection_event used with negate_difftime must be a signed integer type");
393 time_correlated_detection_event<DT> copy(event);
395 static_cast<typename DT::difftime_type
>(-
event.difftime);
396 downstream.handle(std::move(copy));
399 template <
typename DT>
401 void handle(time_correlated_detection_event<DT> &&event) {
403 static_cast<time_correlated_detection_event<DT>
const &
>(event));
406 template <
typename OtherEvent>
407 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
408 void handle(OtherEvent &&event) {
409 downstream.handle(std::forward<OtherEvent>(event));
412 void flush() { downstream.flush(); }
415template <
typename DataTypes,
typename Downstream>
416class remove_time_correlation {
417 static_assert(processor<Downstream, detection_event<DataTypes>>);
419 Downstream downstream;
422 explicit remove_time_correlation(Downstream downstream)
423 : downstream(std::move(downstream)) {}
425 [[nodiscard]]
auto introspect_node() const -> processor_info {
426 return processor_info(
this,
"remove_time_correlation");
429 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
430 return downstream.introspect_graph().push_entry_point(
this);
433 template <
typename DT>
434 void handle(time_correlated_detection_event<DT>
const &event) {
435 static_assert(std::is_same_v<
typename DT::abstime_type,
436 typename DataTypes::abstime_type>);
437 static_assert(std::is_same_v<
typename DT::channel_type,
438 typename DataTypes::channel_type>);
441 detection_event<DataTypes>{
event.abstime,
event.channel});
444 template <
typename DT>
446 void handle(time_correlated_detection_event<DT> &&event) {
448 static_cast<time_correlated_detection_event<DT>
const &
>(event));
451 template <
typename OtherEvent>
452 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
453 void handle(OtherEvent &&event) {
454 downstream.handle(std::forward<OtherEvent>(event));
457 void flush() { downstream.flush(); }
483template <
typename DataTypes = default_data_types,
typename Downstream>
485 return internal::negate_difftime<DataTypes, Downstream>(
486 std::move(downstream));
508template <
typename DataTypes = default_data_types,
typename Downstream>
510 return internal::remove_time_correlation<DataTypes, Downstream>(
511 std::move(downstream));
auto time_correlate_at_fraction(arg::fraction< double > fraction, Downstream downstream)
Create a processor that collapses detection pairs into time-correlated detection events at a fraction...
Definition time_correlate.hpp:359
auto time_correlate_at_start(Downstream downstream)
Create a processor that collapses detection pairs into time-correlated detection events at the start ...
Definition time_correlate.hpp:226
auto negate_difftime(Downstream downstream)
Create a processor that changes the sign of difftime in time-correlated detection events.
Definition time_correlate.hpp:484
auto time_correlate_at_midpoint(Downstream downstream)
Create a processor that collapses detection pairs into time-correlated detection events at the midpoi...
Definition time_correlate.hpp:310
auto time_correlate_at_stop(Downstream downstream)
Create a processor that collapses detection pairs into time-correlated detection events at the stop t...
Definition time_correlate.hpp:264
auto remove_time_correlation(Downstream downstream)
Create a processor that removes the difftime from detection events.
Definition time_correlate.hpp:509
libtcspc namespace.
Definition acquire.hpp:29
Function argument wrapper for fraction parameter.
Definition arg_wrappers.hpp:137