Archive de la catégorie «python»

29 avril 2008 – interface sganarrayl

avril 29, 2008

11h24 :
Pour faire l’interface d’ajout du fichier gal, j’ai voulu reprendre celle d’ajout du fichier gff.
celle-ci étant assez moyenne, j’ai donc décidé de la reprendre.
pour que ce soit cohérent avec l’interface finale de sganarrayl, il faut deja pensé a l’intégralité de l’interface.
Depuis la page d’accueil pour ajouter des puce, on pourra donc voir la liste des puces disponibles et aussi du fichier de définition des features utilisé.
on pourra depuis cette page aussi ajouter de nouveaux fichiers de puce et de feature.
l’ajout de feature va renvoyer sur la page add_gff.php
cette page propose un champ browse pour parcourir le disque local et ajouter un fichier.
l’envoie du formulaire va renvoyer sur la meme page.
cette fois ci, comme il y a un fichier uploader, ca va déclencher le script php.
celui-ci copie le fichier uploadé dans un répertoire spécifique.
il va aussi modifier la page pour faire apparaitre le nom du fichier traité et faire disparaitre le champs browse.
la page va aussi avoir un script javascript (add_gff.js).
celui-ci va se déclencher s’il y a un nom de fichier a traiter.
dans ce cas il va faire appelle au script add_gff.py pour traiter le fichier gff et renvoyer la réponse qui correspond au traitement et l’afficher.
add_gff.py parse le fichier gff à l’aide des du parser gff de parser_tools puis utilise la classe garden_state du module sganarrayl_interface pour se connecter à la base luce_la_puce et ajouter les feature par la méthode add_feature_data.

add_gff.py renvoie un fichier xml avec les balises ou selon le déroulement du code.
le script javascript va interpréter ce xml et afficher les messages correspondants dans une balise prévue a cette effet et ingénieusement intitulée gff
voici le flux de données


L’interface pour le fichier gff fonctionne bien maintenant et le code est propre.
passons au fichier gal

déroulement de la séquence.
l’utilisateur doit ajouter une puce dans la base.
il va alors aller sur la page add_gal.php.
il n’y a que 2 champs pour le moment.
le premier pour donner un nom à la puce.
le 2eme pour mettre le fichier gal qui contiendra les info sur les spots.
le nom de la puce sera celui utilisé par la suite pour faire référence à celle-ci.
le script va ensuite ajouter le nom de la puce dans la table array_chip_types s’il n’existe pas encore. s’il existe deja, l’ajout de la puce est refusé. par la suite il devra permettre la mise a jour de la puce.
ensuite il faut parcourir chaque spot, déterminer son type, vérifier dans la table array_spot_type si le type existe et sinon l’ajouter. on recherche ensuite dans les features de la table bank_orf qui ont la meme annotation que le spot.
si on trouve on garde la ref de la feature, sinon, la ref est nulle. on ajoute ensuite les info du spot dans la table array_spots, en ajoutant les liaisons vers les tables array_chip_types array_spot_type et bank_orf.

todo -> modifier sganarrayl_interface pour pouvoir sélectionner les id des orf ayant l’annotation du spot

14 avril 2008 – ajout du module de conversion des données

avril 14, 2008

10h48
suite de la construction du parser global.
pour mieux utiliser les données dans le parser, il est utile de les convertir au bon format.
elles sont toutes reconnues comme texte.
les seuls autres types pouvant exister pour des données sont integer ou float.
il pourrait y avoir des booléens mais on va partir du principe qu’il n’y en a pas.
les types listes ou autre propres a python ne sont pas présents dans des fichiers de données.
la conversion des données est intéressante mais ralenti le parsing.
il me semble que malgré tout il y a un gain de temps par la suite
La conversion utilise la fonction try. qui permet e s’affranchir de pas mal de test qui sont réalisé par les fonction de conversion elle-meme. ces fonctions sont int et float.
code du convertisseur

 def set_type(self, value):     '''     val = x.set_type(value)     value -> str     val -> str, int or float     convert the data to the correct data type     '''     #store the data into the return variable     val = value     #try converting     try :         #try first to convert into a float         val = float(value)         #if succeed, try to convert into an integer         val = int(value)     except ValueError:         #catch a converting error, either from float or int         pass     #return the stored value     return val

et le code du test correspondant

 def test_type_parsed_data(self):     '''     teste si le type des donnees parsees est correcte     '''     header_info_1 = "header_01"     header_info_2 = "header_02"     col_1 = "col_1"     col_2 = "col_2"     col_3 = "col_3"     data_l1_c1 = "texte"     data_l1_c2 = 1     data_l2_c1 = 1.5     data_l2_c2 = "1e+5"     test_file='''#%s#%s%s\t%s%s\t%s%s\t%s''' % (header_info_1, header_info_2, col_1, col_2, data_l1_c1, data_l1_c2, data_l2_c1, data_l2_c2)     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     self.assert_(type(test_item[0].get_attribute(col_1)) == type(data_l1_c1))     self.assert_(type(test_item[0].get_attribute(col_2)) == type(data_l1_c2))     self.assert_(type(test_item[1].get_attribute(col_1)) == type(data_l2_c1))     self.assert_(type(test_item[1].get_attribute(col_2)) == type(float(data_l2_c2)))

     remove('tmp_file')

ce qui donne en sortie de la fonction test

..the argument is not a regular file objectfile toto doesn't existpermission denied for file tmp_parse.txt..----------------------------------------------------------------------Ran 4 tests in 0.065s

OK

11h34
le parser est bien avancé. il lui manque quelques fonctions comme l’impression

c’est facile a ajouter. l’impression sera par defaut basique en utilisant les marker et séparateur par défaut.
touts les attributs seront imprimé par défaut.
il sera cependant possible de spécifier ces paramètres

DANS Items def __str__(self, text_sep='', attr_list=[]):     '''     print x  x.__str__()     print the data in a text format, using default options

     '''     #if no text separator was specified, use the default one     if not text_sep : text_sep = self.text_sep     #if no attribute list was specified, use the default one if exist or nothing     if not attr_list :         try :             attr_list = self.attr_list         except AttributeError :             pass     #if header exist add the header_mark at the top of the each line     #and add all lines into the text to print     try :         text_list = map(lambda x: self.header_mark + x , self.header)     except AttributeError :         text_list = []     #if exist, add the attribute list, join by the text separator     if attr_list : text_list += [join(attr_list,text_sep)]     #call the print method of the item using the text separator and the attribute list as options     #and add the resulting text into the text to print     text_list += [item.__str__(text_sep=text_sep, attr_list=attr_list) for item in self]     #join element of the text to print by a \n and return it     return join(text_list, '\n')

DANS Item def __str__(self, text_sep = '\t', attr_list = []):     '''     print x  x.__str__()     print all element of x using tabulation as default text separator     options :     x.__str__([text_sep, [attr_list]])     print only the values of the attributes specified in attr_list     return the values as text using text_sep as text separator

     '''     #if no attribute list, use all the attributes of self         if not attr_list : attr_list = self.keys()     #get the value of the attributes in attr_list or an empty string if attribute does'nt exist     text_val = [self.get(attr, '') for attr in attr_list]     #return the values in a text format join by text_sep     return join(map(str,text_val), text_sep)

et j’ai donc ajouté un module de test pour cette fonction

 def test_printed_data(self):     '''     teste si les donnees parsees sont imprimees correctement     '''     header_info_1 = "header_01"     header_info_2 = "header_02"     col_1 = "col_1"     col_2 = "col_2"     data_l1_c1 = "data_l1_c1"     data_l1_c2 = "data_l1_c2"     data_l2_c1 = "data_l2_c1"     data_l2_c2 = "data_l2_c2"

     #test with a complete file     test_file='''#%s#%s%s\t%s%s\t%s%s\t%s''' % (header_info_1, header_info_2, col_1, col_2, data_l1_c1, data_l1_c2, data_l2_c1, data_l2_c2)     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     self.assert_(test_item.__str__() == test_file)

     #test using a specific attribute list     test_file='''#%s#%s%s\t%s%s\t%s%s\t%s''' % (header_info_1, header_info_2, col_1, col_2, data_l1_c1, data_l1_c2, data_l2_c1, data_l2_c2)     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     attr_list=[col_1]     test_file='''#%s#%s%s%s%s''' % (header_info_1, header_info_2, col_1, data_l1_c1, data_l2_c1)     self.assert_(test_item.__str__(attr_list=attr_list) == test_file)

     #test using a specific text separator     test_file='''#%s#%s%s\t%s%s\t%s%s\t%s''' % (header_info_1, header_info_2, col_1, col_2, data_l1_c1, data_l1_c2, data_l2_c1, data_l2_c2)     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     attr_list=[col_1]     test_file='''#%s#%s%s;%s%s;%s%s;%s''' % (header_info_1, header_info_2, col_1, col_2, data_l1_c1, data_l1_c2, data_l2_c1, data_l2_c2)     self.assert_(test_item.__str__(text_sep=";") == test_file)

     #test with no header     test_file='''%s\t%s%s\t%s%s\t%s''' % (col_1, col_2, data_l1_c1, data_l1_c2, data_l2_c1, data_l2_c2)     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     self.assert_(test_item.__str__() == test_file)

     #test with no attribute list     test_file='''%s\t%s%s\t%s''' % (data_l1_c1, data_l1_c2, data_l2_c1, data_l2_c2)     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     self.assert_(test_item.__str__() == test_file)

     #test with no data     test_file='''%s\t%s''' % (col_1, col_2)     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     self.assert_(test_item.__str__() == test_file)

     #test with only header     test_file='''#%s#%s''' % (header_info_1, header_info_2)     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     self.assert_(test_item.__str__() == test_file)

     #test with nothing     test_file=''     self.write_tmp_file(filetext = test_file)     test_item = Items(file_arg = 'tmp_file')     self.assert_(test_item.__str__() == test_file)

     remove('tmp_file')     def valid_object(self, nb_header_line, nb_col, nb_line):     '''     x.valid_object(nb_header_line, nb_col, nb_line)     create a tmp file with the given parameters     parse the file using Items     test if all data have been correctly parsed     '''     #create the name of the file using the parameters (it could have been an arbitrary filename)     filename = 'file_%s_%s_%s' % (nb_header_line, nb_col, nb_line)     #call the method for creating the file     self.create_tmp_file(filename, nb_header_line, nb_col, nb_line)

     self.valid_item(filename=filename, nb_header_line=nb_header_line, nb_col=nb_col, nb_line=nb_line)

     #delete te tmp file     self.delete_tmp_file(filename)

