Hide keyboard shortcuts

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""" 

231 October 2014 

3 

4The class CosmologyObject provides an interface for the methods in astropy.cosmology that 

5we anticipate using the most. 

6 

7The methods in astropy.cosmology are accessed by instantiating a cosmology object and calling 

8methods that belong to that object. CosmologyObject interfaces with this by declaring a member 

9variable self.activeCosmology. Methods provided by CosmologyObject call the equivalent 

10astropy.cosmology methods on self.activeCosmology. activeCosmology is set by calling 

11CosmologyObject.initializeCosmology(args...) with the appropriate cosmological paramters. 

12Passing in no parametrs loads the Millennium Simulation cosmology (Springel et al 2005, Nature 435, 629 

13or arXiv:astro-ph/0504097). 

14 

15The difficulty with all of this that, between the version of astropy shipped with anaconda (v0.2.5) and 

16the most modern version (v0.4), the API for astropy.cosmology has changed in two ways. 

17 

18One difference is that methods like comoving_distance have gone from returning floats to returning 

19astropy.Quantity's which come with both a value and units. To deal with this, CosmologyObject 

20checks dir(cosmology.comoving_distance()) etc. If 'units' is defined, CosmologyObject sets 

21member variables such as self.distanceUnits, self.hUnits, and self.modulusUnits defining the units 

22in which we want to return those quantities. When you call the wrapper for comoving_distance, 

23CosmologyObject will make sure that the output is returned in the units we expect (Mpc). 

24The expected units are set in CosmologyObject.setUnits() 

25 

26The other API difference is in how 'default_cosmology' is stored. astropy.cosmology allows 

27the user to set a default cosmology that the system stores so that the user does not have to 

28constantly redeclare the same cosmology object at different points in the code. Unfortunately, 

29the naming conventions for the methods to set and retrieve this default cosmology have changed 

30between recent versions of astropy. CosmologyObject deals with this change in API using 

31CosmologyObject.setCurrent() (called automatically by CosmologyObject's __init__) 

32and CosmologyObject.getCurrent(), which returns a cosmology object containing the activeCosmology 

33contained in CosmologyObject. 

34 

35A user who wants to interact with the naked 

36astropy.cosmology methods can run something like 

37 

38uu = CosmologyObject() #which sets activeCosmology to the Millennium Simulation cosmology 

39myUniverse = uu.getCurrent() 

40 

41myUniverse now contains a cosmology object which is equivalent to the activeCosmology. Direct 

42calls to the astropy.cosmology methods of the form 

43 

44dd = myUniverse.comoving_distance(1.0) #comoving distance to redshift z=1 

45 

46will now work. 

47 

48 

49The methods in CosmologyObject have been tested on astropy v0.2.5 and v0.4.2 

50""" 

51 

52from builtins import object 

53import numpy 

54import astropy.cosmology as cosmology 

55import astropy.units as units 

56 

57flatnessthresh = 1.0e-12 

58 

59__all__ = ["CosmologyObject"] 

60 

61class CosmologyObject(object): 

62 

63 def __init__(self, H0=73.0, Om0=0.25, Ok0=None, w0=None, wa=None): 

64 """ 

65 Initialize the cosmology wrapper with the parameters specified 

66 (e.g. does not account for massive neutrinos) 

67 

68 param [in] H0 is the Hubble parameter at the present epoch in km/s/Mpc 

69 

70 param [in] Om0 is the current matter density paramter (fraction of critical density) 

71 

72 param [in] Ok0 is the current curvature density parameter 

73 

74 param [in] w0 is the current dark energy equation of state w0 paramter 

75 

76 param[in] wa is the current dark energy equation of state wa paramter 

77 

78 The total dark energy equation of state as a function of z is 

79 w = w0 + wa z/(1+z) 

80 

81 Currently, this wrapper class expects you to specify either a LambdaCDM (flat or non-flat) cosmology 

82 or a w0, wa (flat or non-flat) cosmology. 

83 

84 The default cosmology is taken as the cosmology used 

85 in the Millennium Simulation (Springel et al 2005, Nature 435, 629 or 

86 arXiv:astro-ph/0504097) 

87 

88 Om0 = 0.25 

89 Ob0 = 0.045 (baryons; not currently used in this code) 

90 H0 = 73.0 

91 Ok0 = 0.0, (implying Ode0 approx 0.75) 

92 w0 = -1.0 

93 wa = 0.0 

94 

95 where  

96 Om0 + Ok0 + Ode0 + Ogamma0 + Onu0 = 1.0  

97 

98 sigma_8 = 0.9 (rms mass flucutation in an 8 h^-1 Mpc sphere; 

99 not currently used in this code) 

100 

101 ns = 1 (index of the initial spectrum of linear mas perturbations; 

102 not currently used in this code) 

103 

104 """ 

