diff --git a/CMakeLists.txt b/CMakeLists.txt index c222a8a..135a670 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,16 +38,23 @@ add_library(triggeralgs SHARED src/TCMakerADCSimpleWindowAlgorithm.cpp src/TAMakerHorizontalMuonAlgorithm.cpp src/TCMakerHorizontalMuonAlgorithm.cpp - src/TriggerCandidateMakerPlaneCoincidence.cpp - src/TriggerActivityMakerPlaneCoincidence.cpp - src/TriggerActivityMakerMichelElectron.cpp - src/TriggerCandidateMakerMichelElectron.cpp + src/TCMakerPlaneCoincidenceAlgorithm.cpp + src/TAMakerPlaneCoincidenceAlgorithm.cpp + src/TAMakerMichelElectronAlgorithm.cpp + src/TCMakerMichelElectronAlgorithm.cpp src/TAMakerPrescaleAlgorithm.cpp src/TCMakerPrescaleAlgorithm.cpp - src/TriggerActivityMakerSupernova.cpp - src/TriggerCandidateMakerSupernova.cpp - src/TriggerDecisionMakerSupernova.cpp - src/TriggerActivityMakerDBSCAN.cpp + src/TAMakerSupernovaAlgorithm.cpp + src/TCMakerSupernovaAlgorithm.cpp + src/TDMakerSupernovaAlgorithm.cpp + src/TAMakerDBSCANAlgorithm.cpp + src/TCMakerDBSCANAlgorithm.cpp + src/TAMakerChannelDistanceAlgorithm.cpp + src/TCMakerChannelDistanceAlgorithm.cpp + src/TAMakerBundleNAlgorithm.cpp + src/TCMakerBundleNAlgorithm.cpp + src/TAMakerChannelAdjacencyAlgorithm.cpp + src/TCMakerChannelAdjacencyAlgorithm.cpp src/TAWindow.cpp src/TPWindow.cpp src/dbscan/dbscan.cpp diff --git a/include/triggeralgs/ADCSimpleWindow/README.md b/include/triggeralgs/ADCSimpleWindow/README.md index af93307..99ba57e 100644 --- a/include/triggeralgs/ADCSimpleWindow/README.md +++ b/include/triggeralgs/ADCSimpleWindow/README.md @@ -3,11 +3,11 @@ - A “next-to-most-simple” triggering algorithm to exercise the TP chain. - Look at the total ADC of incoming TPs in a given time window (`window_length`), trigger if that total goes above some user defined threshold (`adc_threshold`). Both `window_length` and `adc_threshold` are configurable members of the `TAMakerADCSimpleWindow` class. Defaults obtained based on the data in `tps_link_11.txt`. - All of the logic is implemented in the `TAMakerADCSimpleWindow` class. A nested class called `Window` monitors incoming TPs (which are time ordered). - - When a particular window exceeds threshold, `TAMakerADCSimpleWindow::construct_ta()` constructs a `TriggerActivity`. This is enough (eventually) to request data to be read out. The `TriggerCandidateMakerADCSimpleWindow` class simply constructs trigger candidates one-for-one from the trigger activities. + - When a particular window exceeds threshold, `TAMakerADCSimpleWindow::construct_ta()` constructs a `TriggerActivity`. This is enough (eventually) to request data to be read out. The `TCMakerADCSimpleWindowAlgorithm` class simply constructs trigger candidates one-for-one from the trigger activities. - Note that an activity will only be constructed once the window is full length even if the total ADC goes above the threshold beforehand. For example, if the user defines a window 1 ms in length and the ADC threshold is reached after 0.5 ms, a candidate will only be constructed once a TP is received with a start time 1 ms after the first TP in that window. - Can use `faketp_chain` confgen to generate the configuration to run the fake TP chain with the `ADCSimpleWindow` algorithm: ``` -python -m trigger.faketp_chain -a TAMakerADCSimpleWindowPlugin -A "dict(window_length=100000,adc_threshold=1000000)" -c TriggerCandidateMakerADCSimpleWindowPlugin -f tps_link_11.txt faketp_chain_ADCSimpleWindow +python -m trigger.faketp_chain -a TAMakerADCSimpleWindowPlugin -A "dict(window_length=100000,adc_threshold=1000000)" -c TCMakerADCSimpleWindowPlugin -f tps_link_11.txt faketp_chain_ADCSimpleWindow ``` - Then to run: ``` diff --git a/include/triggeralgs/AbstractFactory.hxx b/include/triggeralgs/AbstractFactory.hxx index 71671d9..7f292bf 100644 --- a/include/triggeralgs/AbstractFactory.hxx +++ b/include/triggeralgs/AbstractFactory.hxx @@ -8,6 +8,8 @@ #ifndef TRIGGERALGS_ABSTRACT_FACTORY_HXX_ #define TRIGGERALGS_ABSTRACT_FACTORY_HXX_ +#include "triggeralgs/Issues.hpp" + namespace triggeralgs { template @@ -29,8 +31,7 @@ void AbstractFactory::register_creator(const std::string alg_name, maker_crea makers[alg_name] = creator; return; } - TLOG(0) << "Attempted to overwrite a creator in factory with " << alg_name << "."; - throw; // creators should not be overwritten. + throw FactoryOverwrite(ERS_HERE, alg_name); return; } @@ -41,11 +42,11 @@ std::unique_ptr AbstractFactory::build_maker(const std::string& alg_name) auto it = makers.find(alg_name); if (it != makers.end()) { - TLOG(0) << "Factory building " << alg_name << "."; + TLOG() << "[AF] Factory building " << alg_name << "."; return it->second(); } - TLOG(0) << "Factory couldn't find " << alg_name << "."; + throw FactoryNotFound(ERS_HERE, alg_name); return nullptr; } diff --git a/include/triggeralgs/BundleN/TAMakerBundleNAlgorithm.hpp b/include/triggeralgs/BundleN/TAMakerBundleNAlgorithm.hpp new file mode 100644 index 0000000..3860bb1 --- /dev/null +++ b/include/triggeralgs/BundleN/TAMakerBundleNAlgorithm.hpp @@ -0,0 +1,33 @@ +/** + * @file TAMakerBundleNAlgorithm.hpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2020. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#ifndef TRIGGERALGS_BUNDLEN_TRIGGERACTIVITYMAKERBUNDLEN_HPP_ +#define TRIGGERALGS_BUNDLEN_TRIGGERACTIVITYMAKERBUNDLEN_HPP_ + +#include "triggeralgs/TriggerActivityFactory.hpp" + +#include + +namespace triggeralgs { + +class TAMakerBundleNAlgorithm : public TriggerActivityMaker +{ + public: + void process(const TriggerPrimitive& input_tp, std::vector& output_tas); + void configure(const nlohmann::json& config); + bool bundle_condition(); + + private: + uint64_t m_bundle_size = 1; + TriggerActivity m_current_ta; + void set_ta_attributes(); +}; + +} // namespace triggeralgs + +#endif // TRIGGERALGS_BUNDLEN_TRIGGERACTIVITYMAKERBUNDLEN_HPP_ diff --git a/include/triggeralgs/BundleN/TCMakerBundleNAlgorithm.hpp b/include/triggeralgs/BundleN/TCMakerBundleNAlgorithm.hpp new file mode 100644 index 0000000..6e0a8da --- /dev/null +++ b/include/triggeralgs/BundleN/TCMakerBundleNAlgorithm.hpp @@ -0,0 +1,33 @@ +/** + * @file TCMakerBundleNAlgorithm.hpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2020. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#ifndef TRIGGERALGS_BUNDLEN_TRIGGERCANDIDATEMAKERBUNDLEN_HPP_ +#define TRIGGERALGS_BUNDLEN_TRIGGERCANDIDATEMAKERBUNDLEN_HPP_ + +#include "triggeralgs/TriggerCandidateFactory.hpp" + +#include + +namespace triggeralgs { + +class TCMakerBundleNAlgorithm: public TriggerCandidateMaker +{ + public: + void process(const TriggerActivity& input_ta, std::vector& output_tcs); + void configure(const nlohmann::json& config); + bool bundle_condition(); + + private: + uint64_t m_bundle_size = 1; + TriggerCandidate m_current_tc; + void set_tc_attributes(); +}; + +} // namespace triggeralgs + +#endif // TRIGGERALGS_BUNDLEN_TRIGGERCANDIDATEMAKERBUNDLEN_HPP_ diff --git a/include/triggeralgs/ChannelAdjacency/README.md b/include/triggeralgs/ChannelAdjacency/README.md new file mode 100644 index 0000000..72075a2 --- /dev/null +++ b/include/triggeralgs/ChannelAdjacency/README.md @@ -0,0 +1,3 @@ +The ChannelAdjacency algorithm is a refined version of the HorizontalMuon algorithm (only the TA maker part for the moment). TA logic changes: in a given TP window (of default 8000 ticks), when TAs are constructed, they only contain the TPs which form an activity/track (and are not the outliers). More than one TAs per window are allowed but they should not be overlapping! + +More details can be found here https://indico.fnal.gov/event/63863/ (Horizontal Muon refinement by SS Chhibra) \ No newline at end of file diff --git a/include/triggeralgs/ChannelAdjacency/TAMakerChannelAdjacencyAlgorithm.hpp b/include/triggeralgs/ChannelAdjacency/TAMakerChannelAdjacencyAlgorithm.hpp new file mode 100644 index 0000000..4f5d54e --- /dev/null +++ b/include/triggeralgs/ChannelAdjacency/TAMakerChannelAdjacencyAlgorithm.hpp @@ -0,0 +1,42 @@ +/** + * @file TAMakerChannelAdjacencyAlgorithm.hpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#ifndef TRIGGERALGS_CHANNELADJACENCY_TRIGGERACTIVITYMAKERCHANNELADJACENCY_HPP_ +#define TRIGGERALGS_CHANNELADJACENCY_TRIGGERACTIVITYMAKERCHANNELADJACENCY_HPP_ + +#include "triggeralgs/TPWindow.hpp" +#include "triggeralgs/TriggerActivityFactory.hpp" +#include +#include + +namespace triggeralgs { +class TAMakerChannelAdjacencyAlgorithm : public TriggerActivityMaker +{ +public: + void process(const TriggerPrimitive& input_tp, std::vector& output_ta); + void configure(const nlohmann::json& config); + +private: + TriggerActivity construct_ta(TPWindow) const; + + TPWindow check_adjacency(); + + TPWindow m_current_window; + + // Configurable parameters. + bool m_print_tp_info = false; // Prints out some information on every TP received + uint16_t m_adjacency_threshold = 15; // Default is 15 wire track for testing + uint16_t m_adj_tolerance = 3; // Adjacency tolerance - default is 3 from coldbox testing. + timestamp_t m_window_length = 8000; // Shouldn't exceed the max drift which is ~9375 62.5 MHz ticks for VDCB + + // For debugging and performance study purposes. + void add_window_to_record(TPWindow window); + std::vector m_window_record; +}; +} // namespace triggeralgs +#endif // TRIGGERALGS_CHANNELADJACENCY_TRIGGERACTIVITYMAKERCHANNELADJACENCY_HPP_ diff --git a/include/triggeralgs/ChannelAdjacency/TCMakerChannelAdjacencyAlgorithm.hpp b/include/triggeralgs/ChannelAdjacency/TCMakerChannelAdjacencyAlgorithm.hpp new file mode 100644 index 0000000..aea9d42 --- /dev/null +++ b/include/triggeralgs/ChannelAdjacency/TCMakerChannelAdjacencyAlgorithm.hpp @@ -0,0 +1,46 @@ +/** + * @file TCMakerChannelAdjacencyAlgorithm.hpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#ifndef TRIGGERALGS_CHANNELADJACENCY_TRIGGERCANDIDATEMAKERCHANNELADJACENCY_HPP_ +#define TRIGGERALGS_CHANNELADJACENCY_TRIGGERCANDIDATEMAKERCHANNELADJACENCY_HPP_ + +#include "triggeralgs/TriggerCandidateFactory.hpp" +#include "triggeralgs/TAWindow.hpp" + +#include +#include + +namespace triggeralgs { +class TCMakerChannelAdjacencyAlgorithm : public TriggerCandidateMaker +{ + +public: + // The function that gets called when there is a new activity + void process(const TriggerActivity&, std::vector&); + void configure(const nlohmann::json& config); + +private: + + TriggerCandidate construct_tc() const; + + TAWindow m_current_window; + uint64_t m_activity_count = 0; // NOLINT(build/unsigned) + + // Configurable parameters. + bool m_trigger_on_adc = false; + bool m_trigger_on_n_channels = false; + uint32_t m_adc_threshold = 1200000; + uint16_t m_n_channels_threshold = 600; // 80ish for frames, O(200 - 600) for tpslink + timestamp_t m_window_length = 80000; + + // For debugging purposes. + void add_window_to_record(TAWindow window); + std::vector m_window_record; +}; +} // namespace triggeralgs +#endif // TRIGGERALGS_CHANNELADJACENCY_TRIGGERCANDIDATEMAKERCHANNELADJACENCY_HPP_ diff --git a/include/triggeralgs/ChannelDistance/TAMakerChannelDistanceAlgorithm.hpp b/include/triggeralgs/ChannelDistance/TAMakerChannelDistanceAlgorithm.hpp new file mode 100644 index 0000000..9aeef20 --- /dev/null +++ b/include/triggeralgs/ChannelDistance/TAMakerChannelDistanceAlgorithm.hpp @@ -0,0 +1,35 @@ +/** + * @file TAMakerChannelDistanceAlgorithm.hpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#ifndef TRIGGERALGS_CHANNELDISTANCE_TRIGGERACTIVITYMAKERCHANNELDISTANCE_HPP_ +#define TRIGGERALGS_CHANNELDISTANCE_TRIGGERACTIVITYMAKERCHANNELDISTANCE_HPP_ + +#include "triggeralgs/TriggerActivityFactory.hpp" +#include + +namespace triggeralgs { + +class TAMakerChannelDistanceAlgorithm : public TriggerActivityMaker { + public: + void process(const TriggerPrimitive& input_tp, std::vector& output_tas); + void configure(const nlohmann::json& config); + void set_ta_attributes(); + + private: + void set_new_ta(const TriggerPrimitive& input_tp); + TriggerActivity m_current_ta; + uint32_t m_max_channel_distance = 50; + uint64_t m_window_length = 8000; + uint16_t m_min_tps = 20; // AEO: Type is arbitrary. Surprised even asking for 2^8 TPs. + uint32_t m_current_lower_bound; + uint32_t m_current_upper_bound; +}; + +} // namespace triggeralgs + +#endif // TRIGGERALGS_CHANNELDISTANCE_TRIGGERACTIVITYMAKERCHANNELDISTANCE_HPP_ diff --git a/include/triggeralgs/ChannelDistance/TCMakerChannelDistanceAlgorithm.hpp b/include/triggeralgs/ChannelDistance/TCMakerChannelDistanceAlgorithm.hpp new file mode 100644 index 0000000..cba4a17 --- /dev/null +++ b/include/triggeralgs/ChannelDistance/TCMakerChannelDistanceAlgorithm.hpp @@ -0,0 +1,32 @@ +/** + * @file TCMakerChannelDistanceAlgorithm.hpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#ifndef TRIGGERALGS_CHANNELDISTANCE_TRIGGERCANDIDATEMAKERCHANNELDISTANCE_HPP_ +#define TRIGGERALGS_CHANNELDISTANCE_TRIGGERCANDIDATEMAKERCHANNELDISTANCE_HPP_ + +#include "triggeralgs/TriggerCandidateFactory.hpp" +#include + +namespace triggeralgs { + +class TCMakerChannelDistanceAlgorithm : public TriggerCandidateMaker { + public: + void process(const TriggerActivity& input_ta, std::vector& output_tcs); + void configure(const nlohmann::json& config); + void set_tc_attributes(); + + private: + void set_new_tc(const TriggerActivity& input_ta); + TriggerCandidate m_current_tc; + uint16_t m_current_tp_count; + uint16_t m_max_tp_count = 1000; // Produce a TC when this count is exceeded. AEO: Arbitrary choice of 1000. +}; + +} // namespace triggeralgs + +#endif // TRIGGERALGS_CHANNELDISTANCE_TRIGGERCANDIDATEMAKERCHANNELDISTANCE_HPP_ diff --git a/include/triggeralgs/HorizontalMuon/TAMakerHorizontalMuonAlgorithm.hpp b/include/triggeralgs/HorizontalMuon/TAMakerHorizontalMuonAlgorithm.hpp index 454651d..e403cfd 100644 --- a/include/triggeralgs/HorizontalMuon/TAMakerHorizontalMuonAlgorithm.hpp +++ b/include/triggeralgs/HorizontalMuon/TAMakerHorizontalMuonAlgorithm.hpp @@ -23,16 +23,15 @@ class TAMakerHorizontalMuonAlgorithm : public TriggerActivityMaker private: TriggerActivity construct_ta() const; - uint16_t check_adjacency() const; // Returns longest string of adjacent collection hits in window + uint16_t check_adjacency() const; // Returns longest string of adjacent collection hits in window - TPWindow m_current_window; // Holds collection hits only - uint64_t m_primitive_count = 0; + TPWindow m_current_window; // Holds collection hits only int check_tot() const; // Configurable parameters. bool m_trigger_on_adc = false; bool m_trigger_on_n_channels = false; - bool m_trigger_on_adjacency = true; // Default use of the horizontal muon triggering + bool m_trigger_on_adjacency = true; // Default use of the horizontal muon triggering bool m_trigger_on_tot = false; uint16_t m_tot_threshold = 5000; // Time over threshold - threshold to exceed. bool m_print_tp_info = false; // Prints out some information on every TP received @@ -44,7 +43,7 @@ class TAMakerHorizontalMuonAlgorithm : public TriggerActivityMaker int index = 0; uint16_t ta_adc = 0; uint16_t ta_channels = 0; - timestamp_t m_window_length = 8000; // Shouldn't exceed the max drift which is ~9375 62.5 MHz ticks for VDCB + timestamp_t m_window_length = 8000; // Shouldn't exceed the max drift which is ~9375 62.5 MHz ticks for VDCB // For debugging and performance study purposes. void add_window_to_record(TPWindow window); diff --git a/include/triggeralgs/HorizontalMuon/TCMakerHorizontalMuonAlgorithm.hpp b/include/triggeralgs/HorizontalMuon/TCMakerHorizontalMuonAlgorithm.hpp index f3d37f2..6e0a020 100644 --- a/include/triggeralgs/HorizontalMuon/TCMakerHorizontalMuonAlgorithm.hpp +++ b/include/triggeralgs/HorizontalMuon/TCMakerHorizontalMuonAlgorithm.hpp @@ -38,8 +38,6 @@ class TCMakerHorizontalMuonAlgorithm : public TriggerCandidateMaker uint32_t m_adc_threshold = 1200000; uint16_t m_n_channels_threshold = 600; // 80ish for frames, O(200 - 600) for tpslink timestamp_t m_window_length = 80000; - timestamp_t m_readout_window_ticks_before = 32768; - timestamp_t m_readout_window_ticks_after = 32768; int tc_number = 0; // For debugging purposes. diff --git a/include/triggeralgs/Issues.hpp b/include/triggeralgs/Issues.hpp new file mode 100644 index 0000000..38e32c6 --- /dev/null +++ b/include/triggeralgs/Issues.hpp @@ -0,0 +1,31 @@ +/** +* @file Issues.hpp +* +* This is part of the DUNE DAQ Application Framework, copyright 2020. +* Licensing/copyright details are in the COPYING file that you should have +* received with this code. +*/ + +#ifndef TRIGGERALGS_INCLUDE_TRIGGERALGS_ISSUES_HPP_ +#define TRIGGERALGS_INCLUDE_TRIGGERALGS_ISSUES_HPP_ + +#include "ers/Issue.hpp" + +#include + +ERS_DECLARE_ISSUE(triggeralgs, + FactoryOverwrite, + "Attempted to overwrite a creator in factory with " << alg_name, + ((std::string)alg_name)) + +ERS_DECLARE_ISSUE(triggeralgs, + FactoryNotFound, + "Factory couldn't find: " << alg_name, + ((std::string)alg_name)) + +ERS_DECLARE_ISSUE(triggeralgs, + BadConfiguration, + "Bad configuration in " << alg_name, + ((std::string)alg_name)) + +#endif // TRIGGERALGS_INCLUDE_TRIGGERALGS_ISSUES_HPP_ diff --git a/include/triggeralgs/Logging.hpp b/include/triggeralgs/Logging.hpp new file mode 100644 index 0000000..c9c273f --- /dev/null +++ b/include/triggeralgs/Logging.hpp @@ -0,0 +1,30 @@ +/** + * @file Logging.hpp Common logging declarations in triggeralgs + * + * This is part of the DUNE DAQ , copyright 2020. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ +#ifndef TRIGGERALGS_INCLUDE_LOGGING_HPP_ +#define TRIGGERALGS_INCLUDE_LOGGING_HPP_ + +namespace triggeralgs { + +/** +* @brief Common name used by TRACE TLOG calls from this package +*/ +enum Logging +{ + TLVL_VERY_IMPORTANT = 1, + TLVL_IMPORTANT = 2, + TLVL_GENERAL = 3, + TLVL_DEBUG_INFO = 4, + TLVL_DEBUG_LOW = 5, + TLVL_DEBUG_MEDIUM = 10, + TLVL_DEBUG_HIGH = 15, + TLVL_DEBUG_ALL = 20 +}; + +} // namespace triggeralgs + +#endif // TRIGGERALGS_INCLUDE_LOGGING_HPP_ diff --git a/include/triggeralgs/MichelElectron/TriggerActivityMakerMichelElectron.hpp b/include/triggeralgs/MichelElectron/TAMakerMichelElectronAlgorithm.hpp similarity index 91% rename from include/triggeralgs/MichelElectron/TriggerActivityMakerMichelElectron.hpp rename to include/triggeralgs/MichelElectron/TAMakerMichelElectronAlgorithm.hpp index c9e92c2..de29c95 100644 --- a/include/triggeralgs/MichelElectron/TriggerActivityMakerMichelElectron.hpp +++ b/include/triggeralgs/MichelElectron/TAMakerMichelElectronAlgorithm.hpp @@ -1,5 +1,5 @@ /** - * @file TriggerActivityMakerMichelElectron.hpp + * @file TAMakerMichelElectronAlgorithm.hpp * * This is part of the DUNE DAQ Application Framework, copyright 2021. * Licensing/copyright details are in the COPYING file that you should have @@ -14,7 +14,7 @@ #include namespace triggeralgs { -class TriggerActivityMakerMichelElectron : public TriggerActivityMaker +class TAMakerMichelElectronAlgorithm : public TriggerActivityMaker { public: @@ -113,14 +113,9 @@ class TriggerActivityMakerMichelElectron : public TriggerActivityMaker // Configurable parameters. // triggeractivitymakerhorizontalmuon::ConfParams m_conf; - bool m_trigger_on_adc = false; - bool m_trigger_on_n_channels = false; - bool m_trigger_on_adjacency = true; // Default use of the horizontal muon triggering bool debug = false; // Use to control whether functions write out useful info uint16_t m_adjacency_threshold = 15; // Default is 15 for trigger int m_max_adjacency = 0; // The maximum adjacency seen so far in any window - uint32_t m_adc_threshold = 3000000; // Not currently triggering on this - uint16_t m_n_channels_threshold = 400; // Set this to ~80 for frames.bin, ~150-300 for tps_link_11.txt uint16_t m_adj_tolerance = 3; // Adjacency tolerance - default is 3 from coldbox testing. int index = 0; uint16_t ta_adc = 0; diff --git a/include/triggeralgs/MichelElectron/TriggerCandidateMakerMichelElectron.hpp b/include/triggeralgs/MichelElectron/TCMakerMichelElectronAlgorithm.hpp similarity index 96% rename from include/triggeralgs/MichelElectron/TriggerCandidateMakerMichelElectron.hpp rename to include/triggeralgs/MichelElectron/TCMakerMichelElectronAlgorithm.hpp index cf80448..d8de1d6 100644 --- a/include/triggeralgs/MichelElectron/TriggerCandidateMakerMichelElectron.hpp +++ b/include/triggeralgs/MichelElectron/TCMakerMichelElectronAlgorithm.hpp @@ -1,5 +1,5 @@ /** - * @file TriggerCandidateMakerMichelElectron.hpp + * @file TCMakerMichelElectronAlgorithm.hpp * * This is part of the DUNE DAQ Application Framework, copyright 2021. * Licensing/copyright details are in the COPYING file that you should have @@ -17,7 +17,7 @@ #include namespace triggeralgs { -class TriggerCandidateMakerMichelElectron : public TriggerCandidateMaker +class TCMakerMichelElectronAlgorithm : public TriggerCandidateMaker { public: @@ -138,8 +138,6 @@ class TriggerCandidateMakerMichelElectron : public TriggerCandidateMaker uint32_t m_adc_threshold = 1200000; uint16_t m_n_channels_threshold = 600; // 80ish for frames, O(200 - 600) for tpslink timestamp_t m_window_length = 80000; - timestamp_t m_readout_window_ticks_before = 30000; - timestamp_t m_readout_window_ticks_after = 30000; int tc_number = 0; // Might not be the best type for this map. // std::unordered_map,channel_t> m_channel_map; diff --git a/include/triggeralgs/PlaneCoincidence/TriggerActivityMakerPlaneCoincidence.hpp b/include/triggeralgs/PlaneCoincidence/TAMakerPlaneCoincidenceAlgorithm.hpp similarity index 87% rename from include/triggeralgs/PlaneCoincidence/TriggerActivityMakerPlaneCoincidence.hpp rename to include/triggeralgs/PlaneCoincidence/TAMakerPlaneCoincidenceAlgorithm.hpp index 275e7b8..35a88e0 100644 --- a/include/triggeralgs/PlaneCoincidence/TriggerActivityMakerPlaneCoincidence.hpp +++ b/include/triggeralgs/PlaneCoincidence/TAMakerPlaneCoincidenceAlgorithm.hpp @@ -1,5 +1,5 @@ /** - * @file TriggerActivityMakerPlaneCoincidence.hpp + * @file TAMakerPlaneCoincidenceAlgorithm.hpp * * This is part of the DUNE DAQ Application Framework, copyright 2021. * Licensing/copyright details are in the COPYING file that you should have @@ -23,7 +23,7 @@ #include namespace triggeralgs { -class TriggerActivityMakerPlaneCoincidence : public TriggerActivityMaker +class TAMakerPlaneCoincidenceAlgorithm : public TriggerActivityMaker { public: void process(const TriggerPrimitive& input_tp, std::vector& output_ta); @@ -45,14 +45,10 @@ class TriggerActivityMakerPlaneCoincidence : public TriggerActivityMaker // Configurable parameters. std::string m_channel_map_name = "VDColdboxChannelMap"; // Default is coldbox - bool m_trigger_on_adc = true; - bool m_trigger_on_n_channels = true; - bool m_trigger_on_adjacency = true; // Default use of the triggering uint16_t m_adjacency_threshold = 15; // Default is 15 wire track for testing int m_max_adjacency = 0; // The maximum adjacency seen so far in any window uint32_t m_tot_threshold = 2000; // Work out good values for this uint32_t m_adc_threshold = 300000; // AbsRunningSum HF Alg Finds Induction ADC ~10x higher - uint16_t m_n_channels_threshold = 20; // Set this to ~80 for frames.bin, ~150-300 for tps_link_11.txt uint16_t m_adj_tolerance = 5; // Adjacency tolerance - default is 3 from coldbox testing. int index = 0; uint16_t ta_adc = 0; diff --git a/include/triggeralgs/PlaneCoincidence/TriggerCandidateMakerPlaneCoincidence.hpp b/include/triggeralgs/PlaneCoincidence/TCMakerPlaneCoincidenceAlgorithm.hpp similarity index 86% rename from include/triggeralgs/PlaneCoincidence/TriggerCandidateMakerPlaneCoincidence.hpp rename to include/triggeralgs/PlaneCoincidence/TCMakerPlaneCoincidenceAlgorithm.hpp index dd7f479..6151e3a 100644 --- a/include/triggeralgs/PlaneCoincidence/TriggerCandidateMakerPlaneCoincidence.hpp +++ b/include/triggeralgs/PlaneCoincidence/TCMakerPlaneCoincidenceAlgorithm.hpp @@ -1,5 +1,5 @@ /** - * @file TriggerCandidateMakerPlaneCoincidence.hpp + * @file TCMakerPlaneCoincidenceAlgorithm.hpp * * This is part of the DUNE DAQ Application Framework, copyright 2021. * Licensing/copyright details are in the COPYING file that you should have @@ -15,7 +15,7 @@ #include namespace triggeralgs { -class TriggerCandidateMakerPlaneCoincidence : public TriggerCandidateMaker +class TCMakerPlaneCoincidenceAlgorithm : public TriggerCandidateMaker { public: @@ -37,8 +37,6 @@ class TriggerCandidateMakerPlaneCoincidence : public TriggerCandidateMaker uint32_t m_adc_threshold = 1200000; uint16_t m_n_channels_threshold = 600; // 80ish for frames, O(200 - 600) for tpslink timestamp_t m_window_length = 80000; - timestamp_t m_readout_window_ticks_before = 30000; - timestamp_t m_readout_window_ticks_after = 30000; int tc_number = 0; // For debugging and performance study purposes. diff --git a/include/triggeralgs/Prescale/TCMakerPrescaleAlgorithm.hpp b/include/triggeralgs/Prescale/TCMakerPrescaleAlgorithm.hpp index f87a809..de5b70b 100644 --- a/include/triggeralgs/Prescale/TCMakerPrescaleAlgorithm.hpp +++ b/include/triggeralgs/Prescale/TCMakerPrescaleAlgorithm.hpp @@ -25,9 +25,6 @@ class TCMakerPrescaleAlgorithm : public TriggerCandidateMaker private: - timestamp_t m_readout_window_ticks_before = 0; - timestamp_t m_readout_window_ticks_after = 0; - }; } // namespace triggeralgs diff --git a/include/triggeralgs/Supernova/TriggerActivityMakerSupernova.hpp b/include/triggeralgs/Supernova/TAMakerSupernovaAlgorithm.hpp similarity index 97% rename from include/triggeralgs/Supernova/TriggerActivityMakerSupernova.hpp rename to include/triggeralgs/Supernova/TAMakerSupernovaAlgorithm.hpp index f711615..6d735ee 100644 --- a/include/triggeralgs/Supernova/TriggerActivityMakerSupernova.hpp +++ b/include/triggeralgs/Supernova/TAMakerSupernovaAlgorithm.hpp @@ -1,5 +1,5 @@ /** - * @file TriggerActivityMakerSupernova.hpp + * @file TAMakerSupernovaAlgorithm.hpp * * This is part of the DUNE DAQ Application Framework, copyright 2020. * Licensing/copyright details are in the COPYING file that you should have @@ -16,7 +16,7 @@ #include namespace triggeralgs { -class TriggerActivityMakerSupernova : public TriggerActivityMaker +class TAMakerSupernovaAlgorithm : public TriggerActivityMaker { /// This activity maker makes an activity with all the trigger primitives diff --git a/include/triggeralgs/Supernova/TriggerCandidateMakerSupernova.hpp b/include/triggeralgs/Supernova/TCMakerSupernovaAlgorithm.hpp similarity index 94% rename from include/triggeralgs/Supernova/TriggerCandidateMakerSupernova.hpp rename to include/triggeralgs/Supernova/TCMakerSupernovaAlgorithm.hpp index a730362..5d115f8 100644 --- a/include/triggeralgs/Supernova/TriggerCandidateMakerSupernova.hpp +++ b/include/triggeralgs/Supernova/TCMakerSupernovaAlgorithm.hpp @@ -1,5 +1,5 @@ /** - * @file TriggerCandidateMakerSupernova.hpp + * @file TCMakerSupernovaAlgorithm.hpp * * This is part of the DUNE DAQ Application Framework, copyright 2020. * Licensing/copyright details are in the COPYING file that you should have @@ -18,7 +18,7 @@ #include namespace triggeralgs { -class TriggerCandidateMakerSupernova : public TriggerCandidateMaker +class TCMakerSupernovaAlgorithm : public TriggerCandidateMaker { /// This decision maker just counts the number of activities in the time_window and triggers /// if the number of activities exceeds that. diff --git a/include/triggeralgs/Supernova/TriggerDecisionMakerSupernova.hpp b/include/triggeralgs/Supernova/TDMakerSupernovaAlgorithm.hpp similarity index 94% rename from include/triggeralgs/Supernova/TriggerDecisionMakerSupernova.hpp rename to include/triggeralgs/Supernova/TDMakerSupernovaAlgorithm.hpp index f665b02..c1020ec 100644 --- a/include/triggeralgs/Supernova/TriggerDecisionMakerSupernova.hpp +++ b/include/triggeralgs/Supernova/TDMakerSupernovaAlgorithm.hpp @@ -1,5 +1,5 @@ /** - * @file TriggerDecisionMakerSupernova.hpp + * @file TDMakerSupernovaAlgorithm.hpp * * This is part of the DUNE DAQ Application Framework, copyright 2020. * Licensing/copyright details are in the COPYING file that you should have @@ -18,7 +18,7 @@ #include namespace triggeralgs { -class TriggerDecisionMakerSupernova : public TriggerDecisionMaker +class TDMakerSupernovaAlgorithm : public TriggerDecisionMaker { /// This decision maker just spits out the trigger candidates diff --git a/include/triggeralgs/TriggerActivityMaker.hpp b/include/triggeralgs/TriggerActivityMaker.hpp index 0f30c85..d5044cf 100644 --- a/include/triggeralgs/TriggerActivityMaker.hpp +++ b/include/triggeralgs/TriggerActivityMaker.hpp @@ -9,15 +9,16 @@ #ifndef TRIGGERALGS_INCLUDE_TRIGGERALGS_TRIGGERACTIVITYMAKER_HPP_ #define TRIGGERALGS_INCLUDE_TRIGGERALGS_TRIGGERACTIVITYMAKER_HPP_ +#include "triggeralgs/Issues.hpp" +#include "triggeralgs/Logging.hpp" #include "triggeralgs/TriggerActivity.hpp" #include "triggeralgs/TriggerPrimitive.hpp" #include "triggeralgs/Types.hpp" -#include -#include #include #include -#include +#include +#include // TRACE_NAME to be defined in the derived TAMs #include "TRACE/trace.h" diff --git a/include/triggeralgs/TriggerCandidateMaker.hpp b/include/triggeralgs/TriggerCandidateMaker.hpp index 07486b9..9a9bc95 100644 --- a/include/triggeralgs/TriggerCandidateMaker.hpp +++ b/include/triggeralgs/TriggerCandidateMaker.hpp @@ -9,14 +9,16 @@ #ifndef TRIGGERALGS_INCLUDE_TRIGGERALGS_TRIGGERCANDIDATEMAKER_HPP_ #define TRIGGERALGS_INCLUDE_TRIGGERALGS_TRIGGERCANDIDATEMAKER_HPP_ +#include "triggeralgs/Issues.hpp" +#include "triggeralgs/Logging.hpp" #include "triggeralgs/TriggerActivity.hpp" #include "triggeralgs/TriggerCandidate.hpp" #include "triggeralgs/Types.hpp" -#include -#include #include #include +#include +#include // TRACE_NAME to be defined in the derived TAMs #include "TRACE/trace.h" diff --git a/include/triggeralgs/TriggerDecisionMaker.hpp b/include/triggeralgs/TriggerDecisionMaker.hpp index b745283..7a5bf10 100644 --- a/include/triggeralgs/TriggerDecisionMaker.hpp +++ b/include/triggeralgs/TriggerDecisionMaker.hpp @@ -9,13 +9,15 @@ #ifndef TRIGGERALGS_INCLUDE_TRIGGERALGS_TRIGGERDECISIONMAKER_HPP_ #define TRIGGERALGS_INCLUDE_TRIGGERALGS_TRIGGERDECISIONMAKER_HPP_ +#include "triggeralgs/Issues.hpp" +#include "triggeralgs/Logging.hpp" #include "triggeralgs/TriggerCandidate.hpp" #include "triggeralgs/TriggerDecision.hpp" -#include -#include #include #include +#include +#include namespace triggeralgs { @@ -26,9 +28,6 @@ class TriggerDecisionMaker virtual void operator()(const TriggerCandidate& input_tc, std::vector& output_tds) = 0; virtual void flush(std::vector&) {} virtual void configure(const nlohmann::json&) {} - - std::atomic m_data_vs_system_time = 0; - }; } // namespace triggeralgs diff --git a/include/triggeralgs/TriggerPrimitiveMaker.hpp b/include/triggeralgs/TriggerPrimitiveMaker.hpp index dcb6dc1..3e53329 100644 --- a/include/triggeralgs/TriggerPrimitiveMaker.hpp +++ b/include/triggeralgs/TriggerPrimitiveMaker.hpp @@ -9,6 +9,8 @@ #ifndef TRIGGERALGS_INCLUDE_TRIGGERALGS_TRIGGERPRIMITIVEMAKER_HPP_ #define TRIGGERALGS_INCLUDE_TRIGGERALGS_TRIGGERPRIMITIVEMAKER_HPP_ +#include "triggeralgs/Issues.hpp" +#include "triggeralgs/Logging.hpp" #include "trgdataformats/TriggerPrimitive.hpp" #include diff --git a/include/triggeralgs/dbscan/TriggerActivityMakerDBSCAN.hpp b/include/triggeralgs/dbscan/TAMakerDBSCANAlgorithm.hpp similarity index 89% rename from include/triggeralgs/dbscan/TriggerActivityMakerDBSCAN.hpp rename to include/triggeralgs/dbscan/TAMakerDBSCANAlgorithm.hpp index f2d6cd5..06dfb74 100644 --- a/include/triggeralgs/dbscan/TriggerActivityMakerDBSCAN.hpp +++ b/include/triggeralgs/dbscan/TAMakerDBSCANAlgorithm.hpp @@ -1,5 +1,5 @@ /** - * @file TriggerActivityMakerDBSCAN.hpp + * @file TAMakerDBSCANAlgorithm.hpp * * This is part of the DUNE DAQ Application Framework, copyright 2020. * Licensing/copyright details are in the COPYING file that you should have @@ -16,7 +16,7 @@ #include namespace triggeralgs { -class TriggerActivityMakerDBSCAN : public TriggerActivityMaker +class TAMakerDBSCANAlgorithm : public TriggerActivityMaker { public: @@ -25,6 +25,7 @@ class TriggerActivityMakerDBSCAN : public TriggerActivityMaker void configure(const nlohmann::json &config); private: + int m_eps{10}; int m_min_pts{3}; // Minimum number of points to form a cluster timestamp_t m_first_timestamp{0}; timestamp_t m_prev_timestamp{0}; diff --git a/include/triggeralgs/dbscan/TCMakerDBSCANAlgorithm.hpp b/include/triggeralgs/dbscan/TCMakerDBSCANAlgorithm.hpp new file mode 100644 index 0000000..f6d9d4b --- /dev/null +++ b/include/triggeralgs/dbscan/TCMakerDBSCANAlgorithm.hpp @@ -0,0 +1,35 @@ +/** + * @file TCMakerDBSCANAlgorithm.hpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2020. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#ifndef TRIGGERALGS_DBSCAN_TRIGGERCANDIDATEMAKERDBSCAN_HPP_ +#define TRIGGERALGS_DBSCAN_TRIGGERCANDIDATEMAKERDBSCAN_HPP_ + +#include "triggeralgs/TriggerCandidateFactory.hpp" +#include "triggeralgs/dbscan/dbscan.hpp" + +#include +#include + +namespace triggeralgs { +class TCMakerDBSCANAlgorithm : public TriggerCandidateMaker +{ + +public: + void process(const TriggerActivity& input_ta, std::vector& output_tc); + void configure(const nlohmann::json &config); + +private: + void set_new_tc(const TriggerActivity& input_ta); + void set_tc_attributes(); + TriggerCandidate m_current_tc; + uint16_t m_current_tp_count; + uint16_t m_max_tp_count = 1000; // Produce a TC when this count is exceeded. AEO: Arbitrary choice of 1000. +}; +} // namespace triggeralgs + +#endif // TRIGGERALGS_DBSCAN_TRIGGERCANDIDATEMAKERPRESCALE_HPP_ diff --git a/src/TAMakerADCSimpleWindowAlgorithm.cpp b/src/TAMakerADCSimpleWindowAlgorithm.cpp index 4f36e6d..bb4f030 100644 --- a/src/TAMakerADCSimpleWindowAlgorithm.cpp +++ b/src/TAMakerADCSimpleWindowAlgorithm.cpp @@ -13,7 +13,12 @@ #include + using namespace triggeralgs; +using Logging::TLVL_DEBUG_ALL; +using Logging::TLVL_DEBUG_HIGH; +using Logging::TLVL_DEBUG_LOW; +using Logging::TLVL_IMPORTANT; void TAMakerADCSimpleWindowAlgorithm::process(const TriggerPrimitive& input_tp, std::vector& output_ta) @@ -30,7 +35,7 @@ TAMakerADCSimpleWindowAlgorithm::process(const TriggerPrimitive& input_tp, std:: // If the difference between the current TP's start time and the start of the window // is less than the specified window size, add the TP to the window. if((input_tp.time_start - m_current_window.time_start) < m_window_length){ - //TLOG_DEBUG(TRACE_NAME) << "Window not yet complete, adding the input_tp to the window."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TAM:ADCSW] Window not yet complete, adding the input_tp to the window."; m_current_window.add(input_tp); } // If the addition of the current TP to the window would make it longer @@ -38,18 +43,18 @@ TAMakerADCSimpleWindowAlgorithm::process(const TriggerPrimitive& input_tp, std:: // the existing window is above the specified threshold. If it is, make a TA and start // a fresh window with the current TP. else if(m_current_window.adc_integral > m_adc_threshold){ - //TLOG_DEBUG(TRACE_NAME) << "ADC integral in window is greater than specified threshold."; + TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TAM:ADCSW] ADC integral in window is greater than specified threshold."; output_ta.push_back(construct_ta()); - //TLOG_DEBUG(TRACE_NAME) << "Resetting window with input_tp."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TAM:ADCSW] Resetting window with input_tp."; m_current_window.reset(input_tp); } // If it is not, move the window along. else{ - //TLOG_DEBUG(TRACE_NAME) << "Window is at required length but adc threshold not met, shifting window along."; + TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:ADCSW] Window is at required length but adc threshold not met, shifting window along."; m_current_window.move(input_tp, m_window_length); } - //TLOG_DEBUG(TRACE_NAME) << m_current_window; + TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:ADCSW] " << m_current_window; m_primitive_count++; @@ -67,16 +72,16 @@ TAMakerADCSimpleWindowAlgorithm::configure(const nlohmann::json& config) if (config.contains("adc_threshold")) m_adc_threshold = config["adc_threshold"]; } else{ - TLOG_DEBUG(TRACE_NAME) << "The DEFAULT values of window_length and adc_threshold are being used."; + TLOG_DEBUG(TLVL_IMPORTANT) << "[TAM:ADCSW] The DEFAULT values of window_length and adc_threshold are being used."; } - TLOG_DEBUG(TRACE_NAME) << "If the total ADC of trigger primitives with times within a " + TLOG_DEBUG(TLVL_IMPORTANT) << "[TAM:ADCSW] If the total ADC of trigger primitives with times within a " << m_window_length << " tick time window is above " << m_adc_threshold << " counts, a trigger will be issued."; } TriggerActivity TAMakerADCSimpleWindowAlgorithm::construct_ta() const { - TLOG(TLVL_DEBUG_1) << "I am constructing a trigger activity!"; + TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TAM:ADCSW] I am constructing a trigger activity!"; //TLOG_DEBUG(TRACE_NAME) << m_current_window; TriggerPrimitive latest_tp_in_window = m_current_window.tp_list.back(); diff --git a/src/TAMakerBundleNAlgorithm.cpp b/src/TAMakerBundleNAlgorithm.cpp new file mode 100644 index 0000000..3205908 --- /dev/null +++ b/src/TAMakerBundleNAlgorithm.cpp @@ -0,0 +1,87 @@ +/** + * @file TAMakerBundleNAlgorithm.cpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2020. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#include "triggeralgs/BundleN/TAMakerBundleNAlgorithm.hpp" + +#include "TRACE/trace.h" +#define TRACE_NAME "TAMakerBundleNAlgorithm" + +namespace triggeralgs { + +using Logging::TLVL_IMPORTANT; +using Logging::TLVL_DEBUG_HIGH; + +void TAMakerBundleNAlgorithm::set_ta_attributes() { + // Using the first TA as reference. + TriggerPrimitive first_tp = m_current_ta.inputs.front(); + TriggerPrimitive last_tp = m_current_ta.inputs.back(); + + m_current_ta.channel_start = first_tp.channel; + m_current_ta.channel_end = last_tp.channel; + + m_current_ta.time_start = first_tp.time_start; + m_current_ta.time_end = last_tp.time_start; + + m_current_ta.detid = first_tp.detid; + + m_current_ta.algorithm = TriggerActivity::Algorithm::kBundle; + m_current_ta.type = TriggerActivity::Type::kTPC; + + m_current_ta.adc_peak = 0; + for (const TriggerPrimitive& tp : m_current_ta.inputs) { + m_current_ta.adc_integral += tp.adc_integral; + if (tp.adc_peak <= m_current_ta.adc_peak) continue; + m_current_ta.adc_peak = tp.adc_peak; + m_current_ta.channel_peak = tp.channel; + m_current_ta.time_peak = tp.time_peak; + } + m_current_ta.time_activity = m_current_ta.time_peak; + return; +} + +bool TAMakerBundleNAlgorithm::bundle_condition() { + return m_current_ta.inputs.size() == m_bundle_size; +} + +void +TAMakerBundleNAlgorithm::process(const TriggerPrimitive& input_tp, std::vector& output_tas) +{ + // Expect that TPs are inherently time ordered. + m_current_ta.inputs.push_back(input_tp); + + if (bundle_condition()) { + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TA:BN] Emitting BundleN TA with " << m_current_ta.inputs.size() << " TPs."; + set_ta_attributes(); + output_tas.push_back(m_current_ta); + + // Reset the current. + m_current_ta = TriggerActivity(); + } + + // Should never reach this step. In this case, send it out. + if (m_current_ta.inputs.size() > m_bundle_size) { + TLOG_DEBUG(TLVL_IMPORTANT) << "[TA:BN] Emitting large BundleN TriggerActivity with " << m_current_ta.inputs.size() << " TPs."; + set_ta_attributes(); + output_tas.push_back(m_current_ta); + + // Reset the current. + m_current_ta = TriggerActivity(); + } +} + +void +TAMakerBundleNAlgorithm::configure(const nlohmann::json& config) +{ + if (config.is_object() && config.contains("bundle_size")) { + m_bundle_size = config["bundle_size"]; + } +} + +REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TAMakerBundleNAlgorithm) +} // namespace triggeralgs + diff --git a/src/TAMakerChannelAdjacencyAlgorithm.cpp b/src/TAMakerChannelAdjacencyAlgorithm.cpp new file mode 100644 index 0000000..a067931 --- /dev/null +++ b/src/TAMakerChannelAdjacencyAlgorithm.cpp @@ -0,0 +1,241 @@ +/** + * @file TAMakerChannelAdjacencyAlgorithm.cpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#include "triggeralgs/ChannelAdjacency/TAMakerChannelAdjacencyAlgorithm.hpp" +#include "TRACE/trace.h" +#include "triggeralgs/Logging.hpp" +#define TRACE_NAME "TAMakerChannelAdjacencyAlgorithm" +#include +#include + +using namespace triggeralgs; + +using Logging::TLVL_DEBUG_LOW; + +void +TAMakerChannelAdjacencyAlgorithm::process(const TriggerPrimitive& input_tp, + std::vector& output_ta) +{ + + // Add useful info about recived TPs here for FW and SW TPG guys. + if (m_print_tp_info) { + TLOG_DEBUG(TLVL_DEBUG_LOW) << " ########## m_current_window is reset ##########\n" + << " TP Start Time: " << input_tp.time_start << ", TP ADC Sum: " << input_tp.adc_integral + << ", TP TOT: " << input_tp.time_over_threshold << ", TP ADC Peak: " << input_tp.adc_peak + << ", TP Offline Channel ID: " << input_tp.channel << "\n"; + } + + // 0) FIRST TP ===================================================================== + // The first time process() is called, reset the window object. + if (m_current_window.is_empty()) { + m_current_window.reset(input_tp); + return; + } + + // If the difference between the current TP's start time and the start of the window + // is less than the specified window size, add the TP to the window. + bool adj_pass = 0; // sets to true when adjacency logic is satisfied + bool window_filled = 1; // sets to true when window is ready to test the adjacency logic + if ((input_tp.time_start - m_current_window.time_start) < m_window_length) { + m_current_window.add(input_tp); + window_filled = 0; + TLOG_DEBUG(TLVL_DEBUG_LOW) << "m_current_window.time_start " << m_current_window.time_start << "\n"; + } + + else { + TPWindow win_adj_max; + + bool ta_found = 1; + while (ta_found) { + + // make m_current_window_tmp a copy of m_current_window and clear m_current_window + TPWindow m_current_window_tmp = m_current_window; + m_current_window.clear(); + + // make m_current_window a new window of non-overlapping tps (of m_current_window_tmp and win_adj_max) + for (auto tp : m_current_window_tmp.inputs) { + bool new_tp = 1; + for (auto tp_sel : win_adj_max.inputs) { + if (tp.channel == tp_sel.channel) { + new_tp = 0; + break; + } + } + if (new_tp) + m_current_window.add(tp); + } + + // check adjacency -> win_adj_max now contains only those tps that make the track + win_adj_max = check_adjacency(); + if (win_adj_max.inputs.size() > 0) { + + adj_pass = 1; + ta_found = 1; + output_ta.push_back(construct_ta(win_adj_max)); + } else + ta_found = 0; + } + if (adj_pass) + m_current_window.reset(input_tp); + } + + // if adjacency logic is not true, slide the window along using the current TP. + if (window_filled && !adj_pass) { + m_current_window.move(input_tp, m_window_length); + } + + return; +} + +void +TAMakerChannelAdjacencyAlgorithm::configure(const nlohmann::json& config) +{ + TriggerActivityMaker::configure(config); + if (config.is_object()) { + if (config.contains("window_length")) + m_window_length = config["window_length"]; + if (config.contains("adjacency_tolerance")) + m_adj_tolerance = config["adjacency_tolerance"]; + if (config.contains("adjacency_threshold")) + m_adjacency_threshold = config["adjacency_threshold"]; + if (config.contains("print_tp_info")) + m_print_tp_info = config["print_tp_info"]; + } +} + +TriggerActivity +TAMakerChannelAdjacencyAlgorithm::construct_ta(TPWindow win_adj_max) const +{ + + TriggerActivity ta; + + TriggerPrimitive last_tp = win_adj_max.inputs.back(); + + ta.time_start = last_tp.time_start; + ta.time_end = last_tp.time_start; + ta.time_peak = last_tp.time_peak; + ta.time_activity = last_tp.time_peak; + ta.channel_start = last_tp.channel; + ta.channel_end = last_tp.channel; + ta.channel_peak = last_tp.channel; + ta.adc_integral = win_adj_max.adc_integral; + ta.adc_peak = last_tp.adc_peak; + ta.detid = last_tp.detid; + ta.type = TriggerActivity::Type::kTPC; + ta.algorithm = TriggerActivity::Algorithm::kChannelAdjacency; + ta.inputs = win_adj_max.inputs; + + for (const auto& tp : ta.inputs) { + ta.time_start = std::min(ta.time_start, tp.time_start); + ta.time_end = std::max(ta.time_end, tp.time_start); + ta.channel_start = std::min(ta.channel_start, tp.channel); + ta.channel_end = std::max(ta.channel_end, tp.channel); + if (tp.adc_peak > ta.adc_peak) { + ta.time_peak = tp.time_peak; + ta.adc_peak = tp.adc_peak; + ta.channel_peak = tp.channel; + } + } + + return ta; +} + +// std::vector +TPWindow +TAMakerChannelAdjacencyAlgorithm::check_adjacency() +{ + // This function deals with tp window (m_current_window), select adjacent tps (with a channel gap from 0 to 5; sum of + // all gaps < m_adj_tolerance), checks if track length > m_adjacency_threshold: return the tp window (win_adj_max, + // which is subset of the input tp window) + + unsigned int channel = 0; // Current channel ID + unsigned int next_channel = 0; // Next channel ID + unsigned int next = 0; // The next position in the hit channels vector + unsigned int tol_count = 0; // Tolerance count, should not pass adj_tolerance + + // Generate a channelID ordered list of hit channels for this window; second element of pair is tps + std::vector> chanTPList; + for (auto tp : m_current_window.inputs) { + chanTPList.push_back(std::make_pair(tp.channel, tp)); + } + std::sort(chanTPList.begin(), + chanTPList.end(), + [](const std::pair& a, const std::pair& b) { + return (a.first < b.first); + }); + + // ADAJACENCY LOGIC ==================================================================== + // ===================================================================================== + // Adjcancency Tolerance = Number of times prepared to skip missed hits before resetting + // the adjacency count (win_adj). This accounts for things like dead channels / missed TPs. + + // add first tp, and then if tps are on next channels (check code below to understand the definition) + TPWindow win_adj; + TPWindow win_adj_max; // if track length > m_adjacency_threshold, set win_adj_max = win_adj; return win_adj_max; + + for (int i = 0; i < chanTPList.size(); ++i) { + + win_adj_max.clear(); + + next = (i + 1) % chanTPList.size(); // Loops back when outside of channel list range + channel = chanTPList.at(i).first; + next_channel = chanTPList.at(next).first; // Next channel with a hit + + // End of vector condition. + if (next == 0) { + next_channel = channel - 1; + } + + // Skip same channel hits. + if (next_channel == channel) + continue; + + // If win_adj size == zero, add current tp + if (win_adj.inputs.size() == 0) + win_adj.add(chanTPList[i].second); + + // If next hit is on next channel, increment the adjacency count + if (next_channel - channel == 1) { + win_adj.add(chanTPList[next].second); + } + + // Allow a max gap of 5 channels (e.g., 45 and 50; 46, 47, 48, 49 are missing); increment the adjacency count + // Sum of gaps should be < adj_tolerance (e.g., if toleance is 30, the max total gap can vary from 0 to 29+4 = 33) + else if (next_channel - channel > 0 && next_channel - channel <= 5 && tol_count < m_adj_tolerance) { + win_adj.add(chanTPList[next].second); + tol_count += next_channel - channel - 1; + } + + // if track length > m_adjacency_threshold, set win_adj_max = win_adj; + else if (win_adj.inputs.size() > m_adjacency_threshold) { + win_adj_max = win_adj; + break; + } + + // If track length < m_adjacency_threshold, reset variables for next iteration. + else { + tol_count = 0; + win_adj.clear(); + } + } + + return win_adj_max; +} + +// ===================================================================================== +// Functions below this line are for debugging purposes. +// ===================================================================================== +void +TAMakerChannelAdjacencyAlgorithm::add_window_to_record(TPWindow window) +{ + m_window_record.push_back(window); + return; +} + +// Register algo in TA Factory +REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TAMakerChannelAdjacencyAlgorithm) diff --git a/src/TAMakerChannelDistanceAlgorithm.cpp b/src/TAMakerChannelDistanceAlgorithm.cpp new file mode 100644 index 0000000..bb4d7e4 --- /dev/null +++ b/src/TAMakerChannelDistanceAlgorithm.cpp @@ -0,0 +1,104 @@ +/** + * @file TAMakerChannelDistanceAlgorithm.cpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#include "triggeralgs/ChannelDistance/TAMakerChannelDistanceAlgorithm.hpp" + +#include "TRACE/trace.h" +#define TRACE_NAME "TAMakerChannelDistanceAlgorithm" + +namespace triggeralgs { + +void +TAMakerChannelDistanceAlgorithm::set_new_ta(const TriggerPrimitive& input_tp) +{ + m_current_ta = TriggerActivity(); + m_current_ta.inputs.push_back(input_tp); + m_current_lower_bound = input_tp.channel - m_max_channel_distance; + m_current_upper_bound = input_tp.channel + m_max_channel_distance; + return; +} + +void +TAMakerChannelDistanceAlgorithm::process(const TriggerPrimitive& input_tp, + std::vector& output_tas) +{ + + // Start a new TA if not already going. + if (m_current_ta.inputs.empty()) { + set_new_ta(input_tp); + return; + } + + // Check to close the TA based on time. + if (input_tp.time_start - m_current_ta.inputs.front().time_start > m_window_length) { + // Check to block the TA based on min TPs. + if (m_current_ta.inputs.size() >= m_min_tps) { + set_ta_attributes(); + output_tas.push_back(m_current_ta); + } + set_new_ta(input_tp); + return; + } + + // Check to skip the TP if it's outside the current channel bounds. + if (input_tp.channel > m_current_upper_bound || input_tp.channel < m_current_lower_bound) + return; + + m_current_ta.inputs.push_back(input_tp); + m_current_lower_bound = std::min(m_current_lower_bound, input_tp.channel - m_max_channel_distance); + m_current_upper_bound = std::max(m_current_upper_bound, input_tp.channel + m_max_channel_distance); +} + +void +TAMakerChannelDistanceAlgorithm::configure(const nlohmann::json& config) +{ + TriggerActivityMaker::configure(config); + + if (config.contains("min_tps")) + m_min_tps = config["min_tps"]; + if (config.contains("window_length")) + m_window_length = config["window_length"]; + if (config.contains("max_channel_distance")) + m_max_channel_distance = config["max_channel_distance"]; + + return; +} + +void +TAMakerChannelDistanceAlgorithm::set_ta_attributes() +{ + TriggerPrimitive first_tp = m_current_ta.inputs.front(); + TriggerPrimitive last_tp = m_current_ta.inputs.back(); + + m_current_ta.channel_start = first_tp.channel; + m_current_ta.channel_end = last_tp.channel; + + m_current_ta.time_start = first_tp.time_start; + m_current_ta.time_end = last_tp.time_start; + + m_current_ta.detid = first_tp.detid; + + m_current_ta.algorithm = TriggerActivity::Algorithm::kChannelDistance; + m_current_ta.type = TriggerActivity::Type::kTPC; + + m_current_ta.adc_peak = 0; + for (const TriggerPrimitive& tp : m_current_ta.inputs) { + m_current_ta.adc_integral += tp.adc_integral; + if (tp.adc_peak <= m_current_ta.adc_peak) + continue; + m_current_ta.adc_peak = tp.adc_peak; + m_current_ta.channel_peak = tp.channel; + m_current_ta.time_peak = tp.time_peak; + } + m_current_ta.time_activity = m_current_ta.time_peak; +} + +// Register algo in TA Factory +REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TAMakerChannelDistanceAlgorithm) + +} // namespace triggeralgs diff --git a/src/TriggerActivityMakerDBSCAN.cpp b/src/TAMakerDBSCANAlgorithm.cpp similarity index 62% rename from src/TriggerActivityMakerDBSCAN.cpp rename to src/TAMakerDBSCANAlgorithm.cpp index e2207ef..c791a42 100644 --- a/src/TriggerActivityMakerDBSCAN.cpp +++ b/src/TAMakerDBSCANAlgorithm.cpp @@ -1,34 +1,31 @@ /** - * @file TriggerActivityMakerDBSCAN.cpp + * @file TAMakerDBSCANAlgorithm.cpp * * This is part of the DUNE DAQ Application Framework, copyright 2020. * Licensing/copyright details are in the COPYING file that you should have * received with this code. */ -#include "triggeralgs/dbscan/TriggerActivityMakerDBSCAN.hpp" +#include "triggeralgs/dbscan/TAMakerDBSCANAlgorithm.hpp" #include "dbscan/Point.hpp" #include "TRACE/trace.h" #include "triggeralgs/Types.hpp" #include #include -#define TRACE_NAME "TriggerActivityMakerDBSCANPlugin" +#define TRACE_NAME "TAMakerDBSCANAlgorithm" #include using namespace triggeralgs; +using Logging::TLVL_DEBUG_LOW; + void -TriggerActivityMakerDBSCAN::process(const TriggerPrimitive& input_tp, std::vector& output_ta) +TAMakerDBSCANAlgorithm::process(const TriggerPrimitive& input_tp, std::vector& output_ta) { - // Collection channels only for now - if(input_tp.channel%2560 < 1600){ - return; - } - if(input_tp.time_start < m_prev_timestamp){ - TLOG(TLVL_INFO) << "Out-of-order TPs: prev " << m_prev_timestamp << ", current " << input_tp.time_start; + TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TAM:DBS] Out-of-order TPs: prev " << m_prev_timestamp << ", current " << input_tp.time_start; return; } @@ -60,34 +57,35 @@ TriggerActivityMakerDBSCAN::process(const TriggerPrimitive& input_tp, std::vecto ta.adc_integral += prim.adc_integral; ta.detid = prim.detid; + if (prim.adc_peak > ta.adc_peak) { + ta.adc_peak = prim.adc_peak; + ta.channel_peak = prim.channel; + ta.time_peak = prim.time_peak; + } } - - ta.time_peak = (ta.time_start+ta.time_end)/2; ta.time_activity = ta.time_peak; - ta.channel_peak = (ta.channel_start+ta.channel_end)/2; - ta.type = TriggerActivity::Type::kTPC; ta.algorithm = TriggerActivity::Algorithm::kDBSCAN; - ta.version = 1; - } m_dbscan->trim_hits(); } void -TriggerActivityMakerDBSCAN::configure(const nlohmann::json& config) +TAMakerDBSCANAlgorithm::configure(const nlohmann::json& config) { TriggerActivityMaker::configure(config); - if (config.is_object() && config.contains("min_pts")) + if (config.is_object()) { - m_min_pts = config["min_pts"]; + if (config.contains("min_pts")) + m_min_pts = config["min_pts"]; + if (config.contains("eps")) + m_eps = config["eps"]; } - - m_dbscan=std::make_unique(10, m_min_pts, 10000); + m_dbscan=std::make_unique(m_eps, m_min_pts, 10000); } // Register algo in TA Factory -REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TriggerActivityMakerDBSCAN) +REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TAMakerDBSCANAlgorithm) diff --git a/src/TAMakerHorizontalMuonAlgorithm.cpp b/src/TAMakerHorizontalMuonAlgorithm.cpp index 9ffdbd9..201d52a 100644 --- a/src/TAMakerHorizontalMuonAlgorithm.cpp +++ b/src/TAMakerHorizontalMuonAlgorithm.cpp @@ -11,9 +11,13 @@ #define TRACE_NAME "TAMakerHorizontalMuonAlgorithm" #include #include +#include using namespace triggeralgs; +using Logging::TLVL_DEBUG_ALL; +using Logging::TLVL_DEBUG_MEDIUM; + void TAMakerHorizontalMuonAlgorithm::process(const TriggerPrimitive& input_tp, std::vector& output_ta) @@ -22,19 +26,18 @@ TAMakerHorizontalMuonAlgorithm::process(const TriggerPrimitive& input_tp, uint16_t adjacency; // Add useful info about recived TPs here for FW and SW TPG guys. - if (m_print_tp_info){ - TLOG(1) << "TP Start Time: " << input_tp.time_start << ", TP ADC Sum: " << input_tp.adc_integral - << ", TP TOT: " << input_tp.time_over_threshold << ", TP ADC Peak: " << input_tp.adc_peak - << ", TP Offline Channel ID: " << input_tp.channel; - TLOG(1) << "Adjacency of current window is: " << check_adjacency(); + if (m_print_tp_info) { + TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:HM] TP Start Time: " << input_tp.time_start + << ", TP ADC Sum: " << input_tp.adc_integral + << ", TP TOT: " << input_tp.time_over_threshold << ", TP ADC Peak: " << input_tp.adc_peak + << ", TP Offline Channel ID: " << input_tp.channel; + TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:HM] Adjacency of current window is: " << check_adjacency(); } - // 0) FIRST TP ===================================================================== // The first time process() is called, reset the window object. if (m_current_window.is_empty()) { m_current_window.reset(input_tp); - m_primitive_count++; return; } @@ -53,8 +56,9 @@ TAMakerHorizontalMuonAlgorithm::process(const TriggerPrimitive& input_tp, auto ta = construct_ta(); - TLOG(1) << "[TA]: Emitting ADC threshold trigger with " << m_current_window.adc_integral << - " window ADC integral. ta.time_start=" << ta.time_start << " ta.time_end=" << ta.time_end; + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TA:HM]: Emitting ADC threshold trigger with " << m_current_window.adc_integral + << " window ADC integral. ta.time_start=" << ta.time_start + << " ta.time_end=" << ta.time_end; output_ta.push_back(ta); m_current_window.reset(input_tp); @@ -67,8 +71,8 @@ TAMakerHorizontalMuonAlgorithm::process(const TriggerPrimitive& input_tp, // on channel multiplicity, make a TA and start a fresh window with the current TP. else if (m_current_window.n_channels_hit() > m_n_channels_threshold && m_trigger_on_n_channels) { - TLOG(1) << "Emitting multiplicity trigger with " << m_current_window.n_channels_hit() << - " unique channels hit."; + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TAM:HM] Emitting multiplicity trigger with " + << m_current_window.n_channels_hit() << " unique channels hit."; output_ta.push_back(construct_ta()); m_current_window.reset(input_tp); @@ -85,44 +89,35 @@ TAMakerHorizontalMuonAlgorithm::process(const TriggerPrimitive& input_tp, // Check for a new maximum, display the largest seen adjacency in the log. // uint16_t adjacency = check_adjacency(); - if (adjacency > m_max_adjacency) { m_max_adjacency = adjacency; } - TLOG_DEBUG(TRACE_NAME) << "Emitting track and multiplicity TA with adjacency " << check_adjacency() << - " and multiplicity " << m_current_window.n_channels_hit() << ". The ADC integral of this TA is " << - m_current_window.adc_integral << " and the largest longest track seen so far is " << m_max_adjacency; + if (adjacency > m_max_adjacency) { + m_max_adjacency = adjacency; + } + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TAM:HM] Emitting track and multiplicity TA with adjacency " + << check_adjacency() << " and multiplicity " << m_current_window.n_channels_hit() + << ". The ADC integral of this TA is " << m_current_window.adc_integral + << " and the largest longest track seen so far is " << m_max_adjacency; output_ta.push_back(construct_ta()); m_current_window.reset(input_tp); } // Temporary triggering logic for Adam's large TOT TPs. Trigger on very large TOT TPs. - else if (m_trigger_on_tot && input_tp.time_over_threshold > m_tot_threshold){ - - // If the incoming TP has a large time over threshold, we might have a cluster of - // interesting physics activity surrounding it. Trigger on that. - TLOG_DEBUG(TRACE_NAME) << "Emitting a TA due to a TP with a very large time over threshold: " - << input_tp.time_over_threshold << " ticks and offline channel: " << input_tp.channel - << ", where the ADC integral of that TP is " << input_tp.adc_integral; - output_ta.push_back(construct_ta()); - m_current_window.reset(input_tp); + else if (m_trigger_on_tot && input_tp.time_over_threshold > m_tot_threshold) { + + // If the incoming TP has a large time over threshold, we might have a cluster of + // interesting physics activity surrounding it. Trigger on that. + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TAM:HM] Emitting a TA due to a TP with a very large time over threshold: " + << input_tp.time_over_threshold << " ticks and offline channel: " << input_tp.channel + << ", where the ADC integral of that TP is " << input_tp.adc_integral; + output_ta.push_back(construct_ta()); + m_current_window.reset(input_tp); } // 4) Otherwise, slide the window along using the current TP. else { - m_current_window.move(input_tp, m_window_length); + m_current_window.move(input_tp, m_window_length); } - using namespace std::chrono; - // If this is the first TP of the run, calculate the initial offset: - if (m_primitive_count == 0){ - m_initial_offset = duration_cast(system_clock::now().time_since_epoch()).count() - input_tp.time_start*16*1e-6; - } - - // Update OpMon Variable(s) - uint64_t system_time = duration_cast(system_clock::now().time_since_epoch()).count(); - uint64_t data_time = input_tp.time_start*16*1e-6; // Convert 62.5 MHz ticks to ms - m_data_vs_system_time.store(fabs(system_time - data_time - m_initial_offset)); // Store the difference for OpMon*/ - m_primitive_count++; - return; } @@ -144,8 +139,8 @@ TAMakerHorizontalMuonAlgorithm::configure(const nlohmann::json& config) m_window_length = config["window_length"]; if (config.contains("trigger_on_adjacency")) m_trigger_on_adjacency = config["trigger_on_adjacency"]; - if (config.contains("adj_tolerance")) - m_adj_tolerance = config["adj_tolerance"]; + if (config.contains("adjacency_tolerance")) + m_adj_tolerance = config["adjacency_tolerance"]; if (config.contains("adjacency_threshold")) m_adjacency_threshold = config["adjacency_threshold"]; if (config.contains("print_tp_info")) @@ -167,7 +162,7 @@ TAMakerHorizontalMuonAlgorithm::construct_ta() const TriggerPrimitive last_tp = m_current_window.inputs.back(); ta.time_start = last_tp.time_start; - ta.time_end = last_tp.time_start+last_tp.time_over_threshold; + ta.time_end = last_tp.time_start + last_tp.time_over_threshold; ta.time_peak = last_tp.time_peak; ta.time_activity = last_tp.time_peak; ta.channel_start = last_tp.channel; @@ -182,10 +177,10 @@ TAMakerHorizontalMuonAlgorithm::construct_ta() const for( const auto& tp : ta.inputs ) { ta.time_start = std::min(ta.time_start, tp.time_start); - ta.time_end = std::max(ta.time_end, tp.time_start+tp.time_over_threshold); + ta.time_end = std::max(ta.time_end, tp.time_start + tp.time_over_threshold); ta.channel_start = std::min(ta.channel_start, tp.channel); ta.channel_end = std::max(ta.channel_end, tp.channel); - if (tp.adc_peak > ta.adc_peak ) { + if (tp.adc_peak > ta.adc_peak) { ta.time_peak = tp.time_peak; ta.adc_peak = tp.adc_peak; ta.channel_peak = tp.channel; @@ -220,9 +215,9 @@ TAMakerHorizontalMuonAlgorithm::check_adjacency() const // ADAJACENCY LOGIC ==================================================================== // ===================================================================================== - // Adjcancency Tolerance = Number of times prepared to skip missed hits before resetting - // the adjacency count. This accounts for things like dead channels / missed TPs. The - // maximum gap is 4 which comes from tuning on December 2021 coldbox data, and June 2022 + // Adjcancency Tolerance = Number of times prepared to skip missed hits before resetting + // the adjacency count. This accounts for things like dead channels / missed TPs. The + // maximum gap is 4 which comes from tuning on December 2021 coldbox data, and June 2022 // coldbox runs. for (int i = 0; i < chanList.size(); ++i) { @@ -231,27 +226,37 @@ TAMakerHorizontalMuonAlgorithm::check_adjacency() const next_channel = chanList.at(next); // Next channel with a hit // End of vector condition. - if (next_channel == 0) { next_channel = channel - 1; } + if (next_channel == 0) { + next_channel = channel - 1; + } // Skip same channel hits. - if (next_channel == channel) { continue; } + if (next_channel == channel) { + continue; + } // If next hit is on next channel, increment the adjacency count. - else if (next_channel == channel + 1){ ++adj; } + else if (next_channel == channel + 1) { + ++adj; + } - // If next channel is not on the next hit, but the 'second next', increase adjacency + // If next channel is not on the next hit, but the 'second next', increase adjacency // but also tally up with the tolerance counter. - else if (((next_channel == channel + 2) || (next_channel == channel + 3) || - (next_channel == channel + 4) || (next_channel == channel + 5)) - && (tol_count < m_adj_tolerance)) { + else if (((next_channel == channel + 2) || (next_channel == channel + 3) || (next_channel == channel + 4) || + (next_channel == channel + 5)) && + (tol_count < m_adj_tolerance)) { ++adj; - for (int i = 0 ; i < next_channel-channel ; ++i){ ++tol_count; } + for (int i = 0; i < next_channel - channel; ++i) { + ++tol_count; + } } // If next hit isn't within reach, end the adjacency count and check for a new max. // Reset variables for next iteration. else { - if (adj > max) { max = adj; } + if (adj > max) { + max = adj; + } adj = 1; tol_count = 0; } @@ -304,14 +309,14 @@ TAMakerHorizontalMuonAlgorithm::dump_tp(TriggerPrimitive const& input_tp) outfile.open("coldbox_tps.txt", std::ios_base::app); // Output relevant TP information to file - outfile << input_tp.time_start << " "; + outfile << input_tp.time_start << " "; outfile << input_tp.time_over_threshold << " "; // 50MHz ticks - outfile << input_tp.time_peak << " "; - outfile << input_tp.channel << " "; // Offline channel ID - outfile << input_tp.adc_integral << " "; - outfile << input_tp.adc_peak << " "; - outfile << input_tp.detid << " "; // Det ID - Identifies detector element - outfile << input_tp.type << std::endl; + outfile << input_tp.time_peak << " "; + outfile << input_tp.channel << " "; // Offline channel ID + outfile << input_tp.adc_integral << " "; + outfile << input_tp.adc_peak << " "; + outfile << input_tp.detid << " "; // Det ID - Identifies detector element + outfile << input_tp.type << std::endl; outfile.close(); return; @@ -322,7 +327,7 @@ TAMakerHorizontalMuonAlgorithm::check_tot() const { // Here, we just want to sum up all the tot values for each TP within window, // and return this tot of the window. - int window_tot = 0; + int window_tot = 0; for (auto tp : m_current_window.inputs) { window_tot += tp.time_over_threshold; } diff --git a/src/TriggerActivityMakerMichelElectron.cpp b/src/TAMakerMichelElectronAlgorithm.cpp similarity index 89% rename from src/TriggerActivityMakerMichelElectron.cpp rename to src/TAMakerMichelElectronAlgorithm.cpp index 8f0e83a..0e32d6f 100644 --- a/src/TriggerActivityMakerMichelElectron.cpp +++ b/src/TAMakerMichelElectronAlgorithm.cpp @@ -1,21 +1,23 @@ /** - * @file TriggerActivityMakerMichelElectron.cpp + * @file TAMakerMichelElectronAlgorithm.cpp * * This is part of the DUNE DAQ Application Framework, copyright 2021. * Licensing/copyright details are in the COPYING file that you should have * received with this code. */ -#include "triggeralgs/MichelElectron/TriggerActivityMakerMichelElectron.hpp" +#include "triggeralgs/MichelElectron/TAMakerMichelElectronAlgorithm.hpp" #include "TRACE/trace.h" -#define TRACE_NAME "TriggerActivityMakerMichelElectronPlugin" +#define TRACE_NAME "TAMakerMichelElectronAlgorithm" #include #include using namespace triggeralgs; +using Logging::TLVL_DEBUG_MEDIUM; + void -TriggerActivityMakerMichelElectron::process(const TriggerPrimitive& input_tp, +TAMakerMichelElectronAlgorithm::process(const TriggerPrimitive& input_tp, std::vector& output_ta) { @@ -43,7 +45,7 @@ TriggerActivityMakerMichelElectron::process(const TriggerPrimitive& input_tp, if (check_bragg_peak(trackHits)){ if (check_kinks(trackHits)){ - TLOG(1) << "Emitting a trigger for candidate Michel event."; + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TAM:ME] Emitting a trigger for candidate Michel event."; output_ta.push_back(construct_ta()); m_current_window.reset(input_tp); } // Kinks @@ -61,26 +63,16 @@ TriggerActivityMakerMichelElectron::process(const TriggerPrimitive& input_tp, } void -TriggerActivityMakerMichelElectron::configure(const nlohmann::json& config) +TAMakerMichelElectronAlgorithm::configure(const nlohmann::json& config) { TriggerActivityMaker::configure(config); // FIX ME: Use some schema here. Also can't work out how to pass booleans. if (config.is_object()) { - if (config.contains("trigger_on_adc")) - m_trigger_on_adc = config["trigger_on_adc"]; - if (config.contains("trigger_on_n_channels")) - m_trigger_on_n_channels = config["trigger_on_n_channels"]; - if (config.contains("adc_threshold")) - m_adc_threshold = config["adc_threshold"]; - if (config.contains("n_channels_threshold")) - m_n_channels_threshold = config["n_channels_threshold"]; if (config.contains("window_length")) m_window_length = config["window_length"]; - if (config.contains("trigger_on_adjacency")) - m_trigger_on_adjacency = config["trigger_on_adjacency"]; - if (config.contains("adj_tolerance")) - m_adj_tolerance = config["adj_tolerance"]; + if (config.contains("adjacency_tolerance")) + m_adj_tolerance = config["adjacency_tolerance"]; if (config.contains("adjacency_threshold")) m_adjacency_threshold = config["adjacency_threshold"]; } @@ -88,7 +80,7 @@ TriggerActivityMakerMichelElectron::configure(const nlohmann::json& config) } TriggerActivity -TriggerActivityMakerMichelElectron::construct_ta() const +TAMakerMichelElectronAlgorithm::construct_ta() const { TriggerPrimitive latest_tp_in_window = m_current_window.inputs.back(); @@ -112,7 +104,7 @@ TriggerActivityMakerMichelElectron::construct_ta() const } std::vector -TriggerActivityMakerMichelElectron::longest_activity() const +TAMakerMichelElectronAlgorithm::longest_activity() const { // This function attempts to return a vector of hits that correspond to the longest // piece of activity in the current window. The logic follows that from the HMA @@ -198,7 +190,7 @@ TriggerActivityMakerMichelElectron::longest_activity() const // count up clusters of charge deposition above that baseline. If the largest is at // one of the ends of that collection, signal a potential Bragg peak. bool -TriggerActivityMakerMichelElectron::check_bragg_peak(std::vector trackHits) +TAMakerMichelElectronAlgorithm::check_bragg_peak(std::vector trackHits) { bool bragg = false; std::vector adc_means_list; @@ -244,7 +236,7 @@ TriggerActivityMakerMichelElectron::check_bragg_peak(std::vector finalHits) +TAMakerMichelElectronAlgorithm::check_kinks(std::vector finalHits) { bool kinks = false; // We actually required two kinks in the coldbox, the michel kink and the wes kink std::vector runningGradient; @@ -309,7 +301,7 @@ TriggerActivityMakerMichelElectron::check_kinks(std::vector fi // =============================================================================================== void -TriggerActivityMakerMichelElectron::add_window_to_record(Window window) +TAMakerMichelElectronAlgorithm::add_window_to_record(Window window) { m_window_record.push_back(window); return; @@ -318,7 +310,7 @@ TriggerActivityMakerMichelElectron::add_window_to_record(Window window) // Function to dump the details of the TA window currently on record void -TriggerActivityMakerMichelElectron::dump_window_record() +TAMakerMichelElectronAlgorithm::dump_window_record() { // FIX ME: Need to index this outfile in the name by detid or something similar. std::ofstream outfile; @@ -345,7 +337,7 @@ TriggerActivityMakerMichelElectron::dump_window_record() // Function to add current TP details to a text file for testing and debugging. void -TriggerActivityMakerMichelElectron::dump_tp(TriggerPrimitive const& input_tp) +TAMakerMichelElectronAlgorithm::dump_tp(TriggerPrimitive const& input_tp) { std::ofstream outfile; outfile.open("coldbox_tps.txt", std::ios_base::app); @@ -366,7 +358,7 @@ TriggerActivityMakerMichelElectron::dump_tp(TriggerPrimitive const& input_tp) /* void -TriggerActivityMakerMichelElectron::flush(timestamp_t, std::vector& output_ta) +TAMakerMichelElectronAlgorithm::flush(timestamp_t, std::vector& output_ta) { // Check the status of the current window, construct TA if conditions are met. Regardless // of whether the conditions are met, reset the window. @@ -388,4 +380,4 @@ reset."; m_current_window.clear(); }*/ // Register algo in TA Factory -REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TriggerActivityMakerMichelElectron) +REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TAMakerMichelElectronAlgorithm) diff --git a/src/TriggerActivityMakerPlaneCoincidence.cpp b/src/TAMakerPlaneCoincidenceAlgorithm.cpp similarity index 87% rename from src/TriggerActivityMakerPlaneCoincidence.cpp rename to src/TAMakerPlaneCoincidenceAlgorithm.cpp index c1e7da7..35f3f85 100644 --- a/src/TriggerActivityMakerPlaneCoincidence.cpp +++ b/src/TAMakerPlaneCoincidenceAlgorithm.cpp @@ -1,20 +1,22 @@ /** - * @file TriggerActivityMakerPlaneCoincidence.cpp + * @file TAMakerPlaneCoincidenceAlgorithm.cpp * * This is part of the DUNE DAQ Application Framework, copyright 2021. * Licensing/copyright details are in the COPYING file that you should have * received with this code. */ -#include "triggeralgs/PlaneCoincidence/TriggerActivityMakerPlaneCoincidence.hpp" +#include "triggeralgs/PlaneCoincidence/TAMakerPlaneCoincidenceAlgorithm.hpp" #include "TRACE/trace.h" -#define TRACE_NAME "TriggerActivityMakerPlaneCoincidencePlugin" +#define TRACE_NAME "TAMakerPlaneCoincidenceAlgorithm" #include using namespace triggeralgs; +using Logging::TLVL_DEBUG_MEDIUM; + void -TriggerActivityMakerPlaneCoincidence::process(const TriggerPrimitive& input_tp, std::vector& output_ta) +TAMakerPlaneCoincidenceAlgorithm::process(const TriggerPrimitive& input_tp, std::vector& output_ta) { // Get the plane from which this hit arrived: @@ -60,7 +62,7 @@ TriggerActivityMakerPlaneCoincidence::process(const TriggerPrimitive& input_tp, else if (collectionComplete && (m_induction1_window.adc_integral + m_induction2_window.adc_integral + m_collection_window.adc_integral) > m_adc_threshold && check_adjacency(m_collection_window) >= m_adjacency_threshold){ - TLOG(1) << "Emitting low energy trigger with " << m_induction1_window.adc_integral << " U " + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TAM:PC] Emitting low energy trigger with " << m_induction1_window.adc_integral << " U " << m_induction2_window.adc_integral << " Y induction ADC sums and " << check_adjacency(m_collection_window) << " adjacent collection hits."; @@ -95,25 +97,17 @@ TriggerActivityMakerPlaneCoincidence::process(const TriggerPrimitive& input_tp, } void -TriggerActivityMakerPlaneCoincidence::configure(const nlohmann::json& config) +TAMakerPlaneCoincidenceAlgorithm::configure(const nlohmann::json& config) { TriggerActivityMaker::configure(config); if (config.is_object()) { - if (config.contains("trigger_on_adc")) - m_trigger_on_adc = config["trigger_on_adc"]; - if (config.contains("trigger_on_n_channels")) - m_trigger_on_n_channels = config["trigger_on_n_channels"]; if (config.contains("adc_threshold")) m_adc_threshold = config["adc_threshold"]; - if (config.contains("n_channels_threshold")) - m_n_channels_threshold = config["n_channels_threshold"]; if (config.contains("window_length")) m_window_length = config["window_length"]; - if (config.contains("trigger_on_adjacency")) - m_trigger_on_adjacency = config["trigger_on_adjacency"]; - if (config.contains("adj_tolerance")) - m_adj_tolerance = config["adj_tolerance"]; + if (config.contains("adjacency_tolerance")) + m_adj_tolerance = config["adjacency_tolerance"]; if (config.contains("adjacency_threshold")) m_adjacency_threshold = config["adjacency_threshold"]; } @@ -121,7 +115,7 @@ TriggerActivityMakerPlaneCoincidence::configure(const nlohmann::json& config) } TriggerActivity -TriggerActivityMakerPlaneCoincidence::construct_ta(TPWindow m_current_window) const +TAMakerPlaneCoincidenceAlgorithm::construct_ta(TPWindow m_current_window) const { TriggerPrimitive latest_tp_in_window = m_current_window.inputs.back(); @@ -145,7 +139,7 @@ TriggerActivityMakerPlaneCoincidence::construct_ta(TPWindow m_current_window) co } uint16_t -TriggerActivityMakerPlaneCoincidence::check_adjacency(TPWindow window) const +TAMakerPlaneCoincidenceAlgorithm::check_adjacency(TPWindow window) const { /* This function returns the adjacency value for the current window, where adjacency * is defined as the maximum number of consecutive wires containing hits. It accepts @@ -207,7 +201,7 @@ TriggerActivityMakerPlaneCoincidence::check_adjacency(TPWindow window) const // Functions below this line are for debugging and performance study purposes. // ===================================================================================== void -TriggerActivityMakerPlaneCoincidence::add_window_to_record(TPWindow window) +TAMakerPlaneCoincidenceAlgorithm::add_window_to_record(TPWindow window) { m_window_record.push_back(window); return; @@ -215,7 +209,7 @@ TriggerActivityMakerPlaneCoincidence::add_window_to_record(TPWindow window) // Function to dump the details of the TA window currently on record void -TriggerActivityMakerPlaneCoincidence::dump_window_record() +TAMakerPlaneCoincidenceAlgorithm::dump_window_record() { std::ofstream outfile; outfile.open("window_record_tam.csv", std::ios_base::app); @@ -243,7 +237,7 @@ TriggerActivityMakerPlaneCoincidence::dump_window_record() // Function to add current TP details to a text file for testing and debugging. void -TriggerActivityMakerPlaneCoincidence::dump_tp(TriggerPrimitive const& input_tp) +TAMakerPlaneCoincidenceAlgorithm::dump_tp(TriggerPrimitive const& input_tp) { std::ofstream outfile; outfile.open("triggered_coldbox_tps.txt", std::ios_base::app); @@ -263,7 +257,7 @@ TriggerActivityMakerPlaneCoincidence::dump_tp(TriggerPrimitive const& input_tp) } int -TriggerActivityMakerPlaneCoincidence::check_tot(TPWindow m_current_window) const +TAMakerPlaneCoincidenceAlgorithm::check_tot(TPWindow m_current_window) const { // Here, we just want to sum up all the tot values for each TP within window, // and return this tot of the window. @@ -276,5 +270,5 @@ TriggerActivityMakerPlaneCoincidence::check_tot(TPWindow m_current_window) const } // Regiser algo in TA Factory -REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TriggerActivityMakerPlaneCoincidence) +REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TAMakerPlaneCoincidenceAlgorithm) // END OF TA MAKER - LOW ENERGY EVENTS diff --git a/src/TAMakerPrescaleAlgorithm.cpp b/src/TAMakerPrescaleAlgorithm.cpp index 51bacae..1fc0311 100644 --- a/src/TAMakerPrescaleAlgorithm.cpp +++ b/src/TAMakerPrescaleAlgorithm.cpp @@ -15,36 +15,32 @@ using namespace triggeralgs; +using Logging::TLVL_DEBUG_MEDIUM; +using Logging::TLVL_IMPORTANT; + void TAMakerPrescaleAlgorithm::process(const TriggerPrimitive& input_tp, std::vector& output_ta) { - std::vector tp_list; - tp_list.push_back(input_tp); - - TriggerActivity ta; - ta.time_start = input_tp.time_start; - ta.time_end = input_tp.time_start + input_tp.time_over_threshold; - ta.time_peak = input_tp.time_peak; - ta.time_activity = 0; - ta.channel_start = input_tp.channel; - ta.channel_end = input_tp.channel; - ta.channel_peak = input_tp.channel; - ta.adc_integral = input_tp.adc_integral; - ta.adc_peak = input_tp.adc_peak; - ta.detid = input_tp.detid; - ta.type = TriggerActivity::Type::kTPC; - ta.algorithm = TriggerActivity::Algorithm::kPrescale; - - ta.inputs = tp_list; - - using namespace std::chrono; - - // Update OpMon Variable(s) - uint64_t system_time = duration_cast(system_clock::now().time_since_epoch()).count(); - uint64_t data_time = ta.time_start*16e-6; // Convert 62.5 MHz ticks to ms - m_data_vs_system_time.store(data_time - system_time); // Store the difference for OpMon - - output_ta.push_back(ta); + std::vector tp_list; + tp_list.push_back(input_tp); + + TriggerActivity ta; + ta.time_start = input_tp.time_start; + ta.time_end = input_tp.time_start + input_tp.time_over_threshold; + ta.time_peak = input_tp.time_peak; + ta.time_activity = 0; + ta.channel_start = input_tp.channel; + ta.channel_end = input_tp.channel; + ta.channel_peak = input_tp.channel; + ta.adc_integral = input_tp.adc_integral; + ta.adc_peak = input_tp.adc_peak; + ta.detid = input_tp.detid; + ta.type = TriggerActivity::Type::kTPC; + ta.algorithm = TriggerActivity::Algorithm::kPrescale; + + ta.inputs = tp_list; + + output_ta.push_back(ta); } void diff --git a/src/TriggerActivityMakerSupernova.cpp b/src/TAMakerSupernovaAlgorithm.cpp similarity index 86% rename from src/TriggerActivityMakerSupernova.cpp rename to src/TAMakerSupernovaAlgorithm.cpp index c0b524a..acd0a2d 100644 --- a/src/TriggerActivityMakerSupernova.cpp +++ b/src/TAMakerSupernovaAlgorithm.cpp @@ -1,15 +1,15 @@ /** - * @file TriggerActivityMakerSupernova.cpp + * @file TAMakerSupernovaAlgorithm.cpp * * This is part of the DUNE DAQ Application Framework, copyright 2020. * Licensing/copyright details are in the COPYING file that you should have * received with this code. */ -#include "triggeralgs/Supernova/TriggerActivityMakerSupernova.hpp" +#include "triggeralgs/Supernova/TAMakerSupernovaAlgorithm.hpp" #include "TRACE/trace.h" -#define TRACE_NAME "TriggerActivityMakerSupernovaPlugin" +#define TRACE_NAME "TAMakerSupernovaAlgorithm" #include #include @@ -18,7 +18,7 @@ using pd_clock = std::chrono::duration>; using namespace triggeralgs; void -TriggerActivityMakerSupernova::process(const TriggerPrimitive& input_tp, std::vector& output_ta) +TAMakerSupernovaAlgorithm::process(const TriggerPrimitive& input_tp, std::vector& output_ta) { // Time measurement // auto now = std::chrono::steady_clock::now(); @@ -84,4 +84,4 @@ TriggerActivityMakerSupernova::process(const TriggerPrimitive& input_tp, std::ve } // Register algo in TA Factory -REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TriggerActivityMakerSupernova) +REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TAMakerSupernovaAlgorithm) diff --git a/src/TCMakerBundleNAlgorithm.cpp b/src/TCMakerBundleNAlgorithm.cpp new file mode 100644 index 0000000..17502f4 --- /dev/null +++ b/src/TCMakerBundleNAlgorithm.cpp @@ -0,0 +1,73 @@ +/** + * @file TCMakerBundleNAlgorithm.cpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2020. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#include "triggeralgs/BundleN/TCMakerBundleNAlgorithm.hpp" + +#include "TRACE/trace.h" +#define TRACE_NAME "TCMakerBundleNAlgorithm" + +namespace triggeralgs { + +using Logging::TLVL_IMPORTANT; +using Logging::TLVL_DEBUG_HIGH; + +void TCMakerBundleNAlgorithm::set_tc_attributes() { + // Using the first TA as reference. + dunedaq::trgdataformats::TriggerActivityData front_ta = m_current_tc.inputs.front(); + + m_current_tc.time_start = front_ta.time_start; + m_current_tc.time_end = m_current_tc.inputs.back().time_end; + m_current_tc.time_candidate = front_ta.time_start; // TODO: Conforming. Do we change this? + m_current_tc.detid = front_ta.detid; + m_current_tc.type = TriggerCandidate::Type::kBundle; + m_current_tc.algorithm = TriggerCandidate::Algorithm::kBundle; + return; +} + +bool TCMakerBundleNAlgorithm::bundle_condition() { + return m_current_tc.inputs.size() == m_bundle_size; +} + +void +TCMakerBundleNAlgorithm::process(const TriggerActivity& input_ta, std::vector& output_tcs) +{ + // Expect that TAs are inherently time ordered. + m_current_tc.inputs.push_back(input_ta); + + if (bundle_condition()) { + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TC:BN] Emitting BundleN TriggerCandidate with " << m_current_tc.inputs.size() << " TAs."; + set_tc_attributes(); + output_tcs.push_back(m_current_tc); + + // Reset the current. + m_current_tc = TriggerCandidate(); + } + + // Should never reach this step. In this case, send it out. + if (m_current_tc.inputs.size() > m_bundle_size) { + TLOG_DEBUG(TLVL_IMPORTANT) << "[TC:BN] Emitting large BundleN TriggerCandidate with " << m_current_tc.inputs.size() << " TAs."; + set_tc_attributes(); + output_tcs.push_back(m_current_tc); + + // Reset the current. + m_current_tc = TriggerCandidate(); + } +} + +void +TCMakerBundleNAlgorithm::configure(const nlohmann::json& config) +{ + TriggerCandidateMaker::configure(config); + if (config.is_object() && config.contains("bundle_size")) { + m_bundle_size = config["bundle_size"]; + } +} + +REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerBundleNAlgorithm) +} // namespace triggeralgs + diff --git a/src/TCMakerChannelAdjacencyAlgorithm.cpp b/src/TCMakerChannelAdjacencyAlgorithm.cpp new file mode 100644 index 0000000..2daeb5f --- /dev/null +++ b/src/TCMakerChannelAdjacencyAlgorithm.cpp @@ -0,0 +1,143 @@ +/** + * @file TCMakerChannelAdjacencyAlgorithm.cpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#include "triggeralgs/ChannelAdjacency/TCMakerChannelAdjacencyAlgorithm.hpp" +#include "triggeralgs/Logging.hpp" + +#include "TRACE/trace.h" +#define TRACE_NAME "TCMakerChannelAdjacencyAlgorithm" + +#include +#include + +using namespace triggeralgs; + +using Logging::TLVL_DEBUG_ALL; +using Logging::TLVL_DEBUG_HIGH; +using Logging::TLVL_DEBUG_MEDIUM; +using Logging::TLVL_VERY_IMPORTANT; + +void +TCMakerChannelAdjacencyAlgorithm::process(const TriggerActivity& activity, + std::vector& output_tc) +{ + + // The first time process() is called, reset window object. + if (m_current_window.is_empty()) { + m_current_window.reset(activity); + m_activity_count++; + } + + // If the difference between the current TA's start time and the start of the window + // is less than the specified window size, add the TA to the window. + else if ((activity.time_start - m_current_window.time_start) < m_window_length) { + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:CA] Window not yet complete, adding the activity to the window."; + m_current_window.add(activity); + } + // If it is not, move the window along. + else { + TLOG_DEBUG(TLVL_DEBUG_ALL) + << "[TCM:CA] TAWindow is at required length but specified threshold not met, shifting window along."; + m_current_window.move(activity, m_window_length); + } + + // If the addition of the current TA to the window would make it longer + // than the specified window length, don't add it but check whether the sum of all adc in + // the existing window is above the specified threshold. If it is, and we are triggering on ADC, + // make a TA and start a fresh window with the current TP. + if (m_current_window.adc_integral > m_adc_threshold && m_trigger_on_adc) { + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TCM:CA] m_current_window.adc_integral " << m_current_window.adc_integral + << " - m_adc_threshold " << m_adc_threshold; + TriggerCandidate tc = construct_tc(); + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TCM:CA] tc.time_start=" << tc.time_start << " tc.time_end=" << tc.time_end + << " len(tc.inputs) " << tc.inputs.size(); + + for (const auto& ta : tc.inputs) { + TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TCM:CA] [TA] ta.time_start=" << ta.time_start << " ta.time_end=" << ta.time_end + << " ta.adc_integral=" << ta.adc_integral; + } + + output_tc.push_back(tc); + m_current_window.clear(); + } + + // If the addition of the current TA to the window would make it longer + // than the specified window length, don't add it but check whether the number of hit channels in + // the existing window is above the specified threshold. If it is, and we are triggering on channels, + // make a TC and start a fresh window with the current TA. + else if (m_current_window.n_channels_hit() > m_n_channels_threshold && m_trigger_on_n_channels) { + output_tc.push_back(construct_tc()); + m_current_window.clear(); + } + + m_activity_count++; + return; +} + +void +TCMakerChannelAdjacencyAlgorithm::configure(const nlohmann::json& config) +{ + TriggerCandidateMaker::configure(config); + + if (config.is_object()) { + if (config.contains("trigger_on_adc")) + m_trigger_on_adc = config["trigger_on_adc"]; + if (config.contains("trigger_on_n_channels")) + m_trigger_on_n_channels = config["trigger_on_n_channels"]; + if (config.contains("adc_threshold")) + m_adc_threshold = config["adc_threshold"]; + if (config.contains("n_channels_threshold")) + m_n_channels_threshold = config["n_channels_threshold"]; + if (config.contains("window_length")) + m_window_length = config["window_length"]; + } + + // Both trigger flags were false. This will never trigger. + if (!m_trigger_on_adc && !m_trigger_on_n_channels) { + TLOG_DEBUG(TLVL_VERY_IMPORTANT) << "[TCM:CA] Not triggering! All trigger flags are false!"; + throw BadConfiguration(ERS_HERE, TRACE_NAME); + } + + return; +} + +TriggerCandidate +TCMakerChannelAdjacencyAlgorithm::construct_tc() const +{ + TriggerActivity latest_ta_in_window = m_current_window.inputs.back(); + + TriggerCandidate tc; + tc.time_start = m_current_window.time_start; + tc.time_end = latest_ta_in_window.inputs.back().time_start; + tc.time_candidate = m_current_window.time_start; + tc.detid = latest_ta_in_window.detid; + tc.type = TriggerCandidate::Type::kChannelAdjacency; + tc.algorithm = TriggerCandidate::Algorithm::kChannelAdjacency; + + // Take the list of triggeralgs::TriggerActivity in the current + // window and convert them (implicitly) to detdataformats' + // TriggerActivityData, which is the base class of TriggerActivity + for (auto& ta : m_current_window.inputs) { + tc.inputs.push_back(ta); + if (ta.time_end > tc.time_end) { + tc.time_end = ta.time_end; + } + } + + return tc; +} + +// Functions below this line are for debugging purposes. +void +TCMakerChannelAdjacencyAlgorithm::add_window_to_record(TAWindow window) +{ + m_window_record.push_back(window); + return; +} + +REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerChannelAdjacencyAlgorithm) diff --git a/src/TCMakerChannelDistanceAlgorithm.cpp b/src/TCMakerChannelDistanceAlgorithm.cpp new file mode 100644 index 0000000..bb0e8bc --- /dev/null +++ b/src/TCMakerChannelDistanceAlgorithm.cpp @@ -0,0 +1,80 @@ +/** + * @file TCMakerChannelDistanceAlgorithm.cpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#include "triggeralgs/ChannelDistance/TCMakerChannelDistanceAlgorithm.hpp" + +#include "TRACE/trace.h" +#define TRACE_NAME "TCMakerChannelDistanceAlgorithm" + +namespace triggeralgs { + +void +TCMakerChannelDistanceAlgorithm::set_new_tc(const TriggerActivity& input_ta) +{ + m_current_tc = TriggerCandidate(); + m_current_tc.inputs.push_back(input_ta); + m_current_tp_count = input_ta.inputs.size(); + return; +} + +void +TCMakerChannelDistanceAlgorithm::configure(const nlohmann::json& config) +{ + TriggerCandidateMaker::configure(config); + + if (config.contains("max_tp_count")) + m_max_tp_count = config["max_tp_count"]; + return; +} + +void +TCMakerChannelDistanceAlgorithm::set_tc_attributes() +{ + auto& first_ta = m_current_tc.inputs.front(); + auto& last_ta = m_current_tc.inputs.back(); + + m_current_tc.time_start = first_ta.time_start; + m_current_tc.time_end = last_ta.time_end; + m_current_tc.time_candidate = last_ta.time_start; // Since this is the TA that closed the TC. + + m_current_tc.detid = first_ta.detid; + m_current_tc.algorithm = TriggerCandidate::Algorithm::kChannelDistance; + m_current_tc.type = TriggerCandidate::Type::kChannelDistance; + return; +} + +void +TCMakerChannelDistanceAlgorithm::process(const TriggerActivity& input_ta, + std::vector& output_tcs) +{ + + // Start a new TC if not already going. + if (m_current_tc.inputs.empty()) { + set_new_tc(input_ta); + return; + } + + // Check to close the TC based on TP contents. + if (input_ta.inputs.size() + m_current_tp_count > m_max_tp_count) { + set_tc_attributes(); + output_tcs.push_back(m_current_tc); + + set_new_tc(input_ta); + return; + } + + // Append the new TA and increase the TP count. + m_current_tc.inputs.push_back(input_ta); + m_current_tp_count += input_ta.inputs.size(); + return; +} + +// Register algo in TC Factory +REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerChannelDistanceAlgorithm) + +} // namespace triggeralgs diff --git a/src/TCMakerDBSCANAlgorithm.cpp b/src/TCMakerDBSCANAlgorithm.cpp new file mode 100644 index 0000000..b3716a4 --- /dev/null +++ b/src/TCMakerDBSCANAlgorithm.cpp @@ -0,0 +1,77 @@ +/** + * @file TCMakerDBSCANAlgorithm.cpp + * + * This is part of the DUNE DAQ Application Framework, copyright 2021. + * Licensing/copyright details are in the COPYING file that you should have + * received with this code. + */ + +#include "triggeralgs/dbscan/TCMakerDBSCANAlgorithm.hpp" + +#include "TRACE/trace.h" +#define TRACE_NAME "TCMakerDBSCANAlgorithm" + +namespace triggeralgs { + +void +TCMakerDBSCANAlgorithm::set_new_tc(const TriggerActivity& input_ta) +{ + m_current_tc = TriggerCandidate(); + m_current_tc.inputs.push_back(input_ta); + m_current_tp_count = input_ta.inputs.size(); + return; +} + +void +TCMakerDBSCANAlgorithm::configure(const nlohmann::json& config) +{ + TriggerCandidateMaker::configure(config); + + if (config.contains("max_tp_count")) + m_max_tp_count = config["max_tp_count"]; + return; +} + +void +TCMakerDBSCANAlgorithm::set_tc_attributes() +{ + auto& first_ta = m_current_tc.inputs.front(); + auto& last_ta = m_current_tc.inputs.back(); + + m_current_tc.time_start = first_ta.time_start; + m_current_tc.time_end = last_ta.time_end; + m_current_tc.time_candidate = last_ta.time_start; // Since this is the TA that closed the TC. + + m_current_tc.detid = first_ta.detid; + m_current_tc.algorithm = TriggerCandidate::Algorithm::kDBSCAN; + m_current_tc.type = TriggerCandidate::Type::kDBSCAN; + return; +} + +void +TCMakerDBSCANAlgorithm::process(const TriggerActivity& input_ta, std::vector& output_tcs) +{ + // Start a new TC if not already going. + if (m_current_tc.inputs.empty()) { + set_new_tc(input_ta); + return; + } + + // Check to close the TC based on TP contents. + if (input_ta.inputs.size() + m_current_tp_count > m_max_tp_count) { + set_tc_attributes(); + output_tcs.push_back(m_current_tc); + set_new_tc(input_ta); + return; + } + + // Append the new TA and increase the TP count. + m_current_tc.inputs.push_back(input_ta); + m_current_tp_count += input_ta.inputs.size(); + return; +} + +// Register algo in TC Factory. +REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerDBSCANAlgorithm) + +} // namespace triggeralgs diff --git a/src/TCMakerHorizontalMuonAlgorithm.cpp b/src/TCMakerHorizontalMuonAlgorithm.cpp index 47f241a..37f59df 100644 --- a/src/TCMakerHorizontalMuonAlgorithm.cpp +++ b/src/TCMakerHorizontalMuonAlgorithm.cpp @@ -11,10 +11,15 @@ #include "TRACE/trace.h" #define TRACE_NAME "TCMakerHorizontalMuonAlgorithm" -#include #include +#include + using namespace triggeralgs; +using Logging::TLVL_DEBUG_ALL; +using Logging::TLVL_DEBUG_HIGH; +using Logging::TLVL_DEBUG_MEDIUM; + void TCMakerHorizontalMuonAlgorithm::process(const TriggerActivity& activity, std::vector& output_tc) @@ -23,12 +28,6 @@ TCMakerHorizontalMuonAlgorithm::process(const TriggerActivity& activity, std::vector ta_list = { static_cast( activity) }; - // Find the offset for the very first data vs system time measure: - if (m_activity_count == 0) { - using namespace std::chrono; - m_initial_offset = duration_cast(system_clock::now().time_since_epoch()).count() - activity.time_start*16*1e-6; - } - // The first time operator is called, reset window object. if (m_current_window.is_empty()) { m_current_window.reset(activity); @@ -37,13 +36,6 @@ TCMakerHorizontalMuonAlgorithm::process(const TriggerActivity& activity, // TriggerCandidate tc = construct_tc(); // output_tc.push_back(tc); - // using namespace std::chrono; - - // // Update OpMon Variable(s) - // uint64_t system_time = duration_cast(system_clock::now().time_since_epoch()).count(); - // uint64_t data_time = m_current_window.time_start*16*1e-6; // Convert 62.5 MHz ticks to ms - // m_data_vs_system_time.store(fabs(system_time - data_time - m_initial_offset)); // Store the difference for OpMon - // m_current_window.clear(); // return; } @@ -51,28 +43,32 @@ TCMakerHorizontalMuonAlgorithm::process(const TriggerActivity& activity, // If the difference between the current TA's start time and the start of the window // is less than the specified window size, add the TA to the window. else if ((activity.time_start - m_current_window.time_start) < m_window_length) { - // TLOG_DEBUG(TRACE_NAME) << "Window not yet complete, adding the activity to the window."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:HM] Window not yet complete, adding the activity to the window."; m_current_window.add(activity); } // If it is not, move the window along. else { - // TLOG_DEBUG(TRACE_NAME) << "TAWindow is at required length but specified threshold not met, shifting window along."; + TLOG_DEBUG(TLVL_DEBUG_ALL) + << "[TCM:HM] TAWindow is at required length but specified threshold not met, shifting window along."; m_current_window.move(activity, m_window_length); } - // If the addition of the current TA to the window would make it longer // than the specified window length, don't add it but check whether the sum of all adc in // the existing window is above the specified threshold. If it is, and we are triggering on ADC, // make a TA and start a fresh window with the current TP. if (m_current_window.adc_integral > m_adc_threshold && m_trigger_on_adc) { // TLOG_DEBUG(TRACE_NAME) << "ADC integral in window is greater than specified threshold."; - TLOG() << "[TCHM] m_current_window.adc_integral " << m_current_window.adc_integral << " - m_adc_threshold " << m_adc_threshold; + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TCM:HM] m_current_window.adc_integral " << m_current_window.adc_integral + << " - m_adc_threshold " << m_adc_threshold; tc_number++; TriggerCandidate tc = construct_tc(); - TLOG() << "[TCHM] tc.time_start=" << tc.time_start << " tc.time_end=" << tc.time_end << " len(tc.inputs) " << tc.inputs.size(); - for( const auto& ta : tc.inputs ) { - TLOG() << "[TCHM][TA] ta.time_start=" << ta.time_start << " ta.time_end=" << ta.time_end << " ta.adc_integral=" << ta.adc_integral; + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TCM:HM] tc.time_start=" << tc.time_start << " tc.time_end=" << tc.time_end + << " len(tc.inputs) " << tc.inputs.size(); + + for (const auto& ta : tc.inputs) { + TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TCM:HM] [TA] ta.time_start=" << ta.time_start << " ta.time_end=" << ta.time_end + << " ta.adc_integral=" << ta.adc_integral; } output_tc.push_back(tc); @@ -87,13 +83,15 @@ TCMakerHorizontalMuonAlgorithm::process(const TriggerActivity& activity, else if (m_current_window.n_channels_hit() > m_n_channels_threshold && m_trigger_on_n_channels) { tc_number++; output_tc.push_back(construct_tc()); + // m_current_window.reset(activity); m_current_window.clear(); } // // If it is not, move the window along. // else { - // // TLOG_DEBUG(TRACE_NAME) << "TAWindow is at required length but specified threshold not met, shifting window along."; + // // TLOG_DEBUG(TRACE_NAME) << "TAWindow is at required length but specified threshold not met." + // // << "shifting window along."; // m_current_window.move(activity, m_window_length); // } @@ -101,7 +99,6 @@ TCMakerHorizontalMuonAlgorithm::process(const TriggerActivity& activity, return; } - void TCMakerHorizontalMuonAlgorithm::configure(const nlohmann::json& config) { @@ -118,29 +115,15 @@ TCMakerHorizontalMuonAlgorithm::configure(const nlohmann::json& config) m_n_channels_threshold = config["n_channels_threshold"]; if (config.contains("window_length")) m_window_length = config["window_length"]; - if (config.contains("readout_window_ticks_before")) - m_readout_window_ticks_before = config["readout_window_ticks_before"]; - if (config.contains("readout_window_ticks_after")) - m_readout_window_ticks_after = config["readout_window_ticks_after"]; - } - /*if(m_trigger_on_adc) { - TLOG_DEBUG(TRACE_NAME) << "If the total ADC of trigger activities with times within a " - << m_window_length << " tick time window is above " << m_adc_threshold << " counts, a trigger - will be issued."; } - else if(m_trigger_on_n_channels) { - TLOG_DEBUG(TRACE_NAME) << "If the total number of channels with hits within a " - << m_window_length << " tick time window is above " << m_n_channels_threshold << " channels, - a trigger will be issued."; + if (m_trigger_on_adc && m_trigger_on_n_channels) { + TLOG_DEBUG(TLVL_VERY_IMPORTANT) << "[TCM:HM] Triggering on ADC count and number of channels is not supported."; + throw BadConfiguration(ERS_HERE, TRACE_NAME); } - else if ((!m_trigger_on_adc) && (!m_trigger_on_n_channels)) { - TLOG_DEBUG(TRACE_NAME) << "The candidate maker will construct candidates 1 for 1 from trigger activities."; + if (!m_trigger_on_adc && !m_trigger_on_n_channels) { + TLOG_DEBUG(TLVL_VERY_IMPORTANT) << "[TCM:HM] Not triggering! All trigger flags are false!"; + throw BadConfiguration(ERS_HERE, TRACE_NAME); } - else if (m_trigger_on_adc && m_trigger_on_n_channels) { - TLOG() << "You have requsted to trigger on both the number of channels hit and the sum of adc counts, " - << "unfortunately this is not yet supported. Exiting."; - // FIX ME: Logic to throw an exception here. - }*/ return; } @@ -151,9 +134,8 @@ TCMakerHorizontalMuonAlgorithm::construct_tc() const TriggerActivity latest_ta_in_window = m_current_window.inputs.back(); TriggerCandidate tc; - tc.time_start = m_current_window.time_start - m_readout_window_ticks_before; - tc.time_end = m_current_window.time_start + m_readout_window_ticks_after; - //tc.time_end = latest_ta_in_window.inputs.back().time_start + latest_ta_in_window.inputs.back().time_over_threshold; + tc.time_start = m_current_window.time_start; + tc.time_end = latest_ta_in_window.inputs.back().time_start; tc.time_candidate = m_current_window.time_start; tc.detid = latest_ta_in_window.detid; tc.type = TriggerCandidate::Type::kHorizontalMuon; @@ -164,6 +146,9 @@ TCMakerHorizontalMuonAlgorithm::construct_tc() const // TriggerActivityData, which is the base class of TriggerActivity for (auto& ta : m_current_window.inputs) { tc.inputs.push_back(ta); + if (ta.time_end > tc.time_end) { + tc.time_end = ta.time_end; + } } return tc; diff --git a/src/TriggerCandidateMakerMichelElectron.cpp b/src/TCMakerMichelElectronAlgorithm.cpp similarity index 69% rename from src/TriggerCandidateMakerMichelElectron.cpp rename to src/TCMakerMichelElectronAlgorithm.cpp index 922511b..6169f92 100644 --- a/src/TriggerCandidateMakerMichelElectron.cpp +++ b/src/TCMakerMichelElectronAlgorithm.cpp @@ -1,22 +1,28 @@ /** - * @file TriggerCandidateMakerMichelElectron.cpp + * @file TCMakerMichelElectronAlgorithm.cpp * * This is part of the DUNE DAQ Application Framework, copyright 2021. * Licensing/copyright details are in the COPYING file that you should have * received with this code. */ -#include "triggeralgs/MichelElectron/TriggerCandidateMakerMichelElectron.hpp" +#include "triggeralgs/MichelElectron/TCMakerMichelElectronAlgorithm.hpp" #include "TRACE/trace.h" -#define TRACE_NAME "TriggerCandidateMakerMichelElectronPlugin" +#define TRACE_NAME "TCMakerMichelElectronAlgorithm" #include using namespace triggeralgs; +using Logging::TLVL_DEBUG_ALL; +using Logging::TLVL_DEBUG_HIGH; +using Logging::TLVL_DEBUG_LOW; +using Logging::TLVL_DEBUG_INFO; +using Logging::TLVL_VERY_IMPORTANT; + void -TriggerCandidateMakerMichelElectron::process(const TriggerActivity& activity, +TCMakerMichelElectronAlgorithm::process(const TriggerActivity& activity, std::vector& output_tc) { @@ -34,7 +40,7 @@ TriggerCandidateMakerMichelElectron::process(const TriggerActivity& activity, // add_window_to_record(m_current_window); // dump_window_record(); - // TLOG(1) << "Constructing trivial TC."; + TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TCM:ME] Constructing TC."; TriggerCandidate tc = construct_tc(); output_tc.push_back(tc); @@ -51,7 +57,7 @@ TriggerCandidateMakerMichelElectron::process(const TriggerActivity& activity, // If the difference between the current TA's start time and the start of the window // is less than the specified window size, add the TA to the window. if ((activity.time_start - m_current_window.time_start) < m_window_length) { - // TLOG_DEBUG(TRACE_NAME) << "Window not yet complete, adding the activity to the window."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:ME] Window not yet complete, adding the activity to the window."; m_current_window.add(activity); } // If the addition of the current TA to the window would make it longer @@ -59,11 +65,11 @@ TriggerCandidateMakerMichelElectron::process(const TriggerActivity& activity, // the existing window is above the specified threshold. If it is, and we are triggering on ADC, // make a TA and start a fresh window with the current TP. else if (m_current_window.adc_integral > m_adc_threshold && m_trigger_on_adc) { - // TLOG_DEBUG(TRACE_NAME) << "ADC integral in window is greater than specified threshold."; + TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TCM:ME] ADC integral in window is greater than specified threshold."; TriggerCandidate tc = construct_tc(); output_tc.push_back(tc); - // TLOG_DEBUG(TRACE_NAME) << "Resetting window with activity."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:ME] Resetting window with activity."; m_current_window.reset(activity); } // If the addition of the current TA to the window would make it longer @@ -74,15 +80,15 @@ TriggerCandidateMakerMichelElectron::process(const TriggerActivity& activity, tc_number++; // output_tc.push_back(construct_tc()); m_current_window.reset(activity); - TLOG(1) << "Should not see this!"; + TLOG_DEBUG(TLVL_DEBUG_INFO) << "[TCM:ME] Should not see this!"; } // If it is not, move the window along. else { - // TLOG_DEBUG(TRACE_NAME) << "Window is at required length but specified threshold not met, shifting window along."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:ME] Window is at required length but specified threshold not met, shifting window along."; m_current_window.move(activity, m_window_length); } - // TLOG_DEBUG(TRACE_NAME) << m_current_window; + //TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TCM:ME] " m_current_window; m_activity_count++; @@ -92,7 +98,7 @@ TriggerCandidateMakerMichelElectron::process(const TriggerActivity& activity, } void -TriggerCandidateMakerMichelElectron::configure(const nlohmann::json& config) +TCMakerMichelElectronAlgorithm::configure(const nlohmann::json& config) { TriggerCandidateMaker::configure(config); @@ -108,44 +114,28 @@ TriggerCandidateMakerMichelElectron::configure(const nlohmann::json& config) m_n_channels_threshold = config["n_channels_threshold"]; if (config.contains("window_length")) m_window_length = config["window_length"]; - if (config.contains("readout_window_ticks_before")) - m_readout_window_ticks_before = config["readout_window_ticks_before"]; - if (config.contains("readout_window_ticks_after")) - m_readout_window_ticks_after = config["readout_window_ticks_after"]; - // if (config.contains("channel_map")) m_channel_map = config["channel_map"]; } - /*if(m_trigger_on_adc) { - TLOG_DEBUG(TRACE_NAME) << "If the total ADC of trigger activities with times within a " - << m_window_length << " tick time window is above " << m_adc_threshold << " counts, a trigger - will be issued."; - } - else if(m_trigger_on_n_channels) { - TLOG_DEBUG(TRACE_NAME) << "If the total number of channels with hits within a " - << m_window_length << " tick time window is above " << m_n_channels_threshold << " channels, - a trigger will be issued."; + if (m_trigger_on_adc && m_trigger_on_n_channels) { + TLOG_DEBUG(TLVL_VERY_IMPORTANT) << "[TCM:ME] Triggering on ADC count and number of channels is not supported."; + throw BadConfiguration(ERS_HERE, TRACE_NAME); } - else if ((!m_trigger_on_adc) && (!m_trigger_on_n_channels)) { - TLOG_DEBUG(TRACE_NAME) << "The candidate maker will construct candidates 1 for 1 from trigger activities."; + if (!m_trigger_on_adc && !m_trigger_on_n_channels) { + TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TCM:ME] Both trigger flags are false. Passing TAs through 1:1."; } - else if (m_trigger_on_adc && m_trigger_on_n_channels) { - TLOG() << "You have requsted to trigger on both the number of channels hit and the sum of adc counts, " - << "unfortunately this is not yet supported. Exiting."; - // FIX ME: Logic to throw an exception here. - }*/ return; } TriggerCandidate -TriggerCandidateMakerMichelElectron::construct_tc() const +TCMakerMichelElectronAlgorithm::construct_tc() const { TriggerActivity latest_ta_in_window = m_current_window.inputs.back(); TriggerCandidate tc; - tc.time_start = m_current_window.time_start - m_readout_window_ticks_before; + tc.time_start = m_current_window.time_start; tc.time_end = - latest_ta_in_window.inputs.back().time_start + latest_ta_in_window.inputs.back().time_over_threshold + m_readout_window_ticks_after; + latest_ta_in_window.inputs.back().time_start + latest_ta_in_window.inputs.back().time_over_threshold; tc.time_candidate = m_current_window.time_start; tc.detid = latest_ta_in_window.detid; tc.type = TriggerCandidate::Type::kMichelElectron; @@ -162,7 +152,7 @@ TriggerCandidateMakerMichelElectron::construct_tc() const } bool -TriggerCandidateMakerMichelElectron::check_adjacency() const +TCMakerMichelElectronAlgorithm::check_adjacency() const { // FIX ME: An adjacency check on the channels which have hits. return true; @@ -170,14 +160,14 @@ TriggerCandidateMakerMichelElectron::check_adjacency() const // Functions below this line are for debugging purposes. void -TriggerCandidateMakerMichelElectron::add_window_to_record(Window window) +TCMakerMichelElectronAlgorithm::add_window_to_record(Window window) { m_window_record.push_back(window); return; } void -TriggerCandidateMakerMichelElectron::dump_window_record() +TCMakerMichelElectronAlgorithm::dump_window_record() { // FIX ME: Need to index this outfile in the name by detid or something similar. std::ofstream outfile; @@ -201,7 +191,7 @@ TriggerCandidateMakerMichelElectron::dump_window_record() /* void -TriggerCandidateMakerMichelElectron::flush(timestamp_t, std::vector& output_tc) +TCMakerMichelElectronAlgorithm::flush(timestamp_t, std::vector& output_tc) { // Check the status of the current window, construct TC if conditions are met. Regardless // of whether the conditions are met, reset the window. @@ -222,4 +212,4 @@ reset."; m_current_window.clear(); return; }*/ -REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TriggerCandidateMakerMichelElectron) +REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerMichelElectronAlgorithm) diff --git a/src/TriggerCandidateMakerPlaneCoincidence.cpp b/src/TCMakerPlaneCoincidenceAlgorithm.cpp similarity index 72% rename from src/TriggerCandidateMakerPlaneCoincidence.cpp rename to src/TCMakerPlaneCoincidenceAlgorithm.cpp index 3070737..06100b9 100644 --- a/src/TriggerCandidateMakerPlaneCoincidence.cpp +++ b/src/TCMakerPlaneCoincidenceAlgorithm.cpp @@ -1,22 +1,28 @@ /** - * @file TriggerCandidateMakerPlaneCoincidence.cpp + * @file TCMakerPlaneCoincidenceAlgorithm.cpp * * This is part of the DUNE DAQ Application Framework, copyright 2021. * Licensing/copyright details are in the COPYING file that you should have * received with this code. */ -#include "triggeralgs/PlaneCoincidence/TriggerCandidateMakerPlaneCoincidence.hpp" +#include "triggeralgs/PlaneCoincidence/TCMakerPlaneCoincidenceAlgorithm.hpp" #include "TRACE/trace.h" -#define TRACE_NAME "TriggerCandidateMakerPlaneCoincidencePlugin" +#define TRACE_NAME "TCMakerPlaneCoincidenceAlgorithm" #include using namespace triggeralgs; +using Logging::TLVL_DEBUG_HIGH; +using Logging::TLVL_DEBUG_MEDIUM; +using Logging::TLVL_DEBUG_LOW; +using Logging::TLVL_DEBUG_INFO; +using Logging::TLVL_VERY_IMPORTANT; + void -TriggerCandidateMakerPlaneCoincidence::process(const TriggerActivity& activity, +TCMakerPlaneCoincidenceAlgorithm::process(const TriggerActivity& activity, std::vector& output_tc) { @@ -34,8 +40,8 @@ TriggerCandidateMakerPlaneCoincidence::process(const TriggerActivity& activity, // add_window_to_record(m_current_window); // dump_window_record(); - TLOG(1) << "Constructing trivial TC."; - TLOG(1) << "Activity count: " << m_activity_count; + TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TCM:PC] Constructing TC."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:PC] Activity count: " << m_activity_count; TriggerCandidate tc = construct_tc(); output_tc.push_back(tc); @@ -51,7 +57,6 @@ TriggerCandidateMakerPlaneCoincidence::process(const TriggerActivity& activity, // If the difference between the current TA's start time and the start of the window // is less than the specified window size, add the TA to the window. if ((activity.time_start - m_current_window.time_start) < m_window_length) { - // TLOG_DEBUG(TRACE_NAME) << "TAWindow not yet complete, adding the activity to the window."; m_current_window.add(activity); } // If the addition of the current TA to the window would make it longer @@ -59,11 +64,11 @@ TriggerCandidateMakerPlaneCoincidence::process(const TriggerActivity& activity, // the existing window is above the specified threshold. If it is, and we are triggering on ADC, // make a TA and start a fresh window with the current TP. else if (m_current_window.adc_integral > m_adc_threshold && m_trigger_on_adc) { - // TLOG_DEBUG(TRACE_NAME) << "ADC integral in window is greater than specified threshold."; + TLOG_DEBUG(TLVL_DEBUG_MEDIUM) << "[TCM:PC] ADC integral in window is greater than specified threshold."; TriggerCandidate tc = construct_tc(); output_tc.push_back(tc); - // TLOG_DEBUG(TRACE_NAME) << "Resetting window with activity."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:PC] Resetting window with activity."; m_current_window.reset(activity); } // If the addition of the current TA to the window would make it longer @@ -71,14 +76,15 @@ TriggerCandidateMakerPlaneCoincidence::process(const TriggerActivity& activity, // the existing window is above the specified threshold. If it is, and we are triggering on channels, // make a TC and start a fresh window with the current TA. else if (m_current_window.n_channels_hit() > m_n_channels_threshold && m_trigger_on_n_channels) { + // TODO 04-2024: This case appears unsupported. Throwing error for now, but should this be removed? tc_number++; // output_tc.push_back(construct_tc()); m_current_window.reset(activity); - TLOG(1) << "Should not see this!"; + TLOG_DEBUG(TLVL_DEBUG_INFO) << "[TCM:PC] Should not see this!"; } // If it is not, move the window along. else { - // TLOG_DEBUG(TRACE_NAME) << "TAWindow is at required length but specified threshold not met, shifting window along."; + TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TCM:PC] TAWindow is at required length but specified threshold not met, shifting window along."; m_current_window.move(activity, m_window_length); } @@ -88,7 +94,7 @@ TriggerCandidateMakerPlaneCoincidence::process(const TriggerActivity& activity, } void -TriggerCandidateMakerPlaneCoincidence::configure(const nlohmann::json& config) +TCMakerPlaneCoincidenceAlgorithm::configure(const nlohmann::json& config) { TriggerCandidateMaker::configure(config); if (config.is_object()) { @@ -102,25 +108,27 @@ TriggerCandidateMakerPlaneCoincidence::configure(const nlohmann::json& config) m_n_channels_threshold = config["n_channels_threshold"]; if (config.contains("window_length")) m_window_length = config["window_length"]; - if (config.contains("readout_window_ticks_before")) - m_readout_window_ticks_before = config["readout_window_ticks_before"]; - if (config.contains("readout_window_ticks_after")) - m_readout_window_ticks_after = config["readout_window_ticks_after"]; - + } + if (m_trigger_on_n_channels) { + TLOG_DEBUG(TLVL_VERY_IMPORTANT) << "[TCM:PC] Using trigger_on_n_channels is not supported."; + throw BadConfiguration(ERS_HERE, TRACE_NAME); + } + if (!m_trigger_on_adc && !m_trigger_on_n_channels) { + TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TCM:PC] Both trigger flags are false. Passing TAs through 1:1."; } return; } TriggerCandidate -TriggerCandidateMakerPlaneCoincidence::construct_tc() const +TCMakerPlaneCoincidenceAlgorithm::construct_tc() const { TriggerActivity latest_ta_in_window = m_current_window.inputs.back(); TriggerCandidate tc; - tc.time_start = m_current_window.time_start - m_readout_window_ticks_before; + tc.time_start = m_current_window.time_start; tc.time_end = - latest_ta_in_window.inputs.back().time_start + latest_ta_in_window.inputs.back().time_over_threshold + m_readout_window_ticks_after; + latest_ta_in_window.inputs.back().time_start + latest_ta_in_window.inputs.back().time_over_threshold; tc.time_candidate = m_current_window.time_start; tc.detid = latest_ta_in_window.detid; tc.type = TriggerCandidate::Type::kPlaneCoincidence; @@ -137,7 +145,7 @@ TriggerCandidateMakerPlaneCoincidence::construct_tc() const } bool -TriggerCandidateMakerPlaneCoincidence::check_adjacency() const +TCMakerPlaneCoincidenceAlgorithm::check_adjacency() const { // FIX ME: An adjacency check on the channels which have hits. return true; @@ -145,14 +153,14 @@ TriggerCandidateMakerPlaneCoincidence::check_adjacency() const // Functions below this line are for debugging purposes. void -TriggerCandidateMakerPlaneCoincidence::add_window_to_record(TAWindow window) +TCMakerPlaneCoincidenceAlgorithm::add_window_to_record(TAWindow window) { m_window_record.push_back(window); return; } void -TriggerCandidateMakerPlaneCoincidence::dump_window_record() +TCMakerPlaneCoincidenceAlgorithm::dump_window_record() { // FIX ME: Need to index this outfile in the name by detid or something similar. std::ofstream outfile; @@ -174,4 +182,4 @@ TriggerCandidateMakerPlaneCoincidence::dump_window_record() return; } -REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TriggerCandidateMakerPlaneCoincidence) +REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerPlaneCoincidenceAlgorithm) diff --git a/src/TCMakerPrescaleAlgorithm.cpp b/src/TCMakerPrescaleAlgorithm.cpp index a106891..f88314c 100644 --- a/src/TCMakerPrescaleAlgorithm.cpp +++ b/src/TCMakerPrescaleAlgorithm.cpp @@ -22,8 +22,8 @@ TCMakerPrescaleAlgorithm::process(const TriggerActivity& activity, std::vector(activity)); TriggerCandidate tc; - tc.time_start = activity.time_start - m_readout_window_ticks_before; - tc.time_end = activity.time_end + m_readout_window_ticks_after; + tc.time_start = activity.time_start; + tc.time_end = activity.time_end; tc.time_candidate = activity.time_start; tc.detid = activity.detid; tc.type = TriggerCandidate::Type::kPrescale; @@ -45,14 +45,6 @@ void TCMakerPrescaleAlgorithm::configure(const nlohmann::json &config) { TriggerCandidateMaker::configure(config); - if (config.is_object()) - { - if (config.contains("readout_window_ticks_before")) - m_readout_window_ticks_before = config["readout_window_ticks_before"]; - if (config.contains("readout_window_ticks_after")) - m_readout_window_ticks_after = config["readout_window_ticks_after"]; - - } } REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerPrescaleAlgorithm) diff --git a/src/TriggerCandidateMakerSupernova.cpp b/src/TCMakerSupernovaAlgorithm.cpp similarity index 78% rename from src/TriggerCandidateMakerSupernova.cpp rename to src/TCMakerSupernovaAlgorithm.cpp index 7019440..804c047 100644 --- a/src/TriggerCandidateMakerSupernova.cpp +++ b/src/TCMakerSupernovaAlgorithm.cpp @@ -1,20 +1,20 @@ /** - * @file TriggerCandidateMakerSupernova.cpp + * @file TCMakerSupernovaAlgorithm.cpp * * This is part of the DUNE DAQ Application Framework, copyright 2020. * Licensing/copyright details are in the COPYING file that you should have * received with this code. */ -#include "triggeralgs/Supernova/TriggerCandidateMakerSupernova.hpp" +#include "triggeralgs/Supernova/TCMakerSupernovaAlgorithm.hpp" #include "TRACE/trace.h" -#define TRACE_NAME "TriggerCandidateMakerSupernovaPlugin" +#define TRACE_NAME "TCMakerSupernovaAlgorithm" using namespace triggeralgs; void -TriggerCandidateMakerSupernova::process(const TriggerActivity& activity, std::vector& cand) +TCMakerSupernovaAlgorithm::process(const TriggerActivity& activity, std::vector& cand) { timestamp_t time = activity.time_start; FlushOldActivity(time); // get rid of old activities in the buffer @@ -41,4 +41,4 @@ TriggerCandidateMakerSupernova::process(const TriggerActivity& activity, std::ve } } -REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TriggerCandidateMakerSupernova) +REGISTER_TRIGGER_CANDIDATE_MAKER(TRACE_NAME, TCMakerSupernovaAlgorithm) diff --git a/src/TriggerDecisionMakerSupernova.cpp b/src/TDMakerSupernovaAlgorithm.cpp similarity index 83% rename from src/TriggerDecisionMakerSupernova.cpp rename to src/TDMakerSupernovaAlgorithm.cpp index b5fe62b..0b4bda7 100644 --- a/src/TriggerDecisionMakerSupernova.cpp +++ b/src/TDMakerSupernovaAlgorithm.cpp @@ -1,12 +1,12 @@ /** - * @file TriggerDecisionMakerSupernova.cpp + * @file TDMakerSupernovaAlgorithm.cpp * * This is part of the DUNE DAQ Application Framework, copyright 2020. * Licensing/copyright details are in the COPYING file that you should have * received with this code. */ -#include "triggeralgs/Supernova/TriggerDecisionMakerSupernova.hpp" +#include "triggeralgs/Supernova/TDMakerSupernovaAlgorithm.hpp" #include #include @@ -17,7 +17,7 @@ using pd_clock = std::chrono::duration>; using namespace triggeralgs; void -TriggerDecisionMakerSupernova::operator()(const TriggerCandidate& cand, std::vector& decisions) +TDMakerSupernovaAlgorithm::operator()(const TriggerCandidate& cand, std::vector& decisions) { std::vector vCand; diff --git a/test/test_factory.cxx b/test/test_factory.cxx index 806bc61..bd64868 100644 --- a/test/test_factory.cxx +++ b/test/test_factory.cxx @@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(test_macro_overview) TriggerPrimitive some_tp; for (int idx = 0; idx < 10; idx++) { some_tp.type = TriggerPrimitive::Type::kTPC; - some_tp.algorithm = TriggerPrimitive::Algorithm::kTPCDefault; + some_tp.algorithm = TriggerPrimitive::Algorithm::kSimpleThreshold; some_tp.time_start = idx; some_tp.time_peak = 1+idx; some_tp.time_over_threshold = 2;