Skip to content

Commit ccbcc28

Browse files
committed
added decay correction to the CT-based alignment
1 parent 0b5054a commit ccbcc28

File tree

2 files changed

+72
-11
lines changed

2 files changed

+72
-11
lines changed

amypet/align_brkdyn_ct.py

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def align_break_petct(niidat, cts, Cnt, qcpth=None, refpetidx=None, use_stored=F
3939
used as reference instead.
4040
'''
4141

42+
4243
# > output path from the input dictionary
4344
opth = niidat['outpath'].parent
4445

@@ -55,11 +56,16 @@ def align_break_petct(niidat, cts, Cnt, qcpth=None, refpetidx=None, use_stored=F
5556
outdct = np.load(fout, allow_pickle=True)
5657
outdct = outdct.item()
5758
return outdct
59+
else:
60+
# > output dictionary
61+
outdct = {}
5862

5963
# > number of frames for break dynamic acquisitions A and B
6064
nfrmA = len(niidat['series'][0])
6165
nfrmB = len(niidat['series'][1])
6266

67+
outdct['nfrm_t'] = (nfrmA, nfrmB)
68+
6369
# > sort out the correct index for PET reference frame
6470
if refpetidx is not None:
6571
if any([refpetidx[0]<-nfrmA, refpetidx[1]<-nfrmB, refpetidx[0]>=nfrmA, refpetidx[1]>=nfrmB]):
@@ -72,6 +78,38 @@ def align_break_petct(niidat, cts, Cnt, qcpth=None, refpetidx=None, use_stored=F
7278
refpetidx[1] += nfrmB
7379

7480

81+
# > DECAY CORRECTION (if requested)
82+
if Cnt['align']['decay_corr']:
83+
84+
# > get the start time of each series for decay correction if requested
85+
ts = [sri['time'][0] for sri in niidat['descr']]
86+
# > index the earliest ref time
87+
i_tref = np.argmin(ts)
88+
idxs = list(range(len(ts)))
89+
idxs.pop(i_tref)
90+
i_tsrs = idxs
91+
# > time difference
92+
td = [ts[i] - ts[i_tref] for i in i_tsrs]
93+
if len(td) > 1:
94+
raise ValueError(
95+
'currently only one dynamic break is allowed - detected more than one')
96+
else:
97+
td = td[0]
98+
99+
# > what tracer / radionuclide is used?
100+
istp = 'F18' * (niidat['tracer'] in Cnt['tracer']['f18']) + 'C11' * (niidat['tracer'] in Cnt['tracer']['c11'])
101+
102+
# > decay constant using half-life
103+
lmbd = np.log(2) / nimpa.resources.riLUT[istp]['thalf']
104+
105+
# > decay correction factor
106+
dcycrr = np.exp(lmbd * td)
107+
else:
108+
dcycrr = 1.
109+
110+
outdct['dcycrr'] = dcycrr
111+
112+
75113
# > reference images based on CT
76114
fctref = [None, None]
77115
fpetref = [None, None]
@@ -235,9 +273,22 @@ def align_break_petct(niidat, cts, Cnt, qcpth=None, refpetidx=None, use_stored=F
235273

236274
for fi, f in enumerate(algn_frm[1]['faligned']):
237275
print(f)
238-
fcopy = algnFpth/Path(f).name
239-
shutil.copyfile(f, fcopy)
240-
faligned.append(fcopy)
276+
277+
# > correction for decay
278+
if Cnt['align']['decay_corr']:
279+
fdcrr = algnFpth/(Path(f).name.split('.nii')[0]+'_dcrr.nii.gz')
280+
imd = nimpa.getnii(f, output='all')
281+
nimpa.array2nii(
282+
imd['im']*dcycrr,
283+
imd['affine'],
284+
fdcrr,
285+
trnsp=imd['transpose'],
286+
flip=imd['flip'])
287+
faligned.append(fdcrr)
288+
else:
289+
fcopy = algnFpth/Path(f).name
290+
shutil.copyfile(f, fcopy)
291+
faligned.append(fcopy)
241292

242293
faff = affsF/(Path(f).name.split('.nii')[0]+'_affine.txt')
243294
shutil.copyfile(algn_frm[1]['affines'][fi], faff)
@@ -287,11 +338,23 @@ def align_break_petct(niidat, cts, Cnt, qcpth=None, refpetidx=None, use_stored=F
287338

288339
for fi, f in enumerate(algn_frm[i_acq]['faligned']):
289340
print(f)
290-
#fnii_org.append(niidat['series'][i_acq][keys2[fi]]['fnii'])
291341

292-
fcopy = algnFpth/Path(f).name
293-
shutil.copyfile(f, fcopy)
294-
faligned.append(fcopy)
342+
# > correction for decay
343+
if Cnt['align']['decay_corr']:
344+
fdcrr = algnFpth/(Path(f).name.split('.nii')[0]+'_dcrr.nii.gz')
345+
imd = nimpa.getnii(f, output='all')
346+
nimpa.array2nii(
347+
imd['im']*dcycrr,
348+
imd['affine'],
349+
fdcrr,
350+
trnsp=imd['transpose'],
351+
flip=imd['flip'])
352+
faligned.append(fdcrr)
353+
else:
354+
fcopy = algnFpth/Path(f).name
355+
shutil.copyfile(f, fcopy)
356+
faligned.append(fcopy)
357+
295358

296359
faff = affsF/(Path(f).name.split('.nii')[0]+'_affine.txt')
297360
shutil.copyfile(algn_frm[i_acq]['affines'][fi], faff)
@@ -335,9 +398,6 @@ def align_break_petct(niidat, cts, Cnt, qcpth=None, refpetidx=None, use_stored=F
335398
#--------------------------------------------
336399

337400

338-
339-
# > output dictionary
340-
outdct = {}
341401
outdct['align_acq'] = algn_frm
342402
outdct['ctref'] = fctref
343403
outdct['petref'] = fpetref

amypet/params.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pib = ["pib"]
55
flute = ["flt", "flut", "flute", "flutemetamol"]
66
fbb = ["fbb", "florbetaben"]
77
fbp = ["fbp", "florbetapir"]
8+
mk6240 = ["mk6240", "mk-6240"]
89

910
[regpars]
1011
fwhm_t1_mni = 3
@@ -55,5 +56,5 @@ fbb = [5400, 6600, 1200]
5556
fbp = [3000, 3600, 600]
5657

5758
[tracer]
58-
f18 = ['fbb', 'fbp', 'flute', 'mk-6240']
59+
f18 = ['fbb', 'fbp', 'flute', 'mk6240']
5960
c11 = ['pib']

0 commit comments

Comments
 (0)