diff --git a/docs/examples/abundancecust.rst b/docs/examples/abundancecust.rst index 5ab6273816b..12d6c5769a9 100644 --- a/docs/examples/abundancecust.rst +++ b/docs/examples/abundancecust.rst @@ -66,6 +66,11 @@ work on a mesh with ten cells should be formatted like this: .. literalinclude:: tardis_model_abund.csv +.. note:: + + The file should always contain the cell index as a running index in the + first column. + .. danger:: The header line for the isotopic abundance structure can under no @@ -75,6 +80,7 @@ In this file: - Header row contains element and isotopes symbol - the remaining entries in each row give the set of elemental and isotopic abundances. +- the first column contains a running index The abundances are specified as mass fractions (i.e. the sum of columns in each row should be 1.0). The mass fractions specified will be adopted directly in diff --git a/docs/examples/tardis_model_abund.csv b/docs/examples/tardis_model_abund.csv index 46200ee5b77..96a7b973be0 100644 --- a/docs/examples/tardis_model_abund.csv +++ b/docs/examples/tardis_model_abund.csv @@ -1,11 +1,11 @@ -C O Mg Si Ni56 Ni58 -0 0 0 0.6 0.4 0 -0 0 0 0.1 0.5 0.4 -0 0 0 0.3 0 0.7 -0 0.2 0.8 0 0 0 -0 0.3 0.7 0 0 0 -0 0.2 0.8 0 0 0 -0 0.2 0.8 0 0 0 -0 0.2 0.8 0 0 0 -0.5 0.5 0 0 0 0 -0.5 0.5 0 0 0 0 +Index C O Mg Si Ni56 Ni58 +0 0 0 0 0.6 0.4 0 +1 0 0 0 0.1 0.5 0.4 +2 0 0 0 0.3 0 0.7 +3 0 0.2 0.8 0 0 0 +4 0 0.3 0.7 0 0 0 +5 0 0.2 0.8 0 0 0 +6 0 0.2 0.8 0 0 0 +7 0 0.2 0.8 0 0 0 +8 0.5 0.5 0 0 0 0 +9 0.5 0.5 0 0 0 0 diff --git a/tardis/io/model_reader.py b/tardis/io/model_reader.py index bfc6d62c00c..b18d27535a9 100644 --- a/tardis/io/model_reader.py +++ b/tardis/io/model_reader.py @@ -251,10 +251,14 @@ def read_cmfgen_density(fname): Reading a density file of the following structure (example; lines starting with a hash will be ignored): The first density describes the mean density in the center of the model and is not used. The file consists of a header row and next row contains unit of the respective attributes - velocity densities electron_densities temperature - km/s g/cm^3 /cm^3 K - 871.66905 4.2537191e-09 2.5953807e+14 7.6395577 - 877.44269 4.2537191e-09 2.5953807e+14 7.6395577 + Note that the first column has to contain a running index + + Example: + + index velocity densities electron_densities temperature + - km/s g/cm^3 /cm^3 K + 0 871.66905 4.2537191e-09 2.5953807e+14 7.6395577 + 1 877.44269 4.2537191e-09 2.5953807e+14 7.6395577 Rest columns contain abundances of elements and isotopes @@ -290,11 +294,11 @@ def read_cmfgen_density(fname): elif row_index == 2: quantities = line.split() - velocity = u.Quantity(df['velocity'].values, quantities[0]).to('cm/s') - temperature = u.Quantity(df['temperature'].values, quantities[1])[1:] - mean_density = u.Quantity(df['densities'].values, quantities[2])[1:] + velocity = u.Quantity(df['velocity'].values, quantities[1]).to('cm/s') + temperature = u.Quantity(df['temperature'].values, quantities[2])[1:] + mean_density = u.Quantity(df['densities'].values, quantities[3])[1:] electron_densities = u.Quantity( - df['electron_densities'].values, quantities[3])[1:] + df['electron_densities'].values, quantities[4])[1:] return time_of_model, velocity, mean_density, electron_densities, temperature @@ -345,7 +349,8 @@ def read_cmfgen_composition(fname, delimiter='\s+'): DeprecationWarning) return read_csv_isotope_abundances(fname, delimiter=delimiter, - skip_columns=4, skip_rows=[0, 2]) + skip_columns=4, skip_rows=[0, 2, 3]) + def read_csv_composition(fname, delimiter='\s+'): """Read composition from a simple CSV file @@ -372,10 +377,14 @@ def read_csv_isotope_abundances(fname, delimiter='\s+', skip_columns=0, """ A generic parser for a TARDIS composition stored as a CSV file - The parser can read in both elemental and isotopic abundances. It also - allows for additional information to be stored in the first skip_columns - columns. These will be ignored if skip_columns > 0. Specific header lines - can be skipped by the skip_rows keyword argument + The parser can read in both elemental and isotopic abundances. The first + column is always expected to contain a running index, labelling the grid + cells. The parser also allows for additional information to be stored in + the first skip_columns columns. These will be ignored if skip_columns > 0. + Note that the first column, containing the cell index is not taken into + account here. + + Specific header lines can be skipped by the skip_rows keyword argument It is expected that the first row of the date block (after skipping the rows specified in skip_rows) specifies the different elements and isotopes. @@ -383,10 +392,11 @@ def read_csv_isotope_abundances(fname, delimiter='\s+', skip_columns=0, The first composition row describes the composition of the photosphere and is essentially ignored (for the default value of skip_rows). - Example - C O Ni56 - 1 1 1 - 0.4 0.3 0.2 + Example: + + Index C O Ni56 + 0 1 1 1 + 1 0.4 0.3 0.2 Parameters ---------- @@ -401,29 +411,30 @@ def read_csv_isotope_abundances(fname, delimiter='\s+', skip_columns=0, abundances: ~pandas.DataFrame isotope_abundance: ~pandas.MultiIndex """ + df = pd.read_csv(fname, comment='#', - delimiter=delimiter, skiprows=skip_rows) + sep=delimiter, skiprows=skip_rows, index_col=0) df = df.transpose() - abundance = pd.DataFrame(columns=np.arange(df.shape[1] - 1), + abundance = pd.DataFrame(columns=np.arange(df.shape[1]), index=pd.Index([], name='atomic_number'), dtype=np.float64) isotope_index = pd.MultiIndex( [[]] * 2, [[]] * 2, names=['atomic_number', 'mass_number']) - isotope_abundance = pd.DataFrame(columns=np.arange(df.shape[1] - 1), + isotope_abundance = pd.DataFrame(columns=np.arange(df.shape[1]), index=isotope_index, dtype=np.float64) for element_symbol_string in df.index[skip_columns:]: if element_symbol_string in nucname.name_zz: z = nucname.name_zz[element_symbol_string] - abundance.loc[z, :] = df.loc[element_symbol_string].tolist()[1:] + abundance.loc[z, :] = df.loc[element_symbol_string].tolist() else: z = nucname.znum(element_symbol_string) mass_no = nucname.anum(element_symbol_string) isotope_abundance.loc[( - z, mass_no), :] = df.loc[element_symbol_string].tolist()[1:] + z, mass_no), :] = df.loc[element_symbol_string].tolist() return abundance.index, abundance, isotope_abundance diff --git a/tardis/io/tests/data/cmfgen_model.csv b/tardis/io/tests/data/cmfgen_model.csv index 4e7dffee474..517f5f7ace7 100644 --- a/tardis/io/tests/data/cmfgen_model.csv +++ b/tardis/io/tests/data/cmfgen_model.csv @@ -1,13 +1,13 @@ t0: 0.976 day -velocity temperature densities electron_densities C O Mg Si Ni56 Ni58 -km/s K g/cm^3 /cm^3 1 1 1 1 1 1 -871.66905 76395.577 4.2537191E-09 2.60E+14 0 0 0 0.6 0.4 0 -877.44269 76395.577 4.2537191E-09 2.60E+14 0 0 0 0.1 0.5 0.4 -894.99407 76395.631 4.2537191E-09 2.60E+14 0 0 0 0.3 0 0.7 -931.1571 76396.057 4.2537191E-09 2.60E+14 0 0.2 0.8 0 0 0 -990.30752 76399.042 4.2537271E-09 2.60E+14 0 0.3 0.7 0 0 0 -1050.8676 76411.983 4.2539537E-09 2.60E+14 0 0.2 0.8 0 0 0 -1115.1545 76459.592 4.2563604E-09 2.60E+14 0 0.2 0.8 0 0 0 -1183.3741 76633.367 4.2683079E-09 2.61E+14 0 0.2 0.8 0 0 0 -1255.767 77312.12 4.290997E-09 2.64E+14 0.5 0.5 0 0 0 0 -1332.5886 79602.375 4.3396835E-09 2.72E+14 0.5 0.5 0 0 0 0 +Index velocity temperature densities electron_densities C O Mg Si Ni56 Ni58 +- km/s K g/cm^3 /cm^3 1 1 1 1 1 1 +0 871.66905 76395.577 4.2537191E-09 2.60E+14 0 0 0 0.6 0.4 0 +1 877.44269 76395.577 4.2537191E-09 2.60E+14 0 0 0 0.1 0.5 0.4 +2 894.99407 76395.631 4.2537191E-09 2.60E+14 0 0 0 0.3 0 0.7 +3 931.1571 76396.057 4.2537191E-09 2.60E+14 0 0.2 0.8 0 0 0 +4 990.30752 76399.042 4.2537271E-09 2.60E+14 0 0.3 0.7 0 0 0 +5 1050.8676 76411.983 4.2539537E-09 2.60E+14 0 0.2 0.8 0 0 0 +6 1115.1545 76459.592 4.2563604E-09 2.60E+14 0 0.2 0.8 0 0 0 +7 1183.3741 76633.367 4.2683079E-09 2.61E+14 0 0.2 0.8 0 0 0 +8 1255.767 77312.12 4.290997E-09 2.64E+14 0.5 0.5 0 0 0 0 +9 1332.5886 79602.375 4.3396835E-09 2.72E+14 0.5 0.5 0 0 0 0 diff --git a/tardis/io/tests/data/csv_composition.csv b/tardis/io/tests/data/csv_composition.csv index 46cc0850afa..6ea3cb40efc 100644 --- a/tardis/io/tests/data/csv_composition.csv +++ b/tardis/io/tests/data/csv_composition.csv @@ -1,12 +1,12 @@ -C O Mg Si Ni56 Ni58 -1 1 1 1 1 1 -0 0 0 0.6 0.4 0 -0 0 0 0.1 0.5 0.4 -0 0 0 0.3 0 0.7 -0 0.2 0.8 0 0 0 -0 0.3 0.7 0 0 0 -0 0.2 0.8 0 0 0 -0 0.2 0.8 0 0 0 -0 0.2 0.8 0 0 0 -0.5 0.5 0 0 0 0 -0.5 0.5 0 0 0 0 +Index C O Mg Si Ni56 Ni58 +0 1 1 1 1 1 1 +1 0 0 0 0.6 0.4 0 +2 0 0 0 0.1 0.5 0.4 +3 0 0 0 0.3 0 0.7 +4 0 0.2 0.8 0 0 0 +5 0 0.3 0.7 0 0 0 +6 0 0.2 0.8 0 0 0 +7 0 0.2 0.8 0 0 0 +8 0 0.2 0.8 0 0 0 +9 0.5 0.5 0 0 0 0 +10 0.5 0.5 0 0 0 0 diff --git a/tardis/io/tests/test_model_reader.py b/tardis/io/tests/test_model_reader.py index bf69e6a863b..73345f474c1 100644 --- a/tardis/io/tests/test_model_reader.py +++ b/tardis/io/tests/test_model_reader.py @@ -56,9 +56,11 @@ def test_read_simple_isotope_abundances(csv_composition_fname): csv_composition_fname) assert np.isclose(abundances.loc[6, 8], 0.5, atol=1.e-12) assert np.isclose(abundances.loc[12, 5], 0.8, atol=1.e-12) - assert np.isclose(abundances.loc[14, 1], 0.3, atol=1.e-12) - assert np.isclose(isotope_abundance.loc[(28, 56), 0], 0.5, atol=1.e-12) - assert np.isclose(isotope_abundance.loc[(28, 58), 1], 0.7, atol=1.e-12) + assert np.isclose(abundances.loc[14, 1], 0.1, atol=1.e-12) + assert np.isclose(isotope_abundance.loc[(28, 56), 0], 0.4, atol=1.e-12) + assert np.isclose(isotope_abundance.loc[(28, 58), 2], 0.7, atol=1.e-12) + assert abundances.shape == (4, 10) + assert isotope_abundance.shape == (2, 10) def test_read_cmfgen_isotope_abundances(cmfgen_fname): @@ -69,7 +71,8 @@ def test_read_cmfgen_isotope_abundances(cmfgen_fname): assert np.isclose(abundances.loc[14, 1], 0.3, atol=1.e-12) assert np.isclose(isotope_abundance.loc[(28, 56), 0], 0.5, atol=1.e-12) assert np.isclose(isotope_abundance.loc[(28, 58), 1], 0.7, atol=1.e-12) - + assert abundances.shape == (4, 9) + assert isotope_abundance.shape == (2, 9) def test_read_uniform_abundances(isotope_uniform_abundance):