Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
247ef50
Rebase popsyn unit tests onto v2.3
elizabethteng Mar 26, 2026
1c9bda5
population helper function
elizabethteng Mar 26, 2026
9527e7c
Refactor test_synthetic_population to use make_test_pop helper
elizabethteng Mar 26, 2026
30bcbcf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 26, 2026
cc63eaf
fix failing tests
elizabethteng Mar 26, 2026
af54106
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 26, 2026
a97e18b
Update setup.cfg to exclude analysis.py and GRB.py from testing
elizabethteng Mar 26, 2026
e85ff24
removed tests for inactive code
elizabethteng Mar 26, 2026
904ac5c
Merge branch 'et_unittest_popsyn' of https://github.com/POSYDON-code/…
elizabethteng Mar 26, 2026
4f604c1
add note about being omitted from testing
elizabethteng Mar 26, 2026
ec77dea
Merge branch 'v2.3' into et_unittest_popsyn
elizabethteng Mar 26, 2026
1c50d14
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 26, 2026
5e87ee2
updated for change from metallicity to metallicities
elizabethteng Mar 30, 2026
7b75f9f
updated coverage
elizabethteng Mar 30, 2026
08c42b3
update test coverage
elizabethteng Mar 30, 2026
a8481aa
finishing tests for synthetic_population
elizabethteng Mar 30, 2026
a7246a6
fix small issue with rates helper function
elizabethteng Mar 30, 2026
6fa63f6
finish coverage of synthetic population test
elizabethteng Mar 30, 2026
a2d2dea
cleaning up annoying warnings
elizabethteng Mar 30, 2026
79444d7
update to remove tests for things that have been removed
elizabethteng Mar 30, 2026
063a5c3
update independent_sample test to reflect changes to distributions, a…
elizabethteng Mar 30, 2026
9422a5f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
fe0aad6
change author to authors
elizabethteng Mar 30, 2026
08528e6
update test for io.py
elizabethteng Mar 30, 2026
c8953ec
unit test for sample_from_file
elizabethteng Mar 30, 2026
7183c04
updated transient_select_funcs tests to add a new one for new funcito…
elizabethteng Mar 30, 2026
cfb4493
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
c2bfaab
Update continuous_integration.yml to cover all of popsyn
elizabethteng Mar 30, 2026
152abaa
update defaults for multiple metallicities being in list form
elizabethteng Mar 30, 2026
b77d96f
debug tests
elizabethteng Mar 30, 2026
fb0ea07
fix bug in conditional statement
elizabethteng Mar 30, 2026
e0f8c61
clean up coverage of branches
elizabethteng Mar 30, 2026
cbb02b5
add coverage
elizabethteng Mar 30, 2026
64856a1
Merge branch 'et_unittest_popsyn' of https://github.com/POSYDON-code/…
elizabethteng Mar 30, 2026
773037e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
74861af
moved coverage addition to correct location
elizabethteng Mar 30, 2026
0f4ecec
format
elizabethteng Mar 30, 2026
ef8fed4
get rid of isclass, isroutine imports -- no longer necessary
elizabethteng Mar 30, 2026
24f36bc
add test for selection effects
elizabethteng Mar 30, 2026
d6e7e5a
merge
elizabethteng Mar 30, 2026
6975dfc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
5467494
write tests for Moes_distributions.py
elizabethteng Mar 30, 2026
a6695db
fix bug and update coverage
elizabethteng Mar 30, 2026
72bd2e9
fix bug and update coverage
elizabethteng Mar 30, 2026
013a7cc
remove isroutine checks
elizabethteng Mar 30, 2026
89bedc9
update coverage
elizabethteng Mar 30, 2026
d0a98fb
Merge branch 'et_unittest_popsyn' of https://github.com/POSYDON-code/…
elizabethteng Mar 30, 2026
9232de2
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
f865de8
Update continuous_integration.yml
elizabethteng Mar 30, 2026
9c5c45b
restore test I accidentally deleted
elizabethteng Mar 30, 2026
28be49d
fix mistake from merge
elizabethteng Mar 30, 2026
baff2c1
Merge branch 'et_unittest_popsyn' of https://github.com/POSYDON-code/…
elizabethteng Mar 30, 2026
fc9d205
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
9547b8c
first draft of binarypopulation test
elizabethteng Mar 30, 2026
bf60169
mock out dependence on external data file
elizabethteng Mar 30, 2026
0b5bdb4
Merge branch 'et_unittest_popsyn' of https://github.com/POSYDON-code/…
elizabethteng Mar 30, 2026
0706981
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
3200c54
adjust coverage for binarypopulation
elizabethteng Mar 30, 2026
60224de
debug tests and adjust coverage
elizabethteng Mar 30, 2026
c572068
fix merge conflict
elizabethteng Mar 30, 2026
9936534
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 30, 2026
5902f3c
Apply suggestion from @sgossage -- indent dummy_code
sgossage Mar 31, 2026
fef6715
Apply suggestion from @sgossage
sgossage Mar 31, 2026
71688ae
Apply suggestion from @sgossage
sgossage Mar 31, 2026
530f12c
Apply suggestion from @sgossage -- fix indent
sgossage Mar 31, 2026
b0382d7
Apply suggestion from @sgossage -- remove alt code
sgossage Mar 31, 2026
d4fceb0
Apply suggestion from @sgossage -- fix indent
sgossage Mar 31, 2026
dc1bd2b
Apply suggestion from @sgossage - fix indent
sgossage Mar 31, 2026
e4a60eb
Adding ini_path back to test_io.py
sgossage Mar 31, 2026
3528041
Update posydon/unit_tests/_helper_functions_for_tests/population.py
elizabethteng Mar 31, 2026
21082c8
revert change to population.py
elizabethteng Mar 31, 2026
c71f929
Refactor ini and dummy code content in test_io.py using dedent
sgossage Mar 31, 2026
7d4608e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 31, 2026
e98f569
Fix indent test_io.py
sgossage Mar 31, 2026
d4cf906
Remove extra quote in test_io.py
sgossage Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/continuous_integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ jobs:
--cov=posydon.config \
--cov=posydon.utils \
--cov=posydon.grids \
--cov=posydon.popsyn.IMFs \
--cov=posydon.popsyn.norm_pop \
--cov=posydon.popsyn.distributions \
--cov=posydon.popsyn.star_formation_history \
--cov=posydon.popsyn \
--cov=posydon.CLI \
--cov-branch \
--cov-report term-missing \
Expand Down
3 changes: 3 additions & 0 deletions posydon/popsyn/GRB.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# This code is currently not being actively used, and is not covered by unit tests.
# To test this file, remove it from the 'omit' blocks in POSYDON/setup.cfg.

