From c2b0c8b63cf899085b911c68583e81b5ba18fd7f Mon Sep 17 00:00:00 2001 From: amnona Date: Thu, 30 May 2024 15:59:20 +0300 Subject: [PATCH 1/3] save and load call history --- CHANGELOG.md | 2 ++ calour/__init__.py | 2 +- calour/io.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c0e00e6..c4ed5fcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ # calour changelog +## Version 2024.6.1 +* Add command_history file to Experiment read and save. When saving, a NAME_history.txt file is created with the command history used to create the Experiment. When loading, can supply a call_history="XXX" parameter to load the call history file into the loaded Experiment. ## Version 2024.5.16 Bug Fixes: diff --git a/calour/__init__.py b/calour/__init__.py index 66aa18f5..2042171f 100644 --- a/calour/__init__.py +++ b/calour/__init__.py @@ -18,7 +18,7 @@ __credits__ = "https://github.com/biocore/calour/graphs/contributors" -__version__ = "2024.5.16" +__version__ = "2024.6.1" __all__ = ['read', 'read_amplicon', 'read_ms', 'read_qiime2', 'Experiment', 'AmpliconExperiment', 'MS1Experiment', diff --git a/calour/io.py b/calour/io.py index 9604a6c5..71033cf7 100644 --- a/calour/io.py +++ b/calour/io.py @@ -345,6 +345,7 @@ def _read_metadata(ids, f, kwargs): @ds.get_sectionsf('io.read') def read(data_file, sample_metadata_file=None, feature_metadata_file=None, + call_history_file=None, description='', sparse=True, data_file_type='biom', data_file_sep=',', sample_in_row=False, sample_id_proc=None, feature_id_proc=None, @@ -366,6 +367,8 @@ def read(data_file, sample_metadata_file=None, feature_metadata_file=None, metadata). feature_metadata_file : str, default=None File path to feature metadata. + call_history_file : str, default=None + File path to the call history file (one line per command, generated by Experiment.save() ) description : str description of the experiment sparse : bool @@ -475,8 +478,14 @@ def read(data_file, sample_metadata_file=None, feature_metadata_file=None, exp.normalize(total=normalize, inplace=True) # initialize the call history + exp._call_history = [] + # if we have a command history file, load it + if command_history_file is not None: + old_call_history = read_call_history(command_history_file) + exp._call_history.extend(old_call_history) + param = ['{0!s}={1!r}'.format(k, v) for k, v in fparams.items()] - exp._call_history = ['{0}({1})'.format('read_amplicon', ','.join(param))] + exp._call_history.append('{0}({1})'.format('read_amplicon', ','.join(param))) logger.info('Loaded %d samples, %d features' % (exp.shape[0], exp.shape[1])) @@ -776,6 +785,39 @@ def save(exp: Experiment, prefix, fmt='hdf5'): exp.save_biom('%s.biom' % prefix, fmt=fmt) exp.sample_metadata.to_csv('%s_sample.txt' % prefix, sep='\t') exp.feature_metadata.to_csv('%s_feature.txt' % prefix, sep='\t') + exp.save_call_history('%s_history.txt' % prefix) + + +def save_call_history(exp: Experiment, f): + '''Save experiment call history to file + Save the command history used to generate the experiment to a file. + History file is a text file with one line per call to a calour function. + + Parameters + ---------- + f : str + the file name to save to + ''' + with open(f, 'w') as f: + for cline in exp._call_history: + f.write('%s\n' % cline) + + +def read_call_history(f): + '''Load the call history from a file + + Parameters + ---------- + f : str + the file name to load from + + Returns + ------- + list of str + the call history + ''' + with open(f, 'r') as f: + return [x.strip() for x in f] def save_biom(exp: Experiment, f, fmt='hdf5', add_metadata='taxonomy'): From f98f7593d01bc717f26e3b427195dd2e1fcfbb01 Mon Sep 17 00:00:00 2001 From: amnona Date: Thu, 30 May 2024 16:01:13 +0300 Subject: [PATCH 2/3] bugfix --- calour/io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/calour/io.py b/calour/io.py index 71033cf7..41e726ce 100644 --- a/calour/io.py +++ b/calour/io.py @@ -480,8 +480,8 @@ def read(data_file, sample_metadata_file=None, feature_metadata_file=None, # initialize the call history exp._call_history = [] # if we have a command history file, load it - if command_history_file is not None: - old_call_history = read_call_history(command_history_file) + if call_history_file is not None: + old_call_history = read_call_history(call_history_file) exp._call_history.extend(old_call_history) param = ['{0!s}={1!r}'.format(k, v) for k, v in fparams.items()] From b7c23017ae09bb577018f0aceabc4ad1c957044f Mon Sep 17 00:00:00 2001 From: amnona Date: Thu, 30 May 2024 16:16:44 +0300 Subject: [PATCH 3/3] bugfix --- calour/io.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/calour/io.py b/calour/io.py index 41e726ce..d27237f5 100644 --- a/calour/io.py +++ b/calour/io.py @@ -485,8 +485,8 @@ def read(data_file, sample_metadata_file=None, feature_metadata_file=None, exp._call_history.extend(old_call_history) param = ['{0!s}={1!r}'.format(k, v) for k, v in fparams.items()] - exp._call_history.append('{0}({1})'.format('read_amplicon', ','.join(param))) - + exp._call_history.append('{0}({1})'.format('read', ','.join(param))) + logger.info('Loaded %d samples, %d features' % (exp.shape[0], exp.shape[1])) return exp @@ -533,10 +533,6 @@ def read_amplicon(data_file, sample_metadata_file=None, if normalize is not None: exp.normalize(total=normalize, axis=0, inplace=True) - # initialize the call history - param = ['{0!s}={1!r}'.format(k, v) for k, v in fparams.items()] - exp._call_history = ['{0}({1})'.format('read_amplicon', ','.join(param))] - return exp @@ -741,7 +737,7 @@ def read_ms(data_file, sample_metadata_file=None, feature_metadata_file=None, gn # initialize the call history param = ['{0!s}={1!r}'.format(k, v) for k, v in fparams.items()] - exp._call_history = ['{0}({1})'.format('read_amplicon', ','.join(param))] + exp._call_history.append(['{0}({1})'.format('read_ms', ','.join(param))]) return exp