On this page, we provide a few resources with example code from commonly used software packages to help you start exploring several Atera Onboard Analysis output files.
If you are working with Atera data in an R programming environment, there are several tools available for working with Atera image, cell, and transcript data.
The example below illustrates data analysis use cases with Seurat tools. The function to load Atera data has been optimized for lazy loading and can be run from a desktop computer (recommended specs to process an entire slide of Atera data: 1 TB disk space, SSD hard drive).
If you are working with Atera data in a Python programming environment, there are several tools available for working with Atera image, cell, and transcript data. The examples below illustrate a few of these use cases.
The SpatialData tools function to load Atera data has been optimized for lazy loading and can be run from a desktop computer (recommended specs to process an entire slide of Atera data: 1 TB disk space, SSD hard drive). A demo is provided in this Jupyter notebook to showcase setting up the computing environment, loading the data, and a few use cases.
We highly recommend working with the Zarr file format itself. However, if the Parquet format is needed (e.g., for a third-party tool, such as Proseg), the example below demonstrates how to use Python to convert the transcripts.zarr.zip file to transcripts.parquet format. For larger datasets, you may encounter memory limits for reading and converting the data to Parquet.
# Use the atera_to_parquet function from spatialdata_io import atera_to_parquet # Convert the Atera transcript Zarr bundle into a Parquet file atera_to_parquet( path="path/to/atera_dataset", output="path/to/transcripts.parquet" )
Multi-file OME-TIFF images can be viewed with the commonly used Python package, Tifffile. However, it does not open downsampled multi-file images by default. Downsampled images may be useful for converting to other image file types or for viewing the image if the full resolution is too large. The code snippet below illustrates how to open either full or downsampled resolution images.
To open all of the multi-tissue stain images together, all four ch<number>_<stain name>.ome.tif files must be present in the morphology_2d/ directory.
# Import Python libraries # This code uses python v3.14.6, tifffile v2026.6.1, matplotlib v3.11.0 import tifffile import matplotlib.pyplot as plt # Edit path to file filename="morphology_2d/ch0000_dapi.ome.tif" # This function prints out the resolution levels and shape of each pyramid in the image file. with tifffile.TiffFile(filename) as tif: series = tif.series[0] print("Number of levels:", len(series.levels)) for idx, level in enumerate(series.levels): print(f"Level {idx}: shape={level.shape}, dtype={level.dtype}") # Option 1: Load full resolution image channels # The following may produce a warning: 'OME series cannot read multi-file pyramids'. This is because tifffile does not support loading a pyramidal multi-file OME-TIFF file. Only the full resolution (level=0) data will load for all channels in the directory. fullres_multich_img = tifffile.imread( filename, is_ome=True, level=0, aszarr=False) # Examine shape of array (number of channels, height, width), e.g. (4, 40867, 31318) fullres_multich_img.shape # Extract number of channels, e.g. 4 n_ch = fullres_multich_img.shape[0] # Plot each channel fig, axes = plt.subplots(ncols=n_ch, nrows=1, squeeze=False) for i in range(n_ch): axes[0, i].imshow(fullres_multich_img[i], cmap="gray") axes[0, i].set_title(f"Channel: {i}") plt.savefig('tifffile_fullres_four_channels.png') # Option 2: Load a single channel image at any resolution, e.g., level=0 or level=1. Note 'is_ome' is set to False. # Load one of the multi-file OME-TIFF files as a regular TIFF file at full resolution. fullres_img_tiff = tifffile.imread(filename, is_ome=False, level=0) # Now load the file at downsampled resolution downsampled_img = tifffile.imread(filename, is_ome=False, level=1) # Examine shape of array (number of channels, height, width) downsampled_img.shape # Plot the full resolution and downsampled images side-by-side fig, axes = plt.subplots(ncols=2, nrows=1, squeeze=False) axes[0, 0].imshow(fullres_img_tiff, cmap="gray") axes[0, 0].set_title(f"Full resolution: {fullres_img_tiff.shape}") axes[0, 1].imshow(downsampled_img, cmap="gray") axes[0, 1].set_title(f"Downsampled: {downsampled_img.shape}") plt.savefig('example_fullres_downsample.png')
The zarr Python library documentation and tutorials are available here. These code snippets below show how to read a Zarr array into numpy N-dimensional arrays. This code can be used to explore any of the Atera Onboard Analysis Zarr output files.
Read in the cells.zarr.zip file and take a look at the file's structure:
# Import Python libraries # This script has been tested with zarr v2.13.6, v2.18.3, v3.0.5, v3.2.1 import zarr import numpy as np # Function to open a Zarr file def open_zarr(path: str) -> zarr.Group: store = ( zarr.storage.ZipStore(path, mode="r") if path.endswith(".zip") else zarr.storage.LocalStore(path) ) return zarr.open_group(store=store, mode="r") # For example, use the above function to open the cells Zarr file, which contains segmentation mask Zarr arrays root = open_zarr("cells.zarr.zip") # Look at group array info and structure root.info root.tree() # shows structure, array dimensions, data types # Create cell and nucleus segmentation mask np array objects to read or modify root['masks'].tree() cellseg_mask = np.array(root["masks"]["1"]) nucseg_mask = np.array(root["masks"]["0"]) # Show dimensions of the 2D segmentation mask arrays (also shown in .tree()) # .ndim() shows number of dimensions # The shape should match the number of pixels in the morphology image. cellseg_mask.shape nucseg_mask.shape # Show max value of cells in the masks (value=0 are background pixels) # The .max() method counts all the values that are not 0, which should equal # the total cells detected in the dataset (reported in e.g., analysis_summary.html # summary tab metric). cellseg_mask.max() nucseg_mask.max() # Examples for exploring file contents # How to show array root["masks"]["0"][0:9] # or root["masks/0"] root["cell_summary"][0:9] # How to list out attribute names and values dict(root.attrs.items()) dict(root['cell_summary'].attrs.items()) # How to show attribute values root.attrs["major_version"] root.attrs["segmentation_methods"]
Python or other tools can be used to parse the panel configuration JSON file. Here is example Python code to extract gene name, Ensembl ID, and gene coverage information for each gene target in a given panel:
# Import Python libraries # Example with python v3.14.6, pandas v3.0.3 import json import pandas as pd # Open JSON file f = open('panel_config.json') # Edit file name here # Return JSON object as a dictionary data = json.load(f) # Create lists to store extracted information gene = [] ensembl = [] cov = [] # Iterate through the JSON list to extract information payloads = data.get('payloads', []) if isinstance(payloads, dict): payloads = [payloads] for payload in payloads: for i in payload.get('targets', []): if i['type']['descriptor'] == "gene": gene_name = i['type']['data']['name'] ensembl_id = i['type']['data']['id'] coverage = str(i['info']['gene_coverage']) gene.append(gene_name) ensembl.append(ensembl_id) cov.append(coverage) # Create output CSV file out_df = pd.DataFrame(list(zip(gene, ensembl, cov)), columns=['Gene name', 'Ensembl ID', 'Gene coverage']) out_df.to_csv('my_panel_gene_info.csv', index=False) # Close file f.close()