ToolDAQFramework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nhits.cpp
Go to the documentation of this file.
1 #include "nhits.h"
2 
3 NHits::NHits():Tool(){}
4 
5 bool NHits::Initialise(std::string configfile, DataModel &data){
6 
7  if(configfile!="") m_variables.Initialise(configfile);
8  //m_variables.Print();
9 
10  m_verbose = 0;
11  m_variables.Get("verbose", m_verbose);
12 
13  //Setup and start the stopwatch
14  bool use_stopwatch = false;
15  m_variables.Get("use_stopwatch", use_stopwatch);
16  m_stopwatch = use_stopwatch ? new util::Stopwatch("nhits") : 0;
17 
18  m_stopwatch_file = "";
19  m_variables.Get("stopwatch_file", m_stopwatch_file);
20 
22 
23  m_data= &data;
24 
25  double temp_trigger_search_window;
26  double temp_trigger_search_window_step;
27  double temp_trigger_save_window_pre;
28  double temp_trigger_save_window_post;
29 
30  m_variables.Get("trigger_search_window", temp_trigger_search_window);
31  m_variables.Get("trigger_search_window_step", temp_trigger_search_window_step);
32  m_variables.Get("trigger_threshold", m_trigger_threshold);
33  m_variables.Get("pretrigger_save_window", temp_trigger_save_window_pre);
34  m_variables.Get("posttrigger_save_window", temp_trigger_save_window_post);
35  m_variables.Get("trigger_od", m_trigger_OD);
36  m_variables.Get("degrade_CPU", m_degrade_CPU);
37 
38  m_trigger_search_window = TimeDelta(temp_trigger_search_window);
39  m_trigger_save_window_pre = TimeDelta(temp_trigger_save_window_pre);
40  m_trigger_save_window_post = TimeDelta(temp_trigger_save_window_post);
41 
42  bool adjust_for_noise;
43  m_variables.Get("trigger_threshold_adjust_for_noise", adjust_for_noise);
44  int npmts = m_trigger_OD ? m_data->ODNPMTs : m_data->IDNPMTs;
45  double dark_rate_kHZ = m_trigger_OD ? m_data->ODPMTDarkRate : m_data->IDPMTDarkRate;
46  double trigger_window_seconds = m_trigger_search_window / TimeDelta::s;
47  double dark_rate_Hz = dark_rate_kHZ * 1000;
48  double average_occupancy = dark_rate_Hz * trigger_window_seconds * npmts;
49 
50  m_ss << "INFO: Average number of PMTs in detector active in a " << m_trigger_search_window
51  << "ns window with a dark noise rate of " << dark_rate_kHZ
52  << "kHz is " << average_occupancy
53  << " (" << npmts << " total PMTs)";
55 
56  m_ss << "INFO: m_degrade_CPU " << m_degrade_CPU; StreamToLog(INFO);
57 
58  if(adjust_for_noise) {
59  m_ss << "INFO: Updating the NDigits threshold, from " << m_trigger_threshold
60  << " to " << m_trigger_threshold + round(average_occupancy) << std::endl;
62  m_trigger_threshold += round(average_occupancy);
63  }
64 
65 #ifdef GPU
66  std::string ParameterFile;
67 
68  m_variables.Get("ParameterFile",ParameterFile);
69 
70  GPU_daq::nhits_initialize_ToolDAQ(ParameterFile,m_data->IDGeom.size(),temp_trigger_search_window, temp_trigger_search_window_step, m_trigger_threshold, temp_trigger_save_window_pre, temp_trigger_save_window_post);
71 
72 
73  m_time_int.reserve(2*(int)average_occupancy);
74 
75 #endif
76 
77  if(m_stopwatch) Log(m_stopwatch->Result("Initialise"), INFO, m_verbose);
78 
79 
80 
81 
82  return true;
83 }
84 
87 
88  //do stuff with m_data->Samples
89 
90  std::vector<SubSample> & samples = m_trigger_OD ? (m_data->ODSamples) : (m_data->IDSamples);
91 
92  m_ss << " Number of data samples " << samples.size();
94 
95  for( std::vector<SubSample>::iterator is=samples.begin(); is!=samples.end(); ++is){
96 #ifdef GPU
97 
98  std::vector<int> trigger_ns;
99  std::vector<int> trigger_ts;
100  m_time_int.clear();
101  for(unsigned int i = 0; i < is->m_time.size(); i++) {
102  m_time_int.push_back(is->m_time[i]);
103  }
104  GPU_daq::nhits_execute(is->m_PMTid, m_time_int, &trigger_ns, &trigger_ts);
105  for(int i=0; i<trigger_ns.size(); i++){
106  m_data->IDTriggers.AddTrigger(kTriggerNDigits,
107  TimeDelta(trigger_ts[i]) - m_trigger_save_window_pre + is->m_timestamp,
108  TimeDelta(trigger_ts[i]) + m_trigger_save_window_post + is->m_timestamp,
109  TimeDelta(trigger_ts[i]) - m_trigger_mask_window_pre + is->m_timestamp,
110  TimeDelta(trigger_ts[i]) + m_trigger_mask_window_post + is->m_timestamp,
111  TimeDelta(trigger_ts[i]) + is->m_timestamp,
112  std::vector<float>(1, trigger_ns[i]));
113 
114  m_ss << "trigger! time " << trigger_ts[i] << " nhits " << trigger_ns[i]; StreamToLog(INFO);
115  }
116 #else
117  // Make sure digit times are ordered in time
118  if (not is->IsSortedByTime()){
119  Log("ERROR: Input sample is not sorted by time!", ERROR, m_verbose);
120  return false;
121  }
122  AlgNDigits(&(*is));
123 #endif
124  }//loop over SubSamples
125  //Now we have all the triggers, get the SubSample to determine
126  // - which trigger readout windows each hit is associated with
127  // - which hits should be masked from future triggers
128  for( std::vector<SubSample>::iterator is=samples.begin(); is!=samples.end(); ++is) {
129  (*is).TellMeAboutTheTriggers(m_data->IDTriggers, m_verbose);
130  }//loop over SubSamples
131 
133 
134  return true;
135 }
136 
137 void NHits::AlgNDigits(const SubSample * sample)
138 {
139  //we will try to find triggers
140  //loop over PMTs, and Digits in each PMT. If ndigits > Threshhold in a time window, then we have a trigger
141 
142  const unsigned int ndigits = sample->m_time.size();
143  m_ss << "DEBUG: NHits::AlgNDigits(). Number of entries in input digit collection: " << ndigits;
145 
146  // Where to store the triggers we find
147  TriggerInfo * triggers = m_trigger_OD ? &(m_data->ODTriggers) : &(m_data->IDTriggers);
148  const int num_triggers_start = triggers->m_num_triggers;
149 
150  // Loop over all digits
151  // But we can start with an offset of at least the threhshold to save some time
152  int current_digit = std::min(m_trigger_threshold, ndigits);
153  int first_digit_in_window = 0;
154  for(;current_digit < ndigits; ++current_digit) {
155  // Update first digit in trigger window
156  if( !m_degrade_CPU ){
157  TimeDelta::short_time_t digit_time = sample->m_time.at(current_digit);
158  while(TimeDelta(sample->m_time[first_digit_in_window]) < TimeDelta(digit_time) - m_trigger_search_window){
159  ++first_digit_in_window;
160  }
161  }else{
162  //F. Nova degrade info from float to int to match GPU run
163  int digit_time = (int)sample->m_time.at(current_digit);
164  while(TimeDelta((int)sample->m_time[first_digit_in_window]) <= TimeDelta(digit_time) - m_trigger_search_window){
165  ++first_digit_in_window;
166  }
167  }
168 
169 
170  // if # of digits in window over threshold, issue trigger
171  int n_digits_in_window = current_digit - first_digit_in_window + 1; // +1 because difference is 0 when first digit is the only digit in window
172 
173  if( n_digits_in_window > m_trigger_threshold) {
174  TimeDelta triggertime = sample->AbsoluteDigitTime(current_digit);
175 
176  if( m_degrade_CPU )
177  triggertime = ((uint64_t) (triggertime /TimeDelta::ns)) * TimeDelta::ns;
178 
179  m_ss << "DEBUG: Found NHits trigger in SubSample at " << triggertime;
181  m_ss << "DEBUG: Advancing search by posttrigger_save_window " << m_trigger_save_window_post;
183  while(sample->AbsoluteDigitTime(current_digit) < triggertime + m_trigger_save_window_post){
184  ++current_digit;
185  if (current_digit >= ndigits){
186  // Break if we run out of digits
187  break;
188  }
189  }
190  --current_digit; // We want the last digit *within* post-trigger-window
191  int n_digits = current_digit - first_digit_in_window + 1;
192  m_ss << "DEBUG: Number of digits between (trigger_time - trigger_search_window) and (trigger_time + posttrigger_save_window):" << n_digits;
194 
195  triggers->AddTrigger(kTriggerNDigits,
196  triggertime - m_trigger_save_window_pre,
197  triggertime + m_trigger_save_window_post,
198  triggertime - m_trigger_mask_window_pre,
199  triggertime + m_trigger_mask_window_post,
200  triggertime,
201  std::vector<float>(1, n_digits));
202  }
203  }//loop over Digits
204 
205  m_ss << "INFO: Found " << triggers->m_num_triggers - num_triggers_start
206  << " NDigit trigger(s) from " << (m_trigger_OD ? "OD" : "ID")
207  << " Total triggers found there: " << triggers->m_num_triggers;
208  StreamToLog(INFO);
209 }
210 
212 
213  if(m_stopwatch) {
215  m_stopwatch->Start();
216  }
217 
218 #ifdef GPU
220 #endif
221 
222  if(m_stopwatch) {
223  Log(m_stopwatch->Result("Finalise"), INFO, m_verbose);
224  delete m_stopwatch;
225  }
226 
227  return true;
228 }
void AlgNDigits(const SubSample *samples)
CPU version of the NDigits algorithm.
Definition: nhits.cpp:137
std::string Result(std::string method_name, std::string output_file="")
Definition: Stopwatch.cpp:38
NHits()
Definition: nhits.cpp:3
int nhits_finalize()
float short_time_t
Type for relative hit times within a SubSample. Unit = ns.
Definition: TimeDelta.h:37
TimeDelta m_trigger_mask_window_post
Post-trigger time for masking digits from future tools.
Definition: nhits.h:34
bool Finalise()
Definition: nhits.cpp:211
void Start()
Start the stopwatch.
Definition: Stopwatch.cpp:18
bool Initialise(std::string configfile, DataModel &data)
Definition: nhits.cpp:5
StopwatchTimes Stop()
Stop the stopwatch, returning the CPU time.
Definition: Stopwatch.cpp:24
int nhits_execute()
TimeDelta m_trigger_mask_window_pre
Pre-trigger time for masking digits from future tools.
Definition: nhits.h:32
util::Stopwatch * m_stopwatch
The stopwatch, if we&#39;re using one.
Definition: nhits.h:49
TimeDelta m_trigger_search_window
Width of the sliding window.
Definition: nhits.h:24
std::string m_stopwatch_file
Image filename to save the histogram to, if required.
Definition: nhits.h:51
bool m_trigger_OD
Trigger on OD digits, rather than ID digits?
Definition: nhits.h:36
void AddTrigger(TriggerType_t type, double starttime, double endtime, double triggertime, std::vector< float > info)
Add a trigger, all times in ns.
Definition: TriggerInfo.cpp:21
TimeDelta m_trigger_save_window_post
Post-trigger time for saving digits.
Definition: nhits.h:30
static const TimeDelta ns
TimeDelta of 1 ns.
Definition: TimeDelta.h:57
int nhits_initialize_ToolDAQ(std::string ParameterFile, int nPMTs, int fTriggerSearchWindow, int fTriggerSearchWindowStep, int fTriggerThreshold, int fTriggerSaveWindowPre, int fTriggerSaveWindowPost)
void StreamToLog(int level)
Definition: nhits.h:57
TimeDelta AbsoluteDigitTime(int index) const
Return the absolute time (timestamp + digit time) of a digit.
Definition: SubSample.cpp:150
unsigned int m_trigger_threshold
Trigger threshold - number of digits must be above this value (equal to does not fire the trigger) ...
Definition: nhits.h:26
void Log(const std::string &message, const int message_level)
Format messages in the same way as for tools.
Definition: Utilities.cpp:276
bool Execute()
Definition: nhits.cpp:85
std::vector< TimeDelta::short_time_t > m_time
Vector of hit times relative to timestamp for all hits in SubSample. Unit: ns.
Definition: SubSample.h:42
int m_verbose
Definition: nhits.h:53
TimeDelta m_trigger_save_window_pre
Pre-trigger time for saving digits.
Definition: nhits.h:28
std::stringstream m_ss
Definition: nhits.h:55
static const TimeDelta s
TimeDelta of 1 s.
Definition: TimeDelta.h:63
bool m_degrade_CPU
degrade data type from float to int
Definition: nhits.h:38
unsigned int m_num_triggers
The number of triggers.
Definition: TriggerInfo.h:30