Coverage for astrocalc/coords/separations.py : 96%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/local/bin/python
2# encoding: utf-8
3"""
4*Calculate separations between sky-coordinates*
6:Author:
7 David Young
8"""
9from __future__ import division
10from past.utils import old_div
11from builtins import object
12import sys
13import os
14import math
15os.environ['TERM'] = 'vt100'
16from fundamentals import tools
18class separations(object):
19 """
20 *The worker class for the separations module*
22 **Key Arguments**
24 - ``log`` -- logger
25 - ``settings`` -- the settings dictionary
26 - ``ra1`` -- the right-ascension of the first location. Decimal degrees or sexegesimal.
27 - ``dec1`` -- the declination of the first location. Decimal degrees or sexegesimal.
28 - ``ra2`` -- the right-ascension of the second location. Decimal degrees or sexegesimal.
29 - ``dec2`` -- the declination of the second location. Decimal degrees or sexegesimal.
32 **Usage**
34 .. todo::
36 - replace get_angular_separation throughout all code using dryxPython
37 - replace getAngularSeparationthroughout all code using dryxPython
39 You can input sexegesimal coordinates,
41 ```python
42 from astrocalc.coords import separations
43 calculator = separations(
44 log=log,
45 ra1="23:32:23.2324",
46 dec1="-13:32:45.43553",
47 ra2="23:32:34.642",
48 dec2="-12:12:34.9334",
49 )
50 angularSeparation, north, east = calculator.get()
51 print(angularSeparation, north, east)
53 # OUT: '4813.39431', '4810.50214', '166.83941'
54 ```
56 or decimal degrees,
58 ```python
59 from astrocalc.coords import separations
60 calculator = separations(
61 log=log,
62 ra1=2.3342343,
63 dec1=89.23244233,
64 ra2=45.343545345,
65 dec2=87.3435435
66 )
67 angularSeparation, north, east = calculator.get()
68 print(angularSeparation, north, east)
70 # OUT: '7774.4375', '-6800.0358', '4625.7620'
71 ```
73 or even a mix of both
75 ```python
76 from astrocalc.coords import separations
77 calculator = separations(
78 log=log,
79 ra1=352.5342343,
80 dec1=89.23,
81 ra2="23:32:34.642",
82 dec2="89:12:34.9334"
83 )
84 angularSeparation, north, east = calculator.get()
85 print(angularSeparation, north, east)
87 # OUT: '78.9', '-73.1', '29.9')
88 ```
90 """
91 # Initialisation
93 def __init__(
94 self,
95 log,
96 ra1,
97 dec1,
98 ra2,
99 dec2,
100 settings=False
101 ):
102 self.log = log
103 log.debug("instansiating a new 'separations' object")
104 self.settings = settings
105 self.ra1 = ra1
106 self.dec1 = dec1
107 self.ra2 = ra2
108 self.dec2 = dec2
109 # xt-self-arg-tmpx
110 return None
112 def get(
113 self):
114 """*Calulate the angular separation between two locations on the sky*
116 Input precision should be respected.
118 **Key Arguments**
122 **Return**
124 - ``angularSeparation`` -- total angular separation between coordinates (arcsec)
125 - ``north`` -- north-south separation between coordinates (arcsec)
126 - ``east`` -- east-west separation between coordinates (arcsec)
129 See main class usage for details.
130 """
131 self.log.debug('starting the ``get_angular_separation`` method')
133 from astrocalc.coords import unit_conversion
135 # CONSTANTS
136 pi = (4 * math.atan(1.0))
137 DEG_TO_RAD_FACTOR = old_div(pi, 180.0)
138 RAD_TO_DEG_FACTOR = old_div(180.0, pi)
140 converter = unit_conversion(
141 log=self.log
142 )
143 dec1 = converter.dec_sexegesimal_to_decimal(
144 dec=self.dec1
145 )
146 dec2 = converter.dec_sexegesimal_to_decimal(
147 dec=self.dec2
148 )
149 ra1 = converter.ra_sexegesimal_to_decimal(
150 ra=self.ra1
151 )
152 ra2 = converter.ra_sexegesimal_to_decimal(
153 ra=self.ra2
154 )
156 # PRECISION TEST
157 precision = 100
158 vals = [dec1, dec2, ra1, ra2]
159 for v in vals:
160 thisLen = len(repr(v * 3600.).split(".")[-1])
161 if thisLen < precision:
162 precision = thisLen
164 angularSeparation = None
166 aa = (90.0 - dec1) * DEG_TO_RAD_FACTOR
167 bb = (90.0 - dec2) * DEG_TO_RAD_FACTOR
168 cc = (ra1 - ra2) * DEG_TO_RAD_FACTOR
169 one = math.cos(aa) * math.cos(bb)
170 two = math.sin(aa) * math.sin(bb) * math.cos(cc)
172 # Because acos() returns NaN outside the ranges of -1 to +1
173 # we need to check this. Double precision decimal places
174 # can give values like 1.0000000000002 which will throw an
175 # exception.
177 three = one + two
178 if (three > 1.0):
179 three = 1.0
180 if (three < -1.0):
181 three = -1.0
183 # BE CAREFUL WITH PRECISION PROPAGATION
184 thisVal = math.acos(three)
185 angularSeparation = float(thisVal) * RAD_TO_DEG_FACTOR * 3600.0
187 # Now work out N-S, E-W separations (object 1 relative to 2)
188 north = -(dec1 - dec2) * 3600.0
189 east = -(ra1 - ra2) * \
190 math.cos((dec1 + dec2) * DEG_TO_RAD_FACTOR / 2.) * 3600.0
192 angularSeparation = "%0.*f" % (precision, angularSeparation)
193 north = "%0.*f" % (precision, north)
194 east = "%0.*f" % (precision, east)
196 self.log.debug('completed the ``get_angular_separation`` method')
197 return angularSeparation, north, east
199 # use the tab-trigger below for new method
200 # xt-class-method