1 """
2 Unit test covering sed.fit.py
3
4 @author: Joris Vos
5 """
6 import numpy as np
7 from numpy import inf, array
8 from cc.ivs import sigproc
9 from cc.ivs.sed import fit, model, builder, filters
10 from cc.ivs.units import constants
11 from cc.ivs.catalogs import sesame
12 from cc.ivs.aux import loggers
13 from cc.ivs.units import constants
14 from matplotlib import mlab
15
16 import unittest
17 try:
18 import mock
19 from mock import patch
20 noMock = False
21 except Exception:
22 noMock = True
23
24
25 noIntegration = False
28 """Add some extra usefull assertion methods to the testcase class"""
29
31 patcher = patch.object(name, method, **kwargs)
32 thing = patcher.start()
33 self.addCleanup(patcher.stop)
34 return thing
35
37 msg_ = "Array is not equal to expected array: %s != %s"%(l1,l2)
38 if msg != None: msg_ = msg
39 self.assertEqual(len(l1), len(l2), msg=msg_)
40 self.assertEqual(l1.dtype, l2.dtype, msg=msg_)
41 for f1, f2 in zip(l1,l2):
42 self.assertEqual(f1,f2, msg=msg_)
43
45 msg_ = "assertArrayAlmostEqual Failed: %s != %s"%(str(l1),str(l2))
46 if msg != None: msg_ = msg_ + msg
47 for f1, f2 in zip(l1, l2):
48 self.assertAlmostEqual(f1,f2,places=places, delta=delta, msg=msg_)
49
51 self.assertGreaterEqual(min(l), low, msg=msg)
52 self.assertLessEqual(max(l), high, msg=msg)
53
55 self.assertGreaterEqual(min(l), low, msg=msg)
56 self.assertLessEqual(max(l), high, msg=msg)
57 lr = np.round(l, decimals=places)
58 self.assertTrue(len(np.unique(lr)) > 1, msg="All elements are equal: %s"%(l))
59
61 msg_ = "The given element %s is not in list %s"%(el, lst)
62 if msg != None: msg_=msg
63 res = []
64 for l in lst:
65 try:
66 res.append(all(el == l))
67 except Exception:
68 res.append(el == l)
69 self.assertTrue(any(res), msg=msg_)
70
72 args_, kwargs_ = mck.call_args
73 if args != None:
74 for arg in args:
75 msg_ = msg if msg != None else \
76 'Argument %s was not in call to %s (called with args: %s)'%(arg, mck, args_)
77 self.assertInList(arg, args_, msg=msg_)
78 if kwargs != None:
79 for key in kwargs.keys():
80 msg_ = msg if msg != None else \
81 'Key Word Argument %s=%s was not in call to %s (called with args: %s)'% \
82 (key, kwargs[key], mck, kwargs_)
83 self.assertTrue(key in kwargs_, msg_)
84 try:
85 self.assertEqual(kwargs[key], kwargs_[key], msg_)
86 except Exception:
87 self.assertArrayAlmostEqual(kwargs[key], kwargs_[key], places=5)
88
91
92 @classmethod
100
102 self.photbands = ['STROMGREN.U', '2MASS.H']
103
105 """ model.get_itable_pix() single case """
106 bgrid = {'teff': array([ 5500., 6874., 9645., 7234., 5932.]),
107 'logg': array([ 3.57, 4.00, 4.21, 3.84, 3.25]),
108 'ebv': array([ 0.0018, 0.0077, 0.0112, 0.0046, 0.0110]),
109 'rv': array([ 2.20, 2.40, 2.60, 2.80, 3.00]),
110 'z': array([ -0.5, -0.4, -0.3, -0.2, 0.0])}
111
112 flux_,Labs_ = model.get_itable_pix(photbands=self.photbands, **bgrid)
113
114 flux = [[3255462., 13286738., 53641850., 16012786., 4652578.69189492],
115 [967634., 1262321., 1789486., 1336016., 1066763.]]
116 Labs = [0.819679, 1.997615, 7.739527, 2.450019, 1.107916]
117
118 self.assertArrayAlmostEqual(flux_[0],flux[0],delta=100)
119 self.assertArrayAlmostEqual(flux_[1],flux[1],delta=100)
120 self.assertArrayAlmostEqual(Labs_,Labs,places=3)
121
122
124 """ model.get_itable_pix() multiple case """
125 bgrid = {'teff': array([ 22674., 21774., 22813., 29343., 28170.]),
126 'logg': array([ 5.75, 6.07, 6.03 , 6.38, 5.97]),
127 'ebv': array([ 0.0018, 0.0077, 0.0112, 0.0046, 0.0110]),
128 'rad': array([ 4.96, 7.34, 4.56, 3.30, 8.54]),
129 'teff2': array([ 38779., 36447., 32099. , 31392., 35893.]),
130 'logg2': array([ 4.67, 4.92, 5.46, 4.96, 4.85]),
131 'ebv2': array([ 0.0018, 0.0077, 0.0112, 0.0046, 0.0110]),
132 'rad2': array([ 6.99, 9.61, 9.55, 6.55, 3.99])}
133
134 flux_,Labs_ = model.get_itable_pix(photbands=self.photbands, **bgrid)
135
136 flux = [[1.69858e+11, 2.88402e+11, 1.98190e+11, 1.00088e+11, 1.39618e+11],
137 [5.78019e+08, 1.04221e+09, 7.42561e+08, 3.63444e+08, 5.52846e+08]]
138 Labs = [67046.5663, 115877.0362, 81801.3768, 39791.7467, 56369.3989]
139
140 self.assertArrayAlmostEqual(flux_[0],flux[0],delta=0.01e+11)
141 self.assertArrayAlmostEqual(flux_[1],flux[1],delta=0.01e+09)
142 self.assertArrayAlmostEqual(Labs_,Labs,places=3)
143
145 """ model.get_itable() single case """
146
147 flux_,Labs_ = model.get_itable(photbands=self.photbands, teff=6874, logg=4.21,
148 ebv=0.0077, z=-0.2)
149 flux = [13428649.32576484, 1271090.21316342]
150 Labs = 1.99865981674
151
152 self.assertAlmostEqual(flux_[0],flux[0], delta=100)
153 self.assertAlmostEqual(flux_[1],flux[1], delta=100)
154 self.assertAlmostEqual(Labs_,Labs, delta=100)
155
156
158 """ model.get_itable() multiple case """
159
160 flux_,Labs_ = model.get_itable(photbands=self.photbands, teff=25000,
161 logg=5.12, ebv=0.001, teff2=33240, logg2=5.86, ebv2=0.001)
162
163 flux = [3.31834622e+09, 1.25032866e+07]
164 Labs = 1277.54498257
165
166 self.assertAlmostEqual(flux_[0],flux[0], delta=100)
167 self.assertAlmostEqual(flux_[1],flux[1], delta=100)
168 self.assertAlmostEqual(Labs_,Labs, delta=100)
169
171 """ model.get_table() single case """
172
173 wave, flux = model.get_table(teff=6874, logg=4.21, ebv=0.0)
174
175 self.assertEqual(len(wave), len(flux))
176 self.assertEqual(len(wave), 1221)
177 self.assertAlmostEqual(wave[0], 90.9, delta=0.1)
178 self.assertAlmostEqual(wave[-1], 1600000.0, delta=0.1)
179 self.assertAlmostEqual(wave[400], 4370.0, delta=0.1)
180 self.assertAlmostEqual(wave[800], 15925.0, delta=0.1)
181 self.assertAlmostEqual(flux[0], 0.0, delta=0.0001)
182 self.assertAlmostEqual(flux[-1], 0.020199, delta=0.0001)
183 self.assertAlmostEqual(flux[400], 24828659.5845, delta=0.0001)
184 self.assertAlmostEqual(flux[800], 1435461.60457, delta=0.0001)
185
187 """ model.get_table() multiple case """
188
189 wave,flux = model.get_table(teff=25000, logg=5.12, ebv=0.001,
190 teff2=33240, logg2=5.86, ebv2=0.001)
191
192
193 self.assertEqual(len(wave), len(flux))
194 self.assertEqual(len(wave), 123104)
195 self.assertAlmostEqual(wave[0], 1000, delta=0.1)
196 self.assertAlmostEqual(wave[-1], 24999.8, delta=0.1)
197 self.assertAlmostEqual(wave[40000], 8671.20117188, delta=0.001)
198 self.assertAlmostEqual(wave[80000], 16509.4003906, delta=0.001)
199 self.assertAlmostEqual(flux[0], 170415154318.0, delta=0.5)
200 self.assertAlmostEqual(flux[-1], 2457826.26898, delta=0.0001)
201 self.assertAlmostEqual(flux[40000], 141915936.111, delta=0.001)
202 self.assertAlmostEqual(flux[80000], 12450102.801, delta=0.001)
203
205
206 @classmethod
214
215
217 self.photbands = ['STROMGREN.U', '2MASS.H']
218
220 """ fit.generate_grid_pix() single case """
221 grid = fit.generate_grid_single_pix(self.photbands,teffrange=(5000,10000),
222 loggrange=(3.50,4.50),ebvrange=(0.0, 0.012),zrange=(-0.5,0.0),
223 rvrange=(-inf,inf),points=50)
224
225 self.assertTrue('teff' in grid)
226 self.assertTrue('logg' in grid)
227 self.assertTrue('ebv' in grid)
228 self.assertTrue('rv' in grid)
229 self.assertTrue('z' in grid)
230
231 self.assertFalse('teff2' in grid)
232 self.assertFalse('rad' in grid)
233
234 self.assertAllBetweenDiff(grid['teff'], 5000, 10000, places=-2)
235 self.assertAllBetweenDiff(grid['logg'], 3.5, 4.5, places=1)
236 self.assertAllBetweenDiff(grid['ebv'], 0.0, 0.012, places=3)
237 self.assertAllBetweenDiff(grid['rv'], 2.1, 3.1, places=1)
238 self.assertAllBetweenDiff(grid['z'], -0.5, 0.0, places=1)
239
241 """ fit.generate_grid_pix() binary case """
242 grid = fit.generate_grid_pix(self.photbands,teffrange=(5000,10000),
243 teff2range=(30000, 40000), loggrange=(3.5,4.50),
244 logg2range=(4.50, 6.50), ebvrange=(0.0, 0.012),
245 rvrange=(2.1,3.1), rv2range=(2.1,3.1),
246 masses=[0.47*1.63, 0.47], points=50)
247
248 self.assertTrue('teff' in grid)
249 self.assertTrue('logg' in grid)
250 self.assertTrue('teff2' in grid)
251 self.assertTrue('logg2' in grid)
252 self.assertTrue('ebv' in grid)
253 self.assertTrue('ebv2' in grid)
254 self.assertTrue('rad' in grid)
255 self.assertTrue('rad2' in grid)
256 self.assertFalse('z' in grid)
257 self.assertFalse('z2' in grid)
258
259 self.assertListEqual(grid['ebv'].tolist(), grid['ebv2'].tolist(),
260 msg="ebv should be the same for both components.")
261 self.assertListEqual(grid['rv'].tolist(), grid['rv2'].tolist(),
262 msg="Rv should be the same for both components.")
263
264 self.assertAllBetweenDiff(grid['teff'], 5000, 10000, places=-2)
265 self.assertAllBetweenDiff(grid['logg'], 3.5, 4.5, places=1)
266 self.assertAllBetweenDiff(grid['ebv'], 0.0, 0.012, places=3)
267 self.assertAllBetweenDiff(grid['rv'], 2.1, 3.1, places=1)
268 self.assertAllBetweenDiff(grid['teff2'], 30000, 40000, places=-2)
269 self.assertAllBetweenDiff(grid['logg2'], 4.5, 6.5, places=1)
270
271 G, Msol, Rsol = constants.GG_cgs, constants.Msol_cgs, constants.Rsol_cgs
272 rad = np.sqrt(G*0.47*1.63*Msol/10**grid['logg'])/Rsol
273 rad2 = np.sqrt(G*0.47*Msol/10**grid['logg2'])/Rsol
274
275 self.assertListEqual(rad.tolist(), grid['rad'].tolist())
276 self.assertListEqual(rad2.tolist(), grid['rad2'].tolist())
277
278
280 """ fit.generate_grid_pix() multiple case """
281 grid = fit.generate_grid_pix(self.photbands,teffrange=(5000,10000),
282 teff2range=(20000, 40000), loggrange=(3.5,4.5),radrange=(0.1,1.0),
283 logg2range=(4.50, 6.50), ebvrange=(0.0, 0.012),rad2range=(1.0,10.0),
284 points=50)
285
286 self.assertTrue('teff' in grid)
287 self.assertTrue('logg' in grid)
288 self.assertTrue('teff2' in grid)
289 self.assertTrue('logg2' in grid)
290 self.assertTrue('ebv' in grid)
291 self.assertTrue('ebv2' in grid)
292 self.assertTrue('rad' in grid)
293 self.assertTrue('rad2' in grid)
294 self.assertFalse('z' in grid)
295 self.assertFalse('z2' in grid)
296 self.assertFalse('rv' in grid)
297 self.assertFalse('rv2' in grid)
298
299 self.assertListEqual(grid['ebv'].tolist(), grid['ebv2'].tolist())
300
301 self.assertAllBetweenDiff(grid['teff'], 5000, 10000, places=-2)
302 self.assertAllBetweenDiff(grid['logg'], 3.5, 4.5, places=1)
303 self.assertAllBetweenDiff(grid['ebv'], 0.0, 0.012, places=3)
304 self.assertAllBetweenDiff(grid['rad'], 0.1, 1.0, places=1)
305 self.assertAllBetweenDiff(grid['teff2'], 20000, 40000, places=-2)
306 self.assertAllBetweenDiff(grid['logg2'], 4.5, 6.5, places=1)
307 self.assertAllBetweenDiff(grid['rad2'], 1.0, 10.0, places=0)
308
309 @unittest.skipIf(noMock, "Mock not installed")
311 """ fit.igrid_search_pix() """
312 meas = array([3.64007e-13, 2.49267e-13, 9.53516e-14] )
313 emeas = array([3.64007e-14, 2.49267e-14, 9.53516e-15])
314 photbands = ['STROMGREN.U', 'STROMGREN.B', 'STROMGREN.V']
315 grid = {'teff': array([ 22674., 21774., 22813., 29343., 28170.]),
316 'logg': array([ 5.75, 6.07, 6.03 , 6.38, 5.97]),
317 'ebv': array([ 0.0018, 0.0077, 0.0112, 0.0046, 0.0110]),
318 'z': array([0,0,0,0,0]),
319 'rv': array([ 2.20, 2.40, 2.60, 2.80, 3.00])}
320 syn_flux = array([[8.0218e+08, 7.2833e+08, 8.1801e+08, 1.6084e+09, 1.4178e+09],
321 [4.3229e+08, 4.0536e+08, 4.3823e+08, 7.0594e+08, 6.4405e+08],
322 [6.2270e+08, 5.7195e+08, 6.2482e+08, 1.0415e+09, 9.5594e+08]])
323 lumis = array([232.5337, 200.0878, 238.7946, 625.3935, 533.8251])
324 chisqs = array([260.1680, 255.4640, 251.1565, 221.6586, 233.4854])
325 scales = array([3.9450e-22, 4.2714e-22, 3.8880e-22, 2.2365e-22, 2.4783e-22])
326 e_scales = array([1.7789e-22, 1.9005e-22, 1.7449e-22, 1.0679e-22, 1.1745e-22])
327
328 mock_model = self.create_patch(model, 'get_itable_pix', return_value=(syn_flux, lumis))
329 mock_color = self.create_patch(filters, 'is_color', return_value=False)
330 mock_stat = self.create_patch(fit, 'stat_chi2', return_value=(chisqs,scales,e_scales))
331
332 chisqs_,scales_,e_scales_,lumis_ = fit.igrid_search_pix(meas, emeas, photbands, model_func=model.get_itable_pix, stat_func=fit.stat_chi2, **grid)
333
334 self.assertListEqual(chisqs.tolist(), chisqs_.tolist())
335 self.assertListEqual(scales_.tolist(), scales.tolist())
336 self.assertListEqual(e_scales_.tolist(), e_scales.tolist())
337 self.assertListEqual(lumis_.tolist(), lumis.tolist())
338
339 self.assert_mock_args_in_last_call(mock_model, kwargs=grid)
340 self.assert_mock_args_in_last_call(mock_model, kwargs={'photbands':photbands})
341
342 mock_stat.assert_called()
343
345 """ fit.create_parameter_dict() """
346
347 pars = dict(teff_value=5000, teff_min=4000, teff_max=6000,
348 logg_value=4.5, logg_min=3.5, logg_max=5.5,
349 ebv_value=0.001, ebv_min=0.0, ebv_max=0.01, ebv_vary=False,
350 z_value=0, z_vary=False,
351 rad_expr='G*sqrt(2*logg)/m')
352
353 parameters = fit.create_parameter_dict(**pars)
354
355 self.assertTrue('value' in parameters)
356 self.assertTrue('min' in parameters)
357 self.assertTrue('max' in parameters)
358 self.assertTrue('vary' in parameters)
359 self.assertTrue('expr' in parameters)
360
361 names = parameters['names']
362 self.assertTrue('teff' in names)
363 self.assertTrue('logg' in names)
364 self.assertTrue('ebv' in names)
365 self.assertTrue('z' in names)
366 self.assertTrue('rad' in names)
367
368 for key in parameters.keys():
369 self.assertTrue(type(parameters[key]) == np.ndarray)
370
371 self.assertEqual(parameters['value'][names == 'teff'], 5000)
372 self.assertEqual(parameters['value'][names == 'logg'], 4.5)
373 self.assertEqual(parameters['value'][names == 'ebv'], 0.001)
374 self.assertEqual(parameters['value'][names == 'z'], 0)
375 self.assertEqual(parameters['min'][names == 'teff'], 4000)
376 self.assertEqual(parameters['min'][names == 'logg'], 3.5)
377 self.assertEqual(parameters['min'][names == 'ebv'], 0.0)
378 self.assertEqual(parameters['max'][names == 'teff'], 6000)
379 self.assertEqual(parameters['max'][names == 'logg'], 5.5)
380 self.assertEqual(parameters['max'][names == 'ebv'], 0.01)
381 self.assertEqual(parameters['vary'][names == 'ebv'], False)
382 self.assertEqual(parameters['expr'][names == 'rad'], 'G*sqrt(2*logg)/m')
383
388
390 """ fit.create_parameter_dict() """
391 pars = {'logg_value': 4.0, 'vrad_vary': False, 'z_value': -0.3, 'vrad_value': 0,
392 'logg_vary': True, 'rv_min': 2.1, 'vrad_min': 0, 'vrad_max': 0, 'z_max': 0.0,
393 'ebv_max': 0.015, 'teff_value': 6000, 'z_vary': True, 'rv_value': 2.4,
394 'teff_vary': True, 'logg_min': 3.5, 'rv_max': 3.1, 'z_min': -0.5,
395 'ebv_min': 0.005, 'teff_min': 5000, 'logg_max': 4.5, 'ebv_value': 0.007,
396 'teff_max': 7000, 'rv_vary': True, 'ebv_vary': True}
397 exp = {'max': array([3.1, 7000, 4.5, 0.015, 0, 0.0], dtype=object),
398 'vary': array([True, True, True, True, False, True], dtype=object),
399 'names': array(['rv', 'teff', 'logg', 'ebv', 'vrad', 'z'], dtype='|S4'),
400 'value': array([2.4, 6000, 4.0, 0.007, 0, -0.3], dtype=object),
401 'min': array([2.1, 5000, 3.5, 0.005, 0, -0.5], dtype=object)}
402
403 res = fit.create_parameter_dict(**pars)
404
405 self.assertArrayEqual(res['max'], exp['max'])
406 self.assertArrayEqual(res['vary'], exp['vary'])
407 self.assertArrayEqual(res['min'], exp['min'])
408 self.assertArrayEqual(res['names'], exp['names'])
409 self.assertArrayEqual(res['value'], exp['value'])
410
411 @unittest.skipIf(noMock, "Mock not installed")
413 """ fit.iminimize() normal mocked """
414
415 gm_return = (['minimizer'], ['startpars'], ['newmodels'], ['chisqrs'])
416 gifm_return = (['chisqr'], ['nfev'], ['scale'], ['labs'], ['grid'])
417 cpd_return = dict(names=['teff'], value=[5000], min=[4000], max=[6000], vary=[True])
418
419 mock_sfit_m = self.create_patch(sigproc.fit, 'minimize', return_value='minimizer')
420 mock_sfit_gm = self.create_patch(sigproc.fit, 'grid_minimize', return_value=gm_return)
421 mock_sfit_sp = self.create_patch(sigproc.fit.Function, 'setup_parameters')
422 mock_fit_gifm = self.create_patch(fit, '_get_info_from_minimizer', return_value=gifm_return)
423 mock_fit_cpd = self.create_patch(fit, 'create_parameter_dict', return_value=cpd_return)
424
425 meas = array([1.25e9, 2.34e8])
426 emeas = array([1.25e7, 2.34e6])
427 photbands = array(['J', 'C'])
428
429
430 grid, chisqr, nfev, scale, lumis = fit.iminimize(meas,emeas,photbands, points=None, epsfcn=0.01 )
431
432 self.assert_mock_args_in_last_call(mock_sfit_sp, kwargs=cpd_return)
433 self.assert_mock_args_in_last_call(mock_sfit_m, args=[photbands, meas], kwargs=dict(epsfcn=0.01, weights=1/emeas))
434 self.assert_mock_args_in_last_call(mock_fit_gifm, args=[['minimizer'], photbands, meas, emeas])
435 self.assertListEqual(grid,['grid'])
436 self.assertListEqual(chisqr,['chisqr'])
437 self.assertListEqual(nfev,['nfev'])
438 self.assertListEqual(scale,['scale'])
439 self.assertListEqual(lumis,['labs'])
440
441 @unittest.skipIf(noMock, "Mock not installed")
443 """ fit.iminimize() grid mocked """
444 gm_return = (['minimizer'], ['startpars'], ['newmodels'], ['chisqrs'])
445 gifm_return = (['chisqr'], ['nfev'], ['scale'], ['labs'], ['grid'])
446 cpd_return = dict(names=['teff'], value=[5000], min=[4000], max=[6000], vary=[True])
447
448 mock_sfit_m = self.create_patch(sigproc.fit, 'minimize', return_value='minimizer')
449 mock_sfit_gm = self.create_patch(sigproc.fit, 'grid_minimize', return_value=gm_return)
450 mock_sfit_sp = self.create_patch(sigproc.fit.Function, 'setup_parameters')
451 mock_fit_gifm = self.create_patch(fit, '_get_info_from_minimizer', return_value=gifm_return)
452 mock_fit_cpd = self.create_patch(fit, 'create_parameter_dict', return_value=cpd_return)
453
454 meas = array([1.25e9, 2.34e8])
455 emeas = array([1.25e7, 2.34e6])
456 photbands = array(['J', 'C'])
457
458
459 grid, chisqr, nfev, scale, lumis = fit.iminimize(meas,emeas,photbands, points=10, epsfcn=0.01 )
460
461 self.assert_mock_args_in_last_call(mock_sfit_sp, kwargs=cpd_return)
462 self.assert_mock_args_in_last_call(mock_sfit_gm, args=[photbands, meas], kwargs=dict(epsfcn=0.01, weights=1/emeas, points=10))
463 self.assert_mock_args_in_last_call(mock_fit_gifm, args=[['minimizer'], photbands, meas, emeas])
464 self.assertListEqual(grid,['grid'])
465 self.assertListEqual(chisqr,['chisqr'])
466 self.assertListEqual(nfev,['nfev'])
467 self.assertListEqual(scale,['scale'])
468 self.assertListEqual(lumis,['labs'])
469
472
473 @classmethod
478
479
484
486 """ builder.sed.__init__() ToDo """
487 self.assertTrue(self.sed.ID == 'TEST')
488
490 """ builder.sed.collect_results() """
491 bgrid = {'teff': array([ 22674., 21774., 22813., 29343., 28170.]),
492 'logg': array([ 5.75, 6.07, 6.03, 6.38, 5.97]),
493 'ebv': array([ 0.0018, 0.0077, 0.0112, 0.0046, 0.0110]),
494 'rv': array([ 2.20, 2.40, 2.60, 2.80, 3.00]),
495 'z': array([0,0,0,0,0])}
496 fgrid = {'chisq': array([1.,3.,2.,0.1,np.nan])}
497
498 self.sed.collect_results(grid=bgrid, fitresults=fgrid, mtype='igrid_search', selfact='chisq')
499 res = self.sed.results['igrid_search']['grid']
500
501 self.assertListEqual(res['chisq'].tolist(), [3.0, 2.0, 1.0, 0.1])
502 self.assertListEqual(res['teff'].tolist(), [21774.,22813.,22674.,29343.])
503 self.assertListEqual(res['logg'].tolist(), [6.07,6.03,5.75,6.38])
504 self.assertListEqual(res['ebv'].tolist(), [0.0077,0.0112,0.0018,0.0046])
505 self.assertListEqual(res['rv'].tolist(), [2.40,2.60,2.20,2.80])
506 self.assertListEqual(res['z'].tolist(), [0,0,0,0])
507 self.assertListEqual(res['ci_raw'].tolist(), [0.,0.,0.,0.])
508 self.assertListEqual(res['ci_red'].tolist(), [0.,0.,0.,0.])
509
511 """ builder.sed.calculateDF() """
512 ranges = {'teffrange': (5000,6000), 'teff2range': (20000,50000), 'loggrange': (4.5,4.5),
513 'logg2range': (4.5,5.5), 'ebvrange': (0.0,0.01), 'ebv2range': (0.0,0.01),
514 'zrange': (-0.5,0.5)}
515
516 df, dfinfo = self.sed.calculateDF(**ranges)
517
518 self.assertEqual(df, 6)
519 self.assertTrue('ebv' in dfinfo)
520 self.assertFalse('ebv2' in dfinfo)
521
522 @unittest.skipIf(noMock, "Mock not installed")
524 """ builder.sed.calculate_statistics()"""
525 dtypes = [('teff','f8'), ('logg','f8'),('ebv','f8'),('rv','f8'),('z','f8'), ('chisq','f8')]
526 grid = [array([ 22674., 21774., 22813., 29343., 28170.]),
527 array([ 5.75, 6.07, 6.03, 6.38, 5.97]),
528 array([ 0.0018, 0.0077, 0.0112, 0.0046, 0.0110]),
529 array([ 2.20, 2.40, 2.60, 2.80, 3.00]),
530 array([0,0,0,0,0]),
531 array([1.,3.,2.,0.1,10.0])]
532 master = np.rec.fromarrays(grid,dtype=dtypes)
533 master = mlab.rec_append_fields(master, 'ci_raw', np.zeros(len(master)))
534 master = mlab.rec_append_fields(master, 'ci_red', np.zeros(len(master)))
535 self.sed.results['igrid_search']['grid'] = master
536 self.sed.master['include'] = [True,True,False,True,True]
537
538 with mock.patch.object(builder.SED, 'calculateDF', return_value=5) as mock_method:
539 self.sed.calculate_statistics(df=5)
540
541 res = self.sed.results['igrid_search']
542 raw = [0.6826894, 0.9167354, 0.8427007, 0.2481703, 0.9984345]
543 red = [0.2481703, 0.4161175, 0.3452791, 0.0796556, 0.6826894]
544
545 self.assertFalse(mock_method.called)
546 self.assertArrayAlmostEqual(res['grid']['ci_raw'].tolist(), raw, places=5)
547 self.assertArrayAlmostEqual(res['grid']['ci_red'].tolist(), red, places=5)
548 self.assertEqual(res['factor'], 10.0)
549
550
552 """ builder.sed.calculate_confidence_intervals() ToDo """
553 pass
554
556 """ builder.sed.generate_ranges() ToDo """
557 pass
558
559
560 @unittest.skipIf(noMock, "Mock not installed")
562 """ builder.sed.igrid_search() mocked """
563
564 ranges = {'teffrange':(20000,30000), 'loggrange':(5.5,6.5)}
565 grid = {'teff': array([ 22674., 21774., 22813., 29343., 28170.]),
566 'logg': array([ 5.75, 6.07, 6.03, 6.38, 5.97])}
567 fitres = [[1.,3.,2.,0.1,10.0],[1.,3.,2.,0.1,10.0],[1.,3.,2.,0.1,10.0],[1.,3.,2.,0.1,10.0]]
568 ci = dict(name=['teff', 'logg'], value=[30000, 5.5], cilow=[29000, 5.0], cihigh=[31000, 6.0])
569
570 mock_sed_gr = self.create_patch(builder.SED, 'generate_ranges', return_value=ranges)
571 mock_fit_ggp = self.create_patch(fit, 'generate_grid_pix', return_value=grid)
572 mock_fit_isp = self.create_patch(fit, 'igrid_search_pix', return_value=fitres)
573 mock_sed_cr = self.create_patch(builder.SED, 'collect_results')
574 mock_sed_cs = self.create_patch(builder.SED, 'calculate_statistics')
575 mock_sed_cci = self.create_patch(builder.SED, 'calculate_confidence_intervals', return_value=ci)
576 mock_sed_sci = self.create_patch(builder.SED, 'store_confidence_intervals')
577 mock_sed_sbm = self.create_patch(builder.SED, 'set_best_model')
578 mock_p2s = self.create_patch(builder, 'photometry2str', return_value='TEST')
579
580 self.sed.master = {'include':0, 0:0, 'cmeas':[0,0], 'e_cmeas':[0,0], 'photband':[0,0]}
581 self.sed.igrid_search(teffrange=(10,20), loggrange=(4.5,4.5), ebvrange=(0,0.1), zrange=(0,0),rvrange=(3.1,3.1),vradrange=(0,0), df=4, set_model=True)
582
583 mock_sed_gr.assert_called_with(teffrange=(10,20), loggrange=(4.5,4.5), ebvrange=(0,0.1), zrange=(0,0),rvrange=(3.1,3.1),vradrange=(0,0))
584 mock_fit_ggp.assert_called()
585 mock_fit_isp.assert_called()
586 mock_sed_cr.assert_called()
587 self.assert_mock_args_in_last_call(mock_sed_cr, kwargs={'grid':grid})
588 mock_sed_cs.assert_called()
589 self.assert_mock_args_in_last_call(mock_sed_cs, kwargs={'df':4})
590 mock_sed_sci.assert_called()
591 self.assert_mock_args_in_last_call(mock_sed_sci, kwargs=ci)
592 mock_sed_cci.assert_called()
593 mock_sed_sbm.assert_called()
594
597
598 photbands = ['STROMGREN.U', 'STROMGREN.B', 'STROMGREN.V', 'STROMGREN.Y',
599 '2MASS.H', '2MASS.J', '2MASS.KS']
600 measHot = None
601 measCold = None
602 measBin = None
603
604 @classmethod
606 if not noMock:
607 sesame.search = mock.Mock(return_value={'plx':(0.0,0.0)})
608 if not noIntegration:
609
610 model.set_defaults(grid='kurucztest')
611 model.copy2scratch(z='*', Rv='*')
612 measCold = model.get_itable_pix(photbands=cls.photbands, teff=array([6000]), \
613 logg=array([4.0]),ebv=array([0.01]), rv=array([2.8]), z=array([-0.25]))[0][:,0]
614
615 np.random.seed(111)
616 cls.measCold = measCold
617
618
619 model.set_defaults(grid='tmaptest')
620 model.copy2scratch(z='*', Rv='*')
621 measHot = model.get_itable_pix(photbands=cls.photbands, teff=array([30000]), \
622 logg=array([5.5]),ebv=array([0.01]), rv=3.1, z=0.0)[0][:,0]
623
624 np.random.seed(111)
625 cls.measHot = measHot
626
627
628 grid1 = dict(grid='kurucztest')
629 grid2 = dict(grid='tmaptest')
630 model.set_defaults_multiple(grid1,grid2)
631 model.clean_scratch(z='*', Rv='*')
632 model.copy2scratch(z='*', Rv='*')
633
634 G, Msol, Rsol = constants.GG_cgs, constants.Msol_cgs, constants.Rsol_cgs
635 masses = [0.85, 0.50]
636 rad = array([np.sqrt(G*masses[0]*Msol/10**4.0)/Rsol])
637 rad2 = array([np.sqrt(G*masses[1]*Msol/10**5.5)/Rsol])
638
639 measBin = model.get_itable_pix(photbands=cls.photbands, teff=array([6000]), \
640 logg=array([4.0]),ebv=array([0.01]), teff2=array([30000]),
641 logg2=array([5.5]), ebv2=array([0.01]), rad=rad,
642 rad2=rad2)[0][:,0]
643
644 np.random.seed(111)
645 cls.measBin = measBin
646 cls.masses = masses
647
648 @unittest.skipIf(noIntegration, "Integration tests are skipped.")
650 """ INTEGRATION igrid_search single star (kurucz)"""
651 sed = builder.SED(ID='TEST', load_fits=False)
652 np.random.seed(111)
653 meas = self.measCold + np.random.uniform(0, 0.01, size=len(self.measCold)) * self.measCold
654 emeas = meas / 100.0
655 units = ['erg/s/cm2/AA' for i in meas]
656 source = ['SYNTH' for i in meas]
657 sed.add_photometry_fromarrays(meas, emeas, units, self.photbands, source)
658
659 model.set_defaults(grid='kurucztest')
660 model.copy2scratch(z='*', Rv='*')
661
662 np.random.seed(111)
663 sed.igrid_search(points=100000,teffrange=(5000, 7000),loggrange=(3.5, 4.5),
664 ebvrange=(0.005, 0.015),zrange=(-0.5,0.0),rvrange=(2.1,3.1),
665 vradrange=(0,0),df=None,CI_limit=0.95,set_model=True)
666
667 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff'], 6000, delta=50)
668 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg'], 3.98, delta=0.1)
669 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv'], 0.011, delta=0.02)
670 self.assertAlmostEqual(sed.results['igrid_search']['CI']['rv'], 2.13, delta=0.5)
671 self.assertAlmostEqual(sed.results['igrid_search']['CI']['z'], -0.28, delta=0.1)
672 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff_l'], 5949, delta=50)
673 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg_l'], 3.62, delta=0.1)
674 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv_l'], 0.005, delta=0.02)
675 self.assertAlmostEqual(sed.results['igrid_search']['CI']['rv_l'], 2.1, delta=0.1)
676 self.assertAlmostEqual(sed.results['igrid_search']['CI']['z_l'], -0.46, delta=0.1)
677 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff_u'], 6060, delta=50)
678 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg_u'], 4.5, delta=0.1)
679 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv_u'], 0.015, delta=0.02)
680 self.assertAlmostEqual(sed.results['igrid_search']['CI']['rv_u'], 3.1, delta=0.1)
681 self.assertAlmostEqual(sed.results['igrid_search']['CI']['z_u'], -0.05, delta=0.1)
682
683
684 self.assertTrue('model' in sed.results['igrid_search'])
685 self.assertTrue('synflux' in sed.results['igrid_search'])
686 self.assertTrue('chi2' in sed.results['igrid_search'])
687 self.assertEqual(len(sed.results['igrid_search']['model']), 3, msg='stored model has wrong number of collumns (should be 3)')
688 self.assertEqual(len(sed.results['igrid_search']['synflux']), 3, msg='stored synflux has wrong number of collumns (should be 3)')
689
690
691 @unittest.skipIf(noIntegration, "Integration tests are skipped.")
693 """ INTEGRATION igrid_search single star (tmap) """
694 sed = builder.SED(ID='TEST', load_fits=False)
695 np.random.seed(111)
696 meas = self.measHot + np.random.uniform(0, 0.04, size=len(self.measHot)) * self.measHot
697 emeas = meas / 100.0
698 units = ['erg/s/cm2/AA' for i in meas]
699 source = ['SYNTH' for i in meas]
700 sed.add_photometry_fromarrays(meas, emeas, units, self.photbands, source)
701
702 model.set_defaults(grid='tmaptest')
703 model.copy2scratch(z='*', Rv='*')
704
705 np.random.seed(111)
706 sed.igrid_search(points=100000,teffrange=(25000, 35000),loggrange=(5.0, 6.0),
707 ebvrange=(0.005, 0.015),zrange=(0,0),rvrange=(3.1,3.1),
708 vradrange=(0,0),df=None,CI_limit=0.95,set_model=True)
709
710 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff'], 30200, delta=250)
711 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg'], 5.67, delta=0.1)
712 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv'], 0.0078, delta=0.02)
713 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff_l'], 29337, delta=250)
714 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg_l'], 5.0, delta=0.1)
715 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv_l'], 0.005, delta=0.02)
716 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff_u'], 31623, delta=250)
717 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg_u'], 6.0, delta=0.1)
718 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv_u'], 0.015, delta=0.02)
719
720
721 self.assertTrue('model' in sed.results['igrid_search'])
722 self.assertTrue('synflux' in sed.results['igrid_search'])
723 self.assertTrue('chi2' in sed.results['igrid_search'])
724 self.assertEqual(len(sed.results['igrid_search']['model']), 3, msg='stored model has wrong number of collumns (should be 3)')
725 self.assertEqual(len(sed.results['igrid_search']['synflux']), 3, msg='stored synflux has wrong number of collumns (should be 3)')
726
727 @unittest.skipIf(noIntegration, "Integration tests are skipped.")
729 """ INTEGRATION igrid_search binary star (kurucz-tmap) """
730 sed = builder.BinarySED(ID='TEST', load_fits=False)
731 np.random.seed(111)
732 meas = self.measBin + np.random.uniform(0, 0.04, size=len(self.measBin)) * self.measBin
733 emeas = meas / 100.0
734 units = ['erg/s/cm2/AA' for i in meas]
735 source = ['SYNTH' for i in meas]
736 sed.add_photometry_fromarrays(meas, emeas, units, self.photbands, source)
737
738 grid1 = dict(grid='kurucztest')
739 grid2 = dict(grid='tmaptest')
740 model.set_defaults_multiple(grid1,grid2)
741
742 np.random.seed(111)
743 sed.igrid_search(points=100000,teffrange=[(5000, 7000),(25000, 35000)],
744 loggrange=[(3.5, 4.5),(5.0, 6.0)],
745 ebvrange=[(0.005, 0.015), (0.005, 0.015)],
746 zrange=[(0,0),(0,0)],
747 radrange=[(0,10),(0,10)],
748 masses=self.masses,
749 df=None,CI_limit=0.95,set_model=False)
750
751 teff = sed.results['igrid_search']['CI']['teff']
752 logg = sed.results['igrid_search']['CI']['logg']
753 ebv = sed.results['igrid_search']['CI']['ebv']
754 teff2 = sed.results['igrid_search']['CI']['teff2']
755 logg2 = sed.results['igrid_search']['CI']['logg2']
756 ebv2 = sed.results['igrid_search']['CI']['ebv2']
757
758 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff'], 6134, delta=50)
759 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg'], 4.38, delta=0.25)
760 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv'], 0.008, delta=0.002)
761 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff_l'], 5826, delta=50)
762 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg_l'], 4.35, delta=0.1)
763 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv_l'], 0.005, delta=0.002)
764 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff_u'], 6291, delta=50)
765 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg_u'], 4.40, delta=0.1)
766 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv_u'], 0.015, delta=0.002)
767 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff2'], 32195, delta=250)
768 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg2'], 5.97, delta=0.25)
769 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv2'], 0.008, delta=0.002)
770 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff2_l'], 26820, delta=250)
771 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg2_l'], 5.70, delta=0.1)
772 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv2_l'], 0.005, delta=0.002)
773 self.assertAlmostEqual(sed.results['igrid_search']['CI']['teff2_u'], 33025, delta=250)
774 self.assertAlmostEqual(sed.results['igrid_search']['CI']['logg2_u'], 5.99, delta=0.1)
775 self.assertAlmostEqual(sed.results['igrid_search']['CI']['ebv2_u'], 0.015, delta=0.002)
776
777 @unittest.skipIf(noIntegration, "Integration tests are skipped.")
779 """ INTEGRATION iminimize single star (kurucz) """
780 sed = builder.SED(ID='TEST', load_fits=False)
781 np.random.seed(111)
782 meas = self.measCold + np.random.uniform(0, 0.04, size=len(self.measCold)) * self.measCold
783 emeas = meas / 100.0
784 units = ['erg/s/cm2/AA' for i in meas]
785 source = ['SYNTH' for i in meas]
786 sed.add_photometry_fromarrays(meas, emeas, units, self.photbands, source)
787
788 model.set_defaults(grid='kurucztest')
789 model.copy2scratch(z='*', Rv='*')
790
791 np.random.seed(111)
792 sed.iminimize(teff=6000, logg=4.0, ebv=0.007, z=-0.3, rv=2.4, vrad=0,
793 teffrange=(5000, 7000),loggrange=(3.5, 4.5),zrange=(-0.5,0.0),
794 ebvrange=(0.005, 0.015), rvrange=(2.1,3.1),vradrange=(0,0),
795 points=None,df=None,CI_limit=0.60,calc_ci=True, set_model=True)
796
797 self.assertAlmostEqual(sed.results['iminimize']['CI']['teff'], 6036, delta=50)
798 self.assertAlmostEqual(sed.results['iminimize']['CI']['logg'], 4.19, delta=0.1)
799 self.assertAlmostEqual(sed.results['iminimize']['CI']['ebv'], 0.015, delta=0.02)
800 self.assertAlmostEqual(sed.results['iminimize']['CI']['z'], -0.21, delta=0.1)
801 self.assertAlmostEqual(sed.results['iminimize']['CI']['rv'], 2.1, delta=0.3)
802 self.assertAlmostEqual(sed.results['iminimize']['CI']['scale'], 1, delta=0.5)
803
804 self.assertAlmostEqual(sed.results['iminimize']['CI']['teff_l'], 6025, delta=50)
805 self.assertAlmostEqual(sed.results['iminimize']['CI']['teff_u'], 6036, delta=50)
806 self.assertAlmostEqual(sed.results['iminimize']['CI']['scale_l'], 1, delta=0.5)
807 self.assertAlmostEqual(sed.results['iminimize']['CI']['scale_u'], 1, delta=0.5)
808
809 self.assertEqual(sed.results['iminimize']['grid']['teffstart'][0], 6000)
810 self.assertEqual(sed.results['iminimize']['grid']['loggstart'][0], 4.0)
811 self.assertEqual(sed.results['iminimize']['grid']['ebvstart'][0], 0.007)
812 self.assertEqual(sed.results['iminimize']['grid']['zstart'][0], -0.3)
813 self.assertEqual(sed.results['iminimize']['grid']['rvstart'][0], 2.4)
814 self.assertAlmostEqual(sed.results['iminimize']['grid']['chisq'][0], 3.9, delta=1)
815
816 self.assertTrue('model' in sed.results['iminimize'])
817 self.assertTrue('synflux' in sed.results['iminimize'])
818 self.assertTrue('chi2' in sed.results['iminimize'])
819 self.assertEqual(len(sed.results['iminimize']['model']), 3, msg='stored model has wrong number of collumns (should be 3)')
820 self.assertEqual(len(sed.results['iminimize']['synflux']), 3, msg='stored synflux has wrong number of collumns (should be 3)')
821
822
823 @unittest.skipIf(noIntegration, "Integration tests are skipped.")
825 """ INTEGRATION iminimize single star (tmap) """
826 sed = builder.SED(ID='TEST', load_fits=False)
827 np.random.seed(111)
828 meas = self.measHot + np.random.uniform(0, 0.04, size=len(self.measHot)) * self.measHot
829 emeas = meas / 100.0
830 units = ['erg/s/cm2/AA' for i in meas]
831 source = ['SYNTH' for i in meas]
832 sed.add_photometry_fromarrays(meas, emeas, units, self.photbands, source)
833
834 model.set_defaults(grid='tmaptest')
835 model.copy2scratch(z='*', Rv='*')
836
837 np.random.seed(111)
838 sed.iminimize(teff=27000, logg=5.1, ebv=0.01, z=0, rv=3.1, vrad=0,
839 teffrange=(25000, 35000),loggrange=(5.0, 6.0),
840 ebvrange=(0.005, 0.015),zrange=(0,0),rvrange=(3.1,3.1),
841 vradrange=(0,0),df=None,CI_limit=0.95,set_model=False)
842
843 self.assertAlmostEqual(sed.results['iminimize']['CI']['teff'], 30250, delta=100)
844 self.assertAlmostEqual(sed.results['iminimize']['CI']['logg'], 5.66, delta=0.1)
845 self.assertAlmostEqual(sed.results['iminimize']['CI']['ebv'], 0.008, delta=0.02)
846 self.assertAlmostEqual(sed.results['iminimize']['grid']['chisq'][0], 3.8, delta=1)
847
848
849 @unittest.skipIf(noIntegration, "Integration tests are skipped.")
851 """ INTEGRATION iminimize binary star (kurucz-tmap) """
852 sed = builder.BinarySED(ID='TEST', load_fits=False)
853 np.random.seed(111)
854 meas = self.measBin + np.random.uniform(0, 0.01, size=len(self.measBin)) * self.measBin
855 emeas = meas / 100.0
856 units = ['erg/s/cm2/AA' for i in meas]
857 source = ['SYNTH' for i in meas]
858 sed.add_photometry_fromarrays(meas, emeas, units, self.photbands, source)
859 sed.set_photometry_scheme('abs')
860
861 np.random.seed(111)
862 sed.iminimize(teff=(5300,29000), logg=(4.0,5.3), ebv=(0.01,0.01), z=(0,0), rv=(3.1,3.1),
863 vrad=(0,0),teffrange=[(5000,7000),(25000, 35000)],loggrange=[(3.5,4.5),
864 (5.0, 6.0)], ebvrange=[(0.01,0.01),(0.01, 0.01)] ,zrange=[(0,0),(0,0)],
865 rvrange=[(3.1,3.1),(3.1,3.1)], vradrange=[(0,0),(0,0)], df=2,
866 CI_limit=None, masses = self.masses,calc_ci=False, set_model=True)
867
868 self.assertAlmostEqual(sed.results['iminimize']['CI']['teff'], 6023, delta=100)
869 self.assertAlmostEqual(sed.results['iminimize']['CI']['logg'], 3.95, delta=0.1)
870 self.assertAlmostEqual(sed.results['iminimize']['CI']['ebv'], 0.01, delta=0.02)
871 self.assertAlmostEqual(sed.results['iminimize']['CI']['teff2'], 30506, delta=100)
872 self.assertAlmostEqual(sed.results['iminimize']['CI']['logg2'], 5.47, delta=0.1)
873 self.assertAlmostEqual(sed.results['iminimize']['CI']['scale'], 0.9, delta=0.5)
874
875 self.assertTrue('model' in sed.results['iminimize'])
876 self.assertTrue('synflux' in sed.results['iminimize'])
877 self.assertTrue('chi2' in sed.results['iminimize'])
878 self.assertEqual(len(sed.results['iminimize']['model']), 3, msg='stored model has wrong number of collumns (should be 3)')
879 self.assertEqual(len(sed.results['iminimize']['synflux']), 3, msg='stored synflux has wrong number of collumns (should be 3)')
880