diff --git a/TODO.org b/TODO.org deleted file mode 100644 index bc11a5eab720ac8bc222ff1b99b6bc30ee65b5b9..0000000000000000000000000000000000000000 --- a/TODO.org +++ /dev/null @@ -1,168 +0,0 @@ -* Todo list for the binary_c-python -** Logging functionality: -*** Idea -Idea is to be able to give a string via python that will be used in the through the libbinary_c.so so that log_every_timestep.c -The code below is the piece in log_every_timestep that uses it. - - if(stardata->preferences->custom_output_function != NULL) - { - Dprint("calling custom output function %p\n", - stardata->preferences->custom_output_function); - stardata->preferences->custom_output_function(stardata); - } - -So the function should recieve 'stardata' as input. - -We can do that with providing a logging string alltogether, or generate a logging function - -In either way, this should be passed to stardata->preferences->custom_output_function as a pointer to that function - -*** Provide string for logging -In perl this is done in the following way: -**** code to input -And then to use it via - $population->set( - C_logging_code => ' - PRINTF("MY_STELLAR_DATA %g %g %g %g\n", - stardata->model.time, - stardata->star[0].mass, - stardata->model.probability, - stardata->model.dt); - ' - ); -**** code to handle that input -sub binary_c_log_code -{ - my ($code) = @_; - return " -#pragma push_macro(\"MAX\") -#pragma push_macro(\"MIN\") -#undef MAX -#undef MIN -#include \"binary_c.h\" - -void custom_output_function(SV * x); -SV * custom_output_function_pointer(void); - -SV * custom_output_function_pointer() -{ - /* - * use PTR2UV to convert the function pointer - * &custom_output_function to an unsigned int, - * which is then converted to a Perl SV - */ - return (SV*)newSVuv(PTR2UV(&custom_output_function)); -} - -void custom_output_function(SV * x) -{ - struct stardata_t * stardata = (struct stardata_t *)x; - $code; -} -#undef MAX -#undef MIN -#pragma pop_macro(\"MIN\") -#pragma pop_macro(\"MAX\") -"; -} -Or use it via: -*** auto logging -We should also try to be able to have the code autogenerate some logging function via the following: -**** input in perl -$population->set( C_auto_logging => { - 'MY_STELLAR_DATA' => - [ - 'model.time', - 'star[0].mass', - 'model.probability', - 'model.dt' - ] - }); -**** code to handle that input -Which is handled in perl via (see binary_grid2.pm -sub autogen_C_logging_code -{ - # given a hash of arrays of variable names, where the hash - # key is the header, autogenerate PRINTF statements - my ($self) = @_; - my $code = undef; - if(defined $self->{_grid_options}->{C_auto_logging} && - ref $self->{_grid_options}->{C_auto_logging} eq 'HASH' - ) - { - $code = ''; - - foreach my $header (keys %{$self->{_grid_options}->{C_auto_logging}}) - { - if(ref $self->{_grid_options}->{C_auto_logging}->{$header} eq 'ARRAY') - { - $code .= 'PRINTF("'.$header.' '; - foreach my $x (@{$self->{_grid_options}->{C_auto_logging}->{$header}}) - { - $code .= '%g '; - } - $code .= '\n"'; - - foreach my $x (@{$self->{_grid_options}->{C_auto_logging}->{$header}}) - { - $code .= ',((double)stardata->'.$x.')'; - } - $code .= ');' - } - } - } - print "MADE AUTO CODE \n\n************************************************************\n\n$code\n\n************************************************************\n"; - - return $code; -} -*** DONE Make function in python that puts code into c function - CLOSED: [2019-10-31 Thu 11:13] -*** DONE Make function in python that generates c-function from a list of arguments - CLOSED: [2019-10-29 Tue 23:52] -*** DONE Resolve current issue malloc - CLOSED: [2019-11-08 Fri 11:12] -➜ binary_c-python git:(master) ✗ python python_API_test.py -Traceback (most recent call last): - File "python_API_test.py", line 3, in <module> - import binary_c -ImportError: /home/david/projects/binary_c_root/binary_c-python/libbinary_c_api.so: undefined symbol: MALLOC - -I get this error when I am using the master version of binary_c with either branches of the python wrapper.. - -That went very deep haha. alot of memory allocation stuff - -*** DONE Make sure this works with the last major release of binaryc - CLOSED: [2019-11-08 Fri 15:00] -*** DONE Finish testing a simpler case (see other repo) - CLOSED: [2019-11-08 Fri 09:37] -*** DONE Make master master work - CLOSED: [2019-11-08 Fri 15:00] -*** DONE Sync master with david_branch - CLOSED: [2019-11-08 Fri 15:00] -*** DONE make tag of old master branch for future reference - CLOSED: [2019-11-08 Fri 15:00] -*** DONE Implement the autogeneration of the library - CLOSED: [2019-11-08 Fri 15:48] -*** DONE Load all the things with the c-types - CLOSED: [2019-11-08 Fri 18:49] -*** DONE Implement new function for run_binary_with_custom_logging - CLOSED: [2019-11-08 Fri 21:19] -*** DONE Make new c function run_binary_with_custom_logging - CLOSED: [2019-11-08 Fri 21:19] -*** TODO Put in some new tests in the python test api -*** DONE Make sure the sharedlibs get written to the correct directory - CLOSED: [2019-11-10 Sun 00:21] -** General: -*** DONE Get a more reliable way of loading the default values (running a ./tbse echo or something?) - CLOSED: [2019-10-29 Tue 17:44] -*** DONE make routine that reads out all the lines, splits them into pieces and reads out the correct key - CLOSED: [2019-10-29 Tue 17:43] -*** TODO Put header and other source files in a dedicated directory -*** TODO Use sphinx or read the docs for auto generation of documentation -*** TODO Have the compiled files put into a build directory -*** TODO add pythonpath thing to readme -*** TODO make script that will set up binaryc automatically so that this can become an out of the box thing -*** TODO Test the importing of this code from different places -** Population ideas -*** TODO Queuing system and some multiprocessing to run many systems -*** TODO Consider rewriting the work that perl does diff --git a/examples/examples_run_binary.py b/examples/examples_run_binary.py index 47e84f65e33feff3ec44e3b1c1a54675e21b6aff..2bd18c2cb728a5bec53cf2f8efa450b2ef6f45e5 100644 --- a/examples/examples_run_binary.py +++ b/examples/examples_run_binary.py @@ -34,7 +34,7 @@ def run_example_binary(): output = binary_c.run_binary(argstring) print (output) -# run_example_binary() +run_example_binary() def run_example_binary_with_run_system(): """ @@ -71,7 +71,7 @@ def run_example_binary_with_run_system(): # Some routine to plot. -# run_example_binary_with_run_system() +run_example_binary_with_run_system() def run_example_binary_with_custom_logging(): @@ -110,7 +110,7 @@ def run_example_binary_with_custom_logging(): # Do whatever you like with the dataframe. print(df) -# run_example_binary_with_custom_logging() +run_example_binary_with_custom_logging() def run_example_binary_with_writing_logfile(): """ @@ -119,9 +119,10 @@ def run_example_binary_with_writing_logfile(): import pandas as pd import numpy as np + import tempfile # Run system. all arguments can be given as optional arguments. - output = run_system(M_1=10, M_2=20, separation=0, orbital_period=100000000000, log_filename=os.getcwd()+'/test_log.txt') + output = run_system(M_1=10, M_2=20, separation=0, orbital_period=100000000000, log_filename=tempfile.gettempdir()+'/test_log.txt') # 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') @@ -140,4 +141,4 @@ def run_example_binary_with_writing_logfile(): # Some routine to plot. -# run_example_binary_with_writing_logfile() \ No newline at end of file +run_example_binary_with_writing_logfile() \ No newline at end of file diff --git a/testing_examples/__init__.py b/testing_examples/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/testing_examples/example_notebook.ipynb b/testing_examples/example_notebook.ipynb deleted file mode 100644 index f9db89b1350c3f8d1bbbe76e95a65bffd733a9c1..0000000000000000000000000000000000000000 --- a/testing_examples/example_notebook.ipynb +++ /dev/null @@ -1,165 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Example notebook binarypy" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/user/HS128/dh00601/.pyenv/versions/3.6.4/envs/binaryc_py3.6.4/bin/python\n" - ] - } - ], - "source": [ - "import os, sys\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "\n", - "# Append root dir of this project to include functionality\n", - "print(sys.executable)\n", - "sys.path.append(os.path.dirname(os.getcwd()))\n", - "import binary_c\n", - "from utils.defaults import physics_defaults\n", - "from utils.functions import create_arg_string" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "def example_with_loading_default_args():\n", - " \"\"\"\n", - " Example function loading the default physics args for a binary_c system. Got\n", - " it from the binary_grid2 perl module\n", - "\n", - " This function works if binary_c is set to log something every timestep so that we can plot the evolution of a system\n", - " \"\"\"\n", - "\n", - " # Load args\n", - " physics_args = physics_defaults.copy()\n", - "\n", - " # Manually set M_1, M_2, orbital_period and separation values:\n", - " physics_args['M_1'] = 20\n", - " physics_args['M_2'] = 15\n", - " physics_args['separation'] = 0 # 0 = ignored, use period\n", - " physics_args['orbital_period'] = 4530.0\n", - "\n", - " arg_string = create_arg_string(physics_args)\n", - " arg_string = 'binary_c {arg_string}'.format(arg_string=arg_string)\n", - "\n", - " buffer = \"\"\n", - "\n", - " output = binary_c.run_binary(arg_string)\n", - "\n", - " # Make some \n", - " results = {}\n", - " time_arr = []\n", - " mass_arr = []\n", - " mass_2_arr = []\n", - "\n", - " # split output on newlines\n", - " for line in output.split('\\n'):\n", - " # Skip any blank lines\n", - " if not line=='':\n", - " split_line = line.split()\n", - " header = split_line[0]\n", - " value_array = split_line[1:]\n", - "\n", - " # Use parse data here:\n", - " if header=='TESTLOG':\n", - " # Add values to lists\n", - " time_arr.append(float(value_array[0]))\n", - " mass_arr.append(float(value_array[1]))\n", - " mass_2_arr.append(float(value_array[4]))\n", - "\n", - " # Save in results dir\n", - " results['time'] = time_arr\n", - " results['mass'] = mass_arr\n", - " results['mass2'] = mass_2_arr\n", - "\n", - " return results\n" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "results = example_with_loading_default_args()\n", - "df = pd.DataFrame.from_dict(results)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "<Figure size 720x720 with 1 Axes>" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "min_time = 1e-1\n", - "max_time = 3000\n", - "# Plot some stuff\n", - "plt.figure(figsize=[10,10])\n", - "plt.plot(df[(df.time>min_time) & (df.time<max_time)]['time'], df[(df.time>min_time) & (df.time<max_time)]['mass'])\n", - "plt.plot(df[(df.time>min_time) & (df.time<max_time)]['time'], df[(df.time>min_time) & (df.time<max_time)]['mass2'])\n", - "plt.xscale('log')\n", - "plt.ylabel(r'Mass $M_{\\odot}$')\n", - "plt.xlabel('time (MYr)')\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.4" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/testing_examples/full_evolution_with_plot.py b/testing_examples/full_evolution_with_plot.py deleted file mode 100644 index a966e7c3e56b681280d839f38ccfbe9a73dc3a56..0000000000000000000000000000000000000000 --- a/testing_examples/full_evolution_with_plot.py +++ /dev/null @@ -1,69 +0,0 @@ -import os, sys -import matplotlib.pyplot as plt - -# Append root dir of this project to include functionality -sys.path.append(os.path.dirname(os.getcwd())) -import binary_c - -from utils.defaults import physics_defaults -from utils.functions import create_arg_string - -def example_with_loading_default_args(): - """ - Example function loading the default physics args for a binary_c system. Got - it from the binary_grid2 perl module - - This function works if binary_c is set to log something every timestep so that we can plot the evolution of a system - """ - - # Load args - physics_args = physics_defaults.copy() - - # Manually set M_1, M_2, orbital_period and separation values: - physics_args['M_1'] = 20 - physics_args['M_2'] = 15 - physics_args['separation'] = 0 # 0 = ignored, use period - physics_args['orbital_period'] = 4530.0 - - arg_string = create_arg_string(physics_args) - arg_string = f'binary_c {arg_string}' - - buffer = "" - - output = binary_c.run_binary(arg_string) - - # Make some - results = {} - time_arr = [] - mass_arr = [] - mass_2_arr = [] - - # split output on newlines - for line in output.split('\n'): - # Skip any blank lines - if not line=='': - split_line = line.split() - header = split_line[0] - value_array = split_line[1:] - - # Use parse data here: - if header=='TESTLOG': - # Add values to lists - time_arr.append(float(value_array[0])) - mass_arr.append(float(value_array[1])) - mass_2_arr.append(float(value_array[4])) - - # Save in results dir - results['time'] = time_arr - results['mass'] = mass_arr - results['mass2'] = mass_2_arr - - return results - -results = example_with_loading_default_args() - -# Plot some stuff -plt.plot(results['time'], results['mass']) -plt.plot(results['time'], results['mass2']) -plt.xscale('log') -plt.show() diff --git a/testing_examples/run_system_with_custom_logging.py b/testing_examples/run_system_with_custom_logging.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/tests_and_snippets/.ipynb_checkpoints/test_noteboo-checkpoint.ipynb b/tests_and_snippets/.ipynb_checkpoints/test_noteboo-checkpoint.ipynb deleted file mode 100644 index 2fd64429bf421126b7000c94ce0f6fd186fbd01f..0000000000000000000000000000000000000000 --- a/tests_and_snippets/.ipynb_checkpoints/test_noteboo-checkpoint.ipynb +++ /dev/null @@ -1,6 +0,0 @@ -{ - "cells": [], - "metadata": {}, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/tests_and_snippets/snippets/arg_test.py b/tests_and_snippets/snippets/arg_test.py deleted file mode 100644 index 78fced845236be0aeaa9f712617df18595ecea55..0000000000000000000000000000000000000000 --- a/tests_and_snippets/snippets/arg_test.py +++ /dev/null @@ -1,63 +0,0 @@ -import argparse - - -class grid(object): - def __init__(self, name): - self.name = name - self.grid_options = {} - - def load_grid_options(self): - self.grid_options = { - 'test1': 0, - 'test2': 1, - } - - def argparse(self): - """ - This function handles the arg parsing of the grid. - Make sure that every grid_option key/value is included in this, - preferably with an explanation on what that parameter will do - """ - - - parser = argparse.ArgumentParser(description='Arguments for the binary_c python wrapper grid') - - # add arguments here - parser.add_argument('--test1', type=int, help='input for test1') - parser.add_argument('--test2', type=int, help='input for test2') - - # Load the args from the cmdline - args = parser.parse_args() - - # Copy current grid_option set - new_grid_options = self.grid_options.copy() - - # loop over grid_options - for arg in vars(args): - # print ("arg: {arg} value: {value}".format(arg=arg, value=getattr(args, arg))) - - # If an input has been given in the cmdline: override the previous value of grid_options - if getattr(args, arg): - new_grid_options[arg] = getattr(args, arg) - - # Put the new grid options back - self.grid_options = new_grid_options.copy() - -newgrid = grid('test') -newgrid.load_grid_options() -print(newgrid.grid_options) - -newgrid.argparse() -print(newgrid.grid_options) - -# Custom set a single value: -newgrid.grid_options['test2'] = 2 -print(newgrid.grid_options) - -# Custom set multiple values: -newgrid.grid_options.update({ - 'test1':4, - 'test2':-2, - }) -print(newgrid.grid_options) - diff --git a/tests_and_snippets/snippets/d.py b/tests_and_snippets/snippets/d.py deleted file mode 100644 index ea3c6bdf3dcec9316ea339a28a430f4ea8716afd..0000000000000000000000000000000000000000 --- a/tests_and_snippets/snippets/d.py +++ /dev/null @@ -1,25 +0,0 @@ -import multiprocessing -import time - - -def doubler(number): - return number ** 2 - -def count(number): - nr = 0 - for i in range(number): - nr += i - return number - -if __name__ == '__main__': - numbers = range(2, 100000) - pool = multiprocessing.Pool(processes=6) - # print() - - rs = pool.map_async(pool.map(count, numbers), range(len(numbers))) - pool.close() # No more work - while (True): - if (rs.ready()): break - remaining = rs._number_left - print("Waiting for", remaining, "tasks to complete...") - time.sleep(0.5) \ No newline at end of file diff --git a/tests_and_snippets/snippets/mp2.py b/tests_and_snippets/snippets/mp2.py deleted file mode 100644 index a7c9bc0653af00e95ccea144ce2918bf41fdbbf6..0000000000000000000000000000000000000000 --- a/tests_and_snippets/snippets/mp2.py +++ /dev/null @@ -1,17 +0,0 @@ -import time - -def basic_func(x): - if x == 0: - return 'zero' - elif x%2 == 0: - return 'even' - else: - return 'odd' - -starttime = time.time() -for i in range(0,10): - y = i*i - time.sleep(2) - print('{} squared results in a/an {} number'.format(i, basic_func(y))) - -print('That took {} seconds'.format(time.time() - starttime)) \ No newline at end of file diff --git a/tests_and_snippets/snippets/mp3.py b/tests_and_snippets/snippets/mp3.py deleted file mode 100644 index 3e7b748bb44658a1e793b63e677c1a8e8f0ed4ec..0000000000000000000000000000000000000000 --- a/tests_and_snippets/snippets/mp3.py +++ /dev/null @@ -1,28 +0,0 @@ -import time -import multiprocessing - -def basic_func(x): - if x == 0: - return 'zero' - elif x%2 == 0: - return 'even' - else: - return 'odd' - -def multiprocessing_func(x): - y = x*x - time.sleep(2) - print('{} squared results in a/an {} number'.format(x, basic_func(y))) - -if __name__ == '__main__': - starttime = time.time() - processes = [] - for i in range(0,100): - p = multiprocessing.Process(target=multiprocessing_func, args=(i,)) - processes.append(p) - p.start() - - for process in processes: - process.join() - - print('That took {} seconds'.format(time.time() - starttime)) \ No newline at end of file diff --git a/tests_and_snippets/snippets/mp3_pool.py b/tests_and_snippets/snippets/mp3_pool.py deleted file mode 100644 index 9b40efd977f4af9006499cdd597f02e808d39dd5..0000000000000000000000000000000000000000 --- a/tests_and_snippets/snippets/mp3_pool.py +++ /dev/null @@ -1,23 +0,0 @@ -import time -import multiprocessing -# https://medium.com/@urban_institute/using-multiprocessing-to-make-python-code-faster-23ea5ef996ba -def basic_func(x): - if x == 0: - return 'zero' - elif x%2 == 0: - return 'even' - else: - return 'odd' - -def multiprocessing_func(x): - y = x*x - time.sleep(2) - print('{} squared results in a/an {} number'.format(x, basic_func(y))) - -if __name__ == '__main__': - - starttime = time.time() - pool = multiprocessing.Pool() - pool.map(multiprocessing_func, range(0,10)) - pool.close() - print('That took {} seconds'.format(time.time() - starttime)) \ No newline at end of file diff --git a/tests_and_snippets/snippets/multiprocessing_test.py b/tests_and_snippets/snippets/multiprocessing_test.py deleted file mode 100644 index 5c56076fb430a1cfc344113f2d29ba33acac3ed5..0000000000000000000000000000000000000000 --- a/tests_and_snippets/snippets/multiprocessing_test.py +++ /dev/null @@ -1,30 +0,0 @@ -from multiprocessing import Process, Queue -import time -import sys - -def reader_proc(queue): - ## Read from the queue; this will be spawned as a separate Process - while True: - msg = queue.get() # Read from the queue and do nothing - if (msg == 'DONE'): - break - -def writer(count, queue): - ## Write to the queue - for ii in range(0, count): - queue.put(ii) # Write 'count' numbers into the queue - queue.put('DONE') - -if __name__=='__main__': - pqueue = Queue() # writer() writes to pqueue from _this_ process - for count in [10**4, 10**5, 10**6]: - ### reader_proc() reads from pqueue as a separate process - reader_p = Process(target=reader_proc, args=((pqueue),)) - reader_p.daemon = True - reader_p.start() # Launch reader_proc() as a separate python process - - _start = time.time() - writer(count, pqueue) # Send a lot of stuff to reader() - reader_p.join() # Wait for the reader to finish - print("Sending {0} numbers to Queue() took {1} seconds".format(count, - (time.time() - _start))) \ No newline at end of file diff --git a/tests_and_snippets/testing_automatic_log_readout.py b/tests_and_snippets/testing_automatic_log_readout.py deleted file mode 100644 index 5e8f636c5552e64858772186d5226e0dfd570a51..0000000000000000000000000000000000000000 --- a/tests_and_snippets/testing_automatic_log_readout.py +++ /dev/null @@ -1,44 +0,0 @@ -import os, sys, time - -import matplotlib.pyplot as plt -from collections import defaultdict -import numpy as np -import pandas as pd - -# sys.path.append('../') -import binary_c - - -from binaryc_python_utils.functions import create_arg_string, parse_output, run_system - -""" -Script to test some auto reading out. - -todo: make to hdf5 -""" - -start = time.time() -output = run_system(M_1=10, M_2=20, separation=0, orbital_period=100000000000) -result = parse_output(output, 'DAVID_SINGLE_ANALYSIS') -stop = time.time() -print("Took {:.2f}s to run single system".format(stop-start)) -print("The following keys are present in the results:\n{}".format(result.keys())) - -#### Now do whatever you want with it: -#t_res = np.asarray(result['t'], dtype=np.float64, order='C') -#m_res = np.asarray(result['mass'], dtype=np.float64, order='C') - -# Cast the data into a dataframe. -df = pd.DataFrame.from_dict(result, dtype=np.float64) - -sliced_df = df[df.t < 1000] # Cut off late parts of evolution -# print(sliced_df["t"]) - - - - - -plt.plot(sliced_df['omega'], sliced_df['radius']) -plt.xlabel('Time (Myr)') -plt.ylabel('omega (Rsol)') -plt.show() \ No newline at end of file