From 1e4dab09fe8e43e3f1a3200ccf43c4c735bbb09d Mon Sep 17 00:00:00 2001 From: mdaeron Date: Sat, 9 Dec 2023 12:31:07 +0100 Subject: [PATCH 1/4] Improve computation of D4x repeatability at the session level --- D47crunch/__init__.py | 4 ++++ changelog.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/D47crunch/__init__.py b/D47crunch/__init__.py index b631459..30fa9a4 100755 --- a/D47crunch/__init__.py +++ b/D47crunch/__init__.py @@ -2217,6 +2217,10 @@ def consolidate_sessions(self): if self.standardization_method == 'pooled': for session in self.sessions: + # different (better?) computation of D4x repeatability for each session: + sqresiduals = [(r[f'D{self._4x}'] - self.samples[r['Sample']][f'D{self._4x}'])**2 for r in self.sessions[session]['data']] + self.sessions[session][f'r_D{self._4x}'] = np.mean(sqresiduals)**.5 + self.sessions[session]['a'] = self.standardization.params.valuesdict()[f'a_{pf(session)}'] i = self.standardization.var_names.index(f'a_{pf(session)}') self.sessions[session]['SE_a'] = self.standardization.covar[i,i]**.5 diff --git a/changelog.md b/changelog.md index 4352baa..d4f9893 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # Changelog +### Bugfix +* Simpler (better?) computation of D4x repeatability at the session level when using pooled regression method. + + ## v2.4.0 *Released on 2023-10-04* From b3532c6c21610e542e0d657b169692f4bf310f74 Mon Sep 17 00:00:00 2001 From: mdaeron Date: Tue, 12 Dec 2023 22:32:01 +0100 Subject: [PATCH 2/4] Add todo item --- todo.md | 1 + 1 file changed, 1 insertion(+) diff --git a/todo.md b/todo.md index 9013136..26e4988 100644 --- a/todo.md +++ b/todo.md @@ -6,3 +6,4 @@ * improve `test_virtual_data()` to populate with non-default parameters * use a true CSV parser? * add (many) plot customization options to CLI? +* implement individual weighing of replicates, e.g. according to the sqrt of the number of IRMS acquisitions From aaf61229280ef61e7377a203543963c224a3175d Mon Sep 17 00:00:00 2001 From: Miguel Bernecker Date: Tue, 30 Jul 2024 15:37:52 +0200 Subject: [PATCH 3/4] plot_single_session(): option to return arrays for isoplot --- D47crunch/__init__.py | 69 ++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/D47crunch/__init__.py b/D47crunch/__init__.py index 30fa9a4..352da63 100755 --- a/D47crunch/__init__.py +++ b/D47crunch/__init__.py @@ -2073,7 +2073,7 @@ def table_of_samples( return pretty_table(out) - def plot_sessions(self, dir = 'output', figsize = (8,8), filetype = 'pdf', dpi = 100): + def plot_sessions(self, dir = 'output', figsize = (8,8), filetype = 'pdf', dpi = 100, return_data = False): ''' Generate session plots and save them to disk. @@ -2084,13 +2084,19 @@ def plot_sessions(self, dir = 'output', figsize = (8,8), filetype = 'pdf', dpi = + `filetype`: 'pdf' or 'png' + `dpi`: resolution for PNG output ''' - if not os.path.exists(dir): - os.makedirs(dir) + + if not return_data: + if not os.path.exists(dir): + os.makedirs(dir) - for session in self.sessions: - sp = self.plot_single_session(session, xylimits = 'constant') - ppl.savefig(f'{dir}/D{self._4x}_plot_{session}.{filetype}', **({'dpi': dpi} if filetype.lower() == 'png' else {})) - ppl.close(sp.fig) + for session in self.sessions: + sp = self.plot_single_session(session, xylimits = 'constant') + ppl.savefig(f'{dir}/D{self._4x}_plot_{session}.{filetype}', **({'dpi': dpi} if filetype.lower() == 'png' else {})) + ppl.close(sp.fig) + else: + for session in self.sessions: + sp = self.plot_single_session(session, xylimits='constant') + @make_verbal @@ -2561,32 +2567,39 @@ def plot_single_session(self, out = _SessionPlot() anchors = [a for a in self.anchors if [r for r in self.sessions[session]['data'] if r['Sample'] == a]] unknowns = [u for u in self.unknowns if [r for r in self.sessions[session]['data'] if r['Sample'] == u]] + anchors_d = [r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] in self.anchors] + anchors_D = [r[f'D{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] in self.anchors] + unknowns_d = [r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] in self.unknowns] + unknowns_D = [r[f'D{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] in self.unknowns] + anchor_avg = (np.array([ np.array([ + np.min([r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] == sample]) - 1, + np.max([r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] == sample]) + 1 + ]) for sample in anchors]).T, + np.array([ np.array([0, 0]) + self.Nominal_D4x[sample] for sample in anchors]).T) + unknown_avg = (np.array([ np.array([ + np.min([r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] == sample]) - 1, + np.max([r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] == sample]) + 1 + ]) for sample in unknowns]).T, + np.array([ np.array([0, 0]) + self.unknowns[sample][f'D{self._4x}'] for sample in unknowns]).T) + if fig == 'new': out.fig = ppl.figure(figsize = (6,6)) ppl.subplots_adjust(.1,.1,.9,.9) out.anchor_analyses, = ppl.plot( - [r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] in self.anchors], - [r[f'D{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] in self.anchors], + anchors_d, + anchors_D, **kw_plot_anchors) out.unknown_analyses, = ppl.plot( - [r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] in self.unknowns], - [r[f'D{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] in self.unknowns], + unknowns_d, + unknowns_D, **kw_plot_unknowns) out.anchor_avg = ppl.plot( - np.array([ np.array([ - np.min([r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] == sample]) - 1, - np.max([r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] == sample]) + 1 - ]) for sample in anchors]).T, - np.array([ np.array([0, 0]) + self.Nominal_D4x[sample] for sample in anchors]).T, + *anchor_avg, **kw_plot_anchor_avg) out.unknown_avg = ppl.plot( - np.array([ np.array([ - np.min([r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] == sample]) - 1, - np.max([r[f'd{self._4x}'] for r in self.sessions[session]['data'] if r['Sample'] == sample]) + 1 - ]) for sample in unknowns]).T, - np.array([ np.array([0, 0]) + self.unknowns[sample][f'D{self._4x}'] for sample in unknowns]).T, + *unknown_avg, **kw_plot_unknown_avg) if xylimits == 'constant': x = [r[f'd{self._4x}'] for r in self] @@ -2627,6 +2640,20 @@ def plot_single_session(self, cval = np.arange(np.ceil(SI.min() / .001) * .001, np.ceil(SI.max() / .001 + 1) * .001, cinterval) out.contour = ppl.contour(XI, YI, SI, cval, **kw_contour_error) out.clabel = ppl.clabel(out.contour) + contour = (XI, YI, SI, cval, cinterval) + + if fig == None: + return { + 'anchors':anchors, + 'unknowns':unknowns, + 'anchors_d':anchors_d, + 'anchors_D':anchors_D, + 'unknowns_d':unknowns_d, + 'unknowns_D':unknowns_D, + 'anchor_avg':anchor_avg, + 'unknown_avg':unknown_avg, + 'contour':contour, + } ppl.xlabel(x_label) ppl.ylabel(y_label) From 2b988c457f37492fe4541e9cd7005248cf447f4b Mon Sep 17 00:00:00 2001 From: Miguel Bernecker Date: Wed, 31 Jul 2024 11:50:02 +0200 Subject: [PATCH 4/4] undo changes in plot_sessions() --- D47crunch/__init__.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/D47crunch/__init__.py b/D47crunch/__init__.py index 352da63..c7d5440 100755 --- a/D47crunch/__init__.py +++ b/D47crunch/__init__.py @@ -2073,7 +2073,7 @@ def table_of_samples( return pretty_table(out) - def plot_sessions(self, dir = 'output', figsize = (8,8), filetype = 'pdf', dpi = 100, return_data = False): + def plot_sessions(self, dir = 'output', figsize = (8,8), filetype = 'pdf', dpi = 100): ''' Generate session plots and save them to disk. @@ -2084,18 +2084,13 @@ def plot_sessions(self, dir = 'output', figsize = (8,8), filetype = 'pdf', dpi = + `filetype`: 'pdf' or 'png' + `dpi`: resolution for PNG output ''' - - if not return_data: - if not os.path.exists(dir): - os.makedirs(dir) + if not os.path.exists(dir): + os.makedirs(dir) - for session in self.sessions: - sp = self.plot_single_session(session, xylimits = 'constant') - ppl.savefig(f'{dir}/D{self._4x}_plot_{session}.{filetype}', **({'dpi': dpi} if filetype.lower() == 'png' else {})) - ppl.close(sp.fig) - else: - for session in self.sessions: - sp = self.plot_single_session(session, xylimits='constant') + for session in self.sessions: + sp = self.plot_single_session(session, xylimits = 'constant') + ppl.savefig(f'{dir}/D{self._4x}_plot_{session}.{filetype}', **({'dpi': dpi} if filetype.lower() == 'png' else {})) + ppl.close(sp.fig)