From 5704197cf892a121508d0ccf9a669742e08d6ae5 Mon Sep 17 00:00:00 2001 From: Andrew Nelson Date: Thu, 30 Aug 2018 17:51:44 +1000 Subject: [PATCH] MAINT: np.ediff1d-->np.diff (#224) --- .gitattributes | 1 + CHANGELOG.txt | 4 + INSTALL_CONTRIBUTE.md | 304 ++++++++++++++++---------------- refnx/reduce/platypusnexus.py | 2 +- refnx/reduce/rebin.py | 8 +- refnx/reduce/test/test_rebin.py | 20 +-- refnx/reflect/structure.py | 6 +- 7 files changed, 175 insertions(+), 170 deletions(-) diff --git a/.gitattributes b/.gitattributes index 1d04a056f..53dd58a51 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,6 +6,7 @@ *.rst text=auto eol=lf *.txt text=auto eol=lf *.yml text=auto eol=lf +*.md text=auto eol=lf # Force git to look at some files as binary diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 071e75391..727394915 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,2 +1,6 @@ Details of changes made to refnx ================================ + +0.1.1 +----- +- removal of Python 2.7 support \ No newline at end of file diff --git a/INSTALL_CONTRIBUTE.md b/INSTALL_CONTRIBUTE.md index 8fdcf268e..34ec07eb3 100644 --- a/INSTALL_CONTRIBUTE.md +++ b/INSTALL_CONTRIBUTE.md @@ -1,153 +1,153 @@ -# refnx - Installation and Development Instructions - -refnx is a python package for analysis of neutron and X-ray reflectometry data. -It can also be used as a generalised curvefitting tool. It uses Markov Chain -Monte Carlo to obtain posterior distributions for curvefitting problems. - --------------- -# Installation - -*refnx* has been tested on Python 3.5, 3.6 and 3.7. It requires the *numpy, -scipy, cython, pandas, emcee* packages to work. Additional features require the -*pytest, h5py, xlrd, uncertainties, ptemcee, tqdm, matplotlib, pymc3* packages. -To build the bleeding edge code you will need to have access to a C-compiler to -build a couple of Python extensions. C-compilers should be installed on Linux. -On OSX you will need to install Xcode and the command line tools. On Windows you -will need to install the correct [Visual Studio compiler][Visual-studio-compiler] -for your Python version. - -In the current version of *refnx* the *emcee* package is vendored by *refnx*. That -is, *refnx* possesses it's own private copy of the package, and there is no need to -install the *emcee* package separately. - -## Installation into a *conda* environment - -Perhaps the easiest way to create a scientific computing environment is to use the -[miniconda][miniconda] package manager. Once *conda* has been installed the first -step is to create a *conda* environment. - -### Creating a conda environment - - 1) In a shell window create a conda environment and install the dependencies. The **-n** flag indicates that the environment is called *refnx*. - - ```conda create -n refnx python=3.7 numpy scipy cython pandas h5py xlrd pytest tqdm``` - 2) Activate the environment that we're going to be working in: - - ``` - # on OSX - conda activate refnx - - # on windows - conda activate refnx - ``` - 3) Install the remaining dependencies: - ```pip install uncertainties ptemcee``` - -### Installing into a conda environment from source - - The latest source code can be obtained from either [PyPi][PyPi] or [Github][github-refnx]. You can also build the package from within the refnx git repository (see later in this document). - 1) In a shell window navigate into the source directory and build the package. If you are on Windows you'll need to start a Visual Studio command window. - ``` - python setup.py build - python setup.py install - ``` - 2) Run the tests, they should all work. - ``` - python setup.py test - ``` - -### Installing into a conda environment from a released version - - 1) There are pre-built versions on *conda-forge*, but they're not necessarily at the bleeding edge: - - ```conda install -c conda-forge refnx``` - 2) Start up a Python interpreter and make sure the tests run: - ``` - >>> import refnx - >>> refnx.test() - ``` - ------------------------ -## Development Workflow - -These instructions outline the workflow for contributing to refnx development. -The refnx community welcomes all contributions that will improve the package. -The following instructions are based on use of a command line *git* client. -*Git* is a distributed version control program. An example of [how to contribute to the numpy project][numpy-contrib] -is a useful reference. - -### Setting up a local git repository - 1) Create an account on [github](https://github.com/). - 2) On the [refnx github][github-refnx] page fork the *refnx* repository to your own github account. Forking means that now you have your own personal repository of the *refnx* code. - 3) Now we will make a local copy of your personal repository on your local machine: - ``` - # is your github username - git clone https://github.com//refnx.git - ``` - 4) Add the *refnx* remote repository, we're going to refer to the remote with the *upstream* name: - ``` - git remote add upstream https://github.com/refnx/refnx.git - ``` - 5) List the remote repositories that your local repository knows about: - ``` - git remote -v - ``` - -### Keeping your local and remote repositories up to date -The main *refnx* repository may be a lot more advanced than your fork, or your local copy, of the git repository. - 1) To update your repositories you need to fetch the changes from the main *refnx* repository: - ``` - git fetch upstream - ``` - 2) Now update the local branch you're on by rebasing against the *refnx* master branch: - ``` - git rebase upstream/master - ``` - 3) Push your updated local branch to the remote fork on github. You have to specify the remote branch you're pushing to. Here we push to the *master* branch: - ``` - git push origin master - ``` - -### Adding a feature -The git repository is automatically on the master branch to start with. However, -when developing features that you'd like to contribute to the *refnx* project -you'll need to do it on a feature branch. - - 1) Create a feature branch and check it out: - ``` - git branch my_feature_name - git checkout my_feature_name - ``` - 2) Once you're happy with the changes you've made you should check that the tests still work: - ``` - python setup.py test - ``` - 3) If the performance of what you've added/changed may be critical, then consider writing a benchmark. The benchmarks use - the *asv* package and are run as: - ``` - cd benchmarks - pip install asv - asv run - asv publish - asv preview - ``` - For an example benchmark look at one of the files in the *benchmarks* directory. - 4) Now commit the changes. You'll have to supply a commit message that outlines the changes you made. The commit message should follow the [numpy guidelines][numpy-contib] - ``` - git commit -a - ``` - 5) Now you need to push those changes on the *my_feature_branch* branch to *your* fork of the refnx repository on github: - ``` - git push origin my_feature_branch - ``` - 6) On the main [refnx][github-refnx] repository you should be able to create a pull request (PR). The PR says that you'd like the *refnx* project to include the changes you made. - 7) Once the automated tests have passed, and the *refnx* maintainers are happy with the changes you've made then the PR is merged. You can then delete the feature branch on github, and delete your local feature branch: - ``` - git branch -D my_feature_branch - ``` - - [PyPi]: - [github-refnx]: - [Visual-studio-compiler]: - [miniconda]: +# refnx - Installation and Development Instructions + +refnx is a python package for analysis of neutron and X-ray reflectometry data. +It can also be used as a generalised curvefitting tool. It uses Markov Chain +Monte Carlo to obtain posterior distributions for curvefitting problems. + +-------------- +# Installation + +*refnx* has been tested on Python 3.5, 3.6 and 3.7. It requires the *numpy, +scipy, cython, pandas, emcee* packages to work. Additional features require the +*pytest, h5py, xlrd, uncertainties, ptemcee, tqdm, matplotlib, pymc3* packages. +To build the bleeding edge code you will need to have access to a C-compiler to +build a couple of Python extensions. C-compilers should be installed on Linux. +On OSX you will need to install Xcode and the command line tools. On Windows you +will need to install the correct [Visual Studio compiler][Visual-studio-compiler] +for your Python version. + +In the current version of *refnx* the *emcee* package is vendored by *refnx*. That +is, *refnx* possesses it's own private copy of the package, and there is no need to +install the *emcee* package separately. + +## Installation into a *conda* environment + +Perhaps the easiest way to create a scientific computing environment is to use the +[miniconda][miniconda] package manager. Once *conda* has been installed the first +step is to create a *conda* environment. + +### Creating a conda environment + + 1) In a shell window create a conda environment and install the dependencies. The **-n** flag indicates that the environment is called *refnx*. + + ```conda create -n refnx python=3.7 numpy scipy cython pandas h5py xlrd pytest tqdm``` + 2) Activate the environment that we're going to be working in: + + ``` + # on OSX + conda activate refnx + + # on windows + conda activate refnx + ``` + 3) Install the remaining dependencies: + ```pip install uncertainties ptemcee``` + +### Installing into a conda environment from source + + The latest source code can be obtained from either [PyPi][PyPi] or [Github][github-refnx]. You can also build the package from within the refnx git repository (see later in this document). + 1) In a shell window navigate into the source directory and build the package. If you are on Windows you'll need to start a Visual Studio command window. + ``` + python setup.py build + python setup.py install + ``` + 2) Run the tests, they should all work. + ``` + python setup.py test + ``` + +### Installing into a conda environment from a released version + + 1) There are pre-built versions on *conda-forge*, but they're not necessarily at the bleeding edge: + + ```conda install -c conda-forge refnx``` + 2) Start up a Python interpreter and make sure the tests run: + ``` + >>> import refnx + >>> refnx.test() + ``` + +----------------------- +## Development Workflow + +These instructions outline the workflow for contributing to refnx development. +The refnx community welcomes all contributions that will improve the package. +The following instructions are based on use of a command line *git* client. +*Git* is a distributed version control program. An example of [how to contribute to the numpy project][numpy-contrib] +is a useful reference. + +### Setting up a local git repository + 1) Create an account on [github](https://github.com/). + 2) On the [refnx github][github-refnx] page fork the *refnx* repository to your own github account. Forking means that now you have your own personal repository of the *refnx* code. + 3) Now we will make a local copy of your personal repository on your local machine: + ``` + # is your github username + git clone https://github.com//refnx.git + ``` + 4) Add the *refnx* remote repository, we're going to refer to the remote with the *upstream* name: + ``` + git remote add upstream https://github.com/refnx/refnx.git + ``` + 5) List the remote repositories that your local repository knows about: + ``` + git remote -v + ``` + +### Keeping your local and remote repositories up to date +The main *refnx* repository may be a lot more advanced than your fork, or your local copy, of the git repository. + 1) To update your repositories you need to fetch the changes from the main *refnx* repository: + ``` + git fetch upstream + ``` + 2) Now update the local branch you're on by rebasing against the *refnx* master branch: + ``` + git rebase upstream/master + ``` + 3) Push your updated local branch to the remote fork on github. You have to specify the remote branch you're pushing to. Here we push to the *master* branch: + ``` + git push origin master + ``` + +### Adding a feature +The git repository is automatically on the master branch to start with. However, +when developing features that you'd like to contribute to the *refnx* project +you'll need to do it on a feature branch. + + 1) Create a feature branch and check it out: + ``` + git branch my_feature_name + git checkout my_feature_name + ``` + 2) Once you're happy with the changes you've made you should check that the tests still work: + ``` + python setup.py test + ``` + 3) If the performance of what you've added/changed may be critical, then consider writing a benchmark. The benchmarks use + the *asv* package and are run as: + ``` + cd benchmarks + pip install asv + asv run + asv publish + asv preview + ``` + For an example benchmark look at one of the files in the *benchmarks* directory. + 4) Now commit the changes. You'll have to supply a commit message that outlines the changes you made. The commit message should follow the [numpy guidelines][numpy-contib] + ``` + git commit -a + ``` + 5) Now you need to push those changes on the *my_feature_branch* branch to *your* fork of the refnx repository on github: + ``` + git push origin my_feature_branch + ``` + 6) On the main [refnx][github-refnx] repository you should be able to create a pull request (PR). The PR says that you'd like the *refnx* project to include the changes you made. + 7) Once the automated tests have passed, and the *refnx* maintainers are happy with the changes you've made then the PR is merged. You can then delete the feature branch on github, and delete your local feature branch: + ``` + git branch -D my_feature_branch + ``` + + [PyPi]: + [github-refnx]: + [Visual-studio-compiler]: + [miniconda]: [numpy-contrib]: \ No newline at end of file diff --git a/refnx/reduce/platypusnexus.py b/refnx/reduce/platypusnexus.py index a03b0f7fa..10aa270e5 100644 --- a/refnx/reduce/platypusnexus.py +++ b/refnx/reduce/platypusnexus.py @@ -974,7 +974,7 @@ def process(self, h5norm=None, lo_wavelength=2.5, hi_wavelength=19., be compared. """ if normalise_bins: - div = 1 / np.ediff1d(m_lambda_hist[0])[:, np.newaxis] + div = 1 / np.diff(m_lambda_hist[0])[:, np.newaxis] detector, detector_sd = EP.EPmulk(detector, detector_sd, div) diff --git a/refnx/reduce/rebin.py b/refnx/reduce/rebin.py index 22adf8f71..626a33bc6 100644 --- a/refnx/reduce/rebin.py +++ b/refnx/reduce/rebin.py @@ -193,7 +193,7 @@ def rebin(x1, y1, x2, y1_sd=None): # Divide y1 by bin widths. # This converts y-values from bin total to bin average over bin width. - x1_bin_widths = np.ediff1d(x1) + x1_bin_widths = np.diff(x1) y1_ave = y1 / x1_bin_widths y1_ave_sd = y1_sd_temp / x1_bin_widths @@ -226,7 +226,7 @@ def rebin(x1, y1, x2, y1_sd=None): i_place[start_pos] == 0 and i_place[start_pos + 1] == x1.size): sub_edges = x1 - sub_dx = np.ediff1d(sub_edges) + sub_dx = np.diff(sub_edges) sub_y_ave = y1_ave sub_y_ave_var = y1_ave_var @@ -241,7 +241,7 @@ def rebin(x1, y1, x2, y1_sd=None): i_lo, i_hi = i_place[start_pos], i_place[start_pos + 1] sub_edges = np.hstack([x1[i_lo:i_hi], x2_hi]) - sub_dx = np.ediff1d(sub_edges) + sub_dx = np.diff(sub_edges) sub_y_ave = y1_ave[i_lo: i_hi] sub_y_ave_var = y1_ave_var[i_lo:i_hi] @@ -256,7 +256,7 @@ def rebin(x1, y1, x2, y1_sd=None): i_lo, i_hi = i_place[end_pos - 1], i_place[end_pos] sub_edges = np.hstack([x2_lo, x1[i_lo:i_hi]]) - sub_dx = np.ediff1d(sub_edges) + sub_dx = np.diff(sub_edges) sub_y_ave = y1_ave[i_lo - 1:i_hi] sub_y_ave_var = y1_ave_var[i_lo - 1:i_hi] diff --git a/refnx/reduce/test/test_rebin.py b/refnx/reduce/test/test_rebin.py index ecfc3a69c..66be1e560 100644 --- a/refnx/reduce/test/test_rebin.py +++ b/refnx/reduce/test/test_rebin.py @@ -31,7 +31,7 @@ def test_x2_same_as_x1(self): x_new = np.linspace(0., 1., n + 1) # some arbitrary distribution - y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.ediff1d(x_old) + y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.diff(x_old) # rebin y_new = rebin.rebin(x_old, y_old, x_new) @@ -53,13 +53,13 @@ def test_x2_surrounds_x1(self): x_new = np.linspace(-0.1, 1.2, n + 1) # some arbitrary distribution - y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.ediff1d(x_old) + y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.diff(x_old) # rebin y_new = rebin.rebin(x_old, y_old, x_new) # compute answer here to check rebin - y_old_ave = y_old / np.ediff1d(x_old) + y_old_ave = y_old / np.diff(x_old) y_new_here = [y_old_ave[0] * (x_new[1] - 0.), y_old_ave[0] * (x_old[1] - x_new[1]) + y_old_ave[1] * (x_new[2] - x_old[1]), @@ -85,7 +85,7 @@ def test_x2_surrounds_x1_2(self): x_new = np.linspace(-0.1, 1.2, n + 1) # some arbitrary distribution - y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.ediff1d(x_old) + y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.diff(x_old) # with uncertainties np.random.seed(1) @@ -122,7 +122,7 @@ def test_x2_lower_than_x1(self): x_new = np.linspace(-0.2, -0.0, n + 1) # some arbitrary distribution - y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.ediff1d(x_old) + y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.diff(x_old) # rebin y_new = rebin.rebin(x_old, y_old, x_new) @@ -145,7 +145,7 @@ def test_x2_above_x1(self): x_new = np.linspace(1.2, 10., n + 1) # some arbitrary distribution - y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.ediff1d(x_old) + y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.diff(x_old) # rebin y_new = rebin.rebin(x_old, y_old, x_new) @@ -168,13 +168,13 @@ def test_x2_in_x1(self): x_new = np.linspace(0.3, 0.65, n + 1) # some arbitrary distribution - y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.ediff1d(x_old) + y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.diff(x_old) # rebin y_new = rebin.rebin(x_old, y_old, x_new) # compute answer here to check rebin - y_old_ave = y_old / np.ediff1d(x_old) + y_old_ave = y_old / np.diff(x_old) y_new_here = (y_old_ave[1] * (x_old[2] - x_new[0]) + y_old_ave[2] * (x_new[1] - x_old[2])) @@ -195,7 +195,7 @@ def test_y1_uncertainties(self): x_new = np.linspace(-0.1, 1.2, n + 1) # some arbitrary distribution - y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.ediff1d(x_old) + y_old = 1. + np.sin(x_old[:-1] * np.pi) / np.diff(x_old) # with uncertainties y_old = unp.uarray(y_old, 0.1 * y_old * uniform((m,))) @@ -207,7 +207,7 @@ def test_y1_uncertainties(self): y1_sd=unp.std_devs(y_old)) # compute answer here to check rebin - y_old_ave = y_old / np.ediff1d(x_old) + y_old_ave = y_old / np.diff(x_old) y_new_here = np.array( [y_old_ave[0] * (x_new[1] - 0.), y_old_ave[0] * (x_old[1] - x_new[1]) + diff --git a/refnx/reflect/structure.py b/refnx/reflect/structure.py index cc319b57e..3f4d049ce 100644 --- a/refnx/reflect/structure.py +++ b/refnx/reflect/structure.py @@ -604,7 +604,7 @@ def _profile_slicer(z, sld_profile, slice_size=None): supplying an array with two columns (representing the real and imaginary parts). slice_size : None, float, optional - if `slice_size is None` then `np.min(np.ediff1d(z))/4` is used to + if `slice_size is None` then `np.min(np.diff(z))/4` is used to determine the rough size of the created slabs. Otherwise `float(slice_size)` is used. @@ -630,7 +630,7 @@ def _profile_slicer(z, sld_profile, slice_size=None): imag_interp = interp1d(z, sld.imag, kind='quadratic') if slice_size is None: - slice_size = np.min(np.ediff1d(z)) / 4 + slice_size = np.min(np.diff(z)) / 4 else: slice_size = float(slice_size) @@ -640,7 +640,7 @@ def _profile_slicer(z, sld_profile, slice_size=None): zeds = np.linspace(z_min, z_max, int(n_steps) + 1) # this is the true thickness of the slab - slice_size = np.ediff1d(zeds)[0] + slice_size = np.diff(zeds)[0] zeds -= slice_size / 2 zeds = zeds[1:]