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