Skip to content

Commit

Permalink
Merge pull request #3 from atomprobe-tc/add_env_support
Browse files Browse the repository at this point in the history
Add support for env ranging definitions and pos to csv reconstructions, also started with pycodestyle, pylinting, and mypy code quality refactoring
  • Loading branch information
mkuehbach authored Feb 26, 2024
2 parents 617d60f + 384fe89 commit 349b9eb
Show file tree
Hide file tree
Showing 56 changed files with 6,853 additions and 5,782 deletions.
6 changes: 2 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
## Changelog
**v0.0.7**
- Added Matlab code for extracting ranging definitions from Matlab figures to text
- Added FIG parser for creating proper molecular ion class instances of from these ranging definitions
- Fixed bug that the nuclid list did not show the mass number of isotopes
**v0.2**


211 changes: 103 additions & 108 deletions README.md

Large diffs are not rendered by default.

46 changes: 36 additions & 10 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ argon2-cffi==21.3.0
argon2-cffi-bindings==21.2.0
# via argon2-cffi
ase==3.19.0
# via ifes-apt-tc-data-modeling (pyproject.toml)
# via ifes_apt_tc_data_modeling (pyproject.toml)
astroid==3.0.2
# via pylint
asttokens==2.2.1
# via stack-data
attrs==23.1.0
Expand Down Expand Up @@ -53,20 +55,24 @@ decorator==5.1.1
# via ipython
defusedxml==0.7.1
# via nbconvert
dill==0.3.7
# via pylint
docutils==0.19
# via readme-renderer
executing==1.2.0
# via stack-data
fastjsonschema==2.16.3
# via nbformat
flatdict==4.0.1
# via ifes_apt_tc_data_modeling (pyproject.toml)
fonttools==4.39.3
# via matplotlib
h5grove==1.3.0
# via jupyterlab-h5web
h5py==3.8.0
# via
# h5grove
# ifes-apt-tc-data-modeling (pyproject.toml)
# ifes_apt_tc_data_modeling (pyproject.toml)
# jupyterlab-h5web
idna==3.4
# via
Expand All @@ -88,6 +94,8 @@ ipython-genutils==0.2.0
# via
# nbclassic
# notebook
isort==5.13.2
# via pylint
jaraco-classes==3.2.3
# via keyring
jedi==0.18.2
Expand Down Expand Up @@ -136,9 +144,9 @@ jupyter-server==1.24.0
# nbclassic
# notebook-shim
jupyterlab==3.5.3
# via ifes-apt-tc-data-modeling (pyproject.toml)
# via ifes_apt_tc_data_modeling (pyproject.toml)
jupyterlab-h5web==7.1.1
# via ifes-apt-tc-data-modeling (pyproject.toml)
# via ifes_apt_tc_data_modeling (pyproject.toml)
jupyterlab-pygments==0.2.2
# via nbconvert
jupyterlab-server==2.22.1
Expand All @@ -161,6 +169,8 @@ matplotlib-inline==0.1.6
# via
# ipykernel
# ipython
mccabe==0.7.0
# via pylint
mdurl==0.1.2
# via markdown-it-py
mistune==2.0.5
Expand All @@ -171,6 +181,10 @@ mpmath==1.3.0
# via sympy
msgpack==1.0.7
# via blosc2
mypy==1.8.0
# via ifes_apt_tc_data_modeling (pyproject.toml)
mypy-extensions==1.0.0
# via mypy
nbclassic==0.5.6
# via
# jupyterlab
Expand Down Expand Up @@ -211,7 +225,7 @@ numpy==1.24.3
# contourpy
# h5grove
# h5py
# ifes-apt-tc-data-modeling (pyproject.toml)
# ifes_apt_tc_data_modeling (pyproject.toml)
# matplotlib
# numexpr
# pandas
Expand All @@ -231,7 +245,7 @@ packaging==23.1
# nbconvert
# tables
pandas==2.0.1
# via ifes-apt-tc-data-modeling (pyproject.toml)
# via ifes_apt_tc_data_modeling (pyproject.toml)
pandocfilters==1.5.0
# via nbconvert
parso==0.8.3
Expand All @@ -245,7 +259,9 @@ pillow==9.5.0
pkginfo==1.9.6
# via twine
platformdirs==3.5.0
# via jupyter-core
# via
# jupyter-core
# pylint
prometheus-client==0.16.0
# via
# jupyter-server
Expand All @@ -265,6 +281,8 @@ py-cpuinfo==9.0.0
# via
# blosc2
# tables
pycodestyle==2.11.1
# via ifes_apt_tc_data_modeling (pyproject.toml)
pycparser==2.21
# via cffi
pygments==2.15.1
Expand All @@ -273,6 +291,8 @@ pygments==2.15.1
# nbconvert
# readme-renderer
# rich
pylint==3.0.3
# via ifes_apt_tc_data_modeling (pyproject.toml)
pyparsing==3.0.9
# via matplotlib
pyrsistent==0.19.3
Expand All @@ -292,7 +312,7 @@ pyzmq==25.0.2
# nbclassic
# notebook
radioactivedecay==0.4.17
# via ifes-apt-tc-data-modeling (pyproject.toml)
# via ifes_apt_tc_data_modeling (pyproject.toml)
readme-renderer==37.3
# via twine
requests==2.29.0
Expand Down Expand Up @@ -331,7 +351,7 @@ stack-data==0.6.2
sympy==1.11.1
# via radioactivedecay
tables==3.9.2
# via ifes-apt-tc-data-modeling (pyproject.toml)
# via ifes_apt_tc_data_modeling (pyproject.toml)
terminado==0.17.1
# via
# jupyter-server
Expand All @@ -343,6 +363,8 @@ tinycss2==1.2.1
# via nbconvert
tomli==2.0.1
# via jupyterlab
tomlkit==0.12.3
# via pylint
tornado==6.3.1
# via
# ipykernel
Expand All @@ -367,7 +389,9 @@ traitlets==5.9.0
# nbformat
# notebook
twine==4.0.2
# via ifes-apt-tc-data-modeling (pyproject.toml)
# via ifes_apt_tc_data_modeling (pyproject.toml)
typing-extensions==4.9.0
# via mypy
tzdata==2023.3
# via pandas
urllib3==1.26.15
Expand All @@ -382,6 +406,8 @@ webencodings==0.5.1
# tinycss2
websocket-client==1.5.1
# via jupyter-server
xmltodict==0.13.0
# via ifes_apt_tc_data_modeling (pyproject.toml)
zipp==3.15.0
# via importlib-metadata

