diff --git a/badges/docstring_coverage.svg b/badges/docstring_coverage.svg new file mode 100644 index 0000000000000000000000000000000000000000..3bbc9abdff8b8656da7208d061e7a9227206711f --- /dev/null +++ b/badges/docstring_coverage.svg @@ -0,0 +1,20 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="142" height="20"> + <linearGradient id="s" x2="0" y2="100%"> + <stop offset="0" stop-color="#bbb" stop-opacity=".1"/> + <stop offset="1" stop-opacity=".1"/> + </linearGradient> + <clipPath id="r"> + <rect width="142" height="20" rx="3" fill="#fff"/> + </clipPath> + <g clip-path="url(#r)"> + <rect width="99" height="20" fill="#555"/> + <rect x="99" width="43" height="20" fill="#dfb317"/> + <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)">74%</text> + <text x="1195" y="140" transform="scale(.1)">74%</text> + </g> +</svg> \ No newline at end of file diff --git a/binarycpython/utils/distribution_functions.py b/binarycpython/utils/distribution_functions.py index eaa00396f73cb227e7e3de74aa00436649c932d8..5d388a16d56e0a2efd2caee6747b64db2e4960ef 100644 --- a/binarycpython/utils/distribution_functions.py +++ b/binarycpython/utils/distribution_functions.py @@ -11,8 +11,8 @@ There are distributions for the following parameters: - binary fraction Tasks: - - TODO: make some things globally present? rob does this in his module..i guess it saves calculations but not sure if im gonna do that now - - TODO: make global constants stuff + - TODO: make some things globally present? rob does this in his module..i guess it saves + calculations but not sure if im gonna do that now - TODO: add eccentricity distribution: thermal - TODO: Add SFH distributions depending on redshift - TODO: Add metallicity distributions depending on redshift @@ -24,9 +24,9 @@ import gc import math import json -import numpy as np +from typing import Union -from typing import Optional, Union +import numpy as np from binarycpython.utils.useful_funcs import calc_period_from_sep, calc_sep_from_period from binarycpython.utils.functions import verbose_print @@ -44,7 +44,9 @@ distribution_constants = {} # To store the constants in def prepare_dict(global_dict: dict, list_of_sub_keys: list) -> None: """ - Function that makes sure that the global dict is prepared to have a value set there. This dictionary will store values and factors for the distribution functions, so that they dont have to be calculated each time. + Function that makes sure that the global dict is prepared to have a value set there. + This dictionary will store values and factors for the distribution functions, + so that they dont have to be calculated each time. Args: global_dict: globablly acessible dictionary where factors are stored in @@ -55,7 +57,8 @@ def prepare_dict(global_dict: dict, list_of_sub_keys: list) -> None: # This loop almost mimics a recursive loop into the dictionary. # It checks whether the first key of the list is present, if not; set it with an empty dict. - # Then it overrides itself to be that (new) item, and goes on to do that again, until the list exhausted + # Then it overrides itself to be that (new) item, and goes on to do that again, until the list + # exhausted for k in list_of_sub_keys: # If the sub key doesnt exist then make an empty dict if not internal_dict_value.get(k, None): @@ -1266,12 +1269,13 @@ def build_q_table(options, m, p, verbosity=0): # qmin is set by the minimum stellar mass : below this # the companions are planets - qmin = options["ranges"]["M"][ - 0 - ] # TODO: this lower range must not be lower than Mmin. - # However, since the q_min is used as a sample range for the M2, it should use this value I think. discuss + # qmin = options["ranges"]["M"][ + # 0 + # ] # TODO: this lower range must not be lower than Mmin. + # print("build_q_table qmin: {}".format(qmin)) + qmin = options['Mmin']/options['M1'] + print("build_q_table qmin: {}".format(qmin)) - # TODO: fix that this works. Should depend on metallicity too I think. iirc this function does not work now. # qmax = maximum_mass_ratio_for_RLOF(options[m], options[p]) # TODO: change this to the above qmax = 1 @@ -1433,6 +1437,17 @@ def build_q_table(options, m, p, verbosity=0): verbosity, _MS_VERBOSITY_LEVEL, ) + if pre=='low': + below_qlimit = qlimit-qeps + if below_qlimit > 0: + qdata[below_qlimit] = 0 + qdata[0] = 0 + verbose_print( + "\tM&S: build_q_table: using linear extrapolation and setting the points below the lower q bound ({}) to 0 ".format(qlimit), + verbosity, + _MS_VERBOSITY_LEVEL, + ) + elif method == "plaw2": qdata[qlimit] = powerlaw_extrapolation_q( qs=qs, indices=indices, qdata=qdata, verbosity=verbosity @@ -1451,6 +1466,10 @@ def build_q_table(options, m, p, verbosity=0): verbosity, _MS_VERBOSITY_LEVEL, ) + elif method=="poly": + # TODO: consider implementing the poly method (see perl version) + raise ValueError("M&S: build_q_table: Method 'poly' not implemented") + else: msg = "\tM&S: build_q_table: Error no other methods available. The chosen method ({}) does not exist!".format( method @@ -1462,8 +1481,6 @@ def build_q_table(options, m, p, verbosity=0): ) raise ValueError(msg) - # TODO: consider implementing the poly method (see perl version) - # regenerate qs in new table. This is now the updated list of qs where we have some extrapolated numbers tmp_table = [] for q in sorted(qdata.keys()): diff --git a/binarycpython/utils/functions.py b/binarycpython/utils/functions.py index 6678b05e4f51f792eea6e33ffe2e21337a74e03c..30ae3800186b6fb024a0360e172b6780a70d51c4 100644 --- a/binarycpython/utils/functions.py +++ b/binarycpython/utils/functions.py @@ -13,16 +13,16 @@ import os import tempfile import copy import inspect -import ast import sys -import h5py -import numpy as np - from io import StringIO from typing import Union, Any from collections import defaultdict +import h5py +import numpy as np + + from binarycpython import _binary_c_bindings import binarycpython.utils.moe_distefano_data as moe_distefano_data @@ -32,6 +32,10 @@ import py_rinterpolate # Unsorted ######################################################## def convert_bytes(size): + """ + Function to return the size + a magnitude string + """ + for x in ['bytes', 'KB', 'MB', 'GB', 'TB']: if size < 1024.0: return "%3.1f %s" % (size, x) @@ -40,7 +44,12 @@ def convert_bytes(size): return size def get_size(obj, seen=None): - """Recursively finds size of objects""" + """ + Recursively finds size of objects + + From https://github.com/bosswissam/pysize + """ + size = sys.getsizeof(obj) if seen is None: seen = set() @@ -435,13 +444,15 @@ def create_hdf5(data_dir: str, name: str) -> None: def return_binary_c_version_info(parsed: bool = False) -> Union[str, dict]: """ - Function that returns the version information of binary_c. This function calls the function _binary_c_bindings.return_version_info() + Function that returns the version information of binary_c. This function calls the function + _binary_c_bindings.return_version_info() Args: parsed: Boolean flag whether to parse the version_info output of binary_c. default = False Returns: - Either the raw string of binary_c or a parsed version of this in the form of a nested dictionary + Either the raw string of binary_c or a parsed version of this in the form of a nested + dictionary """ found_prev = False @@ -487,13 +498,13 @@ def parse_binary_c_version_info(version_info_string: str) -> dict: # Clean data and put in correct shape splitted = version_info_string.strip().splitlines() - cleaned = set([el.strip() for el in splitted if not el == ""]) + cleaned = {el.strip() for el in splitted if not el == ""} ########################## # Network: # Split off all the networks and parse the info. - networks = set([el for el in cleaned if el.startswith("Network ")]) + networks = {el for el in cleaned if el.startswith("Network ")} cleaned = cleaned - networks networks_dict = {} @@ -527,7 +538,7 @@ def parse_binary_c_version_info(version_info_string: str) -> dict: ########################## # Isotopes: # Split off - isotopes = set([el for el in cleaned if el.startswith("Isotope ")]) + isotopes = {el for el in cleaned if el.startswith("Isotope ")} cleaned = cleaned - isotopes isotope_dict = {} @@ -581,7 +592,7 @@ def parse_binary_c_version_info(version_info_string: str) -> dict: ########################## # ensembles: # Split off - ensembles = set([el for el in cleaned if el.startswith("Ensemble")]) + ensembles = {el for el in cleaned if el.startswith("Ensemble")} cleaned = cleaned - ensembles ensemble_dict = {} @@ -594,7 +605,7 @@ def parse_binary_c_version_info(version_info_string: str) -> dict: ########################## # macros: # Split off - macros = set([el for el in cleaned if el.startswith("macroxyz")]) + macros = {el for el in cleaned if el.startswith("macroxyz")} cleaned = cleaned - macros param_type_dict = { @@ -625,7 +636,7 @@ def parse_binary_c_version_info(version_info_string: str) -> dict: ########################## # Elements: # Split off: - elements = set([el for el in cleaned if el.startswith("Element")]) + elements = {el for el in cleaned if el.startswith("Element")} cleaned = cleaned - elements # Fill dict: @@ -654,7 +665,7 @@ def parse_binary_c_version_info(version_info_string: str) -> dict: ########################## # dt_limits: # split off - dt_limits = set([el for el in cleaned if el.startswith("DTlimit")]) + dt_limits = {el for el in cleaned if el.startswith("DTlimit")} cleaned = cleaned - dt_limits # Fill dict @@ -671,7 +682,7 @@ def parse_binary_c_version_info(version_info_string: str) -> dict: ########################## # Nucleosynthesis sources: # Split off - nucsyn_sources = set([el for el in cleaned if el.startswith("Nucleosynthesis")]) + nucsyn_sources = {el for el in cleaned if el.startswith("Nucleosynthesis")} cleaned = cleaned - nucsyn_sources # Fill dict @@ -753,13 +764,13 @@ def output_lines(output: str) -> list: if output: return output.splitlines() - else: - return [] + return [] def example_parse_output(output: str, selected_header: str) -> dict: """ - Function that parses output of binary_c. This version serves as an example and is quite detailed. Custom functions can be easier: + Function that parses output of binary_c. This version serves as an example and is quite + detailed. Custom functions can be easier: This function works in two cases: if the caught line contains output like 'example_header time=12.32 mass=0.94 ..' @@ -776,7 +787,8 @@ def example_parse_output(output: str, selected_header: str) -> dict: Args: output: binary_c output string - selected_header: string header of the output (the start of the line that you want to process) + selected_header: string header of the output (the start of the line that you want to + process) Returns: dictionary containing parameters as keys and lists for the values @@ -866,10 +878,12 @@ def get_defaults(filter_values: bool = False) -> dict: def get_arg_keys() -> list: """ - Function that return the list of possible keys to give in the arg string. This function calls get_defaults() + Function that return the list of possible keys to give in the arg string. + This function calls get_defaults() Returns: - list of all the parameters that binary_c accepts (and has default values for, since we call get_defaults()) + list of all the parameters that binary_c accepts (and has default values for, since + we call get_defaults()) """ return list(get_defaults().keys()) @@ -903,7 +917,8 @@ def create_arg_string( arg_dict: dict, sort: bool = False, filter_values: bool = False ) -> str: """ - Function that creates the arg string for binary_c. Takes a dictionary containing the arguments and writes them to a string + Function that creates the arg string for binary_c. Takes a dictionary containing the arguments + and writes them to a string This string is missing the 'binary_c ' at the start. Args: @@ -957,12 +972,15 @@ def get_help( - TODO: consider not returning None, but return empty dict Args: - param_name: name of the parameter that you want info from. Will get checked whether its a valid parameter name + param_name: name of the parameter that you want info from. Will get checked whether its a + valid parameter name print_help: (optional, default = True) whether to print out the help information - fail_silently: (optional, default = False) Whether to print the errors raised if the parameter isn't valid + fail_silently: (optional, default = False) Whether to print the errors raised if the + parameter isn't valid Returns: - Dictionary containing the help info. This dictionary contains 'parameter_name', 'parameter_value_input_type', 'description', optionally 'macros' + Dictionary containing the help info. This dictionary contains 'parameter_name', + 'parameter_value_input_type', 'description', optionally 'macros' """ available_arg_keys = get_arg_keys() @@ -1240,23 +1258,29 @@ def make_build_text() -> str: git_branch = version_info["miscellaneous"]["git_branch"] build_datetime = version_info["miscellaneous"]["build"] - info_string = "This information was obtained by the following binary_c build: \n\t**binary_c git branch**: {}\t**binary_c git revision**: {}\t**Built on**: {}".format( + info_string = """ +This information was obtained by the following binary_c build: +\t**binary_c git branch**: {}\t**binary_c git revision**: {}\t**Built on**: {} +""".format( git_branch, git_revision, build_datetime ) - return info_string + return info_string.strip() def write_binary_c_parameter_descriptions_to_rst_file(output_file: str) -> None: """ - Function that calls the get_help_super() to get the help text/descriptions for all the parameters available in that build. + Function that calls the get_help_super() to get the help text/descriptions for all the + parameters available in that build. Writes the results to a .rst file that can be included in the docs. Tasks: - - TODO: add the specific version git branch, git build, git commit, and binary_c version to this document + - TODO: add the specific version git branch, git build, git commit, and binary_c version to + this document Args: - output_file: name of the output .rst faile containing the ReStructuredText formatted output of all the binary_c parameters. + output_file: name of the output .rst faile containing the ReStructuredText formatted output + of all the binary_c parameters. """ # Get the whole arguments dictionary @@ -1372,7 +1396,8 @@ def inspect_dict( ) -> dict: """ Function to (recursively) inspect a (nested) dictionary. - The object that is returned is a dictionary containing the key of the input_dict, but as value it will return the type of what the value would be in the input_dict + The object that is returned is a dictionary containing the key of the input_dict, but as value + it will return the type of what the value would be in the input_dict In this way we inspect the structure of these dictionaries, rather than the exact contents. @@ -1382,7 +1407,8 @@ def inspect_dict( indent: (optional, default = 0) indent of the first output Returns: - Dictionary that has the same structure as the input_dict, but as values it has the type(input_dict[key]) (except if the value is a dict) + Dictionary that has the same structure as the input_dict, but as values it has the + type(input_dict[key]) (except if the value is a dict) """ structure_dict = {} @@ -1713,8 +1739,9 @@ class BinaryCEncoder(json.JSONEncoder): pass else: return str_repr + # Let the base class default method raise the TypeError - return JSONEncoder.default(self, o) + return json.JSONEncoder.default(self, o) def binaryc_json_serializer(obj: Any) -> Any: @@ -1731,12 +1758,9 @@ def binaryc_json_serializer(obj: Any) -> Any: Either string representation of object if the object is a function, or the object itself """ - if inspect.isfunction(obj): + if inspect.isfunction(obj) or isinstance(obj, py_rinterpolate.Rinterpolate): return str(obj) - elif isinstance(obj, py_rinterpolate.Rinterpolate): - return str(obj) - else: - return obj + return obj def handle_ensemble_string_to_json(raw_output): diff --git a/binarycpython/utils/grid.py b/binarycpython/utils/grid.py index 938b0ba58ac5cc20927a27e63b15681f66a0d89b..53f9f66c1c47789cf73deb04d30153758c9a6611 100644 --- a/binarycpython/utils/grid.py +++ b/binarycpython/utils/grid.py @@ -36,11 +36,10 @@ import datetime import argparse import importlib.util import multiprocessing +from typing import Union, Any import setproctitle +import py_rinterpolate -from typing import Union, Any -from pathos.helpers import mp as pathos_multiprocess -from pathos.pools import _ProcessPool as Pool from binarycpython.utils.grid_options_defaults import ( grid_options_defaults_dict, @@ -65,12 +64,8 @@ from binarycpython.utils.functions import ( update_dicts, extract_ensemble_json_from_string, get_moe_distefano_dataset, - get_size, - convert_bytes, ) -import py_rinterpolate - # from binarycpython.utils.hpc_functions import ( # get_condor_version, # get_slurm_version, @@ -83,13 +78,7 @@ from binarycpython.utils.distribution_functions import ( Moecache, LOG_LN_CONVERTER, fill_data, - Moe_de_Stefano_2017_pdf, get_max_multiplicity, - distribution_constants, -) - -from binarycpython.utils.spacing_functions import ( - const, ) from binarycpython import _binary_c_bindings diff --git a/binarycpython/utils/grid_options_defaults.py b/binarycpython/utils/grid_options_defaults.py index 49f5c0b28146955e483e1299cd6dfc2c6bee0d5a..ec2f3f4962bfbe73f4187b68092a160318777d4f 100644 --- a/binarycpython/utils/grid_options_defaults.py +++ b/binarycpython/utils/grid_options_defaults.py @@ -18,6 +18,7 @@ All the options starting with _ should not be changed by the user except when yo import os from binarycpython.utils.custom_logging_functions import temp_dir +from binarycpython.utils.functions import return_binary_c_version_info _MS_VERBOSITY_LEVEL = 5 _MS_VERBOSITY_INTERPOLATOR_LEVEL = 6 @@ -523,7 +524,7 @@ moe_distefano_default_options = { "ecc": [0.0, 0.99], }, # minimum stellar mass - "Mmin": 0.07, + "Mmin": float(return_binary_c_version_info(parsed=True)['macros']['BINARY_C_MINIMUM_STELLAR_MASS']), # We take the value that binary_c has set as the default # multiplicity model (as a function of log10M1) #