LCOV - code coverage report
Current view: top level - triggeralgs/src - TAMakerProtoDUNEBSMWindowAlgorithm.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 1.0 % 105 1
Test Date: 2026-03-29 15:29:34 Functions: 6.2 % 16 1

            Line data    Source code
       1              : /**
       2              :  * @file TAMakerProtoDUNEBSMWindowAlgorithm.cpp
       3              :  *
       4              :  * This is part of the DUNE DAQ Application Framework, copyright 2021.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : 
       9              : #include "triggeralgs/ProtoDUNEBSMWindow/TAMakerProtoDUNEBSMWindowAlgorithm.hpp"
      10              : 
      11              : #include "TRACE/trace.h"
      12              : #define TRACE_NAME "TAMakerProtoDUNEBSMWindowAlgorithm"
      13              : 
      14              : #include <vector>
      15              : #include <chrono>
      16              : 
      17              : using namespace triggeralgs;
      18              : using Logging::TLVL_DEBUG_ALL;
      19              : using Logging::TLVL_DEBUG_HIGH;
      20              : using Logging::TLVL_DEBUG_LOW;
      21              : using Logging::TLVL_IMPORTANT;
      22              : 
      23              : void
      24            0 : TAMakerProtoDUNEBSMWindowAlgorithm::process(const TriggerPrimitive& input_tp, std::vector<TriggerActivity>& output_ta)
      25              : {
      26              :   
      27            0 :   if(m_current_window.is_empty()){
      28            0 :     m_current_window.reset(input_tp);
      29            0 :     m_last_pred_time = input_tp.time_start;
      30            0 :     m_primitive_count++;
      31              :     // first time operator is called set ROP first and last channel
      32            0 :     unsigned int detelement = channelMap->get_element_id_from_offline_channel(input_tp.channel);
      33            0 :     unsigned int plane = channelMap->get_plane_from_offline_channel(input_tp.channel);
      34              : 
      35            0 :     PlaneInfo plane_info = m_det_plane_map.get_plane_info(m_channel_map_name, detelement, plane);
      36            0 :     m_first_channel = static_cast<channel_t>(plane_info.min_channel);
      37            0 :     channel_t n_channels_on_plane = static_cast<channel_t>(plane_info.n_channels);
      38              : 
      39              :     // If we are in PD-VD use 'effective' channel mapping for CRPs
      40            0 :     if (m_pdvd_map) {
      41            0 :       m_pdvd_eff_channel_mapper = std::make_unique<PDVDEffectiveChannelMap>(plane_info.min_channel, plane_info.n_channels);
      42              : 
      43            0 :       m_first_channel = m_pdvd_eff_channel_mapper->remapCollectionPlaneChannel(m_first_channel);
      44            0 :       m_last_channel = m_first_channel + m_pdvd_eff_channel_mapper->getNEffectiveChannels();
      45            0 :       m_chan_bin_length = m_pdvd_eff_channel_mapper->getNEffectiveChannels() / m_num_chanbins;
      46              :     } else { // still in PD-HD, so don't need effective channel
      47            0 :       m_last_channel = m_first_channel + n_channels_on_plane;
      48            0 :       m_chan_bin_length = n_channels_on_plane / m_num_chanbins;
      49              :     }
      50              : 
      51            0 :     TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:BSMW] 1st Chan = " << m_first_channel << ", last Chan = " << m_last_channel << std::endl
      52            0 :       << "Number of channel bins = " << m_num_chanbins << ", and channel bin length = " << m_chan_bin_length;
      53            0 :     return;
      54              :   } 
      55              :   
      56              :   // If the difference between the current TP's start time and the start of the window
      57              :   // is less than the specified window size, add the TP to the window.
      58            0 :   if((input_tp.time_start - m_current_window.time_start) < m_window_length){
      59            0 :     TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TAM:BSMW] Window not yet complete, adding the input_tp to the window.";
      60            0 :     m_current_window.add(input_tp);
      61              :   }
      62              :   // If the addition of the current TP to the window would make it longer
      63              :   // than the specified window length, don't add it
      64              :   // Instead go through a series of filters and eventually a XGBoost model to determine whether to create a TA
      65            0 :   else if (
      66            0 :       (m_current_window.time_start - m_last_pred_time) > m_bin_length && // check enough time has passed since last window
      67            0 :       m_current_window.tp_list.size() > 20 && // need enough TPs in window to bother
      68            0 :       m_current_window.adc_integral > m_adc_threshold && // set a low minimum threshold for the ADC integral sum
      69            0 :       (m_current_window.mean_adc_peak() / m_current_window.mean_tot()) > m_ratio_threshold && // mean peak / tot cut
      70            0 :       compute_treelite_classification() // XGBoost classifier 
      71              :       )
      72              :   {
      73            0 :     TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TAM:BSMW] ADC integral in window is greater than specified threshold.";
      74            0 :     output_ta.push_back(construct_ta());
      75            0 :     TLOG_DEBUG(TLVL_DEBUG_HIGH) << "[TAM:BSMW] Resetting window with input_tp.";
      76            0 :     m_current_window.reset(input_tp);
      77              :   }
      78              :   // If it is not, move the window along.
      79              :   else{
      80            0 :     TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:BSMW] Window is at required length but adc threshold not met, shifting window along.";
      81            0 :     m_current_window.move(input_tp, m_window_length);
      82              :   }
      83              :   
      84            0 :   TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:BSMW] " << m_current_window;
      85              : 
      86            0 :   m_primitive_count++;
      87              : 
      88            0 :   return;
      89              : 
      90              : }
      91              : 
      92              : void
      93            0 : TAMakerProtoDUNEBSMWindowAlgorithm::configure(const nlohmann::json &config)
      94              : {
      95            0 :   if (config.is_object()){
      96            0 :     if (config.contains("channel_map_name")) m_channel_map_name = config["channel_map_name"];
      97            0 :     if (config.contains("num_time_bins")) m_num_timebins = config["num_time_bins"];
      98            0 :     if (config.contains("adc_threshold")) m_adc_threshold = config["adc_threshold"];
      99            0 :     if (config.contains("ratio_threshold")) {
     100            0 :       m_ratio_threshold = config["ratio_threshold"];
     101            0 :       m_ratio_threshold *= 0.01;
     102              :     }
     103            0 :     if (config.contains("window_length")) {
     104            0 :       m_window_length = config["window_length"];
     105            0 :       m_bin_length = static_cast<timestamp_t>(m_window_length / m_num_timebins);
     106              :     }
     107            0 :     if (config.contains("bdt_threshold")) {
     108            0 :       uint64_t int_bdt_threshold = config["bdt_threshold"];
     109            0 :       if (int_bdt_threshold <= 100) m_bdt_threshold = static_cast<float>(int_bdt_threshold * 0.01);
     110            0 :       else if (int_bdt_threshold <= 1000) m_bdt_threshold = static_cast<float>(int_bdt_threshold * 0.001);
     111            0 :       else if (int_bdt_threshold <= 10000) m_bdt_threshold = static_cast<float>(int_bdt_threshold * 0.0001);
     112            0 :       else m_bdt_threshold = static_cast<float>(int_bdt_threshold * 0.01);
     113              :     }
     114              :   }
     115              :   else{
     116            0 :     TLOG_DEBUG(TLVL_IMPORTANT) << "[TAM:BSMW] The DEFAULT values of window_length and adc_threshold are being used.";
     117              :   }
     118              :   
     119            0 :   TLOG_DEBUG(TLVL_DEBUG_ALL) << "[TAM:BSMW] Bin length is " << m_bin_length << " for a window of " << m_num_timebins << 
     120            0 :     " bins. ADC threshold across window set to " << m_adc_threshold;
     121              :   
     122            0 :   channelMap = dunedaq::detchannelmaps::make_tpc_map(m_channel_map_name);
     123              : 
     124              :   // If we are in PD-VD, set boolean to true to enable effective channel mapping
     125            0 :   if (m_channel_map_name == "PD2VDTPCChannelMap" || m_channel_map_name == "PD2VDBottomTPCChannelMap" ||
     126            0 :       m_channel_map_name == "PD2VDTopTPCChannelMap") {
     127            0 :     m_pdvd_map = true;
     128              :   } else { // else we are in PD-HD and we use true channel mapping
     129            0 :     m_pdvd_map = false;
     130              :   }
     131              :   
     132            0 :   m_compiled_model_interface = std::make_unique<CompiledModelInterface>(nbatch);
     133              : 
     134            0 :   const size_t num_feature = m_compiled_model_interface->GetNumFeatures();
     135              : 
     136            0 :   flat_batched_inputs.resize(num_feature);
     137              : 
     138            0 :   m_num_chanbins = num_feature / m_num_timebins;
     139              : 
     140            0 :   flat_batched_Entries.clear();
     141            0 :   for (size_t i = 0; i < num_feature; ++i) {
     142            0 :     union Entry zero;
     143            0 :     zero.fvalue = 0.0;
     144            0 :     flat_batched_Entries.emplace_back(zero);
     145              :   }
     146            0 : }
     147              : 
     148            0 : TAMakerProtoDUNEBSMWindowAlgorithm::~TAMakerProtoDUNEBSMWindowAlgorithm() {
     149              :   // Nothing to clean up
     150            0 : }
     151              : 
     152              : TriggerActivity
     153            0 : TAMakerProtoDUNEBSMWindowAlgorithm::construct_ta() const
     154              : {
     155            0 :   TLOG_DEBUG(TLVL_DEBUG_LOW) << "[TAM:BSMW] I am constructing a trigger activity!";
     156              : 
     157            0 :   TriggerPrimitive latest_tp_in_window = m_current_window.tp_list.back();
     158              :   // The time_peak, time_activity, channel_* and adc_peak fields of this TA are irrelevent
     159              :   // for the purpose of this trigger alg.
     160            0 :   TriggerActivity ta;
     161            0 :   ta.time_start = m_current_window.time_start;
     162            0 :   ta.time_end = latest_tp_in_window.time_start + latest_tp_in_window.samples_over_threshold * 32;
     163            0 :   ta.time_peak = latest_tp_in_window.samples_to_peak * 32 + latest_tp_in_window.time_start;
     164            0 :   ta.time_activity = ta.time_peak;
     165            0 :   ta.channel_start = latest_tp_in_window.channel;
     166            0 :   ta.channel_end = latest_tp_in_window.channel;
     167            0 :   ta.channel_peak = latest_tp_in_window.channel;
     168            0 :   ta.adc_integral = m_current_window.adc_integral;
     169            0 :   ta.adc_peak = latest_tp_in_window.adc_peak;
     170            0 :   ta.detid = latest_tp_in_window.detid;
     171            0 :   ta.type = TriggerActivity::Type::kTPC;
     172            0 :   ta.algorithm = TriggerActivity::Algorithm::kUnknown;
     173            0 :   ta.inputs = m_current_window.tp_list;
     174            0 :   return ta;
     175            0 : }
     176              : 
     177            0 : bool TAMakerProtoDUNEBSMWindowAlgorithm::compute_treelite_classification() {
     178              :   
     179            0 :   m_last_pred_time = m_current_window.time_start;
     180              :   
     181            0 :   m_current_window.bin_window(
     182            0 :       flat_batched_inputs, m_bin_length, 
     183              :       m_chan_bin_length, m_num_timebins, 
     184              :       m_num_chanbins, m_first_channel, 
     185            0 :       m_pdvd_eff_channel_mapper, m_pdvd_map
     186              :       );
     187              :   
     188            0 :   m_current_window.fill_entry_window(flat_batched_Entries, flat_batched_inputs); 
     189              :     
     190            0 :   std::vector<float> result(nbatch, 0.0f);
     191              :   
     192            0 :   m_compiled_model_interface->Predict(flat_batched_Entries.data(), result.data());
     193              :   
     194            0 :   return m_compiled_model_interface->Classify(result.data(), m_bdt_threshold);
     195              : 
     196            0 : }
     197              : 
     198              : // Register algo in TA Factory
     199           12 : REGISTER_TRIGGER_ACTIVITY_MAKER(TRACE_NAME, TAMakerProtoDUNEBSMWindowAlgorithm)
        

Generated by: LCOV version 2.0-1