11h04
maintenant que le parser global est construit, je vais faire un parser pour le fichier gal dérivé de celui-ci
Format d’un fichier GAL -> GenePix Array List
exemple du fichier /home/gim2/bioinfo/microarray/barcode12k_v2final.gal
la commande
less /home/gim2/bioinfo/microarray/barcode12k_v2final.gal
donne
ATF 1
51 6
Type=GenePix ArrayList V1.0
BlockCount=48
BlockType=0
"Block1= 3530, 8000, 120, 24, 180, 24, 180"
"Block2= 8030, 8000, 120, 24, 180, 24, 180"
"Block3= 12530, 8000, 120, 24, 180, 24, 180"
"Block4= 17030, 8000, 120, 24, 180, 24, 180"
"Block5= 3530, 12500, 120, 24, 180, 24, 180"
"Block6= 8030, 12500, 120, 24, 180, 24, 180"
"Block7= 12530, 12500, 120, 24, 180, 24, 180"
"Block8= 17030, 12500, 120, 24, 180, 24, 180"
"Block9= 3530, 17000, 120, 24, 180, 24, 180"
"Block10= 8030, 17000, 120, 24, 180, 24, 180"
"Block11= 12530, 17000, 120, 24, 180, 24, 180"
"Block12= 17030, 17000, 120, 24, 180, 24, 180"
"Block13= 3530, 21500, 120, 24, 180, 24, 180"
"Block14= 8030, 21500, 120, 24, 180, 24, 180"
"Block15= 12530, 21500, 120, 24, 180, 24, 180"
"Block16= 17030, 21500, 120, 24, 180, 24, 180"
"Block17= 3530, 26000, 120, 24, 180, 24, 180"
"Block18= 8030, 26000, 120, 24, 180, 24, 180"
"Block19= 12530, 26000, 120, 24, 180, 24, 180"
"Block20= 17030, 26000, 120, 24, 180, 24, 180"
"Block21= 3530, 30500, 120, 24, 180, 24, 180"
"Block22= 8030, 30500, 120, 24, 180, 24, 180"
"Block23= 12530, 30500, 120, 24, 180, 24, 180"
"Block24= 17030, 30500, 120, 24, 180, 24, 180"
"Block25= 3530, 35000, 120, 24, 180, 24, 180"
"Block26= 8030, 35000, 120, 24, 180, 24, 180"
"Block27= 12530, 35000, 120, 24, 180, 24, 180"
"Block28= 17030, 35000, 120, 24, 180, 24, 180"
"Block29= 3530, 39500, 120, 24, 180, 24, 180"
"Block30= 8030, 39500, 120, 24, 180, 24, 180"
"Block31= 12530, 39500, 120, 24, 180, 24, 180"
"Block32= 17030, 39500, 120, 24, 180, 24, 180"
"Block33= 3530, 44000, 120, 24, 180, 24, 180"
"Block34= 8030, 44000, 120, 24, 180, 24, 180"
"Block35= 12530, 44000, 120, 24, 180, 24, 180"
"Block36= 17030, 44000, 120, 24, 180, 24, 180"
"Block37= 3530, 48500, 120, 24, 180, 24, 180"
"Block38= 8030, 48500, 120, 24, 180, 24, 180"
"Block39= 12530, 48500, 120, 24, 180, 24, 180"
"Block40= 17030, 48500, 120, 24, 180, 24, 180"
"Block41= 3530, 53000, 120, 24, 180, 24, 180"
"Block42= 8030, 53000, 120, 24, 180, 24, 180"
"Block43= 12530, 53000, 120, 24, 180, 24, 180"
"Block44= 17030, 53000, 120, 24, 180, 24, 180"
"Block45= 3530, 57500, 120, 24, 180, 24, 180"
"Block46= 8030, 57500, 120, 24, 180, 24, 180"
"Block47= 12530, 57500, 120, 24, 180, 24, 180"
"Block48= 17030, 57500, 120, 24, 180, 24, 180"
Block Column Row ID Name Sequence
1 1 1 YHR185C-D-R PFS1 AGAGATCCACTTCCCATAATT
1 2 1 YHR185C-D-R PFS1 AGAGATCCACTTCCCATAATT
1 3 1 YIR043C-D CTGCACATTCGATTACAGCG
1 4 1 YIR043C-D CTGCACATTCGATTACAGCG
1 5 1 YHR067W-D RMD12 TTATGCACCGTGACGAGGCT
1 6 1 YHR067W-D RMD12 TTATGCACCGTGACGAGGCT
1 7 1 YBR296C-U PHO89 CACGACCGACAATATGGTGA
1 8 1 YBR296C-U PHO89 CACGACCGACAATATGGTGA
1 9 1 YOL076W-U MDM2 ACGGATGGATCAGTTGCTAT
1 10 1 YOL076W-U MDM2 ACGGATGGATCAGTTGCTAT
1 11 1 YNL204C-U SPS18 GCGCTGGCACAAGAATACCA
1 12 1 YNL204C-U SPS18 GCGCTGGCACAAGAATACCA
1 13 1 YLR205C-U HMX1 AACTGAACATACCCGGTGAC
1 14 1 YLR205C-U HMX1 AACTGAACATACCCGGTGAC
1 15 1 YJL039C-D NUP192 TTGAGCCCGATCAGTCGATG
1 16 1 YJL039C-D NUP192 TTGAGCCCGATCAGTCGATG
1 17 1 YGR029W-D ERV1 TTACGTCCCGGATGCCGTTT
1 18 1 YGR029W-D ERV1 TTACGTCCCGGATGCCGTTT
1 19 1 YEL072W-D RMD6 TGCAGCACGCAAGACCATGA
1 20 1 YEL072W-D RMD6 TGCAGCACGCAAGACCATGA
1 21 1 YDR022C-D CIS1 GGTCGATAATAACACGCCAC
1 22 1 YDR022C-D CIS1 GGTCGATAATAACACGCCAC
1 23 1 YBL086C-U ACCACTCACTAAGGAGGATC
1 24 1 YBL086C-U ACCACTCACTAAGGAGGATC
1 1 2 YLR327C-D-R GATAACGACTCAGTGC
1 2 2 YLR327C-D-R GATAACGACTCAGTGC
1 3 2 YIL033C-D BCY1 GGATATTAGCCATCTACGTG
description des différentes parties
le fichier est spéraré en 3 parties
les 2 première ligne donne des info sur la structure du fichier
il y a ensuite le header du fichier
puis les données
1ere ligne -> ATF : conforme au format Axon Text File
1 : version du format
2eme ligne -> 51 : nombre de ligne dans le header
6 : nombre de colonne dans les données
3éme à 53 ème ligne ->header
Type=GenePix ArrayList V1.0 -> type du fichier
BlockCount=48 -> nombre de block
BlockType=0 ->Type de block decrit :
0 = rectangulaire.
1 = orange-packing #1.
2 = orange-packing #2.
“Block1= 3530, 8000, 120, 24, 180, 24, 180″ ->position et dimension de chaque block
xOrigin : position x du centre de la feature la plus en haut a gauche
yOrigin : position y du centre de la feature la plus en haut a gauche
FeatureDiameter : Diamètre des features du block
xFeature : Nombre de colonnes de features dans le block
xSpacing : espacement des colonnes
yFeature : Nombre de lignes de features dans le block
ySpacing : espacement des lignes
54eme ligne -> ligne de titre des colonnes
55eme ligne a la fin -> information pour chaque features
Le parser doit donc spécifiquement
lire la première ligne et stocker le format de fichier et sa valeur
lire la 2eme ligne et stocker le nb de ligne de header et le nb de colonne (pas vraimenet utile)
lire toute les ligne du header, les parser pour séparer la clé des données
(possible de rajouter un mini parser pour les données de block)
puis lire les données.
je vais donc faire un parser héritant de la classe Items.
je vais surclasser parse_header pour traiter les 1ere ligne et le header
puis parser le rester par les méthodes de Items.
le code du parser
class Gal_parser(Items):'''Gal_parserparser for *.gal filesx = Gal_parser(**arg)options :file_arg -> file path or file handleitem_list -> list of item instances
'''
def __init__(self, **arg):'''x = Gal_parser(**arg)'''#call the init method of ItemsItems.__init__(self, **arg)
def parse_header(self, fhin):'''x.parse_header(fhin)fhin -> fileparse the header of the file.
'''#get the format of the file (1st line of the file)file_format = fhin.readline()#check if it's a ATF fileif not "ATF" in file_format : raise FormatError("%s format is not correct" % fhin.name)#store the file_format dataself.file_format=split(file_format, '\t')
#get the file structure data (2nd line of the file)try : self.nb_header_rows, self.nb_cols=split(fhin.readline(), '\t')except ValueError : self.nb_header_rows = fhin.readline()
self.nb_header_rows = int(self.nb_header_rows)
#create the structure for the headerself.header={}#get all the header lines and parse themfor i in range(self.nb_header_rows) : try : k,v = self.parse_header_line(fhin.readline()) except AttributeError : continue except ValueError : continue self.header[k] = v#set the parse_header flag to true, so it won't be parsed again laterself.flag['parse_header'] = True
def parse_header_line(self, line):'''k,v = x.parse_header_line(line)clean the line and split the key and the value'''#cleaning of the linetry : #remove backspace line = remove_end_line(line) #remove " line=replace(line,'"', '') #remove tab line=replace(line,'\t', '')
except AttributeError : print "no replace for %s" % line raise#split the line with the field separator =#and return the resulting tuple ok key/valuetry : return split(line,"=")except ValueError : print "no = in %s" % line raise
def get_header(self, *arg):'''header = x.get_header(*arg)return the header dictionnaryarg -> keys : return keys of header values : return values of header items : return tuple ok key/value of header'''#check the arg optionif 'keys' in arg : return self.header.keys()if 'values' in arg : return self.header.values()if 'items' in arg : return self.header.items()#if no optionreturn self.header
class FormatError(exceptions.Exception):def __init__(self, msg=''):self.errmsg = msg
def __str__(self):return self.errmsg
j’ai ajouté un classe FormatError pour gérer les erreur de format de fichier.
j’ai modifié la fonction de test
def test_gal_parser(self):'''test si l'heritage fonctionne bien'''file_format="ATF"file_format_version = 1header_row_nb = 2data_col_nb = 3header_key_1 = "key1"header_val_1 = "val1"header_key_2 = "key2"header_val_2 = "val2"col_1 = "col_1"col_2 = "col_2"col_3 = "col_3"data_l1_c1 = "data_l1_c1"data_l1_c2 = "data_l1_c2"data_l2_c1 = "data_l2_c1"data_l2_c2 = "data_l2_c2"data_l2_c3 = "data_c3"data_l1_c3 = "data_c3"test_file='''%s\t%s%s\t%s%s=%s"%s=%s"%s\t%s\t%s%s\t%s\t%s%s\t%s\t%s''' % (file_format, file_format_version,header_row_nb, data_col_nb,header_key_1, header_val_1,header_key_2, header_val_2,col_1, col_2, col_3,data_l1_c1, data_l1_c2, data_l1_c3,data_l2_c1, data_l2_c2, data_l2_c3)self.write_tmp_file(filetext = test_file)test_gal = Gal_parser(file_arg = 'tmp_file')self.assert_(isinstance(test_gal,Gal_parser))self.assert_(len(test_gal.get_header())==2)
self.assert_(test_gal.get_header('keys')==[header_key_2, header_key_1])self.assert_(test_gal.get_header('values')==[header_val_2, header_val_1])self.assert_(len(test_gal)==2)self.assert_(test_gal[0].get_attribute(col_1)==data_l1_c1)
file_format="ATG"test_file='''%s\t%s%s\t%s%s=%s"%s=%s"%s\t%s\t%s%s\t%s\t%s%s\t%s\t%s''' % (file_format, file_format_version,header_row_nb, data_col_nb,header_key_1, header_val_1,header_key_2, header_val_2,col_1, col_2, col_3,data_l1_c1, data_l1_c2, data_l1_c3,data_l2_c1, data_l2_c2, data_l2_c3)self.write_tmp_file(filetext = test_file)self.assertRaises(FormatError, Gal_parser, filename = 'tmp_file')
remove('tmp_file')
test_gal = Gal_parser(file_arg = '/home/gim2/bioinfo/microarray/barcode12k_v2final.gal');self.assert_(isinstance(test_gal,Gal_parser))self.assert_(len(test_gal.get_header())==51)
et le test me renvoie
tmp_file format is not correct.col_0 is not a valide attribute....the argument is not a regular file objectfile toto doesn't existpermission denied for file tmp_parse.txt..----------------------------------------------------------------------Ran 7 tests in 2.844s
OK
j’ai donc un parser de fichier gal qui fonctionne bien.
quel est le but de tout ca ?
l’idée est de parser le fichier de description de la puce et de mettre les infos dans la base de donnée. je cherche également a liéer les spot aux orf du genome de la levure.
j’ai précédemment examiné le fichier gal et d’autre fichiers décrivant les puces (12 mars, 13 mars (1) et 13 mars (2)
l’analyse de ces fichier a permis de constater que l’annotation de certain spot ne coorespond plus a une orf existante. mais que cette ancienne annotation est généralement toujours présente dans les alias des orf.
l’analyse plus fine de cela a meme permis de déterminer que seule 7 annotations avaient réellement totalement disparues.
YAR037W YAR040C YAR043C YCL006C YCL013W YCL026C YCL053C
ce qui correspond a 30 spot au total
grep YCL053C ~/bioinfo/microarray/barcode12k_v2final.gal
1 23 19 YCL053C-U CTATTGTTGAAATGCCGGGA
1 24 19 YCL053C-U CTATTGTTGAAATGCCGGGA
39 23 20 YCL053C-D CATAGTCGAGAACCGGAGAC
39 24 20 YCL053C-D CATAGTCGAGAACCGGAGAC
grep YAR043C ~/bioinfo/microarray/barcode12k_v2final.gal
34 3 8 YAR043C-U ATTCTAGCGGCAGATCCGTG
34 4 8 YAR043C-U ATTCTAGCGGCAGATCCGTG
grep YCL013W ~/bioinfo/microarray/barcode12k_v2final.gal
13 23 22 YCL013W-D CGCTCGAACATAATTGGGTA
13 24 22 YCL013W-D CGCTCGAACATAATTGGGTA
25 23 22 YCL013W-U CCTGTCAGTAAACCGAGAGA
25 24 22 YCL013W-U CCTGTCAGTAAACCGAGAGA
grep YCL026C ~/bioinfo/microarray/barcode12k_v2final.gal
5 23 21 YCL026C-D CCTCCGAACAGAGAGTCTTA
5 24 21 YCL026C-D CCTCCGAACAGAGAGTCTTA
13 3 4 YCL026C-A-U FRM2 GCTCACCGAACATCAGATTA
13 4 4 YCL026C-A-U FRM2 GCTCACCGAACATCAGATTA
17 3 21 YCL026C-U-R CCTCTGCTAAGTAGTAGA
17 4 21 YCL026C-U-R CCTCTGCTAAGTAGTAGA
17 23 21 YCL026C-U CCCTCTGCTAAAGTAGTAGA
17 24 21 YCL026C-U CCCTCTGCTAAAGTAGTAGA
42 5 19 YCL026C-A-D FRM2 GGCGGACTACAACACATTCA
42 6 19 YCL026C-A-D FRM2 GGCGGACTACAACACATTCA
grep YCL006C ~/bioinfo/microarray/barcode12k_v2final.gal
23 23 23 YCL006C-D CCCGCTAGTCAATAATCGTA
23 24 23 YCL006C-D CCCGCTAGTCAATAATCGTA
29 5 15 YCL006C-D CCCGCTAGTCAATAATCGTA
29 6 15 YCL006C-D CCCGCTAGTCAATAATCGTA
35 23 23 YCL006C-U CCTGAAGATAAATCCCGTCA
35 24 23 YCL006C-U CCTGAAGATAAATCCCGTCA
41 5 15 YCL006C-U CCTGAAGATAAATCCCGTCA
41 6 15 YCL006C-U CCTGAAGATAAATCCCGTCA
grep YAR040C ~/bioinfo/microarray/barcode12k_v2final.gal
7 3 9 YAR040C-U CCATCTCAGTGGGTGCAATG
7 4 9 YAR040C-U CCATCTCAGTGGGTGCAATG
grep YAR037W ~/bioinfo/microarray/barcode12k_v2final.gal
23 3 9 YAR037W-U AGCTAGACTATCGCCCAATG
23 4 9 YAR037W-U AGCTAGACTATCGCCCAATG
a
l’ideal serait de faire cette identification lorsque j’ajoute le fichier gal dans la base.
si on suppose que la liste des orf est dans la base de donnée.
il faut donc extraire le nom des annotation des spot, retirer les caractère qui ont été ajouté pour les puc (U, D et R) en faire une liste d’occurences uniques et les rechercher dans la base de données.
je vais faire une premiere version mais en utilisant un fichier gff au lieu de de la base de donnée.
il faut deja récupéré les ID des spots.
pour ca j’utilise la méthode get_attr_list qui me renvoie la liste des valeur d’un attribut pour l’ensemble des items.
j’utilise ensuite un set pour stocker ces valeur, ainsi je n’ai que celles qui sont distincte.
j’utilise ensuite une expression régulière pour eliminer les -D, -U, et -R
def extract_annotation_id(annot_id):return re.sub(r'-[RUD]+[1-9]*','',annot_id)
def analyse_gal_file():gal_file = '/home/gim2/bioinfo/microarray/barcode12k_v2final.gal'gal = Gal_parser(file_arg = gal_file)id = gal.get_attr_list('ID')print "il y a %i ID de spot dans %s" % (len(id), gal_file)id_set = set(id)print "il y a %i ID distintes dans %s" % (len(id_set), gal_file)id=map(extract_annotation_id, id)id_set = set(id)print "il y a %i annotations d'orf dans %s" % (len(id_set), gal_file)
j’obtiens
il y a 27648 ID de spot dans /home/gim2/bioinfo/microarray/barcode12k_v2final.galil y a 12677 ID distintes dans /home/gim2/bioinfo/microarray/barcode12k_v2final.galil y a 5920 annotations d'orf dans /home/gim2/bioinfo/microarray/barcode12k_v2final.gal
j’arrive donc a récupérer les 5920 orf utilisée dans ces puces
il faut ensuite aller les comparer avec celles du fichiers gff
je refais donc un parser gff rapide (ici)
puis je sélectionne les id des orf
gff_file = '/home/gim2/bank//saccharomyces_cerevisiae.gff'
gff = Gff_parser(file_arg = gff_file)
id2 = gff.get_attr_list('ID')
il y a 16316 ID dans /home/gim2/bank//saccharomyces_cerevisiae.gff
si je prends les tag name et gene en plus j’ai :
id2 = gff.get_attr_list('ID') + gff.get_attr_list('Name') + gff.get_attr_list('gene')
il y a 48948 ID, Name et gene dans /home/gim2/bank//saccharomyces_cerevisiae.gff
si j’utilise les set pour connaitre n’avoir que des valeurs distinctes j’ai :
il y a 16316 ID dans /home/gim2/bank//saccharomyces_cerevisiae.gff
il y a 8098 ID distinctes dans /home/gim2/bank//saccharomyces_cerevisiae.gff
il y a 48948 ID, Name et gene dans /home/gim2/bank//saccharomyces_cerevisiae.gff
il y a 12879 ID, Name et gene distincts dans /home/gim2/bank//saccharomyces_cerevisiae.gff
j’ai besoin aussi des alias des orf car ce sont parfois les anciens noms de ces orfs
alias=gff.get_attr_list('Alias') for x in alias : if not x : continue x=split(x,',') id2 += x print len(id2) print 'il y a %i ID, Name, gene et alias dans %s' % (len(id2), gff_file) id_set2 = set(id2) print 'il y a %i ID, Name, gene et alias distincts dans %s' % (len(id_set2), gff_file)
et j’obtiens
il y a 65786 ID, Name, gene et alias dans /home/gim2/bank//saccharomyces_cerevisiae.gffil y a 15774 ID, Name, gene et alias distincts dans /home/gim2/bank//saccharomyces_cerevisiae.gff
je vais donc comparer les id du fichier gal et ceux du fichier gff en faisant une simple différence de set
print "il y a %i ID presente dans %s qui sont absentes de %s" % (len(id_set2), gal_file, gff_file)
print "ce sont les ID : ", id_set.difference(id_set2)
il y a 15774 ID presentes dans /home/gim2/bioinfo/microarray/barcode12k_v2final.gal qui sont absentes de /home/gim2/bank/saccharomyces_cerevisiae.gffce sont les ID : set(['YCL053C', 'YAR043C', 'Spotting Buffer', 'YCL013W', 'Empty', 'YCL026C', 'YCL006C', 'YAR040C', 'YAR037W'])
Ca correspond a celles trouvées précédemment