__author__ = ['Simone Bavera <Simone.Bavera@unige.ch>']

import numpy as np
Expand Down
12 changes: 6 additions & 6 deletions posydon/popsyn/Moes_distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,15 +367,15 @@ def __init__(self, n_M1=101, n_logP=158, n_q=91, n_e=200,
# save to grid
self.cumPbindist[:,i] = mycumPbindist

def __repr__(self):
def __repr__(self): # pragma: no cover
return ("Moe and Di Stefano 2017 distributions on a grid of "
f"n_M1={self.n_M1}, n_logP={self.n_logP}, n_q={self.n_q}, and "
f"n_e={self.n_e}")
f"n_M1={self.numM1}, n_logP={self.numlogP}, n_q={self.numq}, and "
f"n_e={self.nume}")

def _repr_html_(self):
def _repr_html_(self): # pragma: no cover
return ("<h3>Moe and Di Stefano 2017 distributions on a grid of</h3>"
f"<p>n_M1={self.n_M1}</p><p>n_logP={self.n_logP}</p>"
f"<p>n_q={self.n_q}</p><p>n_e={self.n_e}</p>")
f"<p>n_M1={self.numM1}</p><p>n_logP={self.numlogP}</p>"
f"<p>n_q={self.numq}</p><p>n_e={self.nume}</p>")

