Skip to content
Snippets Groups Projects
Commit 77cef2b1 authored by David Hendriks's avatar David Hendriks
Browse files

made the parse output a bit more functional

parent 64578be9
No related branches found
No related tags found
No related merge requests found
...@@ -122,7 +122,7 @@ def from_binary_c_config(config_file, flag): ...@@ -122,7 +122,7 @@ def from_binary_c_config(config_file, flag):
return res return res
def return_compilation_dict(): def return_compilation_dict(verbose=False):
""" """
Function to build the compile command for the shared library Function to build the compile command for the shared library
...@@ -206,21 +206,23 @@ def return_compilation_dict(): ...@@ -206,21 +206,23 @@ def return_compilation_dict():
] ]
libs = "{} {}".format(" ".join(library_paths), " ".join(non_library_paths)) libs = "{} {}".format(" ".join(library_paths), " ".join(non_library_paths))
print(
"Building shared library for custom logging with (binary_c.h) at {} on {}\n".format( if verbose:
BINARY_C_SRC_DIR, socket.gethostname() print(
"Building shared library for custom logging with (binary_c.h) at {} on {}\n".format(
BINARY_C_SRC_DIR, socket.gethostname()
)
) )
) print(
print( "With options:\n\tcc = {cc}\n\tccflags = {ccflags}\n\tld = {ld}\n\tlibs = {libs}\n\tinc = {inc}\n\n".format(
"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
cc=cc, ccflags=ccflags, ld=ld, libs=libs, inc=inc )
) )
)
return {"cc": cc, "ld": ld, "ccflags": ccflags, "libs": libs, "inc": inc} return {"cc": cc, "ld": ld, "ccflags": ccflags, "libs": libs, "inc": inc}
def compile_shared_lib(code, sourcefile_name, outfile_name): 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. Function to write the custom logging code to a file and then compile it.
""" """
...@@ -245,11 +247,13 @@ def compile_shared_lib(code, sourcefile_name, outfile_name): ...@@ -245,11 +247,13 @@ def compile_shared_lib(code, sourcefile_name, outfile_name):
command = " ".join(command.split()) command = " ".join(command.split())
# Execute compilation # Execute compilation
print("Executing following command:\n{command}".format(command=command)) if verbose:
print("Executing following command:\n{command}".format(command=command))
res = subprocess.check_output("{command}".format(command=command), shell=True) res = subprocess.check_output("{command}".format(command=command), shell=True)
if res: if verbose:
print("Output of compilation command:\n{}".format(res)) if res:
print("Output of compilation command:\n{}".format(res))
def temp_custom_logging_dir(): def temp_custom_logging_dir():
......
...@@ -136,16 +136,20 @@ def run_system_with_log(**kwargs): ...@@ -136,16 +136,20 @@ def run_system_with_log(**kwargs):
def parse_output(output, selected_header): def parse_output(output, selected_header):
""" """
Function that parses output of binaryc when it is construction like this: Function that parses output of binary_c:
DAVID_SINGLE_ANALYSIS t=0 mass=20
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. You can give a 'selected_header' to catch any line that starts with that.
Then the values will be put into a dictionary. Then the values will be put into a dictionary.
TODO: Think about exporting to numpy array or pandas
TODO: Think about exporting to numpy array or pandas instead of a defaultdict
""" """
value_dicts = []
val_lists = [] value_dicts = []
val_lists = []
# split output on newlines # split output on newlines
for i, line in enumerate(output.split("\n")): for i, line in enumerate(output.split("\n")):
...@@ -155,17 +159,25 @@ def parse_output(output, selected_header): ...@@ -155,17 +159,25 @@ def parse_output(output, selected_header):
# Select parts # Select parts
header = split_line[0] header = split_line[0]
value_array = split_line[1:] values_list = split_line[1:]
# print(values_list)
# Catch line starting with selected header # Catch line starting with selected header
if header == selected_header: if header == selected_header:
# print(value_array) # Check if the line contains '=' symbols:
# Make a dict
value_dict = {} value_dict = {}
for el in value_array: if all('=' in el for el in values_list):
key, val = el.split("=") for el in values_list:
value_dict[key] = val key, val = el.split("=")
value_dicts.append(value_dict) 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: if len(value_dicts) == 0:
print( print(
......
...@@ -20,7 +20,6 @@ Use these as inspiration/base. ...@@ -20,7 +20,6 @@ Use these as inspiration/base.
def run_example_binary(): def run_example_binary():
""" """
Function to run a binary system. Very basic approach which directly adresses the run_binary(..) python-c wrapper function. Function to run a binary system. Very basic approach which directly adresses the run_binary(..) python-c wrapper function.
""" """
m1 = 15.0 # Msun m1 = 15.0 # Msun
...@@ -46,7 +45,6 @@ def run_example_binary(): ...@@ -46,7 +45,6 @@ def run_example_binary():
output = binary_c.run_binary(argstring) output = binary_c.run_binary(argstring)
print(output) print(output)
# run_example_binary() # run_example_binary()
...@@ -60,6 +58,8 @@ def run_example_binary_with_run_system(): ...@@ -60,6 +58,8 @@ def run_example_binary_with_run_system():
run_system: mostly just makes passing arguments to the function easier. It also loads all the necessary defaults in the background run_system: mostly just makes passing arguments to the function easier. It also loads all the necessary defaults in the background
parse_output: Takes the raw output of binary_c and selects those lines that start with the given header. parse_output: Takes the raw output of binary_c and selects those lines that start with the given header.
Note, if you dont use the custom_logging functionality binary_c should be configured to have output that starts with that given header Note, if you dont use the custom_logging functionality binary_c should be configured to have output that starts with that given header
The parsing of the output only works correctly if either all of the values are described inline like `mass=<number>' or none of them are.
""" """
import pandas as pd import pandas as pd
...@@ -68,16 +68,31 @@ def run_example_binary_with_run_system(): ...@@ -68,16 +68,31 @@ def run_example_binary_with_run_system():
# Run system. all arguments can be given as optional arguments. # Run system. all arguments can be given as optional arguments.
output = run_system(M_1=10, M_2=20, separation=0, orbital_period=100000000000) output = run_system(M_1=10, M_2=20, separation=0, orbital_period=100000000000)
# print(output)
# Catch results that start with a given header. (Mind that binary_c has to be configured to print them if your not using a custom logging function) # Catch results that start with a given header. (Mind that binary_c has to be configured to print them if your not using a custom logging function)
result_example_header = parse_output(output, "example_header") result_example_header_1 = parse_output(output, selected_header="example_header_1")
result_example_header_2 = parse_output(output, selected_header="example_header_2")
# print(result_example_header_1)
#### Now do whatever you want with it: #### Now do whatever you want with it:
# Put it in numpy arrays # Put it in numpy arrays
# t_res = np.asarray(result_example_header['t'], dtype=np.float64, order='C') # t_res = np.asarray(result_example_header['t'], dtype=np.float64, order='C')
# m_res = np.asarray(result_example_header['mass'], dtype=np.float64, order='C') # m_res = np.asarray(result_example_header['mass'], dtype=np.float64, order='C')
# Or put them into a pandas array
# Cast the data into a dataframe. # Cast the data into a dataframe.
df = pd.DataFrame.from_dict(result_example_header, dtype=np.float64) # This example automatically catches the column names because the binary_c output line is constructed as 'example_header_1 time=<number>..'
df = pd.DataFrame.from_dict(result_example_header_1, dtype=np.float64)
print(df)
# This example has column headers which are numbered, but we can override that with custom headers.
df2 = pd.DataFrame.from_dict(result_example_header_2, dtype=np.float64)
df2.columns=['time', 'mass_1', 'mass_2', 'st1', 'st2', 'sep', 'ecc']
print(df2)
# print(df) # print(df)
# sliced_df = df[df.t < 1000] # Cut off late parts of evolution # sliced_df = df[df.t < 1000] # Cut off late parts of evolution
...@@ -85,8 +100,7 @@ def run_example_binary_with_run_system(): ...@@ -85,8 +100,7 @@ def run_example_binary_with_run_system():
# Some routine to plot. # Some routine to plot.
# run_example_binary_with_run_system() run_example_binary_with_run_system()
def run_example_binary_with_custom_logging(): def run_example_binary_with_custom_logging():
""" """
...@@ -166,4 +180,4 @@ def run_example_binary_with_writing_logfile(): ...@@ -166,4 +180,4 @@ def run_example_binary_with_writing_logfile():
# Some routine to plot. # Some routine to plot.
# run_example_binary_with_writing_logfile() # run_example_binary_with_writing_logfile()
\ No newline at end of file
# from distutils.core import setup, Extension from distutils.core import setup, Extension
# from setuptools import find_packages # from setuptools import find_packages
from setuptools import setup, find_packages, Extension # from setuptools import setup, find_packages, Extension
import os import os
import subprocess import subprocess
import re import re
...@@ -57,11 +57,37 @@ API_h = os.environ["BINARY_C"] + "/src/API/binary_c_API.h" ...@@ -57,11 +57,37 @@ API_h = os.environ["BINARY_C"] + "/src/API/binary_c_API.h"
binary_c_define_macros.extend([("BINARY_C_API_H", API_h)]) binary_c_define_macros.extend([("BINARY_C_API_H", API_h)])
binary_c_python_api_module = Extension(
"binary_c",
["src/binary_c_python.c"],
include_dirs=[
os.environ["BINARY_C"] + "/src",
os.environ["BINARY_C"] + "/src/API",
"include",
]
+ binary_c_incdirs,
libraries=["binary_c"] + binary_c_libs + ["binary_c_api"],
library_dirs=[
os.environ["BINARY_C"] + "/src",
"./",
os.path.join(CWD, "lib/"),
]
+ binary_c_libdirs,
runtime_library_dirs=[
os.environ["BINARY_C"] + "/src",
"./",
os.path.join(CWD, "lib/"),
]
+ binary_c_libdirs,
define_macros=[] + binary_c_define_macros,
extra_objects=[],
extra_compile_args=[],
)
def readme(): def readme():
with open('README.md') as f: with open('README.md') as f:
return f.read() return f.read()
setup( setup(
name="binary_c", name="binary_c",
version="1.0", version="1.0",
...@@ -72,31 +98,6 @@ setup( ...@@ -72,31 +98,6 @@ setup(
url="https://gitlab.eps.surrey.ac.uk/ri0005/binary_c-python", url="https://gitlab.eps.surrey.ac.uk/ri0005/binary_c-python",
license="", license="",
ext_modules=[ ext_modules=[
Extension( binary_c_python_api_module
"binary_c",
["src/binary_c_python.c"],
include_dirs=[
os.environ["BINARY_C"] + "/src",
os.environ["BINARY_C"] + "/src/API",
"include",
]
+ binary_c_incdirs,
libraries=["binary_c"] + binary_c_libs + ["binary_c_api"],
library_dirs=[
os.environ["BINARY_C"] + "/src",
"./",
os.path.join(CWD, "lib/"),
]
+ binary_c_libdirs,
runtime_library_dirs=[
os.environ["BINARY_C"] + "/src",
"./",
os.path.join(CWD, "lib/"),
]
+ binary_c_libdirs,
define_macros=[] + binary_c_define_macros,
extra_objects=[],
extra_compile_args=[],
)
], # binary_c must be loaded ], # binary_c must be loaded
) )
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment