13 size_t waveform_index,
16 return waveform_start + waveform_index * optical_period(clockData,is_daphne);
31 typedef std::vector<std::array<raw::TimeStamp_t,2>> TimeStamps;
33 TimeStamps::iterator insert = std::lower_bound(triggers.begin(), triggers.end(), range,
34 [](
const auto &lhs,
const auto &rhs) {
return lhs[0] < rhs[0]; });
35 triggers.insert(insert, range);
39 typedef std::vector<TriggerPrimitive> TimeStamps;
41 TimeStamps::iterator insert = std::lower_bound(triggers.begin(), triggers.end(), trigger,
42 [](
auto const &lhs,
auto const &rhs) {
return lhs.
start < rhs.start; });
44 triggers.insert(insert, trigger);
48 typedef std::vector<TriggerPrimitive> TimeStamps;
50 TimeStamps::iterator insert = std::upper_bound(triggers.begin(), triggers.end(), trigger,
51 [](
auto const &lhs,
auto const &rhs) {
return lhs.
finish < rhs.finish; });
53 triggers.insert(insert, trigger);
66 std::vector<std::array<raw::TimeStamp_t, 2>> this_trigger_ranges;
67 const std::vector<raw::ADC_Count_t> &adcs = waveform;
78 bool is_arapuca =
false;
79 if( opdet_type.find(
"arapuca") != std::string::npos ) is_arapuca =
true;
80 bool is_daphne =
false;
82 if (sampling_type ==
"daphne") is_daphne =
true;
90 if (start > trigger_window[1])
return;
91 size_t start_i = start > trigger_window[0] ? 0 : (size_t)((trigger_window[0] - start) / optical_period(clockData,is_daphne));
96 tick_to_timestamp(clockData, waveform.
TimeStamp(), start_i,is_daphne))) {
101 tick_to_timestamp(clockData, waveform.
TimeStamp(), start_i,is_daphne)));
104 if (start_i >= adcs.size())
return;
108 size_t end_i = end < trigger_window[1] ? adcs.size()-1 : (size_t)((trigger_window[1] - start) / optical_period(clockData,is_daphne));
113 tick_to_timestamp(clockData, waveform.
TimeStamp(), end_i+1,is_daphne)) && end_i+1 < adcs.size()) {
118 tick_to_timestamp(clockData, waveform.
TimeStamp(), end_i+1,is_daphne)));
120 std::vector<std::array<raw::TimeStamp_t, 2>> this_trigger_locations;
121 bool above_threshold =
false;
122 bool beam_trigger_added =
false;
123 double t_since_last_trigger = 99999.;
127 for (
size_t i = start_i; i <= end_i; i++) {
129 t_since_last_trigger += optical_period(clockData,is_daphne);
130 bool isLive = (t_since_last_trigger > t_deadtime);
133 if (isLive && !above_threshold && val > threshold) {
135 trigger_start = time;
136 above_threshold =
true;
137 t_since_last_trigger = 0;
140 else if (above_threshold && (val < threshold || i+1 == end_i)) {
143 above_threshold =
false;
150 beam_trigger_added =
true;
151 t_since_last_trigger = 0;
165 for (
const std::array<raw::TimeStamp_t, 2> &trigger_range: this_trigger_ranges) {
175 if (in_masked_list)
return true;
193 void opDetSBNDTriggerAlg::ClearTriggerLocations() {
205 for (
const std::array<raw::TimeStamp_t, 2> &range: trigger_ranges.second) {
221 std::vector<TriggerPrimitive> all_trigger_locations;
227 for (std::array<raw::TimeStamp_t,2> trigger_range: trigger_locations_pair.second) {
229 trigger.
start = trigger_range[0];
230 trigger.
finish = trigger_range[1];
231 trigger.
channel = this_channel;
248 bool was_triggering =
false;
250 std::vector<TriggerPrimitive> primitives;
253 while (primitives.back().finish < primitive.start) {
255 primitives.resize(primitives.size() - 1);
259 if (is_triggering && !was_triggering) {
263 was_triggering = is_triggering;
277 end = tpcStart + tpcReadoutWindow;
284 return {{start, end}};
293 return trigger_time >= trigger_range[0] &&
294 trigger_time <= trigger_range[1];
336 std::vector<raw::OpDetWaveform> ret;
340 const std::vector<raw::TimeStamp_t> &trigger_times =
GetTriggerTimes(channel);
341 if( trigger_times.size() == 0 )
return ret;
342 bool is_daphne =
false;
344 if (sampling_type ==
"daphne") is_daphne =
true;
353 const std::vector<raw::ADC_Count_t> &adcs = waveform;
359 unsigned ro_samples = (preTrig+postTrig)/optical_period(clockData,is_daphne);
365 unsigned ro_samples_beam= (preTrigBeam+postTrigBeam)/optical_period(clockData,is_daphne);
369 unsigned trigger_i = 0;
370 double next_trig = trigger_times[trigger_i];
371 bool isReadingOut =
false;
372 bool isBeamTrigger =
false;
373 unsigned min_ro_samples = ro_samples;
375 for(
size_t i=0; i<adcs.size(); i++){
376 double time = tick_to_timestamp(clockData, waveform.
TimeStamp(), i,is_daphne);
379 if( trigger_i >= trigger_times.size() )
break;
380 if( i >= adcs.size()-1-min_ro_samples )
break;
383 isBeamTrigger = ( fabs(next_trig-beamTrigTime)<optical_period(clockData,is_daphne)/2 );
386 double dT = time-next_trig;
387 if( trigger_i < trigger_times.size()-1 &&
388 ((isBeamTrigger && dT >= postTrigBeam)||(!isBeamTrigger && dT >= postTrig))) {
389 for(
size_t j=trigger_i+1; j<trigger_times.size(); j++){
390 double this_trig = trigger_times[j];
391 isBeamTrigger = ( fabs(this_trig-beamTrigTime)<optical_period(clockData,is_daphne)/2 );
392 double t1 = this_trig-preTrig;
393 double t2 = this_trig+postTrig;
395 t1 = this_trig-preTrigBeam;
396 t2 = this_trig+postTrigBeam;
400 next_trig = this_trig;
408 bool isTriggering =
false;
409 if( (!isBeamTrigger && time >= (next_trig-preTrig) && time < (next_trig+postTrig))
410 || ( isBeamTrigger && time >= (next_trig-preTrigBeam) && time < (next_trig+postTrigBeam))
415 if( isReadingOut && this_waveform.size() < min_ro_samples ){
416 this_waveform.push_back(adcs[i]);
421 else if( isReadingOut && this_waveform.size() >= min_ro_samples ){
423 this_waveform.push_back(adcs[i]);
425 ret.push_back(std::move(this_waveform));
426 isReadingOut =
false;
431 if( !isReadingOut && isTriggering ) {
433 this_waveform.push_back(adcs[i]);
435 min_ro_samples = ro_samples;
436 if( isBeamTrigger ) min_ro_samples = ro_samples_beam;
fhicl::Atom< int > PulsePolarityArapuca
bool IsTriggerEnabled(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, raw::TimeStamp_t trigger_time) const
double ReadoutWindowPostTriggerBeam(raw::Channel_t channel) const
double ReadoutWindowPreTrigger(raw::Channel_t channel) const
fhicl::Atom< bool > MaskArapucaT2s
ElecClock const & TPCClock() const noexcept
Borrow a const TPC clock with time set to Trigger time [us].
fhicl::Atom< int > TriggerThresholdADCPMT
fhicl::Atom< double > ReadoutWindowPostTriggerBeam
const std::vector< raw::TimeStamp_t > & GetTriggerTimes(raw::Channel_t channel) const
fhicl::Atom< double > TriggerEnableWindowStart
std::array< double, 2 > TriggerEnableWindow(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp) const
fhicl::Atom< bool > TriggerEnableWindowOneDriftBeforeTPCReadout
std::map< raw::Channel_t, std::vector< std::array< raw::TimeStamp_t, 2 > > > fTriggerRangesPerChannel
fhicl::Atom< bool > MaskPMTs
double TriggerOffsetTPC() const
void FindTriggerLocations(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const raw::OpDetWaveform &waveform, raw::ADC_Count_t baseline)
std::size_t size(FixedBins< T, C > const &) noexcept
unsigned int ReadOutWindowSize() const
double TimeStamp_t
us since 1970, based on TimeService
opDetSBNDTriggerAlg(const Config &config)
fhicl::Atom< unsigned > TriggerChannelCount
fhicl::Atom< double > ReadoutWindowPreTrigger
fhicl::Atom< double > ReadoutWindowPreTriggerBeam
fhicl::Atom< bool > MaskXArapucaPrimes
bool IsChannelMasked(raw::Channel_t channel) const
constexpr double TickPeriod() const noexcept
A single tick period in microseconds.
void MergeTriggerLocations()
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
timescale_traits< TriggerTimeCategory >::time_point_t trigger_time
A point in time on the trigger time scale.
void AddTriggerPrimitiveFinish(std::vector< TriggerPrimitive > &triggers, TriggerPrimitive trigger)
double ReadoutWindowPreTriggerBeam(raw::Channel_t channel) const
void AddTriggerPrimitive(std::vector< TriggerPrimitive > &triggers, TriggerPrimitive trigger)
fhicl::Atom< int > TriggerThresholdADCArapuca
opdet::sbndPDMapAlg fOpDetMap
auto end(FixedBins< T, C > const &) noexcept
void AddTriggerLocation(std::vector< std::array< raw::TimeStamp_t, 2 >> &triggers, std::array< raw::TimeStamp_t, 2 > range)
fhicl::Atom< bool > BeamTriggerEnable
fhicl::OptionalSequence< unsigned > MaskedChannels
fhicl::Atom< bool > AllowTriggerOverlap
fhicl::Atom< bool > MaskBarePMTs
fhicl::Atom< bool > MaskLightBars
ElecClock const & OpticalClock() const noexcept
Borrow a const Optical clock with time set to Trigger time [us].
std::vector< raw::OpDetWaveform > ApplyTriggerLocations(detinfo::DetectorClocksData const &clockData, const raw::OpDetWaveform &waveform) const
fhicl::Atom< double > ReadoutWindowPostTrigger
fhicl::Atom< double > TriggerHoldoff
fhicl::Atom< bool > MaskArapucaT1s
fhicl::Atom< double > BeamTriggerHoldoff
std::vector< unsigned > fMaskedChannels
Contains all timing reference information for the detector.
std::vector< raw::TimeStamp_t > fTriggerLocations
std::string electronicsType(size_t ch) const
fhicl::Atom< double > TriggerEnableWindowLength
double ReadoutWindowPostTrigger(raw::Channel_t channel) const
fhicl::Atom< bool > MaskXArapucas
fhicl::Atom< bool > SelfTriggerPerChannel
fhicl::Atom< double > BeamTriggerTime
std::string pdType(size_t ch) const override
fhicl::Atom< int > PulsePolarityPMT
std::map< raw::Channel_t, std::vector< raw::TimeStamp_t > > fTriggerLocationsPerChannel
fhicl::Atom< double > DriftPeriod