def __call__(self, M1, M_min=0.08, M_max=150.0, all_binaries=True):
"""Initializing the class.
Expand Down
2 changes: 2 additions & 0 deletions posydon/popsyn/analysis.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Module for analyzing binary population simulation results."""

# This code is currently not being actively used, and is not covered by unit tests.
# To test this file, remove it from the 'omit' blocks in POSYDON/setup.cfg.

__authors__ = [
"Konstantinos Kovlakas <Konstantinos.Kovlakas@unige.ch>",
Expand Down
41 changes: 22 additions & 19 deletions posydon/popsyn/binarypopulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,8 @@ def from_ini(cls, path, metallicity_index=0, verbose=False):

return cls(**pop_kwargs)

def evolve(self, **kwargs):
def evolve(self, **kwargs): # pragma: no cover
# wrapper for _safe_evolve
"""Evolve a binary population.

Parameters
Expand Down Expand Up @@ -290,7 +291,8 @@ def evolve(self, **kwargs):
self.kwargs.update(params)
self._safe_evolve(**self.kwargs)

def _safe_evolve(self, **kwargs):
def _safe_evolve(self, **kwargs): # pragma: no cover
# needs more complex test than unit test
"""Evolve binaries in a population, catching warnings/exceptions."""
if not self.population_properties.steps_loaded:
# Enforce the same metallicity for all grid steps
Expand Down Expand Up @@ -486,7 +488,8 @@ def _safe_evolve(self, **kwargs):
f"evolution.combined.{self.rank}.h5"),
mode='w', **kwargs)

def save(self, save_path, **kwargs):
def save(self, save_path, **kwargs): # pragma: no cover
# dependent on full evolution
"""Save BinaryPopulation to hdf file."""
optimize_ram = self.kwargs['optimize_ram']
temp_directory = self.kwargs['temp_directory']
Expand Down Expand Up @@ -514,13 +517,13 @@ def save(self, save_path, **kwargs):

self.combine_saved_files(absolute_filepath, tmp_files, **kwargs)

def make_temp_fname(self):
def make_temp_fname(self): # pragma: no cover
"""Get a valid filename for the temporary file."""
temp_directory = self.kwargs['temp_directory']
return os.path.join(temp_directory, f"evolution.combined.{self.rank}.h5")
# return os.path.join(dir_name, '.tmp{}_'.format(rank) + file_name)

def combine_saved_files(self, absolute_filepath, file_names, **kwargs):
def combine_saved_files(self, absolute_filepath, file_names, **kwargs): # pragma: no cover
"""Combine various temporary files in a given folder.

Parameters
Expand Down Expand Up @@ -623,19 +626,19 @@ def __getstate__(self):
prop.close()
return d

def __iter__(self):
def __iter__(self): # pragma: no cover
"""Iterate the binaries."""
return iter(self.manager)

def __getitem__(self, key):
def __getitem__(self, key): # pragma: no cover
"""Get the k-th binary."""
return self.manager[key]

def __len__(self):
def __len__(self): # pragma: no cover
"""Get the number of binaries in the population."""
return len(self.manager)

def __repr__(self):
def __repr__(self): # pragma: no cover
"""Report key properties of the object."""
s = "<{}.{} at {}>\n".format(
self.__class__.__module__, self.__class__.__name__, hex(id(self))
Expand Down Expand Up @@ -738,7 +741,7 @@ def to_df(self, selection_function=None, **kwargs):
and selection_function(binary)):
holder.append(binary.to_df(**kwargs))

elif len(self.history_dfs) > 0:
elif len(self.history_dfs) > 0: # pragma: no branch
holder.extend(self.history_dfs)

if len(holder) > 0:
Expand All @@ -759,7 +762,7 @@ def to_oneline_df(self, selection_function=None, **kwargs):
and selection_function(binary)):
holder.append(binary.to_oneline_df(**kwargs))

