Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions q2_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
importlib.import_module('q2_types.sample_data')
importlib.import_module('q2_types.per_sample_sequences')
importlib.import_module('q2_types.bowtie2')
importlib.import_module('q2_types.metadata')
18 changes: 18 additions & 0 deletions q2_types/metadata/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ----------------------------------------------------------------------------
# Copyright (c) 2016-2023, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------

import importlib

from ._format import ImmutableMetadataFormat, ImmutableMetadataDirectoryFormat
from ._type import ImmutableMetadata

__all__ = ['ImmutableMetadataFormat',
'ImmutableMetadataDirectoryFormat',
'ImmutableMetadata']

importlib.import_module('q2_types.metadata._transformer')
31 changes: 31 additions & 0 deletions q2_types/metadata/_format.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ----------------------------------------------------------------------------
# Copyright (c) 2016-2023, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------

import qiime2.plugin.model as model
from qiime2.plugin import ValidationError
from qiime2 import Metadata
from qiime2.metadata import MetadataFileError

from ..plugin_setup import plugin


class ImmutableMetadataFormat(model.TextFileFormat):
def _validate_(self, level):
try:
Metadata.load(str(self))
except (MetadataFileError,) as e:
raise ValidationError(str(e))


ImmutableMetadataDirectoryFormat = model.SingleFileDirectoryFormat(
'ImmutableMetadataDirectoryFormat', 'metadata.tsv',
ImmutableMetadataFormat)


plugin.register_formats(ImmutableMetadataFormat,
ImmutableMetadataDirectoryFormat)
17 changes: 17 additions & 0 deletions q2_types/metadata/_transformer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# ----------------------------------------------------------------------------
# Copyright (c) 2016-2023, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------

import qiime2

from ..plugin_setup import plugin
from . import ImmutableMetadataFormat


@plugin.register_transformer
def _1(ff: ImmutableMetadataFormat) -> qiime2.Metadata:
return qiime2.Metadata.load(str(ff))
23 changes: 23 additions & 0 deletions q2_types/metadata/_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# ----------------------------------------------------------------------------
# Copyright (c) 2016-2023, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------

from qiime2.plugin import SemanticType

from ..plugin_setup import plugin
from . import ImmutableMetadataDirectoryFormat


ImmutableMetadata = SemanticType('ImmutableMetadata')

plugin.register_semantic_types(ImmutableMetadata)

