"git@gitlab.surrey.ac.uk:ri0005/binary_c-python.git" did not exist on "90d656ecb430ffcb223b7e5d23d713d6563be2cd"
Newer
Older
import copy
import json
David Hendriks
committed
import os
import h5py
David Hendriks
committed
import tempfile
David Hendriks
committed
import numpy as np
David Hendriks
committed
import binary_c_python_api
David Hendriks
committed
David Hendriks
committed
def remove_file(file, verbose=0):
"""
Function to remove files but with verbosity
"""
if os.path.exists(file):
try:
if verbose > 0:
print("Removed {}".format(file))
os.remove(file)
# TODO: Put correct exception here.
except:
print("Error while deleting file {}".format(file))
raise FileNotFoundError
David Hendriks
committed
def temp_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
David Hendriks
committed
def output_lines(output):
"""
Function that outputs the lines that were recieved from the binary_c run.
"""
return output.splitlines()
David Hendriks
committed
def parse_binary_c_version_info(version_info_string):
version_info_dict = {}
for el in version_info_string.splitlines():
el = el.strip()
if el == "":
David Hendriks
committed
continue
if " is " in el:
David Hendriks
committed
split = el.split(" is ")
version_info_dict[split[0].strip()] = split[1].strip()
else:
if el.startswith("Binary_c/nucsyn"):
version_info_dict["intro"] = el
elif el.startswith("Email"):
emails = el.split("Email ")[1].split(",")
David Hendriks
committed
cleaned_emails = [email.strip() for email in emails]
version_info_dict["emails"] = cleaned_emails
elif el.startswith("DTlimit"):
split = el.split(" : ")
version_info_dict[split[0]] = ": ".join(split[1:])
elif el.startswith("Version"):
David Hendriks
committed
split = el.split("Version ")
version_number = split[1]
version_info_dict["version_number"] = version_number
David Hendriks
committed
elif el.startswith("git URL"):
split = el.split("git URL ")
git_url = split[1]
version_info_dict["git_url"] = git_url
David Hendriks
committed
elif el.startswith("Build: "):
split = el.split("Build: ")
David Hendriks
committed
build = split[1]
version_info_dict["build"] = build
David Hendriks
committed
elif el.startswith("Compiled for "):
split = el.split("Compiled for ")
David Hendriks
committed
compiled_for = split[1]
version_info_dict["compiled_for"] = compiled_for
David Hendriks
committed
elif el.startswith("Stack limit "):
split = el.split("Stack limit ")
David Hendriks
committed
stack_limit = split[1]
version_info_dict["stack_limit"] = stack_limit
elif el.startswith("SVN URL "):
split = el.split("SVN URL ")
David Hendriks
committed
svn_url = split[1]
version_info_dict["svn_url"] = svn_url
elif el.startswith("git branch "):
split = el.split("git branch ")
David Hendriks
committed
git_branch = split[1]
version_info_dict["git_branch"] = git_branch
elif el.startswith("_SC_CLK_TCK"):
split = el.split(" = ")
David Hendriks
committed
_SC_CLK_TCK = split[1]
version_info_dict["_SC_CLK_TCK"] = _SC_CLK_TCK
elif el.startswith("Random number mean "):
split = el.split("Random number mean ")
David Hendriks
committed
random_number_mean = split[1]
version_info_dict["Random number mean"] = random_number_mean
elif el.startswith("SVN revision "):
split = el.split("SVN revision ")
David Hendriks
committed
svn_revision = split[1]
version_info_dict["svn_revision"] = svn_revision
elif el.startswith("Size of :"):
split = el.split("Size of :")
David Hendriks
committed
data_type_sizes = split[1]
version_info_dict["data_type_sizes"] = data_type_sizes
elif el.startswith("git revision "):
split = el.split("git revision ")
David Hendriks
committed
git_revision = split[1]
version_info_dict["git_revision"] = git_revision
elif el.startswith("BINARY_C_PRE_VERSION "):
split = el.split("BINARY_C_PRE_VERSION ")
David Hendriks
committed
binary_c_pre_version = split[1]
version_info_dict["binary_c_pre_version"] = binary_c_pre_version
elif el.startswith("Comenv accretion:"):
split = el.split("Comenv accretion:")
David Hendriks
committed
comenv_accretion = split[1]
version_info_dict["comenv_accretion"] = comenv_accretion
elif el.startswith("Compiled in parameters:"):
split = el.split("Compiled in parameters:")
David Hendriks
committed
compiled_in_parameters = split[1]
version_info_dict["compiled_in_parameters"] = compiled_in_parameters
elif el.startswith("__short__ is"):
split = el.split("__short__ is")
David Hendriks
committed
short_type = split[1]
version_info_dict["short_type"] = short_type
David Hendriks
committed
else:
print("Still found unmatched items!:\n{}".format(repr(el)))
return version_info_dict
David Hendriks
committed
def create_hdf5(data_dir, name):
David Hendriks
committed
"""
Function to create an hdf5 file from the contents of a directory:
- settings file is selected by checking on files ending on settings
- data files are selected by checking on files ending with .dat
David Hendriks
committed
TODO: fix missing settingsfiles
"""
David Hendriks
committed
# Make HDF5:
David Hendriks
committed
# Create the file
hdf5_filename = os.path.join(data_dir, "{}".format(name))
David Hendriks
committed
print("Creating {}".format(hdf5_filename))
David Hendriks
committed
# Get content of data_dir
content_data_dir = os.listdir(data_dir)
David Hendriks
committed
David Hendriks
committed
# Settings
if any([file.endswith("_settings.json") for file in content_data_dir]):
print("Adding settings to HDF5 file")
settings_file = os.path.join(
data_dir,
[file for file in content_data_dir if file.endswith("_settings.json")][0],
)
David Hendriks
committed
with open(settings_file, "r") as settings_file:
settings_json = json.load(settings_file)
David Hendriks
committed
David Hendriks
committed
# Create settings group
settings_grp = f.create_group("settings")
David Hendriks
committed
David Hendriks
committed
# Write version_string to settings_group
settings_grp.create_dataset("used_settings", data=json.dumps(settings_json))
David Hendriks
committed
David Hendriks
committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# Get data files
data_files = [el for el in content_data_dir if el.endswith(".dat")]
if data_files:
print("Adding data to HDF5 file")
# Create the data group
data_grp = f.create_group("data")
# Write the data to the file:
# Make sure:
for data_file in data_files:
# filename stuff
filename = data_file
full_path = os.path.join(data_dir, filename)
base_name = os.path.splitext(os.path.basename(filename))[0]
# Get header info
header_name = "{base_name}_header".format(base_name=base_name)
data_headers = np.genfromtxt(full_path, dtype="str", max_rows=1)
data_headers = np.char.encode(data_headers)
data_grp.create_dataset(header_name, data=data_headers)
# Add data
data = np.loadtxt(full_path, skiprows=1)
data_grp.create_dataset(base_name, data=data)
f.close()
David Hendriks
committed
David Hendriks
committed
def get_help_super(print_help=False, return_dict=True, fail_silently=True):
David Hendriks
committed
"""
Function that first runs get_help_all, and then per argument also run the help function to get as much information as possible.
"""
David Hendriks
committed
# Get help_all information
David Hendriks
committed
help_all_dict = get_help_all(print_help=False, return_dict=True)
help_all_super_dict = help_all_dict.copy()
David Hendriks
committed
# Loop over all sections and stuff
David Hendriks
committed
for section_name in help_all_dict.keys():
section = help_all_dict[section_name]
for parameter_name in section["parameters"].keys():
parameter = section["parameters"][parameter_name]
David Hendriks
committed
David Hendriks
committed
# Get detailed help info
parameter_name,
print_help=False,
return_dict=True,
fail_silently=fail_silently,
David Hendriks
committed
David Hendriks
committed
if detailed_help:
# check whether the descriptions of help_all and detailed help are the same
if not fail_silently:
if not parameter["description"] == detailed_help["description"]:
David Hendriks
committed
print(json.dumps(parameter, indent=4))
## put values into help all super dict
# input type
parameter["parameter_value_input_type"] = detailed_help[
"parameter_value_input_type"
]
David Hendriks
committed
David Hendriks
committed
# default
parameter["default"] = detailed_help["default"]
David Hendriks
committed
David Hendriks
committed
# macros
if "macros" in detailed_help.keys():
David Hendriks
committed
parameter["macros"] = detailed_help["macros"]
David Hendriks
committed
if print_help:
David Hendriks
committed
# TODO: make a pretty print
David Hendriks
committed
print(json.dumps(help_all_super_dict, indent=4))
pass
if return_dict:
David Hendriks
committed
return help_all_super_dict
David Hendriks
committed
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
def get_help_all(print_help=True, return_dict=False):
"""
Function that reads out the output of the help_all api call to binary_c
prints all the parameters and their descriptions.
return_dict: returns a dictionary
"""
# Call function
help_all = binary_c_python_api.return_help_all()
# String manipulation
split = help_all.split(
"############################################################\n"
)
cleaned = [el for el in split if not el == "\n"]
section_nums = [i for i in range(len(cleaned)) if cleaned[i].startswith("#####")]
# Create dicts
help_all_dict = {}
# Select the section name and the contents of that section. Note, not all sections have content!
for i in range(len(section_nums)):
if not i == len(section_nums) - 1:
params = cleaned[section_nums[i] + 1 : section_nums[i + 1]]
else:
params = cleaned[section_nums[i] + 1 : len(cleaned)]
section_name = (
cleaned[section_nums[i]]
.lstrip("#####")
.strip()
.replace("Section ", "")
.lower()
)
#
params_dict = {}
if params:
# Clean it, replace in-text newlines with a space and then split on newlines.
split_params = params[0].strip().replace("\n ", " ").split("\n")
# Process params and descriptions per section
for el in split_params:
split_param_info = el.split(" : ")
if not len(split_param_info) == 3:
# there are ocassions where the semicolon is used in the description text itself.
if len(split_param_info) == 4:
split_param_info = [
split_param_info[0],
": ".join([split_param_info[1], split_param_info[2]]),
split_param_info[3],
]
# other occassions?
# Put the information in a dict
param_name = split_param_info[0]
param_description = split_param_info[1]
rest = split_param_info[2]
params_dict[param_name] = {
"param_name": param_name,
"description": param_description,
"rest": rest,
}
# make section_dict
section_dict = {
"section_name": section_name,
"parameters": params_dict.copy(),
}
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# Put in the total dict
help_all_dict[section_name] = section_dict.copy()
# Print things
if print_help:
for section in sorted(help_all_dict.keys()):
print(
"##################\n###### Section {}\n##################".format(
section
)
)
section_dict = help_all_dict[section]
for param_name in sorted(section_dict["parameters"].keys()):
param = section_dict["parameters"][param_name]
print(
"\n{}:\n\t{}: {}".format(
param["param_name"], param["description"], param["rest"]
)
)
# Loop over all the parameters an call the help() function on it. Takes a long time but this is for testing
# for section in help_all_dict.keys():
# section_dict = help_all_dict[section]
# for param in section_dict['parameters'].keys():
# get_help(param)
if return_dict:
return help_all_dict
else:
return None
def create_arg_string(arg_dict, sort=False, filter_values=False):
"""
Function that creates the arg string
Options:
sort: sort the order of the keys
filter_values: filters the input dict on keys that have NULL or `function` as value
#
keys = sorted(arg_dict.keys()) if sort else arg_dict.keys()
#
for key in keys:
# Filter out NULLS (not compiled anyway)
if filter_values:
if not arg_dict[key] in ["NULL", "Function"]:
arg_string += "{key} {value} ".format(key=key, value=arg_dict[key])
else:
arg_string += "{key} {value} ".format(key=key, value=arg_dict[key])
arg_string = arg_string.strip()
return arg_string
def get_defaults(filter_values=False):
"""
Function that calls the binaryc get args function and cast it into a dictionary
All the values are strings
filter_values: whether to filter out NULL and Function defaults.
David Hendriks
committed
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 filter_values:
if not value in ["NULL", "Function"]:
if not value == "":
default_dict[key] = value
# On default, just show everything
else:
default_dict[key] = value
return default_dict
David Hendriks
committed
def get_arg_keys():
"""
Function that return the list of possible keys to give in the arg string
"""
return get_defaults().keys()
def get_help(param_name="", print_help=True, return_dict=False, fail_silently=False):
"""
Function that returns the help info for a given parameter.
Binary_c will output things in the following order;
- Did you mean?
- binary_c help for variable
- default
- available macros
This function reads out that structure and catches the different components of this output
Will print a dict
return_dict: wether to return the help info dictionary
available_arg_keys = get_arg_keys()
if not param_name:
print(
"Please set the param_name to any of the following:\n {}".format(
sorted(available_arg_keys)
)
)
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
return None
else:
if param_name in available_arg_keys:
help_info = binary_c_python_api.return_help(param_name)
cleaned = [el for el in help_info.split("\n") if not el == ""]
# Get line numbers
did_you_mean_nr = [
i for i, el in enumerate(cleaned) if el.startswith("Did you mean")
]
parameter_line_nr = [
i for i, el in enumerate(cleaned) if el.startswith("binary_c help")
]
default_line_nr = [
i for i, el in enumerate(cleaned) if el.startswith("Default")
]
macros_line_nr = [
i for i, el in enumerate(cleaned) if el.startswith("Available")
]
help_info_dict = {}
# Get alternatives
if did_you_mean_nr:
alternatives = cleaned[did_you_mean_nr[0] + 1 : parameter_line_nr[0]]
alternatives = [el.strip() for el in alternatives]
help_info_dict["alternatives"] = alternatives
# Information about the parameter
parameter_line = cleaned[parameter_line_nr[0]]
parameter_name = parameter_line.split(":")[1].strip().split(" ")[0]
parameter_value_input_type = (
" ".join(parameter_line.split(":")[1].strip().split(" ")[1:])
.replace("<", "")
.replace(">", "")
)
help_info_dict["parameter_name"] = parameter_name
help_info_dict["parameter_value_input_type"] = parameter_value_input_type
description_line = " ".join(
cleaned[parameter_line_nr[0] + 1 : default_line_nr[0]]
)
help_info_dict["description"] = description_line
# Default:
default_line = cleaned[default_line_nr[0]]
default_value = default_line.split(":")[-1].strip()
help_info_dict["default"] = default_value
# Get Macros:
if macros_line_nr:
macros = cleaned[macros_line_nr[0] + 1 :]
help_info_dict["macros"] = macros
if print_help:
for key in help_info_dict.keys():
print("{}:\n\t{}".format(key, help_info_dict[key]))
if return_dict:
return help_info_dict
else:
if not fail_silently:
print(
"{} is not a valid parameter name. Please choose from the following parameters:\n\t{}".format(
param_name, list(available_arg_keys)
)
David Hendriks
committed
)
return None
David Hendriks
committed
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 = []
for i, line in enumerate(output.split("\n")):
split_line = line.split()
# Select parts
header = split_line[0]
values_list = split_line[1:]
# Catch line starting with selected header
# Check if the line contains '=' symbols:
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)
)
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])
def load_logfile(logfile):
David Hendriks
committed
"""
Function that parses the generated logfile of binary_c
"""
with open(logfile, "r") as f:
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
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)