Giter Club home page Giter Club logo

jeol_eds's Introduction

JEOL_eds

A python module to read binary data files ('.pts') by JEOL's Analysis Station software. The function to parse the header of the binary file was copied from HyperSpy (hyperspy/io_plugins/jeol.py scheduled for inclusion into HyperSpy 1.7).

This module does not aim to replace HyperSpy which is much more feature-rich. Instead it provides an easy interface to extract spectra or elemental maps from the binary file much like the Play Back feature in Analysis Station.

Installation

Requirements

Python 3.6+
numpy
scipy
matplotlib
scikit-image
asteval
h5py
(pip for installation)

Download zip and extract or clone repository. From the resulting folder run

$ pip install .

or

$ pip install . -U

to upgrade an existing installation.

Usage

>>>> from JEOL_eds import JEOL_pts

# read EDS data
>>>> dc = JEOL_pts('128.pts', split_frames=True, E_cutoff=11.0)


# Cu Kalpha map of all even frames.
>>>> m = dc.map(interval=(7.9, 8.1),
                energy=True,
                frames=range(0, dc.dcube.shape[0], 2))

# Cu Kalpha map of frames 0..10. Frames are aligned using
# frame 5 as reference. Wiener filtered frames are used to
# calculate the shifts.
# Verbose output
>>>> m = dc.map(interval=(7.9, 8.1),
                energy=True,
                frames=[5,0,1,2,3,4,6,7,8,9,10],
                align='filter',
                verbose=True)
Using channels 790 - 810
Frame 5 used a reference
/../scipy/signal/signaltools.py:1475: RuntimeWarning: divide by zero encountered in true_divide
  res *= (1 - noise / lVar)
/../scipy/signal/signaltools.py:1475: RuntimeWarning: invalid value encountered in multiply
  res *= (1 - noise / lVar)


# Plot spectrum integrated over full image.
# If option 'split_frames' was used to read the data the
# following plots the sum spectrum of all frames added.
>>>> plt.plot(dc.spectrum())
[<matplotlib.lines.Line2D at 0x7f7192feec10>]

# The sum spectrum of the whole data cube is also stored
# in the raw data and can be accessed much quicker.
>>>> plt.plot(dc.ref_spectrum)
[<matplotlib.lines.Line2D at 0x7f3131a489d0>]

# Plot sum spectrum corresponding to a (rectangular) ROI specified
# as tuple (top, bottom, left, light) of pixels for selected frames.
# Verify definition of ROI before you apply it using the total x-ray
# intensity as image.
>>>> ROI = (10, 20, 50, 100)
>>>> show_ROI(dc.map(), ROI, alpha=0.6)
>>>> plt.plot(dc.spectrum(ROI=ROI, frames=[0,1,2,10,11,12,30,31,32]))
<matplotlib.lines.Line2D at 0x7f7192b58050>


# Create overlay of elemental maps
>>>> from JEOL_eds.utils import create_overlay

# Load data. Data does not contain drift images and all frames were
# added, thus only a single frame is present.
>>>> dc = JEOL_pts('data/complex_oxide.h5')

# Extract some elemental maps. Where possible, dd contribution of
# several lines.
>>>> Ti = dc.map(interval=(4.4, 5.1), energy=True)      # Ka,b
>>>> Fe = dc.map(interval=(6.25, 6.6), energy=True)     # Ka
>>>> Sr = dc.map(interval=(13.9, 14.4), energy=True)    # Ka
>>>> Co = dc.map(interval=(6.75, 7.0), energy=True)     # Ka
>>>> Co += dc.map(interval=(7.5, 7.8), energy=True)     # Kb
>>>> O = dc.map(interval=(0.45, 0.6), energy=True)

# Visualize the CoFeOx distribution using first of the `drift_images`
# as background. Note that drift images were not stored in the data
# supplied and this will raise a TypeError.
>>>> create_overlay([Fe, Co],
                    ['Maroon', 'Violet'],
                    legends=['Fe', 'Co'],
                    BG_image=dc.drift_images[0])


# Plot spectra
>>>> from JEOL_eds.utils import plot_spectrum

# Plot and save reference spectrum between 1.0 and 2.5 keV.
# Plot one minor tick on x-axis and four on y-axis. Pass
# some keywords to `matplotlib.pyplot.plot()`.
>>>> plot_spectrum(dc.ref_spectrum,
                   E_range=(4, 17.5),
                   M_ticks=(1, 4),
                   outfile='ref_spectrum.pdf',
                   color='Red', linestyle='-.', linewidth=1.0)


