Adjust per-particle defocus of subparticles in volume alignment tools?

Hi @olibclarke, @rbs_sci! Thanks for this interesting conversation!

Box size

Thank you for bringing the issues which seem to arise with the specific box sizes to our attention! We’ll have to think about this one a bit…

Outlier filtering

I’ve recorded this feature request — and apologies for the cs-tools suggestion below :slight_smile:

Copying higher-order CTF params

Higher-order CTF params live in the following fields:

  • ctf/cs_mm
  • ctf/tilt_A
  • ctf/trefoil_A
  • ctf/tetra_A

Assuming that your subparticles retain their exposure group IDs, you can therefore just copy over the correct values into the field. Here’s a cryosparc-tools script to do this (you’ll need to save as external result afterword, of course).

from cryosparc.tools import CryoSPARC
import json
import numpy as np
from pathlib import Path
with open(Path('~/instance-info.json').expanduser(), 'r') as f:
    instance_info = json.load(f)

cs = CryoSPARC(**instance_info)
assert cs.test_connection()

project_number = "P345"
workspace_number = "W5"
job_number = "J1155"

project = cs.find_project(project_number)
job = project.find_job(job_number)
original_particles = job.load_output("particles")

# obviously, you'll be using a different dataset here,
# but with the same exposure group IDs
subparticles = original_particles.copy()

original_particles.filter_prefix("ctf")

# arbitrarily take single row from each exposure group to access their higher-order CTF params
# we can do this because we know that each exp group has identical values for these params
exposure_groups = list(np.unique(original_particles["ctf/exp_group_id"]))
exposure_group_rows = {
    exp_group: original_particles.query({"ctf/exp_group_id": exp_group})[0]
    for exp_group in exposure_groups
}

# you can change what is copied over here
higher_order_param_colnames = [
    "ctf/cs_mm",
    "ctf/tilt_A",
    "ctf/trefoil_A",
    "ctf/tetra_A",
]

higher_order_param_values = {}
# result: {param_name: {exposure_group: value}}
for colname in higher_order_param_colnames:
    higher_order_param_values[colname] = {
        exp_group: exposure_group_rows[exp_group][colname]
        for exp_group in exposure_groups
    }

for hop_name in higher_order_param_colnames:
    updated_values = [
        higher_order_param_values[hop_name][exp_group] for exp_group in subparticles["ctf/exp_group_id"]
    ]
    subparticles[hop_name] = updated_values

There’s likely a more elegant way to do it, but that’ll work!

Hope that helps!

2 Likes