HPS-MC
random_sample.cc
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
5 #include <stdhep_util.hh>
6 
7 #include <gsl/gsl_rng.h>
8 #include <gsl/gsl_randist.h>
9 
10 #include <unistd.h>
11 
12 #include <random> // std::default_random_engine
13 #include <algorithm> // std::shuffle
14 #include <iostream>
15 using namespace std;
16 
21 int main(int argc, char** argv)
22 {
23  double poisson_mu = -1.0;
24  double poisson_mu_correction = 0;
25  int output_n = 500000;
26  int max_output_files = 1;
27  int output_filename_digits = 1;
28  int n_events_per_batch = 1000000;
29 
30  int rseed = 0;
31  int c;
32 
33  while ((c = getopt(argc, argv, "hn:m:t:N:b:s:")) != -1)
34  switch (c)
35  {
36  case 'h':
37  printf("-h: print this help\n");
38  printf("-m: mean number of events in an event\n");
39  printf("-t: corretion parameter for mu\n");
40  printf("-N: max number of files to write\n");
41  printf("-b: number of events per batch for caching input events\n");
42  printf("-n: o\n");
43  printf("-s: RNG seed\n");
44  return(0);
45  break;
46  case 'm':
47  poisson_mu = atof(optarg);
48  break;
49  case 't':
50  poisson_mu_correction = atof(optarg);
51  break;
52  case 'n':
53  output_n = atoi(optarg);
54  break;
55  case 'N':
56  max_output_files = atoi(optarg);
57  output_filename_digits = strlen(optarg);
58  break;
59  case 's':
60  rseed = atoi(optarg);
61  break;
62  case '?':
63  printf("Invalid option or missing option argument; -h to list options\n");
64  return(1);
65  default:
66  abort();
67  }
68 
69  printf("Mean events per output event %f, output events per output file %d, max output files %d\n", poisson_mu, output_n, max_output_files);
70 
71  if (argc - optind < 2)
72  {
73  printf("<input stdhep filenames> <output stdhep basename>\n");
74  return 1;
75  }
76 
77  // initialize the RNG
78  const gsl_rng_type * T;
79  gsl_rng * r;
80  gsl_rng_env_setup();
81 
82  T = gsl_rng_mt19937;
83  r = gsl_rng_alloc (T);
84  gsl_rng_set(r, rseed);
85 
86  int istream = 0;
87  int ostream = 1;
88  int ilbl;
89 
90  char *output_basename = argv[argc-1];
91  char output_filename[100];
92  int file_n = 1;
93 
94  int n_events = 0;
95  int input_ind = optind;
96  while(input_ind < argc - 1){
97  n_events += open_read(argv[input_ind++], istream);
98  close_read(istream);
99  }
100  printf("read %d events\n", n_events);
101  printf("poisson_mu_correction: %i \n", poisson_mu_correction);
102  printf("output_n: %i \n", output_n);
103 
104  if (poisson_mu < 0) {
105  poisson_mu = ((double) n_events)/((double) output_n*(1-poisson_mu_correction));
106  printf("Setting mu to %f\n", poisson_mu);
107  }
108 
109  int n_batches = n_events/n_events_per_batch + 1;
110  printf("Number of batches for caching: %d\n", n_batches);
111 
112  vector<stdhep_entry> new_event;
113  vector<vector<stdhep_entry> *> input_events;
114  vector<int> event_list;
115  int batch_num = 0;
116  int n_events_used = 0;
117  int event_num = 0;
118  int nevhep = 0;
119  vector<vector<stdhep_entry> *> events_no_used;
120 
121  while (file_n <= max_output_files) {
122  sprintf(output_filename, "%s_%0*d.stdhep", output_basename, output_filename_digits, file_n++);
123  open_write(output_filename, ostream, output_n);
124  nevhep = 0;
125  input_ind = optind;
126  open_read(argv[input_ind++], istream);
127  while (true) {
128  bool no_more_data = false;
129  while (!read_next(istream)) {
130  close_read(istream);
131  if (input_ind < argc - 1)
132  open_read(argv[input_ind++], istream);
133  else
134  {
135  no_more_data = true;
136  break;
137  }
138  }
139  if(!no_more_data){
140  vector<stdhep_entry> *read_event = new vector<stdhep_entry>;
141  read_stdhep(read_event);
142  input_events.push_back(read_event);
143  event_list.push_back(event_num++);
144  }
145  if( ((input_events.size() == n_events_per_batch) && (batch_num < n_batches - 1)) || (no_more_data && (batch_num == n_batches - 1)) )
146  {
147  batch_num++;
148  shuffle(event_list.begin(), event_list.end(), default_random_engine(rseed + 10));
149  int event_list_index = 0;
150  while (nevhep < output_n) {
151  int n_merge = gsl_ran_poisson(r, poisson_mu);
152  if (n_merge == 0)
153  add_filler_particle(&new_event);
154  else {
155  if(event_list_index + n_merge > event_list.size()) {
156  if(batch_num == n_batches) {
157  for(int i = 0; i < input_events.size(); i++)
158  delete input_events[i];
159  input_events.clear();
160  event_list.clear();
161  }
162  else {
163  n_events_used += event_list_index;
164  for(int i = 0; i < event_list_index; i++)
165  delete input_events[event_list[i]];
166  events_no_used.clear();
167  for(int i = event_list_index; i < event_list.size(); i++)
168  events_no_used.push_back(input_events[event_list[i]]);
169  input_events.clear();
170  event_list.clear();
171  event_num = 0;
172  for(int i = 0; i < events_no_used.size(); i++){
173  input_events.push_back(events_no_used[i]);
174  event_list.push_back(event_num++);
175  }
176  }
177  break;
178  }
179  else {
180  for (int i = 0; i < n_merge; i++)
181  append_stdhep(&new_event, input_events[event_list[event_list_index + i]]);
182  event_list_index += n_merge;
183  }
184  }
185  write_stdhep(&new_event,++nevhep);
186  write_file(ostream);
187  }
188  if(nevhep == output_n) {
189  close_write(ostream);
190  break;
191  }
192  }
193  if (no_more_data) break;
194  }
195  close_write(ostream);
196  }
197 }
198 
int main(int argc, char **argv)
void add_filler_particle(vector< stdhep_entry > *new_event)
void open_write(char *filename, int ostream, int n_events)
int open_read(char *filename, int istream, int n_events)
int append_stdhep(vector< stdhep_entry > *event, const vector< stdhep_entry > *new_event)
void write_stdhep(vector< stdhep_entry > *new_event, int nevhep)
Definition: stdhep_util.cpp:69
int read_stdhep(vector< stdhep_entry > *new_event)
Definition: stdhep_util.cpp:14
bool read_next(int istream)
void close_read(int istream)
void write_file(int ostream)
void close_write(int ostream)