Coverage for astrocalc/distances/converter.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*Convert distances between measurement scales*
6:Author:
7 David Young
8"""
9from __future__ import division
10from builtins import range
11from builtins import object
12from past.utils import old_div
13import sys
14import os
15import math
16os.environ['TERM'] = 'vt100'
17from fundamentals import tools
19class converter(object):
20 """
21 *A converter to switch distance between various units of measurement*
23 **Key Arguments**
25 - ``log`` -- logger
26 - ``settings`` -- the settings dictionary
29 **Usage**
31 To instantiate a ``converter`` object:
33 ```python
34 from astrocalc.distances import converter
35 c = converter(log=log)
36 ```
38 """
39 # Initialisation
41 def __init__(
42 self,
43 log,
44 settings=False,
46 ):
47 self.log = log
48 log.debug("instansiating a new 'converter' object")
49 self.settings = settings
50 # xt-self-arg-tmpx
52 # Initial Actions
54 return None
56 def distance_to_redshift(
57 self,
58 mpc):
59 """*Convert a distance from MPC to redshift*
61 The code works by iteratively converting a redshift to a distance, correcting itself and honing in on the true answer (within a certain precision)
63 **Key Arguments**
65 - ``mpc`` -- distance in MPC (assumes a luminousity distance).
68 **Return**
70 - ``redshift``
73 .. todo::
75 - replace convert_mpc_to_redshift in all code
77 **Usage**
79 ```python
80 from astrocalc.distances import converter
81 c = converter(log=log)
82 z = c.distance_to_redshift(
83 mpc=500
84 )
86 print(z)
88 # OUTPUT: 0.108
89 ```
91 """
92 self.log.debug('starting the ``distance_to_redshift`` method')
94 lowerLimit = 0.
95 upperLimit = 30.
96 redshift = upperLimit - lowerLimit
97 distGuess = float(self.redshift_to_distance(redshift)['dl_mpc'])
99 distDiff = mpc - distGuess
101 while math.fabs(distDiff) > 0.0001:
102 if distGuess < mpc:
103 lowerLimit = redshift
104 redshift = lowerLimit + (upperLimit - lowerLimit) / 2.
105 distGuess = float(
106 self.redshift_to_distance(redshift)['dl_mpc'])
107 elif distGuess > mpc:
108 upperLimit = redshift
109 redshift = lowerLimit + (upperLimit - lowerLimit) / 2.
110 distGuess = float(
111 self.redshift_to_distance(redshift)['dl_mpc'])
112 distDiff = mpc - distGuess
114 redshift = float("%5.4f" % (redshift,))
116 self.log.debug('completed the ``distance_to_redshift`` method')
117 return redshift
119 def redshift_to_distance(
120 self,
121 z,
122 WM=0.3,
123 WV=0.7,
124 H0=70.0):
125 """*convert redshift to various distance measurements*
127 **Key Arguments**
129 - ``z`` -- redshift measurement.
130 - ``WM`` -- Omega_matter. Default *0.3*
131 - ``WV`` -- Omega_vacuum. Default *0.7*
132 - ``H0`` -- Hubble constant. (km s-1 Mpc-1) Default *70.0*
135 **Return**
137 - ``results`` -- result dictionary including
138 - ``dcmr_mpc`` -- co-moving radius distance
139 - ``da_mpc`` -- angular distance
140 - ``da_scale`` -- angular distance scale
141 - ``dl_mpc`` -- luminosity distance (usually use this one)
142 - ``dmod`` -- distance modulus (determined from luminosity distance)
145 .. todo::
147 - replace convert_redshift_to_distance in all other code
149 **Usage**
151 ```python
152 from astrocalc.distances import converter
153 c = converter(log=log)
154 dists = c.redshift_to_distance(
155 z=0.343
156 )
158 print("Distance Modulus: " + str(dists["dmod"]) + " mag")
159 print("Luminousity Distance: " + str(dists["dl_mpc"]) + " Mpc")
160 print("Angular Size Scale: " + str(dists["da_scale"]) + " kpc/arcsec")
161 print("Angular Size Distance: " + str(dists["da_mpc"]) + " Mpc")
162 print("Comoving Radial Distance: " + str(dists["dcmr_mpc"]) + " Mpc")
164 # OUTPUT :
165 # Distance Modulus: 41.27 mag
166 # Luminousity Distance: 1795.16 Mpc
167 # Angular Size Scale: 4.85 kpc/arcsec
168 # Angular Size Distance: 999.76 Mpc
169 # Comoving Radial Distance: 1339.68 Mpc
171 from astrocalc.distances import converter
172 c = converter(log=log)
173 dists = c.redshift_to_distance(
174 z=0.343,
175 WM=0.286,
176 WV=0.714,
177 H0=69.6
178 )
180 print("Distance Modulus: " + str(dists["dmod"]) + " mag")
181 print("Luminousity Distance: " + str(dists["dl_mpc"]) + " Mpc")
182 print("Angular Size Scale: " + str(dists["da_scale"]) + " kpc/arcsec")
183 print("Angular Size Distance: " + str(dists["da_mpc"]) + " Mpc")
184 print("Comoving Radial Distance: " + str(dists["dcmr_mpc"]) + " Mpc")
186 # OUTPUT :
187 # Distance Modulus: 41.29 mag
188 # Luminousity Distance: 1811.71 Mpc
189 # Angular Size Scale: 4.89 kpc/arcsec
190 # Angular Size Distance: 1008.97 Mpc
191 # Comoving Radial Distance: 1352.03 Mpc
192 ```
194 """
195 self.log.debug('starting the ``redshift_to_distance`` method')
197 # VARIABLE
198 h = H0 / 100.0
199 WR = old_div(4.165E-5, (h * h)) # Omega_radiation
200 WK = 1.0 - WM - WV - WR # Omega_curvature = 1 - Omega(Total)
201 c = 299792.458 # speed of light (km/s)
203 # Arbitrarily set the values of these variables to zero just so we can
204 # define them.
205 DCMR = 0.0 # comoving radial distance in units of c/H0
206 DCMR_Mpc = 0.0 # comoving radial distance in units of Mpc
207 DA = 0.0 # angular size distance in units of c/H0
208 DA_Mpc = 0.0 # angular size distance in units of Mpc
209 # scale at angular size distance in units of Kpc / arcsec
210 DA_scale = 0.0
211 DL = 0.0 # luminosity distance in units of c/H0
212 DL_Mpc = 0.0 # luminosity distance in units of Mpc
213 # Distance modulus determined from luminosity distance
214 DMOD = 0.0
215 a = 0.0 # 1/(1+z), the scale factor of the Universe
217 az = 1.0 / (1.0 + z) # 1/(1+z), for the given redshift
219 # Compute the integral over a=1/(1+z) from az to 1 in n steps
220 n = 1000
221 for i in range(n):
222 a = az + old_div((1.0 - az) * (i + 0.5), n)
223 adot = math.sqrt(WK + (old_div(WM, a)) + (old_div(WR, (math.pow(a, 2))))
224 + (WV * math.pow(a, 2)))
225 DCMR = DCMR + 1.0 / (a * adot)
227 # comoving radial distance in units of c/H0
228 DCMR = old_div((1.0 - az) * DCMR, n)
229 # comoving radial distance in units of Mpc
230 DCMR_Mpc = (old_div(c, H0)) * DCMR
232 # Tangental comoving radial distance
233 x = math.sqrt(abs(WK)) * DCMR
234 if x > 0.1:
235 if WK > 0.0:
236 ratio = old_div(0.5 * (math.exp(x) - math.exp(-x)), x)
237 else:
238 ratio = old_div(math.sin(x), x)
239 else:
240 y = math.pow(x, 2)
241 if WK < 0.0:
242 y = -y
243 ratio = 1 + y / 6.0 + math.pow(y, 2) / 120.0
245 DA = az * ratio * DCMR # angular size distance in units of c/H0
246 DA_Mpc = (old_div(c, H0)) * DA # angular size distance in units of Mpc
247 # scale at angular size distance in units of Kpc / arcsec
248 DA_scale = DA_Mpc / 206.264806
249 DL = old_div(DA, math.pow(az, 2)) # luminosity distance in units of c/H0
250 DL_Mpc = (old_div(c, H0)) * DL # luminosity distance in units of Mpc
251 # Distance modulus determined from luminosity distance
252 DMOD = 5 * math.log10(DL_Mpc * 1e6) - 5
254 # FIXING PRECISIONS
255 # PRECISION TEST
256 precision = len(repr(z).split(".")[-1])
257 DCMR_Mpc = "%0.*f" % (precision, DCMR_Mpc)
258 DA_Mpc = "%0.*f" % (precision, DA_Mpc)
259 DA_scale = "%0.*f" % (precision, DA_scale)
260 DL_Mpc = "%0.*f" % (precision, DL_Mpc)
261 DMOD = "%0.*f" % (precision, DMOD)
262 z = "%0.*f" % (precision, z)
264 results = \
265 {
266 "dcmr_mpc": float(DCMR_Mpc),
267 "da_mpc": float(DA_Mpc),
268 "da_scale": float(DA_scale),
269 "dl_mpc": float(DL_Mpc),
270 "dmod": float(DMOD),
271 "z": float(z)
272 }
274 self.log.debug('completed the ``redshift_to_distance`` method')
275 return results
277 # use the tab-trigger below for new method
278 # xt-class-method