Exposure Group Utilities - Unexpected Behavior

I wrote a script to pull in image shift data from .mdoc files generated by SerialEM, and cluster the image shifts into groups. Then I updated my exposures with that new group information, and saved it into my project. However, when I run the Exposure Group Utilities job, with those exposures, and check with “info_only”, it simply outputs a single group.

I assigned the groups to mscope_params/exp_group_id and verified by printing every row that the groups were being assigned (in my case, 0-24). I also loaded the output of one of my updated datasets, and checked that parameter, and it was indeed stored correctly.

Below is the CS portion of my script:

cs = CryoSPARC(license=cs_license, email=cs_email, password=cs_password, host=cs_hostname, base_port=cs_port)
assert cs.test_connection()

project = cs.find_project(cs_project)
job = cs.find_job(cs_project, cs_job)
cs_exposures = job.load_output(cs_job_output)
grouped_exposures = cs_exposures.copy()

for row in grouped_exposures.rows():
    for i in range(len(exposures)):
        if exposures[i]['exposure'] == row['movie_blob/path'].rsplit(sep='/')[-1]:
            row['mscope_params/exp_group_id'] = exposures[i]['group']
            break

#for row in grouped_exposures.rows():
#   print(row['movie_blob/path'], row['mscope_params/exp_group_id'])

project.save_external_result(
    workspace_uid=cs_workspace,
    dataset=grouped_exposures,
    type="exposure",
    name="grouped_exposures",
    slots=["mscope_params"],
    passthrough=(cs_job,cs_job_output),
    title="Grouped Exposures"
    )
 

but they don’t seem to want to show up. Here is my external job:

And here is my “Exposure Group Utilities” job:

Am I missing some other parameter that needs to be set?

EDIT: I just saw that there’s actually support for clustering right in CryoSPARC now, so I updated the beam_shift and beam_shift_known params and with the ImageShift values in the .mdoc files, and it’s working great now. I’m still curious why it didn’t find my manual groups, though.

@ccgauvin94 Please can you post screenshots from the Exposure Group Utilities Parameters and Inputs section:

  • expanded inputs
  • parameters

Here’s the output of the job that is the input:

Here’s the parameters and expanded input:

And here is an example row, showing it has actually updated the exposure group:

