diff --git a/.linkmllint.yaml b/.linkmllint.yaml new file mode 100644 index 0000000..355171d --- /dev/null +++ b/.linkmllint.yaml @@ -0,0 +1,11 @@ +# Configuration for `just lint` (linkml-lint reads this file from the repository root). +extends: recommended +rules: + standard_naming: + # StrandEnum in ber_feature_model.yaml uses the GFF3 column 7 symbols as its values, so a + # strand written in a GFF3 file reads back unchanged. + exclude: + - "+" + - "-" + - "." + - "?" diff --git a/src/ber_central_schema/schema/attributes.yaml b/src/ber_central_schema/schema/attributes.yaml new file mode 100644 index 0000000..6936e5b --- /dev/null +++ b/src/ber_central_schema/schema/attributes.yaml @@ -0,0 +1,67 @@ +id: https://w3id.org/ber-data/attributes +name: attributes +title: Reusable attributes (draft) +version: 0.1.0 +description: >- + String-valued attributes for metadata, annotations, and source-reported evidence, with an + optional CURIE for the key and an optional number for the value. +license: https://creativecommons.org/publicdomain/zero/1.0/ +prefixes: + linkml: https://w3id.org/linkml/ + battr: https://w3id.org/ber-data/attributes/ + kb_cdm: http://kbase.github.io/cdm-schema/linkml/ + nmdc: https://w3id.org/nmdc/ +default_prefix: battr +default_range: string +imports: + - linkml:types +classes: + Attribute: + title: Attribute + class_uri: battr:Attribute + description: One named value attached to a record by a consuming model. + notes: + - GFF column 9 is a minimal use case, alongside tabular annotations and metadata. + This module has no dependency on GFF, Feature, Contig, or a genomic coordinate system. + - A key is not an identifier; repeated keys can remain separate entries in an ordered list. + Consuming models choose attachment and cardinality. Keys are source names, not a controlled vocabulary. + - Each value of a multivalued source attribute is its own Attribute entry, with the same key, + in source order; one entry never holds a joined list. + - attribute_cv_id and numeric_value follow the NMDC AttributeValue pattern that BERtron and the + KBase CDM use (an optional attribute CURIE plus the raw string, with a typed value), which + this pair can be projected onto later. key and value keep the source's text. + attributes: + key: + title: Key + slot_uri: battr:key + range: string + required: true + description: Source-reported attribute name, unnormalized (for example a GFF tag or metadata key). + value: + title: Value + slot_uri: battr:value + range: string + required: true + description: >- + The source's text for one value, as a string: not typed or normalized, with any escaping + the source format defines decoded (a GFF3 %2C is stored as a comma). + attribute_cv_id: + title: Attribute CV ID + slot_uri: battr:attribute_cv_id + range: uriorcurie + description: >- + A CURIE for what the key means, from an ontology or controlled vocabulary, for example + EDAM:data_1667 (E-value) for both e-value and + evalue. key keeps the source spelling either way. + exact_mappings: + - kb_cdm:attribute_cv_id + numeric_value: + title: Numeric value + slot_uri: battr:numeric_value + range: float + description: >- + value read as a number, only for keys known to be numeric. value + keeps the source text, so 3.4e-28 and 3.40E-28 stay distinguishable. + exact_mappings: + - kb_cdm:numeric_value + - nmdc:numeric_value diff --git a/src/ber_central_schema/schema/ber_central_schema.yaml b/src/ber_central_schema/schema/ber_central_schema.yaml index e0cfc52..531abfc 100644 --- a/src/ber_central_schema/schema/ber_central_schema.yaml +++ b/src/ber_central_schema/schema/ber_central_schema.yaml @@ -5,7 +5,7 @@ title: BRIDGE Central Schema description: >- The central BRIDGE schema for harmonized cross-BER data access. Defines shared base elements and composes domain modules (currently: - measurements.yaml). + measurements.yaml and ber_feature_model.yaml). license: Apache-2.0 see_also: - https://github.com/ber-data/bridge-central-schema @@ -14,6 +14,11 @@ see_also: prefixes: bridge_central_schema: https://w3id.org/ber-data/bridge-central-schema/ linkml: https://w3id.org/linkml/ + # Also declared here: the generated Python leaves out prefixes that only an imported module + # declares when enum meanings use them (the feature model's ContigCollectionTypeEnum and + # ScoreTypeEnum). + MIXS: https://w3id.org/mixs/ + EDAM_DATA: http://edamontology.org/data_ schema: http://schema.org/ default_prefix: bridge_central_schema default_range: string @@ -21,6 +26,7 @@ default_range: string imports: - linkml:types - measurements + - ber_feature_model classes: diff --git a/src/ber_central_schema/schema/ber_feature_model.yaml b/src/ber_central_schema/schema/ber_feature_model.yaml new file mode 100644 index 0000000..21f540f --- /dev/null +++ b/src/ber_central_schema/schema/ber_feature_model.yaml @@ -0,0 +1,739 @@ +id: https://w3id.org/ber-data/gff-feature-model +name: ber-feature-model +title: BER unified feature model (draft) +version: 0.1.0-bridge.2 +description: >- + Draft LinkML model for genome and metagenome sequence features across BER data sources + (NMDC, JGI IMG, KBase). +notes: + - Copied from the feature-table-corpus v0.1.0 release + (https://github.com/turbomam/feature-table-corpus/releases/tag/v0.1.0). The evidence and + decision history behind each element, and the source-specific conversion tooling, stay in + that repository and are not part of this module. + - Derived from v0.1.0, not identical to it. The first bridge copy, 0.1.0-bridge.1, differed + from v0.1.0 in the following ways, all kept here. Dataset is not tree_root; the name slot is display_name with alias name, because the central schema + defines its own name; the EDAM.DATA prefix is EDAM_DATA; and note, dbxref, ontology_term and + taxonomic_lineage are ordered, with the '.' strand described as not stranded + (https://github.com/turbomam/feature-table-corpus/pull/172, after v0.1.0). + - 0.1.0-bridge.2 adds Feature.method and MethodEnum, from + https://github.com/turbomam/feature-table-corpus/pull/169. +license: https://creativecommons.org/publicdomain/zero/1.0/ + +prefixes: + linkml: https://w3id.org/linkml/ + bfm: https://w3id.org/ber-data/gff-feature-model/ + kb_cdm: http://kbase.github.io/cdm-schema/linkml/ + MIXS: https://w3id.org/mixs/ + EDAM_DATA: http://edamontology.org/data_ + biolink: https://w3id.org/biolink/vocab/ + # The IRI Biolink itself uses for GFF3 columns and tags (biolink-model 4.4.4). + gff3: https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md# + faldo: http://biohackathon.org/resource/faldo# + SO: http://purl.obolibrary.org/obo/SO_ + +default_prefix: bfm +default_range: string + +imports: + - linkml:types + - attributes + +classes: + Dataset: + title: Feature dataset + description: A document holding every Contig and Feature harmonized from one or more workflow executions. + slots: + - contig_collections + - contigs + - features + + Contig: + title: Contig + description: A reference sequence, chromosome, scaffold, or contig that features are located on. + slots: + - contig_id + - member_of + - length_bp + - topology + - translation_table + - taxonomic_lineage + - lineage_confidence + - generated_by + - source_files + + ContigCollection: + title: Contig collection + description: A set of contigs that belong together, such as one isolate genome, one metagenome-assembled genome (MAG) bin, or one whole assembly. + exact_mappings: + - kb_cdm:ContigCollection + notes: + - Only isolate, mag, sag and virus collections stand for one organism. A metagenome or + metatranscriptome collection is a whole community, so a same-organism query filters on + collection_type. + - Assembly and bin statistics (N50, CheckM completeness and contamination) are left to + CDM and source catalogues; this model only records membership. + - Maps to the KBase CDM class of the same name (https://github.com/kbase/cdm-schema, + src/linkml/cdm_bioentity.yaml). CDM records the same membership in its + Contig_x_ContigCollection table. + slots: + - collection_id + - collection_type + - display_name + - taxonomic_lineage + - generated_by + - source_files + slot_usage: + collection_id: + identifier: true + + Feature: + title: Feature + description: An annotated sequence interval. + notes: + - Holds gene- and CDS-level calls and the per-database evidence hits (Pfam, COG, KO, EC and + others) that a functional annotation pipeline reports about a gene, linked to the gene + through parent rather than through a second class. + close_mappings: + # SO:0000110 is "any extent of continuous biological sequence"; a Feature can also be a + # joined location or a protein-coordinate hit, so the match is close, not exact. + - SO:0000110 + slots: + - feature_id + - stable_identifiers + - seqid + - source + - type + - method + - start + - end + - coordinate_system + - score + - score_type + - strand + - phase + - parent + - attributes + - generated_by + - source_files + - is_selected + - is_representative + - product + - product_source + - display_name + - note + - dbxref + - ontology_term + - translated_sequence + - location + - target + slot_usage: + feature_id: + identifier: true + display_name: + # On Feature, name is the GFF3 Name; on ContigCollection it is not, so the mappings live here. + exact_mappings: + - gff3:Name + - biolink:name + rules: + - description: A score_type qualifies a score, so it needs one (issue 46). + preconditions: + slot_conditions: + score_type: + value_presence: PRESENT + postconditions: + slot_conditions: + score: + value_presence: PRESENT + + AlignmentTarget: + description: >- + Where a hit aligns on the thing it matched, such as a Pfam model or a reference protein, in + that thing's own positions. GFF3 writes this as the Target and Gap tags. + notes: + - A hit's own start, end and seqid say where it lies on the query; this says where it lies on + the target. + slots: + - target_id + - target_start + - target_end + - target_strand + - gap + + FeatureLocation: + description: Ordered component intervals; authoritative when present, with scalar feature bounds serving only as an indexing envelope. + slots: + - location_operator + - parts + - crosses_origin + + LocationPart: + description: One oriented, reference-qualified interval with explicit endpoint status. + slots: + - seqid + - start + - end + - strand + - start_status + - end_status + slot_usage: + seqid: + range: Contig + description: The contig this part lies on; a part is always in contig coordinates. + strand: + required: true + +slots: + topology: + description: Declared reference topology; circular locations also require length_bp. + range: TopologyEnum + translation_table: + title: Translation table + range: integer + minimum_value: 1 + maximum_value: 33 + description: NCBI genetic code used to translate coding features on this contig, such as 11 for bacteria and archaea or 4 for Mycoplasma. + notes: + - The upper bound is the highest NCBI genetic code identifier in use, 33 + (https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi). Codes 7, 8 and 17 to 20 are + unassigned. + target: + title: Alignment target + description: Where this hit aligns on the thing it matched; absent for features that are not alignments. + range: AlignmentTarget + inlined: true + close_mappings: + # Close: GFF3's Target holds id, start, end and strand; this keeps Gap alongside. + - gff3:Target + target_id: + title: Target ID + required: true + description: What the hit aligned to, as the source names it, such as a Pfam accession or a reference gene ID. + target_start: + title: Target start + range: integer + minimum_value: 1 + required: true + description: First aligned position on the target, one-based and inclusive. + target_end: + title: Target end + range: integer + minimum_value: 1 + required: true + description: Last aligned position on the target, one-based and inclusive. + target_strand: + title: Target strand + range: StrandEnum + description: Strand of the alignment on the target, when the target is a nucleotide sequence. + gap: + title: Gap + description: The alignment in GFF3 Gap form, a CIGAR-like string of operations and lengths. + exact_mappings: + - gff3:Gap + location: + description: Explicit location parts; parent links and BED drawing blocks are separate concepts. + range: FeatureLocation + inlined: true + location_operator: + description: Whether the parts describe one interval, a joined sequence, or ordered intervals without a join assertion. + range: LocationOperatorEnum + required: true + parts: + description: Parts in biological traversal order, including strand orientation. + range: LocationPart + multivalued: true + inlined_as_list: true + list_elements_ordered: true + required: true + minimum_cardinality: 1 + crosses_origin: + description: True only when traversal crosses the origin of a known-length circular reference. + range: boolean + required: true + start_status: + description: Exact lower endpoint or a bound before or after the reported coordinate. + range: EndpointStatusEnum + required: true + end_status: + description: Exact upper endpoint or a bound before or after the reported coordinate. + range: EndpointStatusEnum + required: true + contig_collections: + title: Contig collections + multivalued: true + inlined_as_list: true + range: ContigCollection + description: Every ContigCollection that this dataset's Contigs name in member_of. + contigs: + title: Contigs + multivalued: true + inlined_as_list: true + range: Contig + description: Every Contig referenced by this dataset's Features. + features: + title: Features + multivalued: true + inlined_as_list: true + range: Feature + description: Every Feature in this dataset. + + contig_id: + title: Contig ID + identifier: true + description: Native NMDC or source-system identifier for the contig or scaffold. + member_of: + title: Member of + multivalued: true + range: ContigCollection + description: Contig collections this contig belongs to, for example its isolate genome, or both its assembly and its MAG bin. + notes: + - Multivalued because one metagenome contig belongs to its assembly and can also be binned + into a MAG. Membership in a bin is a statement by the binning workflow, so the bin's + own generated_by names that workflow rather than the assembly. + collection_id: + title: Collection ID + description: Identifier of the genome, bin or assembly, from the system that defined it. + notes: + - Examples are an NMDC assembly workflow execution (nmdc:wfmgas-...), an NMDC MAG bin name, + or a JGI IMG taxon or Data Portal record. Use a CURIE when the identifier has one. + collection_type: + title: Collection type + range: ContigCollectionTypeEnum + description: What kind of contig collection this is. + display_name: + # Renamed from name in this copy: the root schema defines a name slot, and LinkML refuses two + # imported slots with one name. alias keeps the data key as name. Open question in the PR. + alias: name + title: Name + description: >- + Human-readable name, not an identifier and not unique: for a contig collection an organism + and strain or a bin label; for a feature the GFF3 Name, its display name. + note: + exact_mappings: + - gff3:Note + title: Note + multivalued: true + list_elements_ordered: true + description: GFF3 Note values, free-text remarks about the feature, in source order. + dbxref: + exact_mappings: + - gff3:Dbxref + broad_mappings: + - biolink:xref + title: Database cross-reference + multivalued: true + list_elements_ordered: true + description: >- + GFF3 Dbxref values, db:id references to records in other databases, in source order. Unlike + stable_identifiers, a cross-reference can point at a related record rather than at this + feature itself, such as a GeneID on a CDS. + ontology_term: + exact_mappings: + - gff3:Ontology_term + title: Ontology term + multivalued: true + list_elements_ordered: true + description: GFF3 Ontology_term values, ontology term CURIEs such as GO:0003677, in source order. + length_bp: + title: Length (bp) + range: integer + minimum_value: 1 + description: Contig length in base pairs. + notes: + - Compute directly from the contig's own FASTA record where there is one, not from a + summary statistics file, so it is exact rather than an average. + taxonomic_lineage: + title: Taxonomic lineage + multivalued: true + list_elements_ordered: true + description: Ranked lineage path, domain to strain, one string per rank. + notes: + - Left as a list rather than named rank slots (domain, phylum, class, ...), because + forcing a fixed depth breaks on any lineage reported at a different resolution. + Confirmed 2026-09-18 on one real run, per-contig lineage (Scaffold Lineage tsv) and + per-gene lineage (Gene Phylogeny tsv) for the same organism were reported at + different depths, 2 ranks versus 8. + lineage_confidence: + title: Lineage confidence + range: float + description: Confidence value reported alongside the lineage call. + notes: + - Meaning unverified against any pipeline's own documentation; treat the name as + descriptive, not confirmed. + + feature_id: + close_mappings: + - gff3:ID + title: Feature ID + description: Identifier unique within its Dataset. + notes: + - Uniqueness is a rule for the Dataset, not a property of sources; some sources repeat an ID + within one file. + - feature_id is a file-local key, not a globally unique persistent identifier. GFF3 IDs are + not stable identifiers; use stable_identifiers for those. + stable_identifiers: + title: Stable identifiers + multivalued: true + description: Identifiers an authority assigns to this feature and keeps across releases, as opposed to feature_id, which only needs to be unique within this Dataset. + notes: + - NMDC annotation files carry no such identifier for their own genes. The IMG gene oid in + the KO and EC files (column 2 of Annotation KEGG Orthology, subject_gene_ids in KO_EC + Annotation GFF) identifies the reference gene the query was aligned to, not the + annotated gene, so it does not belong here. Checked 2026-09-25 on + nmdc:wfmgan-11-grwgtd27.2, where both files give 2776147680 for the hit of + nmdc:wfmgan-11-grwgtd27.2_0016_3_1208. + - Use a CURIE when a prefix exists, such as an NCBI GeneID. A locus tag has no registered + prefix and is written as it appears; list both current and legacy locus tags. + seqid: + exact_mappings: + - gff3:seqid + title: Sequence ID + any_of: + - range: Contig + - range: Feature + required: true + description: >- + The reference sequence that start and end are measured along, such as GFF3 column 1 or BED + chrom; interpreted within its assembly context. A contig for contig coordinates; for + protein coordinates, the CDS whose translation they count residues of. + notes: + - A protein-coordinate feature's parent is the same CDS. LocationPart.seqid stays a Contig. + - For a hit reported in protein coordinates, seqid names the protein, because GFF3 column 1 is + the landmark that establishes the coordinate system. + source: + exact_mappings: + - gff3:source + title: Source + description: GFF3 column 2, the producing tool and version, e.g. "Prodigal v2.6.3_patched". + notes: + - Measured 2026-09-11 across 14 real NMDC GFF file types, blank in 3 of them (SMART, + TIGRFAM, COG). A blank value is expected, not an error. + - Confirmed 2026-09-18 on a real run, a workflow's own Annotation Info File sidecar + names the exact database versions (e.g. "TIGRFAM v15.0", "SMART 01_06_2016") even + where the individual GFF's own source column is empty; use `generated_by` plus that + sidecar for full provenance when this is blank. + type: + exact_mappings: + - gff3:type + title: Type + description: GFF3 column 3, nominally a Sequence Ontology term or accession. + notes: + - Range left as a plain string rather than SO-constrained. Measured 2026-09-11, 7 of 14 + real NMDC GFF file types put a bare database accession here instead (Pfam, COG, + TIGRFAM, SMART, and others); an SO-constrained range would reject real production + data. Unresolved from the 2026-09-11 kickoff, whether CURIEs should be required going + forward even though today's data does not comply. + - Confirmed 2026-09-18, the inconsistency runs both directions. A real RFAM/INFERNAL + ncRNA hit used the generic term "misc_feature" here and put its actual identity (an + Rfam covariance model accession) in a lowercase `model`/`accession` attribute pair + instead, an accession where an SO term is expected in one case, a generic placeholder + where an accession would be more specific in another. + method: + title: Method + range: MethodEnum + description: >- + The annotation method or reference database whose search produced this feature, such as + Pfam or KEGG Orthology. + notes: + - Distinct from source, which is the tool and version (GFF3 column 2), and from + generated_by, which is the run. Set it on evidence hits; leave it unset on gene and RNA + calls, where source already names the caller. + - feature_id has no required format, which is why method is a separate slot to filter on. + The IMG per-method converter forms a hit's feature_id as ||, and + when method is set on such a hit it equals that middle part, except for TMHMM and SignalP + hits, whose feature_id carries the IMG file suffixes tmh and cleavage_sites while method + is tmhmm or signalp. Other data, such as tests/data/valid/Dataset-002.yaml, ends hit IDs + in source-specific suffixes such as _pfam and _cath, which are not always MethodEnum + values (_cath is cath_funfam), so a method taken from a feature_id needs mapping. + - Added so one table can hold every method's hits and still be filtered or partitioned by + method. Before it, the method was only inside feature_id, and two converters spelled + SUPERFAMILY hits differently (supfam and superfamily). + start: + exact_mappings: + - gff3:start + - biolink:start_coordinate + close_mappings: + - faldo:begin + title: Start + range: integer + required: true + minimum_value: 1 + description: 1-based inclusive start; when location is present this is only the minimum reported part coordinate, not a claim that gaps are occupied. + end: + exact_mappings: + - gff3:end + - biolink:end_coordinate + close_mappings: + - faldo:end + title: End + range: integer + required: true + minimum_value: 1 + description: 1-based inclusive end, always >= start; when location is present this is only the maximum reported part coordinate. + coordinate_system: + title: Coordinate system + range: CoordinateSystemEnum + required: true + description: Which coordinate space `start`/`end` are measured in. + notes: + - Added 2026-09-18 after measuring a real functional-annotation hit against its own + parent's translated protein length, a Pfam hit on a 159-residue protein reported + start=61, end=136, alignment_length=76 (matching end-start+1 exactly in amino acids, + not nucleotides), so the hit's coordinates are protein-relative while its parent + CDS's own start/end are contig-relative. A table mixing both kinds of row without + this field would silently let one be misread as the other. + score: + exact_mappings: + - gff3:score + title: Score + range: float + description: GFF3 column 6. + notes: + - The GFF3 specification itself says the semantics of the score are ill-defined. + Meaning is tool-specific (an HMMER bit score, a Prodigal confidence value, and so + on); do not compare scores across different `source` values. + score_type: + title: Score type + range: ScoreTypeEnum + description: What kind of number score is. + notes: + - Leave it unset when no source states what the score means. Unset says the meaning is + not recorded, not that the score is generic. + strand: + exact_mappings: + - gff3:strand + - biolink:strand + title: Strand + range: StrandEnum + description: GFF3 column 7. + phase: + exact_mappings: + - gff3:phase + - biolink:phase + title: Phase + range: integer + minimum_value: 0 + maximum_value: 2 + description: GFF3 column 8. One of 0, 1, 2; only meaningful when type is CDS. + notes: + - Measured 2026-09-11, 366 of 368 real values are 0, so a handler that mishandles 1 + and 2 will still pass almost all real-data testing. + parent: + exact_mappings: + - gff3:Parent + title: Parent + multivalued: true + range: Feature + description: GFF3 column-9 Parent tag(s). + notes: + - Multivalued because one feature can belong to several parents, such as an exon + shared by multiple transcripts. This differs from a discontinuous feature, + which repeats the same ID across multiple GFF3 lines. + - The 2026-09-17 BRIDGE discussion confirmed that this relationship does not + have to be flattened into a join table. + attributes: + title: Attributes + # Close, not exact: column 9 is one text field, and this is its ordered key/value pairs. + close_mappings: + - gff3:attributes + multivalued: true + inlined_as_list: true + list_elements_ordered: true + range: Attribute + description: Additional source annotations, metadata, and evidence, including GFF tags not given their own slots. + notes: + - See the Attribute class description for why this stays generic rather than typed. + generated_by: + title: Generated by + description: The workflow execution (or tool run) that produced this ContigCollection, Contig or Feature. + notes: + - Confirmed 2026-09-18 against a real biosample's full sequencing, a Contig and the + Features on it typically come from two DIFFERENT workflow executions, not one. A + metagenome assembly workflow (e.g. nmdc:wfmgas-11-19jh9v28.1) produces the Contig; a + separate annotation workflow run against that assembly (e.g. + nmdc:wfmgan-11-5xxrm214.2) produces the Feature rows on it. Do not assume one + workflow execution id covers both. + source_files: + title: Source files + range: uri + multivalued: true + description: Source artifact URLs supporting this record, including any annotation sidecars used. + notes: + - A sidecar may come from a different workflow than generated_by, for example annotation + lineage on an assembled Contig. Preserve each artifact's workflow in its URL or manifest. + is_selected: + title: Is selected + range: boolean + description: Whether the annotation pipeline chose this call as canonical for its locus. + notes: + - "Open question, found 2026-09-18 in that same worked case: is_selected=false does not + always mean \"a competing caller won\". One real Prodigal call there + (nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_3_65) had no GeneMark call at all for the same + locus, and still did not appear in the roll-up, most plausibly filtered for length or + confidence. This schema does not yet distinguish \"lost to a competitor\" from + \"filtered despite no competitor\"; a future revision may need a second field, or an + enum instead of a boolean." + is_representative: + title: Is representative + range: boolean + description: >- + Whether the source names this transcript as its gene's representative isoform, the one to + use when a query wants a single transcript per gene. + notes: + - Unset means the source does not say; set false only where the source says so. A marked + feature needs a parent (its gene), and a gene has at most one representative. + - Different from is_selected, which records which competing call an annotation pipeline kept + for a locus, not which of a gene's isoforms stands for it. + product: + title: Product + description: Human-readable functional product name for a gene, e.g. "transposase". + notes: + - Populated once, on the gene-level feature; not repeated per functional-evidence hit. + product_source: + title: Product source + description: What justified the product call, e.g. a COG accession or "Hypo-rule applied". + notes: + - Measured 2026-09-18, identical byte for byte to the parallel Product Names sidecar + file for every protein-coding gene checked so far. Use this slot or that file, never + both, so the same product assignment is never recorded twice under two different + provenance stories. + translated_sequence: + title: Translated sequence + description: Amino-acid translation of a CDS feature, from the workflow's protein FASTA output. + notes: + - Not available anywhere else in structured form; GFF files reference a CDS by + coordinate but never carry its sequence. + - Confirmed 2026-09-18, this can legitimately be absent even for a real gene call. One + short, partial Prodigal call had no entry at all in Annotation Amino Acid FASTA, + apparently filtered before translation; treat a missing value as informative, not as + a data gap to fill in. + +enums: + ContigCollectionTypeEnum: + title: Contig collection type + description: Kind of contig collection, using the values and descriptions of KBase CDM ContigCollectionType. + notes: + - Values copied from kbase/cdm-schema src/linkml/cdm_bioentity.yaml at commit c1a59b9 (read + 2026-09-25), which takes them from Genomics Standards Consortium checklists. + - Each meaning is a MIxS checklist (MIXS:0010011 is MIMAG, the checklist for a MAG + submission), as CDM has it, not a term for the kind of genome itself. + permissible_values: + isolate: + description: Sequences assembled from DNA of isolated organism. + mag: + title: Metagenome-Assembled Genome + description: Sequences assembled from DNA of mixed community and binned. + meaning: MIXS:0010011 + metagenome: + description: Sequences assembled from DNA of mixed community. + meaning: MIXS:0010007 + metatranscriptome: + description: Sequences assembled from RNA of mixed community. + sag: + title: Single Amplified Genome + description: Sequences assembled from DNA of single cell. + meaning: MIXS:0010010 + virus: + description: Sequences assembled from uncultivated virus genome (DNA/RNA). + meaning: MIXS:0010012 + marker: + description: Sequences from targeted region of DNA. + ScoreTypeEnum: + title: Score type + description: Kind of number in a feature's score column. + notes: + - EDAM terms checked in OLS on 2026-09-25; none is obsolete. + permissible_values: + bit_score: + description: A score normalised so that scores from different searches compare, in bits. + meaning: EDAM_DATA:2335 + e_value: + description: Expected number of hits at least this good by chance. + meaning: EDAM_DATA:1667 + p_value: + description: Probability of a result at least this extreme by chance. + meaning: EDAM_DATA:1669 + score: + description: A tool-specific score of no more specific kind. + meaning: EDAM_DATA:1772 + MethodEnum: + title: Method + description: Annotation method or reference database that produced an evidence hit. + permissible_values: + pfam: + description: Pfam protein families, https://www.ebi.ac.uk/interpro/entry/pfam/ + cog: + description: Clusters of Orthologous Genes, https://www.ncbi.nlm.nih.gov/research/cog/ + tigrfam: + description: TIGRFAMs protein families, https://www.ncbi.nlm.nih.gov/genome/annotation_prok/tigrfams/ + smart: + description: SMART protein domains, https://smart.embl.de/ + supfam: + description: SUPERFAMILY structural domain assignments, https://supfam.org/ + cath_funfam: + description: CATH functional families (FunFams), https://www.cathdb.info/ + ko_ec: + description: KEGG Orthology assignments and the EC numbers that come with them, https://www.genome.jp/kegg/ko.html + tmhmm: + description: TMHMM transmembrane helix predictions. + signalp: + description: SignalP signal peptide predictions. + TopologyEnum: + description: Reference topology used by location validation and distance queries. + permissible_values: + linear: + description: Linear reference with no origin wrap. + circular: + description: Circular reference whose final base is adjacent to base one. + LocationOperatorEnum: + description: Relationship between ordered location parts. + permissible_values: + single: + description: One interval. + join: + description: Parts are joined end to end. + order: + description: Parts have known order without asserting a joined sequence. + EndpointStatusEnum: + description: Relationship of the true endpoint to the reported position. + permissible_values: + exact: + description: Exact coordinate. + before: + description: Endpoint is before the reported coordinate, possibly outside the presented sequence. + after: + description: Endpoint is after the reported coordinate, possibly outside the presented sequence. + StrandEnum: + title: Strand + description: GFF3 column-7 strand values. + notes: + - "Permissible value names are the literal GFF3 symbols (+, -, ., ?), not word forms + (Plus, Minus, ...), so a value here round-trips to a real GFF3 file unchanged. + linkml-lint's standard_naming and permissible_values_format checks both flag these + four as non-conforming (not uppersnake-case); that is a deliberate exception, not an + oversight, since a word form would be less faithful to the source format this schema + exists to represent." + - "Consequence, confirmed 2026-09-18 by running gen-pydantic against this schema: the + generated Python Enum member for the minus strand is named `_` + (StrandEnum('-') is StrandEnum._), Python's conventional throwaway name, because + pydantic generation can't turn a bare '-' into a valid identifier. Anyone writing code + against a generated model will hit this; it's a consequence of the choice above, not a + new problem, but worth knowing before it surprises someone." + permissible_values: + "+": + description: Plus/forward strand. + "-": + description: Minus/reverse strand. + ".": + description: Not stranded (GFF3 default). + "?": + description: Strand is relevant but unknown (GFF3 allowance). + CoordinateSystemEnum: + title: Coordinate system + description: Which coordinate space a Feature's start/end are measured in. + permissible_values: + contig: + description: start/end are nucleotide positions on the referenced Contig. + protein: + description: >- + start/end are amino-acid positions within the parent feature's translated + sequence, not nucleotide positions on any contig. diff --git a/tests/data/invalid/AlignmentTarget-missing-target-id.yaml b/tests/data/invalid/AlignmentTarget-missing-target-id.yaml new file mode 100644 index 0000000..0dbb060 --- /dev/null +++ b/tests/data/invalid/AlignmentTarget-missing-target-id.yaml @@ -0,0 +1,3 @@ +# A Pfam hit's alignment target from Dataset-004 without its required target_id. +target_start: 2 +target_end: 135 diff --git a/tests/data/invalid/Attribute-missing-value.yaml b/tests/data/invalid/Attribute-missing-value.yaml new file mode 100644 index 0000000..d6f843f --- /dev/null +++ b/tests/data/invalid/Attribute-missing-value.yaml @@ -0,0 +1,2 @@ +# The Name attribute of the first Pfam hit in Dataset-001 without its required value. +key: Name diff --git a/tests/data/invalid/Contig-zero-length.yaml b/tests/data/invalid/Contig-zero-length.yaml new file mode 100644 index 0000000..e6a0a1e --- /dev/null +++ b/tests/data/invalid/Contig-zero-length.yaml @@ -0,0 +1,4 @@ +# The phiX174 contig from Dataset-003 with length_bp 0; length_bp must be at least 1. +contig_id: insdc:NC_001422.1 +length_bp: 0 +topology: circular diff --git a/tests/data/invalid/ContigCollection-unknown-type.yaml b/tests/data/invalid/ContigCollection-unknown-type.yaml new file mode 100644 index 0000000..92e7d04 --- /dev/null +++ b/tests/data/invalid/ContigCollection-unknown-type.yaml @@ -0,0 +1,6 @@ +# The collection from Dataset-002 with collection_type 'assembly', not a ContigCollectionTypeEnum value. +collection_id: nmdc:wfmgas-11-19jh9v28.1 +collection_type: assembly +generated_by: nmdc:wfmgas-11-19jh9v28.1 +source_files: +- https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgas-11-19jh9v28.1/nmdc_wfmgas-11-19jh9v28.1_contigs.fna diff --git a/tests/data/invalid/Dataset-invalid-method.yaml b/tests/data/invalid/Dataset-invalid-method.yaml new file mode 100644 index 0000000..0b1a831 --- /dev/null +++ b/tests/data/invalid/Dataset-invalid-method.yaml @@ -0,0 +1,18 @@ +# A Pfam-style hit whose method is not a MethodEnum value: "superfamily" rather than "supfam". +features: + - feature_id: example:cds_1 + seqid: example:contig_1 + type: CDS + start: 1 + end: 300 + coordinate_system: contig + strand: "+" + - feature_id: example:cds_1|superfamily|47473 + seqid: example:cds_1 + type: "47473" + method: superfamily + start: 5 + end: 90 + coordinate_system: protein + parent: + - example:cds_1 diff --git a/tests/data/invalid/Dataset-undeclared-slot.yaml b/tests/data/invalid/Dataset-undeclared-slot.yaml new file mode 100644 index 0000000..9ebdcb5 --- /dev/null +++ b/tests/data/invalid/Dataset-undeclared-slot.yaml @@ -0,0 +1,10 @@ +# A Feature with an undeclared slot; the feature model's classes are closed. +features: + - feature_id: example:cds_1 + seqid: example:contig_1 + type: CDS + start: 1 + end: 30 + coordinate_system: contig + strand: "+" + gene_symbol: abcD diff --git a/tests/data/invalid/FeatureLocation-unknown-operator.yaml b/tests/data/invalid/FeatureLocation-unknown-operator.yaml new file mode 100644 index 0000000..ed0051b --- /dev/null +++ b/tests/data/invalid/FeatureLocation-unknown-operator.yaml @@ -0,0 +1,16 @@ +# A joined phiX174 location from Dataset-003 with location_operator 'union', not a LocationOperatorEnum value. +location_operator: union +parts: +- seqid: insdc:NC_001422.1 + start: 3981 + end: 5386 + start_status: exact + end_status: exact + strand: + +- seqid: insdc:NC_001422.1 + start: 1 + end: 136 + start_status: exact + end_status: exact + strand: + +crosses_origin: true diff --git a/tests/data/invalid/LocationPart-zero-start.yaml b/tests/data/invalid/LocationPart-zero-start.yaml new file mode 100644 index 0000000..343c50c --- /dev/null +++ b/tests/data/invalid/LocationPart-zero-start.yaml @@ -0,0 +1,7 @@ +# A phiX174 location part from Dataset-003 with start 0; coordinates are one-based, so start must be at least 1. +seqid: insdc:NC_001422.1 +start: 0 +end: 5386 +start_status: exact +end_status: exact +strand: + diff --git a/tests/data/valid/Dataset-001.yaml b/tests/data/valid/Dataset-001.yaml new file mode 100644 index 0000000..004adf9 --- /dev/null +++ b/tests/data/valid/Dataset-001.yaml @@ -0,0 +1,110 @@ +# Real NMDC data: one CDS from annotation nmdc:wfmgan-11-5xxrm214.2 and its three Pfam hits, from +# https://github.com/turbomam/feature-table-corpus/blob/v0.1.0/model/examples/multiple-pfams/harmonized.yaml (CC BY 4.0). +contigs: +- contig_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1 + length_bp: 1173 + generated_by: nmdc:wfmgas-11-19jh9v28.1 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgas-11-19jh9v28.1/nmdc_wfmgas-11-19jh9v28.1_contigs.fna +features: +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1 + source: Prodigal v2.6.3_patched + type: CDS + start: 63 + end: 1091 + coordinate_system: contig + score: 76.5 + strand: '-' + phase: 0 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_prodigal.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_functional_annotation.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_proteins.faa + product: transposase + product_source: COG3415/COG3335 + translated_sequence: MRQNDARQLSHDMLEDMRRRAVTAVQEGQSPEAVGKAFGLNRTTIYDWLAQYRRGGWGALKAKPLAGRPPKLNGKQMKWIYNTVTQKNPLQMKFEFALWTRAMVAKLIKDKFGIRLATNSVGRLLAQLGITPQRPLYQALERDPSLVKKWLKTEFPKIKKAAETLGADIYFGDAAHIRSDHHAGRTWGKKGETPIVVTTGARHGMSLLSAITSKGHMRFMIKEKGGVNSDVFIEFLKRLLVGAKRPVFLIVDRGPAHISKKTKAFVATLGSRLKLFYLPAYSPDRNPDELVWKHLKADTVGRMVTTSKADFKSKVVSSMRSLQKTPEKIRSFFQKPSLQYAA +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_168_312 + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + source: HMMER 3.1b2 (February 2015) + type: PF13358 + # `name` is the key the display_name slot reads, through alias: name. + name: DDE_3 + start: 168 + end: 312 + coordinate_system: protein + method: pfam + score: 94.0 + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_pfam.gff + attributes: + - key: Name + value: DDE_3 + - key: fake_percent_id + value: '25.23' + - key: alignment_length + value: '145' + - key: e-value + value: '3.4e-28' + - key: model_start + value: '2' + - key: model_end + value: '135' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_95_154 + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + source: HMMER 3.1b2 (February 2015) + type: PF13592 + start: 95 + end: 154 + coordinate_system: protein + method: pfam + score: 64.0 + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_pfam.gff + attributes: + - key: Name + value: HTH_33 + - key: fake_percent_id + value: '25.23' + - key: alignment_length + value: '60' + - key: e-value + value: '3.4e-19' + - key: model_start + value: '1' + - key: model_end + value: '59' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_17_70 + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + source: HMMER 3.1b2 (February 2015) + type: PF13518 + start: 17 + end: 70 + coordinate_system: protein + method: pfam + score: 42.5 + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_pfam.gff + attributes: + - key: Name + value: HTH_28 + - key: fake_percent_id + value: '25.23' + - key: alignment_length + value: '54' + - key: e-value + value: '2.4e-12' + - key: model_start + value: '2' + - key: model_end + value: '51' diff --git a/tests/data/valid/Dataset-002.yaml b/tests/data/valid/Dataset-002.yaml new file mode 100644 index 0000000..0ea117c --- /dev/null +++ b/tests/data/valid/Dataset-002.yaml @@ -0,0 +1,390 @@ +# Real NMDC data: three contigs of metagenome assembly nmdc:wfmgas-11-19jh9v28.1, their +# contig collection, and 15 features from annotation nmdc:wfmgan-11-5xxrm214.2 (CC BY 4.0), from +# https://github.com/turbomam/feature-table-corpus/blob/v0.1.0/model/examples/one-biosample-sequencing/harmonized.yaml +contig_collections: +- collection_id: nmdc:wfmgas-11-19jh9v28.1 + collection_type: metagenome + generated_by: nmdc:wfmgas-11-19jh9v28.1 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgas-11-19jh9v28.1/nmdc_wfmgas-11-19jh9v28.1_contigs.fna +contigs: +- contig_id: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1 + member_of: + - nmdc:wfmgas-11-19jh9v28.1 + translation_table: 11 + generated_by: nmdc:wfmgas-11-19jh9v28.1 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgas-11-19jh9v28.1/nmdc_wfmgas-11-19jh9v28.1_contigs.fna + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_scaffold_lineage.tsv + length_bp: 1754 + taxonomic_lineage: + - Bacteria + - Pseudomonadota + lineage_confidence: 0.667 +- contig_id: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1 + member_of: + - nmdc:wfmgas-11-19jh9v28.1 + translation_table: 11 + generated_by: nmdc:wfmgas-11-19jh9v28.1 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgas-11-19jh9v28.1/nmdc_wfmgas-11-19jh9v28.1_contigs.fna + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_scaffold_lineage.tsv + length_bp: 1624 + taxonomic_lineage: + - Bacteria + - Acidobacteriota + - Terriglobia + - Terriglobales + - Acidobacteriaceae + lineage_confidence: 1.0 +- contig_id: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1 + member_of: + - nmdc:wfmgas-11-19jh9v28.1 + generated_by: nmdc:wfmgas-11-19jh9v28.1 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgas-11-19jh9v28.1/nmdc_wfmgas-11-19jh9v28.1_contigs.fna + length_bp: 369 +features: +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_prodigal.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_structural_annotation.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_functional_annotation.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_gene_phylogeny.tsv + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_proteins.faa + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_genemark.gff + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1 + source: Prodigal v2.6.3_patched + type: CDS + start: 104 + end: 853 + coordinate_system: contig + score: 85.0 + strand: '-' + phase: 0 + is_selected: true + product: 3-oxoacyl-[acyl-carrier protein] reductase + product_source: KO:K00059 + translated_sequence: MKRLDNKVAIVTGASKGIGAGIAKAFGAEGAAVVVNYARDHEGAERVVREITGKGGRAIAVQGDVAQRSDAQRLVAEAKKAFGRLDVLVNNAGVFSFAPFEQFSEQEFHRQFNTNVLGMFLMIEAALPAFGAEGGSIINIGSTTSATAYPALSIYVASKSAVNGLTRVLSKEFGPRKIRVNALNPGGTETEGAHAAGVMGAEAKKQIIASTPLGRVGQPEDIARVAVFLASDDAGWLTGEIIFANGGNK + attributes: + - key: translation_table + value: '11' + - key: start_type + value: ATG + - key: genemark_agreement + value: GeneMark called the identical 104-853 boundary independently (score 66.84 vs Prodigal's 85.0); + not instantiated as a separate Feature here since the coordinates are identical, not a competing + claim + - key: phylogeny_subject_gene_ids + value: 2698062542;2695420919 + - key: phylogeny_percent_identity + value: '93.98' + - key: phylogeny_lineage + value: Bacteria;Pseudomonadota;Alphaproteobacteria;Hyphomicrobiales;Nitrobacteraceae;Bradyrhizobium;Bradyrhizobium + erythrophlei;Bradyrhizobium erythrophlei GAS401 +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853_ko_ec + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_ko_ec.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_imgap.info + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + source: lastal 1456 + type: KO:K00059__EC:1.1.1.100 + start: 1 + end: 249 + coordinate_system: protein + score: 518 + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + attributes: + - key: subject_gene_ids + value: '2698062542' + - key: evalue + value: '9.2e-163' + - key: percent_identity + value: '93.98' + - key: alignment_length + value: '249' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853_cog + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_cog.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_imgap.info + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + source: HMMER 3.1b2 (February 2015) + type: COG1028 + start: 2 + end: 248 + coordinate_system: protein + score: 239.1 + score_type: bit_score + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + attributes: + - key: fake_percent_id + value: '98.88' + - key: alignment_length + value: '247' + - key: independent_domain_e-value + value: '2.9e-72' + - key: full_sequence_e-value + value: '2.3e-72' + - key: full_sequence_bitscore + value: '239.4' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853_cath + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_cath_funfam.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_imgap.info + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + source: HMMER 3.1b2 (February 2015) + type: 3.40.50.720 + start: 3 + end: 249 + coordinate_system: protein + score: 290.3 + score_type: bit_score + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + attributes: + - key: fake_percent_id + value: '98.39' + - key: alignment_length + value: '247' + - key: independent_domain_e-value + value: '4.6e-88' + - key: full_sequence_e-value + value: '4.1e-88' + - key: full_sequence_bitscore + value: '290.5' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853_pfam + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_pfam.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_imgap.info + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + source: HMMER 3.1b2 (February 2015) + type: PF13561 + start: 13 + end: 249 + coordinate_system: protein + score: 220.8 + score_type: bit_score + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + attributes: + - key: Name + value: adh_short_C2 + - key: fake_percent_id + value: '99.22' + - key: alignment_length + value: '237' + - key: e-value + value: '8.3e-67' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853_supfam + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_supfam.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_imgap.info + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + source: HMMER 3.1b2 (February 2015) + type: '51735' + start: 5 + end: 248 + coordinate_system: protein + score: 280.3 + score_type: bit_score + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_104_853 + attributes: + - key: fake_percent_id + value: '97.57' + - key: alignment_length + value: '244' + - key: independent_domain_e-value + value: '6.4e-85' + - key: full_sequence_e-value + value: '5.2e-85' + - key: full_sequence_bitscore + value: '280.6' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1_3_866 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_prodigal.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_structural_annotation.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_functional_annotation.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_gene_phylogeny.tsv + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_proteins.faa + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1 + source: Prodigal v2.6.3_patched + type: CDS + start: 3 + end: 866 + coordinate_system: contig + score: 71.4 + strand: '-' + phase: 0 + is_selected: true + product: RNA-directed DNA polymerase + product_source: KO:K00986 + translated_sequence: MHENRETSEAPAAKHCGRTAGEGSSRTARMYIFEESDSGIIPMNHSNKDGKPYAESEEGRPLIKENTHQPSTYPTQSEKRVSQGLAGVRKAAKDNKEMKFTALLHHLTIDLLRDSFYALKRKAAPGVDGVTWQEYETGLQDRLVDLHSRVHRGAYRAKPSRRVYIEKEDGRQRPLGVAALEDKVVQQAVVTILNQIYEEDFLGFSYGFRPGRSQHQALDALSYALLRKKVNYVLDADIRGFFDNLDKSWLIKFVEHRVADPRILRLIQKWLNAGVMEEGKWSEMKTGT + attributes: + - key: translation_table + value: '11' + - key: partial + value: 3' + - key: phylogeny_subject_gene_ids + value: '2841323647' + - key: phylogeny_percent_identity + value: '79.86' + - key: phylogeny_lineage + value: Bacteria;Acidobacteriota;Terriglobia;Terriglobales;Acidobacteriaceae;Acidisarcina;Acidisarcina + polymorpha;Acidisarcina polymorpha SBC82 +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1_3_740 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_genemark.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_structural_annotation.gff + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1 + source: GeneMark.hmm-2 v1.25_lic + type: CDS + start: 3 + end: 740 + coordinate_system: contig + score: 33.69 + strand: '-' + phase: 0 + is_selected: false + attributes: + - key: translation_table + value: '11' + - key: partial + value: 3' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1_3_866_ko_ec + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_ko_ec.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_imgap.info + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1_3_866 + source: lastal 1456 + type: KO:K00986__EC:2.7.7.49 + start: 1 + end: 288 + coordinate_system: protein + score: 532 + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_2_c1_3_866 + attributes: + - key: subject_gene_ids + value: 2841323647;2841327450;2841327638 + - key: evalue + value: '2.7e-166' + - key: percent_identity + value: '79.86' + - key: alignment_length + value: '288' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1_3_65 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_prodigal.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_structural_annotation.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_genemark.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_proteins.faa + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_1_c1 + source: Prodigal v2.6.3_patched + type: CDS + start: 3 + end: 65 + coordinate_system: contig + score: 13.0 + strand: '-' + phase: 0 + is_selected: false + attributes: + - key: translation_table + value: '11' + - key: partial + value: 3' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1_887_1104 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_rfam.gff + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_2_c1 + source: INFERNAL 1.1.3 (Nov 2019) + type: misc_feature + start: 887 + end: 1104 + coordinate_system: contig + score: 170.0 + strand: '-' + attributes: + - key: e-value + value: '2.1e-53' + - key: model + value: RF02005 + - key: accession + value: group-II-D1D4-6 + - key: note + value: Group II catalytic intron D1-D4-6 +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1_76_183 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_crt.gff + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1 + source: CRT 1.8.4 + type: CRISPR + start: 76 + end: 183 + coordinate_system: contig + strand: . + attributes: + - key: number_of_repeats + value: '3' + - key: average_repeat_length + value: '20' + - key: median_repeat_length + value: '20' + - key: average_spacer_length + value: '24' + - key: median_spacer_length + value: '22' +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1_76_183_DR1 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_crt.gff + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1 + source: CRT 1.8.4 + type: repeat_unit + start: 76 + end: 95 + coordinate_system: contig + strand: . + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_344_c1_76_183 +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1_76_183_DR2 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_crt.gff + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1 + source: CRT 1.8.4 + type: repeat_unit + start: 118 + end: 137 + coordinate_system: contig + strand: . + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_344_c1_76_183 +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1_76_183_DR3 + generated_by: nmdc:wfmgan-11-5xxrm214.2 + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_crt.gff + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_344_c1 + source: CRT 1.8.4 + type: repeat_unit + start: 164 + end: 183 + coordinate_system: contig + strand: . + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_344_c1_76_183 diff --git a/tests/data/valid/Dataset-003.yaml b/tests/data/valid/Dataset-003.yaml new file mode 100644 index 0000000..d3cbb73 --- /dev/null +++ b/tests/data/valid/Dataset-003.yaml @@ -0,0 +1,918 @@ +# Real NCBI RefSeq data: Enterobacteria phage phiX174, NC_001422.1, converted with the +# insdc-locations/1.0.0 profile from https://github.com/turbomam/feature-table-corpus/blob/v0.1.0/corpus/sources/ncbi-refseq/NC_001422.1_2026-09-21.gb . +# Joined locations, some crossing the origin of the circular genome. +contigs: +- contig_id: insdc:NC_001422.1 + length_bp: 5386 + topology: circular +features: +- feature_id: insdc:NC_001422.1:feature-1 + seqid: insdc:NC_001422.1 + type: source + coordinate_system: contig + start: 1 + end: 5386 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 1 + end: 5386 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: organism + value: Escherichia phage phiX174 + - key: mol_type + value: genomic DNA + - key: db_xref + value: taxon:2886930 +- feature_id: insdc:NC_001422.1:feature-2 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 1 + end: 5386 + strand: + + location: + location_operator: join + parts: + - seqid: insdc:NC_001422.1 + start: 3981 + end: 5386 + start_status: exact + end_status: exact + strand: + + - seqid: insdc:NC_001422.1 + start: 1 + end: 136 + start_status: exact + end_status: exact + strand: + + crosses_origin: true + attributes: + - key: locus_tag + value: phiX174p01 + - key: db_xref + value: GeneID:2546398 +- feature_id: insdc:NC_001422.1:feature-3 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 1 + end: 5386 + strand: + + location: + location_operator: join + parts: + - seqid: insdc:NC_001422.1 + start: 3981 + end: 5386 + start_status: exact + end_status: exact + strand: + + - seqid: insdc:NC_001422.1 + start: 1 + end: 136 + start_status: exact + end_status: exact + strand: + + crosses_origin: true + attributes: + - key: locus_tag + value: phiX174p01 + - key: function + value: viral strand synthesis + - key: note + value: rf replication + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: DNA replication initiation + - key: protein_id + value: NP_040703.1 + - key: db_xref + value: GeneID:2546398 + - key: translation + value: MVRSYYPSECHADYFDFERIEALKPAIEACGISTLSQSPMLGFHKQMDNRIKLLEEILSFRMQGVEFDNGDMYVDGHKAASDVRDEFVSVTEKLMDELAQCYNVLPQLDINNTIDHRPEGDEKWFLENEKTVTQFCRKLAAERPLKDIRDEYNYPKKKGIKDECSRLLEASTMKSRRGFAIQRLMNAMRQAHADGWFIVFDTLTLADDRLEAFYDNPNALRDYFRDIGRMVLAAEGRKANDSHADCYQYFCVPEYGTANGRLHFHAVHFMRTLPTGSVDPNFGRRVRNRRQLNSLQNTWPYGYSMPIAVRYTQDAFSRSGWLWPVDAKGEPLKATSYMAVGFYVAKYVNKKSDMDLAAKGLGAKEWNNSLKTKLSLLPKKLFRIRMSRNFGMKMLTMTNLSTECLIQLTKLGYDATPFNQILKQNAKREMRLRLGKVTVADVLAAQPVTTNLLKFMRASIKMIGVSNLQSFIASMTQKLTLSDISDESKNYLDKAGITTACLRIKSKWTAGGK + product: DNA replication initiation + translated_sequence: MVRSYYPSECHADYFDFERIEALKPAIEACGISTLSQSPMLGFHKQMDNRIKLLEEILSFRMQGVEFDNGDMYVDGHKAASDVRDEFVSVTEKLMDELAQCYNVLPQLDINNTIDHRPEGDEKWFLENEKTVTQFCRKLAAERPLKDIRDEYNYPKKKGIKDECSRLLEASTMKSRRGFAIQRLMNAMRQAHADGWFIVFDTLTLADDRLEAFYDNPNALRDYFRDIGRMVLAAEGRKANDSHADCYQYFCVPEYGTANGRLHFHAVHFMRTLPTGSVDPNFGRRVRNRRQLNSLQNTWPYGYSMPIAVRYTQDAFSRSGWLWPVDAKGEPLKATSYMAVGFYVAKYVNKKSDMDLAAKGLGAKEWNNSLKTKLSLLPKKLFRIRMSRNFGMKMLTMTNLSTECLIQLTKLGYDATPFNQILKQNAKREMRLRLGKVTVADVLAAQPVTTNLLKFMRASIKMIGVSNLQSFIASMTQKLTLSDISDESKNYLDKAGITTACLRIKSKWTAGGK +- feature_id: insdc:NC_001422.1:feature-4 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 1 + end: 5386 + strand: + + location: + location_operator: join + parts: + - seqid: insdc:NC_001422.1 + start: 4497 + end: 5386 + start_status: exact + end_status: exact + strand: + + - seqid: insdc:NC_001422.1 + start: 1 + end: 136 + start_status: exact + end_status: exact + strand: + + crosses_origin: true + attributes: + - key: locus_tag + value: phiX174p02 + - key: db_xref + value: GeneID:2546406 +- feature_id: insdc:NC_001422.1:feature-5 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 1 + end: 5386 + strand: + + location: + location_operator: join + parts: + - seqid: insdc:NC_001422.1 + start: 4497 + end: 5386 + start_status: exact + end_status: exact + strand: + + - seqid: insdc:NC_001422.1 + start: 1 + end: 136 + start_status: exact + end_status: exact + strand: + + crosses_origin: true + attributes: + - key: locus_tag + value: phiX174p02 + - key: function + value: shut off host DNA synthesis + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: DNA replication initiation + - key: protein_id + value: NP_040704.1 + - key: db_xref + value: GeneID:2546406 + - key: translation + value: MKSRRGFAIQRLMNAMRQAHADGWFIVFDTLTLADDRLEAFYDNPNALRDYFRDIGRMVLAAEGRKANDSHADCYQYFCVPEYGTANGRLHFHAVHFMRTLPTGSVDPNFGRRVRNRRQLNSLQNTWPYGYSMPIAVRYTQDAFSRSGWLWPVDAKGEPLKATSYMAVGFYVAKYVNKKSDMDLAAKGLGAKEWNNSLKTKLSLLPKKLFRIRMSRNFGMKMLTMTNLSTECLIQLTKLGYDATPFNQILKQNAKREMRLRLGKVTVADVLAAQPVTTNLLKFMRASIKMIGVSNLQSFIASMTQKLTLSDISDESKNYLDKAGITTACLRIKSKWTAGGK + product: DNA replication initiation + translated_sequence: MKSRRGFAIQRLMNAMRQAHADGWFIVFDTLTLADDRLEAFYDNPNALRDYFRDIGRMVLAAEGRKANDSHADCYQYFCVPEYGTANGRLHFHAVHFMRTLPTGSVDPNFGRRVRNRRQLNSLQNTWPYGYSMPIAVRYTQDAFSRSGWLWPVDAKGEPLKATSYMAVGFYVAKYVNKKSDMDLAAKGLGAKEWNNSLKTKLSLLPKKLFRIRMSRNFGMKMLTMTNLSTECLIQLTKLGYDATPFNQILKQNAKREMRLRLGKVTVADVLAAQPVTTNLLKFMRASIKMIGVSNLQSFIASMTQKLTLSDISDESKNYLDKAGITTACLRIKSKWTAGGK +- feature_id: insdc:NC_001422.1:feature-6 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 1 + end: 5386 + strand: + + location: + location_operator: join + parts: + - seqid: insdc:NC_001422.1 + start: 5075 + end: 5386 + start_status: exact + end_status: exact + strand: + + - seqid: insdc:NC_001422.1 + start: 1 + end: 51 + start_status: exact + end_status: exact + strand: + + crosses_origin: true + attributes: + - key: locus_tag + value: phiX174p03 + - key: db_xref + value: GeneID:2546405 +- feature_id: insdc:NC_001422.1:feature-7 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 1 + end: 5386 + strand: + + location: + location_operator: join + parts: + - seqid: insdc:NC_001422.1 + start: 5075 + end: 5386 + start_status: exact + end_status: exact + strand: + + - seqid: insdc:NC_001422.1 + start: 1 + end: 51 + start_status: exact + end_status: exact + strand: + + crosses_origin: true + attributes: + - key: locus_tag + value: phiX174p03 + - key: function + value: capsid morphogenesis + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: head morphogenesis + - key: protein_id + value: NP_040705.1 + - key: db_xref + value: GeneID:2546405 + - key: translation + value: MEQLTKNQAVATSQEAVQNQNEPQLRDENAHNDKSVHGVLNPTYQAGLRRDAVQPDIEAERKKRDEIEAGKSYCSRRFGGATCDDKSAQIYARFDKNDWRIQPAEFYRFHDAEVNTFGYF + product: head morphogenesis + translated_sequence: MEQLTKNQAVATSQEAVQNQNEPQLRDENAHNDKSVHGVLNPTYQAGLRRDAVQPDIEAERKKRDEIEAGKSYCSRRFGGATCDDKSAQIYARFDKNDWRIQPAEFYRFHDAEVNTFGYF +- feature_id: insdc:NC_001422.1:feature-8 + seqid: insdc:NC_001422.1 + type: variation + coordinate_system: contig + start: 23 + end: 23 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 23 + end: 23 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p03 + - key: note + value: in am18 and am35 [14] + - key: replace + value: t +- feature_id: insdc:NC_001422.1:feature-9 + seqid: insdc:NC_001422.1 + type: variation + coordinate_system: contig + start: 25 + end: 25 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 25 + end: 25 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p03 + - key: note + value: ts116 [14] + - key: replace + value: c +- feature_id: insdc:NC_001422.1:feature-10 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 51 + end: 221 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 51 + end: 221 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p04 + - key: db_xref + value: GeneID:2546403 +- feature_id: insdc:NC_001422.1:feature-11 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 51 + end: 221 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 51 + end: 221 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p04 + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: K + - key: protein_id + value: NP_040706.1 + - key: db_xref + value: GeneID:2546403 + - key: translation + value: MSRKIILIKQELLLLVYELNRSGLLAENEKIRPILAQLEKLLLCDLSPSTNDSVKN + product: K + translated_sequence: MSRKIILIKQELLLLVYELNRSGLLAENEKIRPILAQLEKLLLCDLSPSTNDSVKN +- feature_id: insdc:NC_001422.1:feature-12 + seqid: insdc:NC_001422.1 + type: variation + coordinate_system: contig + start: 57 + end: 57 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 57 + end: 57 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p04 + - key: note + value: am6 [14] + - key: replace + value: c +- feature_id: insdc:NC_001422.1:feature-13 + seqid: insdc:NC_001422.1 + type: variation + coordinate_system: contig + start: 117 + end: 117 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 117 + end: 117 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p04 + - key: note + value: am6 [14] + - key: replace + value: a +- feature_id: insdc:NC_001422.1:feature-14 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 133 + end: 393 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 133 + end: 393 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p05 + - key: db_xref + value: GeneID:2546402 +- feature_id: insdc:NC_001422.1:feature-15 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 133 + end: 393 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 133 + end: 393 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p05 + - key: note + value: DNA maturation + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: terminase + - key: protein_id + value: NP_040707.1 + - key: db_xref + value: GeneID:2546402 + - key: translation + value: MRKFDLSLRSSRSSYFATFRHQLTILSKTDALDEEKWLNMLGTFVKDWFRYESHFVHGRDSLVDILKERGLLSESDAVQPLIGKKS + product: terminase + translated_sequence: MRKFDLSLRSSRSSYFATFRHQLTILSKTDALDEEKWLNMLGTFVKDWFRYESHFVHGRDSLVDILKERGLLSESDAVQPLIGKKS +- feature_id: insdc:NC_001422.1:feature-16 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 358 + end: 3975 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 358 + end: 3975 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p06 + - key: db_xref + value: GeneID:2546408 +- feature_id: insdc:NC_001422.1:feature-17 + seqid: insdc:NC_001422.1 + type: mRNA + coordinate_system: contig + start: 358 + end: 3975 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 358 + end: 3975 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p06 + - key: product + value: major transcript + - key: db_xref + value: GeneID:2546408 + product: major transcript +- feature_id: insdc:NC_001422.1:feature-18 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 358 + end: 991 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 358 + end: 991 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p07 + - key: db_xref + value: GeneID:2546399 +- feature_id: insdc:NC_001422.1:feature-19 + seqid: insdc:NC_001422.1 + type: mRNA + coordinate_system: contig + start: 358 + end: 991 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 358 + end: 991 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p07 + - key: product + value: minor transcript + - key: db_xref + value: GeneID:2546399 + product: minor transcript +- feature_id: insdc:NC_001422.1:feature-20 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 390 + end: 848 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 390 + end: 848 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p07 + - key: function + value: capsid morphogenesis + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: head morphogenesis + - key: protein_id + value: NP_040708.1 + - key: db_xref + value: GeneID:2546399 + - key: translation + value: MSQVTEQSVRFQTALASIKLIQASAVLDLTEDDFDFLTSNKVWIATDRSRARRCVEACVYGTLDFVGYPRFPAPVEFIAAVIAYYVHPVNIQTACLIMEGAEFTENIINGVERPVKAAELFAFTLRVRAGNTDVLTDAEENVRQKLRAEGVM + product: head morphogenesis + translated_sequence: MSQVTEQSVRFQTALASIKLIQASAVLDLTEDDFDFLTSNKVWIATDRSRARRCVEACVYGTLDFVGYPRFPAPVEFIAAVIAYYVHPVNIQTACLIMEGAEFTENIINGVERPVKAAELFAFTLRVRAGNTDVLTDAEENVRQKLRAEGVM +- feature_id: insdc:NC_001422.1:feature-21 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 568 + end: 843 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 568 + end: 843 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p08 + - key: db_xref + value: GeneID:2546400 +- feature_id: insdc:NC_001422.1:feature-22 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 568 + end: 843 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 568 + end: 843 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p08 + - key: function + value: cell lysis + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: endolysin + - key: protein_id + value: NP_040709.1 + - key: db_xref + value: GeneID:2546400 + - key: translation + value: MVRWTLWDTLAFLLLLSLLLPSLLIMFIPSTFKRPVSSWKALNLRKTLLMASSVRLKPLNCSRLPCVYAQETLTFLLTQKKTCVKNYVRKE + product: endolysin + translated_sequence: MVRWTLWDTLAFLLLLSLLLPSLLIMFIPSTFKRPVSSWKALNLRKTLLMASSVRLKPLNCSRLPCVYAQETLTFLLTQKKTCVKNYVRKE +- feature_id: insdc:NC_001422.1:feature-23 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 848 + end: 964 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 848 + end: 964 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p09 + - key: db_xref + value: GeneID:2546404 +- feature_id: insdc:NC_001422.1:feature-24 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 848 + end: 964 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 848 + end: 964 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p09 + - key: note + value: core protein + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: DNA condensation + - key: protein_id + value: NP_040710.1 + - key: db_xref + value: GeneID:2546404 + - key: translation + value: MSKGKKRSGARPGRPQPLRGTKGKRKGARLWYVGGQQF + product: DNA condensation + translated_sequence: MSKGKKRSGARPGRPQPLRGTKGKRKGARLWYVGGQQF +- feature_id: insdc:NC_001422.1:feature-25 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 1001 + end: 2284 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 1001 + end: 2284 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p06 + - key: note + value: major coat protein + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: major head protein + - key: protein_id + value: NP_040711.1 + - key: db_xref + value: GeneID:2546408 + - key: translation + value: MSNIQTGAERMPHDLSHLGFLAGQIGRLITISTTPVIAGDSFEMDAVGALRLSPLRRGLAIDSTVDIFTFYVPHRHVYGEQWIKFMKDGVNATPLPTVNTTGYIDHAAFLGTINPDTNKIPKHLFQGYLNIYNNYFKAPWMPDRTEANPNELNQDDARYGFRCCHLKNIWTAPLPPETELSRQMTTSTTSIDIMGLQAAYANLHTDQERDYFMQRYHDVISSFGGKTSYDADNRPLLVMRSNLWASGYDVDGTDQTSLGQFSGRVQQTYKHSVPRFFVPEHGTMFTLALVRFPPTATKEIQYLNAKGALTYTDIAGDPVLYGNLPPREISMKDVFRSGDSSKKFKIAEGQWYRYAPSYVSPAYHLLEGFPFIQEPPSGDLQERVLIRHHDYDQCFQSVQLLQWNSQVKFNVTVYRNLPTTRDSIMTS + product: major head protein + translated_sequence: MSNIQTGAERMPHDLSHLGFLAGQIGRLITISTTPVIAGDSFEMDAVGALRLSPLRRGLAIDSTVDIFTFYVPHRHVYGEQWIKFMKDGVNATPLPTVNTTGYIDHAAFLGTINPDTNKIPKHLFQGYLNIYNNYFKAPWMPDRTEANPNELNQDDARYGFRCCHLKNIWTAPLPPETELSRQMTTSTTSIDIMGLQAAYANLHTDQERDYFMQRYHDVISSFGGKTSYDADNRPLLVMRSNLWASGYDVDGTDQTSLGQFSGRVQQTYKHSVPRFFVPEHGTMFTLALVRFPPTATKEIQYLNAKGALTYTDIAGDPVLYGNLPPREISMKDVFRSGDSSKKFKIAEGQWYRYAPSYVSPAYHLLEGFPFIQEPPSGDLQERVLIRHHDYDQCFQSVQLLQWNSQVKFNVTVYRNLPTTRDSIMTS +- feature_id: insdc:NC_001422.1:feature-26 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 2395 + end: 2922 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 2395 + end: 2922 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p10 + - key: db_xref + value: GeneID:2546401 +- feature_id: insdc:NC_001422.1:feature-27 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 2395 + end: 2922 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 2395 + end: 2922 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p10 + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: major spike protein + - key: protein_id + value: NP_040712.1 + - key: db_xref + value: GeneID:2546401 + - key: translation + value: MFQTFISRHNSNFFSDKLVLTSVTPASSAPVLQTPKATSSTLYFDSLTVNAGNGGFLHCIQMDTSVNAANQVVSVGADIAFDADPKFFACLVRFESSSVPTTLPTAYDVYPLNGRHDGGYYTVKDCVTIDVLPRTPGNNVYVGFMVWSNFTATKCRGLVSLNQVIKEIICLQPLK + product: major spike protein + translated_sequence: MFQTFISRHNSNFFSDKLVLTSVTPASSAPVLQTPKATSSTLYFDSLTVNAGNGGFLHCIQMDTSVNAANQVVSVGADIAFDADPKFFACLVRFESSSVPTTLPTAYDVYPLNGRHDGGYYTVKDCVTIDVLPRTPGNNVYVGFMVWSNFTATKCRGLVSLNQVIKEIICLQPLK +- feature_id: insdc:NC_001422.1:feature-28 + seqid: insdc:NC_001422.1 + type: gene + coordinate_system: contig + start: 2931 + end: 3917 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 2931 + end: 3917 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p11 + - key: db_xref + value: GeneID:2546407 +- feature_id: insdc:NC_001422.1:feature-29 + seqid: insdc:NC_001422.1 + type: CDS + coordinate_system: contig + start: 2931 + end: 3917 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 2931 + end: 3917 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p11 + - key: function + value: adsorption + - key: note + value: minor spike protein + - key: codon_start + value: '1' + - key: transl_table + value: '11' + - key: product + value: pilot protein for DNA ejection + - key: protein_id + value: NP_040713.1 + - key: db_xref + value: GeneID:2546407 + - key: translation + value: MFGAIAGGIASALAGGAMSKLFGGGQKAASGGIQGDVLATDNNTVGMGDAGIKSAIQGSNVPNPDEAAPSFVSGAMAKAGKGLLEGTLQAGTSAVSDKLLDLVGLGGKSAADKGKDTRDYLAAAFPELNAWERAGADASSAGMVDAGFENQKELTKMQLDNQKEIAEMQNETQKEIAGIQSATSRQNTKDQVYAQNEMLAYQQKESTARVASIMENTNLSKQQQVSEIMRQMLTQAQTAGQYFTNDQIKEMTRKVSAEVDLVHQQTQNQRYGSSHIGATAKDISNVVTDAASGVVDIFHGIDKAVADTWNNFWKDGKADGIGSNLSRK + product: pilot protein for DNA ejection + translated_sequence: MFGAIAGGIASALAGGAMSKLFGGGQKAASGGIQGDVLATDNNTVGMGDAGIKSAIQGSNVPNPDEAAPSFVSGAMAKAGKGLLEGTLQAGTSAVSDKLLDLVGLGGKSAADKGKDTRDYLAAAFPELNAWERAGADASSAGMVDAGFENQKELTKMQLDNQKEIAEMQNETQKEIAGIQSATSRQNTKDQVYAQNEMLAYQQKESTARVASIMENTNLSKQQQVSEIMRQMLTQAQTAGQYFTNDQIKEMTRKVSAEVDLVHQQTQNQRYGSSHIGATAKDISNVVTDAASGVVDIFHGIDKAVADTWNNFWKDGKADGIGSNLSRK +- feature_id: insdc:NC_001422.1:feature-30 + seqid: insdc:NC_001422.1 + type: misc_feature + coordinate_system: contig + start: 3962 + end: 3962 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 3962 + end: 3962 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p06 + - key: note + value: transcription start site +- feature_id: insdc:NC_001422.1:feature-31 + seqid: insdc:NC_001422.1 + type: rep_origin + coordinate_system: contig + start: 4306 + end: 4306 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 4306 + end: 4306 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p01 + - key: note + value: origin of viral strand synthesis +- feature_id: insdc:NC_001422.1:feature-32 + seqid: insdc:NC_001422.1 + type: misc_feature + coordinate_system: contig + start: 4899 + end: 4899 + strand: + + location: + location_operator: single + parts: + - seqid: insdc:NC_001422.1 + start: 4899 + end: 4899 + start_status: exact + end_status: exact + strand: + + crosses_origin: false + attributes: + - key: locus_tag + value: phiX174p02 + - key: note + value: transcription start site diff --git a/tests/data/valid/Dataset-004.yaml b/tests/data/valid/Dataset-004.yaml new file mode 100644 index 0000000..cc9e949 --- /dev/null +++ b/tests/data/valid/Dataset-004.yaml @@ -0,0 +1,123 @@ +# Real NMDC data: one CDS and its three Pfam hits from annotation nmdc:wfmgan-11-5xxrm214.2 +# (CC BY 4.0), converted with the nmdc-pfam-protein/5.0.0 profile, which records each hit's +# alignment target. Source: https://github.com/turbomam/feature-table-corpus/blob/v0.1.0/corpus/sources/nmdc/nmdc_wfmgan-11-5xxrm214.2_pfam.gff +contigs: +- contig_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1 +features: +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1 + type: CDS + start: 63 + end: 1091 + coordinate_system: contig + strand: '-' + attributes: + - key: ID + value: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + - key: translation_table + value: '11' + - key: start_type + value: ATG + source: Prodigal v2.6.3_patched + score: 76.5 + phase: 0 + translated_sequence: MRQNDARQLSHDMLEDMRRRAVTAVQEGQSPEAVGKAFGLNRTTIYDWLAQYRRGGWGALKAKPLAGRPPKLNGKQMKWIYNTVTQKNPLQMKFEFALWTRAMVAKLIKDKFGIRLATNSVGRLLAQLGITPQRPLYQALERDPSLVKKWLKTEFPKIKKAAETLGADIYFGDAAHIRSDHHAGRTWGKKGETPIVVTTGARHGMSLLSAITSKGHMRFMIKEKGGVNSDVFIEFLKRLLVGAKRPVFLIVDRGPAHISKKTKAFVATLGSRLKLFYLPAYSPDRNPDELVWKHLKADTVGRMVTTSKADFKSKVVSSMRSLQKTPEKIRSFFQKPSLQYAA + source_files: + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_structural_annotation.gff + - https://data.microbiomedata.org/data/nmdc:omprc-11-2t8ft192/nmdc:wfmgan-11-5xxrm214.2/nmdc_wfmgan-11-5xxrm214.2_proteins.faa +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_168_312 + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + type: PF13358 + start: 168 + end: 312 + coordinate_system: protein + strand: . + attributes: + - key: ID + value: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_168_312 + - key: Name + value: DDE_3 + - key: fake_percent_id + value: '25.23' + - key: alignment_length + value: '145' + - key: e-value + value: '3.4e-28' + - key: model_start + value: '2' + - key: model_end + value: '135' + source: HMMER 3.1b2 (February 2015) + score: 94.0 + name: DDE_3 + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + score_type: bit_score + target: + target_id: PF13358 + target_start: 2 + target_end: 135 +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_95_154 + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + type: PF13592 + start: 95 + end: 154 + coordinate_system: protein + strand: . + attributes: + - key: ID + value: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_95_154 + - key: Name + value: HTH_33 + - key: fake_percent_id + value: '25.23' + - key: alignment_length + value: '60' + - key: e-value + value: '3.4e-19' + - key: model_start + value: '1' + - key: model_end + value: '59' + source: HMMER 3.1b2 (February 2015) + score: 64.0 + name: HTH_33 + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + score_type: bit_score + target: + target_id: PF13592 + target_start: 1 + target_end: 59 +- feature_id: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_17_70 + seqid: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + type: PF13518 + start: 17 + end: 70 + coordinate_system: protein + strand: . + attributes: + - key: ID + value: nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091_17_70 + - key: Name + value: HTH_28 + - key: fake_percent_id + value: '25.23' + - key: alignment_length + value: '54' + - key: e-value + value: '2.4e-12' + - key: model_start + value: '2' + - key: model_end + value: '51' + source: HMMER 3.1b2 (February 2015) + score: 42.5 + name: HTH_28 + parent: + - nmdc:wfmgas-11-19jh9v28.1_scf_10_c1_63_1091 + score_type: bit_score + target: + target_id: PF13518 + target_start: 2 + target_end: 51 diff --git a/tests/test_data.py b/tests/test_data.py index b27414e..9a59584 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -7,7 +7,11 @@ import ber_central_schema.datamodel.ber_central_schema from linkml_runtime.loaders import yaml_loader +from linkml.validator import validate +from linkml_runtime import SchemaView +import yaml +SCHEMA = Path(__file__).parents[1] / "src" / "ber_central_schema" / "schema" / "ber_central_schema.yaml" DATA_DIR_VALID = Path(__file__).parent / "data" / "valid" DATA_DIR_INVALID = Path(__file__).parent / "data" / "invalid" @@ -25,3 +29,14 @@ def test_valid_data_files(filepath): ) obj = yaml_loader.load(filepath, target_class=tgt_class) assert obj + + +@pytest.mark.parametrize("filepath", INVALID_EXAMPLE_FILES) +def test_invalid_data_files(filepath): + """Every counterexample must fail validation against its class.""" + target_class_name = Path(filepath).stem.split("-")[0] + instance = yaml.safe_load(Path(filepath).read_text()) + # Load through SchemaView so imports resolve beside the schema, not the working directory. + schema = SchemaView(str(SCHEMA)).materialize_derived_schema() + report = validate(instance, schema, target_class_name) + assert report.results, f"{filepath} validated, but it is a counterexample"