Jpp - 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 acoustic data. More...

#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <algorithm>
#include "TROOT.h"
#include "TFile.h"
#include "JLang/JComparator.hh"
#include "JDB/JToAshort.hh"
#include "JDB/JSupport.hh"
#include "JDetector/JDetector.hh"
#include "JDetector/JDetectorToolkit.hh"
#include "JDetector/JDetectorSupportkit.hh"
#include "JDetector/JTripod.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/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 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.
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 60 of file JAcousticsEventBuilder.cc.

61 {
62  using namespace std;
63  using namespace JPP;
64 
66 
67  typedef JContainer< vector<JTripod> > tripods_container;
68  typedef JContainer< vector<JHydrophone> > hydrophones_container;
69 
71  JLimit_t& numberOfEvents = inputFile.getLimit();
74  JSoundVelocity V = getSoundVelocity; // default sound velocity
75  string detectorFile;
76  tripods_container tripods; // tripods
77  hydrophones_container hydrophones; // hydrophones
78  double precision;
79  int debug;
80 
81  try {
82 
83  JParser<> zap("Main program to trigger acoustic data.");
84 
85  zap['f'] = make_field(inputFile, "output of JConvertDB -q toashort");
86  zap['n'] = make_field(numberOfEvents) = JLimit::max();
87  zap['@'] = make_field(parameters, "trigger parameters");
88  zap['o'] = make_field(outputFile, "output file") = "event.root";
89  zap['V'] = make_field(V, "sound velocity") = JPARSER::initialised();
90  zap['a'] = make_field(detectorFile, "detector file");
91  zap['T'] = make_field(tripods, "tripod data");
92  zap['H'] = make_field(hydrophones, "hydrophone data") = JPARSER::initialised();
93  zap['W'] = make_field(getEmitterID, "waveform identification data") = JPARSER::initialised();
94  zap['p'] = make_field(precision, "precision time-of-arrival") = 1.0e-6;
95  zap['d'] = make_field(debug) = 1;
96 
97  zap(argc, argv);
98  }
99  catch(const exception &error) {
100  FATAL(error.what() << endl);
101  }
102 
103 
105 
106  try {
107  load(detectorFile, detector);
108  }
109  catch(const JException& error) {
110  FATAL(error);
111  }
112 
113  V.set(detector.getUTMZ());
114 
115  JHashMap<int, JReceiver> receivers;
116  JHashMap<int, JEmitter> emitters;
117 
118  for (JDetector::const_iterator i = detector.begin(); i != detector.end(); ++i) {
119 
120  JPosition3D pos(0.0, 0.0, 0.0);
121 
122  if (i->getFloor() == 0) { // get relative position of hydrophone
123 
124  try {
125  pos = getPosition(hydrophones.begin(),
126  hydrophones.end(),
127  make_predicate(&JHydrophone::getString, i->getString()));
128  }
129  catch(const exception&) {
130  continue; // if no position avialable, discard hydrophone
131  }
132  }
133 
134  receivers[i->getID()] = JReceiver(i->getID(),
135  i->getPosition() + pos,
136  i->getT0() * 1.0e-9);
137  }
138 
139  for (tripods_container::const_iterator i = tripods.begin(); i != tripods.end(); ++i) {
140  emitters[i->getID()] = JEmitter(i->getID(),
141  i->getUTMPosition() - detector.getUTMPosition());
142  }
143 
144 
145  outputFile.open();
146 
147  if (!outputFile.is_open()) {
148  FATAL("Error opening file " << outputFile << endl);
149  }
150 
151  outputFile.put(JMeta(argc, argv));
152  outputFile.put(parameters);
153 
154  // statistics
155 
156  struct map_type :
157  public map<int, JQuantile>
158  {
159  long long int sum() const
160  {
161  long long int count = 0;
162 
163  for (const_iterator i = this->begin(); i != this->end(); ++i) {
164  count += i->second.getCount();
165  }
166 
167  return count;
168  }
169  };
170 
171  map_type number_of_entries;
172  map_type number_of_triggers;
173  map_type number_of_events;
174 
175  // input data
176 
177  string oid; // detector identifier
178 
179  typedef vector<JTransmission> buffer_type; // data type
180 
181  map<int, map< int, buffer_type > > f1; // emitter -> receiver -> data
182 
183  while (inputFile.hasNext()) {
184 
185  if (inputFile.getCounter()%1000 == 0) {
186  STATUS("counter: " << setw(8) << inputFile.getCounter() << '\r' << flush); DEBUG(endl);
187  }
188 
189  JToAshort* parameters = inputFile.next();
190 
191  if (oid == "") {
192  oid = parameters->DETID;
193  }
194 
195  if (oid != parameters->DETID) { // consistency check
196  FATAL("Invalid detector identifier " << parameters->DETID << " != " << oid << endl);
197  }
198 
199  const int id = getEmitterID(parameters->EMITTERID);
200 
201  number_of_entries[parameters->EMITTERID].put(1);
202 
203  if (emitters.has(id) && receivers.has(parameters->DOMID)) {
204 
205  const JTransceiver transceiver(emitters[id], receivers[parameters->DOMID]);
206 
207  f1[transceiver.emitter.getID()][transceiver.receiver.getID()].push_back(transceiver.getTransmission(*parameters, V));
208  }
209  }
210  STATUS(endl);
211 
212  for (map_type::const_iterator i = number_of_entries.begin(); i != number_of_entries.end(); ++i) {
213  STATUS("number of entries: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << endl);
214  }
215 
216 
217  // filter similar hits
218 
219  for (map<int, map< int, buffer_type> >::iterator i = f1.begin(); i != f1.end(); ++i) {
220 
221  for (map< int, buffer_type>::iterator receiver = i->second.begin(); receiver != i->second.end(); ++receiver) {
222 
223  buffer_type& buffer = receiver->second;
224 
225  sort(buffer.begin(), buffer.end(), JTransmission::compare(precision));
226 
227  buffer.erase(unique(buffer.begin(), buffer.end(), JTransmission::equals(precision)), buffer.end());
228  }
229  }
230 
231 
232  // output events
233 
234  for (map<int, map< int, buffer_type> >::iterator i = f1.begin(); i != f1.end(); ++i) {
235 
236  buffer_type buffer;
237 
238  for (map< int, buffer_type>::iterator receiver = i->second.begin(); receiver != i->second.end(); ++receiver) {
239 
240  // selection based on quality
241 
242  buffer_type& f2 = receiver->second;
243  double Qmin = parameters.Q;
244 
245  if (parameters.Q > 0.0 && parameters.Q < 1.0) {
246 
247  const JQuantile Q1("quality", make_array(f2.begin(), f2.end(), &JTransmission::getQ), true);
248 
249  Qmin = Q1.getQuantile(parameters.Q);
250  }
251 
252  buffer_type::iterator __end = partition(f2.begin(), f2.end(), make_predicate(&JTransmission::getQ, Qmin, JComparison::gt()));
253 
254  copy(f2.begin(), __end, back_inserter(buffer));
255  }
256 
257 
258  sort(buffer.begin(), buffer.end()); // sort according time-of-emisson
259 
260  STATUS("number of toes: " << setw(3) << i->first << ' ' << setw(8) << buffer.size() << endl);
261 
262  JTriggerOutput data;
263 
264  for (buffer_type::const_iterator p = buffer.begin(); p != buffer.end(); ++p) {
265 
266  buffer_type::const_iterator q = p;
267 
268  // basic correlator
269 
270  while (++q != buffer.end() && q->getToE() - p->getToE() <= parameters.TMax_s) {}
271 
272  if (distance(p,q) >= parameters.numberOfHits) {
273 
274  STATUS("trigger: " << setw(8) << number_of_triggers.sum() << '\r' << flush); DEBUG(endl);
275 
276  JEvent event(oid, number_of_triggers.sum(), i->first, p, q);
277 
278  number_of_triggers[i->first].put(event.size());
279 
280  DEBUG("trigger: " << endl << event);
281 
282  data.push_back(event);
283  }
284  }
285 
286  data.merge(JEventOverlap(parameters.TMax_s));
287 
288  for (JTriggerOutput::const_iterator event = data.begin(); event != data.end(); ++event) {
289 
290  number_of_events[event->getID()].put(event->size());
291 
292  outputFile.put(*event);
293  }
294  }
295  STATUS(endl);
296 
297  for (map_type::const_iterator i = number_of_triggers.begin(); i != number_of_triggers.end(); ++i) {
298  STATUS("number of triggers: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << endl);
299  }
300 
301  for (map_type::const_iterator i = number_of_events.begin(); i != number_of_events.end(); ++i) {
302  STATUS("number of events: " << setw(3) << i->first << ' ' << setw(8) << i->second.getCount() << ' ' << FIXED(7,3) << i->second.getMean() << endl);
303  }
304 
305  JMultipleFileScanner<JMeta> io(inputFile);
306 
307  io >> outputFile;
308 
309  outputFile.close();
310 }
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:1500
General exception.
Definition: JException.hh:23
Acoustic receiver.
Definition: JReceiver.hh:27
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
Greater than.
Definition: JComparison.hh:73
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:80
std::string DETID
constraint
Definition: JToAshort.hh:22
*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
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:66
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
string outputFile
Type list.
Definition: JTypeList.hh:22
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:196
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:1961
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition: JVectorize.hh:54
JPosition3D getPosition(const Vec &pos)
Get position.
Acoustic transceiver.
Definition: JTransceiver.hh:29
int debug
debug level
Definition: JSirene.cc:63
Implementation for velocity of sound.
#define FATAL(A)
Definition: JMessage.hh:67
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
std::vector< int > count
Definition: JAlgorithm.hh:180
General purpose class for object reading from a list of file names.
then usage $script< input_file >< detector_file > fi set_variable OUTPUT_DIR set_variable SELECTOR JDAQTimesliceL1 set_variable DEBUG case set_variable DEBUG
Auxiliary class to compare transmissions.
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition: JHead.cc:139
Acoustic event.
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:73
bool equals(const JFirst_t &first, const JSecond_t &second, const double precision=std::numeric_limits< double >::min())
Check equality.
Definition: JMathToolkit.hh:86
static JEmitterID getEmitterID
Function object for emitter identification.
Definition: JEmitterID.hh:119
do set_variable DETECTOR_TXT $WORKDIR detector
Match of two events considering overlap in time.
int EMITTERID
waveform identifier
Definition: JToAshort.hh:27