Row([
    ('uid', 5533343968883223838),
    ('mscope_params/accel_kv', 200.0),
    ('mscope_params/cs_mm', 2.7),
    ('mscope_params/total_dose_e_per_A2', 56.2),
    ('mscope_params/phase_plate', 0),
    ('mscope_params/neg_stain', 0),
    ('mscope_params/exp_group_id', 4),
    ('mscope_params/defect_path', ''),
    ('mscope_params/beam_shift', [0.297378  0.0683696]),
    ('mscope_params/beam_shift_known', 1),
    ('ctf/type', 'spline'),
    ('ctf/path', 'S1/ctfestimated/20231114_RIC8_Dilution_00262_patch_aligned_ctf_spline.npy'),
    ('ctf/exp_group_id', 1),
    ('ctf/accel_kv', 200.0),
    ('ctf/cs_mm', 2.7),
    ('ctf/amp_contrast', 0.1),
    ('ctf/df1_A', 13990.161),
    ('ctf/df2_A', 13627.588),
    ('ctf/df_angle_rad', -0.8429444),
    ('ctf/phase_shift_rad', 0.0),
    ('ctf/cross_corr_ctffind4', 0.0),
    ('ctf/ctf_fit_to_A', 3.0416863),
    ('ctf/fig_of_merit_gctf', 0.0),
    ('movie_blob/path', 'S1/import_movies/20231114_RIC8_Dilution_00262.tif'),
    ('movie_blob/shape', [  25 4092 5760]),
    ('movie_blob/psize_A', 0.686),
    ('movie_blob/is_gain_corrected', 0),
    ('movie_blob/format', 'TIFF'),
    ('movie_blob/has_defect_file', 0),
    ('movie_blob/import_sig', 11564040647930883326),
    ('micrograph_blob/path', 'S1/motioncorrected/20231114_RIC8_Dilution_00262_patch_aligned_doseweighted.mrc'),
    ('micrograph_blob/idx', 0),
    ('micrograph_blob/shape', [4092 5760]),
    ('micrograph_blob/psize_A', 0.686),
    ('micrograph_blob/format', 'MRC/2'),
    ('micrograph_blob/is_background_subtracted', 1),
    ('micrograph_blob/vmin', -3899.7783),
    ('micrograph_blob/vmax', 3914.893),
    ('micrograph_blob/import_sig', 0),
    ('ctf_stats/type', 'spline'),
    ('ctf_stats/ctf_fit_to_A', 3.0416863),
    ('ctf_stats/cross_corr', 0.0),
    ('ctf_stats/df_range', [13504.425 14142.731]),
    ('ctf_stats/df_tilt_normal', [-0.13653247 -0.02561055]),
    ('ctf_stats/ice_thickness_rel', 1.1037979),
    ('ctf_stats/spectrum_dim', 1568),
    ('ctf_stats/diag_image_path', 'S1/ctfestimated/20231114_RIC8_Dilution_00262_patch_aligned_ctf_diag_2D.mrc'),
    ('ctf_stats/fit_data_path', 'S1/ctfestimated/20231114_RIC8_Dilution_00262_patch_aligned_ctf_diag_plt.npy'),
    ('micrograph_blob_non_dw/path', 'S1/motioncorrected/20231114_RIC8_Dilution_00262_patch_aligned.mrc'),
    ('micrograph_blob_non_dw/idx', 0),
    ('micrograph_blob_non_dw/shape', [4092 5760]),
    ('micrograph_blob_non_dw/psize_A', 0.686),
    ('micrograph_blob_non_dw/format', 'MRC/2'),
    ('micrograph_blob_non_dw/is_background_subtracted', 1),
    ('micrograph_blob_non_dw/vmin', -3899.7783),
    ('micrograph_blob_non_dw/vmax', 3914.893),
    ('micrograph_blob_non_dw/import_sig', 0),
    ('background_blob/path', 'S1/motioncorrected/20231114_RIC8_Dilution_00262_background.mrc'),
    ('background_blob/idx', 0),
    ('background_blob/binfactor', 6),
    ('background_blob/shape', [4092 5760]),
    ('background_blob/psize_A', 0.686),
    ('spline_motion/type', 'spline'),
    ('spline_motion/path', 'S1/motioncorrected/20231114_RIC8_Dilution_00262_bending_traj.npy'),
    ('spline_motion/idx', 0),
    ('spline_motion/frame_start', 0),
    ('spline_motion/frame_end', 25),
    ('spline_motion/zero_shift_frame', 0),
    ('spline_motion/psize_A', 0.686),
    ('micrograph_blob_thumb/path', 'S1/motioncorrected/20231114_RIC8_Dilution_00262_patch_aligned_thumb.mrc'),
    ('micrograph_blob_thumb/idx', 0),
    ('micrograph_blob_thumb/shape', [511 720]),
    ('micrograph_blob_thumb/psize_A', 0.686),
    ('micrograph_blob_thumb/format', 'MRC/2'),
    ('micrograph_blob_thumb/is_background_subtracted', 1),
    ('micrograph_blob_thumb/vmin', -3899.7783),
    ('micrograph_blob_thumb/vmax', -3899.7783),
    ('micrograph_blob_thumb/import_sig', 0),
    ('gain_ref_blob/path', 'S1/import_movies/CountRef_20231114_RIC8_Dilution_00001.mrc'),
    ('gain_ref_blob/idx', 0),
    ('gain_ref_blob/shape', [4092 5760]),
    ('gain_ref_blob/flip_x', 0),
    ('gain_ref_blob/flip_y', 1),
    ('gain_ref_blob/rotate_num', 0),
    ('rigid_motion/type', 'rigid'),
    ('rigid_motion/path', 'S1/motioncorrected/20231114_RIC8_Dilution_00262_traj.npy'),
    ('rigid_motion/idx', 0),
    ('rigid_motion/frame_start', 0),
    ('rigid_motion/frame_end', 25),
    ('rigid_motion/zero_shift_frame', 0),
    ('rigid_motion/psize_A', 0.686),
])

Dear @ccgauvin94,

I believe this is because the exposure group id is stored in two separate fields:

  • mscope_params/exp_group_id
  • ctf/exp_group_id
    Could you try also updating the ctf/exp_group_id field and repeating the above steps, along with re-running the info only Exposure Group Utilities job?

Michael

That did the trick! Thanks Michael.