Analyse du fichier GenBank :obtenir la balise de lieu par rapport au produit
Question
Fondamentalement, un fichier GenBank est constitué d'entrées de gènes (annoncées par 'gène' suivi de son entrée 'CDS' correspondante (une seule par gène) comme les deux que je montre ci-dessous.Je voudrais obtenir locus_tag vs product dans un fichier à deux colonnes délimité par des tabulations.« gène » et « CDS » sont toujours précédés et suivis d'espaces.
Une question précédente suggérait un script.
Le problème est qu'il semble que parce que 'produit' a parfois le caractère '/' dans son nom, il est en conflit avec ce script qui, pour autant que je sache, utilise '/' comme séparateur de champ pour stocker des informations dans un tableau?
J'aimerais résoudre ce problème, soit en modifiant ce script, soit en en construisant un autre.
perl -nE'
BEGIN{ ($/, $") = ("CDS", "\t") }
say "@r[0,1]" if @r= m!/(?:locus_tag|product)="(.+?)"!g and @r>1
' file
gene complement(8972..9094)
/locus_tag="HAPS_0004"
/db_xref="GeneID:7278619"
CDS complement(8972..9094)
/locus_tag="HAPS_0004"
/codon_start=1
/transl_table=11
/product="hypothetical protein"
/protein_id="YP_002474657.1"
/db_xref="GI:219870282"
/db_xref="GeneID:7278619"
/translation="MYYKALAHFLPTLSTMQNILSKSPLSLDFRLLFLAFIDKR"
gene 68..637
/locus_tag="HPNK_00040"
CDS 68..637
/locus_tag="HPNK_00040"
/codon_start=1
/transl_table=11
/product="NinG recombination protein/bacteriophage lambda
NinG family protein"
/protein_id="CRESA:HPNK_00040"
/translation="MIKPKVKKRKCKCCGGEFKSADSFRKWCSAECGVKLAKIAQEKA
RQKAIEKRNREERAKIKATRERLKSRSEWLKDAQAIFNEYIRLRDKDEPCISCRRFHQ
GQYHAGHYRTVKAMPELRFNEDNVHKQCSACNNHLSGNITEYRINLVRKIGAERVEAL
ESYHPPVKWSVEDCKEIIKTYRAKIKELK"
La solution
Comme votre exemple de fichier GenBank était incomplet, je suis allé en ligne pour trouver un exemple de fichier qui pourrait être utilisé dans un exemple, et j'ai trouvé ce fichier.
En utilisant ce code et le Bio::GenBankParser
module, il a été analysé en devinant quelles parties de la structure vous recherchiez.Dans ce cas, les « fonctionnalités » qui contenaient à la fois un locus_tag
champ et un product
champ.
use strict;
use warnings;
use feature 'say';
use Bio::GenBankParser;
my $file = shift;
my $parser = Bio::GenBankParser->new( file => $file );
while ( my $seq = $parser->next_seq ) {
my $feat = $seq->{'FEATURES'};
for my $f (@$feat) {
my $tag = $f->{'feature'}{'locus_tag'};
my $prod = $f->{'feature'}{'product'};
if (defined $tag and defined $prod) {
say join "\t", $tag, $prod;
}
}
}
Usage:
perl script.pl input.txt > output.txt
Sortir:
MG_001 DNA polymerase III, beta subunit
MG_470 CobQ/CobB/MinD/ParA nucleotide binding domain-containing protein
Le résultat de votre one-liner pour la même entrée serait :
MG_001 DNA polymerase III, beta subunit
MG_470 CobQ/CobB/MinD/ParA nucleotide binding
domain-containing protein
En supposant bien sûr que vous ajoutiez le /s
modificateur à l'expression régulière pour tenir compte des entrées multilignes (qui leeduhem souligné dans les commentaires):
m!/(?:locus_tag|product)="(.+?)"!sg
# ^---- this
Autres conseils
Having read your duplicated question http://www.biostars.org/p/94164/ (please don't double post like this), here's a minimal Biopython answer:
import sys
from Bio import SeqIO
filename = sys.argv[1] # Takes first command line argument input filename
for record in SeqIO.parse(filename, "genbank"):
for feature in record.features:
if feature.type == "CDS":
locus_tag = feature.qualifiers.get("locus_tag", ["???"])[0]
product = feature.qualifiers.get("product", ["???"])[0]
print("%s\t%s" % (locus_tag, product))
With minor changes you can write this out to a file instead.