105 

106 self.activeCosmology = None 

107 

108 if w0 is not None and wa is None: 

109 wa = 0.0 

110 

111 isCosmologicalConstant = False 

112 if (w0 is None and wa is None) or (w0==-1.0 and wa==0.0): 

113 isCosmologicalConstant = True 

114 

115 isFlat = False 

116 if Ok0 is None or (numpy.abs(Ok0) < flatnessthresh): 

117 isFlat = True 

118 

119 if isCosmologicalConstant and isFlat: 

120 universe = cosmology.FlatLambdaCDM(H0=H0, Om0=Om0) 

121 elif isCosmologicalConstant: 

122 tmpmodel = cosmology.FlatLambdaCDM(H0=H0, Om0=Om0) 

123 Ode0 = 1.0 - Om0 - tmpmodel.Ogamma0 - tmpmodel.Onu0 - Ok0 

124 universe = cosmology.LambdaCDM(H0=H0, Om0=Om0, Ode0=Ode0) 

125 elif isFlat: 

126 universe = cosmology.Flatw0waCDM(H0=H0, Om0=Om0, w0=w0, wa=wa) 

127 else: 

128 tmpmodel = cosmology.Flatw0waCDM(H0=H0, Om0=Om0, w0=w0, wa=wa) 

129 Ode0 = 1.0 - Om0 - tmpmodel.Ogamma0 - tmpmodel.Onu0 - Ok0 

130 

131 universe = cosmology.w0waCDM(H0=H0, Om0=Om0, Ode0=Ode0, 

132 w0=w0, wa=wa) 

133 

134 self.setCurrent(universe) 

135 

136 def setCurrent(self, universe): 

137 """ 

138 Take the cosmology indicated by 'universe' and set it as the current/default 

139 cosmology (depending on the API of the version of astropy being run) 

140 

141 universe is also assigned to self.activeCosmology, which is the cosmology that 

142 this wrapper's methods use for calculations. 

143 """ 

144 

145 if 'default_cosmology' in dir(cosmology): 

146 cosmology.default_cosmology.set(universe) 

147 elif 'set_current' in dir(cosmology): 

148 cosmology.set_current(universe) 

149 else: 

150 raise RuntimeError("CosmologyObject.setCurrent does not know how to handle this version of astropy") 

151 

152 self.activeCosmology = universe 

153 self.setUnits() 

154 

155 def setUnits(self): 

156 """ 

157 This method specifies the units in which various outputs from the wrapper are expected 

158 (this is because the latest version of astropy.cosmology outputs quantities such as 

159 the Hubble parameter and luminosity distance with units attached; the version of 

160 astropy.cosmology that comes within anaconda does not do this as of 30 October 2014) 

161 """ 

162 

163 H = self.activeCosmology.H(0.0) 

164 if 'unit' in dir(H): 

165 self.hUnits = units.Unit("km / (Mpc s)") 

166 else: 

167 self.hUnits = None 

168 

169 dd = self.activeCosmology.comoving_distance(0.0) 

170 if 'unit' in dir(dd): 

171 self.distanceUnits = units.Mpc 

172 else: 

173 self.distanceUnits = None 

174 

175 mm = self.activeCosmology.distmod(1.0) 

176 if 'unit' in dir(mm): 

177 self.modulusUnits = units.mag 

178 else: 

179 self.modulusUnits = None 

180 

181 def getCurrent(self): 

182 """ 

183 Return the cosmology currently stored as the current cosmology 

184 

185 This is for users who want direct access to all of astropy.cosmology's methods, 

186 not just those wrapped by this class. 

187 

188 documentation for astropy.cosmology can be found at the URL below (be sure to check which version of 

189 astropy you are running; as of 30 October 2014, the anaconda distributed with the stack 

190 comes with version 0.2.5) 

191 

192 https://astropy.readthedocs.org/en/v0.2.5/cosmology/index.html 

193 """ 

194 

195 return self.activeCosmology 

196 

197 def H(self, redshift=0.0): 

198 """ 

199 return the Hubble paramter in km/s/Mpc at the specified redshift 

200 

201 effectively wrapps astropy.cosmology.FLRW.H() 

202 """ 

203 

204 H = self.activeCosmology.H(redshift) 

205 

206 if 'value' in dir(H): 

207 if H.unit == self.hUnits: 

208 return H.value 

209 else: 

210 return H.to(self.hUnits).value 

211 else: 

212 return H 

213 

214 def OmegaMatter(self, redshift=0.0): 

215 """ 

216 return the matter density paramter (fraction of critical density) at the specified redshift 

217 

218 effectively wraps astropy.cosmology.FLRW.Om() 

219 """ 

220 

221 return self.activeCosmology.Om(redshift) 

222 

