Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update python to go along with matlab changes in 9beee53 #278

Merged
merged 28 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
91136ea
update python to go along with matlab changes in 9beee53
bendhouseart Feb 26, 2024
1f158f8
Merge branch 'main' of github.com:openneuropet/PET2BIDS into 272-ecat…
bendhouseart Mar 6, 2024
9dfc2b0
These these modifications are helping?
bendhouseart Mar 12, 2024
06a3ce0
moved int testing to this repo
bendhouseart Mar 26, 2024
b0fd706
remove redundant step 1
bendhouseart Mar 27, 2024
bee1571
update readme
bendhouseart Apr 2, 2024
24cb01c
nothing wrong with reading
bendhouseart Apr 9, 2024
7ac1aa8
steady as she goes
bendhouseart Apr 24, 2024
2c2d89e
need to make a new output function for first_middle_last_frames_to_te…
bendhouseart Apr 24, 2024
b8b21fd
things diverge after step 7
bendhouseart Apr 24, 2024
d9831b3
step 8 now matches between python and matlab
bendhouseart Apr 27, 2024
3e38914
rounding...
bendhouseart Apr 27, 2024
7b41bb6
it's the nifti's that are the issue..
bendhouseart Apr 29, 2024
161ca42
fixed min/max, need to check difference between outputs before final …
bendhouseart May 9, 2024
f25cdd2
Update ecat2nii.py (#308)
effigies May 9, 2024
13e9271
add seconds back
bendhouseart May 9, 2024
2392575
Update matlab/nii_tool.m remove print
bendhouseart May 9, 2024
6dd9a78
Update matlab/ecat2nii.m uncomment commented out catch
bendhouseart May 9, 2024
202ed34
added seconds back in
bendhouseart May 9, 2024
ba09063
Merge branch '272-ecat-bug-fbp-scaling-negative-values-error' of gith…
bendhouseart May 9, 2024
f946848
put try/catch back in
bendhouseart May 9, 2024
87e7f91
is this what's crashing ci?
bendhouseart May 9, 2024
a029106
add ad-hoc final test script
bendhouseart May 9, 2024
eb0261e
Merge branch 'main' into 272-ecat-bug-fbp-scaling-negative-values-error
bendhouseart May 9, 2024
c3b4d66
run black, add conditional for testing
bendhouseart May 9, 2024
0e3422c
Apply suggestions from code review
bendhouseart May 10, 2024
ad7368f
Update ecat_testing/read_matlab_nii.py
bendhouseart May 10, 2024
28a7db0
bump version before merge to main
bendhouseart May 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions pypet2bids/pypet2bids/ecat2nii.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,14 @@ def ecat2nii(ecat_main_header=None,
f"type(ecat_subheaders)={type(ecat_subheaders)}, "
f"type(ecat_pixel_data)={type(ecat_pixel_data)} instead.")

# set the byte order and the pixel data type from the input array
pixel_data_type = data.dtype

# check for TimeZero supplied via kwargs
if kwargs.get('TimeZero', None):
TimeZero = kwargs['TimeZero']
else:
logger.warn("Metadata TimeZero is missing -- set to ScanStart or empty to use the scanning time as "
logger.warning("Metadata TimeZero is missing -- set to ScanStart or empty to use the scanning time as "
"injection time")

# get image shape
Expand All @@ -106,7 +109,7 @@ def ecat2nii(ecat_main_header=None,
sub_headers[0]['Y_DIMENSION'],
sub_headers[0]['Z_DIMENSION'],
main_header['NUM_FRAMES']),
dtype=numpy.dtype('>f4'))
dtype=">f4")

# collect timing information
start, delta = [], []
Expand All @@ -117,9 +120,8 @@ def ecat2nii(ecat_main_header=None,
# load frame data into img temp
for index in reversed(range(img_shape[3])): # Don't throw stones working from existing matlab code
print(f"Loading frame {index + 1}")
# save out our slice of data before flip to a text file to compare w/ matlab data
img_temp[:, :, :, index] = numpy.flip(numpy.flip(numpy.flip(
data[:, :, :, index].astype(numpy.dtype('>f4')) * sub_headers[index]['SCALE_FACTOR'], 1), 2), 0)
data[:, :, :, index] * sub_headers[index]['SCALE_FACTOR'], 1), 2), 0)
start.append(sub_headers[index]['FRAME_START_TIME'] * 60) # scale to per minute
delta.append(sub_headers[index]['FRAME_DURATION'] * 60) # scale to per minute

Expand All @@ -132,11 +134,23 @@ def ecat2nii(ecat_main_header=None,
prompts.append(0)
randoms.append(0)

# so the only real difference between the matlab code and the python code is that that we aren't manually
# scaling the date to 16 bit integers.
rg = img_temp.max() - img_temp.min()
if rg != 32767:
max_img = img_temp.max()
img_temp = img_temp / max_img * 32767
sca = max_img / 32767
min_img = img_temp.min()
if min_img < -32768:
img_temp = img_temp / (min_img * -32768)
sca = sca * (min_img * -32768)

ecat_cal_units = main_header['CALIBRATION_UNITS'] # Header field designating whether data has already been calibrated
if ecat_cal_units==1: # Calibrate if it hasn't been already
final_image = img_temp * main_header['ECAT_CALIBRATION_FACTOR']
if ecat_cal_units == 1: # Calibrate if it hasn't been already
final_image = img_temp.astype(numpy.single) * sca * main_header['ECAT_CALIBRATION_FACTOR']
else: # And don't calibrate if CALIBRATION_UNITS is anything else but 1
final_image = img_temp
final_image = sca * img_temp.astype(numpy.single)

qoffset_x = -1 * (
((sub_headers[0]['X_DIMENSION'] * sub_headers[0]['X_PIXEL_SIZE'] * 10 / 2) - sub_headers[0][
Expand All @@ -161,7 +175,7 @@ def ecat2nii(ecat_main_header=None,
t[3, 1] = qoffset_y
t[3, 2] = qoffset_z

# note this affine is the transform of of a nibabel ecat object's affine
# note this affine is the transform of a nibabel ecat object's affine
affine = t

img_nii = nibabel.Nifti1Image(final_image, affine=affine)
Expand Down
7 changes: 6 additions & 1 deletion pypet2bids/pypet2bids/read_ecat.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ def read_ecat(ecat_file: str, calibrated: bool = False, collect_pixel_data: bool
for entry, dictionary in ecat_header_maps['ecat_headers'].items():
possible_ecat_headers[entry] = dictionary['mainheader']

# set byte order
byte_order = '>'

confirmed_version = None
for version, dictionary in possible_ecat_headers.items():
try:
Expand Down Expand Up @@ -379,7 +382,8 @@ def read_ecat(ecat_file: str, calibrated: bool = False, collect_pixel_data: bool
formatting = '>f4'
pixel_data_type = numpy.dtype(formatting)
elif dt_val == 6:
pixel_data_type = '>H'
# >H is unsigned short e.g. >u2, reverting to int16 e.g. i2 to align with commit 9beee53
pixel_data_type = '>i2'
else:
raise ValueError(
f"Unable to determine pixel data type from value: {dt_val} extracted from {subheader}")
Expand All @@ -388,6 +392,7 @@ def read_ecat(ecat_file: str, calibrated: bool = False, collect_pixel_data: bool
dtype=pixel_data_type,
count=image_size[0] * image_size[1] * image_size[2]).reshape(
*image_size, order='F')
#pixel_data_matrix_3d.newbyteorder(byte_order)
else:
raise Exception(f"Unable to determine frame image size, unsupported image type {subheader_type_number}")

Expand Down
Loading