@@ -466,6 +466,20 @@ def fit_segmented_tri_exp(bvalues, dw_data, bounds=([0, 0, 0, 0.005, 0, 0.06], [
466
466
return 0. , 0. , 0. , 0. , 0. , 0.
467
467
468
468
469
+ def neg_log_likelihood (p , bvalues , dw_data ):
470
+ """
471
+ This function determines the negative of the log of the likelihood of parameters p, given the data dw_data for the Bayesian fit
472
+ :param p: 1D Array with the estimates of D, f, D* and (optionally) S0
473
+ :param bvalues: 1D array with b-values
474
+ :param dw_data: 1D Array diffusion-weighted data
475
+ :returns: the log-likelihood of the parameters given the data
476
+ """
477
+ if len (p ) == 4 :
478
+ return 0.5 * (len (bvalues ) + 1 ) * np .log (
479
+ np .sum ((ivim (bvalues , p [0 ], p [1 ], p [2 ], p [3 ]) - dw_data ) ** 2 )) # 0.5*sum simplified
480
+ else :
481
+ return 0.5 * (len (bvalues ) + 1 ) * np .log (
482
+ np .sum ((ivim (bvalues , p [0 ], p [1 ], p [2 ], 1 ) - dw_data ) ** 2 )) # 0.5*sum simplified
469
483
def empirical_neg_log_prior (Dt0 , Fp0 , Dp0 , S00 = None ):
470
484
"""
471
485
This function determines the negative of the log of the empirical prior probability of the IVIM parameters
@@ -519,6 +533,18 @@ def neg_log_prior(p):
519
533
520
534
return neg_log_prior
521
535
536
+ def neg_log_posterior (p , bvalues , dw_data , neg_log_prior ):
537
+ """
538
+ This function determines the negative of the log of the likelihood of parameters p, given the prior likelihood and the data
539
+ :param p: 1D Array with the estimates of D, f, D* and (optionally) S0
540
+ :param bvalues: 1D array with b-values
541
+ :param dw_data: 1D Array diffusion-weighted data
542
+ :param neg_log_prior: prior likelihood function (created with empirical_neg_log_prior)
543
+ :returns: the posterior probability given the data and the prior
544
+ """
545
+ return neg_log_likelihood (p , bvalues , dw_data ) + neg_log_prior (p )
546
+
547
+
522
548
def flat_neg_log_prior (Dt_range , Fp_range , Dp_range , S0_range = None ):
523
549
"""
524
550
This function determines the negative of the log of the empirical prior probability of the IVIM parameters
@@ -537,45 +563,19 @@ def neg_log_prior(p):
537
563
if (Dp < Dt ):
538
564
return 1e8
539
565
else :
540
- eps = 1e-8
541
- Dp_prior = stats .loguniform .pdf (Dp , Dp_range [0 ], scale = Dp_range [1 ]- Dp_range [0 ])
542
- Dt_prior = stats .loguniform .pdf (Dt , Dt_range [0 ], scale = Dt_range [1 ]- Dt_range [0 ])
543
- Fp_prior = stats .loguniform .pdf (Fp , Fp_range [0 ], scale = Fp_range [1 ]- Fp_range [0 ])
544
566
# determine and return the prior for D, f and D* (and S0)
545
567
if len (p ) == 4 :
546
- S0_prior = stats .loguniform .pdf (S0 , S0_range [0 ], scale = S0_range [1 ] - S0_range [0 ])
547
- return - np .log (Dp_prior + eps ) - np .log (Dt_prior + eps ) - np .log (Fp_prior + eps ) - np .log (
548
- S0_prior + eps )
568
+ if Dt_range [0 ] < Dt < Dt_range [1 ] and Fp_range [0 ] < Fp < Fp_range [1 ] and Dp_range [0 ] < Dp < Dp_range [1 ]: # and S0_range[0] < S0 < S0_range[1]: << not sure whether this helps. Technically it should be here
569
+ return 0
570
+ else :
571
+ return 1e8
549
572
else :
550
- return - np .log (Dp_prior + eps ) - np .log (Dt_prior + eps ) - np .log (Fp_prior + eps )
573
+ if Dt_range [0 ] < Dt < Dt_range [1 ] and Fp_range [0 ] < Fp < Fp_range [1 ] and Dp_range [0 ] < Dp < Dp_range [1 ]:
574
+ return 0
575
+ else :
576
+ return 1e8
551
577
552
578
return neg_log_prior
553
- def neg_log_likelihood (p , bvalues , dw_data ):
554
- """
555
- This function determines the negative of the log of the likelihood of parameters p, given the data dw_data for the Bayesian fit
556
- :param p: 1D Array with the estimates of D, f, D* and (optionally) S0
557
- :param bvalues: 1D array with b-values
558
- :param dw_data: 1D Array diffusion-weighted data
559
- :returns: the log-likelihood of the parameters given the data
560
- """
561
- if len (p ) == 4 :
562
- return 0.5 * (len (bvalues ) + 1 ) * np .log (
563
- np .sum ((ivim (bvalues , p [0 ], p [1 ], p [2 ], p [3 ]) - dw_data ) ** 2 )) # 0.5*sum simplified
564
- else :
565
- return 0.5 * (len (bvalues ) + 1 ) * np .log (
566
- np .sum ((ivim (bvalues , p [0 ], p [1 ], p [2 ], 1 ) - dw_data ) ** 2 )) # 0.5*sum simplified
567
-
568
-
569
- def neg_log_posterior (p , bvalues , dw_data , neg_log_prior ):
570
- """
571
- This function determines the negative of the log of the likelihood of parameters p, given the prior likelihood and the data
572
- :param p: 1D Array with the estimates of D, f, D* and (optionally) S0
573
- :param bvalues: 1D array with b-values
574
- :param dw_data: 1D Array diffusion-weighted data
575
- :param neg_log_prior: prior likelihood function (created with empirical_neg_log_prior)
576
- :returns: the posterior probability given the data and the prior
577
- """
578
- return neg_log_likelihood (p , bvalues , dw_data ) + neg_log_prior (p )
579
579
580
580
581
581
def fit_bayesian_array (bvalues , dw_data , paramslsq , arg ):
@@ -655,7 +655,7 @@ def fit_bayesian(bvalues, dw_data, neg_log_prior, x0=[0.001, 0.2, 0.05], fitS0=T
655
655
'''
656
656
try :
657
657
# define fit bounds
658
- bounds = [(0 , 0.005 ), (0 , 0.7 ), (0.005 , 0. 2 ), (0 , 2.5 )]
658
+ bounds = [(0 , 0.005 ), (0 , 1 ), (0 , 2 ), (0 , 2.5 )]
659
659
# Find the Maximum a posterior probability (MAP) by minimising the negative log of the posterior
660
660
if fitS0 :
661
661
params = minimize (neg_log_posterior , x0 = x0 , args = (bvalues , dw_data , neg_log_prior ), bounds = bounds )
0 commit comments