GffFeatureReader
in package
implements
GffFeatureReaderInterface
Deliberately independent of DatabaseParserFactory/ParseDbAbstractManager : that machinery is built around GenBank-style databases, each entry delimited by its own start/end sentinel line and ultimately persisted through Doctrine (DatabaseManager::recording()). GFF3 has neither shape - one feature per line, no entry delimiters, no persistence - and forcing it through that abstraction would fight it rather than reuse it. This class is a standalone, persistence-independent text reader, in keeping with the rest of Domain/Cloning.
Each of the nine standard tab-separated columns (seqid, source, type, start, end, score, strand, phase, attributes) is read directly ; comment and pragma lines ("#..."), including the "##gff-version" header, are skipped, and reading stops at a "##FASTA" pragma without attempting to parse the embedded sequence it introduces - a GFF3 file's sequence, when present at all, is not this reader's concern. Start must never exceed end in GFF3 ; a feature crossing the origin of a circular landmark is instead written with end = its real end + the landmark length, the landmark itself carrying Is_circular=true (GFF3 specification, columns 4 and 5). Such a feature is folded back here into PlasmidFeature's own convention (start > end). The landmark length is taken from a line whose own seqid it is, starting at 1 and flagged Is_circular=true, wherever it appears in the file. A line with start > end, or one longer than the circular landmark itself, is malformed and, like any other malformed line, skipped and reported in GffImportResult::getWarnings() rather than thrown. The phase column is kept on CDS features only, the one type GFF3 requires it for. A GFF3 feature split across several lines that share a Parent/ID relationship (a spliced gene's exons) is read as that many independent PlasmidFeature instances, not reassembled into one ; this mirrors the equivalent, documented limitation GenbankPlasmidMapper already accepts for a GenBank join() location. Class GffFeatureReader
Tags
Table of Contents
Interfaces
- GffFeatureReaderInterface
- Interface GffFeatureReaderInterface - reads a GFF3 annotation file into PlasmidFeature instances, independently of any specific Plasmid.
Constants
- EXPECTED_COLUMN_COUNT : mixed = 9
- FASTA_PRAGMA : mixed = "##FASTA"
- FEATURE_TYPE_BY_SO_TERM : array<string, string> = ["cds" => \Amelaye\BioPHP\Domain\Cloning\ValueO...
- Sequence Ontology terms that map unambiguously onto a FeatureType, matched case-insensitively since real-world GFF3 producers disagree on casing (e.g. "CDS" vs "cds"). Anything else, including "gene" (a broader region than any single FeatureType here, exactly as GenbankPlasmidMapper already treats it), falls back to FeatureType::MISC_FEATURE, with the original term preserved in metadata rather than guessed at.
Methods
- read() : GffImportResult
- findCircularLandmarkLengths() : array<string, int>
- Lengths of the landmarks declared circular : a line whose seqid is its own ID, starting at 1 and flagged Is_circular=true (e.g. "p1 . region 1 5000 . + . ID=p1;Is_circular=true").
- mapColumns() : PlasmidFeature
- parseAttributes() : array<string, array<string|int, string>>
- Parses the ninth GFF3 column into its semicolon-separated, percent-decoded key=value pairs. A key repeated with a comma-separated value list (e.g. "Parent=mRNA1,mRNA2") keeps every value.
Constants
EXPECTED_COLUMN_COUNT
private
mixed
EXPECTED_COLUMN_COUNT
= 9
FASTA_PRAGMA
private
mixed
FASTA_PRAGMA
= "##FASTA"
FEATURE_TYPE_BY_SO_TERM
Sequence Ontology terms that map unambiguously onto a FeatureType, matched case-insensitively since real-world GFF3 producers disagree on casing (e.g. "CDS" vs "cds"). Anything else, including "gene" (a broader region than any single FeatureType here, exactly as GenbankPlasmidMapper already treats it), falls back to FeatureType::MISC_FEATURE, with the original term preserved in metadata rather than guessed at.
private
array<string, string>
FEATURE_TYPE_BY_SO_TERM
= ["cds" => \Amelaye\BioPHP\Domain\Cloning\ValueObject\FeatureType::CDS, "promoter" => \Amelaye\BioPHP\Domain\Cloning\ValueObject\FeatureType::PROMOTER, "terminator" => \Amelaye\BioPHP\Domain\Cloning\ValueObject\FeatureType::TERMINATOR, "origin_of_replication" => \Amelaye\BioPHP\Domain\Cloning\ValueObject\FeatureType::ORIGIN_OF_REPLICATION]
Methods
read()
public
read(array<string|int, string> $aLines) : GffImportResult
Parameters
- $aLines : array<string|int, string>
Return values
GffImportResultfindCircularLandmarkLengths()
Lengths of the landmarks declared circular : a line whose seqid is its own ID, starting at 1 and flagged Is_circular=true (e.g. "p1 . region 1 5000 . + . ID=p1;Is_circular=true").
private
findCircularLandmarkLengths(array<string|int, string> $aLines) : array<string, int>
Parameters
- $aLines : array<string|int, string>
Return values
array<string, int> —Landmark seqid => length
mapColumns()
private
mapColumns(array<string|int, string> $aColumns, array<string, int> $aCircularLengths) : PlasmidFeature
Parameters
- $aColumns : array<string|int, string>
-
Exactly the 9 standard GFF3 columns, in order
- $aCircularLengths : array<string, int>
-
From findCircularLandmarkLengths()
Return values
PlasmidFeatureparseAttributes()
Parses the ninth GFF3 column into its semicolon-separated, percent-decoded key=value pairs. A key repeated with a comma-separated value list (e.g. "Parent=mRNA1,mRNA2") keeps every value.
private
parseAttributes(string $sRaw) : array<string, array<string|int, string>>
Parameters
- $sRaw : string