Skip to content

Commit 51541d5

Browse files
committed
Bounds update
1 parent bf52071 commit 51541d5

11 files changed

+102
-169
lines changed

src/standardized/ASD_MemorialSloanKettering_QAMPER_IVIM.py

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ def __init__(self, bvalues=None, thresholds=None, bounds=None, initial_guess=Non
4141
Our OsipiBase object could contain functions that compare the inputs with
4242
the requirements.
4343
"""
44-
#super(OGC_AmsterdamUMC_biexp, self).__init__(bvalues, bounds, initial_guess, fitS0)
4544
super(ASD_MemorialSloanKettering_QAMPER_IVIM, self).__init__(bvalues=bvalues, bounds=bounds, initial_guess=initial_guess)
46-
self.initialize(bounds, initial_guess)
45+
46+
self.use_bounds = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
47+
self.use_initial_guess = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
48+
4749
if eng is None:
4850
print('initiating matlab; this may take some time. For repeated testing one could use the optional input eng as an already initiated matlab engine')
4951
self.eng=matlab.engine.start_matlab()
@@ -63,22 +65,6 @@ def algorithm(self,dwi_arr, bval_arr, LB0, UB0, x0in):
6365
(f_arr, D_arr, Dx_arr, s0_arr, fitted_dwi_arr, RSS, rms_val, chi, AIC, BIC, R_sq) = results
6466
return D_arr/1000, f_arr, Dx_arr/1000, s0_arr
6567

66-
def initialize(self, bounds, initial_guess):
67-
if self.bounds is None:
68-
print('warning, no bounds were defined, so algorithm-specific default bounds are used')
69-
self.bounds=([1e-6, 0, 0.004, 0],[0.003, 1.0, 0.2, 5])
70-
else:
71-
self.bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
72-
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
73-
if self.initial_guess is None:
74-
print('warning, no initial guesses were defined, so algorithm-specific default initial guess is used')
75-
self.initial_guess = [0.001, 0.2, 0.01, 1]
76-
else:
77-
self.initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
78-
self.use_initial_guess = True
79-
self.use_initial_guess = True
80-
self.use_bounds = True
81-
8268
def ivim_fit(self, signals, bvalues, **kwargs):
8369
"""Perform the IVIM fit
8470
@@ -89,12 +75,16 @@ def ivim_fit(self, signals, bvalues, **kwargs):
8975
Returns:
9076
_type_: _description_
9177
"""
78+
bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
79+
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
80+
81+
initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
9282

9383
bvalues=np.array(bvalues)
94-
LB = np.array(self.bounds[0])[[1,0,2,3]]
95-
UB = np.array(self.bounds[1])[[1,0,2,3]]
84+
LB = np.array(bounds[0])[[1,0,2,3]]
85+
UB = np.array(bounds[1])[[1,0,2,3]]
9686

97-
fit_results = self.algorithm(np.array(signals)[:,np.newaxis], bvalues, LB, UB, np.array(self.initial_guess)[[1,0,2,3]])
87+
fit_results = self.algorithm(np.array(signals)[:,np.newaxis], bvalues, LB, UB, np.array(initial_guess)[[1,0,2,3]])
9888

9989
results = {}
10090
results["D"] = fit_results[0]

src/standardized/OGC_AmsterdamUMC_Bayesian_biexp.py

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,13 @@ def __init__(self, bvalues=None, thresholds=None, bounds=None, initial_guess=Non
5757
self.fit_segmented=fit_segmented
5858

5959
def initialize(self, bounds=None, initial_guess=None, fitS0=True, prior_in=None, thresholds=None):
60-
61-
62-
if bounds is None:
63-
print('warning, no bounds were defined, so default bounds are used of [0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3]')
64-
self.bounds=([0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3])
65-
else:
66-
self.bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
67-
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
68-
if initial_guess is None:
69-
print('warning, no initial guesses were defined, so default bounds are used of [0.001, 0.001, 0.01, 1]')
70-
self.initial_guess = [0.001, 0.001, 0.01, 1]
71-
else:
72-
self.initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
73-
self.use_initial_guess = True
74-
self.use_bounds = True
75-
if thresholds is None:
76-
print('warning, no bounds were defined, so default bounds are used of [0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3]')
77-
thresholds = 150
60+
self.use_initial_guess = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
61+
self.use_bounds = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
7862
self.thresholds = thresholds
63+
7964
if prior_in is None:
8065
print('using a flat prior between bounds')
81-
self.neg_log_prior=flat_neg_log_prior([self.bounds[0][0],self.bounds[1][0]],[self.bounds[0][1],self.bounds[1][1]],[self.bounds[0][2],self.bounds[1][2]],[self.bounds[0][3],self.bounds[1][3]])
66+
self.neg_log_prior=flat_neg_log_prior([self.bounds["D"][0],self.bounds["D"][1]],[self.bounds["f"][0],self.bounds["f"][1]],[self.bounds["Dp"][0],self.bounds["Dp"][1]],[self.bounds["S0"][0],self.bounds["S0"][1]])
8267
else:
8368
print('warning, bounds are not used, as a prior is used instead')
8469
if len(prior_in) == 4:
@@ -97,15 +82,20 @@ def ivim_fit(self, signals, bvalues, initial_guess=None, **kwargs):
9782
Returns:
9883
_type_: _description_
9984
"""
85+
bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
86+
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
87+
88+
initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
89+
10090
bvalues=np.array(bvalues)
10191

10292
epsilon = 0.000001
103-
fit_results = fit_segmented(bvalues, signals, bounds=self.bounds, cutoff=self.thresholds, p0=self.initial_guess)
93+
fit_results = fit_segmented(bvalues, signals, bounds=bounds, cutoff=self.thresholds, p0=initial_guess)
10494
fit_results=np.array(fit_results+(1,))
10595
for i in range(4):
106-
if fit_results[i] < self.bounds[0][i] : fit_results[0] = self.bounds[0][i]+epsilon
107-
if fit_results[i] > self.bounds[1][i] : fit_results[0] = self.bounds[1][i]-epsilon
108-
fit_results = self.OGC_algorithm(bvalues, signals, self.neg_log_prior, x0=fit_results, fitS0=self.fitS0, bounds=self.bounds)
96+
if fit_results[i] < bounds[0][i] : fit_results[0] = bounds[0][i]+epsilon
97+
if fit_results[i] > bounds[1][i] : fit_results[0] = bounds[1][i]-epsilon
98+
fit_results = self.OGC_algorithm(bvalues, signals, self.neg_log_prior, x0=fit_results, fitS0=self.fitS0, bounds=bounds)
10999

110100
results = {}
111101
results["D"] = fit_results[0]
@@ -122,6 +112,11 @@ def ivim_fit_full_volume(self, signals, bvalues, njobs=4, **kwargs):
122112
Returns:
123113
_type_: _description_
124114
"""
115+
bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
116+
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
117+
118+
initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
119+
125120
# normalize signals
126121
# Get index of b=0
127122
shape=np.shape(signals)
@@ -140,19 +135,19 @@ def ivim_fit_full_volume(self, signals, bvalues, njobs=4, **kwargs):
140135
bvalues=np.array(bvalues)
141136

142137
epsilon = 0.000001
143-
fit_results = np.array(fit_segmented_array(bvalues, signals, bounds=self.bounds, cutoff=self.thresholds, p0=self.initial_guess))
138+
fit_results = np.array(fit_segmented_array(bvalues, signals, bounds=bounds, cutoff=self.thresholds, p0=initial_guess))
144139
#fit_results=np.array(fit_results+(1,))
145140
# Loop over parameters (rows)
146141

147142
for i in range(4):
148143
if i == 3:
149144
fit_results[i] = np.random.normal(1,0.2,np.shape(fit_results[i]))
150145
else:
151-
below = fit_results[i] < self.bounds[0][i]
152-
above = fit_results[i] > self.bounds[1][i]
146+
below = fit_results[i] < bounds[0][i]
147+
above = fit_results[i] > bounds[1][i]
153148

154-
fit_results[i, below] = self.bounds[0][i] + epsilon
155-
fit_results[i, above] = self.bounds[1][i] - epsilon
149+
fit_results[i, below] = bounds[0][i] + epsilon
150+
fit_results[i, above] = bounds[1][i] - epsilon
156151
self.jobs=njobs
157152
fit_results = self.OGC_algorithm_array(bvalues, signals,fit_results, self)
158153

src/standardized/OGC_AmsterdamUMC_biexp.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,8 @@ def __init__(self, bvalues=None, thresholds=None, bounds=None, initial_guess=Non
4747
self.OGC_algorithm = fit_least_squares
4848
self.OGC_algorithm_array = fit_least_squares_array
4949
self.fitS0=fitS0
50-
self.initialize(bounds, initial_guess, fitS0)
51-
52-
def initialize(self, bounds, initial_guess, fitS0):
53-
if bounds is None:
54-
print('warning, no bounds were defined, so default bounds are used of [0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3]')
55-
self.bounds=([0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3])
56-
else:
57-
self.bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
58-
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
59-
if initial_guess is None:
60-
print('warning, no initial guesses were defined, so default bounds are used of [0.001, 0.001, 0.01, 1]')
61-
self.initial_guess = [0.001, 0.1, 0.01, 1]
62-
else:
63-
self.initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
64-
self.use_initial_guess = True
65-
self.fitS0=fitS0
66-
self.use_initial_guess = True
67-
self.use_bounds = True
50+
self.use_initial_guess = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
51+
self.use_bounds = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
6852

6953
def ivim_fit(self, signals, bvalues, **kwargs):
7054
"""Perform the IVIM fit
@@ -76,9 +60,13 @@ def ivim_fit(self, signals, bvalues, **kwargs):
7660
Returns:
7761
_type_: _description_
7862
"""
63+
bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
64+
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
65+
66+
initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
7967

8068
bvalues=np.array(bvalues)
81-
fit_results = self.OGC_algorithm(bvalues, signals, p0=self.initial_guess, bounds=self.bounds, fitS0=self.fitS0)
69+
fit_results = self.OGC_algorithm(bvalues, signals, p0=initial_guess, bounds=bounds, fitS0=self.fitS0)
8270

8371
results = {}
8472
results["D"] = fit_results[0]

src/standardized/OGC_AmsterdamUMC_biexp_segmented.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,15 @@ def __init__(self, bvalues=None, thresholds=150, bounds=None, initial_guess=None
4545
super(OGC_AmsterdamUMC_biexp_segmented, self).__init__(bvalues, thresholds, bounds, initial_guess)
4646
self.OGC_algorithm = fit_segmented
4747
self.OGC_algorithm_array = fit_segmented_array
48-
self.initialize(bounds, initial_guess, thresholds)
49-
48+
self.initialize(thresholds)
5049

51-
def initialize(self, bounds, initial_guess, thresholds):
52-
if bounds is None:
53-
print('warning, no bounds were defined, so default bounds are used of [0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3]')
54-
self.bounds=([0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3])
55-
else:
56-
self.bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
57-
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
58-
if initial_guess is None:
59-
print('warning, no initial guesses were defined, so default bounds are used of [0.001, 0.001, 0.01, 1]')
60-
self.initial_guess = [0.001, 0.001, 0.01, 1]
61-
else:
62-
self.initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
63-
self.use_initial_guess = True
64-
self.use_bounds = True
65-
if thresholds is None:
50+
def initialize(self, thresholds):
51+
self.use_initial_guess = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
52+
self.use_bounds = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
53+
54+
if self.thresholds is None:
6655
self.thresholds = 150
67-
print('warning, no thresholds were defined, so default bounds are used of 150')
56+
print('warning, no thresholds were defined, so default threshold of 150 was used')
6857
else:
6958
self.thresholds = thresholds
7059

@@ -78,9 +67,13 @@ def ivim_fit(self, signals, bvalues, **kwargs):
7867
Returns:
7968
_type_: _description_
8069
"""
70+
bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
71+
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
72+
73+
initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
8174

8275
bvalues=np.array(bvalues)
83-
fit_results = self.OGC_algorithm(bvalues, signals, bounds=self.bounds, cutoff=self.thresholds, p0=self.initial_guess)
76+
fit_results = self.OGC_algorithm(bvalues, signals, bounds=bounds, cutoff=self.thresholds, p0=initial_guess)
8477

8578
results = {}
8679
results["D"] = fit_results[0]

src/standardized/OJ_GU_bayesMATLAB.py

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ def __init__(self, bvalues=None, thresholds=None, bounds=None, initial_guess=Non
4343
"""
4444
#super(OGC_AmsterdamUMC_biexp, self).__init__(bvalues, bounds, initial_guess, fitS0)
4545
super(OJ_GU_bayesMATLAB, self).__init__(bvalues=bvalues, bounds=bounds, initial_guess=initial_guess)
46-
self.initialize(bounds, initial_guess)
46+
47+
self.use_initial_guess = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
48+
self.use_bounds = {"f" : True, "D" : True, "Dp" : True, "S0" : True}
49+
4750
if eng is None:
4851
print('initiating matlab; this may take some time. For repeated testing one could use the optional input eng as an already initiated matlab engine')
4952
self.eng=matlab.engine.start_matlab()
@@ -52,33 +55,17 @@ def __init__(self, bvalues=None, thresholds=None, bounds=None, initial_guess=Non
5255
self.eng = eng
5356
self.keep_alive=True
5457

55-
def algorithm(self, Y, b, lim, blim):
58+
def algorithm(self, Y, b, lim, blim, initial_guess):
5659
Y = matlab.double(Y.tolist())
57-
f = matlab.double(self.initial_guess[1])
58-
D = matlab.double(self.initial_guess[0])
59-
Dstar = matlab.double(self.initial_guess[2])
60-
S0 = matlab.double(self.initial_guess[3])
60+
f = matlab.double(initial_guess[1])
61+
D = matlab.double(initial_guess[0])
62+
Dstar = matlab.double(initial_guess[2])
63+
S0 = matlab.double(initial_guess[3])
6164
b = matlab.double(b.tolist())
6265
lim = matlab.double(lim.tolist())
6366
out = self.eng.IVIM_bayes(Y, f, D, Dstar, S0, b, lim, nargout=1)
6467
return out['D']['mode'], out['f']['mode'], out['Dstar']['mode'], out['S0']['mode']
6568

66-
def initialize(self, bounds,initial_guess):
67-
if bounds is None:
68-
print('warning, no bounds were defined, so default bounds are used of [0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3]')
69-
self.bounds=([0, 0, 0.005, 0.7],[0.005, 1.0, 0.2, 1.3])
70-
else:
71-
self.bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
72-
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
73-
if initial_guess is None:
74-
print('warning, no initial guesses were defined, so default bounds are used of [0.001, 0.001, 0.01, 1]')
75-
self.initial_guess = [0.001, 0.1, 0.01, 1]
76-
else:
77-
self.initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
78-
self.use_initial_guess = True
79-
self.use_initial_guess = True
80-
self.use_bounds = True
81-
8269
def ivim_fit(self, signals, bvalues, **kwargs):
8370
"""Perform the IVIM fit
8471
@@ -89,11 +76,16 @@ def ivim_fit(self, signals, bvalues, **kwargs):
8976
Returns:
9077
_type_: _description_
9178
"""
79+
bounds = ([self.bounds["D"][0], self.bounds["f"][0], self.bounds["Dp"][0], self.bounds["S0"][0]],
80+
[self.bounds["D"][1], self.bounds["f"][1], self.bounds["Dp"][1], self.bounds["S0"][1]])
81+
82+
initial_guess = [self.initial_guess["D"], self.initial_guess["f"], self.initial_guess["Dp"], self.initial_guess["S0"]]
9283

9384
fit_results = self.algorithm(np.array(signals)[:,np.newaxis],
9485
np.array(bvalues),
95-
np.array(self.bounds)[:,[1,0,2,3]],
96-
self.thresholds)
86+
np.array(bounds)[:,[1,0,2,3]],
87+
self.thresholds,
88+
initial_guess)
9789

9890
results = {}
9991
results["D"] = fit_results[0]

src/standardized/OJ_GU_seg.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@ def __init__(self, bvalues=None, thresholds=None, bounds=None, initial_guess=Non
4141
the requirements.
4242
"""
4343
super(OJ_GU_seg, self).__init__(bvalues, thresholds, bounds, initial_guess)
44-
if bounds is not None:
45-
print('warning, bounds from wrapper are not (yet) used in this algorithm')
46-
self.use_bounds = False
47-
self.use_initial_guess = False
44+
self.use_bounds = {"f" : False, "D" : False, "Dp" : False, "S0" : False}
45+
self.use_initial_guess = {"f" : False, "D" : False, "Dp" : False, "S0" : False}
4846
# Check the inputs
4947

5048
# Initialize the algorithm

0 commit comments

Comments
 (0)