Jpp  19.0.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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

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();
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 }
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:70
Object writing to file.
Utility class to parse command line options.
Definition: JParser.hh:1711
General exception.
Definition: JException.hh:24
Acoustic receiver.
Definition: JReceiver.hh:27
Q(UTCMax_s-UTCMin_s)-livetime_s
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
JContainer< std::vector< JTransmitter > > transmitters_container
Definition: JSydney.cc:80
void merge(const JEvent &event)
Merge event.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
General purpose class for hash map of unique keys.
Definition: JHashMap.hh:72
Auxiliary data structure for running average, standard deviation and quantiles.
Definition: JQuantile.hh:43
#define STATUS(A)
Definition: JMessage.hh:63
Detector data structure.
Definition: JDetector.hh:89
Match of two events considering overlap in time.
then usage $script< input file >[option] nPossible options count
Definition: JVolume1D.sh:31
int32_t WAVEFORMID
DOM unique identifeir.
Definition: JToA.hh:33
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
then fatal Number of tripods
Definition: JFootprint.sh:45
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:84
Time-of-arrival data from acoustic piezo sensor or hydrophone.
Definition: JToA.hh:25
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
V(JDAQEvent-JTriggerReprocessor)*1.0/(JDAQEvent+1.0e-10)
string outputFile
JMODEL::JString getString(const JFit &fit)
Get model parameters of string.
std::vector< JHitW0 > buffer_type
hits
Definition: JPerth.cc:70
Type list.
Definition: JTypeList.hh:22
const JPolynome f1(1.0, 2.0, 3.0)
Function.
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
static const JSoundVelocity getSoundVelocity(1541.0,-17.0e-3,-2000.0)
Function object for velocity of sound.
Detector file.
Definition: JHead.hh:226
JContainer< std::vector< JHydrophone > > hydrophones_container
Definition: JSydney.cc:79
Acoustic emitter.
Definition: JEmitter.hh:27
Auxiliary wrapper for I/O of container with optional comment (see JComment).
Definition: JContainer.hh:39
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:2158
JPosition3D getPosition(const Vec &pos)
Get position.
Acoustic transceiver.
Definition: JTransceiver.hh:25
JContainer< std::vector< JTripod > > tripods_container
Definition: JSydney.cc:78
Implementation for depth dependend velocity of sound.
#define FATAL(A)
Definition: JMessage.hh:67
int32_t DETID
Definition: JToA.hh:30
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
General purpose class for object reading from a list of file names.
JPosition3D getPiezoPosition()
Get relative position of piezo in optical module.
static const int PIEZO_DISABLE
Enable (disable) use of piezo if this status bit is 0 (1);.
Auxiliary class to compare transmissions.
Acoustic event.
static const int HYDROPHONE_DISABLE
Enable (disable) use of hydrophone if this status bit is 0 (1);.
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:84
bool equals(const JFirst_t &first, const JSecond_t &second, const double precision=std::numeric_limits< double >::min())
Check equality.
Definition: JMathToolkit.hh:87
std::map< int, range_type > map_type
uint32_t DOMID
DAQ run number.
Definition: JToA.hh:32
static JEmitterID getEmitterID
Function object for emitter identification.
Definition: JEmitterID.hh:119
do set_variable DETECTOR_TXT $WORKDIR detector
int debug
debug level
#define DEBUG(A)
Message macros.
Definition: JMessage.hh:62