1
2 """module for coordinate manipulation (conversions, calculations etc.)
3
4 (c) 2007-2009 Matt Hilton
5
6 U{http://astlib.sourceforge.net}
7
8 """
9
10 import sys
11 import math
12 from PyWCSTools import wcscon
13
14
16 """Converts a delimited string of Hours:Minutes:Seconds format into decimal degrees.
17
18 @type RAString: string
19 @param RAString: coordinate string in H:M:S format
20 @type delimiter: string
21 @param delimiter: delimiter character in RAString
22 @rtype: float
23 @return: coordinate in decimal degrees
24
25 """
26
27 if delimiter=="":
28 RABits=str(RAString).split()
29 else:
30 RABits=str(RAString).split(delimiter)
31 if len(RABits)>1:
32 RAHDecimal=float(RABits[0])
33 if len(RABits)>1:
34 RAHDecimal=RAHDecimal+(float(RABits[1])/60.0)
35 if len(RABits)>2:
36 RAHDecimal=RAHDecimal+(float(RABits[2])/3600.0)
37 RADeg=(RAHDecimal/24.0)*360.0
38 else:
39 RADeg=float(RAString)
40
41 return RADeg
42
43
45 """Converts a delimited string of Degrees:Minutes:Seconds format into decimal degrees.
46
47 @type decString: string
48 @param decString: coordinate string in D:M:S format
49 @type delimiter: string
50 @param delimiter: delimiter character in decString
51 @rtype: float
52 @return: coordinate in decimal degrees
53
54 """
55
56 if delimiter=="":
57 decBits=str(decString).split()
58 else:
59 decBits=str(decString).split(delimiter)
60 if len(decBits)>1:
61 decDeg=float(decBits[0])
62 if decBits[0].find("-")!=-1:
63 if len(decBits)>1:
64 decDeg=decDeg-(float(decBits[1])/60.0)
65 if len(decBits)>2:
66 decDeg=decDeg-(float(decBits[2])/3600.0)
67 else:
68 if len(decBits)>1:
69 decDeg=decDeg+(float(decBits[1])/60.0)
70 if len(decBits)>2:
71 decDeg=decDeg+(float(decBits[2])/3600.0)
72 else:
73 decDeg=float(decString)
74
75 return decDeg
76
77
79 """Converts decimal degrees to string in Hours:Minutes:Seconds format with user specified
80 delimiter.
81
82 @type RADeg: float
83 @param RADeg: coordinate in decimal degrees
84 @type delimiter: string
85 @param delimiter: delimiter character in returned string
86 @rtype: string
87 @return: coordinate string in H:M:S format
88
89
90 """
91 hours=(RADeg/360.0)*24
92 if hours<10 and hours>=1:
93 sHours="0"+str(hours)[0]
94 elif hours>=10:
95 sHours=str(hours)[:2]
96 elif hours<1:
97 sHours="00"
98
99
100 if str(hours).find(".")==-1:
101 mins=float(hours)*60.0
102 else:
103 mins=float(str(hours)[str(hours).index("."):])*60.0
104 if mins<10 and mins>=1:
105 sMins="0"+str(mins)[:1]
106 elif mins>=10:
107 sMins=str(mins)[:2]
108 elif mins<1:
109 sMins="00"
110
111 secs=(hours-(float(sHours)+float(sMins)/60.0))*3600.0
112 if secs<10 and secs>0.001:
113 sSecs="0"+str(secs)[:str(secs).find(".")+4]
114
115
116 elif secs<0.0001:
117 sSecs="00.001"
118 else:
119 sSecs=str(secs)[:str(secs).find(".")+4]
120 if len(sSecs)<5:
121 sSecs=sSecs+"00"
122
123
124 return sHours+delimiter+sMins+delimiter+sSecs
125
126
128 """Converts decimal degrees to string in Degrees:Minutes:Seconds format with user specified
129 delimiter.
130
131 @type decDeg: float
132 @param decDeg: coordinate in decimal degrees
133 @type delimiter: string
134 @param delimiter: delimiter character in returned string
135 @rtype: string
136 @return: coordinate string in D:M:S format
137
138 """
139
140 if decDeg>0:
141 if decDeg<10 and decDeg>=1:
142 sDeg="0"+str(decDeg)[0]
143 elif decDeg>=10:
144 sDeg=str(decDeg)[:2]
145 elif decDeg<1:
146 sDeg="00"
147
148 if str(decDeg).find(".")==-1:
149 mins=float(decDeg)*60.0
150 else:
151 mins=float(str(decDeg)[str(decDeg).index("."):])*60
152 if mins<10 and mins>=1:
153 sMins="0"+str(mins)[:1]
154 elif mins>=10:
155 sMins=str(mins)[:2]
156 elif mins<1:
157 sMins="00"
158
159 secs=(decDeg-(float(sDeg)+float(sMins)/60.0))*3600.0
160 if secs<10 and secs>0:
161 sSecs="0"+str(secs)[:str(secs).find(".")+3]
162 elif secs<0.001:
163 sSecs="00.00"
164 else:
165 sSecs=str(secs)[:str(secs).find(".")+3]
166 if len(sSecs)<5:
167 sSecs=sSecs+"0"
168
169 return "+"+sDeg+delimiter+sMins+delimiter+sSecs
170
171 else:
172 if decDeg>-10 and decDeg<=-1:
173 sDeg="-0"+str(decDeg)[1]
174 elif decDeg<=-10:
175 sDeg=str(decDeg)[:3]
176 elif decDeg>-1:
177 sDeg="-00"
178
179 if str(decDeg).find(".")==-1:
180 mins=float(decDeg)*-60.0
181 else:
182 mins=float(str(decDeg)[str(decDeg).index("."):])*60
183 if mins<10 and mins>=1:
184 sMins="0"+str(mins)[:1]
185 elif mins>=10:
186 sMins=str(mins)[:2]
187 elif mins<1:
188 sMins="00"
189
190 secs=(decDeg-(float(sDeg)-float(sMins)/60.0))*3600.0
191 if secs>-10 and secs<0:
192 sSecs="0"+str(secs)[1:str(secs).find(".")+3]
193 elif secs>-0.001:
194 sSecs="00.00"
195 else:
196 sSecs=str(secs)[1:str(secs).find(".")+3]
197 if len(sSecs)<5:
198 sSecs=sSecs+"0"
199
200 return sDeg+delimiter+sMins+delimiter+sSecs
201
202
204 """Calculates the angular separation of two positions on the sky (specified in decimal
205 degrees) in decimal degrees, assuming a tangent plane projection (so separation has to be
206 <90 deg).
207
208 @type RADeg1: float
209 @param RADeg1: R.A. in decimal degrees for position 1
210 @type decDeg1: float
211 @param decDeg1: dec. in decimal degrees for position 1
212 @type RADeg2: float
213 @param RADeg2: R.A. in decimal degrees for position 2
214 @type decDeg2: float
215 @param decDeg2: dec. in decimal degrees for position 2
216 @rtype: float
217 @return: angular separation in decimal degrees
218
219 """
220 cRA=math.radians(float(RADeg1))
221 cDec=math.radians(float(decDeg1))
222
223 gRA=math.radians(float(RADeg2))
224 gDec=math.radians(float(decDeg2))
225
226 dRA=cRA-gRA
227 dDec=gDec-cDec
228 cosC=(math.sin(gDec)*math.sin(cDec))+(math.cos(gDec)*math.cos(cDec)*math.cos(gRA-cRA))
229 x=(math.cos(cDec)*math.sin(gRA-cRA))/cosC
230 y=((math.cos(gDec)*math.sin(cDec))-(math.sin(gDec)*math.cos(cDec)*math.cos(gRA-cRA)))/cosC
231 r=math.degrees(math.sqrt(x*x+y*y))
232
233 return r
234
235
236 -def convertCoords(inputSystem, outputSystem, coordX, coordY, epoch):
237 """Converts specified coordinates (given in decimal degrees) between J2000, B1950, and
238 Galactic.
239
240 @type inputSystem: string
241 @param inputSystem: system of the input coordinates (either "J2000", "B1950" or "GALACTIC")
242 @type outputSystem: string
243 @param outputSystem: system of the returned coordinates (either "J2000", "B1950" or
244 "GALACTIC")
245 @type coordX: float
246 @param coordX: longitude coordinate in decimal degrees, e.g. R. A.
247 @type coordY: float
248 @param coordY: latitude coordinate in decimal degrees, e.g. dec.
249 @type epoch: float
250 @param epoch: epoch of the input coordinates
251 @rtype: list
252 @return: coordinates in decimal degrees in requested output system
253
254
255 """
256
257 if inputSystem=="J2000" or inputSystem=="B1950" or inputSystem=="GALACTIC":
258 if outputSystem=="J2000" or outputSystem=="B1950" or outputSystem=="GALACTIC":
259
260 outCoords=wcscon.wcscon(wcscon.wcscsys(inputSystem),
261 wcscon.wcscsys(outputSystem), 0, 0, coordX, coordY, epoch)
262
263 return outCoords
264
265 raise Exception, "inputSystem and outputSystem must be 'J2000', 'B1950' or 'GALACTIC'"
266
267
268