ToolDAQFramework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
test_vertices.cpp
Go to the documentation of this file.
1 #include "test_vertices.h"
2 
4 
5 
6 bool test_vertices::Initialise(std::string configfile, DataModel &data){
7 
8  float m_trigger_gate_up;
9  float m_trigger_gate_down;
10 
11  if(configfile!="") m_variables.Initialise(configfile);
12  //m_variables.Print();
13 
14  m_verbose = 0;
15  m_variables.Get("verbose", m_verbose);
16  //Setup and start the stopwatch
17  bool use_stopwatch = false;
18  m_variables.Get("use_stopwatch", use_stopwatch);
19  m_stopwatch = use_stopwatch ? new util::Stopwatch("test_vertices") : 0;
20 
21  m_stopwatch_file = "";
22  m_variables.Get("stopwatch_file", m_stopwatch_file);
23 
25 
26  m_data= &data;
27 
28  m_data->triggeroutput=false;
29 
30 
31 
32 
33  std::string DetectorFile;
34  std::string ParameterFile;
35 
36 
37  m_variables.Get("DetectorFile",DetectorFile);
38  m_variables.Get("ParameterFile",ParameterFile);
39 
40  m_variables.Get("distance_between_vertices", m_distance_between_vertices);
41  m_variables.Get("wall_like_distance", m_wall_like_distance);
42  m_variables.Get("water_like_threshold_number_of_pmts", m_water_like_threshold_number_of_pmts);
43  m_variables.Get("wall_like_threshold_number_of_pmts", m_wall_like_threshold_number_of_pmts);
44  m_variables.Get("coalesce_time", m_coalesce_time);
45  m_variables.Get("trigger_gate_up", m_trigger_gate_up);
46  m_variables.Get("trigger_gate_down", m_trigger_gate_down);
47  m_variables.Get("output_txt", m_output_txt);
48  m_variables.Get("correct_mode", m_correct_mode);
49  m_variables.Get("n_direction_bins_theta", m_n_direction_bins_theta);
50  m_variables.Get("cylindrical_grid", m_cylindrical_grid);
51  m_variables.Get("costheta_cone_cut", m_costheta_cone_cut);
52  m_variables.Get("select_based_on_cone", m_select_based_on_cone);
53  m_variables.Get("write_output_mode", m_write_output_mode);
54  m_variables.Get("trigger_threshold_adjust_for_noise", m_trigger_threshold_adjust_for_noise);
55  m_variables.Get("max_n_hits_per_job", m_max_n_hits_per_job);
56  m_variables.Get("num_blocks_y", m_num_blocks_y);
57  m_variables.Get("num_threads_per_block_y", m_num_threads_per_block_y);
58  m_variables.Get("num_threads_per_block_x", m_num_threads_per_block_x);
59  m_return_vertex = false;
60  m_variables.Get("return_vertex", m_return_vertex);
61  m_return_direction = false;
62  m_variables.Get("return_direction", m_return_direction);
63 
64  m_ss << " DetectorFile " << DetectorFile.c_str(); StreamToLog(INFO);
65  m_ss << " ParameterFile " << ParameterFile.c_str() ; StreamToLog(INFO);
66  m_ss << " m_distance_between_vertices " << m_distance_between_vertices; StreamToLog(INFO);
67  m_ss << " m_wall_like_distance " << m_wall_like_distance; StreamToLog(INFO);
68  m_ss << " m_water_like_threshold_number_of_pmts " << m_water_like_threshold_number_of_pmts; StreamToLog(INFO);
69  m_ss << " m_wall_like_threshold_number_of_pmts " << m_wall_like_threshold_number_of_pmts; StreamToLog(INFO);
70  m_ss << " m_coalesce_time " << m_coalesce_time; StreamToLog(INFO);
71  m_ss << " m_trigger_gate_up " << m_trigger_gate_up; StreamToLog(INFO);
72  m_ss << " m_trigger_gate_down " << m_trigger_gate_down; StreamToLog(INFO);
73  m_ss << " m_output_txt " << m_output_txt; StreamToLog(INFO);
74  m_ss << " m_correct_mode " << m_correct_mode; StreamToLog(INFO);
75  m_ss << " m_n_direction_bins_theta " << m_n_direction_bins_theta; StreamToLog(INFO);
76  m_ss << " m_cylindrical_grid " << m_cylindrical_grid; StreamToLog(INFO);
77  m_ss << " m_costheta_cone_cut " << m_costheta_cone_cut; StreamToLog(INFO);
78  m_ss << " m_select_based_on_cone " << m_select_based_on_cone; StreamToLog(INFO);
79  m_ss << " m_write_output_mode " << m_write_output_mode; StreamToLog(INFO);
80  m_ss << " m_max_n_hits_per_job " << m_max_n_hits_per_job; StreamToLog(INFO);
81  m_ss << " m_trigger_threshold_adjust_for_noise " << m_trigger_threshold_adjust_for_noise; StreamToLog(INFO);
82  m_ss << " m_num_blocks_y " << m_num_blocks_y; StreamToLog(INFO);
83  m_ss << " m_num_threads_per_block_y " << m_num_threads_per_block_y; StreamToLog(INFO);
84  m_ss << " m_num_threads_per_block_x " << m_num_threads_per_block_x; StreamToLog(INFO);
85  m_ss << " m_return_vertex " << m_return_vertex; StreamToLog(INFO);
86  m_ss << " m_return_direction " << m_return_direction; StreamToLog(INFO);
87 
88  m_trigger_save_window_pre = TimeDelta(-m_trigger_gate_down);
89  m_trigger_save_window_post = TimeDelta(m_trigger_gate_up);
90 
91  // gpu_daq_initialize(PMTFile,DetectorFile,ParameterFile);
92 
93 #ifdef GPU
94  // GPU_daq::test_vertices_initialize();
95 
96 
97  std::vector<int> tube_no;
98  std::vector<float> tube_x;
99  std::vector<float> tube_y;
100  std::vector<float> tube_z;
101  for( std::vector<PMTInfo>::const_iterator ip=m_data->IDGeom.begin(); ip!=m_data->IDGeom.end(); ip++){
102  tube_no.push_back(ip->m_tubeno);
103  tube_x.push_back(ip->m_x);
104  tube_y.push_back(ip->m_y);
105  tube_z.push_back(ip->m_z);
106  }
107 
108 
109 
110  GPU_daq::test_vertices_initialize_ToolDAQ(m_data->detector_length, m_data->detector_radius, m_data->pmt_radius, ParameterFile, tube_no, tube_x, tube_y, tube_z, m_data->IDPMTDarkRate*1000,
111  m_distance_between_vertices,
112  m_wall_like_distance,
113  m_water_like_threshold_number_of_pmts,
114  m_wall_like_threshold_number_of_pmts,
115  m_coalesce_time,
116  m_trigger_gate_up,
117  m_trigger_gate_down,
118  m_output_txt,
119  m_correct_mode,
120  m_n_direction_bins_theta,
121  m_cylindrical_grid,
122  m_costheta_cone_cut,
123  m_select_based_on_cone,
124  m_trigger_threshold_adjust_for_noise,
125  m_max_n_hits_per_job,
126  m_num_blocks_y,
127  m_num_threads_per_block_y,
128  m_num_threads_per_block_x,
129  m_write_output_mode,
130  m_return_vertex,
131  m_return_direction
132 );
133 
134 #else
135 
136  trigger_gate_up = m_trigger_gate_up; // ns
137  trigger_gate_down = m_trigger_gate_down; // ns
139 
140 #endif
141 
142  int npmts = m_data->IDNPMTs;
143  double dark_rate_kHZ = m_data->IDPMTDarkRate;
144  double dark_rate_Hz = dark_rate_kHZ * 1000;
145  double average_occupancy = dark_rate_Hz * m_coalesce_time * npmts;
146  m_time_int.reserve(2*(int)average_occupancy);
147 
148  // can acess variables directly like this and would be good if you could impliment in your code
149 
150  float dark_rate;
151  m_variables.Get("dark_rate",dark_rate);
152 
153  //to do this in your code instead of passing the three strings you could just do
154 
155  //gpu_daq_initialize(m_variables);
156 
157  // then in your code you can include
158  //#include "Store.h"
159  // gpu_daq_initialize(Store variables);
160 
161  //and pull them out with the get function in the same way
162 
163  if(m_stopwatch) Log(m_stopwatch->Result("Initialise"), INFO, m_verbose);
164 
165  return true;
166 }
167 
168 
171 
172  std::vector<SubSample> & samples = m_data->IDSamples;
173 
174  for( std::vector<SubSample>::const_iterator is=samples.begin(); is!=samples.end(); ++is){
175 
176  std::vector<int> trigger_ns;
177  std::vector<int> trigger_ts;
178  std::vector<double> trigger_vtx_xs;
179  std::vector<double> trigger_vtx_ys;
180  std::vector<double> trigger_vtx_zs;
181  std::vector<double> trigger_dir_xs;
182  std::vector<double> trigger_dir_ys;
183  std::vector<double> trigger_dir_zs;
184  //Copy the times from the `float` format in the DataModel to `int` format
185  //This is not strictly required for the CPU version of the algorithm, but is done for consistency of results
186  m_time_int.clear();
187  for(unsigned int i = 0; i < is->m_time.size(); i++) {
188  m_time_int.push_back(is->m_time[i]);
189  }
190 
191 #ifdef GPU
192  if( m_time_int.size() )
193  GPU_daq::test_vertices_execute(is->m_PMTid, m_time_int, &trigger_ns, &trigger_ts, &trigger_vtx_xs, &trigger_vtx_ys, &trigger_vtx_zs, &trigger_dir_xs, &trigger_dir_ys, &trigger_dir_zs);
194 #else
195  CPU_test_vertices_execute(is->m_PMTid, m_time_int, &trigger_ns, &trigger_ts);
196 #endif
197 
198  for(int i=0; i<trigger_ns.size(); i++){
199  std::vector<float> info;
200  info.push_back(trigger_ns[i]);
201 #ifdef GPU
202  if( m_return_vertex ){
203  info.push_back(trigger_vtx_xs[i]);
204  info.push_back(trigger_vtx_ys[i]);
205  info.push_back(trigger_vtx_zs[i]);
206  }
207  if( m_return_direction ){
208  info.push_back(trigger_dir_xs[i]);
209  info.push_back(trigger_dir_ys[i]);
210  info.push_back(trigger_dir_zs[i]);
211  }
212 #endif
213  m_data->IDTriggers.AddTrigger(kTriggerUndefined,
214  TimeDelta(trigger_ts[i]) - m_trigger_save_window_pre + is->m_timestamp,
215  TimeDelta(trigger_ts[i]) + m_trigger_save_window_post + is->m_timestamp,
216  TimeDelta(trigger_ts[i]) - m_trigger_mask_window_pre + is->m_timestamp,
217  TimeDelta(trigger_ts[i]) + m_trigger_mask_window_post + is->m_timestamp,
218  TimeDelta(trigger_ts[i]) + is->m_timestamp,
219  info);
220 
221  m_ss << " trigger! time "<< trigger_ts[i] << " -> " << TimeDelta(trigger_ts[i] ) + is->m_timestamp << " nhits " << trigger_ns[i]; StreamToLog(INFO);
222  }
223 
224  }
225  //Now we have all the triggers, get the SubSample to determine
226  // - which trigger readout windows each hit is associated with
227  // - which hits should be masked from future triggers
228  for( std::vector<SubSample>::iterator is=samples.begin(); is!=samples.end(); ++is) {
229  (*is).TellMeAboutTheTriggers(m_data->IDTriggers, m_verbose);
230  }//loop over SubSamples
231 
232 
234 
235  return true;
236 
237 }
238 
239 
241  if(m_stopwatch) {
243  m_stopwatch->Start();
244  }
245 
246 #ifdef GPU
248 #else
250 #endif
251 
252  if(m_stopwatch) {
253  Log(m_stopwatch->Result("Finalise"), INFO, m_verbose);
254  delete m_stopwatch;
255  }
256 
257  return true;
258 }
259 
260 
262 
263  use_verbose = false;
264 
265  n_PMTs = m_data->IDNPMTs;
266  if( !n_PMTs ) return 0;
267  PMT_x = (double *)malloc(n_PMTs*sizeof(double));
268  PMT_y = (double *)malloc(n_PMTs*sizeof(double));
269  PMT_z = (double *)malloc(n_PMTs*sizeof(double));
270  int n_PMTs_counter = 0;
271  for( std::vector<PMTInfo>::const_iterator ip=m_data->IDGeom.begin(); ip!=m_data->IDGeom.end(); ip++){
272  PMT_x[n_PMTs_counter] = ip->m_x;
273  PMT_y[n_PMTs_counter] = ip->m_y;
274  PMT_z[n_PMTs_counter] = ip->m_z;
275  n_PMTs_counter++;
276  }
277  printf(" [2] detector contains %d PMTs \n", n_PMTs);
278 
279  //read_user_parameters();
280  {
281  twopi = 2.*acos(-1.);
282  speed_light_water = 29.9792/1.3330; // speed of light in water, cm/ns
283  //double speed_light_water = 22.490023;
284 
285  cerenkov_costheta =1./1.3330;
289 
290  dark_rate = m_data->IDPMTDarkRate*1000; // Hz
293  wall_like_distance = m_wall_like_distance; // units of distance between vertices
294  time_step_size = (unsigned int)(sqrt(3.)*distance_between_vertices/(4.*speed_light_water)); // ns
295  int extra_threshold = 0;
297  extra_threshold = (int)(dark_rate*n_PMTs*2.*time_step_size*1.e-9); // to account for dark current occupancy
298  }
306 
310 
311  }
312 
313  printf(" [2] --- user parameters \n");
314  printf(" [2] dark_rate %f \n", dark_rate);
315  printf(" [2] distance between test vertices = %f cm \n", distance_between_vertices);
316  printf(" [2] wall_like_distance %f \n", wall_like_distance);
317  printf(" [2] water_like_threshold_number_of_pmts = %d \n", water_like_threshold_number_of_pmts);
318  printf(" [2] wall_like_threshold_number_of_pmts %d \n", wall_like_threshold_number_of_pmts);
319  printf(" [2] coalesce_time = %f ns \n", coalesce_time);
320  printf(" [2] trigger_gate_up = %f ns \n", trigger_gate_up);
321  printf(" [2] trigger_gate_down = %f ns \n", trigger_gate_down);
322  printf(" [2] max_n_hits_per_job = %d \n", max_n_hits_per_job);
323  printf(" [2] output_txt %d \n", output_txt);
324  printf(" [2] correct_mode %d \n", correct_mode);
325  printf(" [2] cylindrical_grid %d \n", cylindrical_grid);
326  printf(" [2] time step size = %d ns \n", time_step_size);
327  printf(" [2] write_output_mode %d \n", write_output_mode);
328  if( correct_mode == 9 ){
329  printf(" [2] n_direction_bins_theta %d, n_direction_bins_phi %d, n_direction_bins %d \n",
331  }
332 
333 
334 
335 
337  // read detector ////
339  // set: detector_height, detector_radius, pmt_radius
340  detector_height = m_data->detector_length;
341  detector_radius = m_data->detector_radius;
342  printf(" [2] detector height %f cm, radius %f cm \n", detector_height, detector_radius);
343 
344 
345 
346 
348  // make test vertices //
350  // set: n_test_vertices, n_water_like_test_vertices, vertex_x, vertex_y, vertex_z
351  // use: detector_height, detector_radius
353 
354 
355 
357  // table of times_of_flight //
359  // set: host_times_of_flight, time_offset
360  // use: n_test_vertices, vertex_x, vertex_y, vertex_z, n_PMTs, PMT_x, PMT_y, PMT_z
361  // malloc: host_times_of_flight
363 
364  if( correct_mode == 9 ){
366  // table of directions //
368  // set: host_directions_phi, host_directions_cos_theta
369  // use: n_test_vertices, vertex_x, vertex_y, vertex_z, n_PMTs, PMT_x, PMT_y, PMT_z
370  // malloc: host_directions_phi, host_directions_cos_theta
372  }
373 
374 
375  return 1;
376 
377 }
378 
380 
381  printf(" [2] --- make test vertices \n");
382  float semiheight = detector_height/2.;
383  n_test_vertices = 0;
384 
385 
386  if( !cylindrical_grid ){
387 
388  // 1: count number of test vertices
389  for(int i=-1*semiheight; i <= semiheight; i+=distance_between_vertices) {
392  if(pow(j,2)+pow(k,2) > pow(detector_radius,2))
393  continue;
394  n_test_vertices++;
395  }
396  }
397  }
398  vertex_x = (double *)malloc(n_test_vertices*sizeof(double));
399  vertex_y = (double *)malloc(n_test_vertices*sizeof(double));
400  vertex_z = (double *)malloc(n_test_vertices*sizeof(double));
401 
402  // 2: assign coordinates to test vertices
403  // water-like events
404  n_test_vertices = 0;
405  for(int i=-1*semiheight; i <= semiheight; i+=distance_between_vertices) {
408 
409 
410  if(
411  // skip endcap region
412  abs(i) > semiheight - wall_like_distance*distance_between_vertices ||
413  // skip sidewall region
415  ) continue;
416 
417  vertex_x[n_test_vertices] = j*1.;
418  vertex_y[n_test_vertices] = k*1.;
419  vertex_z[n_test_vertices] = i*1.;
420  n_test_vertices++;
421  }
422  }
423  }
425 
426  // wall-like events
427  for(int i=-1*semiheight; i <= semiheight; i+=distance_between_vertices) {
430 
431  if(
432  abs(i) > semiheight - wall_like_distance*distance_between_vertices ||
434  ){
435 
436  if(pow(j,2)+pow(k,2) > pow(detector_radius,2)) continue;
437 
438  vertex_x[n_test_vertices] = j*1.;
439  vertex_y[n_test_vertices] = k*1.;
440  vertex_z[n_test_vertices] = i*1.;
441  n_test_vertices++;
442  }
443  }
444  }
445  }
446 
447  }else{ // cylindrical grid
448 
450  double distance_vertical = detector_height/n_vertical;
451  int n_radial = 2.*detector_radius/distance_between_vertices;
452  double distance_radial = 2.*detector_radius/n_radial;
453  int n_angular;
454  double distance_angular;
455 
456  printf(" [2] distance_between_vertices %f, distance_vertical %f, distance_radial %f \n",
457  distance_between_vertices, distance_vertical, distance_radial);
458 
459  double the_r, the_z, the_phi;
460  bool first = false; // true: add extra layer near wall
461  // false: regular spacing
462 
463  bool add_extra_layer = first;
464 
465  // 1: count number of test vertices
466  the_r = detector_radius;
467  while( the_r >= 0. ){
468  n_angular = twopi*the_r / distance_between_vertices;
469  distance_angular = twopi/n_angular;
470 
471  the_z = -semiheight;
472 
473  while( the_z <= semiheight){
474 
475  the_phi = 0.;
476  while( the_phi < twopi - distance_angular/2. ){
477 
478  n_test_vertices ++;
479 
480  if( the_r == 0. ) break;
481  the_phi += distance_angular;
482  }
483 
484 
485  if( add_extra_layer ){
486  if( the_z + semiheight < 0.3*distance_vertical ) // only true at bottom endcap
487  the_z += distance_vertical/2.;
488  else if( semiheight - the_z < 0.7*distance_vertical ) // only true near top endcap
489  the_z += distance_vertical/2.;
490  else
491  the_z += distance_vertical;
492  }else{
493  the_z += distance_vertical;
494  }
495  }
496  if( first ){
497  the_r -= distance_radial/2.;
498  first = false;
499  }
500  else{
501  the_r -= distance_radial;
502  }
503  }
504 
505  vertex_x = (double *)malloc(n_test_vertices*sizeof(double));
506  vertex_y = (double *)malloc(n_test_vertices*sizeof(double));
507  vertex_z = (double *)malloc(n_test_vertices*sizeof(double));
508 
509  first = add_extra_layer;
510  // 2: assign coordinates to test vertices
511  // water-like events
512  n_test_vertices = 0;
513 
514  the_r = detector_radius;
515  while( the_r >= 0. ){
516 
517  // skip sidewall region
519 
520  n_angular = twopi*the_r / distance_between_vertices;
521  distance_angular = twopi/n_angular;
522 
523  the_z = -semiheight;
524 
525  while( the_z <= semiheight){
526 
527  // skip endcap region
528  if( fabs(the_z) <= semiheight - wall_like_distance*distance_between_vertices ){
529 
530  the_phi = 0.;
531  while( the_phi < twopi - distance_angular/2. ){
532 
533  vertex_x[n_test_vertices] = the_r*cos(the_phi);
534  vertex_y[n_test_vertices] = the_r*sin(the_phi);
535  vertex_z[n_test_vertices] = the_z;
536  n_test_vertices ++;
537 
538  if( the_r == 0. ) break;
539  the_phi += distance_angular;
540  }
541  }
542 
543  if( add_extra_layer ){
544  if( the_z + semiheight < 0.3*distance_vertical ) // only true at bottom endcap
545  the_z += distance_vertical/2.;
546  else if( semiheight - the_z < 0.7*distance_vertical ) // only true near top endcap
547  the_z += distance_vertical/2.;
548  else
549  the_z += distance_vertical;
550  }else{
551  the_z += distance_vertical;
552  }
553  }
554 
555  }
556  if( first ){
557  the_r -= distance_radial/2.;
558  first = false;
559  }
560  else{
561  the_r -= distance_radial;
562  }
563  }
564 
565 
567 
568  first = add_extra_layer;
569  // wall-like events
570  the_r = detector_radius;
571  while( the_r >= 0. ){
572 
573  n_angular = twopi*the_r / distance_between_vertices;
574  distance_angular = twopi/n_angular;
575 
576  the_z = -semiheight;
577 
578  while( the_z <= semiheight){
579 
580  if( fabs(the_z) > semiheight - wall_like_distance*distance_between_vertices ||
582 
583  the_phi = 0.;
584  while( the_phi < twopi - distance_angular/2. ){
585 
586  vertex_x[n_test_vertices] = the_r*cos(the_phi);
587  vertex_y[n_test_vertices] = the_r*sin(the_phi);
588  vertex_z[n_test_vertices] = the_z;
589  n_test_vertices ++;
590 
591  if( the_r == 0. ) break;
592  the_phi += distance_angular;
593  }
594  }
595  if( add_extra_layer ){
596  if( the_z + semiheight < 0.3*distance_vertical ) // only true at bottom endcap
597  the_z += distance_vertical/2.;
598  else if( semiheight - the_z < 0.7*distance_vertical ) // only true near top endcap
599  the_z += distance_vertical/2.;
600  else
601  the_z += distance_vertical;
602  }else{
603  the_z += distance_vertical;
604  }
605  }
606  if( first ){
607  the_r -= distance_radial/2.;
608  first = false;
609  }
610  else{
611  the_r -= distance_radial;
612  }
613  }
614 
615 
616  }
617 
618  printf(" [2] made %d test vertices \n", n_test_vertices);
619 
620  return;
621 
622 }
623 
624 
626 
627  printf(" [2] --- fill times_of_flight \n");
629  printf(" [2] speed_light_water %f \n", speed_light_water);
630  if( correct_mode == 10 ){
631  host_light_dx = (float*)malloc(n_test_vertices*n_PMTs * sizeof(double));
632  host_light_dy = (float*)malloc(n_test_vertices*n_PMTs * sizeof(double));
633  host_light_dz = (float*)malloc(n_test_vertices*n_PMTs * sizeof(double));
634  host_light_dr = (float*)malloc(n_test_vertices*n_PMTs * sizeof(double));
635  }
636  unsigned int distance_index;
637  time_offset = 0.;
638  for(unsigned int ip=0; ip<n_PMTs; ip++){
639  for(unsigned int iv=0; iv<n_test_vertices; iv++){
640  distance_index = get_distance_index(ip + 1, n_PMTs*iv);
641  host_times_of_flight[distance_index] = sqrt(pow(vertex_x[iv] - PMT_x[ip],2) + pow(vertex_y[iv] - PMT_y[ip],2) + pow(vertex_z[iv] - PMT_z[ip],2))/speed_light_water;
642  if( correct_mode == 10 ){
643  host_light_dx[distance_index] = PMT_x[ip] - vertex_x[iv];
644  host_light_dy[distance_index] = PMT_y[ip] - vertex_y[iv];
645  host_light_dz[distance_index] = PMT_z[ip] - vertex_z[iv];
646  host_light_dr[distance_index] = sqrt(pow(host_light_dx[distance_index],2) + pow(host_light_dy[distance_index],2) + pow(host_light_dz[distance_index],2));
647  }
648  if( host_times_of_flight[distance_index] > time_offset )
649  time_offset = host_times_of_flight[distance_index];
650 
651  }
652  }
653  //print_times_of_flight();
654 
655  return;
656 }
657 
658 
660 
661  printf(" [2] --- fill directions \n");
662  printf(" [2] cerenkov_angle_water %f \n", cerenkov_angle_water);
664  float dx, dy, dz, dr, phi, cos_theta, sin_theta;
665  float phi2, cos_theta2, angle;
666  unsigned int dir_index_at_angles;
667  unsigned int dir_index_at_pmt;
668  for(unsigned int ip=0; ip<n_PMTs; ip++){
669  for(unsigned int iv=0; iv<n_test_vertices; iv++){
670  dx = PMT_x[ip] - vertex_x[iv];
671  dy = PMT_y[ip] - vertex_y[iv];
672  dz = PMT_z[ip] - vertex_z[iv];
673  dr = sqrt(pow(dx,2) + pow(dy,2) + pow(dz,2));
674  phi = atan2(dy,dx);
675  // light direction
676  cos_theta = dz/dr;
677  sin_theta = sqrt(1. - pow(cos_theta,2));
678  // particle direction
679  for(unsigned int itheta = 0; itheta < n_direction_bins_theta; itheta++){
680  cos_theta2 = -1. + 2.*itheta/(n_direction_bins_theta - 1);
681  for(unsigned int iphi = 0; iphi < n_direction_bins_phi; iphi++){
682  phi2 = 0. + twopi*iphi/n_direction_bins_phi;
683 
684  if( (itheta == 0 || itheta + 1 == n_direction_bins_theta ) && iphi != 0 ) break;
685 
686  // angle between light direction and particle direction
687  angle = acos( sin_theta*sqrt(1 - pow(cos_theta2,2)) * cos(phi - phi2) + cos_theta*cos_theta2 );
688 
689  dir_index_at_angles = get_direction_index_at_angles(iphi, itheta);
690  dir_index_at_pmt = get_direction_index_at_pmt(ip, iv, dir_index_at_angles);
691 
692  //printf(" [2] phi %f ctheta %f phi' %f ctheta' %f angle %f dir_index_at_angles %d dir_index_at_pmt %d \n",
693  // phi, cos_theta, phi2, cos_theta2, angle, dir_index_at_angles, dir_index_at_pmt);
694 
695  host_directions_for_vertex_and_pmt[dir_index_at_pmt]
696  = (bool)(fabs(angle - cerenkov_angle_water) < twopi/(2.*n_direction_bins_phi));
697  }
698  }
699  }
700  }
701  //print_directions();
702 
703  return;
704 }
705 
706 
707 
708 
709 unsigned int test_vertices::get_distance_index(unsigned int pmt_id, unsigned int vertex_block){
710  // block = (npmts) * (vertex index)
711 
712  return pmt_id - 1 + vertex_block;
713 
714 }
715 
716 unsigned int test_vertices::get_time_index(unsigned int hit_index, unsigned int vertex_block){
717  // block = (n time bins) * (vertex index)
718 
719  return hit_index + vertex_block;
720 
721 }
722 
723  unsigned int test_vertices::get_direction_index_at_angles(unsigned int iphi, unsigned int itheta){
724 
725  if( itheta == 0 ) return 0;
726  if( itheta + 1 == n_direction_bins_theta ) return n_direction_bins - 1;
727 
728  return 1 + (itheta - 1) * n_direction_bins_phi + iphi;
729 
730 }
731 
732 unsigned int test_vertices::get_direction_index_at_pmt(unsigned int pmt_id, unsigned int vertex_index, unsigned int direction_index){
733 
734  // pmt id 1 ... pmt id p
735  // [ vertex 1 vertex 2 ... vertex m] ... [vertex 1 ... vertex m]
736  // [(dir 1 ... dir n) (dir 1 ... dir n) ... (dir 1 ... dir n)] ...
737 
738  return n_direction_bins * (pmt_id * n_test_vertices + vertex_index) + direction_index ;
739 
740 }
741 
742 unsigned int test_vertices::get_direction_index_at_time(unsigned int time_bin, unsigned int vertex_index, unsigned int direction_index){
743 
744  // time 1 ... time p
745  // [ vertex 1 vertex 2 ... vertex m] ... [vertex 1 ... vertex m]
746  // [(dir 1 ... dir n) (dir 1 ... dir n) ... (dir 1 ... dir n)] ...
747 
748  return n_direction_bins* (time_bin * n_test_vertices + vertex_index ) + direction_index ;
749 
750 }
751 
752 
754 
755 
757  // deallocate global memory //
759  if( use_verbose )
760  printf(" [2] --- deallocate tofs memory \n");
762 
763 
764 
765  return 1;
766 
767 }
768 
770 
771  if( correct_mode == 9 ){
773  }
774 
775  free(PMT_x);
776  free(PMT_y);
777  free(PMT_z);
778  free(vertex_x);
779  free(vertex_y);
780  free(vertex_z);
781  free(host_times_of_flight);
782  if( correct_mode == 10 ){
783  free(host_light_dx);
784  free(host_light_dy);
785  free(host_light_dz);
786  free(host_light_dr);
787  }
788 
789  return;
790 }
791 
792 
793 
794 int test_vertices::CPU_test_vertices_execute(std::vector<int> PMTid, std::vector<int> time, std::vector<int> * trigger_ns, std::vector<int> * trigger_ts){
795 
796  n_events = 0;
797 
798  while( 1 ){
799 
800  printf(" [2] ------ analyzing event %d \n", n_events+1);
801 
803  // read input //
805  // set: n_hits, host_ids, host_times, time_offset, n_time_bins
806  // use: time_offset, n_test_vertices
807  // memcpy: constant_n_time_bins, constant_n_hits
808  int earliest_time = 0;
809  // if( !read_the_input() ){
810  if( !read_the_input_ToolDAQ(PMTid, time, &earliest_time) ){
811  write_output();
812  n_events ++;
813  continue;
814  }
815 
816 
817 
819  // allocate candidates memory on host //
821  // use: n_time_bins
822  // malloc: host_max_number_of_pmts_in_time_bin, host_vertex_with_max_n_pmts
824 
825 
826 
828  // execute kernel //
830  if( correct_mode == 8 ){
831  printf(" [2] --- execute kernel to correct times and get n pmts per time bin \n");
833  }
834 
835 
836 
837 
838 
840  // find candidates above threshold //
842  if( use_verbose )
843  printf(" [2] --- execute candidates kernel \n");
845 
846 
847 
849  // choose candidates above threshold //
851  if( use_verbose )
852  printf(" [2] --- choose candidates above threshold \n");
854 
855 
856 
858  // coalesce triggers //
861 
862 
863 
864 
866  // separate triggers into gates //
868  separate_triggers_into_gates(trigger_ns, trigger_ts);
869 
870 
871 
873  // write output //
875  write_output();
876 
878  // deallocate event memory //
880  if( use_verbose )
881  printf(" [2] --- deallocate memory \n");
883 
884  n_events ++;
885 
886  break;
887  }
888 
889  printf(" [2] ------ analyzed %d events \n", n_events);
890 
891 
892  return 1;
893 }
894 
895 
896 bool test_vertices::read_the_input_ToolDAQ(std::vector<int> PMTids, std::vector<int> times, int * earliest_time){
897 
898  printf(" [2] --- read input \n");
899  n_hits = PMTids.size();
900  if( !n_hits ) return false;
901  if( n_hits != times.size() ){
902  printf(" [2] n PMT ids %d but n times %d \n", n_hits, times.size());
903  return false;
904  }
905  printf(" [2] input contains %d hits \n", n_hits);
906  host_ids = (unsigned int *)malloc(n_hits*sizeof(unsigned int));
907  host_times = (unsigned int *)malloc(n_hits*sizeof(unsigned int));
908 
909  //copy all hit times from `int` to `unsigned int` arrays
910  // `unsigned int` operations are faster on GPU (done here for consistency)
911  // if( !read_input() ) return false;
912  // read_input()
913  {
914  int min = INT_MAX;
915  int max = INT_MIN;
916  int time;
917  for(int i=0; i<PMTids.size(); i++){
918  time = int(floor(times[i]));
919  host_times[i] = time;
920  host_ids[i] = PMTids[i];
921  // printf(" [2] input %d PMT %d time %d \n", i, host_ids[i], host_times[i]);
922  if( time > max ) max = time;
923  if( time < min ) min = time;
924  }
925  //ensure there are no negatively underflowed `unsigned int` times
926  if( min < 0 ){
927  for(int i=0; i<PMTids.size(); i++){
928  host_times[i] -= min;
929  }
930  max -= min;
931  min -= min;
932  }
933  the_max_time = max;
934  *earliest_time = min - min % time_step_size;
935  }
936 
937 
938  //time_offset = 600.; // set to constant to match trevor running
939  n_time_bins = int(floor((the_max_time + time_offset)/time_step_size))+1; // floor returns the integer below
940  printf(" [2] input max_time %d, n_time_bins %d \n", the_max_time, n_time_bins);
941  printf(" [2] time_offset = %d ns \n", time_offset);
942  //print_input();
943 
944  return true;
945 }
946 
948 
949  if( output_txt ){
950  FILE *of=fopen(output_file.c_str(), "a");
951 
952  int trigger;
953  if( write_output_mode == 0 ){
954  // output 1 if there is a trigger, 0 otherwise
955  trigger = (trigger_pair_vertex_time.size() > 0 ? 1 : 0);
956  }
957 
958  if( write_output_mode == 1 ){
959  // output the n of triggers
960  trigger = trigger_pair_vertex_time.size();
961  }
962 
963  if( write_output_mode == 2 ){
964  // output the n of water-like triggers
965  int trigger = 0;
966  for(std::vector<std::pair<unsigned int,unsigned int> >::const_iterator itrigger=trigger_pair_vertex_time.begin(); itrigger != trigger_pair_vertex_time.end(); ++itrigger){
967  if( itrigger->first < n_water_like_test_vertices )
968  trigger ++;
969  }
970  }
971 
972  if( write_output_mode == 0 || write_output_mode == 1 || write_output_mode == 2 ){
973  fprintf(of, " %d \n", trigger);
974  }
975 
976  if( write_output_mode == 3 ){
977  unsigned int triggertime, trigger_index;
978  // output reconstructed vertices
979  for(std::vector<std::pair<unsigned int,unsigned int> >::const_iterator itrigger=trigger_pair_vertex_time.begin(); itrigger != trigger_pair_vertex_time.end(); ++itrigger){
980  triggertime = itrigger->second*time_step_size - time_offset;
981  if( correct_mode == 10 ){
982  trigger_index = itrigger - trigger_pair_vertex_time.begin();
983  fprintf(of, " %d %f %f %f %d %d %d \n", n_events, vertex_x[itrigger->first], vertex_y[itrigger->first], vertex_z[itrigger->first], triggertime, trigger_npmts_in_time_bin.at(trigger_index), trigger_npmts_in_cone_in_time_bin.at(trigger_index));
984  }else{
985  fprintf(of, " %d %f %f %f %d \n", n_events, vertex_x[itrigger->first], vertex_y[itrigger->first], vertex_z[itrigger->first], triggertime);
986  }
987  }
988  }
989 
990  if( write_output_mode == 4 ){
991  // output non-corrected and corrected times for best vertex
992  int max_n_pmts = 0;
993  unsigned int best_vertex;
994  for(std::vector<std::pair<unsigned int,unsigned int> >::const_iterator itrigger=trigger_pair_vertex_time.begin(); itrigger != trigger_pair_vertex_time.end(); ++itrigger){
995  unsigned int vertex_index = itrigger->first;
996  unsigned int time_index = itrigger->second;
997  unsigned int local_n_pmts = host_max_number_of_pmts_in_time_bin[itrigger->second];
998  if( local_n_pmts > max_n_pmts ){
999  max_n_pmts = local_n_pmts;
1000  best_vertex = vertex_index;
1001  }
1002  }
1003  unsigned int distance_index;
1004  double tof;
1005  double corrected_time;
1006 
1007  for(unsigned int i=0; i<n_hits; i++){
1008 
1009  distance_index = get_distance_index(host_ids[i], n_PMTs*best_vertex);
1010  tof = host_times_of_flight[distance_index];
1011  corrected_time = host_times[i]-tof;
1012 
1013  fprintf(of, " %d %d %f \n", host_ids[i], host_times[i], corrected_time);
1014  //fprintf(of, " %d %f \n", host_ids[i], corrected_time);
1015  }
1016  }
1017 
1018  fclose(of);
1019  }
1020 
1021 
1022 }
1023 
1025 
1026  printf(" [2] --- allocate candidates memory on host \n");
1027 
1029  host_vertex_with_max_n_pmts = (unsigned int *)malloc(n_time_bins*sizeof(unsigned int));
1030  host_n_pmts_per_time_bin = (unsigned int *)malloc(n_time_bins*n_test_vertices*sizeof(unsigned int));
1031 
1032  if( correct_mode == 10 ){
1033  host_max_number_of_pmts_in_cone_in_time_bin = (unsigned int *)malloc(n_time_bins*sizeof(unsigned int));
1034  }
1035 
1036  return;
1037 
1038 }
1039 
1040 
1042 
1043  unsigned int distance_index;
1044  double tof;
1045  double corrected_time;
1046  unsigned int bin;
1047 
1048  for(unsigned int i=0; i<n_hits; i++){
1049  for(unsigned int iv=0; iv<n_test_vertices; iv++){
1050 
1051  distance_index = get_distance_index(host_ids[i], n_PMTs*iv);
1052  tof = host_times_of_flight[distance_index];
1053  corrected_time = host_times[i]-tof + time_offset;
1054 
1055  bin = corrected_time/time_step_size + n_time_bins*iv;
1056 
1057  ct[bin] ++;
1058  }
1059  }
1060 
1061 
1062 }
1063 
1064 
1066 
1067  for(unsigned int time_bin_index=0; time_bin_index<n_time_bins; time_bin_index++){
1068 
1069  unsigned int number_of_pmts_in_time_bin = 0;
1070  unsigned int time_index;
1071  histogram_t max_number_of_pmts_in_time_bin=0;
1072  unsigned int vertex_with_max_n_pmts = 0;
1073 
1074  for(unsigned int iv=0;iv<n_test_vertices;iv++) { // loop over test vertices
1075  // sum the number of hit PMTs in this time window and the next
1076 
1077  time_index = time_bin_index + n_time_bins*iv;
1078  if( time_index >= n_time_bins*n_test_vertices - 1 ) continue;
1079  number_of_pmts_in_time_bin = np[time_index] + np[time_index+1];
1080  if( number_of_pmts_in_time_bin >= max_number_of_pmts_in_time_bin ){
1081  max_number_of_pmts_in_time_bin = number_of_pmts_in_time_bin;
1082  vertex_with_max_n_pmts = iv;
1083  }
1084  }
1085 
1086  mnp[time_bin_index] = max_number_of_pmts_in_time_bin;
1087  vmnp[time_bin_index] = vertex_with_max_n_pmts;
1088  }
1089 
1090  return;
1091 
1092 }
1093 
1095 
1098  if( correct_mode == 10 ){
1100  }
1101 
1102  unsigned int the_threshold;
1103  unsigned int number_of_pmts_to_cut_on;
1104 
1105  for(unsigned int time_bin = 0; time_bin<n_time_bins - 1; time_bin++){ // loop over time bins
1106  // n_time_bins - 1 as we are checking the i and i+1 at the same time
1107 
1109  the_threshold = water_like_threshold_number_of_pmts;
1110  else
1111  the_threshold = wall_like_threshold_number_of_pmts;
1112 
1113  number_of_pmts_to_cut_on = host_max_number_of_pmts_in_time_bin[time_bin];
1114  if( correct_mode == 10 ){
1115  if( select_based_on_cone ){
1116  number_of_pmts_to_cut_on = host_max_number_of_pmts_in_cone_in_time_bin[time_bin];
1117  }
1118  }
1119 
1120  if(number_of_pmts_to_cut_on > the_threshold) {
1121 
1122  if( use_verbose ){
1123  printf(" [2] time %f vertex (%f, %f, %f) npmts %d \n", (time_bin + 2)*time_step_size - time_offset, vertex_x[host_vertex_with_max_n_pmts[time_bin]], vertex_y[host_vertex_with_max_n_pmts[time_bin]], vertex_z[host_vertex_with_max_n_pmts[time_bin]], number_of_pmts_to_cut_on);
1124  }
1125 
1126  candidate_trigger_pair_vertex_time.push_back(std::make_pair(host_vertex_with_max_n_pmts[time_bin],time_bin+1));
1128  if( correct_mode == 10 ){
1130  }
1131  }
1132 
1133  }
1134 
1135  if( use_verbose )
1136  printf(" [2] n candidates: %d \n", candidate_trigger_pair_vertex_time.size());
1137 }
1138 
1139 
1140 
1142 
1143  trigger_pair_vertex_time.clear();
1144  trigger_npmts_in_time_bin.clear();
1145  if( correct_mode == 10 ){
1147  }
1148 
1149  unsigned int vertex_index, time_upper, number_of_pmts_in_time_bin, number_of_pmts_in_cone_in_time_bin;
1150  unsigned int max_pmt=0,max_vertex_index=0,max_time=0,max_pmt_in_cone=0;
1151  bool first_trigger, last_trigger, coalesce_triggers;
1152  unsigned int trigger_index;
1153  for(std::vector<std::pair<unsigned int,unsigned int> >::const_iterator itrigger=candidate_trigger_pair_vertex_time.begin(); itrigger != candidate_trigger_pair_vertex_time.end(); ++itrigger){
1154 
1155  vertex_index = itrigger->first;
1156  time_upper = itrigger->second;
1157  trigger_index = itrigger - candidate_trigger_pair_vertex_time.begin();
1158  number_of_pmts_in_time_bin = candidate_trigger_npmts_in_time_bin.at(trigger_index);
1159  if( correct_mode == 10 ){
1160  number_of_pmts_in_cone_in_time_bin = candidate_trigger_npmts_in_cone_in_time_bin.at(trigger_index);
1161  }
1162 
1163  first_trigger = (trigger_index == 0);
1164  last_trigger = (trigger_index == candidate_trigger_pair_vertex_time.size()-1);
1165 
1166  if( first_trigger ){
1167  max_pmt = number_of_pmts_in_time_bin;
1168  max_vertex_index = vertex_index;
1169  max_time = time_upper;
1170  if( correct_mode == 10 ){
1171  max_pmt_in_cone = number_of_pmts_in_cone_in_time_bin;
1172  }
1173  }
1174  else{
1175  coalesce_triggers = (std::abs((int)(max_time - time_upper)) < coalesce_time/time_step_size);
1176 
1177  if( coalesce_triggers ){
1178  if( number_of_pmts_in_time_bin >= max_pmt) {
1179  max_pmt = number_of_pmts_in_time_bin;
1180  max_vertex_index = vertex_index;
1181  max_time = time_upper;
1182  if( correct_mode == 10 ){
1183  max_pmt_in_cone = number_of_pmts_in_cone_in_time_bin;
1184  }
1185  }
1186  }else{
1187  trigger_pair_vertex_time.push_back(std::make_pair(max_vertex_index,max_time));
1188  trigger_npmts_in_time_bin.push_back(max_pmt);
1189  max_pmt = number_of_pmts_in_time_bin;
1190  max_vertex_index = vertex_index;
1191  max_time = time_upper;
1192  if( correct_mode == 10 ){
1193  trigger_npmts_in_cone_in_time_bin.push_back(max_pmt_in_cone);
1194  max_pmt_in_cone = number_of_pmts_in_cone_in_time_bin;
1195  }
1196  }
1197  }
1198 
1199  if(last_trigger){
1200  trigger_pair_vertex_time.push_back(std::make_pair(max_vertex_index,max_time));
1201  trigger_npmts_in_time_bin.push_back(max_pmt);
1202  if( correct_mode == 10 ){
1203  trigger_npmts_in_cone_in_time_bin.push_back(max_pmt_in_cone);
1204  }
1205  }
1206 
1207  }
1208 
1209  for(std::vector<std::pair<unsigned int,unsigned int> >::const_iterator itrigger=trigger_pair_vertex_time.begin(); itrigger != trigger_pair_vertex_time.end(); ++itrigger)
1210  printf(" [2] coalesced trigger timebin %d vertex index %d \n", itrigger->first, itrigger->second);
1211 
1212  return;
1213 
1214 }
1215 
1216 
1217 void test_vertices::separate_triggers_into_gates(std::vector<int> * trigger_ns, std::vector<int> * trigger_ts){
1218 
1220  unsigned int trigger_index;
1221 
1222  unsigned int time_start=0;
1223  for(std::vector<std::pair<unsigned int,unsigned int> >::const_iterator itrigger=trigger_pair_vertex_time.begin(); itrigger != trigger_pair_vertex_time.end(); ++itrigger){
1224  //once a trigger is found, we must jump in the future before searching for the next
1225  if(itrigger->second > time_start) {
1226  unsigned int triggertime = itrigger->second*time_step_size - time_offset;
1227  final_trigger_pair_vertex_time.push_back(std::make_pair(itrigger->first,triggertime));
1228  time_start = triggertime + trigger_gate_up;
1229  trigger_index = itrigger - trigger_pair_vertex_time.begin();
1231  output_trigger_information.push_back(vertex_x[itrigger->first]);
1232  output_trigger_information.push_back(vertex_y[itrigger->first]);
1233  output_trigger_information.push_back(vertex_z[itrigger->first]);
1234  output_trigger_information.push_back(trigger_npmts_in_time_bin.at(trigger_index));
1235  output_trigger_information.push_back(triggertime);
1236 
1237  trigger_ns->push_back(trigger_npmts_in_time_bin.at(trigger_index));
1238  trigger_ts->push_back(triggertime);
1239 
1240  printf(" [2] triggertime: %d, npmts: %d, x: %f, y: %f, z: %f \n", triggertime, trigger_npmts_in_time_bin.at(trigger_index), vertex_x[itrigger->first], vertex_y[itrigger->first], vertex_z[itrigger->first]);
1241 
1242  /* if( output_txt ){ */
1243  /* FILE *of=fopen(output_file.c_str(), "w"); */
1244 
1245  /* unsigned int distance_index; */
1246  /* double tof; */
1247  /* double corrected_time; */
1248 
1249  /* for(unsigned int i=0; i<n_hits; i++){ */
1250 
1251  /* distance_index = get_distance_index(host_ids[i], n_PMTs*(itrigger->first)); */
1252  /* tof = host_times_of_flight[distance_index]; */
1253 
1254  /* corrected_time = host_times[i]-tof; */
1255 
1256  /* //fprintf(of, " %d %d %f \n", host_ids[i], host_times[i], corrected_time); */
1257  /* fprintf(of, " %d %f \n", host_ids[i], corrected_time); */
1258  /* } */
1259 
1260  /* fclose(of); */
1261  /* } */
1262 
1263  }
1264  }
1265 
1266 
1267  return;
1268 }
1269 
1270 
1272 
1273  free(host_ids);
1274  free(host_times);
1277  if( correct_mode == 10 ){
1279  }
1280 
1281  return;
1282 }
int CPU_test_vertices_execute(std::vector< int > PMTid, std::vector< int > time, std::vector< int > *trigger_ns, std::vector< int > *trigger_ts)
unsigned int n_water_like_test_vertices
std::string Result(std::string method_name, std::string output_file="")
Definition: Stopwatch.cpp:38
unsigned int * host_times
unsigned int n_direction_bins
void choose_candidates_above_threshold()
double cerenkov_angle_water
unsigned int * host_max_number_of_pmts_in_cone_in_time_bin
float * host_light_dy
double * PMT_z
double detector_radius
Definition: test_vertices.h:97
util::Stopwatch * m_stopwatch
The stopwatch, if we&#39;re using one.
unsigned int * host_vertex_with_max_n_pmts
bool m_return_vertex
Definition: test_vertices.h:42
float m_coalesce_time
Definition: test_vertices.h:29
int CPU_test_vertices_initialize()
std::string output_file
unsigned int n_direction_bins_phi
void allocate_candidates_memory_on_host()
bool triggeroutput
DEPRECATED! Use IDTriggers and ODTriggers instead.
Definition: DataModel.h:81
void free_global_memories()
void Start()
Start the stopwatch.
Definition: Stopwatch.cpp:18
unsigned int get_time_index(unsigned int hit_index, unsigned int vertex_block)
bool m_cylindrical_grid
Definition: test_vertices.h:33
unsigned int n_test_vertices
vertices
StopwatchTimes Stop()
Stop the stopwatch, returning the CPU time.
Definition: Stopwatch.cpp:24
void find_vertex_with_max_npmts_in_timebin(histogram_t *np, histogram_t *mnp, unsigned int *vmnp)
std::vector< unsigned int > candidate_trigger_npmts_in_time_bin
int m_n_direction_bins_theta
Definition: test_vertices.h:32
bool Initialise(std::string configfile, DataModel &data)
std::vector< unsigned int > trigger_npmts_in_cone_in_time_bin
int m_max_n_hits_per_job
Definition: test_vertices.h:37
void StreamToLog(int level)
void free_event_memories()
unsigned int * host_n_pmts_per_time_bin
void coalesce_triggers()
float costheta_cone_cut
Definition: test_vertices.h:93
float m_distance_between_vertices
Definition: test_vertices.h:25
unsigned int n_PMTs
pmts
Definition: test_vertices.h:99
std::vector< unsigned int > candidate_trigger_npmts_in_cone_in_time_bin
unsigned int get_distance_index(unsigned int pmt_id, unsigned int vertex_block)
bool m_return_direction
Definition: test_vertices.h:43
double speed_light_water
unsigned int n_hits
float m_wall_like_threshold_number_of_pmts
Definition: test_vertices.h:28
std::stringstream m_ss
For easy formatting of Log messages.
float m_wall_like_distance
Definition: test_vertices.h:26
double trigger_gate_down
Definition: test_vertices.h:90
int m_verbose
Verbosity level, as defined in tool parameter file.
double * vertex_z
std::vector< std::pair< unsigned int, unsigned int > > final_trigger_pair_vertex_time
unsigned int histogram_t
Definition: test_vertices.h:56
std::vector< double > output_trigger_information
double trigger_gate_up
Definition: test_vertices.h:89
unsigned int wall_like_threshold_number_of_pmts
Definition: test_vertices.h:86
std::vector< unsigned int > trigger_npmts_in_time_bin
double * PMT_y
double detector_height
detector
Definition: test_vertices.h:96
void make_test_vertices()
histogram_t * host_max_number_of_pmts_in_time_bin
unsigned int water_like_threshold_number_of_pmts
Definition: test_vertices.h:85
double coalesce_time
Definition: test_vertices.h:88
int test_vertices_initialize_ToolDAQ(double detector_length, double detector_radius, double pmt_radius, std::string ParameterFile, std::vector< int > tube_no, std::vector< float > tube_x, std::vector< float > tube_y, std::vector< float > tube_z, float f_dark_rate, float distance_between_vertices, float wall_like_distance, float water_like_threshold_number_of_pmts, float wall_like_threshold_number_of_pmts, float coalesce_time, float trigger_gate_up, float trigger_gate_down, int output_txt, int correct_mode, int n_direction_bins_theta, bool cylindrical_grid, float costheta_cone_cut, bool select_based_on_cone, bool trigger_threshold_adjust_for_noise, int f_max_n_hits_per_job, int f_num_blocks_y, int f_num_threads_per_block_y, int f_num_threads_per_block_x, int f_write_output_mode, bool f_return_vertex, bool f_return_direction)
int m_num_threads_per_block_y
Definition: test_vertices.h:39
unsigned int * host_ids
int m_write_output_mode
Definition: test_vertices.h:41
TimeDelta m_trigger_mask_window_pre
Pre-trigger time for masking digits from future tools.
Definition: test_vertices.h:50
unsigned int write_output_mode
void separate_triggers_into_gates(std::vector< int > *trigger_ns, std::vector< int > *trigger_ts)
unsigned int get_direction_index_at_pmt(unsigned int pmt_id, unsigned int vertex_index, unsigned int direction_index)
unsigned int correct_mode
bool * host_directions_for_vertex_and_pmt
void correct_times_and_get_histo_per_vertex_shared(unsigned int *ct)
TimeDelta m_trigger_save_window_pre
Pre-trigger time for saving digits.
Definition: test_vertices.h:46
unsigned int time_step_size
Definition: test_vertices.h:84
unsigned int the_max_time
double * vertex_y
unsigned int get_direction_index_at_time(unsigned int time_bin, unsigned int vertex_index, unsigned int direction_index)
float * host_light_dx
bool read_the_input_ToolDAQ(std::vector< int > PMTid, std::vector< int > time, int *earliest_time)
std::vector< int > m_time_int
float * host_light_dz
void Log(const std::string &message, const int message_level)
Format messages in the same way as for tools.
Definition: Utilities.cpp:276
int test_vertices_execute()
int CPU_test_vertices_finalize()
int test_vertices_finalize()
double * vertex_x
float * host_light_dr
offset_t time_offset
hits
std::vector< std::pair< unsigned int, unsigned int > > candidate_trigger_pair_vertex_time
bool m_trigger_threshold_adjust_for_noise
Definition: test_vertices.h:36
float cerenkov_costheta
unsigned int time_of_flight_t
Definition: test_vertices.h:57
std::vector< std::pair< unsigned int, unsigned int > > trigger_pair_vertex_time
unsigned int max_n_hits_per_job
Definition: test_vertices.h:91
float m_costheta_cone_cut
Definition: test_vertices.h:34
double distance_between_vertices
CPU parameters.
Definition: test_vertices.h:82
unsigned int get_direction_index_at_angles(unsigned int iphi, unsigned int itheta)
time_of_flight_t * host_times_of_flight
std::string m_stopwatch_file
Image filename to save the histogram to, if required.
TimeDelta m_trigger_save_window_post
Post-trigger time for saving digits.
Definition: test_vertices.h:48
bool m_select_based_on_cone
Definition: test_vertices.h:35
void make_table_of_directions()
bool select_based_on_cone
Definition: test_vertices.h:94
double dark_rate
Definition: test_vertices.h:92
unsigned int n_direction_bins_theta
int m_num_threads_per_block_x
Definition: test_vertices.h:40
unsigned int n_time_bins
TimeDelta m_trigger_mask_window_post
Post-trigger time for masking digits from future tools.
Definition: test_vertices.h:52
float m_water_like_threshold_number_of_pmts
Definition: test_vertices.h:27
void make_table_of_tofs()
double * PMT_x
double wall_like_distance
Definition: test_vertices.h:83