elif len(self.oneline_dfs) > 0:
elif len(self.oneline_dfs) > 0: # pragma: no branch
holder.extend(self.oneline_dfs)

if len(holder) > 0:
Expand All @@ -786,7 +789,7 @@ def generate(self, **kwargs):
self.append(binary)
return binary

def from_hdf(self, indices=None, where=None, restore=False):
def from_hdf(self, indices=None, where=None, restore=False): # pragma: no cover
"""Load a BinaryStar instance from an hdf file of a saved population.

Parameters
Expand Down Expand Up @@ -856,7 +859,7 @@ def from_hdf(self, indices=None, where=None, restore=False):

return binary_holder

def save(self, fname, **kwargs):
def save(self, fname, **kwargs): # pragma: no cover
"""Save binaries to an hdf file using pandas HDFStore.

Any object dtype columns not parsed by infer_objects() is converted to
Expand Down Expand Up @@ -961,19 +964,19 @@ def save(self, fname, **kwargs):
return


def __getitem__(self, key):
def __getitem__(self, key): # pragma: no cover
"""Return the key-th binary."""
return self.binaries[key]

def __iter__(self):
def __iter__(self): # pragma: no cover
"""Iterate the binaries in the population."""
return iter(self.binaries)

def __len__(self):
def __len__(self): # pragma: no cover
"""Return the number of binaries in the population."""
return len(self.binaries)

def __bool__(self):
def __bool__(self): # pragma: no cover
"""Evaluate as True if binaries have been appended."""
return len(self) > 0

Expand Down Expand Up @@ -1029,7 +1032,7 @@ def draw_initial_samples(self, orbital_scheme='separation', **kwargs):
if orbital_scheme == 'separation':
separation, eccentricity, m1, m2 = sampler_output
orbital_period = orbital_period_from_separation(separation, m1, m2)
elif orbital_scheme == 'period':
elif orbital_scheme == 'period': # pragma: no branch
orbital_period, eccentricity, m1, m2 = sampler_output
separation = orbital_separation_from_period(orbital_period, m1, m2)
else:
Expand Down Expand Up @@ -1176,7 +1179,7 @@ def draw_initial_binary(self, **kwargs):
star_2=SingleStar(**star2_params))
return binary