plugin.register_artifact_class(
ImmutableMetadata,
directory_format=ImmutableMetadataDirectoryFormat,
description=("Immutable sample or feature metadata.")
)
7 changes: 7 additions & 0 deletions q2_types/metadata/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ----------------------------------------------------------------------------
# Copyright (c) 2016-2023, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------
36 changes: 36 additions & 0 deletions q2_types/metadata/tests/data/invalid-metadata-1.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
bad-id-label barcode-sequence body-site year month day subject reported-antibiotic-usage days-since-experiment-start
#q2:types categorical categorical numeric numeric numeric categorical categorical numeric
L1S8 AGCTGACTAGTC gut 2008 10 28 subject-1 Yes 0
L1S57 ACACACTATGGC gut 2009 1 20 subject-1 No 84
L1S76 ACTACGTGTGGT gut 2009 2 17 subject-1 No 112
L1S105 AGTGCGATGCGT gut 2009 3 17 subject-1 No 140
L2S155 ACGATGCGACCA left palm 2009 1 20 subject-1 No 84
L2S175 AGCTATCCACGA left palm 2009 2 17 subject-1 No 112
L2S204 ATGCAGCTCAGT left palm 2009 3 17 subject-1 No 140
L2S222 CACGTGACATGT left palm 2009 4 14 subject-1 No 168
L3S242 ACAGTTGCGCGA right palm 2008 10 28 subject-1 Yes 0
L3S294 CACGACAGGCTA right palm 2009 1 20 subject-1 No 84
L3S313 AGTGTCACGGTG right palm 2009 2 17 subject-1 No 112
L3S341 CAAGTGAGAGAG right palm 2009 3 17 subject-1 No 140
L3S360 CATCGTATCAAC right palm 2009 4 14 subject-1 No 168
L5S104 CAGTGTCAGGAC tongue 2008 10 28 subject-1 Yes 0
L5S155 ATCTTAGACTGC tongue 2009 1 20 subject-1 No 84
L5S174 CAGACATTGCGT tongue 2009 2 17 subject-1 No 112
L5S203 CGATGCACCAGA tongue 2009 3 17 subject-1 No 140
L5S222 CTAGAGACTCTT tongue 2009 4 14 subject-1 No 168
L1S140 ATGGCAGCTCTA gut 2008 10 28 subject-2 Yes 0
L1S208 CTGAGATACGCG gut 2009 1 20 subject-2 No 84
L1S257 CCGACTGAGATG gut 2009 3 17 subject-2 No 140
L1S281 CCTCTCGTGATC gut 2009 4 14 subject-2 No 168
L2S240 CATATCGCAGTT left palm 2008 10 28 subject-2 Yes 0
L2S309 CGTGCATTATCA left palm 2009 1 20 subject-2 No 84
L2S357 CTAACGCAGTCA left palm 2009 3 17 subject-2 No 140
L2S382 CTCAATGACTCA left palm 2009 4 14 subject-2 No 168
L3S378 ATCGATCTGTGG right palm 2008 10 28 subject-2 Yes 0
L4S63 CTCGTGGAGTAG right palm 2009 1 20 subject-2 No 84
L4S112 GCGTTACACACA right palm 2009 3 17 subject-2 No 140
L4S137 GAACTGTATCTC right palm 2009 4 14 subject-2 No 168
L5S240 CTGGACTCATAG tongue 2008 10 28 subject-2 Yes 0
L6S20 GAGGCTCATCAT tongue 2009 1 20 subject-2 No 84
L6S68 GATACGTCCTGA tongue 2009 3 17 subject-2 No 140
L6S93 GATTAGCACTCT tongue 2009 4 14 subject-2 No 168
36 changes: 36 additions & 0 deletions q2_types/metadata/tests/data/metadata.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
sample-id barcode-sequence body-site year month day subject reported-antibiotic-usage days-since-experiment-start
#q2:types categorical categorical numeric numeric numeric categorical categorical numeric
L1S8 AGCTGACTAGTC gut 2008 10 28 subject-1 Yes 0
L1S57 ACACACTATGGC gut 2009 1 20 subject-1 No 84
L1S76 ACTACGTGTGGT gut 2009 2 17 subject-1 No 112
L1S105 AGTGCGATGCGT gut 2009 3 17 subject-1 No 140
L2S155 ACGATGCGACCA left palm 2009 1 20 subject-1 No 84
L2S175 AGCTATCCACGA left palm 2009 2 17 subject-1 No 112
L2S204 ATGCAGCTCAGT left palm 2009 3 17 subject-1 No 140
L2S222 CACGTGACATGT left palm 2009 4 14 subject-1 No 168
L3S242 ACAGTTGCGCGA right palm 2008 10 28 subject-1 Yes 0
L3S294 CACGACAGGCTA right palm 2009 1 20 subject-1 No 84
L3S313 AGTGTCACGGTG right palm 2009 2 17 subject-1 No 112
L3S341 CAAGTGAGAGAG right palm 2009 3 17 subject-1 No 140
L3S360 CATCGTATCAAC right palm 2009 4 14 subject-1 No 168
L5S104 CAGTGTCAGGAC tongue 2008 10 28 subject-1 Yes 0
L5S155 ATCTTAGACTGC tongue 2009 1 20 subject-1 No 84
L5S174 CAGACATTGCGT tongue 2009 2 17 subject-1 No 112
L5S203 CGATGCACCAGA tongue 2009 3 17 subject-1 No 140
L5S222 CTAGAGACTCTT tongue 2009 4 14 subject-1 No 168
L1S140 ATGGCAGCTCTA gut 2008 10 28 subject-2 Yes 0
L1S208 CTGAGATACGCG gut 2009 1 20 subject-2 No 84
L1S257 CCGACTGAGATG gut 2009 3 17 subject-2 No 140
L1S281 CCTCTCGTGATC gut 2009 4 14 subject-2 No 168
L2S240 CATATCGCAGTT left palm 2008 10 28 subject-2 Yes 0
L2S309 CGTGCATTATCA left palm 2009 1 20 subject-2 No 84
L2S357 CTAACGCAGTCA left palm 2009 3 17 subject-2 No 140
L2S382 CTCAATGACTCA left palm 2009 4 14 subject-2 No 168
L3S378 ATCGATCTGTGG right palm 2008 10 28 subject-2 Yes 0
L4S63 CTCGTGGAGTAG right palm 2009 1 20 subject-2 No 84
L4S112 GCGTTACACACA right palm 2009 3 17 subject-2 No 140
L4S137 GAACTGTATCTC right palm 2009 4 14 subject-2 No 168
L5S240 CTGGACTCATAG tongue 2008 10 28 subject-2 Yes 0
L6S20 GAGGCTCATCAT tongue 2009 1 20 subject-2 No 84
L6S68 GATACGTCCTGA tongue 2009 3 17 subject-2 No 140
L6S93 GATTAGCACTCT tongue 2009 4 14 subject-2 No 168
39 changes: 39 additions & 0 deletions q2_types/metadata/tests/test_format.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ----------------------------------------------------------------------------
# Copyright (c) 2016-2023, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------

