Skip to content

recon_steps --reconstruction-type full --rotation-axis-method ai crashes with TypeError: cannot unpack non-iterable NoneType object #82

Description

@decarlof

Summary

The AI-based rotation-axis detection (--rotation-axis-method ai) works with tomocupy recon in try mode, but crashes with TypeError: cannot unpack non-iterable NoneType object when combined with tomocupy recon_steps --reconstruction-type full. The failure happens after preprocessing and backprojection have already completed — output h5 is written correctly, then the process dies while trying to hand caches to the AI classifier that were never actually built.

Steps to reproduce

Any recon_steps invocation combining --reconstruction-type full with --rotation-axis-method ai:

tomocupy recon_steps \
  --file-name <some_raw.h5> \
  --reconstruction-type full \
  --rotation-axis-auto auto --rotation-axis-method ai \
  --infer-model-path <model.pt> \
  --retrieve-phase-method paganin --retrieve-phase-alpha 0.001 \
  --propagation-distance 200 --pixel-size 1.4 --energy 30 \
  --fbp-filter shepp \
  --remove-stripe-method vo-all --vo-all-la-size 201 \
  --flat-linear True

Expected behavior

Either
(a) recon_steps internally runs try+AI to find the center, then full recon with that center (the useful behavior), or
(b) recon_steps refuses the combination up front with a clear error message and points the user at the two-step workflow.

Actual behavior

Reconstruction runs to completion (preprocessing, phase retrieval, backprojection, tiff/h5 writing all succeed), then crashes:

Traceback (most recent call last):
  File ".../tomocupy/bin/tomocupy", line 6, in <module>
    sys.exit(main())
  File ".../tomocupy/__main__.py", line 347, in main
    results = args._func(args, cl_reader, cl_writer, save_test_results_ok=save_test_results_ok)
  File ".../tomocupy/__main__.py", line 236, in run_recsteps
    img_cache, center_of_rotation_cache, _ = clpthandle.recon_steps_all()
TypeError: cannot unpack non-iterable NoneType object

recon_steps_all() returned None because the underlying rec_fun for full mode (recon_sino_parallel in reconstruction/backproj_parallel.py:344) has no cache_to_infer branch and never returns anything. Meanwhile run_recsteps unconditionally expects a 3-tuple back.

Root cause

Compare run_rec and run_recsteps in src/tomocupy/__main__.py:

run_rec (line 166) — correct:

cache_to_infer = args.reconstruction_type == 'try' and use_ai

Only try+ai gets the cache-building path.

run_recsteps (line 233) — wrong:

cache_to_infer = use_ai

Full+ai also flips cache_to_infer to True, promising caches that full-mode rec paths never build. Then line 236 unconditionally unpacks a 3-tuple return from recon_steps_all(), which crashes when it returns None.

Additionally, in reconstruction/backproj_parallel.py, only the recon_try_* variants have the if self.cache_to_infer: … return img_cache, center_of_rotation_cache, id_slice_cache branch. The full-recon variants (recon_sino_parallel, recon_sino_proj_parallel) do not. So no matter what cache_to_infer is set to, full-mode rec_funs never return anything.

Suggested fix

Two options, pick based on desired UX:

Minimal — match run_rec's gating and error clearly when the combo is requested:

# in run_recsteps
cache_to_infer = args.reconstruction_type == 'try' and use_ai
if args.reconstruction_type == 'full' and use_ai:
    log.error("--rotation-axis-method ai requires --reconstruction-type try in recon_steps. "
              "Run try mode first to find the center, then re-run with "
              "--rotation-axis-auto manual --rotation-axis <value from try>.")
    exit()

Non-breaking; users get a helpful error instead of a crash.

Better — actually do the useful thing:
When --reconstruction-type full --rotation-axis-method ai is requested via recon_steps, internally run a try+ai pass to find the center, then continue to full recon with that center. Mirrors what a user would want: one command → correct center → full volume.

Environment

  • tomocupy 1.1.0 installed from source (with the earlier inference_pipeline return-value fix applied — without that fix the crash surfaces earlier as set rotation axis None, but this bug is separate)
  • Python 3.10, cupy 12.x
  • CUDA 12.x
  • Linux, 2-BM beamline workstation

Workaround

Split into two tomocupy invocations mediated by the center_of_rotation.txt file that inference_pipeline writes:

# 1. AI center detection (try mode)
tomocupy recon \
  --file-name <raw.h5> \
  --rotation-axis-auto auto --rotation-axis-method ai \
  --infer-model-path <model.pt>

# 2. Read the center and do the full recon
CENTER=$(tail -1 <dirname>_rec/try_center/<basename>/center_of_rotation.txt)
tomocupy recon_steps \
  --file-name <raw.h5> \
  --rotation-axis-auto manual --rotation-axis "$CENTER" \
  --reconstruction-type full \
  <all other flags…>

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions