From 10cb57a3399edddc488d84d0a8feedeab89a779e Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Thu, 3 Aug 2023 16:23:12 +0200 Subject: [PATCH] Continued work on conformance. Added algorithm defining attributes to the algorithm-specific class. Added simple RMSE calculation for single parameter set to OsipiBase. --- .../__pycache__/LinearFitting.cpython-39.pyc | Bin 3097 -> 3097 bytes src/standardized/ETP_SRI_LinearFitting.py | 51 ++++++++++++++++-- src/wrappers/OsipiBase.py | 50 ++++++++++++++--- .../__pycache__/OsipiBase.cpython-39.pyc | Bin 2050 -> 3420 bytes 4 files changed, 89 insertions(+), 12 deletions(-) diff --git a/src/original/ETP_SRI/__pycache__/LinearFitting.cpython-39.pyc b/src/original/ETP_SRI/__pycache__/LinearFitting.cpython-39.pyc index cff98ae4d8738fa02a12d5048fe9cea1beb481e8..f356058523cabb5462f63a9f91c2f7805550e013 100644 GIT binary patch delta 20 acmbO!F;jv&k(ZZ?0SL5roZiUI#{&Q^;RJU8 delta 20 acmbO!F;jv&k(ZZ?0SJ6DPHp7o;{gCI;{- parameter estimates out. + Everything else such as segmentation thresholds, bounds, etc. should + be object attributes. + + This makes the execution of submissions easy and predictable. + All execution stepts requires should be performed here. + """ + ETP_object = LinearFit(self.thresholds[0]) f, D, Dstar = ETP_object.ivim_fit(b_values, signals) @@ -27,6 +68,6 @@ def ivim_model(b, S0=1, f=0.1, Dstar=0.03, D=0.001): signals = ivim_model(b_values) -model = ETP_SRI_LinearFitting() -model.thresholds = [200] -results = model.ivim_fit(b_values, signals) \ No newline at end of file +model = ETP_SRI_LinearFitting([200]) +results = model.ivim_fit(signals, b_values) +test = model.simple_bias_and_RMSE_test(SNR=20, b_values=b_values, f=0.1, Dstar=0.03, D=0.001, noise_realizations=10) \ No newline at end of file diff --git a/src/wrappers/OsipiBase.py b/src/wrappers/OsipiBase.py index 3903a46..78f38fc 100644 --- a/src/wrappers/OsipiBase.py +++ b/src/wrappers/OsipiBase.py @@ -1,4 +1,5 @@ - +import numpy as np +from scipy.stats import norm class OsipiBase: @@ -29,22 +30,57 @@ def accepts_dimension_osipi(self, dim): return False return accepted[dim] - def thresholds_required_osipi(): + def check_thresholds_required_osipi(self): """How many segmentation thresholds does it require?""" - return 0 + if (len(self.thresholds) < self.thresholds_required[0]) or (len(self.thresholds) > self.thresholds_required[1]): + print("Conformance error: Number of thresholds.") + return False + return True - def guess_required_osipi(): + def check_guess_required_osipi(): """Does it require an initial guess?""" return False - def bounds_required_osipi(): + def check_bounds_required_osipi(): """Does it require bounds?""" return False + + def check_b_values_required_osipi(): + """Minimum number of b-values required""" + pass def author_osipi(): """Author identification""" return '' - def simple_test(): - pass + def simple_bias_and_RMSE_test(self, SNR, b_values, f, Dstar, D, noise_realizations=100): + # Generate signal + b_values = np.asarray(b_values) + signals = f*np.exp(-b_values*Dstar) + (1-f)*np.exp(-b_values*D) + + f_estimates = np.zeros(noise_realizations) + Dstar_estimates = np.zeros(noise_realizations) + D_estimates = np.zeros(noise_realizations) + for i in range(noise_realizations): + # Add some noise + sigma = signals[0]/SNR + noised_signal = np.array([norm.rvs(signal, sigma) for signal in signals]) + + # Perform fit with the noised signal + f_estimates[i], Dstar_estimates[i], D_estimates[i] = self.ivim_fit(noised_signal, b_values) + + # Calculate bias + f_bias = np.mean(f_estimates) - f + Dstar_bias = np.mean(Dstar_estimates) - Dstar + D_bias = np.mean(D_estimates) - D + + # Calculate RMSE + f_RMSE = np.sqrt(np.var(f_estimates) + f_bias**2) + Dstar_RMSE = np.sqrt(np.var(Dstar_estimates) + Dstar_bias**2) + D_RMSE = np.sqrt(np.var(D_estimates) + D_bias**2) + + print(f"f bias:\t{f_bias}\nf RMSE:\t{f_RMSE}") + print(f"Dstar bias:\t{Dstar_bias}\nDstar RMSE:\t{Dstar_RMSE}") + print(f"D bias:\t{D_bias}\nD RMSE:\t{D_RMSE}") + diff --git a/src/wrappers/__pycache__/OsipiBase.cpython-39.pyc b/src/wrappers/__pycache__/OsipiBase.cpython-39.pyc index c997aa7f976013c23148ab3e63bde927e52b4270..b1b369b444718d2be865cb51e73eaf68e4ed5df0 100644 GIT binary patch literal 3420 zcma)9TW=dh6rS0OyWK208QybaJ5?RjFYA7U1w&U z5^M96O28uzNJt2YJoXpxBlrjN%2S_t ziWA-m)M&C;F!%(jXo6tc-;P1?j!9qCzA*T)Y2hK-v1ySy&=zQky3iJBnO2~6XqC=D zTcWdc4qBI0#IWm)<{gx&B{U$FigclH=*L5~EHF9c~PoP4pp z@#O~DxVy1Q+F_c8@$Ob&1FB&uKnFwp9I8;b^#+Z8qY7E|74*aOc zgi8kHHcNXv7UY}lORJ>4O6qSzy*FCkdW32PX$cm!rKLPcr{(1?WHpS#H1s2H7aR&% zXeGUvLVN##&vyk^V6^z>?)sJH*Mf1;+&J*#W<3dd9Tumec{5CJ^;*q4jrZ0rduosG zY~J4R))UIslPF?A8YXd5@SypC``xZ`Fd}QMdnil5h?gk(%4+up2xRvc#yX?*Kv6U- zs;}xg)Je*IR`mOv`-dcH6F&%8H)WL25WosRGA50!?XHa|T6wp=3S_>g<@;Ka%X#xb z-h5cEjkWLa9$O{3Z1|CY!70typjK$;qN#j@xjOtYw_NR9o*jbq#$a<|=G7iGF@^qX zV`84EA81`LQbk=YRW(s7(8S8| z7(XOoTSpzlPkx$XHc1Ep4iW9QBF5EmG-`%iI0cwABNo?8y>V&62BkC9n&x3CUl3y& zau&{kd*OgUhJzQeh5Hw$xp>OvsgM~l@iF*Gfs1ePF$M{V;Vc3+R-TwMV9w%~QeM$`so3jKF)B@al)j}M7pyXqeJD$Ic<&ct34Q9)?J1PN2Z*?uqN?7F7svErz| zvYy0{7Qj4UgmIqmD`czJX)&&1cI;!Vai?bSIWUp#cvdcq``*Aim3EhhamuTpJWc2; z!5$0ld#70C#9joO0kJFCQN-59#Qu+M0Jcw*)9&QO`jcD`KPH2;Lv-4?-k88VN;&zp zIF}>PdZX>;z*RKo_rmDEJ`MRagXcoKG>tY-iT{Q1e2y_!oC3Kz0rHJ$kf&Na7s}T* zfx%9%L*h~3wBE^c`Y`0^*0Wi?FhD$b2Bt7yn!x zkIIw%J!)h9#o=VdIy%PSqXJ2|kW~PM(KItBD_=!fNlRDB{U+EIGv`F3IjZVW2}ag3 zI-1cV7e+RWW?`fdm9%!1+6!n2c5*Z~npbu+qxmzVdF5etG(VrZw2)PQMYNdB{fd6G zRKkNfC!2w}Qg&uy&dp|FuAI#e=csxvDqDOJDAsxIiM*>`BXt1kAjC3=UC6ul=8iBx z!5RJmoftnE`;c38xYi7=45Y~q1Ux3j+9g>K;co0lkFd0%*YWeP){mxpH3~%enX?2(%!*|*~Po;SPt4n~VwlH`!x3_L{71t8CrLF(I#Pyx|I0*%V`|C$x zU*9Gni#cCHmfId|HSGAXV>zpBCML@Di2)8}RlA~IZY>LKO`FX3n)eI!LEF|$4%ZY9 z64q3kAI_@)bnsd8%p*`wuy`E=GF-e0RsAYP1uvV#oWbxjmofZ|MR@KfKYX6)v1V;S zsbT&yIIUHs<9V^)VV);l&+8<#2ch7}is$Y3{AjRJ^gNmbp2y+;62xbeP=U%-pz^ay zs1FZ*UWp4z+)!eirF2ilB3B7Ueb@BJ7Un`yFUpiOwEnHJ?tp4V8aK-!=?b>kB delta 720 zcmZ{iJxc>Y5QcZ}F5V_a@go{eBvB*ifry|sBBCOSO#}stG$CeJJuoKj<`8TIwbwAe z!P5Vrt)*qK5LCq4#?qY&91X zm@r<`c;QlM2KQ}=!>E~|y|8TF8lMC{%v=^TnkM%uO;#$GMXfHlY|*eP4z4v!9ay*K z;N2dFCu=sFY~#Ybz>6cwfrprr9?`DCOJbbmwv<=%R!d4u>)77rud1*#b>Iu7ic*~T zo)o-T#k%nbDHD<~6*Bfb+;t4C|4SU$tNO?MH*zw9%!WvC>;;H3XX0O6vgFqftFrZB zQ?SX#;LXnN68#rwKJscIAb65aMy*)FW{la)YONri*E527e*v0ov8Phy{*hQh I%$MHe2lfSwX8-^I