diff --git a/binarycpython/utils/.ipynb_checkpoints/custom_logging_functions-checkpoint.py b/binarycpython/utils/.ipynb_checkpoints/custom_logging_functions-checkpoint.py deleted file mode 100644 index cd37988bc1f86ab8cfb1516389c2aa5f02bf0fb0..0000000000000000000000000000000000000000 --- a/binarycpython/utils/.ipynb_checkpoints/custom_logging_functions-checkpoint.py +++ /dev/null @@ -1,302 +0,0 @@ -import os -import textwrap -import subprocess -import socket -import tempfile -import ctypes - -def autogen_C_logging_code(logging_dict): - """ - Function that autogenerates PRINTF statements for binaryc. intput is a dictionary where the key is the header of that logging line and items which are lists of parameters\ - that will be put in that logging line - - Example:: - - {'MY_STELLAR_DATA': - [ - 'model.time', - 'star[0].mass', - 'model.probability', - 'model.dt' - ] - } - """ - - # Check if the input is of the correct form - if not type(logging_dict) == dict: - print("Error: please use a dictionary as input") - return None - - code = "" - # Loop over dict keys - for key in logging_dict: - logging_dict_entry = logging_dict[key] - - # Check if item is of correct type: - if type(logging_dict_entry) == list: - - # Construct print statement - code += 'Printf("{}'.format(key) - code += " {}".format("%g " * len(logging_dict_entry)) - code = code.strip() - code += '\\n"' - - # Add format keys - for param in logging_dict_entry: - code += ",((double)stardata->{})".format(param) - code += ");\n" - - else: - print( - "Error: please use a list for the list of parameters that you want to have logged" - ) - code = code.strip() - # print("MADE AUTO CODE\n\n{}\n\n{}\n\n{}\n".format('*'*60, repr(code), '*'*60)) - - return code - - -#################################################################################### -def binary_c_log_code(code): - """ - Function to construct the code to construct the custom logging function - """ - custom_logging_function_string = """\ -#pragma push_macro(\"MAX\") -#pragma push_macro(\"MIN\") -#undef MAX -#undef MIN -#include \"binary_c.h\" - -// add visibility __attribute__ ((visibility ("default"))) to it -void binary_c_API_function custom_output_function(struct stardata_t * stardata); -void binary_c_API_function custom_output_function(struct stardata_t * stardata) -{{ - // struct stardata_t * stardata = (struct stardata_t *)x; - {}; -}} - -#undef MAX -#undef MIN -#pragma pop_macro(\"MIN\") -#pragma pop_macro(\"MAX\")\ - """.format( - code - ) - - # print(repr(textwrap.dedent(custom_logging_function_string))) - return textwrap.dedent(custom_logging_function_string) - - -def binary_c_write_log_code(code, filename): - """ - Function to write the generated logging code to a file - """ - - cwd = os.getcwd() - - filePath = os.path.join(cwd, filename) - if os.path.exists(filePath): - try: - os.remove(filePath) - except: - print("Error while deleting file {}".format(filePath)) - - with open(filePath, "w") as f: - f.write(code) - - -def from_binary_c_config(config_file, flag): - """ - Function to run the binaryc_config command with flags - """ - - res = subprocess.check_output( - "{config_file} {flag}".format(config_file=config_file, flag=flag), - shell=True, - stderr=subprocess.STDOUT, - ) - - # convert and chop off newline - res = res.decode("utf").rstrip() - return res - - -def return_compilation_dict(verbose=False): - """ - Function to build the compile command for the shared library - - inspired by binary_c_inline_config command in perl - - TODO: this function still has some cleaning up to do wrt default values for the compile command - # https://developers.redhat.com/blog/2018/03/21/compiler-and-linker-flags-gcc/ - - - returns: - - string containing the command to build the shared library - """ - - # use binary_c-config to get necessary flags - BINARY_C_DIR = os.getenv("BINARY_C") - if BINARY_C_DIR: - BINARY_C_CONFIG = os.path.join(BINARY_C_DIR, "binary_c-config") - BINARY_C_SRC_DIR = os.path.join(BINARY_C_DIR, "src") - # TODO: build in check to see whether the file exists - else: - raise NameError("Envvar BINARY_C doesnt exist") - return None - - # TODO: make more options for the compiling - cc = from_binary_c_config(BINARY_C_CONFIG, "cc") - - # Check for binary_c - BINARY_C_EXE = os.path.join(BINARY_C_DIR, "binary_c") - if not os.path.isfile(BINARY_C_EXE): - print("We require binary_c executable; have you built binary_c?") - raise NameError("BINARY_C executable doesnt exist") - - # TODO: debug - libbinary_c = "-lbinary_c" - binclibs = from_binary_c_config(BINARY_C_CONFIG, "libs") - libdirs = "{} -L{}".format( - from_binary_c_config(BINARY_C_CONFIG, "libdirs"), BINARY_C_SRC_DIR - ) - bincflags = from_binary_c_config(BINARY_C_CONFIG, "cflags") - bincincdirs = from_binary_c_config(BINARY_C_CONFIG, "incdirs") - - # combine - binclibs = " {} {} {}".format(libdirs, libbinary_c, binclibs) - - # setup defaults: - defaults = { - "cc": "gcc", # default compiler - "ccflags": bincflags, - "ld": "ld", # 'ld': $Config{ld}, # default linker - "debug": 0, - "inc": "{} -I{}".format(bincincdirs, BINARY_C_SRC_DIR), - # inc => ' '.($Config{inc}//' ').' '.$bincincdirs." -I$srcdir ", # include the defaults plus # GSL and binary_c - # 'libname': libname, # libname is usually just binary_c corresponding to libbinary_c.so - "libs": binclibs, - } - - # set values with defaults. TODO: make other input possile. - ld = defaults["ld"] - debug = defaults["debug"] - inc = defaults[ - "inc" - ] # = ($ENV{BINARY_GRID2_INC} // $defaults{inc}).' '.($ENV{BINARY_GRID2_EXTRAINC} // ''); - libs = defaults[ - "libs" - ] # = ($ENV{BINARY_GRID2_LIBS} // $defaults{libs}).' '.($ENV{BINARY_GRID2_EXTRALIBS}//''); - ccflags = defaults[ - "ccflags" - ] # = $ENV{BINARY_GRID2_CCFLAGS} // ($defaults{ccflags}) . ($ENV{BINARY_GRID2_EXTRACCFLAGS} // ''); - - # you must define _SEARCH_H to prevent it being loaded twice - ccflags += " -shared -D_SEARCH_H" - - # remove the visibility=hidden for this compilation - ccflags = ccflags.replace("-fvisibility=hidden", "") - - # ensure library paths to the front of the libs: - libs_content = libs.split(" ") - library_paths = [el for el in libs_content if el.startswith("-L")] - non_library_paths = [ - el for el in libs_content if (not el.startswith("-L") and not el == "") - ] - libs = "{} {}".format(" ".join(library_paths), " ".join(non_library_paths)) - - - if verbose: - print( - "Building shared library for custom logging with (binary_c.h) at {} on {}\n".format( - BINARY_C_SRC_DIR, socket.gethostname() - ) - ) - print( - "With options:\n\tcc = {cc}\n\tccflags = {ccflags}\n\tld = {ld}\n\tlibs = {libs}\n\tinc = {inc}\n\n".format( - cc=cc, ccflags=ccflags, ld=ld, libs=libs, inc=inc - ) - ) - - return {"cc": cc, "ld": ld, "ccflags": ccflags, "libs": libs, "inc": inc} - - -def compile_shared_lib(code, sourcefile_name, outfile_name, verbose=False): - """ - Function to write the custom logging code to a file and then compile it. - """ - - # Write code to file - binary_c_write_log_code(code, sourcefile_name) - - # create compilation command - compilation_dict = return_compilation_dict() - - # Construct full command - command = "{cc} {ccflags} {libs} -o {outfile_name} {sourcefile_name} {inc}".format( - cc=compilation_dict["cc"], - ccflags=compilation_dict["ccflags"], - libs=compilation_dict["libs"], - outfile_name=outfile_name, - sourcefile_name=sourcefile_name, - inc=compilation_dict["inc"], - ) - - # remove extra whitespaces: - command = " ".join(command.split()) - - # Execute compilation - if verbose: - print("Executing following command:\n{command}".format(command=command)) - res = subprocess.check_output("{command}".format(command=command), shell=True) - - if verbose: - if res: - print("Output of compilation command:\n{}".format(res)) - - -def temp_custom_logging_dir(): - """ - Function to return the path the custom logging library shared object and script will be written to. - - Makes use of os.makedirs exist_ok which requires python 3.2+ - """ - - tmp_dir = tempfile.gettempdir() - path = os.path.join(tmp_dir, "binary_c_python") - - # - os.makedirs(path, exist_ok=True) - - return path - - -def create_and_load_logging_function(custom_logging_code): - """ - Function to automatically compile the shared library with the given custom logging code and load it with ctypes - - returns: - memory adress of the custom logging function in a int type. - """ - - # - compile_shared_lib( - custom_logging_code, - sourcefile_name=os.path.join(temp_custom_logging_dir(), "custom_logging.c"), - outfile_name=os.path.join(temp_custom_logging_dir(), "libcustom_logging.so"), - ) - - # Loading library - dll1 = ctypes.CDLL("libgslcblas.so", mode=ctypes.RTLD_GLOBAL) - dll2 = ctypes.CDLL("libgsl.so", mode=ctypes.RTLD_GLOBAL) - dll3 = ctypes.CDLL("libbinary_c.so", mode=ctypes.RTLD_GLOBAL) - libmean = ctypes.CDLL( - os.path.join(temp_custom_logging_dir(), "libcustom_logging.so"), - mode=ctypes.RTLD_GLOBAL, - ) # loads the shared library - - # Get memory adress of function. mimicking a pointer - func_memaddr = ctypes.cast(libmean.custom_output_function, ctypes.c_void_p).value - - return func_memaddr diff --git a/binarycpython/utils/.ipynb_checkpoints/functions-checkpoint.py b/binarycpython/utils/.ipynb_checkpoints/functions-checkpoint.py deleted file mode 100644 index d7fd123a3d6a8063032330791a5f45ee82d5df7c..0000000000000000000000000000000000000000 --- a/binarycpython/utils/.ipynb_checkpoints/functions-checkpoint.py +++ /dev/null @@ -1,233 +0,0 @@ -from collections import defaultdict - -import binary_c_python_api -from binarycpython.utils.custom_logging_functions import ( - create_and_load_logging_function, -) - - -def create_arg_string(arg_dict): - """ - Function that creates the arg string - """ - arg_string = "" - for key in arg_dict.keys(): - arg_string += "{key} {value} ".format(key=key, value=arg_dict[key]) - arg_string = arg_string.strip() - return arg_string - - -def get_defaults(): - """ - Function that calls the binaryc get args function and cast it into a dictionary - All the values are strings - """ - default_output = binary_c_python_api.return_arglines() - default_dict = {} - - for default in default_output.split("\n"): - if not default in ["__ARG_BEGIN", "__ARG_END", ""]: - key, value = default.split(" = ") - - # Filter out NULLS (not compiled anyway) - if not value in ["NULL", "Function"]: - if not value == "": - default_dict[key] = value - return default_dict - - -def get_arg_keys(): - """ - Function that return the list of possible keys to give in the arg string - """ - - return get_defaults().keys() - - -def run_system(**kwargs): - """ - Wrapper to run a system with settings - - This function determines which underlying python-c api function will be called based upon the arguments that are passed via kwargs. - - - if custom_logging_code or custom_logging_dict is included in the kwargs then it will - - if - - """ - - # Load default args - args = get_defaults() - if "custom_logging_code" in kwargs: - # Use kwarg value to override defaults and add new args - for key in kwargs.keys(): - if not key == "custom_logging_code": - args[key] = kwargs[key] - - # Generate library and get memaddr - func_memaddr = create_and_load_logging_function(kwargs["custom_logging_code"]) - - # Construct arguments string and final execution string - arg_string = create_arg_string(args) - arg_string = "binary_c {}".format(arg_string) - - # Run it and get output - output = binary_c_python_api.run_binary_custom_logging(arg_string, func_memaddr) - return output - - elif "log_filename" in kwargs: - # Use kwarg value to override defaults and add new args - for key in kwargs.keys(): - args[key] = kwargs[key] - - # Construct arguments string and final execution string - arg_string = create_arg_string(args) - arg_string = "binary_c {}".format(arg_string) - - # Run it and get output - output = binary_c_python_api.run_binary_with_logfile(arg_string) - return output - - else: # run the plain basic type - - # Use kwarg value to override defaults and add new args - for key in kwargs.keys(): - args[key] = kwargs[key] - - # Construct arguments string and final execution string - arg_string = create_arg_string(args) - arg_string = "binary_c {}".format(arg_string) - - # Run it and get output - output = binary_c_python_api.run_binary(arg_string) - - return output - - -def run_system_with_log(**kwargs): - """ - Wrapper to run a system with settings AND logs the files to a designated place defined by the log_filename parameter. - """ - - # Load default args - args = get_defaults() - # args = {} - - # For example - # physics_args['M_1'] = 20 - # physics_args['separation'] = 0 # 0 = ignored, use period - # physics_args['orbital_period'] = 100000000000 # To make it single - - # Use kwarg value to override defaults and add new args - for key in kwargs.keys(): - args[key] = kwargs[key] - - # Construct arguments string and final execution string - arg_string = create_arg_string(args) - arg_string = "binary_c {}".format(arg_string) - - # print(arg_string) - - # Run it and get output - buffer = "" - output = binary_c_python_api.run_binary_with_log(arg_string) - - return output - - -def parse_output(output, selected_header): - """ - Function that parses output of binary_c: - - This function works in two cases: - if the caught line contains output like 'example_header time=12.32 mass=0.94 ..' - or if the line contains output like 'example_header 12.32 0.94' - - You can give a 'selected_header' to catch any line that starts with that. - Then the values will be put into a dictionary. - - TODO: Think about exporting to numpy array or pandas instead of a defaultdict - """ - - value_dicts = [] - val_lists = [] - - # split output on newlines - for i, line in enumerate(output.split("\n")): - # Skip any blank lines - if not line == "": - split_line = line.split() - - # Select parts - header = split_line[0] - values_list = split_line[1:] - - # print(values_list) - # Catch line starting with selected header - if header == selected_header: - # Check if the line contains '=' symbols: - value_dict = {} - if all('=' in el for el in values_list): - for el in values_list: - key, val = el.split("=") - value_dict[key.strip()] = val.strip() - value_dicts.append(value_dict) - else: - if any('=' in el for el in values_list): - raise ValueError('Caught line contains some = symbols but not all of them do. aborting run') - else: - for i, val in enumerate(values_list): - value_dict[i] = val - value_dicts.append(value_dict) - - if len(value_dicts) == 0: - print( - "Sorry, didnt find any line matching your header {}".format(selected_header) - ) - return None - - keys = value_dicts[0].keys() - - # Construct final dict. - final_values_dict = defaultdict(list) - for value_dict in value_dicts: - for key in keys: - final_values_dict[key].append(value_dict[key]) - - return final_values_dict - - - -def load_logfile(logfile): - with open(logfile, 'r') as f: - logfile_data = f.readlines() - - time_list = [] - m1_list = [] - m2_list = [] - k1_list = [] - k2_list = [] - sep_list = [] - ecc_list = [] - rel_r1_list = [] - rel_r2_list = [] - event_list = [] - - random_seed = logfile_data[0].split()[-2] - random_count = logfile_data[0].split()[-1] - probability = logfile_data[-1].split() - - for line in logfile_data[1:-1]: - split_line = line.split() - - time_list.append(split_line[0]) - m1_list.append(split_line[1]) - m2_list.append(split_line[2]) - k1_list.append(split_line[3]) - k2_list.append(split_line[4]) - sep_list.append(split_line[5]) - ecc_list.append(split_line[6]) - rel_r1_list.append(split_line[7]) - rel_r2_list.append(split_line[8]) - event_list.append(' '.join(split_line[9:])) - - print(event_list) \ No newline at end of file