Starguide reconstruction in forward function

Thank you Luke for this exceptional effort.
I am trying to recon starguide data and I see Seperable1DBlurNet.forward recives an 2D input in some place and throws an erro in permute function.
Do you have any idea how to solve it?
Thank you

Hey Yazdan, sorry for the super late reply here, can you share a screenshot of what you are doing? Or would you like to set up a video call?

You are welcome Luke. Thank you for your response.
this is the code I copied from your instruction:

code

import yazdan
import sys
import os
from glob import glob
from termcolor import cprint
from natsort import os_sorted
from tqdm import tqdm
import pandas as pd
import SimpleITK as sitk
import numpy as np
import shutil
import matplotlib.pyplot as plt
import pydicom
from pytomography.transforms.SPECT import SPECTAttenuationTransform, SPECTPSFTransform
from pytomography.io.SPECT import dicom
from pytomography.algorithms import OSEM
from pytomography.likelihoods import PoissonLogLikelihood
from pytomography.projectors.SPECT import StarGuideSystemMatrix
############################ import defaults ############################
if name == “main”:
scatter_correction = True
# Define the path to the data
PATH = r’D:\test-pytomography’
# Get the file paths of the 12 projection DICOM files
path_NM = os.path.join(PATH, ‘starguide’, ‘NM_files’)
files_NM = glob(os.path.join(path_NM, “*”))[:12]
# Retrieve metadata and projection data
object_meta, proj_meta = dicom.get_starguide_metadata(files_NM, nearest_theta=0.1)
projections = dicom.get_starguide_projections(files_NM)
print(projections.shape) # Expected output: torch.Size([2, 2575, 16, 112])
# Obtain the attenuation map and transform
path_CT = os.path.join(PATH, ‘starguide’, ‘CT_files’)
files_CT = [os.path.join(path_CT, file) for file in os.listdir(path_CT)]
files_CT = [x for x in files_CT if not “.ini” in x]
attenuation_map = dicom.get_starguide_attenuation_map_from_CT_slices(files_CT, files_NM, index_peak=0)
attenuation_transform = SPECTAttenuationTransform(attenuation_map, assume_padded=False)
print(“attenuation map generated”)
# Define the PSF transform
psf_meta = dicom.get_psfmeta_from_scanner_params(
‘G8-LEHR’, # Collimator parameters from the header
energy_keV=140.5, # Imaging of Tc-99m
material=‘tungsten’, # Known material
shape=‘square’ # Collimator hole shape
)
psf_transform = SPECTPSFTransform(psf_meta, assume_padded=False)
print(“psf_transform was defined”)
# Build the system matrix
system_matrix = StarGuideSystemMatrix(
object_meta=object_meta,
proj_meta=proj_meta,
# obj2obj_transforms=[psf_transform],
proj2proj_transforms=
)
print(“system matrix was defined”)
# Separate photopeak and scatter for the likelihood
photopeak = projections[0]
# yazdan.image.view([photopeak])
if scatter_correction:
scatter = dicom.get_energy_window_scatter_estimate_projections(
files_NM[0],
projections,
index_peak=0,
index_lower=1
)
# Define the likelihood and reconstruct using OSEM
likelihood = PoissonLogLikelihood(system_matrix, photopeak, additive_term=scatter)
else:
likelihood = PoissonLogLikelihood(system_matrix, photopeak)

reconstruction_algorithm = OSEM(likelihood)
print("reconstruction_algorithm was set")

recon_pytomography = reconstruction_algorithm(n_iters=4, n_subsets=4)
print("reconstruction_algorithm was executed")

# Load vendor reconstruction for comparison

Output

it recives a 2D array in forward. I changed the data, the error exists with ether a single bed or multi bed scan.

this is the error:
torch.Size([5, 3350, 16, 112])
attenuation map generated
psf_transform was defined
system matrix was defined
reconstruction_algorithm was set
Traceback (most recent call last):
File “C:\Users\Yazdan\Downloads\pytomoexample.py”, line 83, in
recon_pytomography = reconstruction_algorithm(n_iters=4, n_subsets=4)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Yazdan\anaconda3\envs\image\Lib\site-packages\pytomography\algorithms\preconditioned_gradient_ascent.py”, line 119, in call
likelihood_gradient = self.likelihood.compute_gradient(self.object_prediction, subset_idx)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Yazdan\anaconda3\envs\image\Lib\site-packages\pytomography\likelihoods\poisson_log_likelihood.py”, line 34, in compute_gradient
self.projections_predicted = self.system_matrix.forward(object, subset_idx) + additive_term_subset
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Yazdan\anaconda3\envs\image\Lib\site-packages\torch\utils_contextlib.py”, line 116, in decorate_context
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Yazdan\anaconda3\envs\image\Lib\site-packages\pytomography\projectors\SPECT\starguide_system_matrix.py”, line 64, in forward
obj_translate_rot = self._translate_object(obj_rotate, offsets_i/self.object_meta.dx)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Yazdan\anaconda3\envs\image\Lib\site-packages\pytomography\projectors\SPECT\starguide_system_matrix.py”, line 167, in _translate_object
obj_translated = Translate(translation)(obj.permute((0,3,1,2))).permute((0,2,3,1))
^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: permute(sparse_coo): number of dimensions in the tensor input does not match the length of the desired ordering of dimensions i.e. input.dim() = 3 is not equal to len(dims) = 4