diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 5913a97..cacd529 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -5,16 +5,17 @@ name: Build Examples on: push: - branches: [ master ] + branches: "*" pull_request: branches: [ master ] jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: matrix: + os: [ubuntu-latest, windows-latest, macos-latest] python-version: [3.6, 3.7, 3.8] steps: @@ -28,12 +29,14 @@ jobs: python -m pip install --upgrade pip pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + shell: bash - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + shell: bash - name: Get Tag uses: olegtarasov/get-tag@v2 id: tagName @@ -43,9 +46,16 @@ jobs: - name: Set Tag # Output usage example run: | echo ::set-env name=GIT_TAG::${{ steps.tagName.outputs.tag }} + shell: bash - name: Test tag run: | python -c "import os; print(os.getenv(\"GIT_TAG\"))" + shell: bash + - name: Test encoding + run: | + python -c "import sys; print(sys.getdefaultencoding())" - name: Testing examples run: | make examples + pytest examples + shell: bash diff --git a/.gitignore b/.gitignore index 35dacec..c068a06 100644 --- a/.gitignore +++ b/.gitignore @@ -109,3 +109,7 @@ ENV/ /examples/spectra_files/*.svg /*.csv /*.svg +/bin/renishaw-export.py +*.txt +*.csv +/examples/*.svg diff --git a/Makefile b/Makefile index d41c359..6884446 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ $(PIP_DONE): setup.py $(PKG_PYS) download: $(DOWN_DONE) $(DOWN_DONE): $(EX_DIR)/spectra_files - wget -nv https://github.com/alchem0x2A/py-wdf-reader/releases/download/binary/spectra_files.zip + curl -LO https://github.com/alchem0x2A/py-wdf-reader/releases/download/binary/spectra_files.zip unzip -o spectra_files.zip -d examples/ rm spectra_files.zip touch $@ @@ -25,4 +25,4 @@ examples: download pip $(EX_PYS) $(EX_PYS): cd $(EX_DIR) &&\ - python3 $(shell basename $@) + python $(shell basename $@) diff --git a/examples/_path.py b/examples/_path.py index fb15c97..87960cb 100644 --- a/examples/_path.py +++ b/examples/_path.py @@ -1,5 +1,10 @@ from pathlib import Path import os +try: + import pytest +except ImportError: + #print("No pytest") + pass curdir = Path(__file__).parent imgdir = curdir / "img" diff --git a/examples/ex10_executable.py b/examples/ex10_executable.py new file mode 100644 index 0000000..aaaed24 --- /dev/null +++ b/examples/ex10_executable.py @@ -0,0 +1,94 @@ +#! /usr/bin/env python3 + +########################################################### +# The example shows how to get mapping data # +# The peak ratio at 1315 cm^-1 and 1380 cm^-1 are plotted # +# Details see Small 14, 1804006 (2018). # +########################################################### +import subprocess +import os +from pathlib import Path + +import numpy as np +from renishawWiRE import WDFReader +from _path import curdir, imgdir +try: + import matplotlib.pyplot as plt + import matplotlib.image as mpimg + plot = True +except ImportError: + plot = False + + +def call_exe(name, extras="", output=None): + filename = curdir / "spectra_files" / "{0}.wdf".format(name) + root = filename.parent + # clean up all + reader = WDFReader(filename) + assert reader is not None + for ext in (".csv", ".txt"): + for f in root.glob("*" + ext): + print(f) + os.remove(f) + # Initial name + cmd = "wdf-export {0} {1}".format(filename.as_posix(), + extras) + if output is not None: + cmd += "-o {0}".format(output) + + run = subprocess.run(cmd, shell=True) + assert run.returncode == 0 + + # Manually set output + if output is not None: + output = Path(output) + else: + if ".txt" not in extras: + output = filename.with_suffix(".csv") + else: + output = filename.with_suffix(".txt") + + assert output.is_file() is True + # Read the data + if output.suffix == ".csv": + delimiter = "," + else: + delimiter = " " + + data = np.genfromtxt(output, delimiter=delimiter, skip_header=1) + wn_data = data[:, 0] + spectra_data = data[:, 1:] + assert reader.xdata.shape[0] == wn_data.shape[0] + assert reader.count == spectra_data.shape[1] + spectra_reader = reader.spectra.reshape(reader.count, + reader.xdata.shape[0]).T + # Only do this for decreasing sequence + if reader.xdata[0] > reader.xdata[1]: + spectra_reader = spectra_reader[::-1, :] + print(spectra_reader) + print(spectra_data) + assert np.all(np.isclose(spectra_reader, spectra_data, 1e-3)) + + + + + +def main(): + + for name in ("sp", "line", "depth", + "mapping", "undefined", "streamline"): + # Normal exe + call_exe(name) + call_exe(name, extras="-f .txt") + call_exe(name, + output="test.txt") + call_exe(name, + output="test.csv") + + + + + + +if __name__ == "__main__": + main() diff --git a/examples/ex1_getinfo.py b/examples/ex1_getinfo.py index 71dbea3..a87e71e 100644 --- a/examples/ex1_getinfo.py +++ b/examples/ex1_getinfo.py @@ -7,14 +7,17 @@ from renishawWiRE import WDFReader from _path import curdir +#import pytest def main(): - for name in ("sp", "line", "depth", "mapping"): + for name in ("sp", "line", "depth", + "mapping", "undefined", "streamline"): filename = curdir / "spectra_files" / "{0}.wdf".format(name) print("Testing: ", filename.as_posix()) # if debug=True, debug information will show in stderr reader = WDFReader(filename, debug=True) + assert reader is not None # Explicitly print into stdout reader.print_info() reader.close() diff --git a/examples/ex2_sp_spectra.py b/examples/ex2_sp_spectra.py index 110ed25..0dfa34a 100644 --- a/examples/ex2_sp_spectra.py +++ b/examples/ex2_sp_spectra.py @@ -27,6 +27,7 @@ def main(): sp = reader.spectra # spectrum / spectra in ccd counts # For single spectrum the spectra has shape (point_per_spectrum, ) print(wn.shape, sp.shape) + assert wn.shape == sp.shape if plot: print("Use matplotlib to plot spectrum") plt.figure(figsize=(6, 4)) diff --git a/examples/ex3_linscan.py b/examples/ex3_linscan.py index 0d88c24..185b5d7 100644 --- a/examples/ex3_linscan.py +++ b/examples/ex3_linscan.py @@ -23,6 +23,7 @@ def main(): # For mapping, xdata is still wavenumber wn = reader.xdata spectra = reader.spectra + assert wn.shape[0] == spectra.shape[1] # Now spectra.shape becomes (i, j, spectrum) print(wn.shape, spectra.shape) if plot is True: diff --git a/examples/ex9_streamline.py b/examples/ex9_streamline.py new file mode 100644 index 0000000..03138c2 --- /dev/null +++ b/examples/ex9_streamline.py @@ -0,0 +1,91 @@ +#! /usr/bin/env python3 + +########################################################### +# The example shows how to get mapping data # +# The peak ratio at 1315 cm^-1 and 1380 cm^-1 are plotted # +# Details see Small 14, 1804006 (2018). # +########################################################### + +import numpy as np +from renishawWiRE import WDFReader +from _path import curdir, imgdir +try: + import matplotlib.pyplot as plt + import matplotlib.image as mpimg + plot = True +except ImportError: + plot = False + + +def peak_in_range(spectra, wn, range, method="max", **params): + """Find the max intensity of peak within range + method can be max, min, or mean + """ + cond = np.where((wn >= range[0]) & (wn <= range[1]))[0] + spectra_cut = spectra[:, :, cond] + return getattr(np, method)(spectra_cut, axis=2, **params) + + +def main(): + filename = curdir / "spectra_files" / "streamline.wdf" + reader = WDFReader(filename) + print("Measurement: ", reader.measurement_type) + print("Scan: ", reader.scan_type) + assert reader.measurement_type == 3 + assert reader.scan_type == 6 + wn = reader.xdata + spectra = reader.spectra + print(wn.shape, spectra.shape) + x = reader.xpos + y = reader.ypos + print(len(x), len(y)) + w, h = reader.map_shape + print("The size of mapping is {0:d} * {1:d}". + format(w, h)) + # w and h are the measure in xy coordinates + # Level the spectra + spectra = spectra - np.min(spectra, axis=2, keepdims=True) + peaks_a = peak_in_range(spectra, wn, [1295, 1340]) + peaks_b = peak_in_range(spectra, wn, [1350, 1400]) + + ratio = peaks_a / peaks_b + ratio_fl = ratio.flatten() + + if plot is True: + plt.figure(figsize=(10, 5)) + + # Left plot histogram of Peak A/B ratio + plt.subplot(121) + img = mpimg.imread(reader.img, format="jpg") + img_x0, img_y0 = reader.img_origins + img_w, img_h = reader.img_dimensions + plt.imshow(img, extent=(img_x0, img_x0 + img_w, + img_y0 + img_h, img_y0)) + plt.scatter(x, y, s=0.4, alpha=0.8) + # plt.hist(ratio_fl, bins=50, range=(0.1, 2)) + # plt.xlabel("Ratio peak A / peak B") + # plt.ylabel("Counts") + + # Right plot histogram of Peak A/B mapping + plt.subplot(122) + + plt.imshow(peaks_b, interpolation="bicubic", + extent=[0, x.max() - x.min(), + y.max() - y.min(), 0],) + # vmin=0.5, vmax=1.5) + plt.xlabel("Mapping x [μm]") + plt.ylabel("Mapping y [μm]") + cb = plt.colorbar() + cb.ax.set_title("Signal") + plt.tight_layout() + plt.show(block=False) + plt.pause(3) + plt.savefig(imgdir / "mapping_streamline.png", dpi=100) + plt.close() + else: + pass + return + + +if __name__ == "__main__": + main() diff --git a/examples/pytest.ini b/examples/pytest.ini new file mode 100644 index 0000000..7ae5ac5 --- /dev/null +++ b/examples/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +python_files = ex*.py +python_functions = main diff --git a/renishawWiRE/__init__.py b/renishawWiRE/__init__.py index 67f7f7c..7a26e2d 100644 --- a/renishawWiRE/__init__.py +++ b/renishawWiRE/__init__.py @@ -1 +1,2 @@ from .wdfReader import WDFReader +from .export import main diff --git a/bin/wdf-export b/renishawWiRE/export.py similarity index 100% rename from bin/wdf-export rename to renishawWiRE/export.py diff --git a/renishawWiRE/types.py b/renishawWiRE/types.py index 2635219..43e900e 100644 --- a/renishawWiRE/types.py +++ b/renishawWiRE/types.py @@ -80,7 +80,7 @@ def __str__(self): Wavenumber="nm", # nm Nanometre="nm", ElectronVolt="eV", - Micron="μm", # same for EXIF units + Micron="um", # same for EXIF units Counts="counts", Electrons="electrons", Millimetres="mm", diff --git a/renishawWiRE/wdfReader.py b/renishawWiRE/wdfReader.py index 8d0d954..0fae8f5 100644 --- a/renishawWiRE/wdfReader.py +++ b/renishawWiRE/wdfReader.py @@ -539,12 +539,12 @@ def print_info(self, **params): """Print information of the wdf file """ s = [] - s.append("{0:>24s}:\t{1}".format("Title", self.title)) - s.append("{0:>17s} version:\t{1}.{2}.{3}.{4}". + s.append(u"{0:>24s}:\t{1}".format("Title", self.title)) + s.append(u"{0:>17s} version:\t{1}.{2}.{3}.{4}". format(self.application_name, *self.application_version)) - s.append("{0:>24s}:\t{1} nm".format("Laser Wavelength", + s.append(u"{0:>24s}:\t{1} nm".format("Laser Wavelength", self.laser_length)) for a in ("count", "capacity", "point_per_spectrum", "scan_type", "measurement_type", @@ -559,7 +559,8 @@ def print_info(self, **params): except AttributeError: continue s.append("{0:>24s}:\t{1}".format(sname, val)) - print("\n".join(s), **params) + text = u"\n".join(s) + print(text, **params) if __name__ == '__main__': diff --git a/setup.py b/setup.py index 52cf7ee..339ebfa 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ # from setuptools.command.install import install NAME = "renishawWiRE" -VERSION = "0.1.11" +VERSION = "0.1.12" DESCRIPTION = open("README.md", encoding="utf-8").read() @@ -60,9 +60,12 @@ def verify_version(): "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", ], - scripts=[ - "bin/wdf-export", - ], + #scripts=[ + # "bin/wdf-export", + #], + entry_points = { + "console_scripts": ["wdf-export=renishawWiRE.export:main"], + }, python_requires=">=3.6", # cmdclass={"verify": VerifyVersionCommand}, )