From 16ebe93c351a382d683391604973de7869757556 Mon Sep 17 00:00:00 2001 From: tommiluk Date: Thu, 2 May 2024 19:55:01 +0300 Subject: [PATCH 01/10] Changed Severinghaus' dissolution curve to format not causing division by zero. Signed-off-by: tommiluk --- modules/O2PTSolver.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/O2PTSolver.py b/modules/O2PTSolver.py index bbfed20b..2d2406c3 100644 --- a/modules/O2PTSolver.py +++ b/modules/O2PTSolver.py @@ -393,8 +393,8 @@ def calc(self): #w=workload object, details=dict QaO2 = self.formatQaO2(Q, CaO2) # Calculate diffusion DO2 - a = 11700 * np.float_power( ( np.float_power(SvO2,-1) - 1 ), -1 ) - b = np.float_power( 50**3 + np.float_power(a,2), 0.5 ) + a = 11700.0/(1.0/SvO2 - 1) + b = np.sqrt( 50**3 + a**2) PvO2_calc = self.formatPvO2(a, b) # mmHg if PvO2_calc < 0: @@ -447,7 +447,7 @@ def calc(self): #w=workload object, details=dict PvO2_err = PvO2_corrected-PvO2_calc # Calculate datapoints for diffusion line - PvO2 = np.arange(0.01,100.01,0.1) + PvO2 = np.arange(0.0, 100.01, 0.1) k = float(self.d['k']) # y = k * DO2 * PvO2 y = k * DO2_graph * PvO2 @@ -460,7 +460,7 @@ def calc(self): #w=workload object, details=dict Hb = Hb / 10 # Calculate datapoints for convective curve - y2 = lambda x: Q * 1.34 * Hb * (SaO2/100 - 1/((23400/(np.float_power(x,3)+150*x))+1))*10 + y2 = lambda x: Q * 1.34 * Hb * (SaO2/100 - (x**3 + 150*x)/(x**3 + 150*x + 23400))*10 x2 = self.phTempCorrection(pH, pH0, T, T0, PvO2) y2 = y2(x2) From f6f44a955cc4592308a3a193119c53fc8c571033 Mon Sep 17 00:00:00 2001 From: tommiluk Date: Thu, 2 May 2024 20:08:25 +0300 Subject: [PATCH 02/10] Changed PvO2 = np.arange(0.0,100.01,0.1) including 0.0 Signed-off-by: tommiluk --- .gitignore | 1 + modules/panel_plotting.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4fb67e81..15d4e886 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /build /dist /O2 +/__pycache__ README.md Entitlements.plist \ No newline at end of file diff --git a/modules/panel_plotting.py b/modules/panel_plotting.py index 968be059..acc99f2c 100644 --- a/modules/panel_plotting.py +++ b/modules/panel_plotting.py @@ -365,7 +365,7 @@ def setYLim(self): self.plot[0].canvas.draw() def createPlot(self): - PvO2 = np.arange(0.01,100.01,0.1) + PvO2 = np.arange(0.0,100.01,0.1) self.plot = plt.subplots(constrained_layout=True) self.fig, self.ax = self.plot From 58bdab1cda7d092a85565bfaf222b53a2ad9f05b Mon Sep 17 00:00:00 2001 From: tommiluk Date: Thu, 2 May 2024 21:21:11 +0300 Subject: [PATCH 03/10] Commented out unused codes. Comennted out np.log(PvO2) in pHTempCorrection. Removed lnPvO2 from the exp. Signed-off-by: tommiluk --- modules/O2PTSolver.py | 12 ++++++------ objects/workLoadDetails.py | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/O2PTSolver.py b/modules/O2PTSolver.py index 2d2406c3..bc1dc5f7 100644 --- a/modules/O2PTSolver.py +++ b/modules/O2PTSolver.py @@ -316,7 +316,7 @@ def formatPvO2(self, a, b): return self.validValues def phTempCorrection(self, pH0, pH, T0, T, PvO2): - lnPvO2 = np.log(PvO2) + # lnPvO2 = np.log(PvO2) if pH != pH0 or T != T0: lnPO2pH = (pH - pH0) * (-1.1) @@ -325,7 +325,7 @@ def phTempCorrection(self, pH0, pH, T0, T, PvO2): lnPO2pH = 0 lnPO2Temp = 0 - PvO2 = np.exp( lnPvO2 + lnPO2Temp + lnPO2pH ) + PvO2 *= np.exp(lnPO2Temp + lnPO2pH) return PvO2 @@ -394,7 +394,7 @@ def calc(self): #w=workload object, details=dict # Calculate diffusion DO2 a = 11700.0/(1.0/SvO2 - 1) - b = np.sqrt( 50**3 + a**2) + b = np.sqrt(50**3 + a**2) PvO2_calc = self.formatPvO2(a, b) # mmHg if PvO2_calc < 0: @@ -443,8 +443,8 @@ def calc(self): #w=workload object, details=dict [DO2, DO2_graph] = self.solveDO2(VO2, PvO2_corrected) # Two values to improve graphical display accuracy # Compute the coefficient for convection curve shift - PvO2_coef = PvO2_corrected/PvO2_calc - PvO2_err = PvO2_corrected-PvO2_calc + # PvO2_coef = PvO2_corrected/PvO2_calc + # PvO2_err = PvO2_corrected-PvO2_calc # Calculate datapoints for diffusion line PvO2 = np.arange(0.0, 100.01, 0.1) @@ -481,6 +481,6 @@ def calc(self): #w=workload object, details=dict SvO2 = SvO2 * 100 - self.w.setCalcResults(y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO2, QaO2, T0, T, pH0, pH, PvO2_corrected, DO2, PvO2_coef, PvO2_err) + self.w.setCalcResults(y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO2, QaO2, T0, T, pH0, pH, PvO2_corrected, DO2) #, PvO2_coef, PvO2_err) return self.validValues \ No newline at end of file diff --git a/objects/workLoadDetails.py b/objects/workLoadDetails.py index 504571bd..693c6bfa 100644 --- a/objects/workLoadDetails.py +++ b/objects/workLoadDetails.py @@ -25,8 +25,8 @@ def __init__(self, name): self.pH = testDefaults['pH'] self.PaO2 = 0 self.PvO2 = 0 - self.PvO2_coef = 0 - self.PvO2_err = 0 + # self.PvO2_coef = 0 + # self.PvO2_err = 0 self.DO2 = 0 self.p50 = 0 self.k = testDefaults['k'] @@ -367,7 +367,7 @@ def getCoords(self): 'yi': self.yi } - def setCalcResults(self, y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO2, QaO2, Trest, T, pHrest, pH, PvO2, DO2, PvO2_coef, PvO2_err): + def setCalcResults(self, y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO2, QaO2, Trest, T, pHrest, pH, PvO2, DO2): #, PvO2_coef, PvO2_err): self.y = y self.y2 = y2 self.xi = xi @@ -386,8 +386,8 @@ def setCalcResults(self, y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO self.pHrest = pHrest self.pH = pH self.PvO2 = PvO2 - self.PvO2_coef = PvO2_coef - self.PvO2_err = PvO2_err + # self.PvO2_coef = PvO2_coef + # self.PvO2_err = PvO2_err self.DO2 = DO2 # self.p50 = p50 From a6f5493fb3bd22eb239132c64604253ba1067ed7 Mon Sep 17 00:00:00 2001 From: tommiluk Date: Thu, 2 May 2024 21:33:28 +0300 Subject: [PATCH 04/10] Added __pycache__ folders to .gitignore Signed-off-by: tommiluk --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 15d4e886..a405d9f4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,7 @@ /dist /O2 /__pycache__ +/modules/__pycache__ +/objects/__pycache__ README.md Entitlements.plist \ No newline at end of file From 98de020d840c589bba3bf83ed356df6780d0507d Mon Sep 17 00:00:00 2001 From: tommiluk Date: Wed, 8 May 2024 21:43:35 +0300 Subject: [PATCH 05/10] Simplified pH and Temp correction calculation. Signed-off-by: tommiluk --- modules/O2PTSolver.py | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/modules/O2PTSolver.py b/modules/O2PTSolver.py index bc1dc5f7..ff89d264 100644 --- a/modules/O2PTSolver.py +++ b/modules/O2PTSolver.py @@ -413,32 +413,8 @@ def calc(self): #w=workload object, details=dict if self.preventCorrection: PvO2_corrected = PvO2_calc - # p50 = self.d['p50'] else: - # Modeling from 37/7.4 -> 38.5/7.03 should produce same results as 38.5/7.03 - if (pH0 == pH and T0 == T): - # If no change in pH or T values, check if normal physiological conditions - if pH0 != 7.4 and T0 == 37: - PvO2_corrected = self.phTempCorrection(7.4, pH, T0, T, PvO2_calc) - # p50 = self.solveP50(7.4, pH, T0, T) - elif T0 != 37 and pH0 == 7.4: - PvO2_corrected = self.phTempCorrection(pH0, pH, 37, T, PvO2_calc) - # p50 = self.solveP50(pH0, pH, 37, T) - else: - PvO2_corrected = self.phTempCorrection(7.4, pH, 37, T, PvO2_calc) - # p50 = self.solveP50(7.4, pH, 37, T) - elif pH0 != 7.4 or T0 != 37: - # If initial values for pH/T are different than physiological normals e.g. pH0= 7.2 - # E.g. 7.2/37.5 -> 7.0/39 - # Correct first to normal physiological conditions - PvO2_corrected = self.phTempCorrection(7.4, pH0, 37, T0, PvO2_calc) - # Then to the final peak value - PvO2_corrected = self.phTempCorrection(7.4, pH, 37, T, PvO2_corrected) - # p50 = self.solveP50(7.4, pH, 37, T) - else: - # If initial values are equal to normal physiological conditions - PvO2_corrected = self.phTempCorrection(pH0, pH, T0, T, PvO2_calc) - # p50 = self.solveP50(pH0, pH, T0, T) + PvO2_corrected = self.phTempCorrection(pH0, pH, T0, T, PvO2_calc) [DO2, DO2_graph] = self.solveDO2(VO2, PvO2_corrected) # Two values to improve graphical display accuracy From 734a5e54ec1b64863392afc88d4d11d60fdf7601 Mon Sep 17 00:00:00 2001 From: tommiluk Date: Wed, 8 May 2024 22:26:05 +0300 Subject: [PATCH 06/10] Removed unused codes and simplified calculations. Signed-off-by: tommiluk --- modules/O2PTSolver.py | 27 +++------------------------ objects/workLoadDetails.py | 7 +------ 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/modules/O2PTSolver.py b/modules/O2PTSolver.py index ff89d264..c6e83756 100644 --- a/modules/O2PTSolver.py +++ b/modules/O2PTSolver.py @@ -4,7 +4,6 @@ class O2PTSolver(): def __init__(self, workloadObject, detailsDict): self.w = workloadObject self.d = detailsDict - self.preventCorrection = False self.validValues = True def formatQ(self): @@ -305,12 +304,7 @@ def formatPvO2(self, a, b): self.w.setMC('PvO2_MC', 1) try: - if PvO2 == 0: - return np.float_power( a+b, (1/3)) - np.float_power( b-a, (1/3)) - else: - # self.preventCorrection = True - # return PvO2 - return np.float_power( a+b, (1/3)) - np.float_power( b-a, (1/3)) + return (a + b)**(1/3.0) - (b - a)**(1/3.0) except: self.validValues = False return self.validValues @@ -369,13 +363,6 @@ def solveDO2(self, VO2, PvO2): self.validValues = False return self.validValues - def solveP50(self, pH0, pH, T0, T): - p50S = 26.86 - p50pH = p50S-25.535*(pH-pH0)+10.646*(pH-pH0)**2-1.764*(pH-pH0)**3 - p50T = p50S+1.435*(T-T0) + np.float_power(4.163, -2)*(T-T0)**2 + np.float_power(6.86, -4)*(T-T0)**3 - p50 = p50S * (p50pH/p50S) * (p50T/p50S) - return p50 - def calc(self): #w=workload object, details=dict # validValues = True Q = self.formatQ() @@ -410,18 +397,10 @@ def calc(self): #w=workload object, details=dict except: self.validValues = False return self.validValues - - if self.preventCorrection: - PvO2_corrected = PvO2_calc - else: - PvO2_corrected = self.phTempCorrection(pH0, pH, T0, T, PvO2_calc) + PvO2_corrected = self.phTempCorrection(pH0, pH, T0, T, PvO2_calc) [DO2, DO2_graph] = self.solveDO2(VO2, PvO2_corrected) # Two values to improve graphical display accuracy - # Compute the coefficient for convection curve shift - # PvO2_coef = PvO2_corrected/PvO2_calc - # PvO2_err = PvO2_corrected-PvO2_calc - # Calculate datapoints for diffusion line PvO2 = np.arange(0.0, 100.01, 0.1) k = float(self.d['k']) @@ -457,6 +436,6 @@ def calc(self): #w=workload object, details=dict SvO2 = SvO2 * 100 - self.w.setCalcResults(y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO2, QaO2, T0, T, pH0, pH, PvO2_corrected, DO2) #, PvO2_coef, PvO2_err) + self.w.setCalcResults(y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO2, QaO2, T0, T, pH0, pH, PvO2_corrected, DO2) return self.validValues \ No newline at end of file diff --git a/objects/workLoadDetails.py b/objects/workLoadDetails.py index 693c6bfa..fd704541 100644 --- a/objects/workLoadDetails.py +++ b/objects/workLoadDetails.py @@ -25,8 +25,6 @@ def __init__(self, name): self.pH = testDefaults['pH'] self.PaO2 = 0 self.PvO2 = 0 - # self.PvO2_coef = 0 - # self.PvO2_err = 0 self.DO2 = 0 self.p50 = 0 self.k = testDefaults['k'] @@ -367,7 +365,7 @@ def getCoords(self): 'yi': self.yi } - def setCalcResults(self, y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO2, QaO2, Trest, T, pHrest, pH, PvO2, DO2): #, PvO2_coef, PvO2_err): + def setCalcResults(self, y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO2, QaO2, Trest, T, pHrest, pH, PvO2, DO2): self.y = y self.y2 = y2 self.xi = xi @@ -386,10 +384,7 @@ def setCalcResults(self, y, y2, xi, yi, VO2, Q, Hb, SaO2, CaO2, SvO2, CvO2, CavO self.pHrest = pHrest self.pH = pH self.PvO2 = PvO2 - # self.PvO2_coef = PvO2_coef - # self.PvO2_err = PvO2_err self.DO2 = DO2 - # self.p50 = p50 def setImported(self, bool): self.isImported = bool From 41c1a83b36f99ba3ece784684ccb097e026817dc Mon Sep 17 00:00:00 2001 From: tommiluk Date: Wed, 8 May 2024 22:44:39 +0300 Subject: [PATCH 07/10] Simplified solveDO2 function Signed-off-by: tommiluk --- modules/O2PTSolver.py | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/modules/O2PTSolver.py b/modules/O2PTSolver.py index c6e83756..c603ddba 100644 --- a/modules/O2PTSolver.py +++ b/modules/O2PTSolver.py @@ -336,10 +336,6 @@ def formatT(self, label): def solveDO2(self, VO2, PvO2): VO2Unit = self.d['VO2_unit'] - try: - DO2 = float(self.d['DO2']) - except ValueError: - DO2 = 0 try: k = float(self.d['k']) @@ -350,15 +346,10 @@ def solveDO2(self, VO2, PvO2): # self.w.setMC('DO2_MC', 1) try: - if DO2 == 0: - if VO2Unit == 'ml/min': # -> l/min - VO2 = VO2 / 1000 + if VO2Unit == 'ml/min': # -> l/min + VO2 = VO2 / 1000 - # return VO2 / 2 / PvO2 * 1000 - return [VO2 / k / PvO2 * 1000, VO2 / k / PvO2 * 1000] - else: - return [DO2, VO2 / k / PvO2 * 1000] - # return VO2 / k / PvO2 * 1000 + return VO2 / 2 / PvO2 * 1000 except: self.validValues = False return self.validValues @@ -399,13 +390,12 @@ def calc(self): #w=workload object, details=dict return self.validValues PvO2_corrected = self.phTempCorrection(pH0, pH, T0, T, PvO2_calc) - [DO2, DO2_graph] = self.solveDO2(VO2, PvO2_corrected) # Two values to improve graphical display accuracy + DO2 = self.solveDO2(VO2, PvO2_corrected) # Calculate datapoints for diffusion line PvO2 = np.arange(0.0, 100.01, 0.1) k = float(self.d['k']) - # y = k * DO2 * PvO2 - y = k * DO2_graph * PvO2 + y = k * DO2 * PvO2 # Convert to l/min if self.d['Q_unit'] == 'ml/min': From 50fd0107b535794556ef3c8d04f08848540d9f83 Mon Sep 17 00:00:00 2001 From: tommiluk Date: Wed, 8 May 2024 22:57:03 +0300 Subject: [PATCH 08/10] Corrected .gitignore Signed-off-by: tommiluk --- .gitignore | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index a405d9f4..d9bf608f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ /build /dist /O2 -/__pycache__ -/modules/__pycache__ -/objects/__pycache__ +__pycache__/ README.md Entitlements.plist \ No newline at end of file From 2d54e91d8f4cf5f330d46b975ac2b24e5943bacd Mon Sep 17 00:00:00 2001 From: tommiluk Date: Wed, 8 May 2024 23:00:46 +0300 Subject: [PATCH 09/10] Removed unnecessary code from solveDO2 Signed-off-by: tommiluk --- modules/O2PTSolver.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/modules/O2PTSolver.py b/modules/O2PTSolver.py index c603ddba..b5a97c6b 100644 --- a/modules/O2PTSolver.py +++ b/modules/O2PTSolver.py @@ -335,20 +335,10 @@ def formatT(self, label): return T def solveDO2(self, VO2, PvO2): - VO2Unit = self.d['VO2_unit'] - - try: - k = float(self.d['k']) - except ValueError: - self.validValues = False - return self.validValues - - # self.w.setMC('DO2_MC', 1) - + VO2Unit = self.d['VO2_unit'] try: if VO2Unit == 'ml/min': # -> l/min - VO2 = VO2 / 1000 - + VO2 = VO2 / 1000 return VO2 / 2 / PvO2 * 1000 except: self.validValues = False From ebe04173442e971f48484dc87f1f1d6d4ba89a2b Mon Sep 17 00:00:00 2001 From: tommiluk Date: Thu, 9 May 2024 09:48:10 +0300 Subject: [PATCH 10/10] Moved PvO2 calculation and DO2 solve to calc-function. Signed-off-by: tommiluk --- modules/O2PTSolver.py | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/modules/O2PTSolver.py b/modules/O2PTSolver.py index b5a97c6b..1496a035 100644 --- a/modules/O2PTSolver.py +++ b/modules/O2PTSolver.py @@ -296,19 +296,6 @@ def formatQaO2(self, Q, CaO2): self.validValues = False return self.validValues - def formatPvO2(self, a, b): - try: - PvO2 = float(self.d['PvO2']) - except ValueError: - PvO2 = 0 - self.w.setMC('PvO2_MC', 1) - - try: - return (a + b)**(1/3.0) - (b - a)**(1/3.0) - except: - self.validValues = False - return self.validValues - def phTempCorrection(self, pH0, pH, T0, T, PvO2): # lnPvO2 = np.log(PvO2) @@ -334,16 +321,6 @@ def formatT(self, label): else: return T - def solveDO2(self, VO2, PvO2): - VO2Unit = self.d['VO2_unit'] - try: - if VO2Unit == 'ml/min': # -> l/min - VO2 = VO2 / 1000 - return VO2 / 2 / PvO2 * 1000 - except: - self.validValues = False - return self.validValues - def calc(self): #w=workload object, details=dict # validValues = True Q = self.formatQ() @@ -363,7 +340,8 @@ def calc(self): #w=workload object, details=dict # Calculate diffusion DO2 a = 11700.0/(1.0/SvO2 - 1) b = np.sqrt(50**3 + a**2) - PvO2_calc = self.formatPvO2(a, b) # mmHg + PvO2_calc = (a + b)**(1/3.0) - (b - a)**(1/3.0) + self.w.setMC('PvO2_MC', 1) if PvO2_calc < 0: self.validValues = False @@ -380,7 +358,11 @@ def calc(self): #w=workload object, details=dict return self.validValues PvO2_corrected = self.phTempCorrection(pH0, pH, T0, T, PvO2_calc) - DO2 = self.solveDO2(VO2, PvO2_corrected) + # Solve DO2 + if self.d['VO2_unit'] == 'ml/min': + DO2 = VO2 / 2 / PvO2_corrected + else: # 'l/min' + DO2 = VO2 / 2 / PvO2_corrected * 1000 # Calculate datapoints for diffusion line PvO2 = np.arange(0.0, 100.01, 0.1) @@ -395,9 +377,8 @@ def calc(self): #w=workload object, details=dict Hb = Hb / 10 # Calculate datapoints for convective curve - y2 = lambda x: Q * 1.34 * Hb * (SaO2/100 - (x**3 + 150*x)/(x**3 + 150*x + 23400))*10 x2 = self.phTempCorrection(pH, pH0, T, T0, PvO2) - y2 = y2(x2) + y2 = Q * 1.34 * Hb * (SaO2/100 - (x2**3 + 150*x2)/(x2**3 + 150*x2 + 23400))*10 # Calculation of intersection point idx = np.argwhere(np.diff(np.sign(y - y2))).flatten()