casacore
Loading...
Searching...
No Matches
MVAngle.h
Go to the documentation of this file.
1// # MVAngle.h: Class to handle angle type conversions and I/O
2// # Copyright (C) 1996,1997,1998,1999,2000,2001
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_MVANGLE_H
27#define CASA_MVANGLE_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/casa/Quanta/Quantum.h>
32#include <casacore/casa/iosfwd.h>
33
34namespace casacore { // # NAMESPACE CASACORE - BEGIN
35
36// # Forward Declarations
37class String;
38class MUString;
39
40// # Constants (SUN compiler does not accept non-simple default arguments)
41
42// <summary>
43// Class to handle angle type conversions and I/O
44// </summary>
45
46// <use visibility=export>
47
48// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tMeasure" demos="">
49// </reviewed>
50
51// <prerequisite>
52// <li> <linkto class=Quantum>Quantum</linkto>
53// </prerequisite>
54//
55// <etymology>
56// From Measure, Value and Angle
57// </etymology>
58//
59// <synopsis>
60// An MVAngle is a simple Double, to be used for angle conversions and I/O.
61// It can be constructed from a Double (in which case radians are assumed),
62// or from a Quantity (<src>Quantum<Double></src>). Quantities must be in
63// either angle or time units.<br>
64// It has an automatic conversion to Double, so all standard mathematical
65// operations can operate on it.<br>
66// The class has a number of special member operations:
67// <ul>
68// <li> <src>MVAngle operator()</src> will normalise the angle between
69// -180 and +180(inclusive) degrees and return the value
70// <li> <src>MVAngle operator(Double)</src> will normalise the angle
71// using the value specified (and return the value)
72// in fractions of a circle (this was chosen rather than radians to make
73// for easier and more precise programming) as a lower bound. I.e.
74// (-0.5) will normalise between -180 and +180 degrees, (0.) between
75// 0 and 360 degrees, (-0.25) between -90 and +270 degrees,
76// (5.) between 1800 and 2160 dgrees.
77// <li> <src>MVAngle operator(MVAngle)</src> will normalise (and
78// return the normalised value) to within 180 degrees of the
79// argument value. This is useful for making a range of angles
80// contiguous.
81// <li> <src>MVAngle binorm(Double)</src> will normalise the angle in
82// steps of 180 degrees.
83// using the value specified (and return the value)
84// in fractions of 180 degrees (this was chosen rather than radians to make
85// for easier and more precise programming) as a lower bound. I.e.
86// (-0.5) will normalise between -90 and +90 degrees, (0.) between
87// 0 and 180 degrees, (10.) between 1800 and 1980 dgrees.
88// <li> <src>Double radian()</src> will return value in radians
89// <li> <src>Double degree()</src> will return value in degrees
90// <li> <src>Double circle()</src> will return value in fraction of circles
91// <li> <src>MVAngle coAngle()</src> will return 90-angle (or rather
92// pi/2 - angle), with (0) normalisation.
93// <li> <src>Quantity get()</src> will return radians
94// <li> <src>Quantity get(Unit)</src> will return in specified units
95// (angle or time)
96// </ul>
97// Output formatting is done with the <src><<</src> statement, with the
98// following rules:
99// <ul>
100// <li> standard output is done in the following format:
101// <src>+ddd.mm.ss.tt</src> with a floating sign. The number of
102// digits presented will be based on the precision attached to the
103// current stream
104// <li> output can be formatted by using either the <src>setFormat()</src>
105// method for global angle format setting, or the output of
106// <src>MVAngle::Format()</src> data for a once off change (see later).
107// Formats have a first argument which
108// determines the type (default, if not given, MVAngle::ANGLE, other
109// possibility MVAngle::TIME (as hh:mm:ss.tt..),
110// the second the number of digits wanted (default stream precision),
111// with a value:
112// <ul>
113// <li> <3 : ddd.. only
114// <li> <5 : ddd.mm.
115// <li> <7 : ddd.mm.ss
116// <li> >6 : with precision-6 t's added
117// </ul>
118// comparable for time. <note role=tip> The added periods are to enable input
119// checking of the format. Look at the 'clean' types to bypass them.
120// </note>
121// The output format can be modified with modifiers (specify as
122// MVAngle::ANGLE | MVAngle::MOD (or + MVAngle::MOD)).
123// <note role=caution>
124// For overloading/casting problems with some compilers, the
125// use of modifiers necessitates either the presence of a precision
126// (i.e. <src>(A|B, prec)</src>), or an explicit cast:
127// <src>((MVAngle::formatTypes)(A|B))</src>, or make use of
128// the provided <src>ANGLE[_CLEAN][_NO_D[M]]</src> and
129// <src>TIME[_CLEAN][_NO_H[M]].</src>
130// </note>
131//
132// The modifiers can be:
133// <ul>
134// <li> <src>MVAngle::CLEAN</src> to suppress leading or trailing
135// periods (or colons for TIME), + and leading zeroes in degree
136// field for angle representation will be replaced with a space.
137// Note that the result can not be read automatically.
138// <li> <src>MVAngle::NO_D</src> (or <src>NO_H</src>) to suppress
139// the output of degrees (or hours): useful for offsets
140// <li> <src>MVAngle::NO_DM</src> (or <src>NO_HM</src>), to
141// suppress the degrees and minutes.
142// <li> <src>MVAngle::DIG2</src> to allow only 2 digits for degrees,
143// or -12 - +12 range for hours
144// <li> <src>MVAngle::LOCAL</src> to indicate local time to FITS
145// formatting only
146// <li> <src>MVAngle::FITS</src> to produce, if
147// LOCAL set, the time zone (note that if local set
148// here, as opposed to in MVTime) the angle is supposed
149// to be in local time already).
150// <li> <src>MVAngle::ALPHA</src> to use d (or h) and m instead of
151// periods or colons.
152// </ul>
153// Output in formats like <src>20'</src> can be done via the standard
154// Quantum output (e.g. <src> stream << angle.get("'") </src>).
155// <li> Available formats:
156// <ul>
157// <li> MVAngle::ANGLE in +ddd.mm.ss.ttt format
158// <li> MVAngle::TIME in hh:mm:ss.ttt format
159// <li> MVAngle::[ANGLE|TIME]_CLEAN format without superfluous periods
160// <li> MVAngle::[ANGLE|TIME][_CLEAN]_NO_[D|H][M] in format with
161// leading zero fields left empty.
162// <li> MVAngle::CLEAN modifier for suppressing superfluous periods
163// <li> MVAngle::NO_[D|H][M] modifier to suppress first field(s)
164// <li> MVAngle::DIG2 modifier to output in +dd.mm.ss.ttt format or
165// in time format in range -12 to +12h
166// </ul>
167// </ul>
168// The default formatting can be overwritten by a
169// <src> MVAngle::setFormat(); </src> statement; which returns an
170// MVAngle::Format
171// structure, that can be used in a subsequent one to reset to previous.
172// The format set holds for all MVAngle output on all streams.<br>
173// Temporary formats (i.e. for one MVAngle output only), can be set by
174// outputting a format (i.e. <src> stream << MVAngle::Format() << ... </src>).
175// <note role=caution> A setFormat() will also reset any lingering temporary format.
176// A setFormat(getFormat()) will reset without changing. Problems could
177// arise in parallel processors. </note>
178// Input can be read if the values are in any of the above (non-clean) output
179// formats. <br>
180// For other formatting practice, the output can be written to a String with
181// the string() member function.<br>
182// Note that using a temporary format is inherently thread-unsafe because
183// the format is kept in a static variable. Another thread may overwrite
184// the format just set. The only thread-safe way to format an MVTime is using
185// a <src>print</src> or <src>string</src> that accepts a Format object.
186//
187// Strings and input can be converted to an MVAngle (or Quantity) by
188// <src>Bool read(Quantity &out, const String &in)</src> and
189// <src> istream >> MVAngle &</src>. In the latter case the actual
190// reading is done by the String read, which reads between white-spaces.<br>
191// The following input formats (note no blanks allowed) are supported
192// (+stands for an optional + or -; v for an unsigned integer; dv for a
193// floating number. [] indicate optional values. Separating codes are
194// case insensitive):
195// <ul>
196// <li> +[v].[v].[dv] -- value in deg, arcmin, arcsec
197// <li> +[v]D[v[M[dv]]] -- value in deg, arcmin, arcsec
198// <li> +[v]:[v[:[dv]]] -- value in h, min, s
199// <li> +[v]H[v[M[dv]]] -- value in h, min, s
200// <li> +[v]{D|H|:}[dv] -- value in deg (or h), arcmin (or min)
201// <li> +dv[unit string] -- value in time or angle units. rad default
202// </ul>
203// Examples of valid strings:
204// <srcblock>
205// 5::2.59 5h + 0min + 2.59 s
206// 5..2.59 5deg + 0arcmin + 2.59arcsec
207// 5.259 5.259 rad
208// 5..259 5deg + 259arcsec
209// 5.259a 5.259 * pi * 2 *365.25 rad (normalised)
210// </srcblock>
211// <note role=caution> In general the input will be read as a Quantity.
212// Reading of Quantities will always try to read special formats (like
213// MVAngle, MVTime) first. In
214// that case problems could arise converting strings like 5d, 5::, 5hm, 5dm.
215// In 'angle' mode they could have meant to be
216// 5d0m, 5:0:, 5h0m, 5d0m, but they could have
217// meant: days, min, hectometre, decimetre. In the same vain 5d2 could have
218// meant 5d2m or 5 d<sup>2</sup>.
219// To try to guess the general use, the following interpretation is made:
220// <ul>
221// <li> 5d, 5:: == 5deg, 5h0m; make float (like 5.d) to make it days/min
222// <li> 5dm, 5hm == decimetre, hectometre; use 5d0m 5h0m for
223// angle
224// <li> 5d2, 5h2, 5:2 == 5d2m, 5h2m, 5:2:; use float 5 or explicit () for
225// other interpretation
226// </ul>
227// </note>
228// </synopsis>
229//
230// <example>
231// See synopsis
232// </example>
233//
234// <motivation>
235// To be able to format angle-like values in user-required ways.
236// </motivation>
237//
238// <todo asof="1997/09/16">
239// <li> Use AipsrcData once moved to aips from trial
240// </todo>
241
242class MVAngle {
243 public:
244 // # Enumerations (should mimic those in MVTime)
245 // Format types
271
272 // # Local structure
273 // Format structure
274 class Format {
275 public:
276 friend class MVAngle;
278 : typ(intyp), prec(inprec) {
279 ;
280 };
281 Format(uInt inprec) : typ(MVAngle::ANGLE), prec(inprec) { ; };
282 // Construct from type and precision (present due to overlaoding problems)
283 Format(uInt intyp, uInt inprec) : typ((MVAngle::formatTypes)intyp), prec(inprec) { ; };
284
285 private:
288 };
289
290 // # Friends
291 // Output an angle
292 friend ostream &operator<<(ostream &os, const MVAngle &meas);
293 // Input an angle
294 friend istream &operator>>(istream &is, MVAngle &meas);
295 // Set a temporary format
296 friend ostream &operator<<(ostream &os, const MVAngle::Format &form);
297
298 // # Constructors
299 // Default constructor: generate a zero value
301 // Copy constructor
302 MVAngle(const MVAngle &other);
303 // Copy assignment
304 MVAngle &operator=(const MVAngle &other);
305 // Constructor from Double
307 // Constructor from Quantum : value can be an angle or time
308 // <thrown>
309 // <li> AipsError if not a time or angle
310 // </thrown>
311 MVAngle(const Quantity &other);
312
313 // Destructor
315
316 // # Operators
317 // Conversion operator
318 operator Double() const;
319 // Normalisation between -180 and +180 degrees (-pi and +pi)
321 // Normalisation between 2pi*norm and 2pi*norm + 2pi
323 // Normalisation between norm-pi and norm+pi
325
326 // # General member functions
327 // Normalisation between pi*norm and pi*norm + pi
329 // Check if String unit
330 static Bool unitString(UnitVal &uv, String &us, MUString &in);
331
332 // Make res angle Quantity from string in angle/time-like format. In the
333 // case of String input, also quantities are recognised.
334 // chk=True means that the entire string should be consumed.
335 // throwExcp=True means that an exception is thrown in case of an error.
336 // <group>
337 static Bool read(Quantity &res, const String &in, Bool chk = True);
338 static Bool read(Quantity &res, MUString &in, Bool chk = True);
339 static Bool read(Quantity &res, const String &in, Bool chk, Bool throwExcp);
340 static Bool read(Quantity &res, MUString &in, Bool chk, Bool throwExcp);
341 // </group>
342 // Handle a read error. An exception is thrown if indicated so.
343 // Otherwise in.pop() is called and False is returned.
344 static Bool handleReadError(MUString &in, Bool throwExcp);
345
346 // Make co-angle (e.g. zenith distance from elevation)
348 // Get value in given unit
349 // <group>
350 Double radian() const;
351 Double degree() const;
352 Double circle() const;
353 Quantity get() const;
354 Quantity get(const Unit &inunit) const;
355 // </group>
356 // Output data
357 // <note role=warning>
358 // The first function below is thread-unsafe because it uses the result of
359 // the setFormat function which changes a static class member.
360 // The other functions are thread-safe because the format is directly given.
361 // </note>
362 // <group>
363 String string() const;
364 String string(MVAngle::formatTypes intyp, uInt inprec = 0) const;
365 String string(uInt intyp, uInt inprec) const;
366 String string(uInt inprec) const;
367 String string(const MVAngle::Format &form) const;
368 void print(ostream &oss, const MVAngle::Format &form) const;
369 void print(ostream &oss, const MVAngle::Format &form, Bool loc) const;
370 // </group>
371 // Set default format
372 // <note role=warning>
373 // It is thread-unsafe to print using the setFormat functions because they
374 // change a static class member. The only thred-safe way to print a time is
375 // to use the print function above.
376 // </note>
377 // <group>
378 static Format setFormat(MVAngle::formatTypes intyp, uInt inprec = 0);
379 static Format setFormat(uInt intyp, uInt inprec);
380 static Format setFormat(uInt inprec = 0);
381 static Format setFormat(const Format &form);
382 // </group>
383 // Get default format
385 // Get code belonging to string. 0 if not known
387 // Get time zone offset (in days)
388 static Double timeZone();
389
390 private:
391 // # Data
392 // Value
394 // Default format
396 // Temporary format
397 // <group>
400 // </group>
401
402 // # Member functions
403};
404
405// Global functions
406// <summary> Global output/input functions </summary>
407// Output/Input
408// <group name=output>
409ostream &operator<<(ostream &os, const MVAngle &meas);
410istream &operator>>(istream &is, MVAngle &meas);
411// Set a temporary format (thread-unsafe).
412ostream &operator<<(ostream &os, const MVAngle::Format &form);
413// </group>
415} // namespace casacore
416
417#endif
Format structure.
Definition MVAngle.h:274
MVAngle::formatTypes typ
Definition MVAngle.h:286
Format(MVAngle::formatTypes intyp=MVAngle::ANGLE, uInt inprec=0)
Definition MVAngle.h:277
Format(uInt intyp, uInt inprec)
Construct from type and precision (present due to overlaoding problems).
Definition MVAngle.h:283
String string(const MVAngle::Format &form) const
static Bool read(Quantity &res, MUString &in, Bool chk, Bool throwExcp)
String string(uInt intyp, uInt inprec) const
String string(uInt inprec) const
String string() const
Output data Warning: The first function below is thread-unsafe because it uses the result of the set...
~MVAngle()
Destructor.
Double circle() const
void print(ostream &oss, const MVAngle::Format &form) const
MVAngle(const MVAngle &other)
Copy constructor.
static Format setFormat(MVAngle::formatTypes intyp, uInt inprec=0)
Set default format Warning: It is thread-unsafe to print using the setFormat functions because they ...
const MVAngle & operator()(Double norm)
Normalisation between 2pi*norm and 2pi*norm + 2pi.
static Double timeZone()
Get time zone offset (in days).
static Format getFormat()
Get default format.
static Bool read(Quantity &res, const String &in, Bool chk=True)
Make res angle Quantity from string in angle/time-like format.
MVAngle(const Quantity &other)
Constructor from Quantum : value can be an angle or time.
friend ostream & operator<<(ostream &os, const MVAngle::Format &form)
Set a temporary format.
MVAngle(Double d)
Constructor from Double.
static Bool read(Quantity &res, const String &in, Bool chk, Bool throwExcp)
MVAngle()
Default constructor: generate a zero value.
formatTypes
Format types.
Definition MVAngle.h:246
MVAngle coAngle() const
Make co-angle (e.g.
static Bool unitString(UnitVal &uv, String &us, MUString &in)
Check if String unit.
static MVAngle::formatTypes giveMe(const String &in)
Get code belonging to string.
static MVAngle::Format interimFormat
Temporary format.
Definition MVAngle.h:398
const MVAngle & binorm(Double norm)
Normalisation between pi*norm and pi*norm + pi.
friend istream & operator>>(istream &is, MVAngle &meas)
Input an angle.
static MVAngle::Format defaultFormat
Default format.
Definition MVAngle.h:395
static Format setFormat(uInt intyp, uInt inprec)
void print(ostream &oss, const MVAngle::Format &form, Bool loc) const
Quantity get() const
Double val
Value.
Definition MVAngle.h:393
Double radian() const
Get value in given unit.
Double degree() const
Quantity get(const Unit &inunit) const
MVAngle & operator=(const MVAngle &other)
Copy assignment.
const MVAngle & operator()(const MVAngle &norm)
Normalisation between norm-pi and norm+pi.
static Format setFormat(const Format &form)
String string(MVAngle::formatTypes intyp, uInt inprec=0) const
static Bool read(Quantity &res, MUString &in, Bool chk=True)
static Bool interimSet
Definition MVAngle.h:399
static Format setFormat(uInt inprec=0)
friend ostream & operator<<(ostream &os, const MVAngle &meas)
Output an angle.
const MVAngle & operator()()
Normalisation between -180 and +180 degrees (-pi and +pi).
static Bool handleReadError(MUString &in, Bool throwExcp)
Handle a read error.
String: the storage and methods of handling collections of characters.
Definition String.h:355
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
friend AipsIO & operator>>(AipsIO &os, Record &rec)
Read the Record from an input stream.
Definition Record.h:431
ostream & operator<<(ostream &os, const IComplex &)
Show on ostream.
unsigned int uInt
Definition aipstype.h:49
T norm(const TableVector< T > &tv)
Definition TabVecMath.h:419
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
Quantum< Double > Quantity
Definition Quantum.h:40
const Bool True
Definition aipstype.h:41
double Double
Definition aipstype.h:53
ostream & operator<<(ostream &os, const MVAngle::Format &form)
Set a temporary format (thread-unsafe).
istream & operator>>(istream &is, MVAngle &meas)
ostream & operator<<(ostream &os, const MVAngle &meas)