import shutil

from q2_types.metadata import (ImmutableMetadataDirectoryFormat,
ImmutableMetadataFormat)
from qiime2.plugin.testing import TestPluginBase
from qiime2.plugin import ValidationError


class TestFormats(TestPluginBase):
package = "q2_types.metadata.tests"

def test_metadata_format_validate_positive(self):
filepath = self.get_data_path('metadata.tsv')
format = ImmutableMetadataFormat(filepath, mode='r')

format.validate()

def test_metadata_dir_format_validate_positive(self):
filepath = self.get_data_path('metadata.tsv')
shutil.copy(filepath, self.temp_dir.name)
format = ImmutableMetadataDirectoryFormat(self.temp_dir.name, mode='r')

format.validate()

def test_metadata_format_validate_negative(self):
filepath = self.get_data_path('invalid-metadata-1.tsv')
format = ImmutableMetadataFormat(filepath, mode='r')

with self.assertRaisesRegex(ValidationError,
"column name 'bad-id-label'"):
format.validate()
31 changes: 31 additions & 0 deletions q2_types/metadata/tests/test_transformer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ----------------------------------------------------------------------------
# Copyright (c) 2016-2023, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------

import qiime2
from q2_types.metadata import ImmutableMetadataFormat
from qiime2.plugin.testing import TestPluginBase
from qiime2.metadata import MetadataFileError


class TestTransformers(TestPluginBase):
package = "q2_types.metadata.tests"

def test_metadata_format_to_metadata(self):
filename = 'metadata.tsv'
_, obs = self.transform_format(ImmutableMetadataFormat,
qiime2.Metadata,
filename)
exp_md = qiime2.Metadata.load(self.get_data_path(filename))
self.assertEqual(obs, exp_md)

def test_non_metadata(self):
filename = 'invalid-metadata-1.tsv'
with self.assertRaisesRegex(MetadataFileError,
"column name 'bad-id-label'"):
self.transform_format(ImmutableMetadataFormat, qiime2.Metadata,
filename)
22 changes: 22 additions & 0 deletions q2_types/metadata/tests/test_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# ----------------------------------------------------------------------------
# Copyright (c) 2016-2023, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------

from q2_types.metadata import (ImmutableMetadataDirectoryFormat,
ImmutableMetadata)
from qiime2.plugin.testing import TestPluginBase


class TestTypes(TestPluginBase):
package = "q2_types.metadata.tests"

def test_immutable_metadata_semantic_type_registration(self):
self.assertRegisteredSemanticType(ImmutableMetadata)

def test_immutable_metadata_dir_fmt_registration(self):
self.assertSemanticTypeRegisteredToFormat(
ImmutableMetadata, ImmutableMetadataDirectoryFormat)
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
'q2_types.distance_matrix.tests': ['data/*'],
'q2_types.feature_data.tests': ['data/*', 'data/taxonomy/*'],
'q2_types.feature_table.tests': ['data/*'],
'q2_types.metadata.tests': ['data/*'],
'q2_types.multiplexed_sequences.tests': ['data/*'],
'q2_types.ordination.tests': ['data/*'],
'q2_types.per_sample_sequences.tests':
Expand Down