From 72bf06b3a36d575b7ea090fcfbf65b87d393f941 Mon Sep 17 00:00:00 2001 From: dh00601 <dh00601@surrey.ac.uk> Date: Wed, 29 Dec 2021 12:51:59 +0000 Subject: [PATCH] working on the docstring --- badges/docstring_coverage.svg | 6 +- badges/test_coverage.svg | 6 +- binarycpython/tests/test_functions.py | 164 +++++++++--------- binarycpython/utils/HPC.py | 5 + binarycpython/utils/Moe_di_Stefano_2017.py | 5 +- binarycpython/utils/analytics.py | 4 + binarycpython/utils/cache.py | 34 +++- binarycpython/utils/condor.py | 5 +- binarycpython/utils/dataIO.py | 5 +- binarycpython/utils/dicts.py | 33 +++- binarycpython/utils/distribution_functions.py | 5 +- binarycpython/utils/ensemble.py | 6 + binarycpython/utils/grid_logging.py | 5 +- binarycpython/utils/grid_options_defaults.py | 4 + binarycpython/utils/gridcode.py | 16 +- binarycpython/utils/metadata.py | 4 + binarycpython/utils/slurm.py | 5 +- binarycpython/utils/spacing_functions.py | 57 ++++-- binarycpython/utils/version_info.py | 5 +- 19 files changed, 257 insertions(+), 117 deletions(-) diff --git a/badges/docstring_coverage.svg b/badges/docstring_coverage.svg index ea63cd22b..ede195758 100644 --- a/badges/docstring_coverage.svg +++ b/badges/docstring_coverage.svg @@ -8,13 +8,13 @@ </clipPath> <g clip-path="url(#r)"> <rect width="99" height="20" fill="#555"/> - <rect x="99" width="43" height="20" fill="#97CA00"/> + <rect x="99" width="43" height="20" fill="#4c1"/> <rect width="142" height="20" fill="url(#s)"/> </g> <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="110"> <text x="505" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="890">docstr-coverage</text> <text x="505" y="140" transform="scale(.1)" textLength="890">docstr-coverage</text> - <text x="1195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">91%</text> - <text x="1195" y="140" transform="scale(.1)">91%</text> + <text x="1195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">100%</text> + <text x="1195" y="140" transform="scale(.1)">100%</text> </g> </svg> \ No newline at end of file diff --git a/badges/test_coverage.svg b/badges/test_coverage.svg index c97e50489..9e1a50b1a 100644 --- a/badges/test_coverage.svg +++ b/badges/test_coverage.svg @@ -9,13 +9,13 @@ </mask> <g mask="url(#a)"> <path fill="#555" d="M0 0h63v20H0z"/> - <path fill="#dfb317" d="M63 0h36v20H63z"/> + <path fill="#e05d44" d="M63 0h36v20H63z"/> <path fill="url(#b)" d="M0 0h99v20H0z"/> </g> <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> <text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text> <text x="31.5" y="14">coverage</text> - <text x="80" y="15" fill="#010101" fill-opacity=".3">66%</text> - <text x="80" y="14">66%</text> + <text x="80" y="15" fill="#010101" fill-opacity=".3">12%</text> + <text x="80" y="14">12%</text> </g> </svg> diff --git a/binarycpython/tests/test_functions.py b/binarycpython/tests/test_functions.py index d4ad330ec..0f3bec3a5 100644 --- a/binarycpython/tests/test_functions.py +++ b/binarycpython/tests/test_functions.py @@ -19,8 +19,6 @@ from binarycpython.utils.functions import ( get_username, bin_data, create_hdf5, - return_binary_c_version_info, - parse_binary_c_version_info, output_lines, get_defaults, example_parse_output, @@ -190,87 +188,87 @@ class test_create_hdf5(unittest.TestCase): self.assertIn("settings_2", json.loads(file.get("settings/used_settings")[()])) -class test_return_binary_c_version_info(unittest.TestCase): - """ - Unittests for return_binary_c_version_info - """ - - def test_not_parsed(self): - with Capturing() as output: - self._test_not_parsed() - - def _test_not_parsed(self): - """ - Test for the raw version_info output - """ - - version_info = return_binary_c_version_info(parsed=False) - - self.assertTrue(isinstance(version_info, str)) - self.assertIn("Build", version_info) - self.assertIn("REIMERS_ETA_DEFAULT", version_info) - self.assertIn("SIGMA_THOMPSON", version_info) - - def test_parsed(self): - with Capturing() as output: - self._test_parsed() - - def _test_parsed(self): - """ - Test for the parssed version_info - """ - - # also tests the parse_version_info indirectly - version_info_parsed = return_binary_c_version_info(parsed=True) - - self.assertTrue(isinstance(version_info_parsed, dict)) - self.assertIn("isotopes", version_info_parsed.keys()) - self.assertIn("argpairs", version_info_parsed.keys()) - self.assertIn("ensembles", version_info_parsed.keys()) - self.assertIn("macros", version_info_parsed.keys()) - self.assertIn("elements", version_info_parsed.keys()) - self.assertIn("dt_limits", version_info_parsed.keys()) - self.assertIn("nucleosynthesis_sources", version_info_parsed.keys()) - self.assertIn("miscellaneous", version_info_parsed.keys()) - - -class test_parse_binary_c_version_info(unittest.TestCase): - """ - Unittests for function parse_binary_c_version_info - """ - - def test_1(self): - with Capturing() as output: - self._test_1() - - def _test_1(self): - """ - Test for the parsed versio info, more detailed - """ - - info = return_binary_c_version_info(parsed=False) - parsed_info = parse_binary_c_version_info(info) - - self.assertIn("isotopes", parsed_info.keys()) - self.assertIn("argpairs", parsed_info.keys()) - self.assertIn("ensembles", parsed_info.keys()) - self.assertIn("macros", parsed_info.keys()) - self.assertIn("elements", parsed_info.keys()) - self.assertIn("dt_limits", parsed_info.keys()) - self.assertIn("nucleosynthesis_sources", parsed_info.keys()) - self.assertIn("miscellaneous", parsed_info.keys()) - - self.assertIsNotNone(parsed_info["argpairs"]) - self.assertIsNotNone(parsed_info["ensembles"]) - self.assertIsNotNone(parsed_info["macros"]) - self.assertIsNotNone(parsed_info["dt_limits"]) - self.assertIsNotNone(parsed_info["miscellaneous"]) - - if parsed_info["macros"]["NUCSYN"] == "on": - self.assertIsNotNone(parsed_info["isotopes"]) - - if parsed_info["macros"]["NUCSYN_ID_SOURCES"] == "on": - self.assertIsNotNone(parsed_info["nucleosynthesis_sources"]) +# class test_return_binary_c_version_info(unittest.TestCase): +# """ +# Unittests for return_binary_c_version_info +# """ + +# def test_not_parsed(self): +# with Capturing() as output: +# self._test_not_parsed() + +# def _test_not_parsed(self): +# """ +# Test for the raw version_info output +# """ + +# version_info = return_binary_c_version_info(parsed=False) + +# self.assertTrue(isinstance(version_info, str)) +# self.assertIn("Build", version_info) +# self.assertIn("REIMERS_ETA_DEFAULT", version_info) +# self.assertIn("SIGMA_THOMPSON", version_info) + +# def test_parsed(self): +# with Capturing() as output: +# self._test_parsed() + +# def _test_parsed(self): +# """ +# Test for the parssed version_info +# """ + +# # also tests the parse_version_info indirectly +# version_info_parsed = return_binary_c_version_info(parsed=True) + +# self.assertTrue(isinstance(version_info_parsed, dict)) +# self.assertIn("isotopes", version_info_parsed.keys()) +# self.assertIn("argpairs", version_info_parsed.keys()) +# self.assertIn("ensembles", version_info_parsed.keys()) +# self.assertIn("macros", version_info_parsed.keys()) +# self.assertIn("elements", version_info_parsed.keys()) +# self.assertIn("dt_limits", version_info_parsed.keys()) +# self.assertIn("nucleosynthesis_sources", version_info_parsed.keys()) +# self.assertIn("miscellaneous", version_info_parsed.keys()) + + +# class test_parse_binary_c_version_info(unittest.TestCase): +# """ +# Unittests for function parse_binary_c_version_info +# """ + +# def test_1(self): +# with Capturing() as output: +# self._test_1() + +# def _test_1(self): +# """ +# Test for the parsed versio info, more detailed +# """ + +# info = return_binary_c_version_info(parsed=False) +# parsed_info = parse_binary_c_version_info(info) + +# self.assertIn("isotopes", parsed_info.keys()) +# self.assertIn("argpairs", parsed_info.keys()) +# self.assertIn("ensembles", parsed_info.keys()) +# self.assertIn("macros", parsed_info.keys()) +# self.assertIn("elements", parsed_info.keys()) +# self.assertIn("dt_limits", parsed_info.keys()) +# self.assertIn("nucleosynthesis_sources", parsed_info.keys()) +# self.assertIn("miscellaneous", parsed_info.keys()) + +# self.assertIsNotNone(parsed_info["argpairs"]) +# self.assertIsNotNone(parsed_info["ensembles"]) +# self.assertIsNotNone(parsed_info["macros"]) +# self.assertIsNotNone(parsed_info["dt_limits"]) +# self.assertIsNotNone(parsed_info["miscellaneous"]) + +# if parsed_info["macros"]["NUCSYN"] == "on": +# self.assertIsNotNone(parsed_info["isotopes"]) + +# if parsed_info["macros"]["NUCSYN_ID_SOURCES"] == "on": +# self.assertIsNotNone(parsed_info["nucleosynthesis_sources"]) class test_output_lines(unittest.TestCase): diff --git a/binarycpython/utils/HPC.py b/binarycpython/utils/HPC.py index 4cc6fccac..ff2ae39ac 100644 --- a/binarycpython/utils/HPC.py +++ b/binarycpython/utils/HPC.py @@ -27,6 +27,10 @@ class HPC(condor, slurm): """ def __init__(self, **kwargs): + """ + Init function for the gridcode class + """ + condor.__init__(self) slurm.__init__(self) @@ -34,6 +38,7 @@ class HPC(condor, slurm): """ Function to return the number of jobs this HPC jobs will use, as an int. """ + if self.grid_options["slurm"] > 0: n = self.grid_options["slurm_njobs"] elif self.grid_options["condor"] > 0: diff --git a/binarycpython/utils/Moe_di_Stefano_2017.py b/binarycpython/utils/Moe_di_Stefano_2017.py index d15b9e9e2..e2d48d8a7 100644 --- a/binarycpython/utils/Moe_di_Stefano_2017.py +++ b/binarycpython/utils/Moe_di_Stefano_2017.py @@ -34,7 +34,10 @@ class Moe_di_Stefano_2017: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the Moe_di_Stefano_2017 class + """ + return def set_moe_di_stefano_settings(self, options=None): diff --git a/binarycpython/utils/analytics.py b/binarycpython/utils/analytics.py index 2e8e1b867..f2bc4a3e0 100644 --- a/binarycpython/utils/analytics.py +++ b/binarycpython/utils/analytics.py @@ -12,6 +12,10 @@ class analytics: """ def __init__(self, **kwargs): + """ + Init function for the analytics class + """ + return ####################### diff --git a/binarycpython/utils/cache.py b/binarycpython/utils/cache.py index f515324bb..4a83d3a2b 100644 --- a/binarycpython/utils/cache.py +++ b/binarycpython/utils/cache.py @@ -26,13 +26,17 @@ class cache: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the spacing_functions class + """ + return def default_cache_dir(self): """ Return a default cache directory path for binary_c-python, or None if we cannot find one. This is used in grid_options_defaults.py """ + error_string = "__*ERR*__" # string that cannot be a path for path in [ os.path.join(os.environ.get("HOME", error_string), ".cache"), @@ -49,18 +53,40 @@ class cache: """ def __init__(self, *args, **kwargs): + """ + Init function for the spacing_functions class + + TODO: is this class necesarry to be defined *within* the cache class? can't it just be outside? + """ + return None def popitem(self): + """ + pop function placeholder + """ + return # do nothing def __getitem__(self, key): + """ + getter function placeholder + """ + return self.__missing__(key) def __setitem__(self, key, value): + """ + Setter function placeholder + """ + return def __delitem__(self, key): + """ + deleter function placeholder + """ + return def setup_function_cache(self, vb=False, cachetype=None): @@ -224,6 +250,12 @@ class cache: if testargs: def _func_wrap(*args, **kwargs): + """ + wrap to return args and kwargs + + TODO: i think this function can be defined elsewhere + """ + return (args, kwargs) args, kwargs = eval("_func_wrap({})".format(testargs)) diff --git a/binarycpython/utils/condor.py b/binarycpython/utils/condor.py index b6746b7f8..5275b657e 100644 --- a/binarycpython/utils/condor.py +++ b/binarycpython/utils/condor.py @@ -24,7 +24,10 @@ class condor: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the condor class + """ + return def condorID(self, ClusterID=None, Process=None): diff --git a/binarycpython/utils/dataIO.py b/binarycpython/utils/dataIO.py index 01d27fed6..ddd0796d3 100644 --- a/binarycpython/utils/dataIO.py +++ b/binarycpython/utils/dataIO.py @@ -35,7 +35,10 @@ class dataIO: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the spacing_functions class + """ + return def dir_ok(self, directory): diff --git a/binarycpython/utils/dicts.py b/binarycpython/utils/dicts.py index 419091e22..f39f969dc 100644 --- a/binarycpython/utils/dicts.py +++ b/binarycpython/utils/dicts.py @@ -104,26 +104,41 @@ def recursive_change_key_to_string(input_dict, custom_format="{:g}"): return new_dict -############################################################ -# code to walk a dictionary recursively based on -# https://stackoverflow.com/questions/13687924/setting-a-value-in-a-nested-python-dictionary-given-a-list-of-indices-and-value + def _nested_set(dic, keys, value): + """ + Code to set a value of a nested dict based on a list of keys. We take into account the fact that the vallue in the dict might not be set at all by the setdefault call and the reverse looping of the keys + + https://stackoverflow.com/questions/13687924/setting-a-value-in-a-nested-python-dictionary-given-a-list-of-indices-and-value + + TODO: describe better + """ + for key in keys[:-1]: dic = dic.setdefault(key, {}) dic[keys[-1]] = value def _nested_get(dic, keys): + """ + Code to get a value of a nested dict based on a list of keys. We take into account the fact that the vallue in the dict might not be set at all by the setdefault call and the reverse looping of the keys + + TODO: unused. Remove? + """ + for key in keys[:-1]: dic = dic.setdefault(key, {}) return dic[keys[-1]] -# function to walk through the dictionary, multiplying -# only float values by a const def _recursive_normalize_floats(path, d, const, parent=None, ignore=None): + """ + function to walk through the dictionary, multiplying only float values by a const + """ + if not parent: parent = d + for k, v in d.items(): if ignore and k in ignore: continue @@ -318,6 +333,10 @@ class AutoVivificationDict(dict): """ def __getitem__(self, item): + """ + Getitem function for the autovivication dict + """ + try: return dict.__getitem__(self, item) except KeyError: @@ -325,6 +344,10 @@ class AutoVivificationDict(dict): return value def __iadd__(self, other): + """ + iadd function (handling the +=) for the autovivication dict. + """ + # if a value does not exist, assume it is 0.0 try: self += other diff --git a/binarycpython/utils/distribution_functions.py b/binarycpython/utils/distribution_functions.py index 92f26cbc1..da62b8cef 100644 --- a/binarycpython/utils/distribution_functions.py +++ b/binarycpython/utils/distribution_functions.py @@ -58,7 +58,10 @@ class distribution_functions: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the distribution_functions class + """ + return def flat(self) -> float: diff --git a/binarycpython/utils/ensemble.py b/binarycpython/utils/ensemble.py index 80328c299..7573fc6b5 100644 --- a/binarycpython/utils/ensemble.py +++ b/binarycpython/utils/ensemble.py @@ -73,6 +73,7 @@ def open_ensemble(filename, encoding="utf-8"): """ Function to open an ensemble at filename for reading and decompression if required. """ + compression = ensemble_compression(filename) if ensemble_file_type(filename) == "msgpack": flags = "rb" @@ -103,6 +104,7 @@ def ensemble_file_type(filename): """ Returns the file type of an ensemble file. """ + if ".json" in filename: filetype = "JSON" elif ".msgpack" in filename: @@ -145,6 +147,10 @@ def load_ensemble( _loaded = False def _hook(obj): + """ + Hook to load ensemble + """ + nonlocal _loaded if _loaded is False: _loaded = True diff --git a/binarycpython/utils/grid_logging.py b/binarycpython/utils/grid_logging.py index 2ee7a5b17..980de9c01 100644 --- a/binarycpython/utils/grid_logging.py +++ b/binarycpython/utils/grid_logging.py @@ -33,7 +33,10 @@ class grid_logging: The class extension for the population object that contains logging functionality """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the grid_logging class + """ + return def _set_custom_logging(self): diff --git a/binarycpython/utils/grid_options_defaults.py b/binarycpython/utils/grid_options_defaults.py index dfc1fe43c..e6ab8fef5 100644 --- a/binarycpython/utils/grid_options_defaults.py +++ b/binarycpython/utils/grid_options_defaults.py @@ -34,7 +34,11 @@ class grid_options_defaults: """ Class extension to Population grid containing all the functionality for the options and defaults """ + def __init__(self, **kwargs): + """ + Init function for the grid_options_defaults class + """ return diff --git a/binarycpython/utils/gridcode.py b/binarycpython/utils/gridcode.py index 800c26ed0..93f9cc8a4 100644 --- a/binarycpython/utils/gridcode.py +++ b/binarycpython/utils/gridcode.py @@ -23,7 +23,10 @@ class gridcode: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the gridcode class + """ + return ################################################### @@ -93,6 +96,7 @@ class gridcode: Results in a generated file that contains a system_generator function. # TODO: make sure running systems with multiplicity 3+ is also possible. + # TODO: there is a lot of things going on in this function. Make sure to describe clearly what happens here. """ self.verbose_print("Generating grid code", self.grid_options["verbosity"], 1) @@ -754,10 +758,12 @@ class gridcode: def _write_gridcode_system_call( self, grid_variable, dry_run, branchpoint, branchcode ): - ################################################################################# - # Here are the calls to the queue or other solution. - # this part is for every system - # + """ + Function to write the block of code (as string) that handles the setting the final probability, taking into account the weight and repeat settings, incrementing the total starcount and total probability. + + Then if the run is a dry run we implement the dry_run_hook or pass depending on the settings. If it is not a dry run we yield the system dict + """ + self._increment_indent_depth(+1) self._add_code("#" * 40 + "\n") diff --git a/binarycpython/utils/metadata.py b/binarycpython/utils/metadata.py index d577bf391..4e1f5704b 100644 --- a/binarycpython/utils/metadata.py +++ b/binarycpython/utils/metadata.py @@ -23,6 +23,10 @@ class metadata: """ def __init__(self, **kwargs): + """ + Init function for the metadata class + """ + return def add_system_metadata(self): diff --git a/binarycpython/utils/slurm.py b/binarycpython/utils/slurm.py index 2117def6e..65f772412 100644 --- a/binarycpython/utils/slurm.py +++ b/binarycpython/utils/slurm.py @@ -23,7 +23,10 @@ class slurm: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the slurm class + """ + return def slurmID(self, jobid=None, jobarrayindex=None): diff --git a/binarycpython/utils/spacing_functions.py b/binarycpython/utils/spacing_functions.py index f4c70ec20..64eacce2d 100644 --- a/binarycpython/utils/spacing_functions.py +++ b/binarycpython/utils/spacing_functions.py @@ -31,7 +31,10 @@ class spacing_functions: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the spacing_functions class + """ + return @cachetools.cachedmethod(lambda self: self.caches["spacing_functions.const_linear"]) @@ -255,6 +258,10 @@ class spacing_functions: usecache=True, vb=False, ): + """ + Wrapper function for the const_dt funtion which handles verbose logging and filtering of arguments + """ + print( "call _const_dt num_cores={} dt={} dlogt={} mmin={} mmax={} nres={} logspacing={} tmin={} mindm={} maxdm={} fsample={} factor={} logmasses={} log10masses={} showlist={} usecache={} [cache={} vb={}]".format( num_cores, @@ -326,8 +333,16 @@ class spacing_functions: # make it a wrapped function that just returns the # _const_dt function acting on its arguments def __dummy_decorator(func): + """ + Placeholder decorator function + """ + @functools.wraps(func) def wrapped(*args, **kwargs): + """ + Dummy wrapper function + """ + return func(*args, **kwargs) return wrapped @@ -361,11 +376,15 @@ class spacing_functions: showtable=False, usecache=True, ): - # first thing to do is make a stellar lifetime table - # - # we should use the bse_options_json passed in - # so our lifetime_population uses the same physics - # as the main grid + """ + first thing to do is make a stellar lifetime table + + we should use the bse_options_json passed in + so our lifetime_population uses the same physics + as the main grid + + TODO: Describe this function better with arguments and + """ # convert bse_options to dict bse_options = json.loads(bse_options_json) @@ -417,6 +436,10 @@ class spacing_functions: # set up the parse function def _parse_function(self, output): + """ + Parse function for the const_dt binary_c calls + """ + if output: for line in output.splitlines(): data = line.split() @@ -496,23 +519,37 @@ class spacing_functions: verbosity=0, # lifetime # mass ) - # function to get a mass given a time (Myr) def _mass_from_time(linear_time): + """ + Function to get a mass given a time, calculated by using the interpolator_time_mass + """ + return ( 10.0 ** interpolator_time_mass.interpolate([math.log10(linear_time)])[0] ) - # function to get a time given a mass (Msun) def _time_from_mass(mass): + """ + Function to get a time given a mass, calculated by using the interpolator_time_mass + """ + return 10.0 ** interpolator_mass_time.interpolate([math.log10(mass)])[0] - # return a unique list def _uniq(_list): + """ + Function to return a list containing only unique elements + + TODO: move this to the functions file + """ + return sorted(list(set(_list))) - # format a whole list like %g def _format(_list): + """ + Function to format a list of numbers as %g strings + """ + return [float("{x:g}".format(x=x)) for x in _list] # construct mass list, always include the min and max diff --git a/binarycpython/utils/version_info.py b/binarycpython/utils/version_info.py index 8ea9fd899..2bc09d228 100644 --- a/binarycpython/utils/version_info.py +++ b/binarycpython/utils/version_info.py @@ -25,7 +25,10 @@ class version_info: """ def __init__(self, **kwargs): - # don't do anything: we just inherit from this class + """ + Init function for the version_info class + """ + return ######################################################## -- GitLab