Jpp master_rocky-44-g75b7c4f75
the software that should make you happy
Loading...
Searching...
No Matches
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
25
29#include "JAcoustics/JModel.hh"
30
31
32/**
33 * \file
34 *
35 * Acoustic geometries.
36 * \author mdejong
37 */
38namespace JACOUSTICS {}
39namespace JPP { using namespace JACOUSTICS; }
40
41namespace 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 */
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()) :
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 {
146 using std::vector<JFloor>::operator[];
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 */
215 static inline JPosition3D getPosition(const JMODEL::JString& parameters,
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),
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),
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 */
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 */
400 double getDistance(const JMODEL::JString& parameters,
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 */
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(),
554 make_predicate(&JHydrophone::getString, i->first));
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
Acoustics support kit.
Acoustics toolkit.
Model for fit to acoutsics data.
Data structure for detector geometry and calibration.
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
General purpose class for hash map of unique elements.
Data structure for hydrophone.
Logical location of module.
I/O manipulators.
Mechanical modelling of string.
Module support kit.
Detector data structure.
Definition JDetector.hh:96
Logical location of module.
Definition JLocation.hh:40
int getFloor() const
Get floor number.
Definition JLocation.hh:146
int getString() const
Get string number.
Definition JLocation.hh:135
Data structure for vector in two dimensions.
Definition JVector2D.hh:34
Data structure for position in three dimensions.
JPosition3D()
Default constructor.
const JPosition3D & getPosition() const
Get position.
Data structure for vector in three dimensions.
Definition JVector3D.hh:36
double getY() const
Get y position.
Definition JVector3D.hh:104
double getLength() const
Get length.
Definition JVector3D.hh:246
double getDistance(const JVector3D &pos) const
Get distance to point.
Definition JVector3D.hh:270
double getZ() const
Get z position.
Definition JVector3D.hh:115
double getX() const
Get x position.
Definition JVector3D.hh:94
Exception for missing value.
Exception for accessing a value in a collection that is outside of its range.
Auxiliary classes and methods for acoustic position calibration.
JVector3D getPosition(T __begin, T __end, const JPredicate< JTypename_t, JComparator_t > &predicate)
Get position from element in data which corresponds to given predicate.
JGEOMETRY::JDetector JGeometry
Type definition of detector geometry.
Definition JGeometry.hh:639
static JDetectorMechanics getMechanics
Function object to get string mechanics.
JPosition3D getPiezoPosition()
Get relative position of piezo in optical module.
JComparator< JResult_t T::*, JComparison::lt > make_comparator(JResult_t T::*member)
Helper method to create comparator between values of data member.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
std::vector< double > vs
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Detector file.
Definition JHead.hh:227
Auxiliary data structure for module location and position.
Definition JGeometry.hh:619
module_type(const JLocation &location, const JPosition3D &position)
Constructor.
Definition JGeometry.hh:626
JDetector(const JDETECTOR::JDetector &detector, const std::vector< JHydrophone > &hydrophones=std::vector< JHydrophone >())
Constructor.
Definition JGeometry.hh:524
bool hasLocation(const JLocation &location) const
Check if this detector has given location.
Definition JGeometry.hh:588
bool hasString(int string) const
Check if this detector has given string.
Definition JGeometry.hh:576
friend std::ostream & operator<<(std::ostream &out, const JDetector &detector)
Write detector parameters to output stream.
Definition JGeometry.hh:601
JDetector()
Default constructor.
Definition JGeometry.hh:505
friend std::ostream & operator<<(std::ostream &out, const JFloor &floor)
Write floor parameters to output stream.
Definition JGeometry.hh:116
JFloor()
Default constructor.
Definition JGeometry.hh:65
double getHeight() const
Get height of this floor.
Definition JGeometry.hh:91
JFloor(const double height, const JVector2D &position=JVector2D())
Constructor.
Definition JGeometry.hh:78
const JVector3D & getPosition() const
Get position of this floor.
Definition JGeometry.hh:103
JPosition3D hydrophone
Hydrophone.
Definition JGeometry.hh:485
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
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
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
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
double getHeight(const size_t floor) const
Get height of receiver at given floor with respect to reference position.
Definition JGeometry.hh:339
JFloor & operator[](size_t floor)
Get floor data.
Definition JGeometry.hh:308
JString()
Default constructor.
Definition JGeometry.hh:231
const JMechanics & getMechanics() const
Get mechanical model parameters.
Definition JGeometry.hh:296
JString(const JVector3D &position, const JMechanics &mechanics)
Constructor.
Definition JGeometry.hh:245
bool hasFloor(size_t floor) const
Check if this string has receiver at given floor.
Definition JGeometry.hh:324
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
friend std::ostream & operator<<(std::ostream &out, const JString &string)
Write string parameters to output stream.
Definition JGeometry.hh:463
static constexpr double PRECISION_M
precision of height evaluation [m]
Definition JGeometry.hh:148
JMechanics mechanics
Mechanical data.
Definition JGeometry.hh:492
JString(const JVector3D &position, const JMechanics &mechanics, T __begin, T __end)
Constructor.
Definition JGeometry.hh:275
static double getLength(const JMODEL::JString &parameters, const JMechanics &mechanics, const double height)
Get approximate length of string.
Definition JGeometry.hh:158
const JPosition3D & getPosition() const
Get position.
JPosition3D getPosition(const size_t floor) const
Get position of receiver at given floor.
Definition JGeometry.hh:379
double getLengthSquared() const
Get length squared.
Auxiliary data structure for parameters of mechanical model.
Definition JMechanics.hh:41
double a
0 <= a < (maximal height)⁻1; [m^-1]
double b
0 <= b; [m]
double getHeight(const double height) const
Get effective height for given actual height.
Definition JMechanics.hh:70
Type definition of hydrophone.
Auxiliary data structure to list files in directory.
General purpose class for hash map of unique keys.
Definition JHashMap.hh:75
container_type::const_iterator const_iterator
Definition JHashMap.hh:86