Jpp  debug
the software that should make you happy
Functions
JAcousticsEventBuilder.cc File Reference

Main program to trigger events in acoustic data. More...

#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <algorithm>
#include "TROOT.h"
#include "TFile.h"
#include "km3net-dataformat/definitions/module_status.hh"
#include "JLang/JComparator.hh"
#include "JDetector/JDetector.hh"
#include "JDetector/JDetectorToolkit.hh"
#include "JDetector/JModuleSupportkit.hh"
#include "JDetector/JTripod.hh"
#include "JDetector/JTransmitter.hh"
#include "JDetector/JHydrophone.hh"
#include "JLang/JPredicate.hh"
#include "JTools/JRange.hh"
#include "JTools/JQuantile.hh"
#include "JTools/JHashMap.hh"
#include "JSupport/JMultipleFileScanner.hh"
#include "JSupport/JFileRecorder.hh"
#include "JSupport/JMeta.hh"
#include "JAcoustics/JToA.hh"
#include "JAcoustics/JEmitterID.hh"
#include "JAcoustics/JTransceiver.hh"
#include "JAcoustics/JTransmission.hh"
#include "JAcoustics/JAcousticsToolkit.hh"
#include "JAcoustics/JAcousticsSupportkit.hh"
#include "JAcoustics/JTriggerParameters.hh"
#include "JAcoustics/JEvent.hh"
#include "JAcoustics/JEventOverlap.hh"
#include "JAcoustics/JTriggerOutput.hh"
#include "JAcoustics/JSupport.hh"
#include "Jeep/JContainer.hh"
#include "Jeep/JPrint.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Main program to trigger events in acoustic data.

An acoustic event is based on a coincidence of estimated times of emission from the same emitter.
If the number of coincident times of emission exceeds a preset minimum, the event is triggered and subsequently stored in the output file.
Note that an event counter is added which can be used to disambiguate the different cycles from the same emitter within one "super" event that is used for the global fit.
In this, a super event refers to the coincidence of events from a variety of emitters.

Author
mdejong

Definition in file JAcousticsEventBuilder.cc.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 61 of file JAcousticsEventBuilder.cc.