qui renvoie

...the argument is not a regular file objectfile toto doesn't existpermission denied for file tmp_parse.txt..----------------------------------------------------------------------Ran 5 tests in 0.065s

OK

je vais aussi ajouter une fonction assez pratique au parser.
il s’agit d’une sorte d’index des infos qui sont dans les attributs.
je ne suis pas sur que ce soit pertinenet car ca risque d’etre lourd d’un point de vue traitement.
il faut probablement que ce soit fait a la demande.
comment procéder ?
il faut une fonction de requete.
cette fonction va créer l’index nécessaire s’il n’existe pas et rechercher dedans par la suite.
elle va donc passer par une fonction de création d’index. cette fonction var créer l’index souhaité pour le ou les attributs passé en argument.
en laissant la possibilité d’avoir plusieurs attributs en argument, on s’assure que la fonction pourra etre utilisée dans d’autre cas, comme la création de ces index de manière explicite.
si aucun argument est passé a cette fonction alors l’ensemble des index pour chaque attribut sera créé (risque d’etre long)

def create_indexes(self, attr_list=[]):       '''       x.create_indexes([attr_list])       attr_list -> list of string or str       create indexes for a list of attribute       '''       #test if there is an argument       if not attr_list :           #if not try to get the default attribute list           try :               attr_list = self.attr_list           except AttributeError :               #catch the error if it does'nt exist               print "no attribute for these data, indexes cannot be created"               #and stop function by raising error               raise       #build the index for each item       map(lambda x : self.build_index(x, attr_list), self)

   def build_index(self, item, attr_list):       '''       x.build_index(item, attr_list)       item -> instance of item       attr_list -> list of str or str       '''       #if attr_list is a single string, convert, put it in a list       if type(attr_list) == str : attr_list=[attr_list]       #for each attr       for attr in attr_list :           #test if it's a valid attribute           if attr not in self.attr_list :               print "%s is not a valide attribute" % attr               continue           #try to access to the value associated with the key attr           #if it doesn't exist, create the key as an empty dict and return it           try :               attr_index_list = self.indexes.setdefault(attr,{})           except AttributeError :               #catch the error if the attribute indexes does'nt exist,               #and create it               self.indexes = {}               attr_index_list = self.indexes.setdefault(attr,{})           #get the list associated with the key of the attribute of the item           #or an empty list if the key does'nt already exist           attr_index_item_list = attr_index_list.setdefault(item.get_attribute(attr), [])           #add item into this list           attr_index_item_list.append(item)

   def get_items_by_value(self, attr, value):       '''       item_list = x.get_items_by_value(attr, value)       attr -> str       value -> str, int or float       item_list -> instance of Items       return a list of items having a specified value for the attribute attr       '''

       try :           #check if the attr is in the attribute list           if attr not in self.attr_list :               #if not raise a keyError               print "%s is not a valide attribute" % attr               raise IndexError, "%s is not a valide attribute" % attr       except AttributeError :           #catch the AttributeError if ther is no attribute list           print "no attribute list available"           raise       #try to access to the index of the given attribute       try :           attr_index_list = self.indexes[attr]       except AttributeError :           #catch the error if the attribute indexes doesn't exist           #or if the key attr does'nt exist           #the index for the given attribuite is created           self.create_indexes(attr)           #and put into attr_index_list           attr_index_list = self.indexes[attr]       except KeyError :           #catch the error if the attribute indexes doesn't exist           #or if the key attr does'nt exist           #the index for the given attribuite is created           self.create_indexes(attr)           #and put into attr_index_list           attr_index_list = self.indexes[attr]       #return an instance of items with the list of the items matching with the given value       return Items(item_list = attr_index_list.get(value, []))   

j’ai du coup du modifier un peu le __init__ pour qu’il accepte des liste de item pour créer l’objet. cela permet dans une fonction de recherche de renvoyer un sous ensemble de l’objet de la meme forme que l’objet (une instance de items) plutot que une simple liste.
j’ai ajouté le code de test correspondant

def test_indexed_data(self):       '''       teste si les index creer sont correct       '''       header_info_1 = "header_01"       header_info_2 = "header_02"       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#%s%s\t%s\t%s%s\t%s\t%s%s\t%s\t%s''' % (header_info_1, header_info_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_item = Items(file_arg = 'tmp_file')       items_index_1 = test_item.get_items_by_value(col_1, data_l1_c1)       self.assert_(isinstance(items_index_1,Items))       self.assert_(len(items_index_1)==1)       self.assert_(isinstance(items_index_1[0], Item))       self.assert_(items_index_1[0].get_attribute(col_1) == data_l1_c1)

       items_index_2 = test_item.get_items_by_value(col_3, data_l1_c3)       self.assert_(isinstance(items_index_2,Items))       self.assert_(len(items_index_2)==2)       self.assert_(isinstance(items_index_2[0], Item))       self.assert_(isinstance(items_index_2[1], Item))       self.assert_(items_index_2[0].get_attribute(col_3) == data_l1_c3)       self.assert_(items_index_2[1].get_attribute(col_3) == data_l2_c3)

       items_index_3 = test_item.get_items_by_value(col_1, 'toto')       self.assert_(isinstance(items_index_3,Items))       self.assert_(len(items_index_3)==0)       self.assertFalse(items_index_3)

       self.assertRaises(IndexError, test_item.get_items_by_value, attr = 'col_0', value = 'toto')     

       remove('tmp_file')

le test renvoie alors

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 6 tests in 0.170s

OK

Le parser a l’air a peu pret complet, a voir a l’usage.
–> todo list tester le parser sur un plus gros fichier, type gal

1er avril 2008 – détermination du maximum des segments de sage

avril 1, 2008

les résultats de la manip de sage se présentes sous la formes de séquences dont une partie a été identifiée et localisée sur le génomes.
ces séquences ou tag, sont répartis de façon non aléatoire sur le génome et foirmes des groupes ou cluster.
l’identification de ces cluster a été effectuée par la méthode CNC (Closest Neighbour Clustering). cette méthode met bout a bout chaque brins de tous les chromosomes de la levure. on parcours ensuite l’ensemble du génome ainsi formé jusqu’a ce qu’un sage soit rencontré. on enregistre cette position (S0) puis on parcours a nouveau le génome. si on rencontre a nouveau un sage entre la position sur une distance N depuis la position du sage précédent, on enregistre cette nouvelle position pui on parcours a nouveau le génome sur une distance N et on note si un sage est présent sur cette distance. on repète cette opération tant qu’un sage est trouvé. si aucun sage est trouvé on note la position du dernier sage trouvé (E). on calcule alors entre les position S et E combien de sage il y a et s’il y en a plus que le seuil limite n (a déterminé au préalable) alors on considère que la zone de S à E est un cluster.
puis on recommence la recherche.
cette recherche a donc 2 paramètres, N et n, qui sont très important et font varier les résultats de façon importante.
en prennant N = 100 et n = 1, on obtient 14258 segments.
les résultats sont stockés dans le fichier ~/sage/total/stats/ratio2_5.mat
ils se présente sous la forme d’une matrice avec 11 colonnes (ratio2_5_100_1)
colonnes :
1 -> ratio Wt oligo d(T) / (Wt oligo d(T) + Cbp20-TAP)
2 -> position du start du segment sur le genome reconstitué
3 -> position du end du segment sur le genome reconstitué
4 -> nb de tag dans le segment
5 -> nb de tag dans le segment
6 -> reference du chromosome
7 -> start du segment sur lme chromosome
8 -> end du segment sur le chromosome
9 -> taille du segment
10 -> classe du segment (de 1 à 10 en fn du ratio)

Je dois a partir de cette matrice retrouver la position dans chaque segment pour laquelle le nb de tag est maximale.
j’ai écrit un script simple.
je parcours la matrice ligne par ligne.
je récupére les positions start et end du segment considéré sur le génome linearisé (stocké dans la matriceheader cette matrice a 24millions de lignes et 7 colonnes. ces colonnes correspondent a : 1-> manip 1 à 10; 2-> manip 1 & 2; 3-> manip 1 à 8; 4-> manip 1,2,3,4,9 et 10; 5-> manip 1,2, 7 et 8; 6-> manip 7 & 8; 7-> manip 1 à 12; c’est la colonne 5 qui nous intéresse dans ce cas)
j’extrait le segment du genome
je recherche le max de ce segment et détermine sa position dansle segment
si j’en ai plusieurs, je garde que le premier
je calcule la position du max dans le chromosome en l’ajoutant a celle du strat
je rajoute une colonne dans la matrice ratio2_5_100_1 ou je stocke cette valeur
et voila

for i=1:size(ratio2_5_100_1,1)d= ratio2_5_100_1(i,2);f=ratio2_5_100_1(i,3);segment=header(d:f,5);max_seg=find(segment==max(segment));ratio2_5_100_1(i,11)=ratio2_5_100_1(i,7) + max_seg(1) - 1;end

