def test_two_files_one_dbtype(capfd): pb.run('configs/tli_hitran_two_files_one_dbtype.cfg') captured = capfd.readouterr() caps = [ "Read command-line arguments from configuration file:", "'configs/tli_hitran_two_files_one_dbtype.cfg'", "Reading input database files:", "tests/inputs/01_hit12.par", "tests/inputs/02_4000-4500_HITEMP2010.par", "There are 2 input database file(s).", "Initial TLI wavelength (um): 2.300 ( 4347.826 cm-1)", "Final TLI wavelength (um): 2.400 ( 4166.667 cm-1)", "Database (1/2): 'HITRAN H2O' (H2O molecule)", "Number of temperatures: 503", "Number of isotopes: 9", "Database (2/2): 'HITRAN CO2' (CO2 molecule)", "Number of isotopes: 13", "Cumulative number of isotopes per database: [0, 9, 22]", "Process HITRAN H2O database between records 60,574 and 61,991.", "Process HITRAN CO2 database between records 20,424 and 41,477.", "[ 610 233 163 411 20937 17 27 73]", "Writing 22,471 transition lines.", "/HITRAN_H2O_CO2_2.3-2.4um_test.tli'.", ] for cap in caps: assert cap in captured.out
def test_two_files_two_databases(capfd): pb.run('configs/tli_hitran_two_files_two_db_test.cfg') captured = capfd.readouterr() caps = [ "Read command-line arguments from configuration file:", "'configs/tli_hitran_two_files_two_db_test.cfg'", "Reading input database files:", "tests/inputs/01_hit12.par", "tests/inputs/02_4000-4500_HITEMP2010.par", "There are 2 input database file(s).", "Initial TLI wavelength (um): 2.000 ( 5000.000 cm-1)", "Final TLI wavelength (um): 3.000 ( 3333.333 cm-1)", "Database (1/2): 'HITRAN H2O' (H2O molecule)", "Number of temperatures: 503", "Number of isotopes: 9", "Database (2/2): 'HITRAN CO2' (CO2 molecule)", "Number of isotopes: 13", "Cumulative number of isotopes per database: [0, 9, 22]", "Process HITRAN H2O database between records 42,645 and 66,776.", "Process HITRAN CO2 database between records 0 and 138,257.", "[12296 5132 3973 2568 147 99541 9119 22521 220 6854 2]", "Writing 162,373 transition lines.", "/HITRAN_H2O_CO2_2.0-3.0um_test.tli'.", ] for cap in caps: assert cap in captured.out
def test_pyrat_emission_str(tmp_path): cfg = make_config(tmp_path, ROOT + 'tests/configs/spectrum_transmission_test.cfg', reset={'rt_path': 'emission'}) pyrat = pb.run(cfg) assert pyrat is not None assert str(pyrat.spec) == """\ Spectral information: Wavenumber internal units: cm-1 Wavelength internal units: cm Wavelength display units (wlunits): um Low wavenumber boundary (wnlow): 5882.353 cm-1 (wlhigh = 1.70 um) High wavenumber boundary (wnhigh): 9090.909 cm-1 (wllow = 1.10 um) Number of samples (nwave): 3209 Sampling interval (wnstep): 1.000 cm-1 Wavenumber array (wn, cm-1): [ 5882.353 5883.353 5884.353 ... 9088.353 9089.353 9090.353] Oversampling factor (wnosamp): 2160 Intensity zenithal angles (raygrid, degree): [ 0. 20. 40. 60. 80.] raygrid internal units: radian Intensity spectra (intensity, erg s-1 cm-2 sr-1 cm): [ 7.741e+02 7.734e+02 7.727e+02 ... 3.549e+01 3.545e+01 3.542e+01] [ 7.741e+02 7.734e+02 7.727e+02 ... 3.549e+01 3.545e+01 3.542e+01] [ 7.741e+02 7.734e+02 7.727e+02 ... 3.549e+01 3.545e+01 3.542e+01] [ 7.741e+02 7.734e+02 7.727e+02 ... 3.549e+01 3.545e+01 3.542e+01] [ 7.741e+02 7.734e+02 7.727e+02 ... 3.549e+01 3.545e+01 3.542e+01] Emission spectrum (spectrum, erg s-1 cm-2 cm): [ 2.432e+03 2.430e+03 2.428e+03 ... 1.115e+02 1.114e+02 1.113e+02] """ assert str(pyrat.od) == """\
def spectrum_exomol(): pyrat = pb.run(ROOT + 'tests/configs/spectrum_transmission_exomol.cfg') plt.figure(1) plt.clf() plt.plot(1e4 / hcn[0], hcn[1], 'b') plt.plot(1e4 / pyrat.spec.wn, pyrat.spec.spectrum, 'orange', alpha=0.5)
def test_missing_mass_units(tmp_path, capfd): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_tcea.cfg', reset={'mplanet':'1.0'}) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Invalid units 'None' for parameter mplanet." in captured.out
def test_transmission_patchy(tmp_path): cfg = make_config(tmp_path, ROOT + 'tests/configs/spectrum_transmission_test.cfg', reset={ 'fpatchy': '0.5', 'rpars': '10.0 -15.0' }) pyrat = pb.run(cfg) np.testing.assert_allclose(pyrat.spec.spectrum, expected['patchy'], rtol=rtol) np.testing.assert_allclose(pyrat.spec.clear, expected['patchy_clear'], rtol=rtol) np.testing.assert_allclose(pyrat.spec.cloudy, expected['patchy_cloudy'], rtol=rtol) pyrat.cloud.fpatchy = 0.0 pyrat.run() np.testing.assert_allclose(pyrat.spec.spectrum, expected['patchy_clear'], rtol=rtol) pyrat.cloud.fpatchy = 1.0 pyrat.run() np.testing.assert_allclose(pyrat.spec.spectrum, expected['patchy_cloudy'], rtol=rtol)
def test_units_separate(tmp_path): cfg = make_config(tmp_path, ROOT + 'tests/configs/pt_isothermal.cfg', reset={ 'mplanet': '1.0', 'mpunits': 'mjup' }) pressure, temperature, abundances, species, radius = pb.run(cfg)
def test_invalid_file_path(tmp_path, capfd, param, invalid_path): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_isothermal.cfg', reset={param:'nope/file.dat'}) pyrat = pb.run(cfg) captured = capfd.readouterr() assert pyrat is None assert "Error in module: 'parser.py', function: 'parse'" in captured.out assert invalid_path[param] in captured.out
def test_transmission_deck(tmp_path): cfg = make_config(tmp_path, ROOT + 'tests/configs/spectrum_transmission_test.cfg', remove=['tlifile', 'csfile', 'rayleigh', 'alkali']) pyrat = pb.run(cfg) np.testing.assert_allclose(pyrat.spec.spectrum, expected['deck'], rtol=rtol)
def test_lower_equal(tmp_path, capfd, param): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_isothermal.cfg', reset={param:'1.1'}) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'parser.py', function: 'parse'" in captured.out assert "({:s}) must be <= ".format(param) in captured.out
def test_greater_than(tmp_path, capfd, param, value): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_tcea.cfg', reset={param:value}) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'parser.py', function: 'parse'" in captured.out assert "({:s}) must be > ".format(param) in captured.out
def main(): cfile = 'run_HATP-41b_tsiaras/mcmc_HATP-41b_tsiaras_w00000-mc.cfg' folder, cfile = os.path.split(cfile) _, planet, dset = folder.split('_') with pt.cd(folder): pyrat = pb.run(cfile, run_step='init', no_logfile=True) with np.load(pyrat.ret.mcmcfile) as mcmc: post, zchain, zmask = mc3.utils.burn(mcmc) texnames = mcmc['texnames'] bestp = mcmc['bestp'] imol = np.in1d(mcmc['ifree'], pyrat.ret.imol) posteriors = pyrat.ret.posterior = post u, uind, uinv = np.unique(posteriors[:, 0], return_index=True, return_inverse=True) nunique = np.size(u) # Get mean molecular mass: ZX_ratio = np.zeros(nunique, np.double) params = pyrat.ret.params for k in range(nunique): params[imol] = posteriors[uind[k], imol] ZX_ratio[k] = ZX(params, pyrat) iN2 = pyrat.ret.pnames.index('log(N2)') # Metal mass fraction relative to solar values, i.e., [Z/X]: posteriors[:, iN2] = ZX_ratio[uinv] bestp[iN2] = ZX(bestp, pyrat) texnames[iN2] = r"$[Z/X]$" posteriors = roll(posteriors, indices=pyrat.ret.imol[:-1]) bestp = roll(bestp, indices=pyrat.ret.imol[:-1]) texnames = roll(texnames, indices=pyrat.ret.imol[:-1]) texnames[4] = texnames[4].replace('f', 'X') rect = [0.105, 0.11, 0.99, 0.99] ranges = [(100, 3000), (1.49, 1.68), (-4.5, 2.6), (-5.5, 2.5), (-7., -0.45)] plt.figure(316, (6, 6)) plt.clf() axes, cax = mc3.plots.pairwise(posteriors, pnames=texnames, ranges=ranges, fignum=8, rect=rect, nbins=20) ax = axes[1][2] plt.text(0.15, 0.125, 'cloudy', rotation=45, transform=ax.transAxes) plt.text(0.70, 0.25, 'heavy', rotation=45, transform=ax.transAxes) plt.text(0.75, 0.67, 'deplet', rotation=90, transform=ax.transAxes) ax = axes[3][3] plt.text(0.05, 0.30, 'cloudy', rotation=305, transform=ax.transAxes) plt.text(0.55, 0.75, 'heavy', rotation=0, transform=ax.transAxes) plt.text(0.65, 0.10, 'deplet', rotation=0, transform=ax.transAxes) plt.savefig(f'plots/WFC3_{planet}_{dset}_correlation.pdf') plt.savefig(f'plots/WFC3_{planet}_{dset}_correlation.png', dpi=300)
def test_atmosphere_tea_missing_elements(tmp_path, capfd, undefined): cfg = make_config(tmp_path, ROOT+'tests/configs/atmosphere_tea_test.cfg', remove=['elements']) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'driver.py', function: 'check_atm'" in captured.out assert undefined['elements'] in captured.out
def test_atmosphere_missing_species(tmp_path, capfd, undefined, chem): cfg = make_config(tmp_path, f'{ROOT}tests/configs/atmosphere_{chem}_test.cfg', remove=['species']) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'driver.py', function: 'check_atm'" in captured.out assert undefined['species'] in captured.out
def test_pt_temperature_missing(tmp_path, capfd, param, undefined): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_isothermal.cfg', remove=[param]) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'driver.py', function: 'check_temp'" \ in captured.out assert undefined[param] in captured.out
def test_pressure_invalid_units(tmp_path, capfd, param): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_isothermal.cfg', reset={param:'10.0 20.0'}) pyrat = pb.run(cfg) captured = capfd.readouterr() assert pyrat is None assert "Error in module: 'parser.py', function: 'parse'" in captured.out assert f"Invalid units for value '10.0 20.0' for parameter {param}." \ in captured.out
def test_transmission_input_radius(tmp_path): cfg = make_config( tmp_path, ROOT + 'tests/configs/spectrum_transmission_test.cfg', reset={'atmfile': f'{INPUTS}atmosphere_uniform_radius.atm'}, remove=['radmodel']) pyrat = pb.run(cfg) atm = io.read_atm('inputs/atmosphere_uniform_radius.atm') np.testing.assert_allclose(pyrat.atm.radius, atm[5] * pc.km, rtol=rtol)
def test_bulk_molfree_overlap(tmp_path, capfd): cfg = make_config(tmp_path, ROOT+'tests/configs/spectrum_transmission_test.cfg', reset={'molmodel':'vert', 'molfree':'H2', 'bulk':'H2'}) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'argum.py', function: 'setup'" in captured.out assert "These species were marked as both bulk and variable-abundance: ['H2']." in captured.out
def test_units_in_value_invalid(tmp_path, capfd): cfg = make_config(tmp_path, ROOT + 'tests/configs/pt_isothermal.cfg', reset={'mplanet': '1.0 nope'}) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Invalid units for value '1.0 nope' for parameter mplanet." \ in captured.out
def test_spectrum_emission(tmp_path): cfg = make_config(tmp_path, ROOT + 'tests/configs/spectrum_transmission_test.cfg', reset={ 'rt_path': 'emission', 'cpars': '-0.5' }) pyrat = pb.run(cfg) assert pyrat is not None
def test_invalid_float_all_params(tmp_path, capfd, param): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_isothermal.cfg', reset={param:'abc'}) pyrat = pb.run(cfg) captured = capfd.readouterr() assert pyrat is None assert "Error in module: 'parser.py', function: 'parse'" in captured.out assert ("Invalid data type for {:s}, could not convert string to " "float: 'abc'".format(param)) in captured.out
def test_transmission_clear(tmp_path): # No opacity whatsoever: cfg = make_config( tmp_path, ROOT + 'tests/configs/spectrum_transmission_test.cfg', remove=['tlifile', 'csfile', 'rayleigh', 'alkali', 'clouds']) pyrat = pb.run(cfg) depth_bottom = (pyrat.atm.radius[-1] / pyrat.phy.rstar)**2 np.testing.assert_allclose(pyrat.spec.spectrum, depth_bottom, rtol=rtol)
def test_transmission_input_radius_overwrite(tmp_path): cfg = make_config( tmp_path, ROOT + 'tests/configs/spectrum_transmission_test.cfg', reset={'atmfile': f'{INPUTS}/atmosphere_uniform_radius.atm'}) pyrat = pb.run(cfg) atm = io.read_atm('inputs/atmosphere_uniform_radius.atm') np.testing.assert_raises(AssertionError, np.testing.assert_array_equal, pyrat.atm.radius, atm[5] * pc.km)
def test_molfree_mismatch(tmp_path, capfd): cfg = make_config(tmp_path, ROOT+'tests/configs/spectrum_transmission_test.cfg', reset={'molmodel':'vert'}) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'argum.py', function: 'setup'" in captured.out assert "molmodel is set, but there are no molfree." in captured.out
def test_molfree_mismatch3(tmp_path, capfd): cfg = make_config(tmp_path, ROOT+'tests/configs/spectrum_transmission_test.cfg', reset={'molmodel':'vert', 'molfree':'N2'}) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'argum.py', function: 'setup'" in captured.out assert "These species are not present in the atmosphere: ['N2']." in captured.out
def test_pressure_invalid_type(tmp_path, capfd, param, value): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_isothermal.cfg', reset={param:value}) pyrat = pb.run(cfg) captured = capfd.readouterr() assert pyrat is None assert "Error in module: 'parser.py', function: 'parse'" in captured.out assert "Invalid value '{:s}' for parameter {:s}.". \ format(value, param) in captured.out
def test_transmission_resolution(tmp_path): cfg = make_config(tmp_path, ROOT + 'tests/configs/spectrum_transmission_test.cfg', reset={'resolution': '5000.0'}, remove=['clouds']) pyrat = pb.run(cfg) np.testing.assert_allclose(pyrat.spec.spectrum, expected['resolution'], rtol=rtol)
def test_invalid_units(tmp_path, capfd, param, var): cfg = make_config(tmp_path, ROOT+'tests/configs/pt_isothermal.cfg', reset={param:'invalid'}) pyrat = pb.run(cfg) captured = capfd.readouterr() assert pyrat is None assert "Error in module: 'parser.py', function: 'parse'" in captured.out assert "Invalid {:s} units ({:s}): invalid".format(var, param) \ in captured.out
def test_opacity_missing(tmp_path, capfd, param, undefined_opacity): cfg = make_config(tmp_path, ROOT+'tests/configs/opacity_test.cfg', reset={'extfile':str(tmp_path/'new_opacity.dat')}, remove=[param]) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'argum.py', function: 'check_spectrum'" \ in captured.out assert undefined_opacity[param] in captured.out
def test_kurucz_missing_pars(tmp_path, capfd, param, undefined): cfg = make_config(tmp_path, ROOT+'tests/configs/spectrum_transmission_test.cfg', reset={'kurucz':f'{ROOT}/tests/inputs/fp00k0odfnew.pck'}, remove=[param]) pyrat = pb.run(cfg) assert pyrat is None captured = capfd.readouterr() assert "Error in module: 'argum.py', function: 'setup'" in captured.out assert undefined[param] in captured.out