from collections import defaultdict import binary_c from binaryc_python_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.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.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.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.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.run_binary_with_log(arg_string) return output def parse_output(output, selected_header): """ Function that parses output of binaryc when it is construction like this: DAVID_SINGLE_ANALYSIS t=0 mass=20 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 """ 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] value_array = split_line[1:] # Catch line starting with selected header if header==selected_header: # print(value_array) # Make a dict value_dict = {} for el in value_array: key, val = el.split('=') value_dict[key] = 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