From 8e7abc569313c1e39321e71b862b5ba60d433e01 Mon Sep 17 00:00:00 2001 From: Antonio Gonzalez Date: Wed, 16 Sep 2020 16:57:27 -0600 Subject: [PATCH 1/3] Version 092020 (#3034) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * inject study_type in EBI and improvements to current automatic processing pipeline (#3023) * inject study_type in ebi and improvements to current automatic proecssing pipeline * addressing @ElDeveloper comments * some general fixes/additions for next release (#3026) * some general fixes/additions for next release * adding test for not None job.release_validator_job * fix #2839 * fix #2868 (#3028) * fix #2868 * 2nd round * fix errors * more changes * fix errors * fix ProcessingJobTest * fix PY_PATCH * add missing TRN.add * encapsulated_query -> perform_as_transaction * fix #3022 (#3030) * fix #3022 * adding tests * fix #2320 (#3031) * fix #2320 * adding prints to debug * children -> 1 * APIArtifactHandlerTest -> APIArtifactHandlerTests * configure_biom * qdb.util.activate_or_update_plugins * improving code * almost there * add values.template * fix filepaths * filepaths -> files * fixing errors * add prep.artifact insertion * addressing @ElDeveloper comments * fix artifact_definition active command * != -> == * Added three tutorial sections to the Qiita documentation (#3032) * Added three tutorial sections to the Qiita documentation: 'Retrieving Public Data for Own Analysis' and 'Processing public data retrieved with redbiom' to the redbiom tab, and 'Statistical Analysis to Justify Clinical Trial Sample Size Tutorial' to the analyzing samples tab. * Update redbiom.rst * Update redbiom.rst * Update redbiom.rst * Further updates to redbiom.rst and the Stats tutorial. * update redbiom.rst * Finished proof-reading * Placed all three tutorials/sections together under Introduction to the download and analysis of public Qiita data * added a new introduction, with links to the three sections * Added figures to stats tutorial and contexts explanation * Added figures to stats tutorial and contexts explanation * Apply suggestions from code review [skip ci] Co-authored-by: Yoshiki Vázquez Baeza Co-authored-by: Antonio Gonzalez Co-authored-by: Yoshiki Vázquez Baeza * 092020 (#3033) * 092020 * connect artifact with job * rm INSERT qiita.artifact_processing_job * Apply suggestions from code review [skip ci] Co-authored-by: Yoshiki Vázquez Baeza Co-authored-by: Yoshiki Vázquez Baeza Co-authored-by: Daniel McDonald Co-authored-by: Mirte Kuijpers <67341505+mcmk3@users.noreply.github.com> Co-authored-by: Yoshiki Vázquez Baeza --- .travis.yml | 2 +- CHANGELOG.md | 11 + README.rst | 6 +- qiita_core/__init__.py | 2 +- qiita_db/__init__.py | 2 +- qiita_db/analysis.py | 44 +- qiita_db/artifact.py | 32 +- qiita_db/download_link.py | 12 +- qiita_db/handlers/artifact.py | 69 +- qiita_db/handlers/tests/test_artifact.py | 106 +- qiita_db/logger.py | 23 +- qiita_db/meta_util.py | 8 +- .../base_metadata_template.py | 25 +- qiita_db/metadata_template/prep_template.py | 48 +- qiita_db/metadata_template/sample_template.py | 17 + .../test/test_prep_template.py | 6 + .../test/test_sample_template.py | 6 + qiita_db/ontology.py | 18 +- qiita_db/portal.py | 60 +- qiita_db/processing_job.py | 106 +- qiita_db/software.py | 51 +- qiita_db/sql_connection.py | 18 + qiita_db/study.py | 101 +- qiita_db/test/test_analysis.py | 20 +- qiita_db/test/test_archive.py | 7 +- qiita_db/test/test_commands.py | 24 +- qiita_db/test/test_meta_util.py | 24 +- qiita_db/test/test_ontology.py | 7 +- qiita_db/test/test_processing_job.py | 29 +- qiita_db/test/test_software.py | 77 +- qiita_db/test/test_study.py | 11 +- qiita_db/test/test_user.py | 4 +- qiita_db/test/test_util.py | 44 +- qiita_db/user.py | 30 +- qiita_pet/__init__.py | 2 +- qiita_pet/handlers/api_proxy/__init__.py | 2 +- .../support_files/doc/source/dev/rest.rst | 8 + .../support_files/doc/source/downloading.rst | 2 +- qiita_pet/support_files/doc/source/index.rst | 6 + .../doc/source/reanalysis/contexts.jpg | Bin 0 -> 78849 bytes .../doc/source/reanalysis/fig.1.R.png | Bin 0 -> 15896 bytes .../doc/source/reanalysis/fig.1.python.png | Bin 0 -> 53272 bytes .../doc/source/reanalysis/fig.2.R.png | Bin 0 -> 22482 bytes .../doc/source/reanalysis/fig.2.python.png | Bin 0 -> 88680 bytes .../doc/source/reanalysis/reanalysis.rst | 1124 +++++++++++++++++ .../reanalysis/understanding-contexts.rst | 93 ++ .../support_files/doc/source/redbiom.rst | 6 +- qiita_pet/webserver.py | 4 +- qiita_ware/__init__.py | 2 +- qiita_ware/ebi.py | 5 + qiita_ware/test/test_ebi.py | 1 + scripts/qiita-auto-processing | 77 +- setup.py | 2 +- 53 files changed, 1953 insertions(+), 431 deletions(-) create mode 100755 qiita_pet/support_files/doc/source/reanalysis/contexts.jpg create mode 100755 qiita_pet/support_files/doc/source/reanalysis/fig.1.R.png create mode 100755 qiita_pet/support_files/doc/source/reanalysis/fig.1.python.png create mode 100755 qiita_pet/support_files/doc/source/reanalysis/fig.2.R.png create mode 100755 qiita_pet/support_files/doc/source/reanalysis/fig.2.python.png create mode 100644 qiita_pet/support_files/doc/source/reanalysis/reanalysis.rst create mode 100755 qiita_pet/support_files/doc/source/reanalysis/understanding-contexts.rst mode change 100755 => 100644 qiita_pet/support_files/doc/source/redbiom.rst diff --git a/.travis.yml b/.travis.yml index f083ba6f1..a4fe0f137 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,7 +64,7 @@ install: - pip install https://github.com/qiita-spots/qiita_client/archive/master.zip - pip install https://github.com/qiita-spots/qtp-biom/archive/master.zip - export QIITA_SERVER_CERT=`pwd`/qiita_core/support_files/server.crt - - configure_biom --env-script "source ~/virtualenv/python2.7/bin/activate; export PATH=$HOME/miniconda3/bin/:$PATH; . activate qtp-biom" --server-cert $QIITA_SERVER_CERT + - configure_biom --env-script "export PATH=$HOME/miniconda3/bin/:$PATH; source activate qtp-biom" --server-cert $QIITA_SERVER_CERT - source deactivate - source activate qiita before_script: diff --git a/CHANGELOG.md b/CHANGELOG.md index 038c296a3..82838c1e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Qiita changelog +Version 092020 +-------------- + +* Added a new endpoint to inject artifacts to existing preparations or jobs: `/qiita_db/artifact/` +* Outdated commands with the exact same name than newer commands will be marked as not outdated. This is helpful for cases where the commands haven't changed between version +* Added the `add_ebi_accessions` to the `to_dataframe()` method of the information files so it can be used to `redbiom`. This will allow searching via sample or experiment accessions +* Added the `release_validator_job` method to `ProcessingJob` method to easily retrieve the `release_validator` job of a `processing_job` +* Re-added `STUDY_TYPE` to the EBI-ENA submission as they are required but deprecated so just adding as Other +* Added qiime2.2020.08 to the system; which updated these plugins: qp-qiime2, qtp-biom, qtp-diversity, qtp-visualization +* Shogun processing using Woltka will now produce 2 extra artifacts: a per genome and per gene artifacts + Version 072020 -------------- diff --git a/README.rst b/README.rst index e04fae360..e2ed9e94d 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ compute resources to the global community, alleviating the technical burdens, such as familiarity with the command line or access to compute power, that are typically limiting for researchers studying microbial ecology. -Qiita is currently in alpha status. We are very open to community +Qiita is currently in beta status. We are very open to community contributions and feedback. If you're interested in contributing to Qiita, see `CONTRIBUTING.md `__. If you'd like to report bugs or request features, you can do that in the @@ -43,9 +43,7 @@ Current features * Target gene data: we support deblur against GreenGenes (13_8) and close reference picking against GreenGenes (13_8) and Silva. - * Metagenoic/Shotgun data: we support Shogun processing. Note that this data - is suitable for download and further down stream analyses but we don't recommend - meta-analysis within Qiita (only single study). + * Metagenomic and Metatranscriptomic data: we support Shogun processing. * biom files can be added as new preparation templates for downstream analyses; however, this cannot be made public. diff --git a/qiita_core/__init__.py b/qiita_core/__init__.py index 854abc53a..a86cb7731 100644 --- a/qiita_core/__init__.py +++ b/qiita_core/__init__.py @@ -6,4 +6,4 @@ # The full license is in the file LICENSE, distributed with this software. # ----------------------------------------------------------------------------- -__version__ = "052020" +__version__ = "092020" diff --git a/qiita_db/__init__.py b/qiita_db/__init__.py index 60f8a3716..e63edbb4d 100644 --- a/qiita_db/__init__.py +++ b/qiita_db/__init__.py @@ -27,7 +27,7 @@ from . import user from . import processing_job -__version__ = "052020" +__version__ = "092020" __all__ = ["analysis", "artifact", "archive", "base", "commands", "environment_manager", "exceptions", "investigation", "logger", diff --git a/qiita_db/analysis.py b/qiita_db/analysis.py index c41a6ac0e..e0be83ae9 100644 --- a/qiita_db/analysis.py +++ b/qiita_db/analysis.py @@ -355,11 +355,9 @@ def description(self, description): QiitaDBStatusError Analysis is public """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.{0} SET description = %s - WHERE analysis_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [description, self._id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{0} SET description = %s + WHERE analysis_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [description, self._id]) @property def samples(self): @@ -513,11 +511,9 @@ def pmid(self, pmid): ----- An analysis should only ever have one PMID attached to it. """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.{0} SET pmid = %s - WHERE analysis_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [pmid, self._id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{0} SET pmid = %s + WHERE analysis_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [pmid, self._id]) @property def can_be_publicized(self): @@ -618,13 +614,11 @@ def set_error(self, error_msg): error_msg : str The error message """ - with qdb.sql_connection.TRN: - le = qdb.logger.LogEntry.create('Runtime', error_msg) - sql = """UPDATE qiita.analysis - SET logging_id = %s - WHERE analysis_id = %s""" - qdb.sql_connection.TRN.add(sql, [le.id, self.id]) - qdb.sql_connection.TRN.execute() + le = qdb.logger.LogEntry.create('Runtime', error_msg) + sql = """UPDATE qiita.analysis + SET logging_id = %s + WHERE analysis_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [le.id, self.id]) def has_access(self, user): """Returns whether the given user has access to the analysis @@ -696,11 +690,9 @@ def share(self, user): if user.id == self.owner or user.id in self.shared_with: return - with qdb.sql_connection.TRN: - sql = """INSERT INTO qiita.analysis_users (analysis_id, email) - VALUES (%s, %s)""" - qdb.sql_connection.TRN.add(sql, [self._id, user.id]) - qdb.sql_connection.TRN.execute() + sql = """INSERT INTO qiita.analysis_users (analysis_id, email) + VALUES (%s, %s)""" + qdb.sql_connection.perform_as_transaction(sql, [self._id, user.id]) def unshare(self, user): """Unshare the analysis with another user @@ -710,11 +702,9 @@ def unshare(self, user): user: User object The user to unshare the analysis with """ - with qdb.sql_connection.TRN: - sql = """DELETE FROM qiita.analysis_users - WHERE analysis_id = %s AND email = %s""" - qdb.sql_connection.TRN.add(sql, [self._id, user.id]) - qdb.sql_connection.TRN.execute() + sql = """DELETE FROM qiita.analysis_users + WHERE analysis_id = %s AND email = %s""" + qdb.sql_connection.perform_as_transaction(sql, [self._id, user.id]) def _lock_samples(self): """Only dflt analyses can have samples added/removed diff --git a/qiita_db/artifact.py b/qiita_db/artifact.py index 900c80dd0..7b70f35b1 100644 --- a/qiita_db/artifact.py +++ b/qiita_db/artifact.py @@ -388,8 +388,7 @@ def _associate_with_analysis(instance, analysis_id): (analysis_id, artifact_id) VALUES (%s, %s)""" sql_args = [analysis_id, instance.id] - qdb.sql_connection.TRN.add(sql, sql_args) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction(sql, sql_args) with qdb.sql_connection.TRN: if parents: @@ -673,12 +672,10 @@ def name(self, value): ValueError If `value` contains more than 35 chars """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.artifact - SET name = %s - WHERE artifact_id = %s""" - qdb.sql_connection.TRN.add(sql, [value, self.id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.artifact + SET name = %s + WHERE artifact_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [value, self.id]) @property def timestamp(self): @@ -751,8 +748,7 @@ def _set_visibility(self, value): sql = """UPDATE qiita.artifact SET visibility_id = %s WHERE artifact_id IN %s""" - qdb.sql_connection.TRN.add(sql, [vis_id, tuple(ids)]) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction(sql, [vis_id, tuple(ids)]) @visibility.setter def visibility(self, value): @@ -989,15 +985,13 @@ def is_submitted_to_vamps(self, value): QiitaDBOperationNotPermittedError If the artifact cannot be submitted to VAMPS """ - with qdb.sql_connection.TRN: - if not self.can_be_submitted_to_vamps: - raise qdb.exceptions.QiitaDBOperationNotPermittedError( - "Artifact %s cannot be submitted to VAMPS" % self.id) - sql = """UPDATE qiita.artifact - SET submitted_to_vamps = %s - WHERE artifact_id = %s""" - qdb.sql_connection.TRN.add(sql, [value, self.id]) - qdb.sql_connection.TRN.execute() + if not self.can_be_submitted_to_vamps: + raise qdb.exceptions.QiitaDBOperationNotPermittedError( + "Artifact %s cannot be submitted to VAMPS" % self.id) + sql = """UPDATE qiita.artifact + SET submitted_to_vamps = %s + WHERE artifact_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [value, self.id]) @property def filepaths(self): diff --git a/qiita_db/download_link.py b/qiita_db/download_link.py index 92f9efebd..2fd7c971f 100644 --- a/qiita_db/download_link.py +++ b/qiita_db/download_link.py @@ -72,10 +72,8 @@ def delete(cls, jti): jti : object The jwt token identifier """ - with qdb.sql_connection.TRN: - sql = """DELETE FROM qiita.{0} WHERE jti=%s""".format(cls._table) - qdb.sql_connection.TRN.add(sql, [jti]) - qdb.sql_connection.TRN.execute() + sql = """DELETE FROM qiita.{0} WHERE jti=%s""".format(cls._table) + qdb.sql_connection.perform_as_transaction(sql, [jti]) @classmethod def exists(cls, jti): @@ -98,10 +96,8 @@ def delete_expired(cls): r"""Deletes all expired download links""" now = datetime.now(timezone.utc) - with qdb.sql_connection.TRN: - sql = """DELETE FROM qiita.{0} WHERE exp<%s""".format(cls._table) - qdb.sql_connection.TRN.add(sql, [now]) - qdb.sql_connection.TRN.execute() + sql = """DELETE FROM qiita.{0} WHERE exp<%s""".format(cls._table) + qdb.sql_connection.perform_as_transaction(sql, [now]) @classmethod def get(cls, jti): diff --git a/qiita_db/handlers/artifact.py b/qiita_db/handlers/artifact.py index 1536f5d8e..6d701a880 100644 --- a/qiita_db/handlers/artifact.py +++ b/qiita_db/handlers/artifact.py @@ -8,8 +8,9 @@ from tornado.web import HTTPError from collections import defaultdict -from json import loads +from json import loads, dumps +from qiita_core.qiita_settings import r_client import qiita_db as qdb from .oauth2 import OauthBaseHandler, authenticate_oauth @@ -234,3 +235,69 @@ def post(self): self.set_status(200, reason="Artifact type already exists") self.finish() + + +class APIArtifactHandler(OauthBaseHandler): + @authenticate_oauth + def post(self): + user_email = self.get_argument('user_email') + job_id = self.get_argument('job_id', None) + prep_id = self.get_argument('prep_id', None) + atype = self.get_argument('artifact_type') + aname = self.get_argument('command_artifact_name', 'Name') + files = self.get_argument('files') + + if job_id is None and prep_id is None: + raise HTTPError( + 400, reason='You need to specify a job_id or a prep_id') + if job_id is not None and prep_id is not None: + raise HTTPError( + 400, reason='You need to specify only a job_id or a prep_id') + + user = qdb.user.User(user_email) + values = { + 'files': files, 'artifact_type': atype, 'name': aname, + # leaving here in case we need to add a way to add an artifact + # directly to an analysis, for more information see + # ProcessingJob._complete_artifact_transformation + 'analysis': None} + PJ = qdb.processing_job.ProcessingJob + if job_id is not None: + TN = qdb.sql_connection.TRN + job = PJ(job_id) + with TN: + sql = """SELECT command_output_id + FROM qiita.command_output + WHERE name = %s AND command_id = %s""" + TN.add(sql, [aname, job.command.id]) + results = TN.execute_fetchflatten() + if len(results) < 1: + raise HTTPError(400, 'The command_artifact_name does not ' + 'exist in the command') + cmd_out_id = results[0] + provenance = {'job': job_id, + 'cmd_out_id': cmd_out_id, + # direct_creation is a flag to avoid having to wait + # for the complete job to create the new artifact, + # which is normally ran during regular processing. + # Skipping is fine because we are adding an artifact + # to an existing job outside of regular processing + 'direct_creation': True, + 'name': aname} + values['provenance'] = dumps(provenance) + # inherint the first prep info file from the first input artifact + prep_id = job.input_artifacts[0].prep_templates[0].id + else: + prep_id = int(prep_id) + + values['template'] = prep_id + cmd = qdb.software.Command.get_validator(atype) + params = qdb.software.Parameters.load(cmd, values_dict=values) + new_job = PJ.create(user, params, True) + new_job.submit() + + r_client.set('prep_template_%d' % prep_id, + dumps({'job_id': new_job.id, 'is_qiita_job': True})) + + self.write(new_job.id) + self.finish() diff --git a/qiita_db/handlers/tests/test_artifact.py b/qiita_db/handlers/tests/test_artifact.py index 1d951cb82..2cdf09682 100644 --- a/qiita_db/handlers/tests/test_artifact.py +++ b/qiita_db/handlers/tests/test_artifact.py @@ -7,13 +7,13 @@ # ----------------------------------------------------------------------------- from unittest import main, TestCase -from json import loads +from json import loads, dumps from functools import partial from os.path import join, exists, isfile from os import close, remove from shutil import rmtree from tempfile import mkstemp, mkdtemp -from json import dumps +from time import sleep from tornado.web import HTTPError import pandas as pd @@ -288,5 +288,107 @@ def test_post(self): self.assertEqual(obs.code, 200) +class APIArtifactHandlerTests(OauthTestingBase): + def setUp(self): + super(APIArtifactHandlerTests, self).setUp() + self._clean_up_files = [] + + def tearDown(self): + super(APIArtifactHandlerTests, self).tearDown() + + for f in self._clean_up_files: + if exists(f): + remove(f) + + def test_post(self): + # no header + obs = self.post('/qiita_db/artifact/', data={}) + self.assertEqual(obs.code, 400) + + fd, fp = mkstemp(suffix='_table.biom') + close(fd) + # renaming samples + et.update_ids({'S1': '1.SKB1.640202', + 'S2': '1.SKD3.640198', + 'S3': '1.SKM4.640180'}, inplace=True) + with biom_open(fp, 'w') as f: + et.to_hdf5(f, "test") + self._clean_up_files.append(fp) + + # no job_id or prep_id + data = {'user_email': 'demo@microbio.me', + 'artifact_type': 'BIOM', + 'command_artifact_name': 'OTU table', + 'files': dumps({'biom': [fp]})} + + obs = self.post('/qiita_db/artifact/', headers=self.header, data=data) + self.assertEqual(obs.code, 400) + self.assertIn( + 'You need to specify a job_id or a prep_id', str(obs.error)) + + # both job_id and prep_id defined + data['job_id'] = 'e5609746-a985-41a1-babf-6b3ebe9eb5a9' + data['prep_id'] = 'prep_id' + obs = self.post('/qiita_db/artifact/', headers=self.header, data=data) + self.assertEqual(obs.code, 400) + self.assertIn( + 'You need to specify only a job_id or a prep_id', str(obs.error)) + + # make sure that all the plugins are on + qdb.util.activate_or_update_plugins(update=True) + + # tests success by inserting a new artifact into an existing job + original_job = qdb.processing_job.ProcessingJob(data['job_id']) + input_artifact = original_job.input_artifacts[0] + original_children = input_artifact.children + self.assertEqual(len(original_children), 3) + + # send the new data + del data['prep_id'] + obs = self.post('/qiita_db/artifact/', headers=self.header, data=data) + jid = obs.body.decode("utf-8") + + job = qdb.processing_job.ProcessingJob(jid) + while job.status not in ('error', 'success'): + sleep(0.5) + + # now the original job should have 4 children and make sure they have + # the same parent and parameters + children = input_artifact.children + new_children = list(set(children) - set(original_children))[0] + self.assertEqual(len(children), 4) + for c in children[1:]: + self.assertCountEqual(children[0].processing_parameters.values, + c.processing_parameters.values) + self.assertEqual(children[0].parents, c.parents) + + # making sure the new artifact is part of the descendants, which is a + # different method and usage than children method + self.assertIn(new_children, input_artifact.descendants.nodes) + + # now let's test adding an artifact directly to a new prep + new_prep = qdb.metadata_template.prep_template.PrepTemplate.create( + pd.DataFrame({'new_col': {'1.SKB1.640202': 1, + '1.SKD3.640198': 2, + '1.SKM4.640180': 3}}), + qdb.study.Study(1), '16S') + fd, fp = mkstemp(suffix='_table.biom') + close(fd) + with biom_open(fp, 'w') as f: + et.to_hdf5(f, "test") + self._clean_up_files.append(fp) + data = {'user_email': 'demo@microbio.me', + 'artifact_type': 'BIOM', 'prep_id': new_prep.id, + 'files': dumps({'biom': [fp]})} + + obs = self.post('/qiita_db/artifact/', headers=self.header, data=data) + jid = obs.body.decode("utf-8") + + job = qdb.processing_job.ProcessingJob(jid) + while job.status not in ('error', 'success'): + sleep(0.5) + self.assertIsNotNone(new_prep.artifact) + + if __name__ == '__main__': main() diff --git a/qiita_db/logger.py b/qiita_db/logger.py index 5e83c49df..3934fedcd 100644 --- a/qiita_db/logger.py +++ b/qiita_db/logger.py @@ -181,12 +181,9 @@ def msg(self): def clear_info(self): """Resets the list of info dicts to be an empty list """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.{} SET information = %s - WHERE logging_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [dumps([]), self.id]) - - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{} SET information = %s + WHERE logging_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [dumps([]), self.id]) def add_info(self, info): """Adds new information to the info associated with this LogEntry @@ -201,12 +198,10 @@ def add_info(self, info): - When `info` is added, keys can be of any type, but upon retrieval, they will be of type str """ - with qdb.sql_connection.TRN: - current_info = self.info - current_info.append(info) - new_info = dumps(current_info) + current_info = self.info + current_info.append(info) + new_info = dumps(current_info) - sql = """UPDATE qiita.{} SET information = %s - WHERE logging_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [new_info, self.id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{} SET information = %s + WHERE logging_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [new_info, self.id]) diff --git a/qiita_db/meta_util.py b/qiita_db/meta_util.py index 721c732e3..733713dc6 100644 --- a/qiita_db/meta_util.py +++ b/qiita_db/meta_util.py @@ -335,11 +335,9 @@ def sizeof_fmt(value, position): # preparing vals to insert into DB vals = dumps(dict([x[:-1] for x in vals])) - with qdb.sql_connection.TRN: - sql = """INSERT INTO qiita.stats_daily (stats, stats_timestamp) - VALUES (%s, NOW())""" - qdb.sql_connection.TRN.add(sql, [vals]) - qdb.sql_connection.TRN.execute() + sql = """INSERT INTO qiita.stats_daily (stats, stats_timestamp) + VALUES (%s, NOW())""" + qdb.sql_connection.perform_as_transaction(sql, [vals]) return missing_files diff --git a/qiita_db/metadata_template/base_metadata_template.py b/qiita_db/metadata_template/base_metadata_template.py index 51ea5f0a1..eb09ead97 100644 --- a/qiita_db/metadata_template/base_metadata_template.py +++ b/qiita_db/metadata_template/base_metadata_template.py @@ -279,19 +279,18 @@ def setitem(self, column, value): QiitaDBColumnError If the column does not exist in the table """ - with qdb.sql_connection.TRN: - # Check if the column exist in the table - if column not in self._get_categories(): - raise qdb.exceptions.QiitaDBColumnError( - "Column %s does not exist in %s" % - (column, self._dynamic_table)) + # Check if the column exist in the table + if column not in self._get_categories(): + raise qdb.exceptions.QiitaDBColumnError( + "Column %s does not exist in %s" % + (column, self._dynamic_table)) - sql = """UPDATE qiita.{0} - SET sample_values = sample_values || %s - WHERE sample_id = %s""".format(self._dynamic_table) + sql = """UPDATE qiita.{0} + SET sample_values = sample_values || %s + WHERE sample_id = %s""".format(self._dynamic_table) - qdb.sql_connection.TRN.add(sql, [dumps({column: value}), self.id]) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + sql, [dumps({column: value}), self.id]) def __setitem__(self, column, value): r"""Sets the metadata value for the category `column` @@ -1158,8 +1157,8 @@ def to_file(self, fp, samples=None): df.to_csv(fp, index_label='sample_name', na_rep="", sep='\t', encoding='utf-8') - def to_dataframe(self): - """Returns the metadata template as a dataframe + def _common_to_dataframe_steps(self): + """Perform the common to_dataframe steps Returns ------- diff --git a/qiita_db/metadata_template/prep_template.py b/qiita_db/metadata_template/prep_template.py index ecea21ac1..c89a3d94c 100644 --- a/qiita_db/metadata_template/prep_template.py +++ b/qiita_db/metadata_template/prep_template.py @@ -453,14 +453,13 @@ def investigation_type(self, investigation_type): QiitaDBColumnError If the investigation type is not a valid ENA ontology """ - with qdb.sql_connection.TRN: - if investigation_type is not None: - self.validate_investigation_type(investigation_type) + if investigation_type is not None: + self.validate_investigation_type(investigation_type) - sql = """UPDATE qiita.prep_template SET investigation_type = %s - WHERE {0} = %s""".format(self._id_column) - qdb.sql_connection.TRN.add(sql, [investigation_type, self.id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.prep_template SET investigation_type = %s + WHERE {0} = %s""".format(self._id_column) + qdb.sql_connection.perform_as_transaction( + sql, [investigation_type, self.id]) @property def study_id(self): @@ -494,11 +493,9 @@ def deprecated(self, deprecated): deprecated : bool If the prep info file is deprecated """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.prep_template SET deprecated = %s - WHERE {0} = %s""".format(self._id_column) - qdb.sql_connection.TRN.add(sql, [deprecated, self.id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.prep_template SET deprecated = %s + WHERE {0} = %s""".format(self._id_column) + qdb.sql_connection.perform_as_transaction(sql, [deprecated, self.id]) def generate_files(self, samples=None, columns=None): r"""Generates all the files that contain data from this template @@ -761,9 +758,24 @@ def name(self): @name.setter def name(self, value): """Changes the name of the prep template""" - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.prep_template - SET name = %s - WHERE prep_template_id = %s""" - qdb.sql_connection.TRN.add(sql, [value, self.id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.prep_template + SET name = %s + WHERE prep_template_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [value, self.id]) + + def to_dataframe(self, add_ebi_accessions=False): + """Returns the metadata template as a dataframe + + Parameters + ---------- + add_ebi_accessions : bool, optional + If this should add the ebi accessions + """ + df = self._common_to_dataframe_steps() + + if add_ebi_accessions: + accessions = self.ebi_experiment_accessions + df['qiita_ebi_experiment_accessions'] = df.index.map( + lambda sid: accessions[sid]) + + return df diff --git a/qiita_db/metadata_template/sample_template.py b/qiita_db/metadata_template/sample_template.py index 3f05c46c6..1e209ce98 100644 --- a/qiita_db/metadata_template/sample_template.py +++ b/qiita_db/metadata_template/sample_template.py @@ -332,3 +332,20 @@ def biosample_accessions(self, value): If a sample in `value` already has an accession number """ self._update_accession_numbers('biosample_accession', value) + + def to_dataframe(self, add_ebi_accessions=False): + """Returns the metadata template as a dataframe + + Parameters + ---------- + add_ebi_accessions : bool, optional + If this should add the ebi accessions + """ + df = self._common_to_dataframe_steps() + + if add_ebi_accessions: + accessions = self.ebi_sample_accessions + df['qiita_ebi_sample_accessions'] = df.index.map( + lambda sid: accessions[sid]) + + return df diff --git a/qiita_db/metadata_template/test/test_prep_template.py b/qiita_db/metadata_template/test/test_prep_template.py index b5a64efc7..5c836c393 100644 --- a/qiita_db/metadata_template/test/test_prep_template.py +++ b/qiita_db/metadata_template/test/test_prep_template.py @@ -685,6 +685,12 @@ def test_to_dataframe(self): u'illumina_technology', u'sample_center', u'pcr_primers', u'study_center', 'qiita_prep_id'}) + # test with add_ebi_accessions as True + obs = self.tester.to_dataframe(True) + self.assertEqual( + self.tester.ebi_experiment_accessions, + obs.qiita_ebi_experiment_accessions.to_dict()) + def test_clean_validate_template_error_bad_chars(self): """Raises an error if there are invalid characters in the sample names """ diff --git a/qiita_db/metadata_template/test/test_sample_template.py b/qiita_db/metadata_template/test/test_sample_template.py index 1764642c9..dd71cc4ca 100644 --- a/qiita_db/metadata_template/test/test_sample_template.py +++ b/qiita_db/metadata_template/test/test_sample_template.py @@ -1975,6 +1975,12 @@ def test_to_dataframe(self): 'anonymized_name', 'tot_org_carb', 'description_duplicate', 'env_feature', 'scientific_name', 'qiita_study_id'}) + # test with add_ebi_accessions as True + obs = self.tester.to_dataframe(True) + self.assertEqual( + self.tester.ebi_sample_accessions, + obs.qiita_ebi_sample_accessions.to_dict()) + def test_check_restrictions(self): obs = self.tester.check_restrictions( [STC['EBI']]) diff --git a/qiita_db/ontology.py b/qiita_db/ontology.py index 63f37c8d6..0f5010efe 100644 --- a/qiita_db/ontology.py +++ b/qiita_db/ontology.py @@ -77,16 +77,14 @@ def add_user_defined_term(self, term): term : str New user defined term to add into a given ontology """ - with qdb.sql_connection.TRN: - # we don't need to add an existing term - terms = self.user_defined_terms + self.terms - - if term not in terms: - sql = """INSERT INTO qiita.term - (ontology_id, term, user_defined) - VALUES (%s, %s, true);""" - qdb.sql_connection.TRN.add(sql, [self.id, term]) - qdb.sql_connection.TRN.execute() + # we don't need to add an existing term + terms = self.user_defined_terms + self.terms + + if term not in terms: + sql = """INSERT INTO qiita.term + (ontology_id, term, user_defined) + VALUES (%s, %s, true);""" + qdb.sql_connection.perform_as_transaction(sql, [self.id, term]) def term_type(self, term): """Get the type of a given ontology term diff --git a/qiita_db/portal.py b/qiita_db/portal.py index d9cb5ae55..a5585aa69 100644 --- a/qiita_db/portal.py +++ b/qiita_db/portal.py @@ -72,38 +72,36 @@ def create(cls, portal, desc): QiitaDBDuplicateError Portal name already exists """ - with qdb.sql_connection.TRN: - if cls.exists(portal): - raise qdb.exceptions.QiitaDBDuplicateError("Portal", portal) - - # Add portal and default analyses for all users - sql = """DO $do$ - DECLARE - pid bigint; - eml varchar; - aid bigint; - BEGIN - INSERT INTO qiita.portal_type (portal, portal_description) - VALUES (%s, %s) - RETURNING portal_type_id INTO pid; - - FOR eml IN - SELECT email FROM qiita.qiita_user - LOOP - INSERT INTO qiita.analysis - (email, name, description, dflt) - VALUES (eml, eml || '-dflt', 'dflt', true) - RETURNING analysis_id INTO aid; - - INSERT INTO qiita.analysis_portal - (analysis_id, portal_type_id) - VALUES (aid, pid); - END LOOP; - END $do$;""" - qdb.sql_connection.TRN.add(sql, [portal, desc]) - qdb.sql_connection.TRN.execute() + if cls.exists(portal): + raise qdb.exceptions.QiitaDBDuplicateError("Portal", portal) + + # Add portal and default analyses for all users + sql = """DO $do$ + DECLARE + pid bigint; + eml varchar; + aid bigint; + BEGIN + INSERT INTO qiita.portal_type (portal, portal_description) + VALUES (%s, %s) + RETURNING portal_type_id INTO pid; + + FOR eml IN + SELECT email FROM qiita.qiita_user + LOOP + INSERT INTO qiita.analysis + (email, name, description, dflt) + VALUES (eml, eml || '-dflt', 'dflt', true) + RETURNING analysis_id INTO aid; + + INSERT INTO qiita.analysis_portal + (analysis_id, portal_type_id) + VALUES (aid, pid); + END LOOP; + END $do$;""" + qdb.sql_connection.perform_as_transaction(sql, [portal, desc]) - return cls(portal) + return cls(portal) @staticmethod def delete(portal): diff --git a/qiita_db/processing_job.py b/qiita_db/processing_job.py index 2bdd2d7c3..13456e871 100644 --- a/qiita_db/processing_job.py +++ b/qiita_db/processing_job.py @@ -814,12 +814,35 @@ def external_id(self, value): - If the current status of the job is 'running' and `value` is 'queued' """ + sql = """UPDATE qiita.processing_job + SET external_job_id = %s + WHERE processing_job_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [value, self.id]) + + @property + def release_validator_job(self): + """Retrieves the release validator job + + Returns + ------- + qiita_db.processing_job.ProcessingJob or None + The release validator job of this job + """ + rvalidator = None with qdb.sql_connection.TRN: - sql = """UPDATE qiita.processing_job - SET external_job_id = %s - WHERE processing_job_id = %s""" - qdb.sql_connection.TRN.add(sql, [value, self.id]) - qdb.sql_connection.TRN.execute() + sql = """SELECT processing_job_id + FROM qiita.processing_job + WHERE command_id in ( + SELECT command_id + FROM qiita.software_command + WHERE name = 'release_validators') + AND command_parameters->>'job' = %s""" + qdb.sql_connection.TRN.add(sql, [self.id]) + results = qdb.sql_connection.TRN.execute_fetchflatten() + if results: + rvalidator = ProcessingJob(results[0]) + + return rvalidator def submit(self, parent_job_id=None, dependent_jobs_list=None): """Submits the job to execution @@ -1090,6 +1113,14 @@ def _complete_artifact_definition(self, artifact_data): Dict with the artifact information. `filepaths` contains the list of filepaths and filepath types for the artifact and `artifact_type` the type of the artifact + + Notes + ----- + The `provenance` in the job.parameters can contain a `direct_creation` + flag to avoid having to wait for the complete job to create a new + artifact, which is normally ran during regular processing. Skipping is + fine because we are adding an artifact to an existing job outside of + regular processing """ with qdb.sql_connection.TRN: atype = artifact_data['artifact_type'] @@ -1100,18 +1131,41 @@ def _complete_artifact_definition(self, artifact_data): if job_params['provenance'] is not None: # The artifact is a result from a previous job provenance = loads(job_params['provenance']) - if provenance.get('data_type') is not None: - artifact_data = {'data_type': provenance['data_type'], - 'artifact_data': artifact_data} - - sql = """UPDATE qiita.processing_job_validator - SET artifact_info = %s - WHERE validator_id = %s""" - qdb.sql_connection.TRN.add( - sql, [dumps(artifact_data), self.id]) - qdb.sql_connection.TRN.execute() - # Can't create the artifact until all validators are completed - self._set_status('waiting') + if provenance.get('direct_creation', False): + original_job = ProcessingJob(provenance['job']) + artifact = qdb.artifact.Artifact.create( + filepaths, atype, + parents=original_job.input_artifacts, + processing_parameters=original_job.parameters, + analysis=job_params['analysis'], + name=job_params['name']) + + sql = """ + INSERT INTO qiita.artifact_output_processing_job + (artifact_id, processing_job_id, + command_output_id) + VALUES (%s, %s, %s)""" + qdb.sql_connection.TRN.add( + sql, [artifact.id, original_job.id, + provenance['cmd_out_id']]) + qdb.sql_connection.TRN.execute() + + self._set_status('success') + else: + if provenance.get('data_type') is not None: + artifact_data = {'data_type': provenance['data_type'], + 'artifact_data': artifact_data} + + sql = """UPDATE qiita.processing_job_validator + SET artifact_info = %s + WHERE validator_id = %s""" + qdb.sql_connection.TRN.add( + sql, [dumps(artifact_data), self.id]) + qdb.sql_connection.TRN.execute() + + # Can't create the artifact until all validators + # are completed + self._set_status('waiting') else: # The artifact is uploaded by the user or is the initial # artifact of an analysis @@ -1450,16 +1504,14 @@ def step(self, value): qiita_db.exceptions.QiitaDBOperationNotPermittedError If the status of the job is not 'running' """ - with qdb.sql_connection.TRN: - if self.status != 'running': - raise qdb.exceptions.QiitaDBOperationNotPermittedError( - "Cannot change the step of a job whose status is not " - "'running'") - sql = """UPDATE qiita.processing_job - SET step = %s - WHERE processing_job_id = %s""" - qdb.sql_connection.TRN.add(sql, [value, self.id]) - qdb.sql_connection.TRN.execute() + if self.status != 'running': + raise qdb.exceptions.QiitaDBOperationNotPermittedError( + "Cannot change the step of a job whose status is not " + "'running'") + sql = """UPDATE qiita.processing_job + SET step = %s + WHERE processing_job_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [value, self.id]) @property def children(self): diff --git a/qiita_db/software.py b/qiita_db/software.py index 171490597..eb746c476 100644 --- a/qiita_db/software.py +++ b/qiita_db/software.py @@ -622,22 +622,37 @@ def active(self): ------- bool Whether the command is active or not + + Notes + ----- + This method differentiates between commands based on analysis_only or + the software type. The commands that are not for analysis (processing) + and are from an artifact definition software will return as active + if they have the same name than a command that is active; this helps + for situations where the processing plugins are updated but some + commands didn't change its version. """ with qdb.sql_connection.TRN: - sql = """SELECT active - FROM qiita.software_command - WHERE command_id = %s""" + cmd_type = self.software.type + if self.analysis_only or cmd_type == 'artifact definition': + sql = """SELECT active + FROM qiita.software_command + WHERE command_id = %s""" + else: + sql = """SELECT EXISTS ( + SELECT active FROM qiita.software_command + WHERE name IN ( + SELECT name FROM qiita.software_command + WHERE command_id = %s) AND active = true)""" qdb.sql_connection.TRN.add(sql, [self.id]) return qdb.sql_connection.TRN.execute_fetchlast() def activate(self): """Activates the command""" - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.software_command - SET active = %s - WHERE command_id = %s""" - qdb.sql_connection.TRN.add(sql, [True, self.id]) - return qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.software_command + SET active = %s + WHERE command_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [True, self.id]) @property def analysis_only(self): @@ -1277,11 +1292,9 @@ def deprecated(self, deprecate): deprecate : bool New software deprecate value """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.software SET deprecated = %s - WHERE software_id = %s""" - qdb.sql_connection.TRN.add(sql, [deprecate, self._id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.software SET deprecated = %s + WHERE software_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [deprecate, self._id]) @property def active(self): @@ -1299,12 +1312,10 @@ def active(self): def activate(self): """Activates the plugin""" - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.software - SET active = %s - WHERE software_id = %s""" - qdb.sql_connection.TRN.add(sql, [True, self.id]) - return qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.software + SET active = %s + WHERE software_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [True, self.id]) @property def client_id(self): diff --git a/qiita_db/sql_connection.py b/qiita_db/sql_connection.py index 5955d094e..2f4855bf3 100644 --- a/qiita_db/sql_connection.py +++ b/qiita_db/sql_connection.py @@ -493,6 +493,24 @@ def add_post_rollback_func(self, func, *args, **kwargs): TRNADMIN = Transaction(admin=True) +def perform_as_transaction(sql, parameters=None): + """Opens, adds and executes sql as a single transaction + + Parameters + ---------- + sql : str + The SQL to execute + parameters: object, optional + The object of parameters to pass to the TRN.add command + """ + with TRN: + if parameters: + TRN.add(sql, parameters) + else: + TRN.add(sql) + TRN.execute() + + def create_new_transaction(): """Creates a new global transaction diff --git a/qiita_db/study.py b/qiita_db/study.py index 77543854a..2289619ba 100644 --- a/qiita_db/study.py +++ b/qiita_db/study.py @@ -477,7 +477,6 @@ def insert_tags(cls, user, tags): SELECT %s, %s WHERE NOT EXISTS ( SELECT 1 FROM qiita.study_tags WHERE study_tag = %s)""" sql_args = [[email, tag, tag] for tag in tags] - qdb.sql_connection.TRN.add(sql, sql_args, many=True) qdb.sql_connection.TRN.execute() @@ -506,11 +505,9 @@ def title(self, title): title : str The study title """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.{0} SET study_title = %s - WHERE study_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [title, self._id]) - return qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{0} SET study_title = %s + WHERE study_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [title, self._id]) @property def notes(self): @@ -536,11 +533,9 @@ def notes(self, notes): notes : str The study notes """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.{0} SET notes = %s - WHERE study_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [notes, self._id]) - return qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{0} SET notes = %s + WHERE study_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [notes, self._id]) @property def public_raw_download(self): @@ -566,11 +561,10 @@ def public_raw_download(self, public_raw_download): public_raw_download : bool The study public_raw_download """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.{0} SET public_raw_download = %s - WHERE study_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [public_raw_download, self._id]) - return qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{0} SET public_raw_download = %s + WHERE study_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction( + sql, [public_raw_download, self._id]) @property def info(self): @@ -772,13 +766,10 @@ def specimen_id_column(self, value): " contain unique " "values.") - with qdb.sql_connection.TRN: - # Set the new ones - sql = """UPDATE qiita.study SET - specimen_id_column = %s - WHERE study_id = %s""" - qdb.sql_connection.TRN.add(sql, [value, self._id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.study SET + specimen_id_column = %s + WHERE study_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [value, self._id]) @property def investigation(self): @@ -965,16 +956,14 @@ def ebi_study_accession(self, value): QiitDBError If the study already has an EBI study accession """ - with qdb.sql_connection.TRN: - if self.ebi_study_accession is not None: - raise qdb.exceptions.QiitaDBError( - "Study %s already has an EBI study accession" - % self.id) - sql = """UPDATE qiita.{} - SET ebi_study_accession = %s - WHERE study_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [value, self.id]) - qdb.sql_connection.TRN.execute() + if self.ebi_study_accession is not None: + raise qdb.exceptions.QiitaDBError( + "Study %s already has an EBI study accession" + % self.id) + sql = """UPDATE qiita.{} + SET ebi_study_accession = %s + WHERE study_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [value, self.id]) def _ebi_submission_jobs(self): """Helper code to avoid duplication""" @@ -1215,18 +1204,16 @@ def share(self, user): user: User object The user to share the study with """ - with qdb.sql_connection.TRN: - # Make sure the study is not already shared with the given user - if user in self.shared_with: - return - # Do not allow the study to be shared with the owner - if user == self.owner: - return - - sql = """INSERT INTO qiita.study_users (study_id, email) - VALUES (%s, %s)""" - qdb.sql_connection.TRN.add(sql, [self._id, user.id]) - qdb.sql_connection.TRN.execute() + # Make sure the study is not already shared with the given user + if user in self.shared_with: + return + # Do not allow the study to be shared with the owner + if user == self.owner: + return + + sql = """INSERT INTO qiita.study_users (study_id, email) + VALUES (%s, %s)""" + qdb.sql_connection.perform_as_transaction(sql, [self._id, user.id]) def unshare(self, user): """Unshare the study with another user @@ -1236,11 +1223,9 @@ def unshare(self, user): user: User object The user to unshare the study with """ - with qdb.sql_connection.TRN: - sql = """DELETE FROM qiita.study_users - WHERE study_id = %s AND email = %s""" - qdb.sql_connection.TRN.add(sql, [self._id, user.id]) - qdb.sql_connection.TRN.execute() + sql = """DELETE FROM qiita.study_users + WHERE study_id = %s AND email = %s""" + qdb.sql_connection.perform_as_transaction(sql, [self._id, user.id]) def update_tags(self, user, tags): """Sets the tags of the study @@ -1550,11 +1535,9 @@ def address(self, value): value : str New address for person """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.{0} SET address = %s - WHERE study_person_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [value, self._id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{0} SET address = %s + WHERE study_person_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [value, self._id]) @property def phone(self): @@ -1580,8 +1563,6 @@ def phone(self, value): value : str New phone number for person """ - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.{0} SET phone = %s - WHERE study_person_id = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [value, self._id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.{0} SET phone = %s + WHERE study_person_id = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [value, self._id]) diff --git a/qiita_db/test/test_analysis.py b/qiita_db/test/test_analysis.py index 8e5472a0a..952e0914b 100644 --- a/qiita_db/test/test_analysis.py +++ b/qiita_db/test/test_analysis.py @@ -555,12 +555,10 @@ def test_build_files_post_processing_cmd(self): # convert to json representation and store in PostgreSQL results = dumps(results) - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.software_command - SET post_processing_cmd = %s - WHERE command_id = %s""" - qdb.sql_connection.TRN.add(sql, [results, cmd_id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.software_command + SET post_processing_cmd = %s + WHERE command_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [results, cmd_id]) # create a sample analysis and run build_files on it. analysis = self._create_analyses_with_samples() @@ -581,12 +579,10 @@ def test_build_files_post_processing_cmd(self): self.assertEqual(obs, exp) # cleanup (assume command was NULL previously) - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.software_command - SET post_processing_cmd = NULL - WHERE command_id = %s""" - qdb.sql_connection.TRN.add(sql, [cmd_id]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.software_command + SET post_processing_cmd = NULL + WHERE command_id = %s""" + qdb.sql_connection.perform_as_transaction(sql, [cmd_id]) def test_build_files_merge_duplicated_sample_ids(self): user = qdb.user.User("demo@microbio.me") diff --git a/qiita_db/test/test_archive.py b/qiita_db/test/test_archive.py index 2c1f6e473..f1015897e 100644 --- a/qiita_db/test/test_archive.py +++ b/qiita_db/test/test_archive.py @@ -28,10 +28,9 @@ def test_insert_from_biom_and_retrieve_feature_values(self): # 7 - to test error due to not filepath biom aid = 7 - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add("DELETE FROM qiita.artifact_filepath " - "WHERE artifact_id = %d" % aid) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "DELETE FROM qiita.artifact_filepath " + "WHERE artifact_id = %d" % aid) with self.assertRaises(ValueError) as err: qdb.archive.Archive.insert_from_artifact( qdb.artifact.Artifact(aid), {}) diff --git a/qiita_db/test/test_commands.py b/qiita_db/test/test_commands.py index 4960de0ec..495367fd0 100644 --- a/qiita_db/test/test_commands.py +++ b/qiita_db/test/test_commands.py @@ -276,10 +276,8 @@ def _assert_current_patch(self, patch_to_check): def test_unpatched(self): """Test patching from unpatched state""" # Reset the settings table to the unpatched state - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE settings SET current_patch = 'unpatched'") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE settings SET current_patch = 'unpatched'") self._assert_current_patch('unpatched') qdb.environment_manager.patch(self.patches_dir) @@ -289,10 +287,8 @@ def test_unpatched(self): def test_skip_patch(self): """Test patching from a patched state""" - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE settings SET current_patch = '2.sql'") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE settings SET current_patch = '2.sql'") self._assert_current_patch('2.sql') # If it tried to apply patch 2.sql again, this will error @@ -306,10 +302,8 @@ def test_skip_patch(self): def test_nonexistent_patch(self): """Test case where current patch does not exist""" - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE settings SET current_patch = 'nope.sql'") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE settings SET current_patch = 'nope.sql'") self._assert_current_patch('nope.sql') with self.assertRaises(RuntimeError): @@ -322,10 +316,8 @@ def test_python_patch(self): f.write(PY_PATCH) # Reset the settings table to the unpatched state - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE settings SET current_patch = 'unpatched'") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE settings SET current_patch = 'unpatched'") self._assert_current_patch('unpatched') diff --git a/qiita_db/test/test_meta_util.py b/qiita_db/test/test_meta_util.py index 740a41ceb..bae0f1251 100644 --- a/qiita_db/test/test_meta_util.py +++ b/qiita_db/test/test_meta_util.py @@ -34,17 +34,13 @@ def tearDown(self): def _set_artifact_private(self): id_status = qdb.util.convert_to_id('private', 'visibility') - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE qiita.artifact SET visibility_id = %d" % id_status) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE qiita.artifact SET visibility_id = %d" % id_status) def _set_artifact_public(self): id_status = qdb.util.convert_to_id('public', 'visibility') - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE qiita.artifact SET visibility_id = %d" % id_status) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE qiita.artifact SET visibility_id = %d" % id_status) def test_validate_filepath_access_by_user(self): self._set_artifact_private() @@ -108,10 +104,8 @@ def test_validate_filepath_access_by_user(self): self.assertTrue(obs) # test in case there is a prep template that failed - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "INSERT INTO qiita.prep_template (data_type_id) VALUES (2)") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "INSERT INTO qiita.prep_template (data_type_id) VALUES (2)") for i in [1, 2, 3, 4, 5, 9, 12, 17, 18, 19, 20, 21]: obs = qdb.meta_util.validate_filepath_access_by_user(user, i) if i < 3: @@ -467,10 +461,8 @@ def test_generate_biom_and_metadata_release(self): self.assertEqual(txt_obs, txt_exp) # returning configuration - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE settings SET base_data_dir = '%s'" % obdr) - bdr = qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE settings SET base_data_dir = '%s'" % obdr) # testing public/default release qdb.meta_util.generate_biom_and_metadata_release() diff --git a/qiita_db/test/test_ontology.py b/qiita_db/test/test_ontology.py index e0e42951a..5144d0082 100644 --- a/qiita_db/test/test_ontology.py +++ b/qiita_db/test/test_ontology.py @@ -18,10 +18,9 @@ def setUp(self): self.ontology = qdb.ontology.Ontology(999999999) def _remove_term(self, term): - with qdb.sql_connection.TRN: - sql = "DELETE FROM qiita.term WHERE ontology_id = %s AND term = %s" - qdb.sql_connection.TRN.add(sql, [self.ontology.id, term]) - qdb.sql_connection.TRN.execute() + sql = "DELETE FROM qiita.term WHERE ontology_id = %s AND term = %s" + qdb.sql_connection.perform_as_transaction( + sql, [self.ontology.id, term]) def testConvertToID(self): self.assertEqual(qdb.util.convert_to_id('ENA', 'ontology'), 999999999) diff --git a/qiita_db/test/test_processing_job.py b/qiita_db/test/test_processing_job.py index fe887ce8c..c4248c634 100644 --- a/qiita_db/test/test_processing_job.py +++ b/qiita_db/test/test_processing_job.py @@ -446,6 +446,10 @@ def test_complete_type(self): qdb.artifact.Artifact(exp_artifact_count).filepaths]) def test_complete_success(self): + # Note that here we are submitting and creating other multiple jobs; + # thus here is the best place to test any intermediary steps/functions + # of the job creation, submission, exectution, and completion. + # # This first part of the test is just to test that by default the # naming of the output artifact will be the name of the output fd, fp = mkstemp(suffix='_table.biom') @@ -457,8 +461,16 @@ def test_complete_success(self): 'artifact_type': 'BIOM'}} job = _create_job() job._set_status('running') + + # here we can test that job.release_validator_job hasn't been created + # yet so it has to be None + self.assertIsNone(job.release_validator_job) job.complete(True, artifacts_data=artifacts_data) self._wait_for_job(job) + # let's check for the job that released the validators + self.assertIsNotNone(job.release_validator_job) + self.assertEqual(job.release_validator_job.parameters.values['job'], + job.id) # Retrieve the job that is performing the validation: validators = list(job.validator_jobs) self.assertEqual(len(validators), 1) @@ -780,13 +792,11 @@ def test_get_resource_allocation_info(self): # helper to set memory allocations easier def _set_allocation(memory): - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.processing_job_resource_allocation - SET allocation = '{0}' - WHERE name = 'Split libraries FASTQ'""".format( - '-q qiita -l mem=%s' % memory) - qdb.sql_connection.TRN.add(sql) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.processing_job_resource_allocation + SET allocation = '{0}' + WHERE name = 'Split libraries FASTQ'""".format( + '-q qiita -l mem=%s' % memory) + qdb.sql_connection.perform_as_transaction(sql) # let's start with something simple, samples*1000 # 27*1000 ~ 27000 @@ -858,8 +868,9 @@ def test_raise_if_not_in_construction_error(self): tester._raise_if_not_in_construction() def test_submit(self): - # In order to test a success, we need to actually run the jobs, which - # will mean to run split libraries, for example. + # The submit method is being tested in test_complete_success via + # a job, its release validators and validators submissions. + # Leaving this note here in case it's helpful for future development pass def test_from_default_workflow(self): diff --git a/qiita_db/test/test_software.py b/qiita_db/test/test_software.py index 022fd0889..e4cdf4e53 100644 --- a/qiita_db/test/test_software.py +++ b/qiita_db/test/test_software.py @@ -142,12 +142,10 @@ def test_post_processing_cmd(self): results = dumps(results) # modify table directly, in order to test method - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.software_command - SET post_processing_cmd = %s - WHERE command_id = 1""" - qdb.sql_connection.TRN.add(sql, [results]) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.software_command + SET post_processing_cmd = %s + WHERE command_id = 1""" + qdb.sql_connection.perform_as_transaction(sql, [results]) results = qdb.software.Command(1).post_processing_cmd @@ -159,12 +157,10 @@ def test_post_processing_cmd(self): self.assertEqual(results['script_params'], {'a': 'A', 'b': 'B'}) # clean up table - with qdb.sql_connection.TRN: - sql = """UPDATE qiita.software_command - SET post_processing_cmd = NULL - WHERE command_id = 1""" - qdb.sql_connection.TRN.add(sql) - qdb.sql_connection.TRN.execute() + sql = """UPDATE qiita.software_command + SET post_processing_cmd = NULL + WHERE command_id = 1""" + qdb.sql_connection.perform_as_transaction(sql) def test_description(self): self.assertEqual( @@ -334,6 +330,13 @@ def test_create_error(self): self.outputs) def test_create(self): + # let's deactivate all current plugins and commands; this is not + # important to test the creation but it is important to test if a + # command is active as the new commands should take precedence and + # should make the old commands active if they have the same name + qdb.software.Software.deactivate_all() + + # note that here we are adding commands to an existing software obs = qdb.software.Command.create( self.software, "Test Command", "This is a command for testing", self.parameters, self.outputs) @@ -355,6 +358,7 @@ def test_create(self): {'parameters': [], 'outputs': [], 'ignore_parent_command': False}) + # here we are creating a new software that we will add new commads to obs = qdb.software.Command.create( self.software, "Test Command 2", "This is a command for testing", self.parameters, analysis_only=True) @@ -379,23 +383,24 @@ def test_create(self): 'analysis': ('analysis', None), 'files': ('string', None), 'artifact_type': ('string', None)} - obs = qdb.software.Command.create( + validate = qdb.software.Command.create( software, "Validate", "Test creating a validate command", parameters) - self.assertEqual(obs.name, "Validate") - self.assertEqual(obs.description, "Test creating a validate command") + self.assertEqual(validate.name, "Validate") + self.assertEqual( + validate.description, "Test creating a validate command") exp_required = { 'template': ('prep_template', [None]), 'analysis': ('analysis', [None]), 'files': ('string', [None]), 'artifact_type': ('string', [None])} - self.assertEqual(obs.required_parameters, exp_required) + self.assertEqual(validate.required_parameters, exp_required) exp_optional = {'name': ['string', 'dflt_name'], 'provenance': ['string', None]} - self.assertEqual(obs.optional_parameters, exp_optional) - self.assertFalse(obs.analysis_only) - self.assertEqual(obs.naming_order, []) - self.assertEqual(obs.merging_scheme, + self.assertEqual(validate.optional_parameters, exp_optional) + self.assertFalse(validate.analysis_only) + self.assertEqual(validate.naming_order, []) + self.assertEqual(validate.merging_scheme, {'parameters': [], 'outputs': [], 'ignore_parent_command': False}) @@ -426,6 +431,32 @@ def test_create(self): 'ignore_parent_command': False} self.assertEqual(obs.merging_scheme, exp) + # now that we are done with the regular creation testing we can create + # a new command with the name of an old deprecated command and make + # sure that is not deprecated now + # 1. let's find the previous command and make sure is deprecated + cmd_name = 'Split libraries FASTQ' + old_cmd = [cmd for cmd in self.software.commands + if cmd.name == cmd_name][0] + self.assertFalse(old_cmd.active) + + # 2. let's create a new command with the same name and check that now + # the old and the new are active. Remember the new command is going + # to be created in a new software that has a Validate command which + # is an 'artifact definition', so this will allow us to test that + # a previous Validate command is not active + new_cmd = qdb.software.Command.create( + software, cmd_name, cmd_name, parameters, outputs=outputs) + self.assertEqual(old_cmd.name, new_cmd.name) + self.assertTrue(old_cmd.active) + self.assertTrue(new_cmd.active) + # find an old Validate command + old_validate = [c for c in qdb.software.Software.from_name_and_version( + 'BIOM type', '2.1.4 - Qiime2').commands if c.name == 'Validate'][0] + self.assertEqual(old_validate.name, validate.name) + self.assertTrue(validate.active) + self.assertFalse(old_validate.active) + def test_activate(self): qdb.software.Software.deactivate_all() tester = qdb.software.Command(1) @@ -478,10 +509,8 @@ def test_iter(self): '-q qiita -l nodes=1:ppn=5 -l pmem=8gb -l walltime=168:00:00') # delete allocations to test errors - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "DELETE FROM qiita.processing_job_resource_allocation") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "DELETE FROM qiita.processing_job_resource_allocation") with self.assertRaisesRegex(ValueError, "Could not match 'Split " "libraries' to a resource allocation!"): diff --git a/qiita_db/test/test_study.py b/qiita_db/test/test_study.py index 5a3cfe54b..6c9f3b206 100644 --- a/qiita_db/test/test_study.py +++ b/qiita_db/test/test_study.py @@ -204,10 +204,8 @@ def _change_processed_data_status(self, new_status): # Change the status of the studies by changing the status of their # artifacts id_status = qdb.util.convert_to_id(new_status, 'visibility') - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE qiita.artifact SET visibility_id = %s", (id_status,)) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE qiita.artifact SET visibility_id = %s", (id_status,)) def test_get_info(self): # Test get all info for single study @@ -333,9 +331,8 @@ def test_public_raw_download(self): def test_share(self): # Clear all sharing associations self._change_processed_data_status('sandbox') - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add("delete from qiita.study_users") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "delete from qiita.study_users") self.assertEqual(self.study.shared_with, []) # Try to share with the owner, which should not work diff --git a/qiita_db/test/test_user.py b/qiita_db/test/test_user.py index dc40a3d9b..c9932698d 100644 --- a/qiita_db/test/test_user.py +++ b/qiita_db/test/test_user.py @@ -295,9 +295,7 @@ def test_verify_code(self): user_verify_code='verifycode', pass_reset_code='resetcode' WHERE email=%s""" - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add(sql, [email]) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction(sql, [email]) self.assertFalse( qdb.user.User.verify_code(email, 'wrongcode', 'create')) diff --git a/qiita_db/test/test_util.py b/qiita_db/test/test_util.py index b86c9557e..27a3c9b52 100644 --- a/qiita_db/test/test_util.py +++ b/qiita_db/test/test_util.py @@ -458,19 +458,15 @@ def test_get_mountpoint(self): # inserting new ones so we can test that it retrieves these and # doesn't alter other ones - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE qiita.data_directory SET active=false WHERE " - "data_directory_id=1") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE qiita.data_directory SET active=false WHERE " + "data_directory_id=1") count = qdb.util.get_count('qiita.data_directory') sql = """INSERT INTO qiita.data_directory (data_type, mountpoint, subdirectory, active) VALUES ('analysis', 'analysis_tmp', true, true), ('raw_data', 'raw_data_tmp', true, false)""" - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add(sql) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction(sql) # this should have been updated exp = [(count + 1, join(qdb.util.get_db_files_base_dir(), @@ -518,19 +514,15 @@ def test_get_mountpoint_path_by_id(self): # inserting new ones so we can test that it retrieves these and # doesn't alter other ones - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add( - "UPDATE qiita.data_directory SET active=false WHERE " - "data_directory_id=1") - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction( + "UPDATE qiita.data_directory SET active=false WHERE " + "data_directory_id=1") count = qdb.util.get_count('qiita.data_directory') sql = """INSERT INTO qiita.data_directory (data_type, mountpoint, subdirectory, active) VALUES ('analysis', 'analysis_tmp', true, true), ('raw_data', 'raw_data_tmp', true, false)""" - with qdb.sql_connection.TRN: - qdb.sql_connection.TRN.add(sql) - qdb.sql_connection.TRN.execute() + qdb.sql_connection.perform_as_transaction(sql) # this should have been updated exp = join(qdb.util.get_db_files_base_dir(), 'analysis_tmp') @@ -655,12 +647,10 @@ def test_filepath_id_to_rel_path(self): self.files_to_remove.append(fp) test = qdb.util.insert_filepaths( [(fp, "raw_forward_seqs")], 2, "FASTQ")[0] - with qdb.sql_connection.TRN: - sql = """INSERT INTO qiita.artifact_filepath - (artifact_id, filepath_id) - VALUES (%s, %s)""" - qdb.sql_connection.TRN.add(sql, [2, test]) - qdb.sql_connection.TRN.execute() + sql = """INSERT INTO qiita.artifact_filepath + (artifact_id, filepath_id) + VALUES (%s, %s)""" + qdb.sql_connection.perform_as_transaction(sql, [2, test]) obs = qdb.util.filepath_id_to_rel_path(test) exp = 'FASTQ/2/%s' % basename(fp) @@ -674,12 +664,10 @@ def test_filepath_ids_to_rel_paths(self): self.files_to_remove.append(fp) test = qdb.util.insert_filepaths( [(fp, "raw_forward_seqs")], 2, "FASTQ")[0] - with qdb.sql_connection.TRN: - sql = """INSERT INTO qiita.artifact_filepath - (artifact_id, filepath_id) - VALUES (%s, %s)""" - qdb.sql_connection.TRN.add(sql, [2, test]) - qdb.sql_connection.TRN.execute() + sql = """INSERT INTO qiita.artifact_filepath + (artifact_id, filepath_id) + VALUES (%s, %s)""" + qdb.sql_connection.perform_as_transaction(sql, [2, test]) obs = qdb.util.filepath_ids_to_rel_paths([1, 3, test]) exp = {1: 'raw_data/1_s_G1_L001_sequences.fastq.gz', diff --git a/qiita_db/user.py b/qiita_db/user.py index 557941240..60e7a5333 100644 --- a/qiita_db/user.py +++ b/qiita_db/user.py @@ -551,13 +551,11 @@ def change_password(self, oldpass, newpass): def generate_reset_code(self): """Generates a password reset code for user""" - with qdb.sql_connection.TRN: - reset_code = qdb.util.create_rand_string(20, punct=False) - sql = """UPDATE qiita.{0} - SET pass_reset_code = %s, pass_reset_timestamp = NOW() - WHERE email = %s""".format(self._table) - qdb.sql_connection.TRN.add(sql, [reset_code, self._id]) - qdb.sql_connection.TRN.execute() + reset_code = qdb.util.create_rand_string(20, punct=False) + sql = """UPDATE qiita.{0} + SET pass_reset_code = %s, pass_reset_timestamp = NOW() + WHERE email = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction(sql, [reset_code, self._id]) def change_forgot_password(self, code, newpass): """Changes the password if the code is valid @@ -581,16 +579,14 @@ def change_forgot_password(self, code, newpass): return False def _change_pass(self, newpass): - with qdb.sql_connection.TRN: - if not validate_password(newpass): - raise IncorrectPasswordError("Bad password given!") - - sql = """UPDATE qiita.{0} - SET password=%s, pass_reset_code = NULL - WHERE email = %s""".format(self._table) - qdb.sql_connection.TRN.add( - sql, [qdb.util.hash_password(newpass), self._id]) - qdb.sql_connection.TRN.execute() + if not validate_password(newpass): + raise IncorrectPasswordError("Bad password given!") + + sql = """UPDATE qiita.{0} + SET password=%s, pass_reset_code = NULL + WHERE email = %s""".format(self._table) + qdb.sql_connection.perform_as_transaction( + sql, [qdb.util.hash_password(newpass), self._id]) def messages(self, count=None): """Return messages in user's queue diff --git a/qiita_pet/__init__.py b/qiita_pet/__init__.py index 854abc53a..a86cb7731 100644 --- a/qiita_pet/__init__.py +++ b/qiita_pet/__init__.py @@ -6,4 +6,4 @@ # The full license is in the file LICENSE, distributed with this software. # ----------------------------------------------------------------------------- -__version__ = "052020" +__version__ = "092020" diff --git a/qiita_pet/handlers/api_proxy/__init__.py b/qiita_pet/handlers/api_proxy/__init__.py index 472e7b342..58d4ca7f9 100644 --- a/qiita_pet/handlers/api_proxy/__init__.py +++ b/qiita_pet/handlers/api_proxy/__init__.py @@ -38,7 +38,7 @@ from .user import (user_jobs_get_req) from .util import check_access, check_fp -__version__ = "052020" +__version__ = "092020" __all__ = ['prep_template_summary_get_req', 'data_types_get_req', 'study_get_req', 'sample_template_filepaths_get_req', diff --git a/qiita_pet/support_files/doc/source/dev/rest.rst b/qiita_pet/support_files/doc/source/dev/rest.rst index 88011e62a..9a80d197b 100755 --- a/qiita_pet/support_files/doc/source/dev/rest.rst +++ b/qiita_pet/support_files/doc/source/dev/rest.rst @@ -43,6 +43,14 @@ the important parts of the values are described in the Parameters column. |PATCH | ``/qiita_db/artifacts//`` | ``op: operation``, ``path: path``, | Retrieves the artifact information | ArtifactHandler | | | | ``value: value`` | | | +--------+-----------------------------------------------------------------------------------+-----------------------------------------+-----------------------------------------------------+----------------------------+ +|POST | ``/qiita_db/artifact/`` | ``user_email: str``, | Injects artifacts to existing prep templates or | APIArtifactHandler | +| | | ``artifact_type: str``, | jobs | | +| | | ``files: JSON of {'filepath_types': | | | +| | | [filepaths]}`` | | | +| | | ``command_artifact_name: str``, | | | +| | | ``job_id: str, optional``, | | | +| | | ``prep_id: int, optional``, | | | ++--------+-----------------------------------------------------------------------------------+-----------------------------------------+-----------------------------------------------------+----------------------------+ |GET | ``/qiita_db/users/`` | | Retrieves the email and name of all the users | UsersListDBHandler | +--------+-----------------------------------------------------------------------------------+-----------------------------------------+-----------------------------------------------------+----------------------------+ |GET | ``/qiita_db/user//data/`` | | Retrieves the user information | UserInfoDBHandlerTests | diff --git a/qiita_pet/support_files/doc/source/downloading.rst b/qiita_pet/support_files/doc/source/downloading.rst index e7b069d4f..cb87bf14b 100644 --- a/qiita_pet/support_files/doc/source/downloading.rst +++ b/qiita_pet/support_files/doc/source/downloading.rst @@ -109,7 +109,7 @@ off the artifact ID and is present in the artifact and metadata filenames. Finding Samples Based On Their Metadata --------------------------------------- -For help on doing complex searches for samples go to :doc:`../redbiom`. Redbiom +For help on doing complex searches for samples go to :doc:`./redbiom`. Redbiom helps users find samples based on their metadata, a specific taxon or feature of interest via a simple Qiita GUI or the command line (more powerful). diff --git a/qiita_pet/support_files/doc/source/index.rst b/qiita_pet/support_files/doc/source/index.rst index 7abb32d79..59d232d6a 100755 --- a/qiita_pet/support_files/doc/source/index.rst +++ b/qiita_pet/support_files/doc/source/index.rst @@ -52,6 +52,12 @@ Looking for information about analyzing your data? Please see the document here: analyzingsamples/index.rst +Interested in how you can access and use public data available on Qiita? Please see the document here: + + .. toctree:: + + reanalysis/reanalysis.rst + Looking for available guides? Please see these documents: .. toctree:: diff --git a/qiita_pet/support_files/doc/source/reanalysis/contexts.jpg b/qiita_pet/support_files/doc/source/reanalysis/contexts.jpg new file mode 100755 index 0000000000000000000000000000000000000000..ab8236f660f540449f3333a35b80ff6f1801902f GIT binary patch literal 78849 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�htS>+T&Kb?C0@eM(YtYP6&R`>8GSAN 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 z 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 aTZh8s-<-{ZtG)~GH+||%(^#?7_WuG9OH~R0 literal 0 HcmV?d00001 diff --git a/qiita_pet/support_files/doc/source/reanalysis/fig.2.R.png b/qiita_pet/support_files/doc/source/reanalysis/fig.2.R.png new file mode 100755 index 0000000000000000000000000000000000000000..6d1803ad6d9678814cea3ed46108921dff26b36a GIT binary patch literal 22482 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 RB&a~U>Qq$Bac(3o|8Ed<7-awe literal 0 HcmV?d00001 diff --git a/qiita_pet/support_files/doc/source/reanalysis/fig.2.python.png b/qiita_pet/support_files/doc/source/reanalysis/fig.2.python.png new file mode 100755 index 0000000000000000000000000000000000000000..b604706bb4abe160e007d3c7e050ec79d80f8dbe GIT binary patch literal 88680 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%0At7xSi~6n)8dG<3 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 literal 0 HcmV?d00001 diff --git a/qiita_pet/support_files/doc/source/reanalysis/reanalysis.rst b/qiita_pet/support_files/doc/source/reanalysis/reanalysis.rst new file mode 100644 index 000000000..76b853563 --- /dev/null +++ b/qiita_pet/support_files/doc/source/reanalysis/reanalysis.rst @@ -0,0 +1,1124 @@ +Introduction to the download and (re)analysis of public data from Qiita +=========================================================================== + +This documentation provides an introduction to accessing and processing public data within the Qiita database for re-analysis. redbiom can be used to identify public data within Qiita for a meta-analysis focused on some particular factor (or factors). The utility of using redbiom to search the database in this way is that it allows the discovery and subsequent use of a potentially wide variety of samples. This may include data from studies with completely different research goals, which one would otherwise have been unlikely to realize could be used. + +To illustrate this utility, the following tutorials provide guidance on how to search for and download data using redbiom (:ref:`Retrieving Public Data`) and how to process data retrieved with redbiom using QIIME 2 to allow (re-)analysis of said data (:ref:`Processing Public Data`). +Furthermore, the third section (the :ref:`Statistical Analysis`) provides guidance on a specific example of how public data may be repurposed, in this case to justify clinical trial or experimental sample size. + +Two datasets are used in this documentation: + +* the American Gut Project (AGP), +* the data used in Casals-Pascual et al 2020 (originally from Halfvarson et al 2017). + +See :ref:`Intro-to-data` for more detail. Both datasets are used in the first section (:ref:`Retrieving Public Data`) while :ref:`Processing Public Data` uses the AGP data and the :ref:`Statistical Analysis` uses the data used in Casals-Pascual et al 2020. + +.. _Retrieving Public Data: + +Retrieving Public Data for Own Analysis +---------------------------------------- + +Introduction +^^^^^^^^^^^^^^^^ + +This tutorial aims to introduce Qiita [1A]_ and redbiom [2A]_ to new users as utilities for downloading public datasets for subsequent analyses of their own. This will be illustrated with two examples. + +Set up +^^^^^^^^ + +This tutorial will start online using `Qiita `__ , for which one requires an account. If you do not, as yet, have a Qiita account you will need to create one (this is very simple, requiring only an email address); navigate to the `Qiita website `__ and use the sign up action box in the top right corner to do so. +Redbiom can be used as a plugin within Qiita, however, the command line version of redbiom has increased functionality. We will therefore be installing redbiom in the command line to use with the second tutorial example, which demonstrates this functionality. Windows requires some additional set-up, please refer to the *Setting up Windows to use QIIME 2* section in the `QIIME2 docs `__. The following set-up is relevant for linux, Mac and the Windows Subsystem for Linux (setup explained in the `QIIME2 docs `__): + +If you have installed anaconda/miniconda then (in the command line) type: + +.. code-block:: bash + + conda install -c conda-forge redbiom + +If you do not have miniconda or anaconda installed you could choose to install miniconda as follows: + +.. code-block:: bash + + wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh + bash Miniconda3-latest-Linux-x86_64.sh + +Restart the terminal to have changes take effect, then create an environment to work in + +.. code-block:: bash + + conda create --name + +Packages for this tutorial can now be installed in the new environment, keeping them separate from any other projects you may have, and ensuring that different dependencies do not clash. + +Alternatively, if you prefer not to install miniconda, redbiom can be installed as follows: + +.. code-block:: bash + + pip install numpy + pip install redbiom + +.. _Intro-to-data: + +Introduction to the example data +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This tutorial will use two different datasets to highlight both the different questions that can be asked with existing, open source data, and the different methods that can be used to do so. + +The analysis of clinical microbiome data, selected for its similarity to the type of samples one plans to collect for one's own study, allows one to produce example data before starting such a study. This data can then be used for informing and justifying clinical trial format or experimental set-up [3A]_. As this requires only a relatively small data set, and the question is of a less exploratory nature (than the second example), it will be possible to carry out the entire process for this first example within Qiita. + +The second example poses a meta-analysis type question about the microbiome which has not yet been fully addressed in the literature: does a person's frequency of exercise affect their microbiome? To answer this type of exploratory meta-analysis type question does not necessarily require a new study, it may be possible to re-purpose publicly available data for the analysis. This exploratory analysis will require a search through the database for any samples with information about a specific meta-data feature - in this case frequency of exercise - this existing data can then be used to answer the novel question. This is a larger study and will require the use of the command line version of redbiom, and coding tools beyond Qiita. + +The following section will explain how to retrieve the data for these examples, beginning with the simpler clinical data example. + +Retrieving Data +^^^^^^^^^^^^^^^^ + +Contexts +""""""""" + +Processing and bioinformatic techniques can cause inherent biases in datasets. Therefore, within Qiita and redbiom processed samples are partitioned into contexts representing these different methods. The protocol used to obtain samples and extract data may cause biases but, within any one context, data is expected to have the same biases and so be comparable. When retrieving data found in a redbiom search a context must be specified so ensuring the retrieved data is comparable. + +Ultimately a context represents a processing pipeline, so if you are unfamiliar with the methods and processes used in such pipelines it may be worth reading this section: + +.. toctree:: + :maxdepth: 1 + + understanding-contexts.rst + +If you already have a decent understanding of sequencing and processing microbial genomics data then please proceed to the next section. + +Commands to retrieve data +"""""""""""""""""""""""""" + +As previously discussed this tutorial will explore two methods by which one can retrieve data from publicly available studies. The simpler method, that is, completing everything within Qiita, will be outlined first, and this will be illustrated with our first example data set. + +Retrieving data using the redbiom plug-in within Qiita +''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +It is possible to search for data and studies directly on Qiita using the redbiom plug-in. This will be demonstrated by finding the data used in Casals-Pascual et al 2020, which cites that the data used was retrieved from a study in Qiita with ID 1629 [3A]_. On the Qiita website select the *Study -> View Study option*, specify metadata in the tab down menu next to the search box and search for 1629 to find the data for this first example. However, in most scenarios, one would not know of a specific study to search for beforehand. In this case, the Redbiom plugin can be used to search by metadata attributes e.g. a search for IBD brings up 7 studies, including Study 1629. Note that next to the search box you can specify metadata, feature or taxon. Selecting the green plus for the study of interest reveals the study data, in the form of Qiita artifacts. All artifacts of one type can then be selected by using *add all*, or specific artifacts can be selected using *per artifact -> add*. These selected artifacts can then be used to create an analysis as will be outlined subsequently. + +When browsing public studies to find appropriate data, more information on any study can be accessed by selecting it; this will open a new page which includes the study abstract and details as well as options to download the study data. All QIIME 2 maps and BIOMs, as well as EBI accession numbers and sample information can be downloaded directly from this main page. Selecting *data types*, and then the type of interest shows a diagram of the processing pipeline, further information, and list of samples within the dataset of that type. The sample information tab includes a list of all the metadata features (e.g. BMI) associated with the samples, and the option to download this metadata. Perusing these features may give a better indication of whether a study can be repurposed for one's own analysis. + +A search using the redbiom plugin within Qiita therefore allows one to either download data for study on another platform or to select artifacts for processing and analysis within Qiita. Once the artifacts have been added select *analysis* from the top bar and, from the drop down menu, select *create from selected samples*. This opens a window where one can view all selected artifacts and exclude blocks of samples or individual samples that are not required/relevant (first select a particular artifact to view these). Note if one chooses multiple studies that only like data can be merged. +Selecting *create analysis* and entering an analysis name (and optional description) will take one to Qiita's graphical interface processing platform. Note that you should should select "*Merge samples with the same name - useful when merging multiple preparation artifacts*" if you want to use the metadata from the studies the samples originated from. + +Other tutorials (e.g. the :ref:`Statistical Analysis`) explain how to process the raw data that you have just selected within Qiita for analysis. After processing raw data with Qiita the artifacts can be downloaded by selecting an artifact and clicking ‘*generate a download link*'. This is also possible for another's analysis as long as it is public. More generally, using wget or curl in the command line, one can use the general notation: *https://qiita.ucsd.edu/public_artifact_download/?artifact_id=artifact-id*, provided the analysis is public. This is also useful in the situation where one wants to use the processed artifacts from a public study (simply click on an artifact in any public study's processing network to view its artifact ID). To fetch specific types of data one can also use specific calls. The following notation can be used to fetch: + +* All raw data: ``https://qiita.ucsd.edu/public_download/?data=raw&study_id=`` +* All BIOMs + mapping files: ``https://qiita.ucsd.edu/public_download/?data=biom&study_id=`` +* Only 16S raw data: ``https://qiita.ucsd.edu/public_download/?data=raw&study_id=&data_type=16S`` +* Only Metagenomic BIOMs + mapping files: ``https://qiita.ucsd.edu/public_download/?data=biom&study_id=&data_type=Metagenomic`` +* Only the sample information file: ``https://qiita.ucsd.edu/public_download/?data=sample_information&study_id=`` +* Only the preparation information file: ``https://qiita.ucsd.edu/public_download/?data=data=prep_information&prep_id=`` + +Where ``/`` should be replaced with the appropriate study-id/prep-id. + +Retrieving data with redbiom in the command line +'''''''''''''''''''''''''''''''''''''''''''''''''' + +While the redbiom plugin for Qiita is useful for simple searches, and when finding data for processing and analysis within Qiita, the command line version of redbiom has increased functionality, and is particularly useful when data will be processed outside of Qiita. While artifacts, or raw study data, found within Qiita can then be downloaded after accessing the study and finding their ID, the command line version of redbiom allows searching and direct download all within the command line. The exercise frequency example will demonstrate how to use the command line version of redbiom. + +**Background information:** [4A]_ + + +redbiom commands follow a specific syntax: ``redbiom [options] command [arguments]``; for example to search for a metadata feature: ``redbiom search metadata ``. The general structure of the search arguments is `` where ``. Typing ``redbiom`` in the terminal will return its syntax and commands if ever in doubt. Similarly typing ``redbiom `` will return the syntax and options of that redbiom command. + +redbiom search has four commands, ``features``, ``metadata``, ``samples`` and ``taxon``. ``samples`` and ``features`` are complementary, ``features`` retrieves samples containing that feature while ``samples`` fetches the features present in the specified sample/s. In redbiom features are either closed reference OTU ids or exact sequences from deblur. In the future features will be expanded to include other unique attributes produced by processing pipelines. Both of these commands require a specified file and so are not as relevant to initial exploratory searches. ``taxon`` will return features associated with a taxon. ``metadata`` is particularly useful for our purposes. It accepts both ‘natural language' (but uses stemming) and python-like grammar (separately or in combination). Some useful symbols include: ``&`` for intersection, ``|`` for union, ``-`` for difference and ``==`` for equal to. ``<``, ``>``, ``=>``, ``=<``, etc. can also be used. Using the option ``--categories`` one can search for metadata categories rather than values using the same syntax. For example, one could type ``redbiom search metadata --categories `` to see the categories which include that keyword, one can then learn more about a specific category with ``summarize metadata-category --category --counter``. + +Querying and fetching sample data using Redbiom requires a specified context (``-context ``). As contexts are relatively long it is useful to specify them beforehand: ``export CTX=`` and then use ``--context $CTX``. Contexts can be viewed by typing ``redbiom summarize contexts``. To view contexts with a particular keyword use ``redbiom summarize contexts | grep ``. The context used will depend on the data one is looking for, if in doubt, one could choose the context with the most samples. In our case we will initially specify CTX as ``Deblur-NA-Illumina-16S-v4-90nt-99d1d8``, as this is appropriate for study 1629. See the section on understanding contexts for a reminder of their function and utility. + +Making a directory to work in at this point (e.g. ``mkdir querying_redbiom; cd querying_redbiom``), will keep all the data retrieved and generated together and tidy. + +**Retrieving data** + +For the first example, as we know the specific study we are interested in using, we could use the syntax ``redbiom search metadata "where qiita_study_id == "`` . To retrieve the data from this study we could pipe the previous command as follows: + +.. code-block:: bash + + redbiom search metadata "where qiita_study_id == 1629" | redbiom fetch samples --context $CTX --output IBD.data.biom + +Note here the use of our context. Alternatively, it is possible to write the contents of ``redbiom search metadata "where qiita_study_id == "`` to a `sample.lst` file, in which case there will be a record of the samples found. + +.. code-block:: bash + + redbiom search metadata "where qiita_study_id == 1629" > IBD.samples.lst + redbiom fetch samples --from IBD.samples.lst --context $CTX --output IBD.data.biom + +To illustrate the full functionality of redbiom we will now proceed to the exercise frequency example. The first step will be to search for studies that log exercise frequency, ``redbiom search metadata "exercise"`` yields 24 results. +Or, using `NCBI `__ to find the human taxa ID we could use ``redbiom search metadata "exercise where host_taxid==9606"`` which also gives 24 results. These results are studies, rather than individual samples (which is what is returned when searching for a specific study). + +When searching with a key word one cannot be sure how it is being used within the metadata, therefore, it is worth examining the categories which are returned by an exercise search: ``redbiom search metadata --categories exercise``. This searches for metadata categories containing exercise, of which there are eight at the time of writing. +``redbiom summarize metadata-category --category --dump`` gives all samples (not studies) in the category, pipe (``|``) this to ``wc -l`` to get the number of samples. For example, there are 161 samples in the category ``total_hours_exercise``. The ``--dump`` option returns all samples while the other option when searching for metadata categories is ``--counter``. THis gives the responses/variables within a category (e.g. for exercise frequency, one such value is *rarely*, another *frequently*) and also counts the number of samples matching to each of these responses. + +We are interested in exercise frequency, and two categories contain this: ``exercise_frequency_unit`` with 1510 samples and ``exercise_frequency`` with 28017 samples (at the time of writing). One can use ``redbiom summarize metadata-category --category exercise_frequency --dump > exercise.list.txt`` to get a list of all the samples and confirm this worked with ``cat exercise.list.txt | wc -l`` which gives 28017 lines. The output is a file with not only contains the sample IDs but also the variable associated with each response; i.e. there are two columns. To use the file to fetch samples the second column must be removed: ``awk ‘{print $1}' exercise.list.txt > exercise.samples.lst``. It is worth noting that these samples start with their study ID, e.g. 10317 (the American Gut Project (AGP) study ID). ``cat exercise.list.txt | grep 10317 | wc -l`` shows that 26027 of the samples are in fact from the AGP. Using the same code with the ``-v`` option for ``grep`` gives the samples from the other studies that logged exercise frequency. + +As AGP has the most samples, we could consider using data only from this study. All the samples from a single study will have been collected and processed with the same protocol, and the measures of exercise frequency standardised, thus comparison will be less affected by biases than if multiple studies were used. First retrieve a list of the samples present in the AGP study: + +.. code-block:: bash + + redbiom search metadata "where qiita_study_id == 10317" | grep -vi “blank” > AGP-samples. + +``grep`` is a selection tool, the option ``-v`` means to exclude any lines containing the specified keyword and the option ``-i`` causes the function to ignore case, in this way we only retrieve correctly ID'd (non blank) samples. This list (AGP-samples) can be used to retrieve sample data. ``redbiom select`` would allow us to further refine the search if required. ``cat AGP-samples | redbiom summarize samples --category sample_type`` gives information on where the samples originate from e.g. one of the sample type categories is stool. +To fetch the sample metadata and data use ``redbiom fetch``: + +.. code-block:: bash + + redbiom fetch sample-metadata --from AGP-samples --context $CTX --output AGP-metadata.tsv --all-columns + redbiom fetch samples --from AGP-samples --context $CTX --output AGP.data.biom + +Note that here the previous context for sample 1629 returns no results. Instead we need a context appropriate to the American Gut Project. AGP used the V4 region of the 16S rDNA gene sequenced by illumina, trimming to 150nt and deblur for binning. ``export CTX=Deblur-Illumina-16S-V4-150nt-780653`` allows the data for the AGP samples in that context to be fetched (repeat the commands above once the new context has been set). + +For a small study ``redbiom summarize AGP-metadata.tsv``, and ``less AGP-metadata.tsv`` could be used to explore the data retrieved, however, for this large data set they give more details than are currently necessary. ``biom summarize-table -i AGP.data.biom | head`` gives some more condensed information about the sample (rather than meta) data, including a summary of counts. + +Note that the AGP data-set is large. If the previous steps were slow, or if later steps are slow, then you could consider using a subset of the data. Replace: + +.. code-block:: bash + + redbiom search metadata "where qiita_study_id == 10317" | grep -vi “blank” > AGP-samples + +with + +.. code-block:: bash + + redbiom search metadata "where qiita_study_id == 10317" | grep -vi “blank” | shuf -n > AGP-samples + +Where shuf shuffles the lines piped to it and randomly selects the number of lines specified. All other commands remain the same but less samples will be analyzed. + +Conclusion +^^^^^^^^^^^^^^^^ + +This tutorial has demonstrated how to retrieve publicly available data with redbiom either through the Qiita plugin or the command line programme. If you are interested in learning how to process the raw data retrieved through the redbiom programme into a form appropriate for analysis please proceed to the :ref:`Processing Public Data` section (below). Alternatively, if you would like to learn how to use the data retrieved through the Qiita redbiom plugin to perform statistical analysis to justify clinical trial size please see the :ref:`Statistical Analysis` for guidance on how to do so. + +Bibliography +^^^^^^^^^^^^^^^^ + +.. [1A] Gonzalez A et al. 2018 Qiita: rapid, web-enabled microbiome meta-analysis. Nat. Methods 15, 796798. (doi:10.1038/s41592-018-0141-9) + +.. [2A] McDonald D, Kaehler B, Gonzalez A, DeReus J, Ackermann G, Marotz C, Huttley G, Knight R. 2019 redbiom: a Rapid Sample Discovery and Feature Characterization System. mSystems 4. (doi:10.1128/mSystems.00215-19) + +.. [3A] Casals-Pascual C, González A, Vázquez-Baeza Y, Song SJ, Jiang L, Knight R. 2020 Microbial Diversity in Clinical Microbiome Studies: Sample Size and Statistical Power Considerations. Gastroenterology 158, 15241528. (doi:10.1053/j.gastro.2019.11.305) + +.. [4A] https://github.com/biocore/redbiom + +------------------------------------------------------ + +.. _Processing Public Data: + +Processing Public Data Retrieved with redbiom +---------------------------------------------- + + +Introduction +^^^^^^^^^^^^^^^^ + +This tutorial proceeds from the :ref:`Retrieving Public Data` section above, and demonstrates how to process the raw AGP data retrieved through the command line version of redbiom so that it can be used for analysis. The general work flow is transferable to any raw data retrieved through the command line version of redbiom. + +We will be using the AGP-samples, AGP-metadata.tsv and AGP.data.biom files retrieved using redbiom in the :ref:`Retrieving Public Data` section (above). As a reminder, AGP-samples contains a list of the samples retrieved by a search with specification "where qiita_study_id == 10317", this was then used to retrieve the biom table for those samples, and their associated metadata. A quick check to ensure that these are correct: + +.. code-block:: bash + + biom summarize-table -i AGP.data.biom | head + +Should give an output something like as follows: + +.. code-block:: bash + + Num samples: 25,180 + Num observations: 1,028,814 + Total count: 524,626,716 + Table density (fraction of non-zero values): 0.000 + + Counts/sample summary: + Min: 2.000 + Max: 499,002.000 + Median: 14,772.500 + Mean: 20,835.056 + + +Note this will be different if you are using a smaller subset of the data (which will speed up this tutorial). In the tutorial this retrieved data will be processed into an appropriate format for analysis using QIIME 2. QIIME 2 can be used in the command line or as an API for python. The command line is simpler to use, while the API allows more customization for complex processing. Note that while QIIME 2 artifacts cannot easily be viewed from either interface, one can use ``qiime tools peek `` to obtain some information on them in the command line or use the QIIME 2 `artifact viewer `__ to view visualization type QIIME 2 artifacts (.qzv files). + +Set up +^^^^^^^^ + +QIIME 2 is the latest version (at the time of writing) of a package necessary for handling the raw data retrieved through redbiom. It is a command line programme, therefore, if you have Windows OS you will need to use WSL2 for this tutorial. For instructions to set up WSL2 please see this the *Setting up Windows* section in the `QIIME 2 docs `__. Instructions for QIIME 2 installation on Linux, Mac and Windows and the latest release of the software can also be found in these `docs `__ . If you have anaconda/miniconda then use the following commands: + + + +Visit the `QIIME 2 documentation `__ and navigate to *Natively installing QIIME 2* to find the link for the latest version of QIIME 2. +Then install as follows: + +* Installation in a new environment: + +.. code-block:: bash + + wget + conda env create -n qiime2 --file .yml + conda activate qiime2 + +*or* + +* Installation in an existing environment: + +.. code-block:: bash + + wget + conda env update --file .yml + +If you do not have miniconda/anaconda then you can install miniconda as follows: + +.. code-block:: bash + + wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh + bash Miniconda3-latest-Linux-x86_64.sh + +Restart the terminal to have changes take effect, then create an environment to work in + +.. code-block:: bash + + conda create --name + +Packages for this project can now be installed in the new environment, keeping them separate from any other projects you may have, and ensuring that different dependencies do not clash. + +Command line workflow +^^^^^^^^^^^^^^^^^^^^^^^^ + +For the command line version of the processing workflow, make sure you have activated the appropriate conda environment (i.e. the one in which you installed QIIME 2). The first step is to convert the files retrieved with redbiom into QIIME 2 format files. Note that we don't need to convert the metadata into a QIIME 2 format, as its .tsv format is an accepted metadata format for QIIME 2. + +.. code-block:: bash + + #Importing biom data, and converting into a QIIME 2 artifact and QIIME 2 visualization: + + qiime tools import --input-path ../AGP.data.biom --type 'FeatureTable[Frequency]' --input-format BIOMV210Format --output-path feature-table-AGP.qza + + qiime feature-table summarize --i-table feature-table-AGP.qza --o-visualization feature-table-AGP.qzv --m-sample-metadata-file ../AGP-metadata.tsv + +Once the data has been imported into a QIIME 2 format, it needs to undergo quality control. Quality control will depend on the study but in this case we will first filter and discard samples which have a total feature count under a threshold of 1000, so ensuring that samples with a low number of reads (little data) are removed. Then further filtering to remove rare features, i.e. ASVs that only appear a few times in the whole dataset, will remove possible outliers. Furthermore, it is also important to only include samples from the same body site (we will use feces as this is where most of the samples originate) and exclude samples that do not have exercise frequency logged (some AGP participants may not have answered this particular question when filling in the questionnaire). Finally, it may also be worth filtering out unhealthy individuals, who may bias the results (if health conditions limit exercise frequency then we may get a spurious result due to the correlation between ill health and low exercise frequency). + +.. code-block:: bash + + #Filter frequency table using metadata and frequency criteria + + #filter out samples with a low number of reads + qiime feature-table filter-samples --i-table feature-table-AGP.qza --p-min-frequency 1000 --o-filtered-table sample-frequency-filtered-table-AGP.qza + + #filter out features (ASVs) with a low frequency of occurrence + qiime feature-table filter-features --i-table sample-frequency-filtered-table-AGP.qza --p-min-frequency 3 --o-filtered-table feature-filtered-table-AGP.qza + + #filter out samples which fall in unwanted metadata categories, or lack the metadata we require + qiime feature-table filter-samples --i-table feature-filtered-table-AGP.qza --m-metadata-file ../AGP-metadata.tsv --p-where "([body_site]='UBERON:feces') AND ([subset_healthy] IN ('true', 'True', 'TRUE')) AND ([exercise_frequency] IN ('Never', 'Rarely (a few times/month)', 'Occasionally (1-2 times/week)', 'Regularly (3-5 times/week)', 'Daily'))" --o-filtered-table filtered-table-AGP.qza + + #visualise the filtered table + qiime feature-table summarize --i-table filtered-table-AGP.qza --o-visualization filtered-table.qzv --m-sample-metadata-file ../AGP-metadata.tsv + +We now have a filtered dataset, but will need to classify our features if we want to use analyses that take into account phylogenetic distance, and for more general taxonomic analysis. Therefore we need to extract sequences from the dataset and ‘insert' them into a reference phylogenetic tree (this placement identifies their taxonomic position). The first step is to extract representative sequences from the data, and these can then be aligned with and inserted in a reference database. +Obtain this reference data, as follows: +In the command terminal in your working directory (e.g. ``~/microbiome/exercise/``) create a directory for references (``mkdir reference``) and then use wget to download the data: + +.. code-block:: bash + + mkdir reference + cd reference + # get the reference we need now + wget https://data.qiime2.org/2020.2/common/sepp-refs-gg-13-8.qza + # other reference files we will need later and may as well get now too + wget https://github.com/BenKaehler/readytowear/raw/master/data/gg_13_8/515f-806r/human-stool.qza + wget https://github.com/BenKaehler/readytowear/raw/master/data/gg_13_8/515f-806r/ref-seqs-v4.qza + wget https://github.com/BenKaehler/readytowear/raw/master/data/gg_13_8/515f-806r/ref-tax.qza + # return to the previous working directory + cd .. + +Once these have downloaded one can proceed with the fragment insertion workflow. + +.. code-block:: bash + + #generate representative sequences + biom summarize-table --observations -i ../AGP.data.biom | tail -n +16 | awk -F ':' '{print ">"$1"\n"$1}' > rep_seqs.fna + +Note that here we have made a fasta file, this is a very common file type for sequence storage where every sequence is preceded by a header line beginning with ``>``. Generally this header line contains information about the sequence such as it's origin (species, gene etc) but as these are as yet unknown we use the sequence itself as an id for the sequence. + +.. code-block:: bash + + #import these sequences into an artifact form + qiime tools import --input-path rep_seqs.fna --output-path rep_seqs.qza --type 'FeatureData[Sequence]' + + #use the representative sequences artifact to create a fragment insertion placement tree + qiime fragment-insertion sepp --i-representative-sequences ./rep_seqs.qza --i-reference-database ./sepp-refs-gg-13-8.qza --o-tree ./insertion-tree.qza --o-placements ./insertion-placements.qza + +Aligning the fragments and creating an insertion tree is computationally costly, and will require at least 12GB ram and possibly several hours. If you are struggling to complete this step consider decreasing the sample size you are using (go back to the data retrieval section, and use the ``shuf -n`` option, then repeat the steps from there). + +One can also train a taxonomic classifier to classify the sequences. The fragment insertion generated a phylogeny, with the sequences inserted appropriately. The taxonomic classifier classifies the ASVs, assigning them to a particular clade (e.g. with good data to specific species) [1B]_. While it is possible to use pre-trained classifiers these tend to give poorer results than those trained on data similar to that of the sample, therefore we will train a classifier using human-stool samples. + +.. code-block:: bash + + #create and train a taxonomic classifier + qiime feature-classifier fit-classifier-naive-bayes --i-reference-reads ../reference/ref-seqs-v4.qza --i-reference-taxonomy ../reference/ref-tax.qza --i-class-weight ../reference/human-stool.qza --o-classifier classifier.qza + + qiime feature-classifier classify-sklearn --i-classifier classifier.qza --i-reads rep_seqs.qza --o-classification taxonomy.qza + +You have now produced all the artifacts necessary for a basic exploratory analyses and could continue from here to analyse e.g. beta diversity and alpha diversity, as well as producing PCA plots. The next section details how to achieve the same result in python, rather than within the command line. + +Python Workflow +^^^^^^^^^^^^^^^^^^^^^^^^ + +This section will demonstrate how to, using python, process data retrieved via redbiom into a form that can be used for further analysis. + +Set up +"""""""" + +As well as QIIME 2 processing the data in python will require pandas (a data analysis and manipulation tool) and some QIIME 2 plugins: + +* ``Feature_table`` allows feature tables to be filtered, merged, transformed, etc [2B]_. +* ``Fragment_insertion`` improves phylogeny creation from sequence fragments by inserting the sequences into an existing high quality reference phylogeny rather than making a de novo phylogeny [3B]_. +* ``Feature_classifier`` for taxonomic classification of QIIME 2 features [4B]_. +* ``Metadata`` provides functionality for working with and visualizing metadata [5B]_. + +These are loaded into your IDE as follows: + +.. code-block:: python + + #Set up + import biom + import qiime as q + import pandas as pd + import sklearn + from qiime2.plugins import feature_table, fragment_insertion, feature_classifier, metadata + +If any of these are not present, install them through conda (search *conda install * in your preferred internet browser for instructions on how to do so for said package - usually such instructions are found on the Anaconda Cloud web-pages). + +Load and process data +""""""""""""""""""""""" + +The first step is to load the files retrieved using redbiom into QIIME 2 artifact type variables, these can then be recognized by QIIME 2 processing commands. + +.. code-block:: python + + #load metadata + meta = q.Metadata.load('/') + + #load sample data (biom table) + sample_data = q.Artifact.import_data(type='FeatureTable[Frequency]',view='/', view_type='BIOMV210Format') + + #visualize the data + vis_data = feature_table.visualizers.summarize(table=sample_data, sample_metadata=meta) + +If you have trouble loading the metadata file then try use the keemie (google sheets) add-on to validate the metadata tsv file. It might also be worth re-fetching the sample, in case it has been corrupted by an incomplete download. The last command creates a feature table plot, like those in Qiita, which can help you decide how to filter the raw data. A feature in QIIME 2 is a unit of observation such as an OTU or ASV, or gene, or taxon. + +You can (and should) save this visualization, and the generated QIIME 2 artifact feature table to your working directory using the following code: + +.. code-block:: python + + sample_data.save("table.qza") + vis_data.visualization.save("feature_table.qzv") + +(It might be tidier to create a results directory, and then save the files to this by specifying the path to this directory in the command above.) + +The next step is to perform quality control on the data: first filtering and discarding samples which have a total feature count under a threshold of 1000, so ensuring that samples with a low number of reads are removed. Further filtering to remove rare features i.e. ASVs that only appear a few times in the whole dataset should also be performed. Furthermore, it is also important to only include samples from the same body site (we will use feces as this is where most of the samples originate) and exclude samples that do not have exercise frequency logged (some participants may not have answered this particular question in the questionnaire). Finally, it may also be worth filtering out unhealthy individuals, who may bias the results (if health conditions limit exercise frequency then we may get a spurious result due to the correlation between ill health and low exercise frequency). + +.. code-block:: python + + # Inclusion criterion + criterion = "[body_site]='UBERON:feces'"\ + " AND [subset_healthy] IN ('true', 'True', 'TRUE')"\ + " AND [exercise_frequency] IN ('Never', 'Rarely (a few times/month)', 'Occasionally (1-2 times/week)', 'Regularly (3-5 times/week)', 'Daily')" + + # Keep only one sample if there are multiple samples from same subject + ids_to_keep = meta.get_column('host_subject_id').to_series().drop_duplicates().index + filtered_meta = meta.filter_ids(ids_to_keep) + + # Thresholds for filtering samples and features + min_feature_per_sample= 1000 + min_per_feature = 3 + + # Filter FeatureTable[Frequency] with feature-table filter-samples method to remove samples with a small library size + sample_filtered_data = feature_table.methods.filter_samples(table=sample_data, min_frequency=min_feature_per_sample, metadata=filtered_meta, where=criterion) + + # Filter FeatureTable[Frequency] with feature-table filter-features method to remove very rare features + feature_filtered_data = feature_table.methods.filter_features(table=filtered_data.filtered_table, min_frequency=min_per_feature) + + # Visualize the filtered table + vis_filtered_data = feature_table.visualizers.summarize(table=filtered_data.filtered_table, sample_metadata=filtered_meta) + + +To save these to the results directory made in your working directory use the code below. By viewing the feature filtered with the QIIME 2 metadata plugin we can also extract the ids of those samples which have met all filtering criteria for future reference. The metadata format is converted to a dataframe, from which the indexes are extracted and each pasted on a new line to give a variable with the sample ids. These are then written to a file saved in the results directory - you can check this file in the command line with ``cat ./results/filtered.ids | head`` (from your working directory). + +.. code-block:: python + + # save the filtered feature table and visualisations + sample_filtered_data.filtered_table.save('./results/sample-filtered-table.qza') + vis_sample_filtered.visualization.save('./results/sample-filtered-table.qzv') + feature_filtered_data.filtered_table.save('./results/feature-filtered-table.qza') + vis_feature_filtered.visualization.save('./results/feature-filtered-table.qzv') + + # for future reference save the ids of the samples that met filtering criteria + filtered_table = feature_filtered_data.filtered_table.view(q.Metadata) + filtered_ids = "\n".join(filtered_table.to_dataframe().index) + "\n" + with open('./results/filtered.ids', 'w') as f: + f.write(filtered_ids) + +You have now obtained a filtered dataset, but will need to classify the features if you want to use analyses that take into account phylogenetic distance. Therefore we need to extract sequences from the dataset and ‘insert' them into a reference phylogenetic tree (this placement identifies their taxonomic position). To extract representative sequences from the features we will use the ``feature_filtered_data`` (a frequency feature table) to make a fasta file (a universal DNA/protein sequence file format) of sequence feature data. You can view this file with ``less `` or ``cat | head``, as it is a plain text file. Often such files have information about the origin of the sequences (on the > line before the sequence), but we will use the sequence itself as an ID as the taxonomic data is currently unknown. Fragment insertion, mapping representative sequences from the samples to a reference database will allow taxonomic classification of the ASVs. First extract representative sequences from the data: + +.. code-block:: python + + with open('./results/sequences.fna', 'w') as f: + for seq in feature_filtered_data.filtered_table.view(pd.DataFrame).columns: + f.write('>%s\n%s\n' % (seq, seq)) + + # import the fasta file as a FeatureData[Sequence] artifact + sequences = q.Artifact.import_data(type='FeatureData[Sequence]', view='./results/sequences.fna') + + +The first line here creates a writeable output file and assigns it to a variable. ``seqs = ‘'`` creates an empty string that is then filled in the following for loop. The for loop uses two variables ``i`` and ``seq`` representing the index and a column from the ``feature_filtered_data`` represented as a panda DataFrame. Each loop therefore writes a line with > and then the contents of the next column to seqs. Seqs is then written to the output file.We don't necessarily know how many lines have been added to seqs but can specify to write out the slice from the first to the last index using [:-1] (or [0:-1]). + +Again, we can visualize this data and save it: + +.. code-block:: python + + # visualize artifact and save both visualization and artifact + vis_sequences = feature_table.visualizers.tabulate_seqs(data=sequences) + sequences.save('./results/sequences.qza') + vis_sequences.visualization.save('./results/sequences.qzv') + +We can now create a tree to insert the fragments into. For this we will need reference data, this can be downloaded in the command terminal. In your working directory create a directory for references (``mkdir reference``) and then use wget to download the data: + +.. code-block:: bash + + mkdir reference + cd reference + # get the reference we need now + wget https://data.qiime2.org/2020.2/common/sepp-refs-gg-13-8.qza + # other reference files we will need later and may as well get now too + wget https://github.com/BenKaehler/readytowear/raw/master/data/gg_13_8/515f-806r/human-stool.qza + wget https://github.com/BenKaehler/readytowear/raw/master/data/gg_13_8/515f-806r/ref-seqs-v4.qza + wget https://github.com/BenKaehler/readytowear/raw/master/data/gg_13_8/515f-806r/ref-tax.qza + cd .. # return to the directory we have been working in + + +When the data is downloaded the sepp reference data can be loaded into your python IDE and the sample fragments inserted into the sepp tree. + +.. code-block:: python + + ### Fragment insertion + # Load the reference data and insert sequences into sepp tree + sepp_ref = q.Artifact.load('./reference/sepp-refs-gg-13-8.qza') + sepp_result = fragment_insertion.methods.sepp(representative_sequences=sequences, + reference_database=sepp_ref, + threads=8, + debug=True) + + +Once the sequences have been placed save the tree and placements as with the same save function we have been using throughout this section: +This last command is computationally costly (requires at least 12GB ram), and will take a while. If you are having trouble consider using a subset of the entire AGP dataset - you do not need to change your script, simply copy it into a new directory, repeat the redbiom data retrieval steps with the same names for the output files but with the ``shuf -n `` command piped into the initial sample ID retrieval command, and then run your script again in this new directory. Another possible solution is to lower the number of threads, though the process will take longer. + +We can also train a taxonomic classifier to classify the sequences. The fragment insertion generated a phylogeny, with the sequences inserted appropriately. The taxonomic classifier classifies the ASVs, assigning them to a particular clade (e.g., with good data, to specific species) [1B]_. While it is possible to use pre-trained classifiers these tend to give poorer results than those trained on data similar to that of the sample, therefore we will train a classifier using human-stool samples. First we load the other references and the representative sequence: + +.. code-block:: python + + # Load the representative sequences + rep_seqs = qiime2.Artifact.import_data(type='FeatureData[Sequence]', view='./sequences.fna`) + + # Load the Greengenes sequences and taxonomy and Clawback human stool weights + human_stool_weights = q.Artifact.load('./reference/human-stool.qza') + ref_seqs_v4 = q.Artifact.load('./reference/ref-seqs-v4.qza') + ref_tax = q.Artifact.load('./reference/ref-tax.qza') + +We can then generate a classifier and classify the sequences: + +.. code-block:: python + + # Generate a classifier with the loaded reference data + human_stool_v4_result = feature_classifier.methods.fit_classifier_naive_bayes(reference_reads=ref_seqs_v4, reference_taxonomy=ref_tax, class_weight=human_stool_weights) + + # Use classifier to classify sequences + bespoke_taxonomy = feature_classifier.methods.classify_sklearn(reads=rep_seqs, classifier=human_stool_v4_result.classifier, n_jobs=-1) + + + +The classifier training will give a warning +"`The TaxonomicClassifier artifact that results from this method was trained using scikit-learn version 0.23.1. It cannot be used with other versions of scikit-learn.`" +You can check your version of scikit-learn by typing the following in your python console: + +.. code-block:: python + + import sklearn + print('The scikit-learn version is {}.'.format(sklearn.__version__)) + +If you have the correct version, ignore the warning. If not, update to the correct version using conda. + +The classifier and the classifications should be saved. + +.. code-block:: python + + human_stool_v4_result.classifier.save('./results/gg138-v4-human-stool_classifier.qza') + bespoke_taxonomy.classification.save('./results/bespoke-taxonomy.qza') + +We can also visualize this classification as a table: + +.. code-block:: python + + taxonomy_vis = metadata.visualizers.tabulate(bespoke_taxonomy.classification.view(q.Metadata)) + taxonomy_vis.visualization.save('./results/bespoke-taxonomy.qzv') + +With the data processed it is now possible to begin analysis. We have generated a feature table, representative sequences, an insertion tree and taxonomic classification and these will be sufficient for most simple exploratory analyses. + +Conclusion +^^^^^^^^^^^^^^^^ + +This tutorial has demonstrated how to process raw data retrieved through redbiom, using QIIME 2, either directly in the command line or through the python API. The processed data can now be analysed e.g. by calculating alpha and beta diversity metrics. To learn how to analyse the data visit the `QIIME 2 docs `__ and select an appropriate tutorial e.g. the Moving Pictures tutorial (skip to the Alpha and Beta Diversity Analysis section). + +Bibliography +^^^^^^^^^^^^^^^^ + +.. [1B] Bokulich NA, Kaehler BD, Rideout JR, Dillon M, Bolyen E, Knight R, Huttley GA, Gregory Caporaso J. 2018 Optimizing taxonomic classification of marker-gene amplicon sequences with QIIME 2's q2-feature-classifier plugin. Microbiome 6, 90. (doi:10.1186/s40168-018-0470-z) + +.. [2B] QIIME 2 2020.6.0 documentation. See https://docs.qiime2.org/2020.6/plugins/available/feature-table/ + +.. [3B] Janssen S et al. 2018 Phylogenetic Placement of Exact Amplicon Sequences Improves Associations with Clinical Information. mSystems 3, e00021-18 + +.. [4B] Bokulich NA, Kaehler BD, Rideout JR, Dillon M, Bolyen E, Knight R, Huttley GA, Gregory Caporaso J. 2018 Optimizing taxonomic classification of marker-gene amplicon sequences with QIIME 2's q2-feature-classifier plugin. Microbiome 6, 90. (doi:10.1186/s40168-018-0470-z) + +.. [5B] QIIME 2 2020.6.0 documentation. See https://docs.qiime2.org/2020.6/plugins/available/metadata/ + +------------------------------------------------------------------------------ + +.. _Statistical Analysis: + +Statistical Analysis to Justify Clinical Trial Sample Size Tutorial +------------------------------------------------------------------- + +The goal of this tutorial is to demonstrate how to analyse public data similar to that one may obtain from one's own proposed study; and use this to find the minimum sample size needed for appropriate/sufficient statistical power. This will allow relevant conclusions to be drawn for the minimum clinical trial size in one's actual (own) study. The information obtained using this public data will therefore allow justification of the clinical trial format, and strengthen e.g. grant applications. + +This tutorial is based on Casals-Pascual et al 2020 and will be analysing the same data, to reproduce the figures and statistics found in the paper [1]_ . The tutorial continues on from the :ref:`Retrieving Public Data` section and expects that you can find the example data from study 1629, using the Qiita redbiom plugin. + +To reproduce the figures and results in Casals-Pascual et al 2020 we first need to process the raw data from study 1629 to obtain an Alpha_diversity artifact and a Beta_diverstiy artifact for the data. This stage of the tutorial will be completed within the Qiita processing interface, though note that it could be completed in QIIME 2 instead. We will also need the Metadata artifact from the original study. The second half of the process, producing the figures can then be completed using either python or R. + +Set up +^^^^^^^^^^^^^^^^ + +Please follow the instructions in the :ref:`Retrieving Public Data` section for the first example to find the data required for this tutorial. + +For later analysis you will require either a python script editor or R studio. +Python scripts can be written directly in the command line editor vi but if you are a beginner this is not very user friendly, and I would recommend installing spyder (``conda install spyder``, presuming you have `miniconda `__ ) which can then be launched from the command line by typing ``spyder``. +R-studio can be downloaded via the command line using conda if you have miniconda/anaconda. It can also be downloaded and function independently of the command line (note you need to install both R and R-studio in this case). There are many tutorials for this online e.g. `here `__ or `here `__ . + +Find and process data in Qiita +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Once you have selected the study 1629 (see :ref:`Retrieving Public Data` above) there are four artifacts, these are: + +#. *Pick closed-reference OTUs (reference-seq: /databases/gg/13_8/rep_set/97_otus.fasta) | Split libraries FASTQ*. + * This tells us that the data is picked OTUs clustered by closed reference against /databases/gg/13_8/rep_set/97_otus.fasta and is now in a split library FASTQ format. + * FASTQ stores both sequence and corresponding quality score see `here `__ for more information (though note the data in FASTQ format does not have to be illumina sequencing data). + * Split refers to demultiplexing where sequences from the same lane are split into samples based on barcodes. N.B. illumina can sequence multiple different samples at the same time, therefore sequence data has to be demultiplexed into the separate samples present in the same lane. +#. *Pick closed-reference OTUs (reference-seq: /databases/gg/13_8/rep_set/97_otus.fasta) | Trimming (length: 90)* + * This is essentially the same as the previous artifact but the reads have been trimmed to 90nt (see the explanation of contexts for an explanation of why this is done). +#. *Deblur (Reference phylogeny for SEPP: Greengenes_13.8, BIOM: /projects/qiita_data/BIOM/60941/reference-hit.biom) | Trimming (length: 90)* + * Deblur processed sequence data trimmed to 90nt and classified by taxonomy using the greengenes reference database. This artifact contains only those sequences which have been classified thus reference-**hit**.biom + * SEPP is a phylogenetic placement program that can be used to place query sequences (reads e.g. of the V4 region of 16S) into the phylogeny of the full length gene's tree (in this case using the Greengenes database). +#. *Deblur (Reference phylogeny for SEPP: Greengenes_13.8, BIOM: /projects/qiita_data/BIOM/60942/all.biom) | Trimming (length: 90)* + * This artifact been processed in the same manner as the previous artifact, but all ASVs are present, including those that did not get placed (therefore **all**.biom). + +For the Deblur data we will use the reference-hit.biom data as this represents those ASVs which were placed within the Greengenes database. Using the all.biom data would give all ASVs, but the unplaced sequences would have to be removed to allow later analysis with Unifrac (so that they may as well not be present) and therefore we select the reference-hit data from the start. N.B. unifrac uses phylogenetic distance (measures of relatedness), thus the need for placed sequences. +For the OTUs, the trimmed sequences are appropriate, as they represent a later step in the processing pipeline of the raw data. + +With these two artifacts selected proceed to *create analysis*. Both samples will need to be rarefied and then have alpha and beta diversity artifacts created. For a general overview of processing data in the Qiita processing interface see the appropriate section of these `Qiita docs `__ . To rarefy the data select the artifact -> *process* -> *rarefy*, modify the options of rarefy so that total frequency is a 10000 for both -> *add command* -> *run*. +The cut off frequency is an individual choice, but the use of 10 000 strikes a compromise between losing data from samples with large library sizes and discarding samples with smaller library size. One can look at the frequency tables of the biom artifacts to get an idea of what would be an appropriate cut off. In this case 10 000 will allow most samples to be used, while maintaining quality. Once rarefaction has completed the `rarefied_table` artifact can be used for alpha and beta diversity calculations. Select the `rarefied_table` artifact, *process* -> *alpha diversity (phylogenetic) [alpha_phylogenetic]* and in options use the default option of Faith's index then *add command* -> *run*. Beta Diversity can be calculated with *Beta Diversity (phylogenetic)* (this uses Unifrac). For the OTU artifact one can specify the phylogenetic tree from the database (as closed OTUs inherently have taxonomy data). For the Deblur artifact use the ‘artifact tree, if exists' option. The artifact we are using has been aligned to a reference database, but not all deblur data will necessarily have associated taxonomy data. +The distance matrix produced by the Beta Diversity process will allow us to run a principal coordinate analysis, while this is not necessary for reproducing the plots, it allows one to visualise the data and so get an intuitive idea of what it represents. + +Retrieve artifacts/data from Qiita and create figures +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To reproduce the plots in the paper we need to produce two figures (three plots). The first shows sample size against power (1 - P(type II error)) which is used to find statistically significant differences in alpha diversity. This allows one to calculate the standard sample size required to detect an effect between a group and the control population. This sample size will be affected by the effect size, so we need to plot power for at least three different effect sizes. Casals-Pascual et al 2020. use 0.55, 0.82, 1.00 because these represent a difference in Faith's PD (a measure of phylogenetic distance) of 2, 3, and 4. The group being used to calculate alpha diversity is B1. +The second figure includes two plots: the first plots sample size against power (1 - P(type II error)) to find statistically significant differences in Beta diversity (in this case pairwise distances between the two groups). Again, multiple scenarios are used, in this case significance levels of 0.001, 0.01, 0.05 and 0.1. The second is a histogram showing the distribution of pairwise distances within and between the two sample groups. The groups are B1 and B2/3 (i.e. B1 samples are compared to all other samples). + +Download data from Qiita +"""""""""""""""""""""""""" + +This can be done in the command line using wget and the links from your Qiita study. Select an artifact followed by ‘generate download link' if your study is private. If your study is public one can simply use the artifact ID as described in the Retrieving Public Data for Own Analysis Tutorial (under redbiom). Use the -O option to specify the output (downloaded) file's name. We also need the study metadata, this can be retrieved from the study page, under sample information, copy the link address of the sample info download button, or use the study ID as below. + +.. code-block:: bash + + wget -O alpha_div_artifact.zip “” + wget -O beta_div_artifact.zip "" + wget -O metadata.zip “” + +To have this run ‘quietly' (without showing any output) add the -q option. However, note that running in quiet mode might lead to missed error messages. Certain errors, suggesting that the zipfile is corrupt, can be `ignored `__ . +When the files have been downloaded unzip them with ``unzip ``. + +If you did not merge samples when creating your analysis the sample IDs in the beta and alpha diversity artifacts may not match those of the metadata, as they will have your rarefied artifact ID appended to the sample ID. To make the sample IDs match, the simplest fix is to change the metadata file as it is an easily manipulatable .txt file. The code below will append your rarified table ID to the metadata IDs + +.. code-block:: bash + + cat ./templates/ | sed “s/^1629/.1629/g” > ./templates/metadata.txt + +Check this has worked with ``cat templates/metadata.txt | less``. + +Python workflow +^^^^^^^^^^^^^^^^ + +This section works through the `code `__ accompanying the aforementioned paper. Alternatively, you can skip this section and use R studio for the same end result figures. + +Set up environment +""""""""""""""""""" + +There are various modules required to complete this analysis in python. + +* ``qiime2``: a bioinformatics platform for next generation microbiome data. +* ``pandas``: a data analysis and manipulation tool. +* ``Seaborn``: a data visualization library based on matplotlib which facilitates drawing statistical graphics. +* ``Matplotlib.pyplot``: a matplotlib interface (allows plotting in a manner similar to that in MATLAB which is a programming language). +* ``skbio/scikit-bio``: a python package which is used by QIIME 2 (i.e. a dependency), from which the DistanceMatrix function is required. +* ``statistics``: a python package for functions such as mean and stdev +* From ``statsmodels.stats.power`` the ``tt_ind_solve_power`` function is required - this is a function that allows calculation of the power of a two sample t-test given relevant data. + +It is likely that these packages will already be present if you are using conda and have installed QIIME 2. If any are missing do an internet search for the package name + conda; one of the top hits will be from the anaconda cloud, and give instructions for installing the package. Alternatively, you can use ``conda search `` within the command line. + +Open your preferred python IDE or script editor, and make a new script. To set-up the environment use: + +.. code-block:: python + + import pandas as pd + import qiime2 as q2 + import seaborn as sns + import matplotlib.pyplot as plt + + from statsmodels.stats.power import tt_ind_solve_power + from statistics import mean, stdev + from skbio import DistanceMatrix + +Process the artifact data +"""""""""""""""""""""""""""""""""""" + +**Metadata** + +The metadata file unpacks to a folder template, with one file 1629_20180101-113841.txt. If you have used the earlier command to append an artifact ID to the sample ID this name may be different. To assign the metadata to a variable use: + +.. code-block:: python + + metadata = pd.read_csv('./templates/', sep='\\t', dtype=str, index_col=0, engine='python') + + +This code assigns the metadata information to the variable metadata, using the pandas ``read_csv function``, the ``sep =`` sets the separator of the data columns, ``index_col`` specifies the column to use as the index, ``dtype`` specifies the data type for the columns, and ``engine`` specifies the parser. The variable metadata now consists of 38 columns specifying the metadata details of the 683 patients. + +Next, using QIIME 2, the alpha_diversity artifact can be be added to the metadata variable in a new column (deblur alpha diversity): + +.. code-block:: python + + metadata['deblur alpha diversity'] = q2.Artifact.load('./alpha_vector//alpha_diversity.qza').view(pd.Series) + metadata.dropna(subset=['deblur alpha diversity'], inplace=True) + +The ``view(pd.Series)`` is used to view the artifact (loaded by QIIME 2) in panda series format - in this format the data can be appended to the metadata variable. A panda series is an array that can be made from data input such as csv files and existing storage. The last line of code drops those rows with NA (not applicable) values (i.e. missing values) in the deblur alpha diversity column from the data frame. Inplace specifies editing of the object in place rather than returning the output as a new dataframe. + +When working through someone else's code it is often a good aid to understanding to print various variables along the way, this gives a better idea of what is happening, and will flag any possible errors. E.g. at this stage try + +.. code-block:: python + + print(metadata[metadata ['deblur alpha diversity']]) + +Next we can divide the data into groups: + +.. code-block:: python + + b1 = metadata[metadata.cd_behavior == 'Non-stricturing, non-penetrating (B1)'] + bother = metadata[(metadata.cd_behavior != 'Non-stricturing, non-penetrating (B1)') & (metadata.cd_behavior != 'not applicable')] + + dtx = q2.Artifact.load('').view(DistanceMatrix) + + b1_dtx = dtx.filter(ids=b1.index).to_series().values + bother_dtx = dtx.filter(ids=bother.index).to_series().values + +This code makes a variable representing the b1 group. This variable (``b1``) contains all rows in the metadata object which have cd_behaviour equal to the B1 phenotype (Non-structuring, non-penetrating (B1). ``b1_dtx`` contains all the values in the distance matrix after filtering for b1. To do this required loading the distance matrix data into a variable using q2.Artifact.load. We also create variables containing all other non-B1 and present (not NA) data from the metadata and dtx variables. + +**Alpha diversity data** + +Now we have processed the data into a python readable format we can calculate variables such as the standard deviation and the mean: + +.. code-block:: python + + sd1 = b1['deblur alpha diversity'].std() + sd2 = bother['deblur alpha diversity'].std() + sd12 = mean([sd1, sd2]) + +Again, print these to see if they look as expected, or, if you are using an appropriate IDE (such as spyder), you can look at their values and type in the inbuilt variable explorer. Next we will make a data frame containing the data for the first plot + +.. code-block:: python + + # significance level + alpha = 0.05 + + #create empty list + data_alpha = [] + + #in steps of 5 from 10 to 55 + for observations in range(10, 155, 5): + #for differences in Faiths PD representative of effect sizes 0.55, 0.82, 1.00 + for difference in [2, 3, 4]: + #effect size calculation + effect_size = difference/sd12 + x = tt_ind_solve_power(effect_size=effect_size, + #number of observations, iterated by the loop + nobs1=observations, + #significance level + alpha=alpha, + #number of observations for second group presumed to be equal to first group's observations + ratio=1.0, + alternative='two-sided') + data_alpha.append({ + #append parameters and output to list + 'alpha': alpha, 'Power (1-β)': x, + 'Total sample size (N)': observations * 2, + 'Difference': '%d (effect size %0.2f)' % (difference, effect_size)}) + + #turn the list created in the loop into dataframe + data_alpha = pd.DataFrame(data_alpha) + + +``tt_ind_solve_power`` solves for any one parameter of a two sample t-test. In this case we are using it to find power given all data. It requires effect_size, nobs1, alpha, power and ratio; where exactly one needs to be None (and is calculated), while all others need numeric values. + +* ``Effect_size`` is the standardized effect size, the difference between the two means divided by the standard deviation. +* ``Nobs1`` is the number of observations of sample 1 (which we generate with a loop, in steps of 5 from 10 to 55). +* ``Ratio`` is used to specify the ratio between the number of observations of group one and two; so that ``nobs2 = nobs1 * ratio``. +* ``Alpha`` is the significance level - that is the probability of a type I error; that is the probability of finding a significant effect when the null hypothesis is actually true. +* ``Power`` - is what we want to calculate, it is (1 - the probability of a type II error). A type II error is falsely finding a non-significant effect and accepting the null hypothesis (when there is in fact a significant effect). + +Our extra parameter, alternative, ensures that the power is calculated for a two-tailed t-test (this is default in anycase). +The outcome of this code is therefore to calculate the power for a given alpha and difference over a range of sample sizes (represented by observation), and then append all parameters appropriately to a list which is then processed to form a data-frame which we can use as input for plotting. + +**Beta diversity data** + +The process for obtaining the points to plot for beta diversity is similar to that for alpha diversity but now we are considering two groups, and therefore the difference between them. The absolute difference in the two groups' means divided by their mean standard deviation gives the effect size: + +.. code-block:: python + + u2u1 = abs(mean(b1_dtx) - mean(bother_dtx)) + effect_size = u2u1/mean([stdev(b1_dtx), stdev(bother_dtx)]) + +Note here that ``stdev()`` is used rather than ``std()``. ``std()`` calculates population standard deviation, while ``stdev()`` calculates sample standard deviation. For alpha diversity we consider only the contents of the particular sample (i.e. we are not comparing to any other group but rather attempting to find whether the sample is significantly different from the entire population) and therefore, for the null hypothesis can treat it as the population. However, for beta-diversity comparison between groups means that no one group cannot be considered as necessarily representative of the whole population and so sample standard deviation is used. + +Again, a list is created by appending iterated ``tt_ind_solve_power`` output and parameters, and this list is then converted to a dataframe. However, this time we iterate through different significance levels rather than effect levels. + +.. code-block:: python + + data_beta = [] + for observations in range(10, 155, 5): + for alpha in [.001, .01, .05, .1]: + x = tt_ind_solve_power(effect_size=effect_size, nobs1=observations, + alpha=alpha, ratio=1.0, + alternative='two-sided') + data_beta.append({ + 'Significance level (α)': alpha, 'Power (1-β)': x, + 'Total sample size (N)': observations * 2, + 'Difference': '%d (effect size %0.2f)' % (difference, effect_size)}) + data_beta = pd.DataFrame(data_beta) + +We have now generated the necessary data to create the relevant plots. + +Create Figures +""""""""""""""""""""" + +**Figure 1** + +We will use ``fig``, which allows the creation of a background (blank canvas) upon which further commands will take effect, the rest of the first line formats this background. ``sns.set`` can be used to set aesthetic parameters of the graph including plotting context such as grid line width, adjust the parameters of the plotting line axes and specify the axes titles. + +.. code-block:: python + + fig, ax1 = plt.subplots(figsize=(15, 9)) + + sns.set(style="whitegrid") + sns.set_context("paper", font_scale=2, + rc={'lines.linewidth': 2, 'lines.markersize': 12}) + + f = sns.lineplot(x='Total sample size (N)', y='Power (1-β)', markers=True, dashes=False, style='Difference', ax=ax1, data=data_alpha) #plot the data itself + + #x.axis ticks every 20 units + ax1.xaxis.set_major_locator(plt.MultipleLocator(20)) + + plt.axhline(0.8, 0, data_alpha['Total sample size (N)'].max()) + + fig.savefig('figure1.pdf') + +.. figure:: fig.1.python.png + :align: center + + Figure 1 as produced by python code. + +**Figure 2** + +Figure 2 has two graphs within it. This requires a grid to place them within, with three columns, two for the one graph, one for the other graph, on a single row. Then we can plot the two graphs, using similar syntax to the previous figure. + +.. code-block:: python + + fig = plt.figure(figsize=(20, 8)) + grid = plt.GridSpec(ncols=3, nrows=1, hspace=0.2, wspace=0.2) + + # add two new plots to grid + ax1 = fig.add_subplot(grid[0, :2]) + ax2 = fig.add_subplot(grid[0, 2:]) + + #for plot 1 set the style, axes etc + specify the data + sns.lineplot(x='Total sample size (N)', y='Power (1-β)', + style='Significance level (α)', + markers=True, dashes=False, + ax=ax1, data=data_beta) + + # plot the data for plot 1, and set it's x axis ticks to be every 20 units + ax1.axhline(0.8, 0, data_beta['Total sample size (N)'].max()) + ax1.xaxis.set_major_locator(plt.MultipleLocator(20)) + + # specify plot 2 parameters and plot + sns.distplot(b1_dtx, label="B1 within distances", color="red", ax=ax2) + ax2.axvline(mean(b1_dtx), 0, 6, color="red") + sns.distplot(bother_dtx, label="B2-3 within distances", color="skyblue", ax=ax2) + ax2.axvline(mean(bother_dtx), 0, 6, color="skyblue") + ax2.xaxis.set_major_locator(plt.MultipleLocator(.1)) + plt.legend() + + fig.savefig('figure2.pdf') + +You have now replicated the two figures in the Casals-Pascual et al 2020 paper, and should be able to repurpose this code to use for other data relevant to your own study. + +.. figure:: fig.2.python.png + :align: center + + Figure 2 as produced by python code. + +R studio workflow +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Set up environment +""""""""""""""""""" + +In R-studio create a new project and copy the (equivalent) following files to it: + +* metadata.txt +* alpha-diversity.tsv +* alpha_diversity.qza +* distance_matrix.qza +* distance-matrix.tsv + +If you are using windows, and have the windows R-studio, the files can be copied from the linux subshell using ``cp /mnt/c/Users///`` (this assumes you are in the directory containing the files, if not add the path to the file before the file name). Create a new script and set up your R environment: + +.. code-block:: r + + # IBD example + + ##get packages + if (!requireNamespace("installr", quietly = TRUE)){install.packages("installr")} + library("installr") + if (!requireNamespace("devtools", quietly = TRUE)){install.packages("devtools")} + library(devtools) + if (!requireNamespace("qiime2R", quietly = TRUE )) {devtools::install_github("jbisanz/qiime2R")} + library(qiime2R) + if(!requireNamespace("stats", quietly = TRUE)){install.packages("stats")} + library("stats") + if(!requireNamespace("ggplot2", quietly = TRUE)){install.packages("ggplot2")} + library("ggplot2") + if(requireNamespace("gridExtra", quietly = TRUE)){install.packages("gridExtra")} + library("gridExtra") + + +Not all the above steps may be necessary, but do remember to load the libraries, even if they are already installed. After this is completed we can import the data and process it. We will use Qiime2R [2]_ to import the data into formats R can handle, then filter it into appropriate groups. + +Import and process data +"""""""""""""""""""""""" + +.. code-block:: r + + ## Import and prepare data + ### metadata + metadata <- read.table("metadata.txt", sep="\t", header = TRUE) + + ###Load alpha diversity artifact + alpha <- read_qza("alpha_diversity.qza") + metadata <- merge.data.frame(metadata, alpha$data, by.x = 'sample_name', by.y = 0 ) + metadata <- metadata[!is.na(metadata$faith_pd),] + + ####Make variables for each group + b1 <- metadata[(metadata[ ,'cd_behavior'] == 'Non-stricturing, non-penetrating (B1)'), ] + bother <- metadata[(metadata$cd_behavior != 'Non-stricturing, non-penetrating (B1)' & metadata$cd_behavior != 'not applicable'), ] + + ###Load beta diversity/distance matrix artifact + beta <- read_qza("distance_matrix.qza") + dtx <- as.matrix(beta$data) + + ####Make variables for each group + b1_dtx <- as.vector(t(dtx[(metadata[(metadata$cd_behavior == 'Non-stricturing, non-penetrating (B1)'),"sample_name"]), ])) + bother_dtx <- as.vector(t(dtx[(metadata[(metadata$cd_behavior != 'Non-stricturing, non-penetrating (B1)' & metadata$cd_behavior != 'not applicable'), "sample_name"]), ])) + +The artifacts have now been loaded into R and the data separated by group. We can now perform the necessary processing to obtain data for plotting. Note that we do not use R's sd function directly because it calculates sample standard deviation and we require population standard deviation when working with alpha diversity statistics (which consider the sample as the population). + +.. code-block:: r + + ## Process data + ### alpha + n <- length(b1$faith_pd) + + # R's standard sd function uses denominator n -1 i.e. calculates sample standard deviation, therefore we do not use sd directly. + + sd1 <- sqrt((n-1)/n) * sd(b1$faith_pd) + sd2 <- sqrt((n-1)/n) * sd(bother$faith_pd) + sd12 <- mean(sd1, sd2) + + #### power t-test has the parameters n, delta, sd, sig.level and power. Four must be specified and the final is then calculated + + #significance level + sig <- 0.05 + + #create and empty data frame + data_alpha <- data.frame(NULL) + + #calculate the values for plotting and place them in a data frame + #iterate through sample sizes + for(obs in seq(from = 10, to = 155, by = 5)) { + #for each sample size iterate through different effect sizes + for(diff in 2:4){ + x <- power.t.test(n=obs, + delta=diff, + sd=sd12, + sig.level=sig, + power=NULL, + alternative="two.sided") + #place the calculated values into a dataframe + xrow <- c(x$sig.level, x$power, (x$n * 2), x$delta, (x$delta / x$sd)) + data_alpha <- rbind(data_alpha, xrow) + } + } + + # Set column names of the created dataframe + colnames(data_alpha) <- c('Significance level (α)', 'Power (1-β)', 'Total sample size (N)', 'Difference', 'Effect size') + + ###beta + + u2u1 <- abs(mean(b1_dtx) - mean(bother_dtx)) + + # note here we do use sd() because now we do want to calculate the sample standard deviation + sd_dtx <- mean(sd(b1_dtx), sd(bother_dtx)) + + #create empty dataframe + data_beta <- data.frame(NULL) + + #iterate through samples sizes + for(obs in seq(from=10, to=155, by=5)){ + #for each sample size iterate through different significance levels + for(sig in c(0.001, 0.01, 0.05, 0.1)){ + #calculate power for the set variable + x <- power.t.test(n=obs, + delta=u2u1, + sd=sd_dtx, + sig.level=sig, + power=NULL, + type="two.sample", + alternative="two.sided") + #place the calculated data into a data frame + xrow <- c(x$sig.level, x$power, (x$n * 2), x$delta, (x$delta / x$sd)) + data_beta <- rbind(data_beta, xrow) + } + } + + #Name the columns of the data frame appropriately + colnames(data_beta) <- c('Significance level (α)', 'Power (1-β)', 'Total sample size (N)', 'Difference', 'Effect size') + +If you have also looked at the python version of this code you may notice that here we do not use effect size directly, rather the function accepts both the difference and the standard deviation and calculates the effect size itself. + +Make Plots +""""""""""""" + +R's default plotting function is perfectly adequate for exploratory analysis, but for publication level figures the package ggplot is more appropriate. ggplot uses 'layers', first the plot background is made, then points, lines, annotations etc can be added to it. + +.. code-block:: r + + ## Make plots + ### Figure 1 + p <- ggplot(data_alpha, aes(x =as.numeric(`Total sample size (N)`), y =as.numeric(`Power (1-ß)`), group = as.factor(`Difference`), color = as.factor(`Difference`), shape = as.factor(`Difference`))) + + geom_hline(yintercept = 0.8, color = "blue", size = 0.5) + + geom_point() + + geom_line() + + scale_x_continuous(breaks = seq(0, 320, by = 20)) + + scale_y_continuous(breaks = seq(0, 1, by = 0.1)) + + labs(x = "Total sample size (N)", y = "Power (1-ß)") + + scale_shape_discrete(name = 'Difference', breaks = c("2", "3", "4"), labels = c("2 (effect size 0.55)", "3 (effect size 0.82)", "4 (effect size 1.09)")) + + scale_colour_discrete(name = 'Difference', breaks = c("2", "3", "4"), labels = c("2 (effect size 0.55)", "3 (effect size 0.82)", "4 (effect size 1.09)")) + + theme(legend.position = "bottom") + + #save the figure + jpeg('Figure_1.jpg', width = 1306, height = 579) + p + dev.off() + +.. figure:: fig.1.R.png + :align: center + + Figure 1 as produced by R code. + +While this code contains the necessary command to save an image automatically, a better quality image can be saved by running the line ``p`` alone so that the plot is present in the Rstudio plot viewer, and then using *export* -> *export as png* -> optionally alter image size and or ratio -> *save*. The same is true for figure 2 below, but in this case run the line ``grid.arrange(p1, p2, layout_matrix = lay)`` alone. + +.. code-block:: r + + ### Figure 2 + #### First create the two graphs + p1 <- ggplot(data_beta, aes(x =as.numeric(`Total sample size (N)`), y =as.numeric(`Power (1-ß)`), group = as.factor(`Significance level (a)`), color = as.factor(`Significance level (a)`), shape = as.factor(`Significance level (a)`))) + + geom_hline(yintercept = 0.8, color = "blue", size = 0.5) + + geom_point() + + geom_line() + + scale_x_continuous(breaks = seq(0, 320, by = 20)) + + scale_y_continuous(breaks = seq(0, 1, by = 0.1)) + + labs(x = "Total sample size (N)", y = "Power (1-ß)") + + scale_shape_discrete(name = 'Significance level (α)', breaks = c("0.001", "0.01", "0.05", "0.1"), labels = c("0.001", "0.01", "0.05", "0.1")) + + scale_colour_discrete(name = 'Significance level (α)', breaks = c("0.001", "0.01", "0.05", "0.1"), labels = c("0.001", "0.01", "0.05", "0.1")) + + theme(legend.position = "bottom") + + ####prepare data so ggplot can use it for a histogram + mu_b1 <- mean(b1_dtx) + label <- 'b1' + b1_dtx <- cbind(b1_dtx, label) + mu_bother <- mean(bother_dtx) + label <- 'bother' + bother_dtx <- cbind(bother_dtx, label) + merged <- as.data.frame(rbind(b1_dtx, bother_dtx)) + colnames(merged) <- c('dtx', 'Sample') + + + ####plot the histogram + + p2 <- ggplot(data = merged, aes(x = as.numeric(dtx), group = Sample, fill = Sample)) + + geom_histogram(aes(y=..density.., color = Sample), alpha = 0.1, binwidth = 0.01) + + #geom_density(alpha = 0.4) + #optional addition of density overlay + scale_x_continuous(name = '', breaks = seq(0,1,0.1), expand = c(0.1, 0.1)) + + scale_y_continuous(breaks = c(0:20)) + + geom_vline(xintercept = mu_b1, color = 'red', linetype = 'dashed', size = 0.8) + + geom_vline(xintercept = mu_bother, color = 'blue', linetype = 'dashed', size = 0.8) + + theme(legend.position = "bottom") + + scale_color_discrete(name = '', breaks = c('b1', 'bother'), labels = c("B1 within distances", "B2-3 within distances")) + + scale_fill_discrete(name = '', breaks = c('b1', 'bother'), labels = c("B1 within distances", "B2-3 within distances")) + + #specify layout + lay <- cbind(matrix(1), matrix(1), matrix(2)) + + #save figure + jpeg('Figure_2.jpg', width = 1500, height = 579) + grid.arrange(p1, p2, layout_matrix = lay) + dev.off() + +These figures will look slightly different to those in Casals-Pascual et al 2020 because they have been made in R but they are essentially the same, and this code can be modified to one's own data if R is preferred. + +.. figure:: fig.2.R.png + :align: center + + Figure 2 as produced by R code. + +Conclusion +^^^^^^^^^^^^^^^^ + +You should now have two figures essentially the same as those found in Casals-Pascual et al 2020 as well as having obtained the data to quantitatively decide on an appropriate sample size for an experiment that will obtain similar data. The generic paragraph recommended by their publication is as follows: + +**Generic Sample Size Justification Paragraph for Grants or Articles** + +*"The sample size has been determined based on statistical power, effect size, time, and available resources requested in this grant. A total number of 110 patients is realistic and achievable enrollment in our clinical setting. The diversity of microbial communities is a good indicator of dysbiosis in patients with CD1, and we have selected Faith's PD as a suitable metric to calculate alpha diversity. In a similar study, we observed that this metric shows an approximately normal distribution with mean 13.5 and standard deviation 3.45. Thus, to find a significant reduction of 2 units of Faith's PD (effect size, Cohen's D: 0.55) with an alpha value (type I error) of 5% and a statistical power (1 beta) of 80%, we will have to enroll 110 patients (55 with B1 phenotype and 55 with B2/B3 phenotype)."* + + + +Bibliography +^^^^^^^^^^^^^^^^ + +.. [1] Casals-Pascual C, González A, Vázquez-Baeza Y, Song SJ, Jiang L, Knight R. 2020 Microbial Diversity in Clinical Microbiome Studies: Sample Size and Statistical Power Considerations. Gastroenterology 158, 15241528. (doi:10.1053/j.gastro.2019.11.305) + +.. [2] 2018 Tutorial: Integrating QIIME2 and R for data visualization and analysis using qiime2R. QIIME 2 Forum. See https://forum.qiime2.org/t/tutorial-integrating-qiime2-and-r-for-data-visualization-and-analysis-using-qiime2r/4121 diff --git a/qiita_pet/support_files/doc/source/reanalysis/understanding-contexts.rst b/qiita_pet/support_files/doc/source/reanalysis/understanding-contexts.rst new file mode 100755 index 000000000..7b65ec8f0 --- /dev/null +++ b/qiita_pet/support_files/doc/source/reanalysis/understanding-contexts.rst @@ -0,0 +1,93 @@ +An explanation of contexts in redbiom and Qiita. +================================================ + +In both redbiom and Qiita study data is grouped into contexts representing different processing pipelines/methods. Processing and bioinformatic techniques can cause inherent biases in datasets, however if data is grouped by the protocol used to obtain the samples and extract data from them then, within any one such group (context), data is expected to be comparable. This is because the data in such a group (context) should share the same biases/limitations. Therefore, when retrieving data found in a redbiom search a context must be specified; so ensuring the retrieved data is comparable. If you are familiar with the methods and processes used in sample processing pipelines you should be able to interpret contexts as a context ultimately represents a processing pipeline. The general syntax of the context is ----<(if trimmed) trimming length>- and this section should help familiarize you with these considerations therefore providing an understanding of contexts in both redbiom and Qiita. + +.. figure:: contexts.jpg + :align: center + + Diagram of general workflow for obtaining and processing data (green = data state; grey = process; white = example) [Produced at http://interactive.blockdiag.com/] + +Obtaining Data +-------------- + +The first step of any pipeline is obtaining the data for the pipeline. As with any other stage of the pipeline this process could introduce biases or differences in the processed data, and needs to be accounted for. For instance, the region of the genome sequenced will determine whether two studies are directly comparable - use of different marker genes/regions will mean that the sequences (raw data) are not comparable. While the use of different reference databases to taxonomically classify the sequences may allow comparison at the taxonomic level, use of different databases could lead to biases in which sequences are classified. + +Sequencing techniques +--------------------- + +There are several next generation and third generation sequencing techniques on the market, each with their own advantages and limitations. Illumina sequencing is probably the most common high throughput sequencing technique. Below is a short description of some of the major techniques found in redbiom and Qiita contexts. + +* Illumina sequencing is a 'massively parallel' (high throughput) sequencing by synthesis technique, but has relatively short read lengths, a problem for assembly of repetitive regions. Note, however, that repetitive regions are less common in more economical genomes such as those of many bacteria, and are not a problem when assembly is not required such as when sequencing short marker gene fragments. +* Ion torrent is another ‘sequencing by synthesis’ method, which is less high throughput but cheaper as it does not require modified nucleotides. +* 454 sequencing has been out-competed, and the sequencers are no longer in production. It was a sequencing by synthesis method, which utilised polonies (like Illumina) and used imaging (pyrosequencing). While cheaper, it has difficulties distinguishing the number of bases in a run of identical bases because it detects incorporation of nucleotides passed over the cell a single type at a time (which also slows the process). + +Onywera and Meiring [1]_ compared Ion torrent and Illumina and suggest (with caution) that Illumina sequencing may produce reads of higher quality (2.4-fold more quality-filtered reads) with greater efficiency when sequencing 16S variable regions in metagenomic samples. + +Region sequenced for species identification +------------------------------------------- + +Marker genes versus whole genome +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Factors such as cost, time, and complexity all affect the choice of which genomic regions in a sample will actually be sequenced. Whole genome sequencing (WGS) provides the most information, it can also potentially overwhelm an analysis, especially taking into consideration the high frequency of horizontal spread (of genes) among many prokaryotes, as well as varying genome size, gene duplication and deletion. Furthermore, WGS involves greatly increased costs, time and use of resources (sequencing and assembling the entire genomes). Therefore, microbiome studies generally use a marker gene, which allows for rapid and cost efficient identification of the species within a sample, and so analysis of features such as community structure. + +16S rDNA (encoding the 16S rRNA of the ribosome, and thus universally present in prokaryotes) is currently the most commonly used marker gene. The gene's highly conserved function leads to a relatively low observed mutation rate in certain regions, allowing it to be used as a guide to phylogeny and taxonomic identity. More conserved regions of the gene allow reliable amplification (conserved sequences are needed for designing primers capable of annealing sequences from a wide variety of taxa) while hypervariable regions allow greater resolution. Note, however, that there is no consensus quantitative definition of genus or species based on 16S rRNA gene sequence + +Another marker region is the internal transcribed spacer DNA (ITS) between the large and small subunit rRNA-encoding DNA. As with rDNA, it is readily amplified due to both being present in multiple copies, and having conserved flanking regions (the rDNA). + +Within the 16S rDNA sequence, various variable regions can be amplified. V4 is a commonly used variable region of the 16S rDNA sequence, which, in total, contains nine hypervariable regions of varying conservation. Use of a variable region allows the detection of finer scale differences between taxa. Lower levels of variability are useful in determining higher-ranking taxa. Bukin et al [2]_ suggest that the V2-V3 region has the highest resolution for lower-rank taxa (species, genera) and so exploratory and diversity studies may wish to use this region. Conversely, Yang et al [3]_ come to a different conclusion, preferring V4-V6 for phylogenetic analysis. However, traditionally, V3 and V4 have been the most commonly used fragments. + +Processing Data +--------------- + +Processing data can again lead to both differences or biases in data which could affect comparison. Raw sequences undergo quality control, and are often trimmed. Note that trimming is controversial but is required to allow use of data across studies because the same length sequences are required for comparison between studies. Whether trimming occurs, and trimming length, depends on the study; however deblur and DADA require trimmed input sequences because they require input data to be of the same length (as both algorithms consider single nucleotide differences, and differences in length are therefore distinguished). Illumina sequencing technology can theoretically cover as much as 300 nucleotides, though in reality 200 is more common (leading to between 400 and 600 nt for a paired end read), trimming of the ends of this data removes adapter sequences. Common trimming lengths in the Qiita database are 90, 100, 150 and 200 nucleotides. Once quality control is completed, the raw data can then be processed in various manners. + +Assigning sequences to taxa +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Both the strategy of taxa assignment, and the reference database, if used, can lead to potential biases in data. + +**Binning strategies** + +Reads are representative of taxa in the sample and must be assigned appropriately to allow further analysis. There are two main strategies for assigning reads to a particular taxa, either reads are clustered into operational taxonomic units (OTUs) when above some threshold similarity; or specialised processing algorithms are used to yield putatively error free sequences which can then be aligned to a reference database. + +Picked OTUs, the former, involves clustering sequence data into clades based on similarity to a reference database in closed-reference picking, or each other in de novo clustering. Reads that do not cluster are discarded in closed-reference picking. Open picking has a second round of clustering in which reads that do not cluster with reference sequences are clustered against one another (de-novo clustering). The threshold similarity for clustering will determine what taxonomic level clusters represent [4]_ . + +Two common algorithms representative of the second strategy are Deblur and DADA2, which can be used to resolve sequence data to the sub-operational taxonomic unit (sOTU) level (where sequences may differ by only a nucleotide). At such high (single-nucleotide) resolution a specialised programme is necessary to retrieve putative error-free sequences. As both packages infer exact amplicon sequence variants (ASVs) they give higher resolution composition data output than OTU methods [5]_ [6]_ . Furthermore, ASVs are comparable across studies because they represent exact sequences rather than per-study OTU IDs. For this reason there is also no absolute requirement for using a reference database, eliminating a possible source of bias. For these, and further reasons, Callahan et al [7]_ suggest that ASVs (and the associated methods to obtain them) should replace OTUs. + +An independent study comparing DADA2, Deblur and an OTU picking pipeline found that all resulted in similar general community structure, but varied considerably in run times and the number of ASVs/OTUs called per sample (and so the resulting alpha-diversity metrics) [8]_ . OTU clustering tended to exaggerate the number of unique organisms. However, it should be noted that variation between treatments rather than per sample is a more informative metric to consider. + +**Reference taxonomy** + +If the picked OTUs are closed or open reference then the database they were scored against must also be specified (as with all other processing steps, it represents a possible source of bias). The same considerations hold for any microbial data that has had taxa assigned by alignment to a reference database. For example, if deblur generated ASVs have been mapped to a reference database to allow characterisation of known species in the sample, the database used should be specified. + +The most common reference database for 16S rDNA is Greengenes. However, this database has not been actively maintained since 2013. Other databases include: + +* Silva, which contains not only 16S but also 18S and 23S/28S data, and is actively maintained. Note it contains data for bacteria (16S, 23S), archaea and eukarya (18S, 28S). +* Unite, a database for ITS (it does not contain any other regions). +* GTDB, the newest database for Bacterial and Archeal sequences, this database also includes representative sequences not yet assigned a species name, and contains whole (and partial) genomes. + +Conclusion +---------- + +This article should have given you a brief overview of some of the major processes and considerations in processing pipelines for microbiome data and so the ability to interpret redbiom and Qiita contexts. The general syntax of the context is ----. Each of these processes or considerations can lead to differences or biases in the data, and thus is included in contexts. + +Bibliography +------------ + +.. [1] Onywera H, Meiring TL. 2020 Comparative analyses of Ion Torrent V4 and Illumina V3-V4 16S rRNA gene metabarcoding methods for characterization of cervical microbiota: taxonomic and functional profiling. Sci. Afr. 7, e00278. (doi:10.1016/j.sciaf.2020.e00278) + +.. [2] Bukin YS, Galachyants YP, Morozov IV, Bukin SV, Zakharenko AS, Zemskaya TI. 2019 The effect of 16S rRNA region choice on bacterial community metabarcoding results. Sci. Data 6, 190007. (doi:10.1038/sdata.2019.7) + +.. [3] Yang B, Wang Y, Qian P-Y. 2016 Sensitivity and correlation of hypervariable regions in 16S rRNA genes in phylogenetic analysis. BMC Bioinformatics 17. (doi:10.1186/s12859-016-0992-y) + +.. [4] OTU picking strategies in QIIME Homepage. See http://qiime.org/tutorials/otu_picking.html + +.. [5] Amir A et al. 2017 Deblur Rapidly Resolves Single-Nucleotide Community Sequence Patterns. mSystems 2. (doi:10.1128/mSystems.00191-16) + +.. [6] Callahan BJ, McMurdie PJ, Rosen MJ, Han AW, Johnson AJA, Holmes SP. 2016 DADA2: High-resolution sample inference from Illumina amplicon data. Nat. Methods 13, 581583. (doi:10.1038/nmeth.3869) + +.. [7] Callahan BJ, McMurdie PJ, Holmes SP. 2017 Exact sequence variants should replace operational taxonomic units in marker-gene data analysis. ISME J. 11, 26392643. (doi:10.1038/ismej.2017.119) + +.. [8] Nearing JT, Douglas GM, Comeau AM, Langille MGI. 2018 Denoising the Denoisers: an independent evaluation of microbiome sequence error-correction approaches. PeerJ 6, e5364. (doi:10.7717/peerj.5364) diff --git a/qiita_pet/support_files/doc/source/redbiom.rst b/qiita_pet/support_files/doc/source/redbiom.rst old mode 100755 new mode 100644 index da2e7294d..c168324ed --- a/qiita_pet/support_files/doc/source/redbiom.rst +++ b/qiita_pet/support_files/doc/source/redbiom.rst @@ -7,6 +7,10 @@ redbiom * Allows you to search through public studies to find comparable data to your own * Can search by: metadata, feature, or taxon +redbiom is a cache service which can be used to search databases for samples which contain particular taxonomic units or given features (e.g. environmental or clinical factors); either as a Qiita plugin, or as a separately installed command line package. redbiom can therefore be used to identify samples for a meta-analysis focused on some particular factor (or factors). The utility of searching by metadata or feature is that it allows the discovery and subsequent use of a potentially wide variety of samples. This may include data from studies with completely different research goals, which one would have otherwise been unlikely to realize could be used. + +Note that a cache service is a high-speed data storage layer which stores a subset of data allowing a more rapid searching and retrieval experience. redbiom has a much smaller, sparse vector version of the Qiita database containing mainly metadata, which thus allows rapid searching. Samples found in a redbiom search can then be retrieved from the Qiita database through redbiom for subsequent analysis. + For more information, advanced queries and generating `BIOM `__ files go to the `redbiom github page `__. @@ -35,7 +39,7 @@ Search Options will find all samples which have the *qiita_study_id* metadata category, and in which the value for that sample is *10317*. * **Examples:** - + * Find all samples in which both the word 'infant', as well as 'antibiotics' exist, and where the infants are under a year old: .. code-block:: bash diff --git a/qiita_pet/webserver.py b/qiita_pet/webserver.py index 8b1c8a8c7..6777b7a17 100644 --- a/qiita_pet/webserver.py +++ b/qiita_pet/webserver.py @@ -60,7 +60,8 @@ JobHandler, HeartbeatHandler, ActiveStepHandler, CompleteHandler, ProcessingJobAPItestHandler) from qiita_db.handlers.artifact import ( - ArtifactHandler, ArtifactAPItestHandler, ArtifactTypeHandler) + ArtifactHandler, ArtifactAPItestHandler, ArtifactTypeHandler, + APIArtifactHandler) from qiita_db.handlers.sample_information import SampleInfoDBHandler from qiita_db.handlers.user import UserInfoDBHandler, UsersListDBHandler from qiita_db.handlers.prep_template import ( @@ -205,6 +206,7 @@ def __init__(self): (r"/qiita_db/jobs/(.*)", JobHandler), (r"/qiita_db/artifacts/types/", ArtifactTypeHandler), (r"/qiita_db/artifacts/(.*)/", ArtifactHandler), + (r"/qiita_db/artifact/", APIArtifactHandler), (r"/qiita_db/users/", UsersListDBHandler), (r"/qiita_db/user/(.*)/data/", UserInfoDBHandler), (r"/qiita_db/sample_information/(.*)/data/", SampleInfoDBHandler), diff --git a/qiita_ware/__init__.py b/qiita_ware/__init__.py index 854abc53a..a86cb7731 100644 --- a/qiita_ware/__init__.py +++ b/qiita_ware/__init__.py @@ -6,4 +6,4 @@ # The full license is in the file LICENSE, distributed with this software. # ----------------------------------------------------------------------------- -__version__ = "052020" +__version__ = "092020" diff --git a/qiita_ware/ebi.py b/qiita_ware/ebi.py index a4fd8b018..489f0234e 100644 --- a/qiita_ware/ebi.py +++ b/qiita_ware/ebi.py @@ -356,6 +356,11 @@ def generate_study_xml(self): study_title = ET.SubElement(descriptor, 'STUDY_TITLE') study_title.text = escape(clean_whitespace(self.study_title)) + # study type is deprecated and not displayed anywhere on EBI-ENA; + # however it's required for submission so just injecting with Other + ET.SubElement( + descriptor, 'STUDY_TYPE', {'existing_study_type': 'Other'}) + study_abstract = ET.SubElement(descriptor, 'STUDY_ABSTRACT') study_abstract.text = clean_whitespace(escape(self.study_abstract)) diff --git a/qiita_ware/test/test_ebi.py b/qiita_ware/test/test_ebi.py index da784e0d8..28cf12b95 100644 --- a/qiita_ware/test/test_ebi.py +++ b/qiita_ware/test/test_ebi.py @@ -1314,6 +1314,7 @@ def test_parse_EBI_reply(self): Identification of the Microbiomes for Cannabis Soils + This is a preliminary study to examine the microbiota associated with \ the Cannabis plant. Soils samples from the bulk soil, soil associated with \ diff --git a/scripts/qiita-auto-processing b/scripts/qiita-auto-processing index a84990a8f..e3dcb2f39 100644 --- a/scripts/qiita-auto-processing +++ b/scripts/qiita-auto-processing @@ -33,6 +33,7 @@ user = User('antoniog@ucsd.edu') # 'version': the version of the plugin, # 'cmd_name': the command we want to run, # 'input_name': the name of the input parameter of that command +# 'ignore_parameters': list of parameters to ignore, for example: threads # 'parent_artifact_name': name of the parent output, input for this command # 'parameters_names': list of the names of the parameter sets we want to run # } @@ -41,21 +42,24 @@ full_pipelines = [ 'data_type': ['Metagenomic'], 'artifact_type': 'per_sample_FASTQ', 'previous-step': None, + 'requirements': dict(), 'steps': [ {'previous-step': None, 'plugin': 'qp-shogun', 'version': '012020', 'cmd_name': 'Atropos v1.1.24', 'input_name': 'input', + 'ignore_parameters': ['Number of threads used'], 'parent_artifact_name': None, 'parameters_names': ['KAPA HyperPlus with iTru']}, {'previous-step': 'Atropos v1.1.24', 'plugin': 'qp-shogun', - 'version': '012020', - 'cmd_name': 'Shogun v1.0.7', + 'version': '072020', + 'cmd_name': 'Shogun v1.0.8', 'input_name': 'input', + 'ignore_parameters': ['Number of threads'], 'parent_artifact_name': 'Adapter trimmed files', - 'parameters_names': ['wol_bowtie2', 'rep94_bowtie2']} + 'parameters_names': ['wol_bowtie2', 'rep200_bowtie2']} ]}, {'name': 'Target Gene Processing', 'data_type': ['16S', '18S', 'ITS'], @@ -73,6 +77,7 @@ full_pipelines = [ 'version': '1.9.1', 'cmd_name': 'Trimming', 'input_name': 'input_data', + 'ignore_parameters': [], 'parent_artifact_name': None, 'parameters_names': ['90 base pairs', '100 base pairs', @@ -83,6 +88,7 @@ full_pipelines = [ 'version': '1.9.1', 'cmd_name': 'Pick closed-reference OTUs', 'input_name': 'input_data', + 'ignore_parameters': [], 'parent_artifact_name': 'Trimmed Demultiplexed', 'parameters_names': ['Defaults - parallel']}, {'previous-step': 'Trimming', @@ -90,6 +96,7 @@ full_pipelines = [ 'version': '1.1.0', 'cmd_name': 'Deblur', 'input_name': 'Demultiplexed sequences', + 'ignore_parameters': [], 'parent_artifact_name': 'Trimmed Demultiplexed', 'parameters_names': ['Defaults']} ]}, @@ -122,6 +129,22 @@ def _check_requirements(requirements, template): return satisfied +def _check_parameters(jobs, cmd): + params = [{k: str(v) for k, v in j.parameters.values.items() + if k not in cmd['ignore_parameters']} for j in jobs] + return params + + +def _submit_workflows(artifact_process): + for artifact in artifact_process: + if artifact['workflow'] is None: + continue + # nodes will return in position [0] the first job created + first_job = list(artifact['workflow'].graph.nodes())[0] + if first_job.status == 'in_construction': + artifact['workflow'].submit() + + # Step 1. Loop over the full_pipelines to process each step for pipeline in full_pipelines: # Step 2. From the steps generate the list of commands to add to the @@ -149,6 +172,7 @@ for pipeline in full_pipelines: 'previous-step': step['previous-step'], 'parent_artifact_name': step['parent_artifact_name'], 'input_name': step['input_name'], + 'ignore_parameters': step['ignore_parameters'], 'parameters': parameters}) # Step 2. - for children. Get their commands. We currently only support @@ -161,7 +185,9 @@ for pipeline in full_pipelines: if c['previous-step'] == commands[0]['command-name']] # Step 3. Find all preparations/artifacts that we can add the pipeline - artifacts_all = [a for study in Study.iter() + # ... as a first pass we will only process study 10317 (AGP) ... + # artifacts_all = [a for study in Study.iter() + artifacts_all = [a for study in [Study(10317)] # loop over all artifacts of artifact_type with in study for a in study.artifacts( artifact_type=pipeline['artifact_type']) @@ -172,7 +198,10 @@ for pipeline in full_pipelines: artifacts_compliant = [] for a in artifacts_all: st = a.study.sample_template - pt = a.prep_templates[0] + pts = a.prep_templates + if not pts: + continue + pt = pts[0] # {'sandbox', 'awaiting_approval', 'private', 'public'} if a.visibility in ('sandbox', 'awaiting_approval'): @@ -194,23 +223,29 @@ for pipeline in full_pipelines: # of Step 4 but for debugging it makes sense to separate artifact_process = [] children_compliant = [] + cmd = commands[0] for a in artifacts_compliant: - cmd = commands[0] # getting all jobs, includen hiddens, in case the job failed jobs = a.jobs(cmd=cmd['command'], show_hidden=True) - params = [j.parameters.values for j in jobs] + params = _check_parameters(jobs, cmd) # checking that all required parameters of this command exist missing_parameters = [] for p in cmd['parameters']: p = p['values'] p.update({cmd['input_name']: str(a.id)}) - if p not in params: + p_to_compare = p.copy() + for k in cmd['ignore_parameters']: + del p_to_compare[k] + if p_to_compare not in params: missing_parameters.append(p) else: for c in a.children: - if c.processing_parameters.values == p: - children_compliant.append(c) + cpp = c.processing_parameters + if cpp.command.name == cmd['command-name']: + cparams = _check_parameters([cpp], cmd) + if cparams == p_to_compare: + children_compliant.append(c) if missing_parameters: # note that we are building a dict for each artifact so we can # save the workflow id, useful for when we run this in a terminal @@ -224,14 +259,18 @@ for pipeline in full_pipelines: for cmd_id, cmd in enumerate(children_cmds): # getting all jobs, includen hiddens, in case the job failed jobs = a.jobs(cmd=cmd['command'], show_hidden=True) - params = [j.parameters.values for j in jobs] + params = _check_parameters(jobs, cmd) # checking that all required parameters of this command exist missing_parameters = [] for p in cmd['parameters']: p = p['values'] - p.update({cmd['input_name']: str(c.id)}) - if p not in params: + p.update({cmd['input_name']: str(a.id)}) + p_to_compare = p.copy() + for k in cmd['ignore_parameters']: + del p_to_compare[k] + + if p_to_compare not in params: missing_parameters.append(p) if missing_parameters: artifact_process.append( @@ -266,9 +305,9 @@ for pipeline in full_pipelines: # now we can add the rest of the parameters to the workflow for # the first command for params in artifact['missing_parameters'][1:]: - params.update({cmd['input_name']: str(a.id)}) job_params = Parameters.load(cmd['command'], values_dict=params) - artifact['workflow'].add(job_params) + artifact['workflow'].add( + job_params, req_params={cmd['input_name']: str(a.id)}) for cmd in commands[cmd_id + 1:]: # get jobs from the workflow to which we can add this new command @@ -286,10 +325,4 @@ for pipeline in full_pipelines: cmd['parent_artifact_name']: cmd['input_name']}}) # Step 7. submit the workflows! - for artifact in artifact_process: - if artifact['workflow'] is None: - continue - # nodes will return in position [0] the first job created - first_job = list(artifact['workflow'].graph.nodes())[0] - if first_job.status == 'in_construction': - artifact['workflow'].submit() + _submit_workflows(artifact_process) diff --git a/setup.py b/setup.py index cadd6b869..2733da817 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ from setuptools import setup from glob import glob -__version__ = "052020" +__version__ = "092020" classes = """ From cc8f1abf4afd5e4b635757cf5f40913643d7b2eb Mon Sep 17 00:00:00 2001 From: Antonio Gonzalez Date: Thu, 5 Nov 2020 07:01:49 -0700 Subject: [PATCH 2/3] adding job submit ENVIRONMENT and minor improvement to runWorkflow --- qiita_db/processing_job.py | 20 +++++++++++++++++++- qiita_db/test/test_processing_job.py | 19 +++++++++++++++++++ qiita_pet/static/js/networkVue.js | 12 ++++++++---- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/qiita_db/processing_job.py b/qiita_db/processing_job.py index 13456e871..aaa219f26 100644 --- a/qiita_db/processing_job.py +++ b/qiita_db/processing_job.py @@ -880,12 +880,30 @@ def submit(self, parent_job_id=None, dependent_jobs_list=None): # portal server that submitted the job url = "%s%s" % (qiita_config.base_url, qiita_config.portal_dir) + # if the word ENVIRONMENT is in the plugin_env_script we have a special + # case where we are going to execute some command and then wait for the + # plugin to return their own id (first implemented for + # fast-bowtie2+woltka) + if 'ENVIRONMENT' in plugin_env_script: + # the job has to be in running state so the plugin can change its` + # status + with qdb.sql_connection.TRN: + self._set_status('running') + qdb.sql_connection.TRN.commit() + + create_nested_path(job_dir) + cmd = (f'{plugin_env_script}; {plugin_start_script} ' + f'{url} {self.id} {job_dir}') + stdout, stderr, return_value = _system_call(cmd) + if return_value != 0 or stderr != '': + self._set_error(stderr) + job_id = stdout # note that dependent jobs, such as m validator jobs marshalled into # n 'queues' require the job_id returned by an external scheduler such # as Torque's MOAB, rather than a job name that can be defined within # Qiita. Hence, this method must be able to handle the case where a job # requires metadata from a late-defined and time-sensitive source. - if qiita_config.plugin_launcher in ProcessingJob._launch_map: + elif qiita_config.plugin_launcher in ProcessingJob._launch_map: launcher = ProcessingJob._launch_map[qiita_config.plugin_launcher] if launcher['execute_in_process']: # run this launcher function within this process. diff --git a/qiita_db/test/test_processing_job.py b/qiita_db/test/test_processing_job.py index c4248c634..6a730f670 100644 --- a/qiita_db/test/test_processing_job.py +++ b/qiita_db/test/test_processing_job.py @@ -265,6 +265,25 @@ def test_submit_error(self): qdb.exceptions.QiitaDBOperationNotPermittedError): job.submit() + def test_submit_environment(self): + job = _create_job() + software = job.command.software + current = software.environment_script + + # temporal update and then rollback to not commit change + with qdb.sql_connection.TRN: + sql = """UPDATE qiita.software SET environment_script = %s + WHERE software_id = %s""" + qdb.sql_connection.TRN.add(sql, [ + f'{current} ENVIRONMENT', software.id]) + + job.submit() + + self.assertEqual(job.status, 'error') + self.assertIn('No such file', job.log.msg) + + qdb.sql_connection.TRN.rollback() + def test_complete_multiple_outputs(self): # This test performs the test of multiple functions at the same # time. "release", "release_validators" and diff --git a/qiita_pet/static/js/networkVue.js b/qiita_pet/static/js/networkVue.js index efe5f1635..06f7e3a58 100644 --- a/qiita_pet/static/js/networkVue.js +++ b/qiita_pet/static/js/networkVue.js @@ -70,7 +70,7 @@ Vue.component('processing-graph', { '
' + '

Start workflow:

' + '
' + - '
' + @@ -341,6 +341,8 @@ Vue.component('processing-graph', { * */ runWorkflow: function() { + $('#run-btn').attr('disabled', true); + $('#run-btn').html(' Submitting'); let vm = this; $.post(vm.portal + "/study/process/workflow/run/", {workflow_id: vm.workflowId}, function(data){ bootstrapAlert("Workflow " + vm.workflowId + " submitted", "success"); @@ -351,9 +353,11 @@ Vue.component('processing-graph', { .fail(function(object, status, error_msg) { bootstrapAlert("Error submitting workflow: " + object.statusText, "danger"); }); - // return button to regular state - $('#run-btn').attr('disabled', false); - $('#run-btn').html(' Run'); + .always(function() { + // return button to regular state + $('#run-btn').attr('disabled', false); + $('#run-btn').html(' Run'); + }); }, /** From 6e911341933b5382d9eb4a39640f6af58dc7f3c4 Mon Sep 17 00:00:00 2001 From: Antonio Gonzalez Date: Thu, 5 Nov 2020 07:32:19 -0700 Subject: [PATCH 3/3] fix test --- qiita_db/test/test_processing_job.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qiita_db/test/test_processing_job.py b/qiita_db/test/test_processing_job.py index 6a730f670..51f957275 100644 --- a/qiita_db/test/test_processing_job.py +++ b/qiita_db/test/test_processing_job.py @@ -280,7 +280,6 @@ def test_submit_environment(self): job.submit() self.assertEqual(job.status, 'error') - self.assertIn('No such file', job.log.msg) qdb.sql_connection.TRN.rollback()