62 {
63  using namespace std;
64  using namespace JPP;
65 
67 
71 
73  JLimit_t& numberOfEvents = inputFile.getLimit();
74  JTriggerParameters parameters;
76  JSoundVelocity V = getSoundVelocity; // default sound velocity
77  string detectorFile;
78  tripods_container tripods; // tripods
79  transmitters_container transmitters; // transmitters
80  hydrophones_container hydrophones; // hydrophones
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 JConvertDB -q toashort");
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 
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 
128 
129  if (i->getFloor() == 0) { // get relative position of hydrophone
130 
131  try {
132  pos = getPosition(hydrophones.begin(),
133  hydrophones.end(),
134  make_predicate(&JHydrophone::getString, i->getString()));
135  }
136  catch(const exception&) {
137  continue; // if no position available, discard hydrophone
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; // if no string available, discard transmitter
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  // statistics
172 
173  struct map_type :
174  public map<int, JQuantile>
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  // input data
195 
196  typedef vector<JTransmission> buffer_type; // data type
197 
198  map<int, map< int, buffer_type > > f1; // emitter -> receiver -> data
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) { // consistency check
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 
222  const JTransceiver transceiver(emitters[id], receivers[parameters->DOMID]);
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 
249  const JEventOverlap match(parameters.TMax_s);
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  // filter similar hits
258 
259  sort(receiver->second.begin(), receiver->second.end(), JTransmission::compare(precision));
260 
261  buffer_type::iterator __end = unique(receiver->second.begin(), receiver->second.end(), JTransmission::equals(precision));
262 
263  // selection based on quality
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()); // sort according time-of-emisson
273 
274  JQuantile Q; // monitor of trigger
275  JEvent out; // temporary storage of event(s)
276  JTriggerOutput data; //
277 
278  for (buffer_type::const_iterator p = buffer.begin(); p != buffer.end(); ++p) {
279 
280  buffer_type::const_iterator q = p;
281 
282  // basic correlator
283 
284  while (++q != buffer.end() && q->getToE() - p->getToE() <= parameters.TMax_s) {}
285 
286  Q.put(distance(p,q));
287 
288  if (distance(p,q) >= parameters.numberOfHits) {
289 
290  JEvent event(detector.getID(), number_of_triggers.sum(), i->first, p, q);
291 
292  number_of_triggers[i->first].put(event.size());
293 
294  DEBUG("trigger: " << endl << event);
295 
296  if (out.empty()) {
297 
298  out = event;
299 
300  } else if (match(out, event)) {
301 
302  out.merge(event);
303 
304  } else {
305 
306  data.push_back(out);
307 
308  out = event;
309  }
310  }
311  }
312 
313  if (!out.empty()) {
314  data.push_back(out); // pending event
315  }
316 
317  STATUS("number of toes: " << setw(3) << i->first << ' ' << setw(8) << buffer.size());
318  if (Q.getCount() > 0) {
319  STATUS(' ' << FIXED(6,1) << Q.getMean() <<
320  ' ' << FIXED(6,1) << Q.getXmin() <<
321  ' ' << FIXED(6,1) << Q.getXmax());
322  }
323  STATUS(endl);
324 
325  for (JTriggerOutput::const_iterator event = data.begin(); event != data.end(); ++event) {
326 
327  number_of_events[event->getID()].put(event->size());
328 
329  outputFile.put(*event);
330  }
331  }
332  STATUS(endl);
333 
334  for (map_type::const_iterator i = number_of_triggers.begin(); i != number_of_triggers.end(); ++i) {
335  STATUS("number of triggers: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << endl);
336  }
337 
338  for (map_type::const_iterator i = number_of_events.begin(); i != number_of_events.end(); ++i) {
339  STATUS("number of events: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << ' ' << FIXED(7,3) << i->second.getMean() << endl);
340  }
341 
342  JMultipleFileScanner<JMeta> io(inputFile);
343 
344  io >> outputFile;
345 
346  outputFile.close();
347 
348  return 0;
349 }
string outputFile
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62
#define STATUS(A)
Definition: JMessage.hh:63
#define FATAL(A)
Definition: JMessage.hh:67
int debug
debug level
Definition: JSirene.cc:69
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2158
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Detector data structure.
Definition: JDetector.hh:96
Data structure for position in three dimensions.
Definition: JPosition3D.hh:38
General exception.
Definition: JException.hh:24
Utility class to parse command line options.
Definition: JParser.hh:1714
Object writing to file.
General purpose class for object reading from a list of file names.
virtual bool hasNext() override
Check availability of next element.
counter_type getCounter() const
Get counter.
virtual const pointer_type & next() override
Get next element.
bool has(const T &value) const
Test whether given value is present.
static const int HYDROPHONE_DISABLE
Enable (disable) use of hydrophone if this status bit is 0 (1);.
static const int PIEZO_DISABLE
Enable (disable) use of piezo if this status bit is 0 (1);.
const JPolynome f1(1.0, 2.0, 3.0)
Function.
JPosition3D getPosition(const Vec &pos)
Get position.
static JEmitterID getEmitterID
Function object for emitter identification.
Definition: JEmitterID.hh:119
JContainer< std::vector< JTripod > > tripods_container
Definition: JSydney.cc:78
JContainer< std::vector< JTransmitter > > transmitters_container
Definition: JSydney.cc:80
JContainer< std::vector< JHydrophone > > hydrophones_container
Definition: JSydney.cc:79
JMODEL::JString getString(const JFit &fit)
Get model parameters of string.
static const JSoundVelocity getSoundVelocity(1541.0, -17.0e-3, -2000.0)
Function object for velocity of sound.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
JPosition3D getPiezoPosition()
Get relative position of piezo in optical module.
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member.
Definition: JPredicate.hh:128
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
std::vector< JHitW0 > buffer_type
hits
Definition: JPerth.cc:70
std::map< int, range_type > map_type
Definition: JSTDTypes.hh:14
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:448
Detector file.
Definition: JHead.hh:227
Acoustic emitter.
Definition: JEmitter.hh:30
Match of two events considering overlap in time.
void merge(const JEvent &event)
Merge event.
Acoustic receiver.
Definition: JReceiver.hh:30
Implementation for depth dependend velocity of sound.
JSoundVelocity & set(const double z0)
Set depth.
Time-of-arrival data from acoustic piezo sensor or hydrophone.
Definition: JToA.hh:26
uint32_t DOMID
DAQ run number.
Definition: JToA.hh:32
int32_t WAVEFORMID
DOM unique identifeir.
Definition: JToA.hh:33
int32_t DETID
Definition: JToA.hh:30
Acoustic transceiver.
Definition: JTransceiver.hh:28
Auxiliary class to compare transmissions.
Auxiliary class to compare transmissions.
Auxiliary wrapper for I/O of container with optional comment (see JComment).
Definition: JContainer.hh:42
Type list.
Definition: JTypeList.hh:23
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:84
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:45
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:72
General purpose class for hash map of unique keys.
Definition: JHashMap.hh:75
Auxiliary data structure for running average, standard deviation and quantiles.
Definition: JQuantile.hh:46
double getXmin() const
Get minimum value.
Definition: JQuantile.hh:208
void put(const double x, const double w=1.0)
Put value.
Definition: JQuantile.hh:133
long long int getCount() const
Get total count.
Definition: JQuantile.hh:186
double getMean() const
Get mean value.
Definition: JQuantile.hh:252
double getXmax() const
Get maximum value.
Definition: JQuantile.hh:219