HPS-MC
 
Loading...
Searching...
No Matches
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>
15using namespace std;
16
21int 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)
int read_stdhep(vector< stdhep_entry > *new_event)
bool read_next(int istream)
void close_read(int istream)
void write_file(int ostream)
void close_write(int ostream)