diff --git a/binaryc_python_utils/custom_logging_functions.py b/binaryc_python_utils/custom_logging_functions.py index 5e95463b7ac5365828570a67bf70aa9556c40a7a..2d82f67b1839ab4d7c23b5b01790c3f1f5c2fbc1 100644 --- a/binaryc_python_utils/custom_logging_functions.py +++ b/binaryc_python_utils/custom_logging_functions.py @@ -3,6 +3,7 @@ import textwrap import subprocess import socket import tempfile +import ctypes # Functions for the automatic logging of stuff def autogen_C_logging_code(logging_dict): @@ -245,4 +246,31 @@ def temp_custom_logging_dir(): # os.makedirs(path, exist_ok=True) - return path \ No newline at end of file + 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/binaryc_python_utils/defaults.py b/binaryc_python_utils/defaults.py deleted file mode 100644 index aba0d28e9bb06819c8280885ae788180416a275d..0000000000000000000000000000000000000000 --- a/binaryc_python_utils/defaults.py +++ /dev/null @@ -1,379 +0,0 @@ -# WARNING DEPRECATED FROM 11-aug-2019 - -# File containing physics_defaults -physics_defaults = { - - # internal buffering and compression level - 'internal_buffering': 0, - 'internal_buffering_compression': 0, - - # log filename - 'log_filename': '/dev/null', - - 'metallicity': 0.02, # metallicity (default 0.02, solar) - 'max_evolution_time': 13700.0, # max evol time in Myr (default WMAP result) - - # stellar evolution parameters - 'max_tpagb_core_mass': 1.38, - 'chandrasekhar_mass': 1.44, - 'max_neutron_star_mass': 1.8, - 'minimum_mass_for_carbon_ignition': 1.6, - 'minimum_mass_for_neon_ignition': 2.85, - 'AGB_core_algorithm': 0, - 'AGB_radius_algorithm': 0, - 'AGB_luminosity_algorithm': 0, - 'AGB_3dup_algorithm': 0, - - # dredge up calibration (either automatic, or not) - 'delta_mcmin': 0.0, - 'lambda_min': 0.0, - 'minimum_envelope_mass_for_third_dredgeup': 0.5, - - # minimum timestep (1yr = 1e-6 is the default) - 'minimum_timestep': 1e-6, - # maximum timestep (1 Gyr = 1e3 is the default) - 'maximum_timestep': 1e3, - - # orbit - 'eccentricity': 0.0, - - # tidally induced mass loss - 'CRAP_parameter': 0.0, - - # tidal strength factor - 'tidal_strength_factor': 1.0, - - # E2 tidal prescription. 0 = H02, 1 = Siess+2013 - 'E2_prescription': 1, - - # gravitational radiation model - # 0 = H02 model (Eggleton) for J and e - # 1 = H02 when R<RL for both stars for J and e - # 2 = None - # 3 = Landau and Lifshitz (1951) model for J (e is not changed) - # 4 = Landau and Lifshitz (1951) model for J when R<RL only (e is not changed) - 'gravitational_radiation_model': 0, - - # magnetic braking multiplier - 'magnetic_braking_factor': 1.0, - - ############################################################ - ### Mass-loss prescriptions - ############################################################ - - # turn wind mass loss on or off - 'wind_mass_loss': 1, - - # massive stars - 'wr_wind': 0, # default hurley et al wind - 'wr_wind_fac': 1.0, # factor applied to WR stars - - # TPAGB wind details - 'tpagbwind': 0, # default to 0 (Karakas et al 2002) - 'superwind_mira_switchon': 500.0, - 'tpagb_reimers_eta': 1.0, - - # eta for Reimers-like GB mass loss - 'gb_reimers_eta': 0.5, - - # VW93 alterations - 'vw93_mira_shift': 0.0, - 'vw93_multiplier': 1.0, - - # systemic wind angular momentum loss prescription - 'wind_angular_momentum_loss': 0, - 'lw': 1.0, - - # enhanced mass loss due to rotation - # 0 = none = ROTATION_ML_NONE - # 1 = Langer+ formula (in mass-loss rate calculation, - # warning: can be unstable - # = ROTATION_ML_FORMULA) - # 2 = remove material in a decretion disc until J<Jcrit - # (ROTATION_ML_ANGMOM) - # 3 = 1 + 2 (not recommended!) - 'rotationally_enhanced_mass_loss': 2, - 'rotationally_enhanced_exponent': 1.0, - - # timestep modulator - 'timestep_modulator': 1.0, - - # initial rotation rates (0=automatic, >0 = in km/s) - 'vrot1': 0.0, - 'vrot2': 0.0, - - ######################################## - # Supernovae and kicks - ######################################## - - # Black hole masses: - # 0: H02=0 - # 1: Belczynski - # 2: Spera+ 2015 - # 3: Fryer 2012 (delayed) - # 4: Fryer 2012 (rapid) - 'BH_prescription': 2, - 'post_SN_orbit_method': 0, - - 'wd_sigma': 0.0, - 'wd_kick_direction': 0, - 'wd_kick_pulse_number': 0, - 'wd_kick_when': 0, - - # sn_kick_distribution and - # sn_kick_dispersion are only defined - # for SN types that leave a remnant - 'sn_kick_distribution_II': 1, - 'sn_kick_dispersion_II': 190.0, - 'sn_kick_distribution_IBC': 1, - 'sn_kick_dispersion_IBC': 190.0, - 'sn_kick_distribution_GRB_COLLAPSAR': 1, - 'sn_kick_dispersion_GRB_COLLAPSAR': 190.0, - 'sn_kick_distribution_ECAP': 1, - 'sn_kick_dispersion_ECAP': 190.0, - 'sn_kick_distribution_NS_NS': 0, - 'sn_kick_dispersion_NS_NS': 0.0, - 'sn_kick_distribution_TZ': 0, - 'sn_kick_dispersion_TZ': 0.0, - 'sn_kick_distribution_BH_BH': 0, - 'sn_kick_dispersion_BH_BH': 0.0, - 'sn_kick_distribution_BH_NS': 0, - 'sn_kick_dispersion_BH_NS': 0.0, - 'sn_kick_distribution_AIC_BH': 0, - 'sn_kick_dispersion_AIC_BH': 0.0, - - 'sn_kick_companion_IA_He': 0, - 'sn_kick_companion_IA_ELD': 0, - 'sn_kick_companion_IA_CHAND': 0, - 'sn_kick_companion_AIC': 0, - 'sn_kick_companion_ECAP': 0, - 'sn_kick_companion_IA_He_Coal': 0, - 'sn_kick_companion_IA_CHAND_Coal': 0, - 'sn_kick_companion_NS_NS': 0, - 'sn_kick_companion_GRB_COLLAPSAR': 0, - 'sn_kick_companion_HeStarIa': 0, - 'sn_kick_companion_IBC': 0, - 'sn_kick_companion_II': 0, - 'sn_kick_companion_IIa': 0, - 'sn_kick_companion_WDKICK': 0, - 'sn_kick_companion_TZ': 0, - 'sn_kick_companion_AIC_BH': 0, - 'sn_kick_companion_BH_BH': 0, - 'sn_kick_companion_BH_NS': 0, - - # evolution run splitting - 'evolution_splitting': 0, - 'evolution_splitting_sn_n': 10, - 'evolution_splitting_maxdepth': 1, - - ######################################## - #### Mass transfer - ######################################## - - # critical mass ratio for unstable RLOF - # - # qc = m (donor) / m (accretor) : - # if q>qc mass transfer is unstable - # - # H02 = Hurley et al. (2002) - # C14 = Claeys et al. (2014) - - # non-degenerate accretors - 'qcrit_LMMS': 0.6944, # de Mink et al 2007 suggests 1.8, C14 suggest 1/1.44 = 0.694 - 'qcrit_MS': 1.6, # C14 suggest 1.6 - 'qcrit_HG': 4.0, # H02 sect. 2.6.1 gives 4.0 - 'qcrit_GB': -1, # -1 is the H02 prescription for giants - 'qcrit_CHeB': 3.0, - 'qcrit_EAGB': -1, # -1 is the H02 prescription for giants - 'qcrit_TPAGB': -1, # -1 is the H02 prescription for giants - 'qcrit_HeMS': 3, - 'qcrit_HeHG': 0.784, # as in H02 2.6.1 - 'qcrit_HeGB': 0.784, # as in H02 2.6.1 - 'qcrit_HeWD': 3, # H02 - 'qcrit_COWD': 3, # H02 - 'qcrit_ONeWD': 3, # H02 - 'qcrit_NS': 3, # H02 - 'qcrit_BH': 3, # H02 - - # degenerate accretors - 'qcrit_degenerate_LMMS': 1.0, # C14 - 'qcrit_degenerate_MS': 1.0, # C14 - 'qcrit_degenerate_HG': 4.7619, # C14 - 'qcrit_degenerate_GB': 1.15, # C14 (based on Hachisu) - 'qcrit_degenerate_CHeB': 3, # not used - 'qcrit_degenerate_EAGB': 1.15, # as GB - 'qcrit_degenerate_TPAGB': 1.15, # as GB - 'qcrit_degenerate_HeMS': 3, - 'qcrit_degenerate_HeHG': 4.7619, # C14 - 'qcrit_degenerate_HeGB': 1.15, # C14 - 'qcrit_degenerate_HeWD': 0.625, # C14 - 'qcrit_degenerate_COWD': 0.625, # C14 - 'qcrit_degenerate_ONeWD': 0.625, # C14 - 'qcrit_degenerate_NS': 0.625, # C14 - 'qcrit_degenerate_BH': 0.625, # C14 - - # disk wind for SNeIa - 'hachisu_disk_wind': 0, # 0 - 'hachisu_qcrit': 1.15, # 1.15 - - # ELD accretion mass - 'mass_accretion_for_eld': 0.15, # 0.15, or 100(off) - - # mergers have the critical angular momentum - # multiplied by this factor - 'merger_angular_momentum_factor': 1.0, - - # RLOF rate method : 0=H02, 1=Adaptive R=RL, 3=Claeys et al 2014 - 'RLOF_method': 3, - 'RLOF_mdot_factor': 1.0, - - # RLOF time interpolation method - # 0 = binary_c (forward in time only), 1 = BSE (backwards allowed) - 'RLOF_interpolation_method': 0, - - # Angular momentum in RLOF transfer model - # 0 : H02 (including disk treatment) - # 1 : Conservative - 'jorb_RLOF_transfer_model': 0, - - # ang mom factor for non-conservative mass loss - # -2 : a wind from the secondary (accretor), i.e. gamma=Md/Ma (default in C14) - # -1 : donor (alternative in C14), i.e. gamma=Ma/Md - # >=0 : the specific angular momentum of the orbit multiplied by gamma - # - # (NB if Hachisu's disk wind is active, or loss is because of - # super-Eddington accretion or novae, material lost through the - # disk wind automatically gets gamma=-2 i.e. the Jaccretor) - 'nonconservative_angmom_gamma': -2, - - # Hachisu's disc wind - 'hachisu_disk_wind': 0, - 'hachisu_qcrit': -1.0, - - # donor rate limiters - 'donor_limit_thermal_multiplier': 1.0, - 'donor_limit_dynamical_multiplier': 1.0, - - # RLOF assumes circular orbit (0) or at periastron (1) - 'rlperi': 0, - - # general accretion limits - 'accretion_limit_eddington_multiplier': 1.0, # eddington limit factor - 'accretion_limit_dynamical_multiplier': 1.0, # dynamical limit factor - 'accretion_limit_thermal_multiplier': 1.0, # thermal limit on MS,HG and CHeB star factor - 'accretion_rate_novae_upper_limit': 1.03e-7, - 'accretion_rate_soft_xray_upper_limit': 2.71e-7, - - # novae - 'nova_retention_method': 0, - 'nova_retention_fraction': 1e-3, - 'individual_novae': 0, - 'beta_reverse_nova': -1, - 'nova_faml_multiplier': 1.0, - 'nova_irradiation_multiplier': 0.0, - - ######################################## - # common envelope evolution - ######################################## - 'comenv_prescription': 0, # 0=H02, 1=nelemans, 2=Nandez+Ivanova2016 - 'alpha_ce': 1.0, - 'lambda_ce': -1, # -1 = automatically set - 'lambda_ionisation': 0.0, - 'lambda_enthalpy': 0.0, - 'comenv_splitmass': 0.0, - 'comenv_ms_accretion_mass': 0.0, - 'nelemans_minq': 0.0, # 0.0 min q for nelemans - 'nelemans_max_frac_j_change': 1.0, # 1.0 - 'nelemans_gamma': 1.0, # 1.0 - 'nelemans_n_comenvs': 1, # 1 - 'comenv_merger_spin_method': 2, - 'comenv_ejection_spin_method': 1, - 'comenv_post_eccentricity': 0.0, - 'comenv_splitmass': 1.01, - - # comenv accretion - 'comenv_ns_accretion_fraction': 0.0, - 'comenv_ns_accretion_mass': 0.0, - - # ################################################# - # circumbinary disc - # ################################################# - # 'comenv_disc_mass_fraction' : 0.0, - # 'comenv_disc_angmom_fraction' : 0.0, - # 'cbdisc_gamma' : 1.6666666666, - # 'cbdisc_alpha' : 1e-6, - # 'cbdisc_kappa' : 1e-2, - # 'cbdisc_torquef' : 1.0, - # 'cbdisc_mass_loss_constant_rate' : 0.0, - # 'cbdisc_mass_loss_inner_viscous_accretion_method' : 1, - # 'cbdisc_mass_loss_inner_viscous_multiplier' : 1.0, - # 'cbdisc_mass_loss_inner_L2_cross_multiplier' : 0.0, - # 'cbdisc_mass_loss_ISM_ram_pressure_multiplier' : 0.0, - # 'cbdisc_mass_loss_ISM_pressure' : 3000.0, - # 'cbdisc_mass_loss_FUV_multiplier' : 0.0, - # 'cbdisc_mass_loss_Xray_multiplier' : 1.0, - # 'cbdisc_viscous_photoevaporation_coupling' : 1, - # 'cbdisc_inner_edge_stripping' : 1, - # 'cbdisc_outer_edge_stripping' : 1, - # 'cbdisc_minimum_luminosity' : 1e-4, - # 'cbdisc_minimum_mass' : 1e-6, - # 'cbdisc_eccentricity_pumping_method' : 1, - # 'cbdisc_resonance_multiplier' : 1.0, - # 'comenv_post_eccentricity' : 1e-5, - - ################################################## - # wind accretion - ################################################## - - # Bondi-Hoyle accretion multiplier - 'Bondi_Hoyle_accretion_factor': 1.5, - # Wind-RLOF method: 0=none, 1=q-dependent, 2=quadratic - # (See Abate et al. 2012,13,14 series of papers) - 'WRLOF_method': 0, - - # pre-main sequence evolution - 'pre_main_sequence': 0, - 'pre_main_sequence_fit_lobes': 0, - - ######################################## - # Nucleosynthesis - ######################################## - - # lithium - 'lithium_hbb_multiplier': 1.0, - 'lithium_GB_post_1DUP': 0.0, - 'lithium_GB_post_Heflash': 0.0, - - ######################################## - # Yields vs time (GCE) - ######################################## - - 'yields_dt': 100000, - 'escape_velocity': 1e9, # if wind v < this, ignore the yield - # and assume it is lost to the IGM - 'escape_fraction': 0.0, # assume all yield is kept in the population - - # minimum sep/per for RLOF on the ZAMS - 'minimum_separation_for_instant_RLOF': 0, - 'minimum_orbital_period_for_instant_RLOF': 0, -} - - - - - - - - - - - - - - - - - - - - diff --git a/binaryc_python_utils/functions.py b/binaryc_python_utils/functions.py index d12a3e6bf9bd02efe0237906dd8da2da45926483..be648e1bf4a496f1a58b89c393bfc6f6f076b2d8 100644 --- a/binaryc_python_utils/functions.py +++ b/binaryc_python_utils/functions.py @@ -1,7 +1,7 @@ -import binary_c - from collections import defaultdict -from binaryc_python_utils.defaults import physics_defaults + +import binary_c +from binaryc_python_utils.custom_logging_functions import create_and_load_logging_function def create_arg_string(arg_dict): """ @@ -41,33 +41,60 @@ def get_arg_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() - # args = {} + 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] - # For example - # physics_args['M_1'] = 20 - # physics_args['separation'] = 0 # 0 = ignored, use period - # physics_args['orbital_period'] = 100000000000 # To make it single + # Generate library and get memaddr + func_memaddr = create_and_load_logging_function(kwargs['custom_logging_code']) - # 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) - # Construct arguments string and final execution string - arg_string = create_arg_string(args) - arg_string = f'binary_c {arg_string}' + # Run it and get output + output = binary_c.run_binary_custom_logging(arg_string, func_memaddr) + return output - # print(arg_string) + elif 'log_filename' in kwargs: + # Use kwarg value to override defaults and add new args + for key in kwargs.keys(): + args[key] = kwargs[key] - # Run it and get output - buffer = "" - output = binary_c.run_binary(arg_string) + # Construct arguments string and final execution string + arg_string = create_arg_string(args) + arg_string = 'binary_c {}'.format(arg_string) - return output + # 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): """ @@ -89,7 +116,7 @@ def run_system_with_log(**kwargs): # Construct arguments string and final execution string arg_string = create_arg_string(args) - arg_string = f'binary_c {arg_string}' + arg_string = 'binary_c {}'.format(arg_string) # print(arg_string) @@ -105,7 +132,9 @@ def parse_output(output, selected_header): 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 + Then the values will be put into a dictionary. + TODO: Think about exporting to numpy array or pandas + """ value_dicts = [] val_lists = [] diff --git a/examples/.ipynb_checkpoints/example_notebook-checkpoint.ipynb b/examples/.ipynb_checkpoints/example_notebook-checkpoint.ipynb deleted file mode 100644 index f9db89b1350c3f8d1bbbe76e95a65bffd733a9c1..0000000000000000000000000000000000000000 --- a/examples/.ipynb_checkpoints/example_notebook-checkpoint.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/examples/example_run_binary_with_custom_logging.py b/examples/example_run_binary_with_custom_logging.py new file mode 100644 index 0000000000000000000000000000000000000000..02336da32feb64a334bcea5efcf601e9c635b5ee --- /dev/null +++ b/examples/example_run_binary_with_custom_logging.py @@ -0,0 +1,32 @@ +import ctypes +import tempfile +import os + +from binaryc_python_utils.custom_logging_functions import autogen_C_logging_code, binary_c_log_code, compile_shared_lib, temp_custom_logging_dir, create_and_load_logging_function +import binary_c + +# generate logging lines +logging_line = autogen_C_logging_code( + { + 'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], + 'my_sss2': ['model.time', 'star[1].mass'] + } +) + +# Generate code around logging lines +custom_logging_code = binary_c_log_code(logging_line) + +# Generate library and get memaddr +func_memaddr = create_and_load_logging_function(custom_logging_code) + +# +m1 = 15.0 # Msun +m2 = 14.0 # Msun +separation = 0 # 0 = ignored, use period +orbital_period = 4530.0 # days +eccentricity = 0.0 +metallicity = 0.02 +max_evolution_time = 15000 +argstring = "binary_c M_1 {0:g} M_2 {1:g} separation {2:g} orbital_period {3:g} eccentricity {4:g} metallicity {5:g} max_evolution_time {6:g}".format(m1,m2,separation,orbital_period,eccentricity,metallicity,max_evolution_time) +output = binary_c.run_binary_custom_logging(argstring, func_memaddr) +print(output) \ No newline at end of file diff --git a/examples/examples_run_binary.py b/examples/examples_run_binary.py new file mode 100644 index 0000000000000000000000000000000000000000..47e84f65e33feff3ec44e3b1c1a54675e21b6aff --- /dev/null +++ b/examples/examples_run_binary.py @@ -0,0 +1,143 @@ +#!/usr/bin/python3 +import os +import sys + +import binary_c + +from binaryc_python_utils.functions import run_system, parse_output +from binaryc_python_utils.custom_logging_functions import autogen_C_logging_code, binary_c_log_code + +""" +Very basic scripts to run a binary system and print the output. + +Use these as inspiration/base +""" + +def run_example_binary(): + """ + Function to run a binary system. Very basic approach which directly adresses the run_binary(..) python-c wrapper function. + + """ + + m1 = 15.0 # Msun + m2 = 14.0 # Msun + separation = 0 # 0 = ignored, use period + orbital_period = 4530.0 # days + eccentricity = 0.0 + metallicity = 0.02 + max_evolution_time = 15000 # Myr. You need to include this argument. + + # + argstring = "binary_c M_1 {m1} M_2 {m2} separation {separation} orbital_period {orbital_period} \ + eccentricity {eccentricity} metallicity {metallicity} \ + max_evolution_time {max_evolution_time}".format(m1=m1, m2=m2, separation=separation, orbital_period=orbital_period, eccentricity=eccentricity, metallicity=metallicity, max_evolution_time=max_evolution_time) + output = binary_c.run_binary(argstring) + print (output) + +# run_example_binary() + +def run_example_binary_with_run_system(): + """ + This function serves as an example on the function run_system and parse_output. + There is more functionality with this method and several tasks are done behind the scene. + + Requires pandas, numpy to run. + + 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. + Note, if you dont use the custom_logging functionality binary_c should be configured to have output that starts with that given header + """ + + import pandas as pd + import numpy as np + + # Run system. all arguments can be given as optional arguments. + output = run_system(M_1=10, M_2=20, separation=0, orbital_period=100000000000) + + # 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') + + #### Now do whatever you want with it: + # Put it in numpy arrays + #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') + + # Cast the data into a dataframe. + df = pd.DataFrame.from_dict(result_example_header, dtype=np.float64) + + # print(df) + # sliced_df = df[df.t < 1000] # Cut off late parts of evolution + # print(sliced_df[["t","m1"]]) + + # Some routine to plot. + +# run_example_binary_with_run_system() + + +def run_example_binary_with_custom_logging(): + """ + Function that will use a automatically generated piece of logging code. Compile it, load it + into memory and run a binary system. See run_system on how several things are done in the background here. + """ + + import pandas as pd + import numpy as np + + # generate logging lines. Here you can choose whatever you want to have logged, and with what header + # this generates working print statements + logging_line = autogen_C_logging_code( + { + 'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], + } + ) + # OR + # You can also decide to `write` your own logging_line, which allows you to write a more complex logging statement with conditionals. + logging_line = 'Printf("MY_STELLAR_DATA time=%g mass=%g\\n", stardata->model.time, stardata->star[0].mass)' + + # Generate entire shared lib code around logging lines + custom_logging_code = binary_c_log_code(logging_line) + + # Run system. all arguments can be given as optional arguments. the custom_logging_code is one of them and will be processed automatically. + output = run_system(M_1=1, metallicity=0.002, M_2=0.1, separation=0, orbital_period=100000000000, custom_logging_code=custom_logging_code) + + # 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) + # DOESNT WORK YET if you have the line autogenerated. + result_example_header = parse_output(output, 'MY_STELLAR_DATA') + + # Cast the data into a dataframe. + df = pd.DataFrame.from_dict(result_example_header, dtype=np.float64) + + # Do whatever you like with the dataframe. + print(df) + +# run_example_binary_with_custom_logging() + +def run_example_binary_with_writing_logfile(): + """ + Same as above but when giving the log_filename argument the log filename will be written + """ + + import pandas as pd + import numpy as np + + # 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') + + # 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') + + #### Now do whatever you want with it: + # Put it in numpy arrays + #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') + + # Cast the data into a dataframe. + df = pd.DataFrame.from_dict(result_example_header, dtype=np.float64) + + # print(df) + # sliced_df = df[df.t < 1000] # Cut off late parts of evolution + # print(sliced_df[["t","m1"]]) + + # Some routine to plot. + +# run_example_binary_with_writing_logfile() \ No newline at end of file diff --git a/examples/test_log.txt b/examples/test_log.txt new file mode 100644 index 0000000000000000000000000000000000000000..aa24cd9fe727dbca9a651b7a648aa8af8be20a64 --- /dev/null +++ b/examples/test_log.txt @@ -0,0 +1,23 @@ + TIME M1 M2 K1 K2 SEP ECC R1/ROL1 R2/ROL2 TYPE RANDOM_SEED=21708 RANDOM_COUNT=0 + 0.0000 10.000 20.000 1 1 2.8176e+08 0.00 0.000 0.000 INITIAL + 8.8656 9.980 19.203 1 2 2.8966e+08 0.00 0.000 0.000 TYPE_CHNGE + 8.8814 9.980 19.185 1 4 2.8983e+08 0.00 0.000 0.000 TYPE_CHNGE + 9.8724 9.977 10.122 1 5 4.2066e+08 0.00 0.000 0.000 TYPE_CHNGE + 9.8834 9.977 9.974 1 5 4.2379e+08 0.00 0.000 0.000 q-inv + 9.8901 9.977 1.621 1 13 -592.56 -1.00 0.000 0.000 Randbuf=35834 - d48r(0)=0.500757 - d48r(1)=0.0445977 - d48r(2)=0.55466 - d48r(3)=0.342924 - d48r(4)=0.230728 + 9.8901 9.977 1.621 1 13 -592.56 -1.00 0.000 0.000 SN kick II (SN type 12 12, pre-explosion M=8.50996 Mc=6.81718 type=5) -> kick 1(190) vk=61.1258 vr=0.0878271 omega=1.44971 phi=-0.319563 -> vn=61.1158 ; final sep -592.558 ecc -1 (random count 0) - Runaway v=(0,0,0) |v|=0 : companion v=(0,0,0), |v|=0 ; - , dm(exploder) = 6.88872, dm(companion) = 0 + 9.8901 9.977 1.621 1 13 -592.56 -1.00 0.000 0.000 TYPE_CHNGE + 9.8901 9.977 1.621 1 13 -592.56 -1.00 0.000 0.000 DISRUPT + 9.8901 9.977 1.621 1 13 -592.56 -1.00 0.000 0.000 SN + 24.4615 9.890 1.621 2 13 -592.56 -1.00 0.000 0.000 OFF_MS + 24.4615 9.890 1.621 2 13 -592.56 -1.00 0.000 0.000 TYPE_CHNGE + 24.5257 9.887 1.621 3 13 -592.56 -1.00 0.000 0.000 TYPE_CHNGE + 24.5353 9.886 1.621 4 13 -592.56 -1.00 0.000 0.000 TYPE_CHNGE + 27.3558 9.424 1.621 5 13 -592.56 -1.00 0.000 0.000 TYPE_CHNGE + 27.4616 1.338 1.621 13 13 -592.56 -1.00 0.000 0.000 d48r(5)=0.770697 - d48r(6)=0.689651 - d48r(7)=0.21307 - d48r(8)=0.709486 + 27.4616 1.338 1.621 13 13 -592.56 -1.00 0.000 0.000 SN kick II (SN type 12 12, pre-explosion M=9.30206 Mc=2.87012 type=5) -> kick 1(190) vk=327.76 vr=0 omega=4.45783 phi=-0.61121 -> vn=327.76 ; final sep -592.558 ecc -1 (random count 5) - Runaway v=(0,0,0) |v|=0 : companion v=(0,0,0), |v|=0 ; - , dm(exploder) = 7.96389, dm(companion) = 0 + 27.4616 1.338 1.621 13 13 -592.56 -1.00 0.000 0.000 TYPE_CHNGE + 27.4616 1.338 1.621 13 13 -592.56 -1.00 0.000 0.000 q-inv + 27.4616 1.338 1.621 13 13 -592.56 -1.00 0.000 0.000 SN + 15000.0000 1.338 1.621 13 13 -592.56 -1.00 0.000 0.000 MAX_TIME +Probability : 1 diff --git a/examplestest_log.txt b/examplestest_log.txt new file mode 100644 index 0000000000000000000000000000000000000000..9db8a852c34b9928cc1840ca90799ffb5ae8b457 --- /dev/null +++ b/examplestest_log.txt @@ -0,0 +1,23 @@ + TIME M1 M2 K1 K2 SEP ECC R1/ROL1 R2/ROL2 TYPE RANDOM_SEED=55045 RANDOM_COUNT=0 + 0.0000 10.000 20.000 1 1 2.8176e+08 0.00 0.000 0.000 INITIAL + 8.8656 9.980 19.203 1 2 2.8966e+08 0.00 0.000 0.000 TYPE_CHNGE + 8.8814 9.980 19.185 1 4 2.8983e+08 0.00 0.000 0.000 TYPE_CHNGE + 9.8724 9.977 10.122 1 5 4.2066e+08 0.00 0.000 0.000 TYPE_CHNGE + 9.8834 9.977 9.974 1 5 4.2379e+08 0.00 0.000 0.000 q-inv + 9.8901 9.977 1.621 1 13 -16.809 -1.00 0.000 0.000 Randbuf=37809 - d48r(0)=0.335316 - d48r(1)=0.610765 - d48r(2)=0.984646 - d48r(3)=0.74651 - d48r(4)=0.897875 + 9.8901 9.977 1.621 1 13 -16.809 -1.00 0.000 0.000 SN kick II (SN type 12 12, pre-explosion M=8.50996 Mc=6.81718 type=5) -> kick 1(190) vk=362.928 vr=0.0878271 omega=5.64151 phi=0.515558 -> vn=362.867 ; final sep -16.809 ecc -1 (random count 0) - Runaway v=(0,0,0) |v|=0 : companion v=(0,0,0), |v|=0 ; - , dm(exploder) = 6.88872, dm(companion) = 0 + 9.8901 9.977 1.621 1 13 -16.809 -1.00 0.000 0.000 TYPE_CHNGE + 9.8901 9.977 1.621 1 13 -16.809 -1.00 0.000 0.000 DISRUPT + 9.8901 9.977 1.621 1 13 -16.809 -1.00 0.000 0.000 SN + 24.4615 9.890 1.621 2 13 -16.809 -1.00 0.000 0.000 OFF_MS + 24.4615 9.890 1.621 2 13 -16.809 -1.00 0.000 0.000 TYPE_CHNGE + 24.5257 9.887 1.621 3 13 -16.809 -1.00 0.000 0.000 TYPE_CHNGE + 24.5353 9.886 1.621 4 13 -16.809 -1.00 0.000 0.000 TYPE_CHNGE + 27.3558 9.424 1.621 5 13 -16.809 -1.00 0.000 0.000 TYPE_CHNGE + 27.4616 1.338 1.621 13 13 -16.809 -1.00 0.000 0.000 d48r(5)=0.306812 - d48r(6)=0.0954943 - d48r(7)=0.00699521 - d48r(8)=0.980772 + 27.4616 1.338 1.621 13 13 -16.809 -1.00 0.000 0.000 SN kick II (SN type 12 12, pre-explosion M=9.30206 Mc=2.87012 type=5) -> kick 1(190) vk=164.187 vr=0 omega=6.16237 phi=-1.40333 -> vn=164.187 ; final sep -16.809 ecc -1 (random count 5) - Runaway v=(0,0,0) |v|=0 : companion v=(0,0,0), |v|=0 ; - , dm(exploder) = 7.96389, dm(companion) = 0 + 27.4616 1.338 1.621 13 13 -16.809 -1.00 0.000 0.000 TYPE_CHNGE + 27.4616 1.338 1.621 13 13 -16.809 -1.00 0.000 0.000 q-inv + 27.4616 1.338 1.621 13 13 -16.809 -1.00 0.000 0.000 SN + 15000.0000 1.338 1.621 13 13 -16.809 -1.00 0.000 0.000 MAX_TIME +Probability : 1 diff --git a/testing_examples/log_filename_test.py b/testing_examples/log_filename_test.py deleted file mode 100644 index 80d244bac185b7c6730fbba7428a74b335db1626..0000000000000000000000000000000000000000 --- a/testing_examples/log_filename_test.py +++ /dev/null @@ -1,43 +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 - -""" -This script is intended to have the logfile of a binary system being outputted to a given directory so that we can use that logfile for other purposes -Like plotting/visualizing the general evolution of that system using e.g. Mirons script -""" - -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 - - physics_args['log_filename'] = os.path.join(os.getcwd(), 'test.log') - print(physics_args['log_filename']) - - arg_string = create_arg_string(physics_args) - arg_string = f'binary_c {arg_string}' - - buffer = "" - - print(arg_string) - - output = binary_c.run_binary(arg_string) -example_with_loading_default_args() \ No newline at end of file diff --git a/testing_examples/loop_system.py b/testing_examples/loop_system.py deleted file mode 100644 index 622b9c75c6dce6e63a32a715d235b7861561a824..0000000000000000000000000000000000000000 --- a/testing_examples/loop_system.py +++ /dev/null @@ -1,66 +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 - -""" -This script is an example of running a group of binary systems using a loop. For big grids this is not wise, the grid functionality will be built later - -I made this script to with the logging of binaryc set to log only one line per system (when a certain requirement is met). - -You can either capture the data and print it, or write it to a file -""" - -def run_simple_loop_binary(): - # Some simple function with a loop - # This function assumes a single output line - - m2 = 14.0 # Msun - separation = 0 # 0 = ignored, use period - orbital_period = 4530.0 # days - eccentricity = 0.0 - metallicity = 0.02 - max_evolution_time = 15000 - buffer = "" - - print ("Binary_c grid output:") - - mass_1 = [] - time = [] - initial_m1 = [] - - # Set up for loop. Beware: this is only a proof of concept example. big grid should not be run in this way. rather one should use a queueing/threading system. - for m1 in range(15, 20): - argstring = f"binary_c M_1 {m1} M_2 {m2} separation {separation} orbital_period {orbital_period} eccentricity {eccentricity} metallicity {metallicity} max_evolution_time {max_evolution_time}" - - # Get the output string - output = binary_c.run_binary(argstring) - - # split output on newlines - for line in output.split('\n'): - # Example of splitting off certain lines of output - if line.startswith('TESTLOG_BINARY_POP'): - value_array = line.split()[1:] - # print(value_array) - - # Either save the results in arrays or lists - mass_1.append(value_array[1]) - time.append(value_array[0]) - initial_m1.append(value_array[2]) - - # write headers. can be cleaner - if not os.path.isfile("test_output.txt"): - with open("test_output.txt", "a") as f: - f.write('time M1 M1_zams\n') - - # Or write them to a file with a file: - with open("test_output.txt", "a") as myfile: - myfile.write(' '.join(value_array[:3])+'\n') - - print('mass1:', mass_1) - print('zams_mass1:' ,initial_m1) - print('time:', time) \ No newline at end of file diff --git a/testing_examples/simple_test.py b/testing_examples/simple_test.py deleted file mode 100644 index 75191f5bcc984c7a8df7430b2d36721ce987e726..0000000000000000000000000000000000000000 --- a/testing_examples/simple_test.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python3 -import os -import sys - -# 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 run_test_binary(): - m1 = 15.0 # Msun - m2 = 14.0 # Msun - separation = 0 # 0 = ignored, use period - orbital_period = 4530.0 # days - eccentricity = 0.0 - metallicity = 0.02 - max_evolution_time = 15000 - buffer = "" - # argstring = "binary_c M_1 {0:g} M_2 {1:g} separation {2:g} orbital_period {3:g} eccentricity {4:g} metallicity {5:g} max_evolution_time {6:g} ".format(m1,m2,separation,orbital_period,eccentricity,metallicity,max_evolution_time) - - argstring = f"binary_c M_1 {m1} M_2 {m2} separation {separation} orbital_period {orbital_period} eccentricity {eccentricity} metallicity {metallicity} max_evolution_time {max_evolution_time}" - - output = binary_c.run_binary(argstring) - - # print ("Binary_c output:\n\n") - print (output) - -run_test_binary() diff --git a/testing_examples/single_system.py b/testing_examples/single_system.py deleted file mode 100644 index 561a0fd0ee9495cec38900df75cd550086ffd0ae..0000000000000000000000000000000000000000 --- a/testing_examples/single_system.py +++ /dev/null @@ -1,40 +0,0 @@ -import os, sys - -# Append root dir of this project to include functionality -sys.path.append(os.path.dirname(os.getcwd())) -import binary_c - - -""" -Example script for running a single system. This is a very simple set up. -For a different way of inputting arg strings: - -from utils.defaults import physics_defaults -from utils.functions import create_arg_string - -physics_args = physics_defaults.copy() -physics_args['orbital_period'] = 4530.0 - -arg_string = create_arg_string(physics_args) -arg_string = f'binary_c {arg_string}' - -Other examples can be found using this method -""" - -def run_test_binary(): - m1 = 15.0 # Msun - m2 = 14.0 # Msun - separation = 0 # 0 = ignored, use period - orbital_period = 4530.0 # days - eccentricity = 0.0 - metallicity = 0.02 - max_evolution_time = 15000 - buffer = "" - # argstring = "binary_c M_1 {0:g} M_2 {1:g} separation {2:g} orbital_period {3:g} eccentricity {4:g} metallicity {5:g} max_evolution_time {6:g} ".format(m1,m2,separation,orbital_period,eccentricity,metallicity,max_evolution_time) - - argstring = f"binary_c M_1 {m1} M_2 {m2} separation {separation} orbital_period {orbital_period} eccentricity {eccentricity} metallicity {metallicity} max_evolution_time {max_evolution_time}" - - output = binary_c.run_binary(argstring) - - # print ("Binary_c output:\n\n") - print (output) \ No newline at end of file diff --git a/tests_and_snippets/custom_logging_examples.py b/tests_and_snippets/custom_logging_examples.py deleted file mode 100644 index 5bd5b9ea4cedf55e73cbbc1a47aa1eb19bf728c7..0000000000000000000000000000000000000000 --- a/tests_and_snippets/custom_logging_examples.py +++ /dev/null @@ -1,49 +0,0 @@ -import ctypes -import tempfile -import os - -from binaryc_python_utils.custom_logging_functions import autogen_C_logging_code, binary_c_log_code, compile_shared_lib, temp_custom_logging_dir -import binary_c - -# generate logging lines -logging_line = autogen_C_logging_code( - { - 'MY_STELLAR_DATA': ['model.time', 'star[0].mass'], - 'my_sss2': ['model.time', 'star[1].mass'] - } -) - -# Generate code around logging lines -custom_logging_code = binary_c_log_code(logging_line) - -# -compile_shared_lib(created_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 -mem = ctypes.cast(libmean.custom_output_function, ctypes.c_void_p).value - -# -m1 = 15.0 # Msun -m2 = 14.0 # Msun -separation = 0 # 0 = ignored, use period -orbital_period = 4530.0 # days -eccentricity = 0.0 -metallicity = 0.02 -max_evolution_time = 15000 -buffer = "" -argstring = "binary_c M_1 {0:g} M_2 {1:g} separation {2:g} orbital_period {3:g} eccentricity {4:g} metallicity {5:g} max_evolution_time {6:g} ".format(m1,m2,separation,orbital_period,eccentricity,metallicity,max_evolution_time) - -output = binary_c.run_binary_custom_logging(argstring, mem) -# output = binary_c.run_binary(argstring) -print (output) - diff --git a/tests_and_snippets/test.py b/tests_and_snippets/test.py deleted file mode 100644 index 45cb036ed3509bb04ee1070aa75e326199694ea6..0000000000000000000000000000000000000000 --- a/tests_and_snippets/test.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/python3 - -import binary_c - -############################################################ -# Test script to run a binary using the binary_c Python -# module. -############################################################ - -def run_test_binary(): - m1 = 15.0 # Msun - m2 = 14.0 # Msun - separation = 0 # 0 = ignored, use period - orbital_period = 4530.0 # days - eccentricity = 0.0 - metallicity = 0.02 - max_evolution_time = 15000 - buffer = "" - argstring = "binary_c M_1 {0:g} M_2 {1:g} separation {2:g} orbital_period {3:g} eccentricity {4:g} metallicity {5:g} max_evolution_time {6:g} ".format(m1,m2,separation,orbital_period,eccentricity,metallicity,max_evolution_time) - - output = binary_c.run_binary(argstring) - - print ("\n\nBinary_c output:\n\n") - print (output) - - - -binary_star=binary_c.new_system() - -print(dir(binary_c)) -# print(binary_star) -run_test_binary() -ding = binary_c.return_arglines() -print(ding) \ No newline at end of file diff --git a/tests_and_snippets/test_david.py b/tests_and_snippets/test_david.py deleted file mode 100644 index eff9b19fd7181ea01ced3df50a9478358b6684a7..0000000000000000000000000000000000000000 --- a/tests_and_snippets/test_david.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/python3 -import os -import binary_c -import matplotlib.pyplot as plt - -from binaryc_python_utils.defaults import physics_defaults - -############################################################ -# Test script to run a binary using the binary_c Python -# module. -############################################################ - - - -print(binary_c) - - -# print("Current binary_c object class functions: ") -# print(dir(binary_c)) - -# print("Current binary_c.new_system object class functions: ") -# print(dir(binary_c.new_system())) -## WHat is the use of new_system? - -# print("Current binary_c.run_binary object class functions: ") -# print(dir(binary_c.run_binary())) - -# binary_star=binary_c.new_system() -# print(binary_star) -# print(dir(binary_star)) - -# Test single system -# run_test_binary() - -# Test grid-like -# run_simple_loop_binary() \ No newline at end of file