cette matrice est ensuite expostée en format texte tabulé avec l’extension .csv.mat par la fonction ~/sage/total/stats/save_mat.m
le fichier créé a été sauvegardé dans ~/sage/total/stats/max_segments/ratio2_5_100_1.mat.csv
je l’ai ensuite envoyé sur duanierousseau
je l’ai traité alors avec le programme ~/workspace/genepy/src/.segment.py
tout d’abord j’ai converti le fichier .csv.mat en fichier .csv lisible par excel ou openOffice

def matlab2csv(segment_path):

##===============================================================================##           Conversion fichier matlab en fichier csv##===============================================================================print "loading %s" % segment_pathfhin_mat=open("%s.mat.csv" % segment_path,'r')matlab_txt = convert_mat_file(fhin_mat)fhin_mat.close()fhin_csv=open("%s.csv" % segment_path,'w')print >>fhin_csv,"ratio\tstart_gen\tend_gen\tnb1\tnb2\tgenome_pos\tstart\tend\twidth\tgroup\tmaxi"print >>fhin_csv, matlab_txtfhin_csv.close()

le fichier crée est /home/gim2/sage/total/stats/ratio2_5/max_segments/ratio2_5_100_1.csv
puis j’ai déterminer la position des features mais en me basant non plus comme je l’ai deja fait sur le milieu des segment mais sur son maximum

def fetch_features_around_segment(segment_path):#===============================================================================#  recherche des features environantes des segments#===============================================================================#    segment_path = '%ssegments_location%s' % (dir_region, suffixe)seg_list = Segment_list(file = "%s.csv" % segment_path)print "%s read" % segment_pathdb_path='%s/bank/saccharomyces_cerevisiae.gff' % homedb_features = DBGFF.DB(db_path)fhout_path = '%ssegments_description%s' % (dir_region, suffixe)fhout = open("%s.csv" % fhout_path, 'w')segment_info_list=('id','chr', 'strand','start','end','maxi','nb1', 'ratio', 'group')feature_info_list=('feature_up_sens_name', 'feature_up_sens_gene', 'feature_up_sens_start_to_segment', 'feature_up_sens_end_to_segment',             'feature_down_sens_name', 'feature_down_sens_gene', 'feature_down_sens_start_to_segment', 'feature_down_sens_end_to_segment',             'feature_up_antisens_name', 'feature_up_antisens_gene', 'feature_up_antisens_start_to_segment', 'feature_up_antisens_end_to_segment',             'feature_down_antisens_name', 'feature_down_antisens_gene', 'feature_down_antisens_start_to_segment', 'feature_down_antisens_end_to_segment',             'feature_overlap_sens_name', 'feature_overlap_sens_gene', 'feature_overlap_sens_start_to_segment', 'feature_overlap_sens_end_to_segment',             'feature_overlap_antisens_name', 'feature_overlap_antisens_gene', 'feature_overlap_antisens_start_to_segment', 'feature_overlap_antisens_end_to_segment')print >>fhout, "%s\t%s" % (join(segment_info_list, '\t'),join(feature_info_list, '\t') )               

current_chr = ''no_feature_txt = 'no feature found'for segment in seg_list :    mid = segment.get_attribute('mid')    mid = segment.get_attribute('maxi')    chr = segment.get_attribute('chr')    rev = segment.get_attribute('rev')    if chr != current_chr:        feature_chr = db_features.getDBChr2(chr)        current_chr = chr        feature_w = feature_chr.select('rev', False)        feature_c = feature_chr.select('rev', True)        f_start_w = feature_w.get_list_attr('start')        f_end_w = feature_w.get_list_attr('end')        f_coord_w = zip(f_start_w, f_end_w)        f_w = dict(zip(f_coord_w, feature_w))        f_start_c = feature_c.get_list_attr('start')        f_end_c = feature_c.get_list_attr('end')        f_coord_c = zip(f_start_c, f_end_c)        f_c = dict(zip(f_coord_c, feature_c))        key_w = f_w.keys()        key_w.sort(key=operator.itemgetter(0))

        key_c = f_c.keys()        key_c.sort(key=operator.itemgetter(0))        print chr

    dist_f_start_w = map(lambda x : x - mid, f_start_w)    dist_f_end_w = map(lambda x : x - mid, f_end_w)    dist_f_start_c = map(lambda x : x - mid, f_start_c)    dist_f_end_c = map(lambda x : x - mid, f_end_c)

    dist_f_start_w_up = filter(lambda x : x  0, dist_f_start_w)    dist_f_end_w_down = filter(lambda x : x > 0, dist_f_end_w)    dist_f_start_c_up = filter(lambda x : x  0, dist_f_start_c)    dist_f_end_c_down = filter(lambda x : x > 0, dist_f_end_c)

    f_start_w_up = extreme(dist_f_start_w_up, max)    f_end_w_up = extreme(dist_f_end_w_up, max)    f_start_w_down = extreme(dist_f_start_w_down, min)    f_end_w_down = extreme(dist_f_end_w_down, min)    f_start_c_up = extreme(dist_f_start_c_up, max)    f_end_c_up = extreme(dist_f_end_c_up, max)    f_start_c_down = extreme(dist_f_start_c_down, min)    f_end_c_down = extreme(dist_f_end_c_down, min)

    f_coord_w_up = (f_start_w_up + mid, f_end_w_up + mid)    f_coord_w_down = (f_start_w_down + mid, f_end_w_down + mid)    f_coord_c_up = (f_start_c_up + mid, f_end_c_up + mid)    f_coord_c_down = (f_start_c_down + mid, f_end_c_down + mid)

#                print mid#                print f_coord_w_up#                print f_coord_w_down#                print f_coord_c_up#                print f_coord_c_down

    f_start_w_over = 0    feature_w_up = f_w.get(f_coord_w_up, None)    while not feature_w_up :        if not f_start_w_up :            break        f_start_w_over = f_start_w_up        dist_f_start_w_up.remove(f_start_w_up)        f_start_w_up = extreme(dist_f_start_w_up, max)        f_coord_w_up = (f_start_w_up + mid, f_end_w_up + mid)

        feature_w_up = f_w.get(f_coord_w_up, None)

    f_end_w_over = 0    feature_w_down = f_w.get(f_coord_w_down, None)    while not feature_w_down :        if not f_end_w_down :            break        f_end_w_over = f_end_w_down        dist_f_end_w_down.remove(f_end_w_down)        f_end_w_down = extreme(dist_f_end_w_down, min)        f_coord_w_down = (f_start_w_down + mid, f_end_w_down + mid)        feature_w_down = f_w.get(f_coord_w_down, None)

    f_start_c_over = 0    feature_c_up = f_c.get(f_coord_c_up, None)    while not feature_c_up :        if not f_start_c_up :            break        f_start_c_over = f_start_c_up        dist_f_start_c_up.remove(f_start_c_up)        f_start_c_up = extreme(dist_f_start_c_up, max)        f_coord_c_up = (f_start_c_up + mid, f_end_c_up + mid)

        feature_c_up = f_c.get(f_coord_c_up, None)

    f_end_c_over = 0    feature_c_down = f_c.get(f_coord_c_down, None)    while not feature_c_down :        if not f_end_c_down :            break        f_end_c_over = f_end_c_down        dist_f_end_c_down.remove(f_end_c_down)        f_end_c_down = extreme(dist_f_end_c_down, min)        f_coord_c_down = (f_start_c_down + mid, f_end_c_down + mid)        feature_c_down = f_c.get(f_coord_c_down, None)

    f_coord_w_over = (f_start_w_over + mid, f_end_w_over + mid)    feature_w_over = f_w.get(f_coord_w_over, None)

    f_coord_c_over = (f_start_c_over + mid, f_end_c_over + mid)    feature_c_over = f_c.get(f_coord_c_over, None)

    if rev :        feature_sens_up = feature_c_down        f_dist_sens_up = (f_end_c_down,f_start_c_down)        feature_sens_down = feature_c_up        f_dist_sens_down = (f_end_c_up,f_start_c_up)        feature_anti_up = feature_w_down        f_dist_anti_up = (-f_start_w_down,-f_end_w_down)        feature_anti_down = feature_w_up        f_dist_anti_down = (-f_start_w_up,-f_end_w_up)        feature_sens_over = feature_c_over        f_dist_sens_over = (f_end_c_over,f_start_c_over)        feature_anti_over = feature_w_over        f_dist_anti_over = (-f_start_w_over,-f_end_w_over)

    else :        feature_sens_up = feature_w_up        f_dist_sens_up = (-f_start_w_up,-f_end_w_up)        feature_sens_down = feature_w_down        f_dist_sens_down = (-f_start_w_down,-f_end_w_down)        feature_anti_up = feature_c_up        f_dist_anti_up = (f_end_c_up,f_start_c_up)        feature_anti_down = feature_c_down        f_dist_anti_down = (f_end_c_down,f_start_c_down)        feature_sens_over = feature_w_over        f_dist_sens_over = (-f_start_w_over,-f_end_w_over)        feature_anti_over = feature_c_over        f_dist_anti_over = (f_end_c_over,f_start_c_over)

    fhout.write(segment.__str__(segment_info_list))    feature_info = ()    if feature_sens_up :        feature_sens_up_info = (feature_sens_up.getattribute('name'),feature_sens_up.getattribute('gene')) + f_dist_sens_up    else :        feature_sens_up_info = ('', '', '', '')    feature_info += feature_sens_up_info

    if feature_sens_down :        feature_sens_down_info = (feature_sens_down.getattribute('name'),feature_sens_down.getattribute('gene')) + f_dist_sens_down    else :        feature_sens_down_info = ('', '', '', '')    feature_info += feature_sens_down_info

    if feature_anti_up :        feature_anti_up_info = (feature_anti_up.getattribute('name'),feature_anti_up.getattribute('gene')) + f_dist_anti_up    else :        feature_anti_up_info = ('', '', '', '')    feature_info += feature_anti_up_info

    if feature_anti_down :        feature_anti_down_info = (feature_anti_down.getattribute('name'),feature_anti_down.getattribute('gene')) + f_dist_anti_down    else :        feature_anti_down_info = ('', '', '', '')    feature_info += feature_anti_down_info

    if feature_sens_over :        feature_sens_over_info = (feature_sens_over.getattribute('name'),feature_sens_over.getattribute('gene')) + f_dist_sens_over    else :        feature_sens_over_info = ('', '', '', '')    feature_info += feature_sens_over_info

    if feature_anti_over :        feature_anti_over_info = (feature_anti_over.getattribute('name'),feature_anti_over.getattribute('gene')) + f_dist_anti_over    else :        feature_anti_over_info = ('', '', '', '')    feature_info += feature_anti_over_info

    if feature_sens_over and feature_anti_over :        print mid#                    feature_over_info = zip(feature_sens_over_info, feature_anti_over_info)#                    feature_over_info = tuple(map(lambda x : join(x, ' / ') , feature_over_info))    print >>fhout, join(map(str,feature_info), '\t')fhout.close()

