Attempt at python f2py wrapping
See https://github.com/nrc-cnrc/EGSnrc/issues/625 for more details.
Here's a good place to pause for today.
Installation instructions for Ubuntu:
Python pre-reqs (from https://github.com/pyenv/pyenv/wiki/Common-build-problems#prerequisites)
sudo apt-get install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
Install pyenv (from https://github.com/pyenv/pyenv-installer#install)
curl https://pyenv.run | bash
Install Python:
exec $SHELL # Only for resetting the shell after install pyenv
pyenv install 3.7.9
pyenv global 3.7.9
Install Poetry (only used in development environment -- from https://python-poetry.org/docs/#installation):
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
exec $SHELL # For resetting the shell after install poetry
poetry self update --preview
Install dependencies:
cd ~/git/EGSnrc/HEN_HOUSE/python
poetry install
mortran --> fortran --> numpy.f2py:
make
See that the "Hello World!" version runs and can "see" the fortran subroutines:
poetry run python -c "import egsnrc"
With gives:
Hello World!
Everything that is accessible from Python:
['THIS',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__path__',
'__spec__',
'_egsnrc',
'alias_sample',
'alias_sample1',
'annih',
'annih_at_rest',
'ausgab',
'bhabha',
'bounds',
'brempr',
'brems',
'ch_steps',
'compt',
'compton_data',
'edge',
'edgset',
'egs_add_medium',
'egs_check_arguments',
'egs_combine_runs',
'egs_conver_month',
'egs_date',
'egs_date_and_time',
'egs_day_diff',
'egs_day_diff_o',
'egs_eadl_relax',
'egs_etime',
'egs_fdate',
'egs_finish',
'egs_get_canonical_system',
'egs_get_configuration_name',
'egs_get_electron_data',
'egs_get_fdate',
'egs_get_hostnm',
'egs_get_medium_name',
'egs_get_photon_data',
'egs_get_rndm',
'egs_get_rndm_array',
'egs_get_unit',
'egs_get_usercode',
'egs_heap_sort',
'egs_init',
'egs_init1',
'egs_init_default_rng',
'egs_init_rayleigh',
'egs_init_rayleigh_sampling',
'egs_init_relax',
'egs_init_rng',
'egs_init_user_photon',
'egs_io',
'egs_is_absolute_path',
'egs_isdir',
'egs_itostring',
'egs_kn_sigma0',
'egs_kn_sigma1',
'egs_month',
'egs_open_datfile',
'egs_open_file',
'egs_open_file_junk',
'egs_open_units',
'egs_print_binding_energies',
'egs_print_canonical_system',
'egs_print_configuration_name',
'egs_print_hostnm',
'egs_rayleigh_sampling',
'egs_rayleigh_sigma',
'egs_read_byte',
'egs_read_int',
'egs_read_real',
'egs_read_shellwise_pe',
'egs_read_short',
'egs_rndm',
'egs_scale_photon_xsection',
'egs_scale_xcc',
'egs_secnds',
'egs_set_defaults',
'egs_shellwise_photo',
'egs_strip_extension',
'egs_strip_path',
'egs_swap_2',
'egs_swap_4',
'egs_system',
'egs_time',
'egs_time_diff',
'egs_time_diff_o',
'egs_tot_time',
'egs_vr',
'egs_weekday',
'egs_write_string',
'egsi_get_data',
'egsi_get_shell_data',
'eii_data',
'eii_init',
'eii_sample',
'elecin',
'electr',
'emf_inputs',
'epcont',
'erf1',
'error',
'et_control',
'fcoulc',
'fix_brems',
'gauss_legendre',
'geom',
'get_ranlux_state',
'hatch',
'howfar',
'hownear',
'ibsearch',
'importlib',
'init_compton',
'init_ms_sr',
'init_nist_brems',
'init_nrc_pair',
'init_ranlux',
'init_spin',
'init_spin_old',
'init_triplet',
'lnblnk1',
'media',
'misc',
'moller',
'ms_data',
'mscat',
'mscati',
'msdist_pi',
'msdist_pii',
'my_times',
'nist_brems',
'nrc_pair',
'old_compt',
'pair',
'pe_shell_data',
'photin',
'photo',
'photon',
'photonuc',
'pprint',
'prepare_alias_histogram',
'prepare_alias_sampling',
'prepare_alias_table',
'prepare_rayleigh_data',
'print_ranlux_seeds',
'qdebug',
'randomm',
'ranlux',
'rayleigh_inputs',
'rayleigh_sampling',
'relax',
'relax_data',
'relax_for_user',
'replace_env',
'sample_alias_histogram',
'sample_triplet',
'set_ranlux_state',
'set_spline',
'shell_data',
'show_ranlux_seeds',
'shower',
'sigma',
'sigmamedium',
'spin_data',
'spin_rejection',
'spline',
'sscat',
'stack',
'thresh',
'toupper',
'triplet_data',
'uphi',
'uphiin',
'uphiot',
'useful',
'user_relax',
'vmc_electron',
'watch',
'x_options',
'xsif',
'zero']
@ftessier here's the initial PR :)
Nice progress!
So, I am currently aiming to run "tutor1" code within python. Initially the plan is to get something working, and then from a working framework step back to make things a bit more flexible.
For now, just to get things working, I have hardcoded into fortran the following:
user_code = 'tutor1';
pegs_file = 'tutor_data';
This is to get around the fact that I am no longer calling a compiled executable via the CLI, instead I am trying to call it via the Python interpreter. At some point I will need to sort out bypassing this initialisation logic and enabling this variables to be passed via Python.
...potentially also bypassing the user_code concept altogether. As I plan to not have the user need to have an $EGS_HOME directory at all.
In it's state at the moment, the compiled egs_nrc package is able to run egs_init(). Next session hopefully I might be able to implement the tutor1 logic within Python. Let's see...
~/git/EGSnrc/HEN_HOUSE/python$ poetry run python -c "import egsnrc; egsnrc.egs_init();"
debug-capi:Python C/API function _egsnrc.egs_init()
debug-capi:Fortran subroutine `egs_init()'
================================================================================
EGSnrc version 4 for x86_64-unknown-linux-gnu Tue Sep 1 23:37:33 2020
================================================================================
configuration............................................linux
user code................................................tutor1
pegs file................................................tutor_data on HEN_HOUSE
using host...............................................dads-desktop
output file(s)...........................................
================================================================================
debug-capi:Building return value.
debug-capi:Python C/API function _egsnrc.egs_init: successful.
debug-capi:Freeing memory.
Nice progress!
Thanks :)