Open and Create a Molecule Archive in Python

level: beginner, duration: 10 min

In this tutorial you will learn how to open, explore, and create Molecule Archives (.yama files) directly in Python — in a Jupyter notebook, a plain script, or anywhere else Python runs. This uses marspylib, a pure-Python library that reads and writes the .yama format natively.

No Fiji, no Java, no special environment is required. marspylib does not talk to Fiji at all — it decodes the .yama file format directly — so setup is just installing one package.

Install marspylib

If you use Anaconda or Miniconda, create an environment with marspylib and Jupyter in one step:

conda create -n mars-python -c conda-forge marspylib notebook
conda activate mars-python
jupyter notebook

Your browser will open with the Jupyter interface. Create a new notebook (New -> Python 3) and you’re ready to go.

If you prefer plain pip, this works just as well:

pip install marspylib notebook
jupyter notebook

The code below can be copied into a notebook cell and run with “Shift + Enter” (“Option/Alt + Enter” runs the cell and creates a new one below it, which is convenient for working through the rest of this tutorial).

Open an Existing Molecule Archive

To start, open a .yama file that was saved from Fiji/Mars Rover (or from another Python session — see Create a New Molecule Archive below). For this tutorial you can download the example TestVideo_archive_var.yama from the git tutorials repository (the same archive used in the Let’s calculate the Variance tutorial). Use GitHub’s “Download raw file” button on that page rather than right-click-save, since the file is stored with Git LFS.

import marspylib.yama as yama

archive = yama.open('/path/to/TestVideo_archive_var.yama')  # use your own file path

That’s it — archive now holds every molecule and metadata record from the file, ready to explore. Note the file path has to point to wherever you saved the archive on your computer.

Explore the Archive

Number of molecules

len(archive)

This also works: archive.properties.number_of_molecules.

Molecule UIDs Every molecule has a unique ID (UID). Looping over the archive gives you the molecule objects directly — no separate lookup step needed:

for molecule in archive:
    print(molecule.uid)

A single molecule Molecules are accessed by UID, like a dictionary:

molecule = archive['2AEygnwajcvHUBYGGUHcNa']  # use one of the UIDs printed above
molecule.tags          # e.g. ['Active']
molecule.parameters    # e.g. {'Channel': 0.0, 'var': 0.0136}

The data table Every molecule carries a table of traces (e.g. position over time) as a pandas DataFrame — no conversion step is needed, it’s ready to use immediately:

molecule.table

Get Started with Simple Operations

Check tags and get a parameter
This loop prints the UID of every molecule tagged 'Active' together with its 'var' parameter:

for molecule in archive:
    if molecule.has_tag('Active'):
        print(molecule.uid, molecule.parameters['var'])

Plot a distribution
The 'var' parameter calculated in the variance tutorial can be collected into a list and plotted directly with matplotlib:

import matplotlib.pyplot as plt
import numpy as np

variances = [molecule.parameters['var'] for molecule in archive]

bins = round(np.sqrt(len(variances)))
plt.hist(variances, bins=bins, alpha=0.5)
plt.title('Variance')
plt.xlabel('var')
plt.ylabel('count')
plt.show()

That’s the core loop you’ll use over and over: iterate over archive, read .tags / .parameters / .table, collect what you need into a list, and hand it to matplotlib (or pandas, or seaborn, or anything else in the Python ecosystem).

Create a New Molecule Archive from Scratch

You don’t need Fiji to build a .yama file either — you can construct one entirely in Python. This is a simple example with three molecules, each holding a small table:

import pandas as pd
import marspylib.yama as yama

properties = yama.Properties(archive_type=yama.ARCHIVE_TYPES['SingleMoleculeArchive'])
archive = yama.Archive(properties, metadata={}, molecules={})

metadata = yama.MarsMetadata(microscope='My Microscope', source_directory='/data/my_experiment')
archive.put_metadata(metadata)

for i in range(3):
    molecule = yama.SingleMolecule(metadata_uid=metadata.uid)
    molecule.add_tag('accepted')
    molecule.parameters['dwell'] = 5.5 + i
    molecule.table = pd.DataFrame({
        'T': [0.0, 1.0, 2.0],
        'Intensity': [10.1 + i, 10.5 + i, 10.9 + i],
    })
    archive.put(molecule)   # molecule.uid was generated automatically

archive.save('my_first_archive.yama')

Reopen it to check that everything saved correctly:

archive = yama.open('my_first_archive.yama')
len(archive)   # 3

This same archive can be opened later in Fiji/Mars Rover, just like any other .yama file.

Next Steps

This tutorial deliberately kept things simple. For more patterns — working with tags, parameters, regions and positions, segment tables, large .yama.store archives, and archives stored on S3 — continue with Common python functions and patterns.

If you’re coming from Groovy/Java scripting in Fiji and looking for the Python equivalent of a method you already know, marspylib’s README has a full method-name mapping table, and the full API reference is at marspylib.readthedocs.io.