le fichier créé est /home/gim2/sage/total/stats/ratio2_5/max_segments/ segments_description2_5_100_1.csv
le fichier est ouvert avec excel sur bambino et la macro du fichier F:/users/christophe/search_features_A_and_B.xlsest utilisée pour trouver les features A & B et pour classifier les segment
j’obtiens le fichier F:/users/christophe/segment_distance_to_features_using_max.xls
j’exporte ce fichier sur douanierousseau.
je vais comparer la classification obtenue evec celle obtenue pour le calcul des distance avec le milieu des segments.
j’ai donc 2 fichiers
~sage/total/stats/ratio2_5/max_segments/segment_distance_to_features_using_max.xls
~sage/total/stats/ratio2_5/max_segments/segment_distance_to_features_using_mid.xls
j’utilise la fonction grep pour trouver toute les catégories

cut -f42 segments_distance_to_feature_using_mid.txt | sort | uniq > categories

et j’ai dans categories

11010010410811112121314151623456789

j’utilise grep pour compter chacune des lignes appartenant a ces catégories

while read line   do       n=$(cut -f42 segments_distance_to_feature_using_mid.txt | sort | grep -w $line -c)       echo categorie $line    $n segments   done &lt categories

et je récupère pour les deux fichiers

 
catégorie mid to feature max to feature
1 2417 2451
2 196 0
3 1334 1388
4 22 0
5 1103 1133
6 240 0
7 2012 2083
8 33 0
9 1535 1571
10 218 0
11 1494 1571
12 24 0
13 1917 2024
14 378 0
15 1225 1271
16 24 0
100 11 137
104 21 193
108 32 162
112 23 274

les résultats sont assez proche mais on vois que certaine catégories ont disparues au profit des catégories non définies àla fin.
je referai le point sur ces catégories pour savoir exactement ce qu’il se passe.

14 mars 2008 – recherche d’un module R pour python

mars 14, 2008

14h12 : Pour SganArrayl il va etre nécessaire de traiter les valeurs par des modules statistiques accessibles dans des package R.
comme je compte tout refaire en python, l’idéal serait d’interfacer avec R a partir de python.
il me faut donc un module pour ca.
une petite recherche de google donne déja un premier apercu de ce qu’il existe.
première piste

Il n’y a pas vraiment d’autre module d’interface avec R. je vais essayer celui la.
au passage j’ai trouvé un document qui met en correspondance les fonction matlab, R et Python (NumPy). très pratique je pense. on le trouve ici : http://www.scribd.com/doc/26685/Matlab-Python-and-R
document.write(”);

Read this doc on Scribd: Matlab, Python, and R

var scribd_doc = new scribd.Document(26685, ‘ffe3v3jpfltbv’); scribd_doc.write(‘embedded_flash_26685_o9kh7′);
avec le document c’est encore mieux

