62{
63 using namespace std;
65
66 typedef JTYPELIST<JEvent, JTriggerParameters, JMeta>::typelist typelist;
67
71
72 JMultipleFileScanner<JToA> inputFile;
73 JLimit_t& numberOfEvents = inputFile.getLimit();
75 JFileRecorder<typelist> outputFile;
77 string detectorFile;
81 double precision;
82 int debug;
83
84 try {
85
86 JParser<> zap("Main program to trigger events in acoustic data.");
87
88 zap['f'] = make_field(inputFile, "output of JToA");
89 zap['n'] = make_field(numberOfEvents) = JLimit::max();
90 zap['@'] = make_field(parameters, "trigger parameters");
91 zap['o'] = make_field(outputFile, "output file") = "event.root";
92 zap['V'] = make_field(V, "sound velocity") = JPARSER::initialised();
93 zap['a'] = make_field(detectorFile, "detector file");
94 zap['T'] = make_field(tripods, "tripod data");
95 zap['Y'] = make_field(transmitters, "transmitter data") = JPARSER::initialised();
96 zap['H'] = make_field(hydrophones, "hydrophone data") = JPARSER::initialised();
97 zap['W'] = make_field(getEmitterID, "waveform identification data") = JPARSER::initialised();
98 zap['p'] = make_field(precision, "precision time-of-arrival") = 1.0e-6;
99 zap['d'] = make_field(debug) = 1;
100
101 zap(argc, argv);
102 }
103 catch(const exception &error) {
104 FATAL(error.what() << endl);
105 }
106
107
108 JDetector detector;
109
110 try {
111 load(detectorFile, detector);
112 }
113 catch(const JException& error) {
114 FATAL(error);
115 }
116
117 V.
set(detector.getUTMZ());
118
119 JHashMap<int, JReceiver> receivers;
120 JHashMap<int, JEmitter> emitters;
121
122 for (JDetector::const_iterator i = detector.begin(); i != detector.end(); ++i) {
123
124 if ((i->getFloor() == 0 && !i->has(HYDROPHONE_DISABLE)) ||
125 (i->getFloor() != 0 && !i->has(PIEZO_DISABLE))) {
126
127 JPosition3D pos = getPiezoPosition();
128
129 if (i->getFloor() == 0) {
130
131 try {
133 hydrophones.end(),
134 make_predicate(&JHydrophone::getString, i->getString()));
135 }
136 catch(const exception&) {
137 continue;
138 }
139 }
140
141 receivers[i->getID()] =
JReceiver(i->getID(),
142 i->getPosition() + pos,
143 i->getT0() * 1.0e-9);
144 }
145 }
146
147 for (tripods_container::const_iterator i = tripods.begin(); i != tripods.end(); ++i) {
148 emitters[i->getID()] =
JEmitter(i->getID(),
149 i->getUTMPosition() - detector.getUTMPosition());
150 }
151
152 for (transmitters_container::const_iterator i = transmitters.begin(); i != transmitters.end(); ++i) {
153 try {
154 emitters[i->getID()] =
JEmitter(i->getID(),
155 i->getPosition() + detector.getModule(i->getLocation()).getPosition());
156 }
157 catch(const exception&) {
158 continue;
159 }
160 }
161
162 outputFile.open();
163
164 if (!outputFile.is_open()) {
165 FATAL("Error opening file " << outputFile << endl);
166 }
167
168 outputFile.put(JMeta(argc, argv));
169 outputFile.put(parameters);
170
171
172
173 struct map_type :
174 public map<int, JStats>
175 {
176 long long int sum() const
177 {
178 long long int count = 0;
179
180 for (const_iterator i = this->begin(); i != this->end(); ++i) {
181 count += i->second.getCount();
182 }
183
184 return count;
185 }
186 };
187
188 map_type number_of_entries;
189 map_type number_of_aliens;
190 map_type number_of_misses;
191 map_type number_of_triggers;
192 map_type number_of_events;
193
194
195
196 typedef vector<JTransmission> buffer_type;
197
198 map<int, map< int, buffer_type > > f1;
199
200 while (inputFile.hasNext()) {
201
202 if (inputFile.getCounter()%10000 == 0) {
203 STATUS("counter: " << setw(8) << inputFile.getCounter() << '\r' << flush); DEBUG(endl);
204 }
205
206 JToA* parameters = inputFile.next();
207
208 if (detector.getID() != parameters->
DETID) {
209 FATAL(
"Invalid detector identifier " << parameters->
DETID <<
" != " << detector.getID() << endl);
210 }
211
212 try {
213
214 const int id = getEmitterID(parameters->
WAVEFORMID);
215
216 number_of_entries[parameters->
WAVEFORMID].put(1);
217
218 if (emitters.has(id)) {
219
220 if (receivers.has(parameters->
DOMID)) {
221
223
224 f1[transceiver.emitter.getID()][transceiver.receiver.getID()].push_back(transceiver.getTransmission(*parameters, V));
225 }
226
227 } else {
228 number_of_misses[id].put(1);
229 }
230 }
231 catch(const exception&) {
232 number_of_aliens[parameters->
WAVEFORMID].put(1);
233 }
234 }
235 STATUS(endl);
236
237 for (map_type::const_iterator i = number_of_entries.begin(); i != number_of_entries.end(); ++i) {
238 STATUS("number of entries: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << endl);
239 }
240
241 for (map_type::const_iterator i = number_of_aliens.begin(); i != number_of_aliens.end(); ++i) {
242 STATUS("number of aliens: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << endl);
243 }
244
245 for (map_type::const_iterator i = number_of_misses.begin(); i != number_of_misses.end(); ++i) {
246 STATUS("number of misses: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << endl);
247 }
248
250
251 for (map<int, map< int, buffer_type> >::iterator i = f1.begin(); i != f1.end(); ++i) {
252
253 buffer_type buffer;
254
255 for (map< int, buffer_type>::iterator receiver = i->second.begin(); receiver != i->second.end(); ++receiver) {
256
257
258
260
261 buffer_type::iterator __end = unique(receiver->second.begin(), receiver->second.end(),
JTransmission::equals(precision));
262
263
264
265 for (buffer_type::const_iterator p = receiver->second.begin(); p != __end; ++p) {
266 if (p->getQ() >= parameters.Q * (parameters.Q <= 1.0 ? p->getW() : 1.0)) {
267 buffer.push_back(*p);
268 }
269 }
270 }
271
272 sort(buffer.begin(), buffer.end());
273
274 JStats Q;
276
277 for (buffer_type::const_iterator p = buffer.begin(); p != buffer.end(); ++p) {
278
279 buffer_type::const_iterator q = p;
280
281
282
283 while (++q != buffer.end() && q->getToE() - p->getToE() <= parameters.TMax_s) {}
284
285 Q.put(distance(p,q));
286
287 if (distance(p,q) >= parameters.numberOfHits) {
288
289 JEvent event(detector.getID(), number_of_triggers.sum(), i->first, p, q);
290
291 number_of_triggers[i->first].put(event.size());
292
293 DEBUG("trigger: " << endl << event);
294
295 if (out.empty()) {
296
297 out = event;
298
299 } else if (match(out, event)) {
300
302
303 } else {
304
305 outputFile.put(out);
306
307 number_of_events[out.
getID()].put(out.size());
308
309 out = event;
310 }
311 }
312 }
313
314 if (!out.empty()) {
315
316 outputFile.put(out);
317
318 number_of_events[out.
getID()].put(out.size());
319 }
320
321 STATUS("number of toes: " << setw(3) << i->first << ' ' << setw(8) << buffer.size());
322 if (Q.getCount() > 0) {
323 STATUS(' ' << FIXED(6,1) << Q.getMean() <<
324 ' ' << FIXED(6,1) << Q.getXmin() <<
325 ' ' << FIXED(6,1) << Q.getXmax());
326 }
327 STATUS(endl);
328 }
329 STATUS(endl);
330
331 for (map_type::const_iterator i = number_of_triggers.begin(); i != number_of_triggers.end(); ++i) {
332 STATUS("number of triggers: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << endl);
333 }
334
335 for (map_type::const_iterator i = number_of_events.begin(); i != number_of_events.end(); ++i) {
336 STATUS("number of events: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << ' ' << FIXED(7,3) << i->second.getMean() << endl);
337 }
338
339 JMultipleFileScanner<JMeta> io(inputFile);
340
341 io >> outputFile;
342
343 outputFile.close();
344
345 return 0;
346}
JContainer< std::vector< JTripod > > tripods_container
JContainer< std::vector< JTransmitter > > transmitters_container
JVector3D getPosition(T __begin, T __end, const JPredicate< JTypename_t, JComparator_t > &predicate)
Get position from element in data which corresponds to given predicate.
JContainer< std::vector< JHydrophone > > hydrophones_container
Match of two events considering overlap in time and position.
void merge(const JEvent &event)
Merge event.
int getID() const
Get emitter identifier.
Implementation for depth dependend velocity of sound.
JSoundVelocity & set(const double z0)
Set depth.
Time-of-arrival data from acoustic piezo sensor or hydrophone.
uint32_t DOMID
DAQ run number.
int32_t WAVEFORMID
DOM unique identifeir.
Auxiliary class to compare transmissions.
Auxiliary class to compare transmissions.