9#include "arg_wrappers.hpp"
11#include "int_arith.hpp"
12#include "introspect.hpp"
13#include "numeric_traits.hpp"
14#include "processor.hpp"
15#include "time_tagged_events.hpp"
34template <
typename NumericTraits,
bool UseStartTimeAndChannel,
36class time_correlate_at_start_or_stop {
38 processor<Downstream, time_correlated_detection_event<NumericTraits>>);
40 Downstream downstream;
43 explicit time_correlate_at_start_or_stop(Downstream downstream)
44 : downstream(std::move(downstream)) {}
46 [[nodiscard]]
auto introspect_node() const -> processor_info {
47 return processor_info(
this,
"time_correlate_at_start_or_stop");
50 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
51 return downstream.introspect_graph().push_entry_point(
this);
54 template <
typename NT>
55 void handle(std::array<detection_event<NT>, 2>
const &event) {
56 static_assert(std::is_same_v<
typename NT::abstime_type,
57 typename NumericTraits::abstime_type>);
58 static_assert(std::is_same_v<
typename NT::channel_type,
59 typename NumericTraits::channel_type>);
60 auto const &anchor = UseStartTimeAndChannel ?
event[0] :
event[1];
62 convert_with_check<typename NumericTraits::difftime_type>(
63 subtract_with_check(event[1].abstime, event[0].abstime));
64 downstream.handle(time_correlated_detection_event<NumericTraits>{
65 anchor.abstime, anchor.channel, difftime});
68 template <
typename NT>
70 void handle(std::array<detection_event<NT>, 2> &&event) {
71 handle(
static_cast<std::array<detection_event<NT>, 2
> const &>(event));
74 template <
typename OtherEvent>
75 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
76 void handle(OtherEvent &&event) {
77 downstream.handle(std::forward<OtherEvent>(event));
80 void flush() { downstream.flush(); }
83template <
typename NumericTraits,
bool UseStartChannel,
typename Downstream>
84class time_correlate_at_midpoint {
86 processor<Downstream, time_correlated_detection_event<NumericTraits>>);
88 Downstream downstream;
91 explicit time_correlate_at_midpoint(Downstream downstream)
92 : downstream(std::move(downstream)) {}
94 [[nodiscard]]
auto introspect_node() const -> processor_info {
95 return processor_info(
this,
"time_correlate_at_midpoint");
98 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
99 return downstream.introspect_graph().push_entry_point(
this);
102 template <
typename NT>
103 void handle(std::array<detection_event<NT>, 2>
const &event) {
104 static_assert(std::is_same_v<
typename NT::abstime_type,
105 typename NumericTraits::abstime_type>);
106 static_assert(std::is_same_v<
typename NT::channel_type,
107 typename NumericTraits::channel_type>);
108 auto const difftime =
109 subtract_with_check(event[1].abstime, event[0].abstime);
110 auto const abstime =
event[0].abstime + difftime / 2;
112 UseStartChannel ?
event[0].channel :
event[1].channel;
113 downstream.handle(time_correlated_detection_event<NumericTraits>{
115 convert_with_check<typename NumericTraits::difftime_type>(
119 template <
typename NT>
121 void handle(std::array<detection_event<NT>, 2> &&event) {
122 handle(
static_cast<std::array<detection_event<NT>, 2
> const &>(event));
125 template <
typename OtherEvent>
126 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
127 void handle(OtherEvent &&event) {
128 downstream.handle(std::forward<OtherEvent>(event));
131 void flush() { downstream.flush(); }
134template <
typename NumericTraits,
bool UseStartChannel,
typename Downstream>
135class time_correlate_at_fraction {
137 processor<Downstream, time_correlated_detection_event<NumericTraits>>);
140 Downstream downstream;
143 explicit time_correlate_at_fraction(arg::fraction<double> fraction,
144 Downstream downstream)
145 : frac(fraction.value), downstream(std::move(downstream)) {
146 if (frac < 0.0 || frac > 1.0)
147 throw std::invalid_argument(
148 "time_correlate_at_fraction fraction must be in range [0.0, 1.0]");
151 [[nodiscard]]
auto introspect_node() const -> processor_info {
152 return processor_info(
this,
"time_correlate_at_fraction");
155 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
156 return downstream.introspect_graph().push_entry_point(
this);
159 template <
typename NT>
160 void handle(std::array<detection_event<NT>, 2>
const &event) {
161 static_assert(std::is_same_v<
typename NT::abstime_type,
162 typename NumericTraits::abstime_type>);
163 static_assert(std::is_same_v<
typename NT::channel_type,
164 typename NumericTraits::channel_type>);
165 auto const difftime =
166 subtract_with_check(event[1].abstime, event[0].abstime);
169 static_cast<NumericTraits::abstime_type
>(
170 std::llround(
static_cast<double>(difftime) * frac));
172 UseStartChannel ?
event[0].channel :
event[1].channel;
173 downstream.handle(time_correlated_detection_event<NumericTraits>{
175 convert_with_check<typename NumericTraits::difftime_type>(
179 template <
typename NT>
181 void handle(std::array<detection_event<NT>, 2> &&event) {
182 handle(
static_cast<std::array<detection_event<NT>, 2
> const &>(event));
185 template <
typename OtherEvent>
186 requires handler_for<Downstream, std::remove_cvref_t<OtherEvent>>
187 void handle(OtherEvent &&event) {
188 downstream.handle(std::forward<OtherEvent>(event));
191 void flush() { downstream.flush(); }
228template <
typename NumericTraits = default_numeric_traits,
typename Downstream>
230 return internal::time_correlate_at_start_or_stop<NumericTraits,
true,
232 std::move(downstream));
266template <
typename NumericTraits = default_numeric_traits,
typename Downstream>
268 return internal::time_correlate_at_start_or_stop<NumericTraits,
false,
270 std::move(downstream));
311template <
typename NumericTraits = default_numeric_traits,
312 bool UseStartChannel =
false,
typename Downstream>
314 return internal::time_correlate_at_midpoint<NumericTraits, UseStartChannel,
316 std::move(downstream));
360template <
typename NumericTraits = default_numeric_traits,
361 bool UseStartChannel =
false,
typename Downstream>
363 Downstream downstream) {
364 return internal::time_correlate_at_fraction<NumericTraits, UseStartChannel,
366 fraction, std::move(downstream));
371template <
typename NumericTraits,
typename Downstream>
372 requires processor<Downstream, detection_event<NumericTraits>>
374 Downstream downstream;
377 explicit remove_time_correlation(Downstream downstream)
378 : downstream(std::move(downstream)) {}
380 [[nodiscard]]
auto introspect_node() const -> processor_info {
381 return processor_info(
this,
"remove_time_correlation");
384 [[nodiscard]]
auto introspect_graph() const -> processor_graph {
385 return downstream.introspect_graph().push_entry_point(
this);
388 template <
typename NT>
389 void handle(time_correlated_detection_event<NT>
const &event) {
390 static_assert(std::is_same_v<
typename NT::abstime_type,
391 typename NumericTraits::abstime_type>);
392 static_assert(std::is_same_v<
typename NT::channel_type,
393 typename NumericTraits::channel_type>);
396 detection_event<NumericTraits>{
event.abstime,
event.channel});
399 template <
typename NT>
401 void handle(time_correlated_detection_event<NT> &&event) {
403 static_cast<time_correlated_detection_event<NT>
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(); }
437template <
typename NumericTraits = default_numeric_traits,
typename Downstream>
439 return internal::remove_time_correlation<NumericTraits, Downstream>(
440 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:362
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:229
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:313
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:267
auto remove_time_correlation(Downstream downstream)
Create a processor that removes the difftime from detection events.
Definition time_correlate.hpp:438
libtcspc namespace.
Definition acquire.hpp:30
Function argument wrapper for fraction parameter.
Definition arg_wrappers.hpp:137