def __repr__(self,):
def __repr__(self,): # pragma: no cover
"""Report key properties of the BinaryGenerator instance."""
s = "<{}.{} at {}>\n".format(
self.__class__.__module__, self.__class__.__name__, hex(id(self))
Expand Down
14 changes: 8 additions & 6 deletions posydon/popsyn/independent_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def generate_independent_samples(orbital_scheme='period', **kwargs):
# Generate primary masses
m1_set = generate_primary_masses(**kwargs)

if use_Moe_17_PsandQs(orbital_scheme=orbital_scheme, **kwargs):
if use_Moe_17_PsandQs(orbital_scheme=orbital_scheme, **kwargs): # pragma: no cover
# this requires an integration test with actual external datafiles. No unit test
# initialize generator for Moe+17-PsandQs
if _gen_Moe_17_PsandQs is None:
_gen_Moe_17_PsandQs = Moe_17_PsandQs(**kwargs)
Expand Down Expand Up @@ -124,7 +125,7 @@ def generate_orbital_periods(primary_masses,
orbital_period_max=10**3.5,
orbital_period_scheme='Sana+12_period_extended',
**kwargs):
"""Randomaly generate orbital periods for a sample of binaries."""
"""Randomly generate orbital periods for a sample of binaries."""
RNG = kwargs.get('RNG', np.random.default_rng())

# Check inputs
Expand Down Expand Up @@ -209,7 +210,7 @@ def generate_orbital_separations(number_of_binaries=1,
)
orbital_separations = sep_dist.rvs(size=number_of_binaries, rng=RNG)

else:
else: # pragma: no cover
pass

return orbital_separations
Expand Down Expand Up @@ -253,7 +254,7 @@ def generate_eccentricities(number_of_binaries=1,
elif eccentricity_scheme == 'zero':
ecc_dist = distributions.ZeroEccentricity()
eccentricities = ecc_dist.rvs(size=number_of_binaries, rng=RNG)
else:
else: # pragma: no cover
# This should never be reached
pass

Expand Down Expand Up @@ -307,7 +308,7 @@ def generate_primary_masses(number_of_binaries=1,
elif primary_mass_scheme == 'Kroupa2001':
imf = IMFs.Kroupa2001(m_min=primary_mass_min, m_max=primary_mass_max)
primary_masses = imf.rvs(size=number_of_binaries, rng=RNG)
else:
else: # pragma: no cover
pass

return primary_masses
Expand Down Expand Up @@ -401,6 +402,7 @@ def generate_binary_fraction(m1=None, binary_fraction_const=1,
elif not isinstance(m1,np.ndarray):
m1 = np.asarray(m1)
binary_fraction = np.zeros_like(m1, dtype=float)

# Input parameter checks
if binary_fraction_scheme not in binary_fraction_scheme_options:
raise ValueError("You must provide an allowed binary fraction scheme.")
Expand All @@ -415,7 +417,7 @@ def generate_binary_fraction(m1=None, binary_fraction_const=1,
binary_fraction[(m1 <= 5) & (m1 > 2)] = 0.59
binary_fraction[(m1 <= 2)] = 0.4

else:
else: # pragma: no cover
pass

return binary_fraction
30 changes: 15 additions & 15 deletions posydon/popsyn/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,11 @@ def clean_binary_history_df(binary_df, extra_binary_dtypes_user=None,
assert isinstance( binary_df, pd.DataFrame )

# User specified extra binary and star columns
if extra_binary_dtypes_user is None:
if extra_binary_dtypes_user is None: # pragma: no cover
extra_binary_dtypes_user = {}
if extra_S1_dtypes_user is None:
if extra_S1_dtypes_user is None: # pragma: no cover
extra_S1_dtypes_user = {}
if extra_S2_dtypes_user is None:
if extra_S2_dtypes_user is None: # pragma: no cover
extra_S2_dtypes_user = {}

# try to coerce data types automatically first
Expand Down Expand Up @@ -231,7 +231,7 @@ def clean_binary_history_df(binary_df, extra_binary_dtypes_user=None,
common_dtype_dict[key] = SP_comb_S1_dict.get( key.replace('S1_', '') )
elif key in S2_keys:
common_dtype_dict[key] = SP_comb_S2_dict.get( key.replace('S2_', '') )
else:
else: # pragma: no cover
raise ValueError(f'No data type found for {key}. Dtypes must be explicity declared.')
# set dtypes
binary_df = binary_df.astype( common_dtype_dict )
Expand Down Expand Up @@ -275,11 +275,11 @@ def clean_binary_oneline_df(oneline_df, extra_binary_dtypes_user=None,
assert isinstance( oneline_df, pd.DataFrame )

# User specified extra binary and star columns
if extra_binary_dtypes_user is None:
if extra_binary_dtypes_user is None: # pragma: no cover
extra_binary_dtypes_user = {}
if extra_S1_dtypes_user is None:
if extra_S1_dtypes_user is None: # pragma: no cover
extra_S1_dtypes_user = {}
if extra_S2_dtypes_user is None:
if extra_S2_dtypes_user is None: # pragma: no cover
extra_S2_dtypes_user = {}

# try to coerce data types automatically first
Expand Down Expand Up @@ -330,7 +330,7 @@ def clean_binary_oneline_df(oneline_df, extra_binary_dtypes_user=None,
common_dtype_dict[key] = SP_comb_S1_dict.get( strip_prefix_and_suffix(key) )
elif key in S2_keys:
common_dtype_dict[key] = SP_comb_S2_dict.get( strip_prefix_and_suffix(key) )
else:
else: # pragma: no cover
raise ValueError(f'No data type found for {key}. Dtypes must be explicity declared.')
# set dtypes
oneline_df = oneline_df.astype( common_dtype_dict )
Expand Down Expand Up @@ -369,15 +369,15 @@ def parse_inifile(path, verbose=False):

if isinstance(path, str):
path = os.path.abspath(path)
if verbose:
if verbose: # pragma: no cover
print('Reading inifile: \n\t{}'.format(path))
if not os.path.exists(path):
raise FileNotFoundError(
errno.ENOENT, os.strerror(errno.ENOENT), path)
elif isinstance(path, (list, np.ndarray)):
path = [os.path.abspath(f) for f in path]

if verbose:
if verbose: # pragma: no cover
print('Reading inifiles: \n{}'.format(pprint.pformat(path)))
bad_files = []
for f in path:
Expand All @@ -393,7 +393,7 @@ def parse_inifile(path, verbose=False):

files_read = parser.read(path)
# Catch silent errors from configparser.read
if len(files_read) == 0:
if len(files_read) == 0: # pragma: no cover
raise ValueError("No files were read successfully. Given {}.".
format(path))
return parser
Expand Down Expand Up @@ -425,7 +425,7 @@ def simprop_kwargs_from_ini(path, only=None, verbose=False):
parser_dict = {}
for section in parser:
# skip default section
if section == 'DEFAULT':
if section == 'DEFAULT': # pragma: no cover
continue
if only is not None:
if section != only:
Expand Down Expand Up @@ -534,15 +534,15 @@ def binarypop_kwargs_from_ini(path, verbose=False):
if pop_kwargs['use_MPI'] == True and JOB_ID is not None:
raise ValueError('MPI must be turned off for job arrays.')
exit()
elif pop_kwargs['use_MPI'] == True:
elif pop_kwargs['use_MPI'] == True: # pragma: no cover
from mpi4py import MPI
pop_kwargs['comm'] = MPI.COMM_WORLD
# MPI needs to be turned off for job arrays
else:
pop_kwargs['comm'] = None

# Check if we are running as a job array
if JOB_ID is not None and pop_kwargs['use_MPI'] is True:
if JOB_ID is not None and pop_kwargs['use_MPI'] is True: # pragma: no cover
raise ValueError('MPI must be turned off for job arrays.')
elif JOB_ID is not None:
pop_kwargs['JOB_ID'] = np.int64(os.environ['SLURM_ARRAY_JOB_ID'])
Expand Down Expand Up @@ -570,7 +570,7 @@ def binarypop_kwargs_from_ini(path, verbose=False):
if pop_kwargs['include_S1']:
pop_kwargs['S1_kwargs'] = S1_kwargs

elif section == 'SingleStar_2_output':
elif section == 'SingleStar_2_output': # pragma: no branch
S2_kwargs = dict()
for key, val in parser[section].items():
S2_kwargs[key] = ast.literal_eval(val)
Expand Down
4 changes: 2 additions & 2 deletions posydon/popsyn/rate_calculation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__author__ = [
__authors__ = [
"Simone Bavera <Simone.Bavera@unige.ch>",
"Max Briel <max.briel@unige.ch>",
]
Expand Down Expand Up @@ -204,7 +204,7 @@ def get_redshift_bin_centers(delta_t):
# compute the redshift
z_birth = []
for i in range(n_redshift_bin_centers + 1):
# z_at_value is from astopy.cosmology
# z_at_value is from astropy.cosmology
z_birth.append(z_at_value(cosmology.age, t_birth[i] * u.Gyr))
z_birth = np.array(z_birth)

Expand Down
Loading
Loading