————–edit du 25 mars 2008——————–
bon, j’ai pas mal galéré avec le module RSPython.
j’avais d’ailleurs trouvé un autre module, RPython (http://rpy.sourceforge.net/) mais pas vraiment plus simple a installer.
j’ai installé rpy très facilement sur douanierousseau / ubuntu feisty avec synaptic.
par contre j’ai essayé sur berthemorisot et ca a été beaucoup plus dur.
premier esssai sudo yum install rpy
ca semble s’installer mais bien sur quand je lance python et que j’importe le module rpy j’ai une erreur.
je télécharge le fichier source du module et décide de le compiler moi-meme, ce qui me permettra de l’installer dans python2.5 installer sur berthemorisot dans le répertoire tools de l’utilisateur gim.
dans le fichier d’instruction d’installation, il est précisé que R doit etre installé en librairies partagées. j’ai supposé que c’était le cas et j’ai essayé d’installé le package rpy mais ca n’a pas marché.
j’ai essayé de réinstallé R par yum mais ca n’a pas marché non plus.
j’ai essayé d’ajouter au pythonpath les répertoires ou se trouve rpy.
ca m’a permis de faire import rpy mais j’avais une erreur. impossible de trouver le module _rpy2041.so.
comme je l’ai sur ma machine, je le copie sur berthemorisot, mais ca ne marche pas, il faut qu’il soit compilé sur la machine ou il est installé.
je fini par télécharger la source de R, la réinstaller avec l’option qui va bien, ce qui se passe très bien sur centos.
puis je réinstalle rpy
j’ai encore qq erreur due aux chemin d’accès qui ne sont pas mis tout seul dans le pythonpath.
je rajoute les bons chemins et je modifie un peu rpy.py (voir ici).
au final ca marche sur python2.5, c cool.
tous les tests ne passent pas mais bon, on verra a l’usage.
j’ai réussi a m’en servir un peu qd meme. sur les fonction de base, pas de problème, l’interface est très simple.
je mettrais un tutorail en ligne dés que je commencerais a m’en servir vraiment.

12 mars 2008 – recupération des information des microarray

mars 12, 2008

12h03 : les données des puces ne sont pas très simple a récupérée sachant que d’une part les tag sur les spot sont liées a des régions dont l’annotation peut avoir changer depuis le premier design de la puce et que d’autre part certaine séquence de la puce n’ont pas été bien séquencées.
j’ai ecrit 2 parser simple en python pour parser le fichier gal (/home/gim2/workspace/SganArrayL/src/gal_parser.py) et le fichier contenant l’ensemble des délétion (/home/gim2/workspace/SganArrayL/src/deletion_parser.py)
j’ai ainsi pu parser les fichiers barcode12k_v2final.gal et Deletion_primers_PCR_sizes.txt
grace aux méthodes objets créés lors du parsing, j’ai pu verifier quelles séquences du fichiers gal étaient présentes dans le fichiers de description des délétions
j’ai utilisé des set pour cette recherche, c’est très rapide et très pratique pour croisé 2 set de données.
le programme renvoie ceci

ouverture de barcode12k_v2final.gal en 2.764 secbarcode12k_v2final.gal contient 27648 lignesouverture de Deletion_primers_PCR_sizes.txt en 3.048 secDeletion_primers_PCR_sizes.txt contient 6363 lignesbarcode12k_v2final.gal contient 12683 tags distinctsDeletion_primers_PCR_sizes.txt contient 12481 tags distincts688 elements de Deletion_primers_PCR_sizes.txt sont absents de barcode12k_v2final.gal890 elements de barcode12k_v2final.gal sont absents de Deletion_primers_PCR_sizes.txt

*****Edit du 14 mars 2008*****
On vois qu’un certain nombre de tag du fichier gal ne sont pas dans le fichier de deletion. cela provient du fait que certain tag ont été mal séquencés a l’origine. ils ont donc été resequencés et la bonne séquence a été introduites dans le fichier gal.
si je fais un grep sur le fichier barcode12k_v2final.gal en recherchant les ligne qui ont un -R dans le nom de l’orf, que je garde juste la colone du nom d’orf, et que je compte les occurences uniques(grep "\-R" barcode12k_v2final.gal | cut -f4 | uniq |wc) j’obtiens 889 nom d’orf avec un -R (par exemple YDR242W-U-R, YHR005C-D-R, YDR246W-U-R, YHR028C-U-R) vu que le nombre est presque identique a celui des séquences du fichier gal absentes du fichier de délétion, j’en déduis que les ligne avec un nom d’orf en -R correspondent a des spot pour lesquels les tag étaient mal séquencés et qu’il ont été réparés.
si je modifie le programme pour récupéré les id des 890 spot dont les tag ne sont pas dans le fichier de délétion, je constate que ce sont bien les id avec -R, ce qui confirme ma supposition

ouverture de barcode12k_v2final.gal en 3.120 sec
barcode12k_v2final.gal contient 27648 lignes
ouverture de Deletion_primers_PCR_sizes.txt en 1.620 sec
Deletion_primers_PCR_sizes.txt contient 6363 lignes
('Sequence',)
barcode12k_v2final.gal contient 12683 tags distincts
('UPTAG', 'DNTAG')
Deletion_primers_PCR_sizes.txt contient 12481 tags distincts
688 elements de Deletion_primers_PCR_sizes.txt sont absents de barcode12k_v2final.gal
890 elements de barcode12k_v2final.gal sont absents de Deletion_primers_PCR_sizes.txt
liste des 890 id spot present dans barcode12k_v2final.gal et absent de Deletion_primers_PCR_sizes.txt
YDR178W-U-R YIR012W-D-R YNL074C-D-R YDR033W-D-R YPR148C-U-R YCR014C-U-R YLR124W-U-R YPR002W-U-R YML050W-U-R YOL015W-U-R
YGL133W-U-R YJR121W-U-R YLR257W-U-R YNR012W-U-R YDR503C-D-R YJR036C-U-R YEL072W-U-R YKR073C-U-R YDR197W-D-R YKL212W-U-R
YJL139C-U-R YDR400W-U-R YLR432W-D-R YCR083W-D-R YHR008C-D-R YER122C-U-R YLR186W-U-R YML068W-U-R YBR123C-D-R YNL139C-D-R
YGR115C-D-R YDR082W-U-R YLL040C-U-R YNL003C-D-R YPR148C-D-R YMR116C-U-R YMR032W-U-R YNR052C-D-R YKL015W-D-R YKL025C-U-R
YOR179C-D-R YDL161W-U-R YER141W-D-R YOL143C-D-R YKL079W-D-R YAL016W-U-R YOR235W-U-R YJR055W-U-R YER135C-D-R YBL043W-U-R
YOL159C-U-R YOR017W-U-R YGL246C-D-R YLR085C-D-R YOR312C-U-R YER091C-D-R YNR006W-D-R YDR096W-U-R YGR053C-U-R YCR095C-D-R
YMR133W-D-R YFR024C-A-D-R YKL077W-D-R YJL180C-D-R YML115C-U-R YPL078C-U-R YHR125W-D-R YKL166C-U-R YDR504C-U-R YOL056W-D-R
YOR091W-D-R YLR239C-D-R YPR199C-D-R YOR374W-D-R YKR082W-D-R YGR253C-U-R YJL191W-D-R YOL136C-D-R YJR084W-U-R YOR356W-U-R
YIL154C-D-R YOR364W-D-R YNL300W-D-R YLR110C-D-R YMR210W-D-R YNL284C-U-R YGR046W-D-R YPL047W-U-R YDL099W-U-R YDR348C-U-R
YOL118C-U-R YKL002W-D-R YOR170W-U-R YNL117W-U-R YBL008W-D-R YCR090C-D-R YMR172W-D-R YDR300C-U-R YOL043C-D-R YER110C-D-R
YDL020C-U-R YNL014W-D-R YKR006C-U-R YDL199C-D-R YOL013W-A-D-R YGL141W-U-R YGL002W-D-R YOL052C-D-R YKR074W-D-R YDR079W-U-R
YBR047W-U-R YLR341W-D-R YGL036W-U-R YGL041C-U-R YPL049C-U-R YPL270W-U-R YDR043C-D-R YDL146W-D-R YNR047W-U-R YER031C-D-R
YML122C-U-R YDR125C-D-R YGR281W-U-R YGL123W-U-R YNL131W-D-R YLR358C-U-R YOL098C-D-R YPL243W-U-R YDR242W-U-R YNL113W-D-R
YDR507C-U-R YJR011C-U-R YDL005C-U-R YFR057W-U-R YMR041C-U-R YNL237W-U-R YLR060W-U-R YKL009W-U-R YAL047C-U-R YGL094C-D-R
YJR104C-D-R YPL015C-D-R YML117W-A-D-R YLR390W-U-R YNL064C-D-R YJR090C-U-R YKR050W-D-R YBR295W-U-R YCR094W-D-R YPR105C-D-R
YCL038C-U-R YIL114C-D-R YKL138C-U-R YKR057W-D-R YCR063W-U-R YNL015W-D-R YHR167W-D-R YDR525W-A-D-R YLR366W-U-R YIL015W-U-R
YDL236W-U-R YMR201C-D-R YIL118W-U-R YDR113C-U-R YGR165W-U-R YKR014C-D-R YFR027W-D-R YBL102W-D-R YJR097W-U-R YLR423C-U-R
YGR223C-U-R YNL135C-U-R YKL188C-D-R YDR237W-U-R YGR086C-D-R YOR150W-D-R YGR040W-U-R YER095W-D-R YLL057C-D-R YDR216W-D-R
YNL276C-D-R YDR384C-U-R YCR102W-A-D-R YOL163W-D-R YPL187W-D-R YIL034C-U-R YEL009C-D-R YLR420W-D-R YLR431C-D-R YDL117W-U-R
YHR038W-D-R YBR046C-D-R YOR258W-U-R YJL172W-D-R YDR056C-D-R YHR185C-D-R YLR134W-D-R YFL010C-D-R YPR154W-U-R YGR136W-U-R
YKL081W-D-R YPL076W-U-R YGR110W-U-R YKL135C-D-R YDR041W-D-R YDL233W-U-R YKL084W-U-R YNL066W-D-R YNL224C-U-R YPR137W-U-R
YJR119C-U-R YFR049W-U-R YER134C-U-R YOR120W-U-R YJL088W-D-R YDR027C-D-R YDR455C-D-R YGL034C-D-R YGR028W-D-R YDR177W-D-R
YNL050C-D-R YLR052W-D-R YKR072C-D-R YMR121C-D-R YMR275C-U-R YDL196W-D-R YBL046W-D-R YGL147C-D-R YHL034C-U-R YGR051C-U-R
YDL146W-U-R YNR040W-D-R YER117W-U-R YMR302C-D-R YKL069W-D-R YPL069C-U-R YMR021C-U-R YHR178W-U-R YBR161W-D-R YER013W-D-R
YKL041W-U-R YFR010W-D-R YDR270W-U-R YOR133W-U-R YHR110W-D-R YCL024W-U-R YJR024C-D-R YOL077C-D-R YMR129W-D-R YML054C-U-R
YDL234C-U-R YGL171W-U-R YJR107W-U-R YBR278W-U-R YFL044C-U-R YLR328W-D-R YKR098C-D-R YJR124C-U-R YLR130C-D-R YJR091C-D-R
YNL101W-D-R YGL160W-U-R YKL159C-D-R YCR061W-D-R YMR004W-D-R YGR277C-U-R YOR386W-U-R YJL027C-U-R YKL042W-D-R YPL215W-D-R
YDR246W-U-R YDR006C-D-R YGR195W-D-R YBR231C-D-R YML096W-D-R YMR232W-D-R YER014W-D-R YKR044W-D-R YMR227C-U-R YNL141W-D-R
YNL023C-U-R YNL330C-U-R YBR109C-D-R YOR361C-U-R YBR273C-D-R YDR199W-U-R YNL266W-U-R YNL028W-D-R YBR112C-U-R YGR279C-U-R
YJL163C-D-R YLR139C-D-R YPR036W-U-R YDL065C-U-R YKL169C-U-R YGR086C-U-R YDR365C-U-R YPR044C-U-R YKL096W-A-D-R YIR003W-U-R
YJL110C-D-R YCL034W-U-R Empty YPR190C-D-R YMR175W-D-R YPL061W-U-R YPR195C-D-R YLR004C-D-R YML082W-U-R YJL106W-D-R
YKR035C-D-R YPL194W-D-R YNL011C-U-R YBR054W-U-R YNL010W-D-R YHR161C-U-R YBR152W-D-R YPL078C-D-R YFL013W-A-D-R YOR200W-D-R
YLR452C-U-R YPL113C-U-R YLR275W-U-R YLR033W-D-R YPL194W-U-R YLR238W-U-R YFL063W-D-R YMR326C-D-R YKL213C-U-R YFR041C-U-R
YJL043W-D-R YML024W-U-R YDL213C-D-R YBR075W-U-R YKL087C-U-R YCL026C-U-R YKL060C-U-R YOR166C-D-R YCL009C-D-R YJL092W-D-R
YJL128C-U-R YGL142C-U-R YML086C-U-R YPR036W-D-R YDR530C-U-R YPL228W-U-R YJL194W-D-R YOL148C-U-R YMR080C-D-R YPL247C-D-R
YJL074C-U-R YGR248W-U-R YBR056W-D-R YBR176W-D-R YOR056C-U-R YLR327C-D-R YOL141W-D-R YBR075W-D-R YGR174C-D-R YDL023C-U-R
YGR147C-D-R YFR057W-D-R YNL259C-D-R YOR363C-U-R YLR350W-D-R YMR057C-D-R YDR484W-D-R YDR421W-U-R YFL034W-U-R YPR170C-D-R
YER031C-U-R YBR143C-D-R YGR062C-U-R YOR099W-D-R YDL194W-D-R YPL121C-U-R YPL004C-U-R YPL023C-D-R YNL245C-U-R YJR070C-D-R
YNR029C-D-R YER142C-D-R YIL083C-D-R YOL008W-D-R YGL151W-D-R YDR268W-U-R YLR120C-U-R YPL196W-D-R YMR297W-U-R YDL082W-U-R
YPL070W-U-R YAL045C-U-R YDR428C-D-R YGL016W-U-R YDR070C-U-R YNL279W-D-R YGL214W-U-R YMR253C-U-R YMR171C-D-R YGR225W-D-R
YOR298W-U-R YLR092W-U-R YFR011C-U-R YDL010W-U-R YOR259C-U-R YMR170C-D-R YKR001C-U-R YDR450W-D-R YKL128C-U-R YLR291C-D-R
YLL017W-U-R YMR175W-U-R YLL018C-D-R YNL198C-D-R YLR053C-D-R YHL012W-D-R YHR041C-D-R YGL154C-U-R YGL241W-U-R YGL013C-U-R
YFR052W-D-R YPR065W-U-R YNL232W-D-R YDL125C-U-R YOR037W-D-R YJL077C-D-R YNL119W-U-R YHR100C-U-R YHR204W-U-R YDR105C-U-R
YOR057W-U-R YKL222C-D-R YDR289C-U-R YCL022C-U-R YKR106W-U-R YGR257C-D-R YOR381W-U-R YLL051C-D-R YPL201C-D-R YDR182W-U-R
YNL237W-D-R YNL280C-U-R YKL099C-D-R YDR273W-U-R YNL046W-U-R YFR039C-D-R YBR163W-D-R YMR147W-D-R YBR252W-U-R YMR173W-U-R
YBR070C-D-R YHR028C-U-R YMR233W-U-R YNL295W-U-R YEL030W-U-R YPR032W-D-R YNR069C-D-R YKL152C-U-R YNL268W-U-R YOL083W-D-R
YGL227W-U-R YHL045W-D-R YGR112W-U-R YKR030W-D-R YML110C-D-R YGR180C-D-R YGR196C-U-R YKL199C-U-R YLR342W-U-R YGL125W-U-R
YHL035C-U-R YGR093W-D-R YDR496C-D-R YER052C-D-R YOR228C-U-R YNR015W-U-R YJL093C-U-R YMR160W-U-R YFR030W-D-R YJR023C-U-R
YNR014W-D-R YMR216C-D-R YPR129W-D-R YAL013W-U-R YER090W-D-R YOR105W-D-R YHR039C-B-U-R YDL135C-U-R YGR037C-D-R YKR048C-D-R
YMR177W-U-R YPR200C-D-R YGR234W-U-R YNL338W-U-R YJL161W-D-R YFL020C-U-R YIL110W-U-R YPR088C-D-R YMR143W-D-R YBR206W-U-R
YDL142C-U-R YGR286C-U-R YJL010C-U-R YPL032C-D-R YNL043C-U-R YFR055W-U-R YNR056C-D-R YOR200W-U-R YLR125W-U-R YHR154W-U-R
YNL154C-D-R YNR008W-U-R YHR035W-D-R YLR364W-U-R YDR453C-U-R YGL115W-D-R YDR227W-D-R YNL118C-D-R YGR202C-D-R YGR097W-D-R
YKR004C-U-R YKL005C-U-R YNL073W-D-R YLR282C-U-R YPL183W-A-D-R YNL280C-D-R YBL098W-D-R YJL003W-U-R YBR094W-U-R YPL245W-D-R
YBR178W-D-R YLR447C-U-R YHL047C-U-R YCR048W-U-R YMR284W-U-R YGL097W-D-R YPL207W-U-R YML116W-D-R YLR324W-U-R YJL206C-D-R
YDL061C-U-R YOR183W-D-R YJL182C-D-R YNL215W-D-R YDR052C-U-R YOR331C-U-R YPR027C-D-R YBR250W-D-R YBL093C-D-R YGL080W-U-R
YPL199C-D-R YOR021C-U-R YCL038C-D2 YKL100C-D-R YDL084W-D-R YBR285W-D-R YEL052W-D-R YDR284C-U-R YIL077C-U-R YMR119W-D-R
YPL109C-U-R Spotting Buffer YIL014W-U-R YCL037C-U-R YNL156C-D-R YDR392W-U-R YKL001C-D-R YHR154W-D-R YDL126C-U-R YCR083W-U-R
YGL028C-U-R YKL216W-D-R YDL140C-U-R YPR021C-U-R YIL156W-D-R YDR108W-U-R YCL036W-U-R YLR097C-D-R YOR201C-D-R YGL196W-D-R
YNR075W-D-R YER126C-U-R YDR380W-U-R YKL220C-D-R YMR040W-U-R YBL087C-D-R YJL122W-D-R YLR456W-U-R YGR276C-D-R YLR242C-U-R
YBL048W-D-R YPR049C-D-R YPR076W-D-R YDR198C-U-R YNR034W-U-R YDR223W-D-R YGR121C-U-R YGR166W-U-R YPL041C-D-R YFL001W-D-R
YPL025C-U-R YJL126W-D-R YPL005W-U-R YDR500C-U-R YNL109W-U-R YOR029W-D-R YER066W-D-R YKL078W-D-R YOR298C-A-U-R YPR116W-D-R
YBR293W-U-R YIL117C-U-R YML055W-U-R YDR509W-U-R YJR059W-D-R YPL189W-U-R YGR152C-D-R YFL026W-D-R YJL183W-D-R YBL007C-D-R
YJR030C-U-R YGL054C-U-R YDL192W-D-R YOR137C-D-R YNL110C-U-R YCR073C-U-R YPL195W-D-R YMR005W-U-R YJR049C-U-R YJR013W-U-R
YGR161C-U-R YBR020W-U-R YDL183C-D-R YOR350C-D-R YER152C-U-R YGR135W-U-R YFL006W-D-R YKL056C-U-R YBR022W-D-R YMR154C-D-R
YPR163C-D-R YKL055C-U-R YDL238C-U-R YPR145W-D-R YDR179W-A-U-R YBR157C-D-R YIL128W-U-R YDR410C-U-R YOR337W-U-R YLR309C-D-R
YHR196W-D-R YNL271C-D-R YHR044C-U-R YCL060C-U-R YML077W-U-R YOR274W-U-R YGL077C-U-R YPL090C-U-R YML088W-U-R YDL219W-U-R
YFR043C-U-R YDR111C-D-R YLR039C-D-R YDR093W-D-R YGR208W-D-R YDL031W-D-R YGL107C-D-R YKL148C-D-R YDR073W-U-R YLR178C-D-R
YKL142W-D-R YDR176W-U-R YHR137W-U-R YIL141W-D-R YOR197W-D-R YGL040C-U-R YPL107W-D-R YJL076W-U-R YOR107W-D-R YBL006C-D-R
YJL002C-D-R YCR089W-U-R YDR355C-U-R YJL146W-U-R YGL031C-D-R YBR227C-U-R YJR078W-U-R YCL008C-U-R YJR049C-D-R YNL089C-D-R
YCR107W-D-R YPR004C-U-R YMR191W-U-R YJL158C-D-R YKR105C-D-R YBR298C-U-R YIL042C-U-R YJR034W-D-R YMR160W-D-R YIL105C-D-R
YKR076W-D-R YBL082C-D-R YDL134C-A-U-R YGL132W-U-R YBR251W-D-R YBR279W-U-R YPL079W-U-R YDR406W-D-R YGR189C-D-R YIL094C-D-R
YPR055W-U-R YBL101C-D-R YMR073C-U-R YGR213C-U-R YBR263W-D-R YJL017W-U-R YEL045C-U-R YGL105W-U-R YDL162C-D-R YOR352W-D-R
YOR103C-U-R YLR347C-U-R YKL119C-U-R YBR274W-U-R YMR148W-U-R YER008C-U-R YCR092C-D-R YBR137W-D-R YOL147C-U-R YPL048W-U-R
YDR387C-U-R YLR397C-U-R YOR248W-U-R YNL093W-U-R YPL051W-D-R YDL008W-D-R YPL005W-D-R YDL081C-U-R YMR181C-D-R YDR317W-D-R
YPL119C-U-R YBL072C-D-R YDR445C-D-R YJR121W-D-R YLR416C-D-R YBR108W-U-R YLL007C-D-R YJR063W-U-R YER108C-D-R YOR355W-D-R
YFL042C-U-R YCR020W-B-U-R YMR107W-U-R YER030W-D-R YCL064C-U-R YBR182C-D-R YDR102C-U-R YOR161C-D-R YPR043W-D-R YBR014C-U-R
YCR013C-D-R YAL016W-D-R YHL039W-D-R YMR290C-U-R YML104C-D-R YPR106W-D-R YNL281W-U-R YBR189W-D-R YHL013C-U-R YLR402W-D-R
YFL014W-U-R YBR170C-U-R YDR127W-D-R YDR269C-U-R YDR328C-U-R YMR089C-D-R YMR092C-U-R YNL091W-D-R YLL006W-U-R YOR007C-D-R
YNL055C-D-R YLR409C-U-R YHR050W-D-R YHR005C-D-R YML081W-U-R YDR193W-U-R YPL198W-U-R YKL096W-D-R YBR213W-U-R YPR197C-U-R
YJR106W-D-R YBL055C-D-R YJL078C-U-R YPR146C-U-R YBR015C-D-R YIL086C-U-R YDR385W-U-R YKR027W-D-R YKR101W-D-R YCR086W-D-R
YER039C-U-R YDR124W-U-R YBR150C-U-R YML130C-U-R YDR171W-D-R YJL162C-U-R YPL257W-U-R YOR087W-D-R YOL044W-U-R YGR117C-D-R
YOL012C-D-R YJR113C-U-R YNL031C-D-R YBR191W-D-R YDR286C-U-R YKL024C-U-R YBL085W-D-R YDR455C-U-R YNL171C-U-R YDR242W-D-R
YNL080C-D-R YHR064C-D-R YEL017C-A-U-R YGR243W-U-R YLR436C-D-R YLL006W-D-R YER128W-U-R YDL035C-U-R YFL034C-A-U-R YPL268W-D-R
YBL058W-U-R YML035C-D-R YMR169C-D-R YGL092W-U-R YGR032W-D-R YML091C-D-R YNL330C-D-R YIL111W-D-R YBR280C-U-R YML056C-U-R
YBR040W-D-R YML031W-D-R YMR002W-U-R YDL227C-D-R YNR071C-D-R YDL175C-D-R YMR102C-D-R YPR163C-U-R YFR004W-D-R YKR059W-D-R
YKL011C-U-R YOL150C-D-R YIL100W-D-R YGL254W-U-R YCR065W-D-R YBR242W-U-R YLR429W-D-R YDR427W-D-R YDR248C-D-R YHR143W-D-R
YJR006W-U-R YJR032W-U-R YLR206W-U-R YBR300C-U-R YLR389C-U-R YML098W-U-R YPL271W-D-R YLR444C-U-R YDR017C-U-R YPR159W-D-R
YML115C-D-R YLR218C-D-R YCL039W-U-R YOL139C-D-R YFR025C-D-R YJR095W-U-R YOR254C-U-R YDR360W-U-R YJL191W-U-R YJL136C-D-R
YDR054C-D-R YOR318C-U-R YGR089W-U-R YDR341C-D-R


il y a 3 spots sans le -R a la fin : Empty, YCL038C-D2 et Spotting Buffer
seul YCL038C-D2 nous intéresse.
l’orf YCL038C existe dans le gal avec les spots
YCL038C-D1 ATG22 CACCTTTCGAGAGGACGATG
YCL038C-D2 ATG22 CCTGTAGAATAAGGCTCAAC
YCL038C-U2 ATG22 GGTTCTACACACCATAATGC
YCL038C-U-R AUT4 GGTTCTACACACCATAATGA
YCL038C-U1 ATG22 CCAGCCTGTAAAGGTGTCGA

l’orf YCL038C a les noms ATG22 et AUT4
si je cherche les séquence des tag de ces spot dans le fichier de délétion, je retrouve celle du spot YCL038C-D1 et YCL038C-U2 à la ligne de la délétion de YCL038C.
je ne retrouve pas les spot YCL038C-D2 et YCL038C-U-R.
et aussi je retrouve YCL038C-U1 à la ligne de YDR074W dans la colonne UPTAG.
ilsemble y avoir une confusion a ce niveau. cepandant si je recherche YDR074W dans le fichier gal je ne trouve que le spot de la séquence down, donc il semble que ce soit correct quand meme

*****Fin edit*****

le fichier /home/gim2/bioinfo/microarray/A-MEXP-714_SLRI_Yeast_Barcode_13k.txt contient toutes les information de la puce, il est supposé contenir les meme information que le fichier gal
j’ai fait un parser pour ce fichier barcode_parser.py et j’ai appliqué les meme méthode que precedemment.
j’obtiens en sortie

ouverture de barcode12k_v2final.gal en 2.450 secbarcode12k_v2final.gal contient 27648 lignesouverture de Deletion_primers_PCR_sizes.txt en 2.741 secDeletion_primers_PCR_sizes.txt contient 6363 lignesouverture de A-MEXP-714_SLRI_Yeast_Barcode_13k.txt en 3.531 secA-MEXP-714_SLRI_Yeast_Barcode_13k.txt contient 27648 lignesbarcode12k_v2final.gal contient 12683 tags distinctsA-MEXP-714_SLRI_Yeast_Barcode_13k.txt contient 12681 tags distincts0 elements de A-MEXP-714_SLRI_Yeast_Barcode_13k.txt sont absents de barcode12k_v2final.gal2 elements de barcode12k_v2final.gal sont absents de A-MEXP-714_SLRI_Yeast_Barcode_13k.txt

On voit que le fichier gal contient toutes les séquences du fichier barcode. 2 items du fichier gal sont absent du fichier barcode, il s’agit des item empty et Spotting Buffer, ce ne sont donc pas des sequence a proprement parlé.
ce sont donc bien les memes fichiers.

je recherche ensuite les genes du fichier barcode qui ne sont plus présent dans le fichier gff actuel (juillet 2007)
j’ai recréé un parser gff gff_parser.py dans le meme style que les autres.
je fais une recherche sur les nom ou id des orf dans le gff et sur ‘Reporter BioSequence Database Entry [ebi.ac.uk:Database:sgd]‘ dans le fichier barcode
je récupère en sortie

ouverture de A-MEXP-714_SLRI_Yeast_Barcode_13k.txt en 4.002 secA-MEXP-714_SLRI_Yeast_Barcode_13k.txt contient 27648 lignesouverture de saccharomyces_cerevisiae.gff en 3.488 secsaccharomyces_cerevisiae.gff contient 16316 lignessaccharomyces_cerevisiae.gff contient 8097 tags distincts('Reporter BioSequence Database Entry [ebi.ac.uk:Database:sgd]',)A-MEXP-714_SLRI_Yeast_Barcode_13k.txt contient 5867 tags distincts103 elements de A-MEXP-714_SLRI_Yeast_Barcode_13k.txt sont absents de saccharomyces_cerevisiae.gff2333 elements de saccharomyces_cerevisiae.gff sont absents de A-MEXP-714_SLRI_Yeast_Barcode_13k.txtYCR062W YAL064C YCR020W YER014C YCL006C YER108C YKL158W YMR306C YKL006C YKL200CYGL046W YFL018W YER038W YOL053C YFL010W YDR474C YMR031W YFR024C YHR049C YMR244CYFL035C YMR075C YKL199C YMR052C YAR044W YMR086C YBR084C YMR158C YNR032C YIR020WYMR304C YBR162W YER019C YBR100W YJR094W YER068C YAR043C YMR153C YGL226C YBR075WYCR073W YMR172C YLR312W YMR193C YDL045W YPL183W YCL062W YML013C YLR391W YER067CYOR240W YDL133C YHR132W YEL017C YOR298C YPR133W YFL006W YJL018W YML058C YKR035WYML010C YCR102W YER066C YML033W YOR088W YMR135W YOR304C YIL009C YPR090W YHR021WYJR010C YAL034W YCL060C YMR194C YFL013W YLR438C YJL017W YOL013W YAR002C YCR087CYML081C YMR316C YAR037W YCL012W YFL034C YCL013W YKL053C YCL053C YAL035C YIL015CYFL043C YCL026C YER007C YJL021C YDR179W YAL058C YML102C YMR290W YGR122C YER087CYER048W YAR040C YCL003W YCR062W

on voit qu’il y a environ 100 orf qui ne sont plus présentes dans la base

7 mars 2008 – Interface pour l’ajout des orf dans luce_la_puce

mars 7, 2008

11h52 : l’ajout va donc se faire a partir d’un fichier gff.
l’interface va donc etre très simple. une page web avec un formulaire de base. un controle pour envoyer un fichier et un controle submit. et puis le code php pour traiter tout ca. bref, pas trop compliqué. la table bank_orf va etre a revoir cependant.
je vais créer une table bank_gff qui va contenir les metadonnées du fichier gff et la date de release du fichier.

pour créer la table bank_orf, je m’aide de la table feature de la base sophia

CREATE TABLE features(ft_index serial NOT NULL,ft_chr varchar(10),ft_origin varchar(10),ft_type varchar(50),ft_start int4,ft_end int4,ft_score varchar(5),ft_strand varchar(1),ft_frame char(1),ft_rev varchar,ft_dbxref varchar,ft_id varchar,ft_name varchar,ft_note varchar,ft_orf_classification varchar,ft_ontology_term varchar,ft_parent varchar,ft_alias varchar,ft_gene varchar,CONSTRAINT ft_id_key PRIMARY KEY (ft_index))WITHOUT OIDS;ALTER TABLE features OWNER TO fricard;

en fait je ne vais pas créer toute ces colonnes, certaines seront générées automatiquement a partir du fichier gff. cependant je vais les mettre qd meme dans le schema de la base.


create table bank_orf (orf_index serial not null, orf_chr varchar(10), orf_origin varchar(10), orf_type varchar(50), orf_start int4, orf_end int4, orf_score varchar(5), orf_strand varchar(1), orf_frame varchar(1), gff_id serial not null, primary key (orf_index));
create table bank_gff (gff_id serial not null, gff_release_date date, gff_metadata text, primary key (gff_id));

je vais utiliser le module DBGFF.py que j’ai créé pour genepy. comme ca le parser gff est deja fait.

je le fait grace a la commande sys.path += ['/home/gim/genepy']

j’ai finalement modifié bank_gff et j’utilise la date comme clé, ce qui permet d’avoir une contrainte d’unicité sur cette valeur. ce qui se gère bien en python/sql

try :
con.query(query)
except pg.ProgrammingError, e :
print e

qui renvoie

ERROR: duplicate key violates unique constraint "bank_gff_pkey"

si la date existe deja.

j’ai ajouté dans DBGFF.py une méthode pour la classe Features renvoyant un dictionnaire dont les clés sont les attributs de l’objet et les valeurs sont le contenu des attributs. on peut de plus passer un prefixe pour le nom des clés en argument.

  def get_attrdict(self, prefixe=''):      attr_tupple = [ (prefixe + attr, self.getattribute(attr)) for attr in self.attrList  ]      return dict(attr_tupple)

l’avantage de cette méthode est donc d’avoir un dictionnaire des couple attributs, valeurs, ce qui est assez pratique avec la méthode insert de pg.DB
le script pour introduire des features dans la base est donc le suivant

#! /usr/bin/python2.5

import cgiimport pgimport sys

sys.path += ['/home/gim/genepy']

import DBGFF

def create_postgres_db(base):#===============================================================================#    creation de la base de donnee postgresql#===============================================================================

    db = DBGFF.DB(base)    db_date=db.get_release_date('DATE')    print db_date    a=2    DBNAME = "luce_la_puce"    HOST = 'berthemorisot.gim.pasteur.fr'    USER = 'postgres'       #con = pg.connect(dbname=DBNAME, host=HOST, user=USER)    llp=pg.DB(dbname=DBNAME, host=HOST, user=USER)    try :        llp.insert('bank_gff', {'gff_release_date' : db_date, 'gff_metadata':db.info})

    except pg.ProgrammingError, e :        print e        return    prefixe = "orf_"    i = 0    listfields = llp.get_attnames('bank_orf').keys()    listfields = set(map(lambda x : x[4:], listfields))    date_dict={'gff_release_date' : db_date}    for feature in db :        attr_list = set(feature.get_attrlist().keys())        diff = attr_list.difference(listfields)

        if diff :               for attr in diff :

                attr_col = "%s%s" % (prefixe, attr)

                llp.query("alter table bank_orf add column %s varchar" % attr_col)

                listfields.add(attr)

        values = feature.get_attrdict(prefixe)        values.update(date_dict)        llp.insert('bank_orf', values)

        i+=1        if not i%1000 :            print i

print "Content-type: text/html"print

print "insertion des donnees"

post_data=cgi.FieldStorage()gff=post_data['gff_file']create_postgres_db(gff.file)

print "script fini"

ce script n’est pas définitif, il faut l’améliorer pour que l’ergonomie soit correcte.

20 février 2008 – installation du module pg pour python2.5 sur berthemorisot

février 20, 2008

14h59: comme rien n’est jamais simple, il est impossible d’utiliser python2.5 par défaut sur berthemorisot a cause de CENTOS qui nécessite python2.3 pour fonctionner (on croit réver).
mais comme python2.5 est en génral plus rapide que le 2.3 et gère mieux certaines chose, c qd meme pas mal de l’utilser si possible.
il est installé dans ~/tools/python-2.5.0/ et on l’appelle par la commande ~>python2.5
je veux utiliser PyGreSQL dans python2.5. il me faut donc l’installer car il n’est pas par défaut. et bien sur pas possible de passer par les rpm ou yum.
donc deja il faut aller chercher le fichier sur http://www.pygresql.org/ et télécharger ftp://ftp.pygresql.org/pub/distrib/PyGreSQL.tgz
moi j’ai copié l’archive dans ~/tools/python-2.5.0/lib/python2.5/site-package/ mais je ne suis pas sur que ce soit totalement nécésssaire.
là j’ai dezipé l’archive
~>gunzip PyGreSQL.tgz
et dearchivé
~>tar -vxf PyGreSQL.tar
j’ai alors un répertoire PyGreSQL-3.8.1 ou je me rend
je suis les instruction d’installation et je lance la commande ~>python2.5 setyp.py build et la bien sur j’ai une erreur

sh: pg_config: command not found
Traceback (most recent call last):
File "setup.py", line 81, in
pg_include_dir = pg_config('includedir')
File "setup.py", line 51, in pg_config
raise Exception, "pg_config tool is not available."
Exception: pg_config tool is not available.

en fait le programme appelle pg_config (fourni avec la base pgresql) sauf que ce programme n’est pas accessible ainsi. il faut donner son chemin complet /usr/local/pgsql/bin/pg_config et la ca marche
il y a qq erreur mais ca a l’air de marcher qd meme
puis on fait ~>python2.5 setup.py install
encore qq erreur mais ca semble marcher qd meme
et puis je lance python2.5 et je tape import pg
et là miracle, ca marche
donc c cool, ca a fonctionner sans trop de galère. mais j’ai peur qd meme de voir apparaitre qq erreur a l’utilisation, enfin on verra

20 février 2008 – script pour introduire des données dans la base (suite)

février 20, 2008

9h57 : suite du test sur l’utilisation du module cgi de python
je rajoute
print dir(form)

je récupère
['FieldStorageClass', '_FieldStorage__write', '__contains__', '__doc__', '__getattr__', '__getitem__', '__init__', '__iter__', '__len__', '__module__', '__repr__', 'bufsize', 'disposition', 'disposition_options', 'done', 'file', 'filename', 'fp', 'getfirst', 'getlist', 'getvalue', 'has_key', 'headers', 'innerboundary', 'keep_blank_values', 'keys', 'length', 'list', 'make_file', 'name', 'outerboundary', 'read_binary', 'read_lines', 'read_lines_to_eof', 'read_lines_to_outerboundary', 'read_multi', 'read_single', 'read_urlencoded', 'skip_lines', 'strict_parsing', 'type', 'type_options']

les methodes sont

__contains__
__getattr__
__getitem__
__init__
__iter__
__len__
__repr__
getfirst
getlist
getvalue
has_key
keys
make_file
read_binary
read_lines
read_lines_to_eof
read_lines_to_outerboundary
read_multi
read_single
read_urlencoded
skip_lines

l’objet se comporte un peu comme un dictionnaire, les méthodes has_key et keys permettent d’accéder aux noms des variables passées dans l’adresse
f.keys() renvoie la liste ['toto','tati']

maintenant il faut voir si ca marche avec une requete ajax
mon fichier avec la requete ajax
http://berthemorisot.gim.pasteur.fr/test_ajax.php
et son contenu
la partie javascript

function req_object(method,query, sync){
//fonction renvoyant un objet
XMLHttpRequest qui effectue la requete. l'objet est renvoyé juste après avoir effectuer la requete
var xhr_object = null;

if(window.XMLHttpRequest)//Firefox

xhr_object = new XMLHttpRequest();
else if(window.ActiveXObject) // Internet Explorer
xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
else { // XMLHttpRequest non supporté par le navigateur
alert("Your web browser does not support XMLHTTPRequest objects...");
return;
}
xhr_object.open(method,query, sync);
xhr_object.send(null);
return xhr_object;
}
function request(){
//fonction requete qui envoie des données à test_get.py en utilisant la methode get et
//de façon synchrone (sync=false)
query="cgi-bin/sganarrayl/test_get.py?toto=tata&tati=tonton";
method="get";
sync=false;
var xhr_object=req_object(method,query, sync);
if(xhr_object.readyState == 4) {
//quand la requete est effectuée, affiche le résultat renvoyé par test_get.py dans
//une boite de dialogue
var reponseXML =xhr_object.responseText;
alert(reponseXML);
}
}

et la partie html



1
2

ca marche bien et je reçois correctement la réponse du script python.

12h35 : je vais tester la rapidité de python par rapport au php pour l’accès aux bases de données
j’ai écrit 2 script effectuant les meme actions
le premier en python

#! /usr/bin/python

import cgi
import pg
print "Content-type: text/html"
print

DBNAME = 'sophia'
HOST = 'berthemorisot.gim.pasteur.fr'
USER = 'fricard'
con = pg.connect(dbname=DBNAME, host=HOST, user=USER)
query_all = "select * from features"
all = con.query(query_all)
res=all.getresult()
for val in res[0]:
print val

et le second en php

header("Content-type: text/html");

$HOST="berthemorisot.gim.pasteur.fr";
$PORT=5432;
$BASE="sophia";
$USER="fricard";
$db = pg_connect("host=$HOST port=$PORT dbname=$BASE user=$USER") or die("impossible de se connecter à la base de données");
$query_all = "select * from features";

$res = pg_query($db, $query_all) or die("La requète n'a pas pu aboutir");
$ligne= pg_fetch_row($res, 0);
foreach($ligne as $val){
echo $val.'\n';
}

le code python met en moyenne 222 ms pour faire la requete (sur 11 essais) et le code php met 120 ms en moyenne (sur 11 essais). la requete part du meme script ajax, donc tout est bien equivalent. le code python est presque 2 fois plus lent.
je vais le tenter sur une requete plus longue, car il peut s’agir juste d’un problème d’initialisation.
en modifiant le script pour renvoyer l’ensemble des résultats de la table feature (13316 lignes), le temps d’execution du script python passe a 1518 ms en moyenne (sur 10 essais) et le script php 1481 ms en moyenne(12 essais).
la différence venait donc de l’initialisation de python je pense ou quelque chose comme ca. et encore, je suis obligé d’utiliser python2.3 car le module pg n’est pas installé sur python2.5. je vais essayer de l’installer sur python2.5 pour etre plus tranquille. installation ici
15:25 : je test le meme script avec python2.5 et je n’ai aucune différence, c le meme temps d’execution. mais bon, je préfère quand meme pouvoir me servir de python2.5

Au final je vais donc me servir de python puisque c’est a peine plus lent sur les grosse requetes. il serait qd meme interressant de voir s’il est possible de parser le fichier gpr en php de façon assez simple. cela dit le python est plus simple d’utilisation. a voir donc. dans un premier temps python et puis ensuite peut-etre php.

18h38 : la partie essentielle de sganarrayl est de traiter le fichier envoyé par l’utilisateur. il faut donc etre capable d’envoyer et de recevoir un fichier.
pour l’envoie, les formulaires font ca très bien en utilisant cette ligne de commande
form id="ajax_form" name="ajax_form" action="cgi-bin/sganarrayl/test_get.py" method="post" ENCTYPE="multipart/form-data"

il faut donc utiliser la méthode post, j’ai essayé avec get et ca ne marche pas, ce qui finalement est assez normal car le fichier ne peut pas passer dans l’adresse. ne pas oublier non plus l’encodage avec multipart/form-data
il faut aussi ajouter une balise input de type file mais ca c trivial
input type="file" id="fichier" name="fichier"

du coté du cgi, pour traiter ca c assez simple
on créé une première instance de FieldStorage et on récupère ainsi toutes les variable post. quand un fichier est envoyé, il est stocké sous la forme d’un objet FieldStorage (a nouveau) accessible par la clé qui est le nom de la balise input du formulaire. ok c pas clair mais par contre c tres simple a écrire

import cgi #on importe la classe cgi bien sur
post_data=cgi.FieldStorage() #on récupère les données passée en post
f=post_data['fichier'] #on récupère la variable associée a la clé "fichier"
#comme c un fichier l'objet récupéré est un FieldStorage, avec un attribut file qui est un filehandle
for line in f.file: #on parcours alors ce filehandle
print "%s" % line #et on inprime chaque ligne

facile, non ?
ca marche bien, meme avec un gros fichier du type gpr (fichier de resultat de microarray) et c rapide.
par contre, il n’y a pas le choix, il faut pour envoyer le fichier, passer par le formulaire et un bouton submit. c pas possible de traiter ca juste avec AJAX.
c’est très bien expliqué ici