ToolDAQFramework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
BONSAI.cpp
Go to the documentation of this file.
1 #include "BONSAI.h"
2 
3 BONSAI::BONSAI():Tool(){}
4 
5 bool BONSAI::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("BONSAI") : 0;
17 
18  m_stopwatch_file = "";
19  m_variables.Get("stopwatch_file", m_stopwatch_file);
20 
22 
23  m_data= &data;
24 
25  if(!util::FileExists(std::getenv("BONSAIDIR"), "libWCSimBonsai.so")) {
26  Log("FATAL: BONSAI library not found. Ensure the BONSAI library exists at $BONSAIDIR/libWCSimBonsai.so. For more information about BONSAI, see https://github.com/hyperk/hk-BONSAI", FATAL, m_verbose);
27  return false;
28  }
29 
30  m_variables.Get("nhitsmin", m_nhits_min);
31  m_variables.Get("nhitsmax", m_nhits_max);
32 
33  //setup BONSAI with the geometry
34  m_bonsai = new WCSimBonsai();
35  WCSimRootGeom * geo = 0;
36  m_data->WCSimGeomTree->SetBranchAddress("wcsimrootgeom", &geo);
37  m_data->WCSimGeomTree->GetEntry(0);
38  m_bonsai->Init(geo);
39  m_data->WCSimGeomTree->ResetBranchAddresses();
40 
41  //allocate memory for the hit vectors
42  m_in_PMTIDs = new std::vector<int> (m_nhits_max);
43  m_in_Ts = new std::vector<float>(m_nhits_max);
44  m_in_Qs = new std::vector<float>(m_nhits_max);
45 
46  if(m_stopwatch) Log(m_stopwatch->Result("Initialise"), INFO, m_verbose);
47 
48  return true;
49 }
50 
51 
54 
55  float out_vertex[4], out_direction[6], out_maxlike[3];
56  int out_nsel[2];
57  double dout_vertex[3], dout_direction[3], dout_cone[2];
58 
59  //loop over ID triggers
60  for (int itrigger = 0; itrigger < m_data->IDTriggers.m_num_triggers; itrigger++) {
61  //clear the previous triggers' hit information
62  m_in_PMTIDs->clear();
63  m_in_Ts->clear();
64  m_in_Qs->clear();
65 
66  bool found_first_time = false;
67  double first_time;
68 
69  //Loop over ID SubSamples
70  for(std::vector<SubSample>::iterator is = m_data->IDSamples.begin(); is != m_data->IDSamples.end(); ++is){
71 
72  //fill the inputs to BONSAI with the current triggers' hit information
73  //loop over all hits
74  const size_t nhits_in_subsample = is->m_time.size();
75  //starting at m_first_unique, rather than 0, to avoid double-counting hits
76  // that are in multiple SubSamples
77  for(size_t ihit = is->m_first_unique; ihit < nhits_in_subsample; ihit++) {
78  //see if the hit belongs to this trigger
79  if(std::find(is->m_trigger_readout_windows[ihit].begin(),
80  is->m_trigger_readout_windows[ihit].end(),
81  itrigger) == is->m_trigger_readout_windows[ihit].end())
82  continue;
83 
84  //get the first time in the trigger (may not be earliest - this is ok)
85  if(!found_first_time) {
86  first_time = is->m_time[ihit];
87  found_first_time = true;
88  }
89 
90  //it belongs. Add it to the BONSAI input arrays
91  m_ss << "DEBUG: Hit " << ihit << " at time " << is->m_time[ihit];
93  m_in_PMTIDs->push_back(is->m_PMTid[ihit]);
94  //offset the time by first_time, to prevent BONSAI exceptions when the times get too big
95  m_in_Ts ->push_back(is->m_time[ihit] - first_time);
96  m_in_Qs ->push_back(is->m_charge[ihit]);
97  }//ihit
98  }//ID SubSamples
99 
100  //get the number of hits
101  m_in_nhits = m_in_PMTIDs->size();
102 
103  //don't run bonsai on large or small events
104  if(m_in_nhits < m_nhits_min || m_in_nhits > m_nhits_max) {
105  m_ss << "INFO: " << m_in_nhits << " hits in current trigger. Not running BONSAI";
106  StreamToLog(INFO);
107  continue;
108  }
109 
110  m_ss << "DEBUG: BONSAI running over " << m_in_nhits << " hits";
112  m_ss << "DEBUG: First hit time relative to sample: " << m_in_Ts->at(0) + first_time;
114  m_ss << "DEBUG: First hit time absolute: " << TimeDelta(m_in_Ts->at(0) * TimeDelta::ns)
115  + TimeDelta(first_time * TimeDelta::ns) + m_data->IDSamples[0].m_timestamp;
117 
118  //call BONSAI
119  bool success = true;
120  try {
121  m_bonsai->BonsaiFit( out_vertex, out_direction, out_maxlike, out_nsel, &m_in_nhits, m_in_PMTIDs->data(), m_in_Ts->data(), m_in_Qs->data());
122  } catch (int e) {
123  Log("BONSAI threw an exception!", WARN, m_verbose);
124  success = false;
125  }
126 
127  if (success) {
128  //vertex_time (absolute) = reconstructed_time + first_time + SubSample time
129  TimeDelta vertex_time = TimeDelta(out_vertex[3] * TimeDelta::ns)
130  + TimeDelta(first_time * TimeDelta::ns)
131  + m_data->IDSamples[0].m_timestamp;
132 
133  if(m_data->IDSamples.size() > 1) {
134  Log("WARN: You have multiple SubSamples. Absolute time of BONSAI reconstruction could be wrong. This will be fixed in parallel framework", WARN, m_verbose);
135  }
136 
137  m_ss << "DEBUG: Vertex reconstructed at x, y, z, t:";
138  for(int i = 0; i < 3; i++) {
139  m_ss << " " << out_vertex[i] << ",";
140  }
141  m_ss << " " << vertex_time;
143 
144  //fill the data model with the result
145  // need to convert to double...
146  for(int i = 0; i < 3; i++) {
147  dout_vertex[i] = out_vertex[i];
148  dout_direction[i] = out_direction[i];
149  }
150  for(int i = 0; i < 2; i++)
151  dout_cone[i] = out_direction[i+3];
152 
153  //store the reconstruction result
154  m_data->RecoInfo.AddRecon(kReconBONSAI, itrigger, m_in_nhits,
155  vertex_time, &(dout_vertex[0]), out_maxlike[2], out_maxlike[1],
156  &(dout_direction[0]), &(dout_cone[0]), out_direction[5]);
157  }
158  }//itrigger
159 
161 
162  return true;
163 }
164 
165 
167 
168  if(m_stopwatch) {
170  m_stopwatch->Start();
171  }
172 
173  delete m_bonsai;
174  delete m_in_PMTIDs;
175  delete m_in_Ts;
176  delete m_in_Qs;
177 
178  if(m_stopwatch) {
179  Log(m_stopwatch->Result("Finalise"), INFO, m_verbose);
180  delete m_stopwatch;
181  }
182 
183  return true;
184 }
WCSimBonsai * m_bonsai
This is the class that runs the BONSAI low-energy reconstruction algorithm.
Definition: BONSAI.h:27
std::string Result(std::string method_name, std::string output_file="")
Definition: Stopwatch.cpp:38
int m_verbose
Verbosity level, as defined in tool parameter file.
Definition: BONSAI.h:48
void Start()
Start the stopwatch.
Definition: Stopwatch.cpp:18
util::Stopwatch * m_stopwatch
The stopwatch, if we&#39;re using one.
Definition: BONSAI.h:43
StopwatchTimes Stop()
Stop the stopwatch, returning the CPU time.
Definition: Stopwatch.cpp:24
std::vector< float > * m_in_Ts
Times of hits in a trigger.
Definition: BONSAI.h:33
void StreamToLog(int level)
Definition: BONSAI.h:55
int m_in_nhits
Number of hits in a trigger.
Definition: BONSAI.h:29
std::vector< int > * m_in_PMTIDs
PMT IDs of hits in a trigger.
Definition: BONSAI.h:31
unsigned int m_nhits_min
Below this number of hits in a trigger, don&#39;t run BONSAI. Equality is run. Set in config file...
Definition: BONSAI.h:38
bool Execute()
Definition: BONSAI.cpp:52
std::stringstream m_ss
For easy formatting of Log messages.
Definition: BONSAI.h:51
std::vector< float > * m_in_Qs
Charges of hits in a trigger.
Definition: BONSAI.h:35
BONSAI()
Definition: BONSAI.cpp:3
static const TimeDelta ns
TimeDelta of 1 ns.
Definition: TimeDelta.h:57
void Log(const std::string &message, const int message_level)
Format messages in the same way as for tools.
Definition: Utilities.cpp:276
std::string m_stopwatch_file
Image filename to save the histogram to, if required.
Definition: BONSAI.h:45
bool Finalise()
Definition: BONSAI.cpp:166
unsigned int m_nhits_max
Above this number of hits in a trigger, don&#39;t run BONSAI. Equality is run. Set in config file...
Definition: BONSAI.h:40
bool FileExists(std::string pathname, std::string filename)
Check if a file exists.
Definition: Utilities.cpp:264
bool Initialise(std::string configfile, DataModel &data)
Definition: BONSAI.cpp:5