Jpp  18.3.0-rc.1
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JGeometry.hh
Go to the documentation of this file.
1 #ifndef __JACOUSTICS__JGEOMETRY__
2 #define __JACOUSTICS__JGEOMETRY__
3 
4 #include <ostream>
5 #include <iomanip>
6 #include <vector>
7 #include <map>
8 #include <algorithm>
9 #include <cmath>
10 
11 #include "JLang/JException.hh"
12 #include "JLang/JPredicate.hh"
13 #include "JLang/JComparator.hh"
14 #include "JLang/JManip.hh"
15 
18 
19 #include "JTools/JHashMap.hh"
20 
21 #include "JDetector/JLocation.hh"
22 #include "JDetector/JHydrophone.hh"
23 #include "JDetector/JDetector.hh"
25 
28 #include "JAcoustics/JMechanics.hh"
29 #include "JAcoustics/JModel.hh"
30 
31 
32 /**
33  * \file
34  *
35  * Acoustic geometries.
36  * \author mdejong
37  */
38 namespace JACOUSTICS {}
39 namespace JPP { using namespace JACOUSTICS; }
40 
41 namespace JACOUSTICS {
42 
44  using JLANG::JNoValue;
48  using JTOOLS::JHashMap;
51 
52 
53  /**
54  * Auxiliary namespace to encapsulate different geometries.\n
55  */
56  namespace JGEOMETRY {
57 
58  /**
59  * Floor geometry.
60  */
61  struct JFloor {
62  /**
63  * Default constructor.
64  */
65  JFloor() :
66  height(0.0)
67  {}
68 
69 
70  /**
71  * Constructor.\n
72  * The height corresponds to the maximal distance from the top of the T-bar of the parent string to the actual sensor.\n
73  * The optional position corresponds to an anomalous offset of the optical module with respect to its nominal position.
74  *
75  * \param height height
76  * \param position position
77  */
78  JFloor(const double height, const JVector2D& position = JVector2D()) :
79  height(height),
80  position(position.getX(), position.getY(), 0.0)
81  {}
82 
83 
84  /**
85  * Get height of this floor.\n
86  * The height refers to the maximal distance from
87  * the fixed reference point of the parent string.
88  *
89  * \return height
90  */
91  double getHeight() const
92  {
93  return height;
94  }
95 
96 
97  /**
98  * Get position of this floor.\n
99  * The position corresponds to an anomalous offset of the optical module with respect to its nominal position.
100  *
101  * \return position
102  */
103  const JVector3D& getPosition() const
104  {
105  return position;
106  }
107 
108 
109  /**
110  * Write floor parameters to output stream.
111  *
112  * \param out output stream
113  * \param floor floor
114  * \return output stream
115  */
116  friend inline std::ostream& operator<<(std::ostream& out, const JFloor& floor)
117  {
118  return out << FIXED(7,2) << floor.getHeight();
119  }
120 
121 
122  protected:
123  double height;
125  };
126 
127 
128  /**
129  * String geometry.
130  *
131  * This data structure provides for the implementation of the dynamical geometry of a detector string.\n
132  * In this,
133  * the position of floor > 0 corresponds to the piezo sensor which is located inside the optical module and \n
134  * the position of floor = 0 to the hydrophone which is optionally mounted on the anchor.\n
135  * The reference position of a string corresponds to the top of the T-bar located on the anchor.\n
136  * The position of a piezo sensor depends on the tilt of the string and the mechanical model.\n
137  * The position of the hydrophone is fixed.
138  * Its value is relative to the reference position of the string.
139  */
140  struct JString :
141  public JPosition3D,
142  public std::vector<JFloor>
143  {
147 
148  static constexpr double PRECISION_M = 1.0e-4; //!< precision of height evaluation [m]
149 
150  /**
151  * Get approximate length of string.
152  *
153  * \param parameters parameters
154  * \param mechanics mechanics
155  * \param height height
156  * \return length
157  */
158  static inline double getLength(const JMODEL::JString& parameters,
159  const JMechanics& mechanics,
160  const double height)
161  {
162  const double T2 = parameters.getLengthSquared();
163 
164  const double x = 1.0 - mechanics.a*height;
165 
166  return sqrt(1.0 + T2) * height + T2*mechanics.b * log(x) + 0.5*T2*mechanics.a*mechanics.b*mechanics.b * (1.0/x - 1.0);
167  }
168 
169 
170  /**
171  * Get approximate height of string.
172  *
173  * \param parameters parameters
174  * \param mechanics mechanics
175  * \param length length
176  * \param precision precision
177  * \return height
178  */
179  static inline double getHeight(const JMODEL::JString& parameters,
180  const JMechanics& mechanics,
181  const double length,
182  const double precision = PRECISION_M)
183  {
184  const size_t MAXIMUM_NUMBER_OF_ITERATIONS = 10;
185 
186  const double T2 = parameters.getLengthSquared();
187 
188  double z = length; // start value
189 
190  for (size_t i = 0; i != MAXIMUM_NUMBER_OF_ITERATIONS; ++i) {
191 
192  const double ls = getLength(parameters, mechanics, z) - length;
193 
194  if (fabs(ls) <= precision) {
195  break;
196  }
197 
198  const double vs = 1.0 - mechanics.a*mechanics.b / (1.0 - mechanics.a*z);
199 
200  z -= ls / (1.0 + 0.5*T2 * vs*vs);
201  }
202 
203  return z;
204  }
205 
206 
207  /**
208  * Get position at given height according to given string model parameters and mechanics.
209  *
210  * \param parameters parameters
211  * \param mechanics mechanics
212  * \param height height
213  * \return position
214  */
216  const JMechanics& mechanics,
217  const double height)
218  {
219  const double h1 = height * (1.0 + parameters.vs);
220  const double z1 = mechanics.getHeight(h1);
221 
222  return JPosition3D(parameters.tx * z1 + parameters.tx2 * h1*h1,
223  parameters.ty * z1 + parameters.ty2 * h1*h1,
224  getHeight(parameters, mechanics, h1));
225  }
226 
227 
228  /**
229  * Default constructor.
230  */
232  has_hydrophone(false)
233  {}
234 
235 
236  /**
237  * Constructor.
238  *
239  * The given position corresponds to the reference position of the string from
240  * which the positions of the piezo sensors and hydrophone are determined.
241  *
242  * \param position position
243  * \param mechanics mechanical model parameters
244  */
245  JString(const JVector3D& position,
246  const JMechanics& mechanics) :
247  JPosition3D(position),
248  has_hydrophone(false),
249  mechanics(mechanics)
250  {}
251 
252 
253  /**
254  * Constructor.
255  *
256  * The given position corresponds to the reference position of the string from
257  * which the positions of the piezo sensors and hydrophone are determined.
258  *
259  * The template parameter should correspond to a data type which implements the following policy methods.
260  * <pre>
261  * int %getFloor();
262  * JGEOMETRY3d::JPosition3D %getPosition();
263  * </pre>
264  * In this, the position should correspond to the center of the optical module.
265  *
266  * Note that the position of the piezo is offset by JDETECTOR::getPiezoPosition with respect to the center of the optical module.\n
267  * The position of the hydrophone should separately be set.
268  *
269  * \param position position
270  * \param mechanics mechanical model parameters
271  * \param __begin begin of optical modules
272  * \param __end end of optical modules
273  */
274  template<class T>
275  JString(const JVector3D& position,
276  const JMechanics& mechanics,
277  T __begin,
278  T __end) :
279  JPosition3D(position),
280  has_hydrophone(false),
281  mechanics(mechanics)
282  {
283  for (T i = __begin; i != __end; ++i) {
284  (*this)[i->getFloor()] = JFloor(this->getDistance(i->getPosition() + JDETECTOR::getPiezoPosition()),
285  JVector2D(i->getX() - this->getX(),
286  i->getY() - this->getY()));
287  }
288  }
289 
290 
291  /**
292  * Get mechanical model parameters.
293  *
294  * \return mechanical model parameters
295  */
296  const JMechanics& getMechanics() const
297  {
298  return mechanics;
299  }
300 
301 
302  /**
303  * Get floor data.
304  *
305  * \param floor floor number
306  * \return floor data
307  */
308  JFloor& operator[](size_t floor)
309  {
310  if (floor >= this->size()) {
311  this->resize(floor + 1);
312  }
313 
314  return static_cast<std::vector<JFloor>&>(*this)[floor];
315  }
316 
317 
318  /**
319  * Check if this string has receiver at given floor.
320  *
321  * \param floor floor
322  * \return true if receiver present; else false
323  */
324  bool hasFloor(size_t floor) const
325  {
326  if (floor == 0)
327  return has_hydrophone;
328  else
329  return (floor < this->size());
330  }
331 
332 
333  /**
334  * Get height of receiver at given floor with respect to reference position.
335  *
336  * \param floor floor
337  * \return height
338  */
339  double getHeight(const size_t floor) const
340  {
341  if (!hasFloor(floor)) {
342  THROW(JValueOutOfRange, "Invalid floor " << floor);
343  }
344 
345  if (floor == 0)
346  return hydrophone.getZ();
347  else
348  return (*this)[floor].getHeight();
349  }
350 
351 
352  /**
353  * Get position of receiver at given floor according to given string model parameters.
354  *
355  * \param parameters parameters
356  * \param floor floor
357  * \return position
358  */
360  const size_t floor) const
361  {
362  if (!hasFloor(floor)) {
363  THROW(JValueOutOfRange, "Invalid floor " << floor);
364  }
365 
366  if (floor == 0)
367  return this->getPosition() + hydrophone.getPosition();
368  else
369  return this->getPosition() + getPosition(parameters, this->mechanics, (*this)[floor].getHeight()) + (*this)[floor].getPosition();
370  }
371 
372 
373  /**
374  * Get position of receiver at given floor.
375  *
376  * \param floor floor
377  * \return position
378  */
379  JPosition3D getPosition(const size_t floor) const
380  {
381  if (!hasFloor(floor)) {
382  THROW(JValueOutOfRange, "Invalid floor " << floor);
383  }
384 
385  if (floor == 0)
386  return this->getPosition() + hydrophone.getPosition();
387  else
388  return this->getPosition() + JPosition3D(0.0, 0.0, (*this)[floor].getHeight()) + (*this)[floor].getPosition();
389  }
390 
391 
392  /**
393  * Get distance between given position and floor according to given string model parameters.
394  *
395  * \param parameters parameters
396  * \param position position
397  * \param floor floor
398  * \return distance
399  */
401  const JVector3D& position,
402  const size_t floor) const
403  {
404  return this->getPosition(parameters, floor).getDistance(position);
405  }
406 
407 
408  /**
409  * Get model gradient of distance between given position and floor according to given string model parameters.
410  *
411  * \param parameters parameters
412  * \param position position
413  * \param floor floor
414  * \return gradient
415  */
417  const JVector3D& position,
418  const size_t floor) const
419  {
420  if (floor == 0) {
421 
422  return JMODEL::JString();
423 
424  } else if (floor < this->size()) {
425 
426  const JPosition3D pos = this->getPosition(parameters, floor);
427  const double height = (*this)[floor].getHeight();
428  const double h1 = height * (1.0 + parameters.vs);
429  const double z1 = mechanics.getHeight(h1);
430 
431  const double tx = parameters.tx;
432  const double ty = parameters.ty;
433  const double tz = sqrt(1.0 - tx*tx - ty*ty);
434 
435  const double dx = pos.getX() - position.getX();
436  const double dy = pos.getY() - position.getY();
437  const double dz = pos.getZ() - position.getZ();
438 
439  const double D = sqrt(dx*dx + dy*dy + dz*dz);
440  const double vw = 1.0 - mechanics.a * mechanics.b / (1.0 - mechanics.a*h1);
441  const double vs = 1.0 + 0.5 * parameters.getLengthSquared() * vw;
442 
443  return JMODEL::JString(z1 * dx / D - height * (tx / tz) * dz / D,
444  z1 * dy / D - height * (ty / tz) * dz / D,
445  h1*h1 * dx / D,
446  h1*h1 * dy / D,
447  height * vw * (tx * dx + ty * dy) / D + h1 * (dz / vs) / D);
448 
449  } else {
450 
451  THROW(JValueOutOfRange, "Invalid floor " << floor);
452  }
453  }
454 
455 
456  /**
457  * Write string parameters to output stream.
458  *
459  * \param out output stream
460  * \param string string
461  * \return output stream
462  */
463  friend inline std::ostream& operator<<(std::ostream& out, const JString& string)
464  {
465  using namespace std;
466 
467  for (size_t i = 0; i != string.size(); ++i) {
468  if (string.hasFloor(i)) {
469  out << setw(2) << i << ' '
470  << FIXED(7,3) << string[i] << " | "
471  << string.getPosition(i) << ' '
472  << string.mechanics << endl;
473  }
474  }
475 
476  return out;
477  }
478 
479 
480  /**
481  * Hydrophone.
482  *
483  * The position of the hydrophone is relative to the reference position of the string.
484  */
487 
488  private:
489  /**
490  * Mechanical data.
491  */
493  };
494 
495 
496  /**
497  * Detector geometry.
498  */
499  struct JDetector :
500  public JHashMap<int, JString>
501  {
502  /**
503  * Default constructor.
504  */
506  {}
507 
508 
509  /**
510  * Constructor.
511  *
512  * Note that the positions of the base modules correspond to the reference position of the string.\n
513  * As a consequence, a base module (i.e.\ floor = 0) is required for each string.\n
514  * Missing base modules should therefore be added beforehand (e.g.\ using application JDetectorDB.cc).
515  *
516  * Note that if the position of a hydrophone is not available,
517  * it is assumed that there is no hydrophone on that string.\n
518  * If the position of the hydrophone is manually set,
519  * the corresponding parameter JString::has_hydrophone should be set to <tt>true</tt>.
520  *
521  * \param detector detector
522  * \param hydrophones container with data of hydrophones
523  */
525  const std::vector<JHydrophone>& hydrophones = std::vector<JHydrophone>())
526  {
527  using namespace std;
528  using namespace JPP;
529 
530  map<int, vector<module_type> > buffer; // string -> modules
531 
532  for (JDETECTOR::JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
533  buffer[module->getString()].push_back(module_type(module->getLocation(), module->getPosition()));
534  }
535 
536  for (map<int, vector<module_type> >::iterator i = buffer.begin(); i != buffer.end(); ++i) {
537 
538  sort(i->second.begin(), i->second.end(), make_comparator(&module_type::getFloor));
539 
540  if (i->second[0].getFloor() == 0) {
541 
542  JString& string = (*this)[i->first];
543 
544  vector<module_type>::iterator p = i->second.begin();
545 
546  ++p;
547 
548  string = JGEOMETRY::JString(i->second[0].getPosition(), getMechanics(i->first), p, i->second.end());
549 
550  try {
551 
552  string.hydrophone = getPosition(hydrophones.begin(),
553  hydrophones.end(),
555 
556  string.has_hydrophone = true;
557  }
558  catch(const exception&) {
559  string.has_hydrophone = false;
560  }
561 
562  } else {
563 
564  THROW(JNoValue, "No floor 0 in string " << i->first << "; use e.g. JDetectorDB -W.");
565  }
566  }
567  }
568 
569 
570  /**
571  * Check if this detector has given string.
572  *
573  * \param string string
574  * \return true if string present; else false
575  */
576  bool hasString(int string) const
577  {
578  return this->has(string);
579  }
580 
581 
582  /**
583  * Check if this detector has given location.
584  *
585  * \param location location
586  * \return true if location present; else false
587  */
588  bool hasLocation(const JLocation& location) const
589  {
590  return this->hasString(location.getString()) && (*this)[location.getString()].hasFloor(location.getFloor());
591  }
592 
593 
594  /**
595  * Write detector parameters to output stream.
596  *
597  * \param out output stream
598  * \param detector detector
599  * \return output stream
600  */
601  friend inline std::ostream& operator<<(std::ostream& out, const JDetector& detector)
602  {
603  using namespace std;
604 
605  for (JDetector::const_iterator i = detector.begin(); i != detector.end(); ++i) {
606  out << setw(4) << i->first << endl << i->second;
607  }
608 
609  return out;
610  }
611 
612 
613  /**
614  * Auxiliary data structure for module location and position.
615  */
616  struct module_type :
617  public JLocation,
618  public JPosition3D
619  {
620  /**
621  * Constructor.
622  *
623  * \param location module location
624  * \param position module position
625  */
626  module_type(const JLocation& location,
627  const JPosition3D& position) :
628  JLocation (location),
629  JPosition3D(position)
630  {}
631  };
632  };
633  }
634 
635 
636  /**
637  * Type definition of detector geometry.
638  */
640 }
641 
642 #endif
static double getHeight(const JMODEL::JString &parameters, const JMechanics &mechanics, const double length, const double precision=PRECISION_M)
Get approximate height of string.
Definition: JGeometry.hh:179
Data structure for vector in two dimensions.
Definition: JVector2D.hh:32
Mechanical modelling of string.
Module support kit.
Exceptions.
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
const JMechanics & getMechanics() const
Get mechanical model parameters.
Definition: JGeometry.hh:296
JComparator< JResult_t T::*, JComparison::lt > make_comparator(JResult_t T::*member)
Helper method to create comparator between values of data member.
int getFloor() const
Get floor number.
Definition: JLocation.hh:145
static JPosition3D getPosition(const JMODEL::JString &parameters, const JMechanics &mechanics, const double height)
Get position at given height according to given string model parameters and mechanics.
Definition: JGeometry.hh:215
General purpose class for hash map of unique keys.
Definition: JHashMap.hh:72
friend std::ostream & operator<<(std::ostream &out, const JFloor &floor)
Write floor parameters to output stream.
Definition: JGeometry.hh:116
then set_variable DIR else fatal Wrong number of arguments fi for INPUT_FILE in ls rt $DIR stage * log
General purpose class for hash map of unique elements.
Detector data structure.
Definition: JDetector.hh:89
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
double getHeight(const size_t floor) const
Get height of receiver at given floor with respect to reference position.
Definition: JGeometry.hh:339
*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
JString()
Default constructor.
Definition: JGeometry.hh:231
const JVector3D & getPosition() const
Get position of this floor.
Definition: JGeometry.hh:103
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
double getDistance(const JVector3D &pos) const
Get distance to point.
Definition: JVector3D.hh:270
JFloor()
Default constructor.
Definition: JGeometry.hh:65
Data structure for detector geometry and calibration.
JPosition3D getPosition(const size_t floor) const
Get position of receiver at given floor.
Definition: JGeometry.hh:379
Auxiliary data structure for module location and position.
Definition: JGeometry.hh:616
Type definition of hydrophone.
Definition: JHydrophone.hh:30
static constexpr double PRECISION_M
precision of height evaluation [m]
Definition: JGeometry.hh:148
Data structure for hydrophone.
friend std::ostream & operator<<(std::ostream &out, const JString &string)
Write string parameters to output stream.
Definition: JGeometry.hh:463
bool hasString(int string) const
Check if this detector has given string.
Definition: JGeometry.hh:576
JGEOMETRY::JDetector JGeometry
Type definition of detector geometry.
Definition: JGeometry.hh:639
Exception for missing value.
Definition: JException.hh:214
module_type(const JLocation &location, const JPosition3D &position)
Constructor.
Definition: JGeometry.hh:626
JString(const JVector3D &position, const JMechanics &mechanics)
Constructor.
Definition: JGeometry.hh:245
Detector file.
Definition: JHead.hh:226
Acoustics support kit.
std::vector< double > vs
Data structure for vector in three dimensions.
Definition: JVector3D.hh:34
Logical location of module.
Definition: JLocation.hh:37
double getDistance(const JMODEL::JString &parameters, const JVector3D &position, const size_t floor) const
Get distance between given position and floor according to given string model parameters.
Definition: JGeometry.hh:400
Acoustics toolkit.
JPosition3D getPosition(const JMODEL::JString &parameters, const size_t floor) const
Get position of receiver at given floor according to given string model parameters.
Definition: JGeometry.hh:359
JMODEL::JString getGradient(const JMODEL::JString &parameters, const JVector3D &position, const size_t floor) const
Get model gradient of distance between given position and floor according to given string model param...
Definition: JGeometry.hh:416
do set_variable OUTPUT_DIRECTORY $WORKDIR T
static double getLength(const JMODEL::JString &parameters, const JMechanics &mechanics, const double height)
Get approximate length of string.
Definition: JGeometry.hh:158
double a
0 &lt;= a &lt; (maximal height)⁻1; [m^-1]
Definition: JMechanics.hh:102
double getHeight(const double height) const
Get effective height for given actual height.
Definition: JMechanics.hh:70
double getLengthSquared() const
Get length squared.
double getY() const
Get y position.
Definition: JVector3D.hh:104
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
JDetector(const JDETECTOR::JDetector &detector, const std::vector< JHydrophone > &hydrophones=std::vector< JHydrophone >())
Constructor.
Definition: JGeometry.hh:524
double getLength() const
Get length.
Definition: JVector3D.hh:246
Logical location of module.
I/O manipulators.
JString(const JVector3D &position, const JMechanics &mechanics, T __begin, T __end)
Constructor.
Definition: JGeometry.hh:275
double b
0 &lt;= b; [m]
Definition: JMechanics.hh:103
JFloor & operator[](size_t floor)
Get floor data.
Definition: JGeometry.hh:308
bool hasFloor(size_t floor) const
Check if this string has receiver at given floor.
Definition: JGeometry.hh:324
int getString() const
Get string number.
Definition: JLocation.hh:134
friend std::ostream & operator<<(std::ostream &out, const JDetector &detector)
Write detector parameters to output stream.
Definition: JGeometry.hh:601
JPosition3D hydrophone
Hydrophone.
Definition: JGeometry.hh:485
JMechanics mechanics
Mechanical data.
Definition: JGeometry.hh:492
JPosition3D getPiezoPosition()
Get relative position of piezo in optical module.
JPosition3D()
Default constructor.
Definition: JPosition3D.hh:48
JDetector()
Default constructor.
Definition: JGeometry.hh:505
double getX() const
Get x position.
Definition: JVector3D.hh:94
bool hasLocation(const JLocation &location) const
Check if this detector has given location.
Definition: JGeometry.hh:588
Auxiliary data structure to list files in directory.
Definition: JFilesystem.hh:18
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
double getHeight() const
Get height of this floor.
Definition: JGeometry.hh:91
Exception for accessing a value in a collection that is outside of its range.
Definition: JException.hh:178
container_type::const_iterator const_iterator
Definition: JHashMap.hh:86
JFloor(const double height, const JVector2D &position=JVector2D())
Constructor.
Definition: JGeometry.hh:78
Model for fit to acoutsics data.
do echo Generating $dir eval D
Definition: JDrawLED.sh:53
double getZ() const
Get z position.
Definition: JVector3D.hh:115
Auxiliary data structure for parameters of mechanical model.
Definition: JMechanics.hh:41
container_type::iterator iterator
Definition: JHashMap.hh:88