Loading an FEI/TIA Project File (.emi)

An .emi file does not contain the image itself. It stores metadata and points to one or more .ser files in the same folder that hold the pixel data.

This notebook shows that load_data(), using RosettaSciIO [56], follows that link automatically, so you can open the .emi file directly.

JuSPICE Modules and Classes

  • juspice.io: SPICEData, load_data, save_data

  • SPICEData.preprocess: built-in preprocessing accessor

  • juspice.tracking: Tracker

[1]:
from juspice.tracking import Tracker

tracker = Tracker(include_metadata=True, notes='EM (.emi) io basics')

tracker.recording_start()
/Users/amir/GIT_repositories/juspice_pre_release/venvs/.venv/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
[2]:
# --------- Block 0: Setup ----------

# Standard library
from pathlib import Path
import sys
import os

# Third-party
import numpy as np
import matplotlib.pyplot as plt

# JuSPICE
from juspice.io import SPICEData, load_data, save_data

# Paths
try:
    notebook_dir = Path(__file__).resolve().parent
except Exception:
    notebook_dir = Path.cwd()

cur = notebook_dir
repo_root = None
for _ in range(6):
    if (cur / 'juspice').exists() or (cur / 'pyproject.toml').exists():
        repo_root = cur
        break
    if cur.parent == cur:
        break
    cur = cur.parent
if repo_root is None:
    repo_root = notebook_dir
if str(repo_root) not in sys.path:
    sys.path.insert(0, str(repo_root))

[3]:
tracker.recording_stop()

Load the project file

We open the .emi file; the image is read from its companion LMP_LATP_EDS_Location3_0001_1.ser, the same file opened in the .ser notebook. n_series tells us how many image series the project contains (here, one).

[4]:
tracker.recording_start()
[5]:
# --------- Block 1: Load ----------

emi_path = os.path.join(
    repo_root, 'Sample_data', 'em', 'LMP_LATP_EDS_Location3_0001.emi'
)
print(f'EMI file path: {emi_path}')

# `spice` is just a variable name for the SPICEData instance load_data()
# returns here — any name would work; we use `spice` throughout these
# notebooks as an intuitive nod to JuSPICE / SPICEData.
spice = load_data(emi_path)
print(f'data_type:  {spice.data_type}')
print(f'data.shape: {spice.data.shape}')
print(f'data.dtype: {spice.data.dtype}')
print(f'pixel_size: {spice.metadata["pixel_size"]}')
print(f'pixel_unit: {spice.metadata["pixel_unit"]}')
print(f'n_series:   {spice.metadata["n_series"]}')

EMI file path: /Users/amir/GIT_repositories/juspice_pre_release/Sample_data/em/LMP_LATP_EDS_Location3_0001.emi
data_type:  em_emi
data.shape: (1024, 1024)
data.dtype: uint16
pixel_size: [1.079526422547315, 1.079526422547315]
pixel_unit: ['nm', 'nm']
n_series:   1
[6]:
tracker.recording_stop()

The metadata confirms which .ser file supplied the image and when it was recorded.

[7]:
tracker.recording_start()
[8]:
# --------- Block 2: Inspect acquisition metadata ----------

acquisition = spice.metadata['acquisition']
print('General:', acquisition.get('General'))

General: {'original_filename': 'LMP_LATP_EDS_Location3_0001_1.ser', 'date': '2023-02-27', 'time': '14:11:12'}
[9]:
tracker.recording_stop()

The raw image and its histogram:

[10]:
tracker.recording_start()
[11]:
# --------- Block 3: Visualize ----------

spice.preprocess.show_image(
    title='LMP_LATP EMI Image (raw)', show_colorbar=True, show_histogram=True
)
../../_images/notebooks_io_io_emi_14_0.png
[12]:
tracker.recording_stop()

Check that the standard tools work

normalize() rescales the intensities to 0–1, exactly as for any other image.

[13]:
tracker.recording_start()
[14]:
# --------- Block 4: Normalize via spice.preprocess ----------

spice.preprocess.normalize()
print(f'Size of the normalized image: {spice.data.shape}')
spice.preprocess.show_image(
    title='LMP_LATP EMI Image (normalized)', show_colorbar=True, show_histogram=True
)
Size of the normalized image: (1024, 1024)
../../_images/notebooks_io_io_emi_18_1.png
[15]:
tracker.recording_stop()

Save and review

Saving writes the data, its metadata, and a script that recreates it.

[16]:
tracker.recording_start()
[17]:
# --------- Block 5: Save ----------
# This folder holds several notebooks, so save_data()'s automatic
# notebook-name detection would be ambiguous when run outside a live
# Jupyter session (e.g. via nbconvert) — pass output_stem explicitly
# to always land on this notebook's own files. See
# docs/repository_structure.rst.
stem = 'io_emi'
save_data(
    spice,
    output_stem=str(notebook_dir / stem),
)
print(f'Data:           {os.path.join(notebook_dir, stem + ".npy")}')
print(f'JSON sidecar:   {os.path.join(notebook_dir, stem + ".json")}')
print(f'History script: {os.path.join(notebook_dir, stem + "_history.py")}')

Data:           /Users/amir/GIT_repositories/juspice_pre_release/notebooks/io/io_emi.npy
JSON sidecar:   /Users/amir/GIT_repositories/juspice_pre_release/notebooks/io/io_emi.json
History script: /Users/amir/GIT_repositories/juspice_pre_release/notebooks/io/io_emi_history.py
[18]:
tracker.recording_stop()

The history lists every step as runnable code.

[19]:
tracker.recording_start()
[20]:
# --------- Block 6: Inspect human-readable history ----------

readable_lines = spice.history.to_lines()
print('Reconstructed pipeline for this SPICEData object:')
print('\n'.join(readable_lines))

Reconstructed pipeline for this SPICEData object:
import juspice
spice = juspice.io.load_data('/Users/amir/GIT_repositories/juspice_pre_release/Sample_data/em/LMP_LATP_EDS_Location3_0001.emi')
spice.preprocess.normalize()
juspice.io.save_data(spice)
[21]:
tracker.recording_stop()