# To insert the output of the different plot functions imported from
# `JEOL_eds.utils` into a sub-plot, use the following code fragment
fig, (ax1, ax2) = plt.subplots(1, 2)
# Use `ax1` for overlay
>>>> plt.sca(ax1)
>>>> create_overlay((O, Sr, Ti),
                    ('Blue', 'Green', 'Red'),
                    legends=['O', 'Sr', 'Ti'],
                    BG_image=dc.drift_images[0])
# Use `ax2` for spectrum
>>>> plt.sca(ax2)
>>>> plot_spectrum(dc.ref_spectrum, E_range=(4, 17.5))
>>>> plt.tight_layout() 	# Prevents overlapping labels
>>>> plt.savefig('demo.pdf')


# Calculate and plot line profiles.
>>>> from JEOL_eds.utils import show_line, get_profile

# Extract carbon map
>>>> C_map = dc.map(interval=(0.22, 0.34), energy=True)

# Define line. Verify definition.
>>>> line = (80, 5, 110, 100)
>>>> width = 10
>>>> show_line(C_map, line, linewidth=width, cmap='inferno')

# Calculate profile along a given line (width equals 10 pixels) and
# plot it.
>>>> profile = get_profile(C_map, line, linewidth=width)
>>>> plt.plot(profile)


# Make movie of drift_images and total EDS intensity and store it
# as 'data/128.mp4'.
>>>> dc = JEOL_pts('data/128.pts', split_frames=True, read_drift=True)
>>>> dc.make_movie()


# Check for contamination by carbon.
# Integrate carbon Ka line.
>>>> ts = dc.time_series(interval=(0.45, 0.6), energy=True)
# Plot and save the time series.
>>>> from JEOL_eds.utils import plot_tseries
>>>> plot_tseries(ts,
                  M_ticks=(9,4),
                  outfile='carbon_Ka.pdf',
                  color='Red', linestyle='-.', linewidth=1.0)


# Additionally, JEOL_pts object can be saved as hdf5 files.
# This has the benefit that all attributes (drift_images, parameters)
# are also stored.
# Use base name of original file and pass along keywords to
# `h5py.create_dataset()`.
>>>> dc.save_hdf5(compression='gzip', compression_opts=9)

# Initialize from hdf5 file. Only filename is used, additional keywords
# are ignored.
>>>> dc3 = JEOL_pts('128.h5')
>>>> dc3.parameters
{'PTTD Cond': {'Meas Cond': {'CONDPAGE0_C.R': {'Tpl': {'index': 3,
     'List': ['T1', 'T2', 'T3', 'T4']},
.
.
.
    'FocusMP': 16043213}}}}

Bugs

Parameters loaded from '.pts' might have different types than the ones loaded from 'h5' files. Thus take extra care if you need to compare them:

# Load and store as hdf5.
>>>> dc = JEOL_pts('128.pts')
>>>> dc.save_hdf5(compression='gzip', compression_opts=9)
# Initialize from hdf5
>>>> dc_hdf5 = JEOL_pts('128.h5')

# Compare parameters dict gives unexpected result.
>>>> p = dc.parameters['PTTD Data']['AnalyzableMap MeasData']['MeasCond']
>>>> p_hdf5 = dc_hdf5.parameters['PTTD Data']['AnalyzableMap MeasData']['MeasCond']
>>>> p == p_hdf5
False

# But they seem identical.
>>>> p
{'AccKV': 200.0,
 'AccNA': 7.475,
 'Mag': 800000,
 'WD': 3.2,
 'ScanR': 270.0,
 'FocusMP': 16043213}

>>>> p_hdf5
{'AccKV': 200.0,
 'AccNA': 7.475,
 'Mag': 800000,
 'WD': 3.2,
 'ScanR': 270.0,
 'FocusMP': 16043213}

# The issue is different types.
# This works.
>>>> p['AccKV'] == p_hdf5['AccKV']
True
>>>> type(p['AccKV'])
numpy.float32
>>>> type(p_hdf5['AccKV'])
float

# This causes the issue.
>>>> p['AccNA'] == p_hdf5['AccNA']
False
>>>> type(p['AccNA'])
numpy.float32
>>>> type(p_hdf5['AccNA'])
float

jeol_eds's People

Contributors

ialxn avatar

Stargazers

Zhou Xu avatar M avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.