223 def OmegaDarkEnergy(self, redshift=0.0): 

224 """ 

225 return the dark energy density paramter (fraction of critical density) at the specified redshift 

226 

227 effectively wraps astropy.cosmology.FLRW.Ode() 

228 """ 

229 

230 return self.activeCosmology.Ode(redshift) 

231 

232 def OmegaPhotons(self, redshift=0.0): 

233 """ 

234 return the photon density paramter (fraction of critical density) at the specified redshift 

235 

236 effectively wraps astropy.cosmology.FLRW.Ogamma() 

237 """ 

238 

239 return self.activeCosmology.Ogamma(redshift) 

240 

241 def OmegaNeutrinos(self, redshift=0.0): 

242 """ 

243 return the neutrino density paramter (fraction of critical density) at the specified redshift 

244 

245 assumes neutrinos are massless 

246 

247 effectively wraps astropy.cosmology.FLRW.Onu() 

248 """ 

249 

250 return self.activeCosmology.Onu(redshift) 

251 

252 def OmegaCurvature(self, redshift=0.0): 

253 """ 

254 return the effective curvature density paramter (fraction of critical density) at the 

255 specified redshift. 

256 

257 Positive means the universe is open. 

258 

259 Negative means teh universe is closed. 

260 

261 Zero means the universe is flat. 

262 

263 effectively wraps astropy.cosmology.FLRW.Ok() 

264 """ 

265 

266 return self.activeCosmology.Ok(redshift) 

267 

268 def w(self, redshift=0.0): 

269 """ 

270 return the dark energy equation of state at the specified redshift 

271 

272 effecitvely wraps astropy.cosmology.FLRW.w() 

273 """ 

274 

275 return self.activeCosmology.w(redshift) 

276 

277 def comovingDistance(self, redshift=0.0): 

278 """ 

279 return the comoving distance to the specified redshift in Mpc 

280 

281 note, this comoving distance is X in the FRW metric 

282 

283 ds^2 = -c^2 dt^2 + a^2 dX^2 + a^2 sin^2(X) dOmega^2 

284 

285 i.e. the curvature of the universe is folded into the sin()/sinh() function. 

286 This distande just integrates dX = c dt/a 

287 

288 effectively wraps astropy.cosmology.FLRW.comoving_distance() 

289 """ 

290 dd = self.activeCosmology.comoving_distance(redshift) 

291 

292 if 'value' in dir(dd): 

293 if dd.unit == self.distanceUnits: 

294 return dd.value 

295 else: 

296 return dd.to(self.distanceUnits).value 

297 else: 

298 return dd 

299 

300 def luminosityDistance(self, redshift=0.0): 

301 """ 

302 the luminosity distance to the specified redshift in Mpc 

303 

304 accounts for spatial curvature 

305 

306 effectively wraps astropy.cosmology.FLRW.luminosity_distance() 

307 """ 

308 

309 dd = self.activeCosmology.luminosity_distance(redshift) 

310 

311 if 'value' in dir(dd): 

312 if dd.unit == self.distanceUnits: 

313 return dd.value 

314 else: 

315 return dd.to(self.distanceUnits).value 

316 else: 

317 return dd 

318 

319 def angularDiameterDistance(self, redshift=0.0): 

320 """ 

321 angular diameter distance to the specified redshift in Mpc 

322 

323 effectively wraps astropy.cosmology.FLRW.angular_diameter_distance() 

324 """ 

325 

326 dd = self.activeCosmology.angular_diameter_distance(redshift) 

327 

328 if 'value' in dir(dd): 

329 if dd.unit == self.distanceUnits: 

330 return dd.value 

331 else: 

332 return dd.to(self.distanceUnits).value 

333 else: 

334 return dd 

335 

336 def distanceModulus(self, redshift=0.0): 

337 """ 

338 distance modulus to the specified redshift 

339 

340 effectively wraps astropy.cosmology.FLRW.distmod() 

341 """ 

342 

343 mm = self.activeCosmology.distmod(redshift) 

344 if 'unit' in dir(mm): 

345 if mm.unit == self.modulusUnits: 

346 mod = mm.value 

347 else: 

348 mod = mm.to(self.modulusUnits).value 

349 else: 

350 mod = mm 

351 

352 #The astropy.cosmology.distmod() method has no problem returning a negative 

353 #distance modulus (or -inf if redshift==0.0) 

354 #Given that this makes no sense, the code below forces all distance moduli 

355 #to be greater than zero. 

356 # 

357 #a Runtime Warning will be raised (because distmod will try to take the 

358 #logarithm of luminosityDistance = 0, but the code will still run 

359 if isinstance(mod, float): 

360 if mod < 0.0: 

361 return 0.0 

362 else: 

363 return mod 

364 else: 

365 return numpy.where(mod>0.0, mod, 0.0)