Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-3a66518
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
TranslateAngles.c
Go to the documentation of this file.
1//
2// Copyright (C) 2004, 2005, 2015 Reinhard Prix
3// Copyright (C) 2013 Matt Pitkin
4// Copyright (C) 2007 Chris Messenger
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with with program; see the file COPYING. If not, write to the
18// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19// MA 02110-1301 USA
20//
21
22#include <math.h>
23#include <ctype.h>
24#include <errno.h>
25
26#include <lal/StringInput.h>
27#include <lal/LALConstants.h>
28#include <lal/LALString.h>
29#include <lal/TranslateAngles.h>
30
31// ==================== function definitions ====================
32
33///
34/// Translate a string representing an angle in the form "degrees:minutes:seconds" into radians. The string
35/// could also just contain "degrees:minutes" or "degrees", where the absent parts are set to zero.
36///
37/// It requires that the minutes and seconds values are between 0 to 60. Degrees are allowed to be a
38/// positive or negative integer between [-360, 360].
39/// An example would be: XLALTranslateDMStoRAD ( &radians, "-06:52:16.875" );
40///
41int
42XLALTranslateDMStoRAD ( REAL8 *radians, const CHAR *dms )
43{
44 XLAL_CHECK ( dms != NULL, XLAL_EINVAL, "Angle input string 'dms' is NULL" );
45 XLAL_CHECK ( radians != NULL, XLAL_EINVAL );
46
47 XLAL_CHECK ( !isspace(dms[0]), XLAL_EINVAL, "No initial whitespace allowed in input string '%s'\n", dms );
48 XLAL_CHECK ( dms[strlen(dms)-1] != ':', XLAL_EINVAL, "No trailing colons allowed in input string '%s'\n", dms );
49
50 REAL8 s = 0.;
51 INT4 d = 0, m = 0;
52 int numitems = sscanf(dms, "%d:%d:%lf", &d, &m, &s);
53
54 XLAL_CHECK ( numitems == 3 || numitems == 2 || numitems == 1, XLAL_EINVAL, "Angle input string '%s' not in format 'degs:mins:secs'", dms );
55 XLAL_CHECK ( d >= -360 && d <= 360, XLAL_EDOM, "Degrees '%d' outside of valid range of [-360,360] deg\n", d );
56 XLAL_CHECK ( m >= 0 && m < 60, XLAL_EDOM, "Minutes '%d' outside of the valid range of [0, 59] mins", m );
57 XLAL_CHECK ( s >= 0 && s < 60, XLAL_EDOM, "Seconds '%lf' outside of the valid range of [0, 60) secs", s );
58
59 // check if there's a minus sign, and apply to minutes and seconds (degrees would already have it)
60 // Note that this is the reason we don't accept initial whitespace in the input string
61 REAL8 sig = 1;
62 if ( dms[0] == '-' ) {
63 sig = -1;
64 }
65
66 // now convert the pieces from degrees to radians
67 (*radians) = (LAL_PI/180.0) * ( d + (sig*m / 60.0) + (sig*s / 3600.0) );
68
69 return XLAL_SUCCESS;
70
71} // XLALTranslateDMStoRAD()
72
73///
74/// Translate a string representing an angle in the form "hours:minutes:seconds" into radians. The string
75/// could also just contain "hours:minutes" or "hours", where the absent parts are set to zero.
76///
77/// It requires that the hours value to be within [0, 23] hours, and the minutes and seconds values are within [0, 60).
78/// An example would be: XLALTranslateHMStoRAD( &radians, "12:05:07.765" );
79///
80int
81XLALTranslateHMStoRAD ( REAL8 *radians, const CHAR *hms )
82{
83 XLAL_CHECK_REAL8( hms != NULL, XLAL_EINVAL, "Angle input string 'hms' is NULL" );
84 XLAL_CHECK ( radians != NULL, XLAL_EINVAL );
85
86 XLAL_CHECK ( hms[strlen(hms)-1] != ':', XLAL_EINVAL, "No trailing colons allowed in input string '%s'\n", hms );
87
88 REAL8 s = 0.;
89 INT4 h = 0, m = 0;
90 int numitems = sscanf(hms, "%d:%d:%lf", &h, &m, &s);
91
92 XLAL_CHECK_REAL8 ( numitems == 3 || numitems == 2 || numitems == 1, XLAL_EINVAL, "Angle input string '%s' not in format 'hours:mins:secs'\n", hms );
93 XLAL_CHECK_REAL8 ( h >= 0 && h < 24, XLAL_EDOM, "Hours value '%d' must be within [0, 23]\n", h );
94 XLAL_CHECK_REAL8 ( m >= 0 && m < 60, XLAL_EDOM, "Minutes value '%d' must be within [0 to 59]\n", m );
95 XLAL_CHECK_REAL8 ( s >= 0 && s < 60, XLAL_EDOM, "Seconds value '%lf' must be within [0,60)\n", s );
96
97 /* convert from hh:mm:ss to radians */
98 const REAL8 hour2deg = 360./24.;
99 const REAL8 deg2rad = LAL_PI/180.0;
100 const REAL8 hour2rad = hour2deg * deg2rad;
101
102 (*radians) = hour2rad * ( h + (m / 60.0) + (s / 3600.0) );
103
104 return XLAL_SUCCESS;
105
106} // XLALTranslateHMStoRAD()
107
108
109///
110/// Translate (longitude, right-ascencsion, RA) radians into hours:minutes:seconds (HMS) format, returns allocated string.
111///
112CHAR *
114{
115 XLAL_CHECK_NULL ( (radians>=0.0) && (radians < LAL_TWOPI), XLAL_EDOM, "RA %g not in range [0, 2pi) rad\n", radians );
116
117 REAL8 remainderH = radians * 24.0/LAL_TWOPI;
118 INT4 hours = (INT4) floor ( remainderH );
119 remainderH -= hours;
120 INT4 minutes = (INT4) floor ( remainderH * 60.0 );
121 remainderH -= minutes / 60.0;
122 REAL8 seconds = remainderH * 3600.0;
123 INT4 roundedSec = (INT4) round ( seconds * 10000000 ) / 10000000; // round to 1e-7s accuracy
124 if ( roundedSec == 60 )
125 {
126 seconds = 0;
127 minutes ++;
128 if ( minutes == 60 )
129 {
130 minutes = 60;
131 hours ++;
132 if ( hours == 24 ) {
133 hours = 0;
134 }
135 }
136 }
137 CHAR hms[256];
138 snprintf ( hms, sizeof(hms)-1, "%02d:%02d:%010.7f", hours, minutes, seconds ); // output format taken from tempo2
139
140 return XLALStringDuplicate ( hms );
141
142} // XLALTranslateRADtoHMS()
143
144///
145/// Translate (latitude, declination, DEC) radians into "sign*degrees:minutes:seconds" (DMS) format, returns allocated string
146///
147CHAR *
149{
150 XLAL_CHECK_NULL ( (radians >= -LAL_PI_2) && (radians < LAL_PI_2), XLAL_EDOM, "DEC %g not in range [-pi/2, pi/2) rad\n", radians);
151
152 CHAR sign = (radians < 0) ? '-' : '+';
153
154 REAL8 remainderDeg = fabs ( radians * 360.0/LAL_TWOPI );
155
156 INT4 degrees = (INT4) floor ( remainderDeg );
157 remainderDeg -= degrees;
158 INT4 arcmins = (INT4) floor ( remainderDeg * 60.0 );
159 remainderDeg -= arcmins / 60.0;
160 REAL8 arcsecs = remainderDeg * 3600.0;
161 INT4 roundedArcsecs = (INT4) round ( arcsecs * 100000 ) / 100000; // round to 1e-5 arcsec accuracy
162 if ( roundedArcsecs == 60 )
163 {
164 arcsecs = 0;
165 arcmins ++;
166 if ( arcmins == 60 )
167 {
168 arcmins = 0;
169 degrees ++;
170 }
171 }
172
173 CHAR dms[256];
174 snprintf ( dms, sizeof(dms)-1, "%c%02d:%02d:%08.5f", sign, degrees, arcmins, arcsecs );
175
176 return XLALStringDuplicate ( dms );
177
178} // XLALTranslateRADtoDMS()
static int sign(int s)
Definition: LALStringTest.c:27
#define LAL_PI_2
pi/2
Definition: LALConstants.h:181
#define LAL_PI
Archimedes's constant, pi.
Definition: LALConstants.h:179
#define LAL_TWOPI
2*pi is circumference of a circle divided by its radius
Definition: LALConstants.h:180
double REAL8
Double precision real floating-point number (8 bytes).
char CHAR
One-byte signed integer, see Headers LAL(Atomic)Datatypes.h for more details.
int32_t INT4
Four-byte signed integer.
char * XLALStringDuplicate(const char *s)
Like strdup but uses LAL allocation routines (free with LALFree).
Definition: LALString.c:89
static const INT4 m
Definition: Random.c:80
int XLALTranslateHMStoRAD(REAL8 *radians, const CHAR *hms)
Translate a string representing an angle in the form "hours:minutes:seconds" into radians.
CHAR * XLALTranslateRADtoHMS(REAL8 radians)
Translate (longitude, right-ascencsion, RA) radians into hours:minutes:seconds (HMS) format,...
int XLALTranslateDMStoRAD(REAL8 *radians, const CHAR *dms)
Translate a string representing an angle in the form "degrees:minutes:seconds" into radians.
CHAR * XLALTranslateRADtoDMS(REAL8 radians)
Translate (latitude, declination, DEC) radians into "sign*degrees:minutes:seconds" (DMS) format,...
#define XLAL_CHECK(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns an integ...
Definition: XLALError.h:810
#define XLAL_CHECK_REAL8(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns a REAL8.
Definition: XLALError.h:870
#define XLAL_CHECK_NULL(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns a pointe...
Definition: XLALError.h:825
@ XLAL_SUCCESS
Success return value (not an error number)
Definition: XLALError.h:401
@ XLAL_EDOM
Input domain error.
Definition: XLALError.h:410
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409