Expand Down
1 change: 0 additions & 1 deletion ifes_apt_tc_data_modeling/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Init file
#
# Copyright The NOMAD Authors.
#
Expand Down
3 changes: 3 additions & 0 deletions ifes_apt_tc_data_modeling/apt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Getting started
AMETEK/Cameca APT file format used in IVAS/APSuite.
https://github.com/CamecaAPT/cameca-customanalysis-interface/wiki/IonData:-Sections
1 change: 0 additions & 1 deletion ifes_apt_tc_data_modeling/apt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Init file
#
# Copyright The NOMAD Authors.
#
Expand Down
54 changes: 24 additions & 30 deletions ifes_apt_tc_data_modeling/apt/apt6_headers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# AMETEK APT(6) data exchange file reader used by atom probe microscopists.
#
# Copyright The NOMAD Authors.
#
Expand All @@ -17,7 +16,7 @@
# limitations under the License.
#

# pylint: disable=no-member,duplicate-code
"""AMETEK APT(6) data exchange file reader used by atom probe microscopists."""

import numpy as np

Expand All @@ -32,13 +31,13 @@ class AptFileHeaderMetadata():
# when developing the parser for their vendor file format
def __init__(self):
# file format signature
self.c_signature = string_to_typed_nparray('APT\0', 4, np.uint8)
self.c_signature = string_to_typed_nparray("APT\0", 4, np.uint8)
# byte length of the file header
self.i_header_size = np.int32(540)
# version number of the file header, currently expecting 2
self.i_header_version = np.int32(2)
# original filename, i.e. *.apt filename, null-terminated UTF-16 !
self.wc_filename = string_to_typed_nparray('', 256, np.uint16)
self.wc_filename = string_to_typed_nparray("", 256, np.uint16)
# file creation time
# according to AMETEK is implemented as a VisualStudio C++ FILETIME
# 64-bit value, which represents the number of 100-nanosecond intervals
Expand All @@ -50,39 +49,34 @@ def __init__(self):
@classmethod
def get_numpy_struct(cls) -> np.dtype:
"""Create customized numpy struct to read a file header at once."""
return np.dtype([('cSignature', np.uint8, (4,)),
('iHeaderSize', np.int32),
('iHeaderVersion', np.int32),
('wcFilename', np.uint16, 256),
('ftCreationTime', np.uint64),
('llIonCount', np.uint64)])
return np.dtype([("cSignature", np.uint8, (4,)),
("iHeaderSize", np.int32),
("iHeaderVersion", np.int32),
("wcFilename", np.uint16, 256),
("ftCreationTime", np.uint64),
("llIonCount", np.uint64)])

def set_ll_ion_count(self, value: np.uint64):
"""Check and set total ion count."""
assert isinstance(value, np.uint64), \
'llIonCount needs to be an int!'
assert value > 0, \
'llIonCount needs to be positive and not zero!'
assert value <= np.iinfo(np.uint64).max, \
'llIonCount is too large, needs to map to np.uint64!'
if isinstance(value, np.uint64) is False:
raise ValueError(f"llIonCount {value} needs to be an uint64!")
if value <= 0:
raise ValueError(f"llIonCount {value} needs to be positive and not zero!")
if value > np.iinfo(np.uint64).max:
raise ValueError(f"llIonCount is too large {value}, needs to map to np.uint64!")
self.ll_ion_count = np.uint64(value)

def matches(self, found_header: np.ndarray) -> bool:
"""Compare a read header against expectation."""
assert np.array_equal(self.c_signature,
found_header['cSignature'][0],
equal_nan=True), \
'Header cSignature differs!'
assert self.i_header_size \
== found_header['iHeaderSize'][0], \
'Header iHeaderSize differs!'
assert self.i_header_version \
== found_header['iHeaderVersion'][0], \
'Header iHeaderVersion differs!'
assert found_header['llIonCount'][0] > 0, \
'Header indicates there are no ions in the file!'

self.set_ll_ion_count(found_header['llIonCount'][0])
if np.array_equal(self.c_signature, found_header["cSignature"][0], equal_nan=True) is False:
raise ValueError("Header cSignature differs!")
if self.i_header_size != found_header["iHeaderSize"][0]:
raise ValueError("Header iHeaderSize differs!")
if self.i_header_version != found_header["iHeaderVersion"][0]:
raise ValueError("Header iHeaderVersion differs!")
if found_header["llIonCount"][0] <= 0:
raise ValueError("Header indicates there are no ions in the file!")
self.set_ll_ion_count(found_header["llIonCount"][0])
return True


Expand Down
Loading

0 comments on commit 349b9eb

Please sign in to comment.