annotate blast.py @ 3:6ef523b390e0

Uploaded correct file.
author peterjc
date Thu, 20 Sep 2012 10:13:16 -0400
parents
children f9a7783ed7b6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
1 """
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
2 BlastXml class
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
3 """
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
4
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
5 from galaxy.datatypes.data import get_file_peek
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
6 from galaxy.datatypes.data import Text
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
7 from galaxy.datatypes.xml import GenericXml
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
8
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
9 class BlastXml( GenericXml ):
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
10 """NCBI Blast XML Output data"""
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
11 file_ext = "blastxml"
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
12
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
13 def set_peek( self, dataset, is_multi_byte=False ):
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
14 """Set the peek and blurb text"""
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
15 if not dataset.dataset.purged:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
16 dataset.peek = get_file_peek( dataset.file_name, is_multi_byte=is_multi_byte )
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
17 dataset.blurb = 'NCBI Blast XML data'
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
18 else:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
19 dataset.peek = 'file does not exist'
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
20 dataset.blurb = 'file purged from disk'
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
21 def sniff( self, filename ):
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
22 """
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
23 Determines whether the file is blastxml
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
24
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
25 >>> fname = get_test_fname( 'megablast_xml_parser_test1.blastxml' )
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
26 >>> BlastXml().sniff( fname )
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
27 True
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
28 >>> fname = get_test_fname( 'tblastn_four_human_vs_rhodopsin.xml' )
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
29 >>> BlastXml().sniff( fname )
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
30 True
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
31 >>> fname = get_test_fname( 'interval.interval' )
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
32 >>> BlastXml().sniff( fname )
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
33 False
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
34 """
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
35 #TODO - Use a context manager on Python 2.5+ to close handle
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
36 handle = open(filename)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
37 line = handle.readline()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
38 if line.strip() != '<?xml version="1.0"?>':
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
39 handle.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
40 return False
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
41 line = handle.readline()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
42 if line.strip() not in ['<!DOCTYPE BlastOutput PUBLIC "-//NCBI//NCBI BlastOutput/EN" "http://www.ncbi.nlm.nih.gov/dtd/NCBI_BlastOutput.dtd">',
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
43 '<!DOCTYPE BlastOutput PUBLIC "-//NCBI//NCBI BlastOutput/EN" "NCBI_BlastOutput.dtd">']:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
44 handle.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
45 return False
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
46 line = handle.readline()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
47 if line.strip() != '<BlastOutput>':
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
48 handle.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
49 return False
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
50 handle.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
51 return True
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
52
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
53 def merge(split_files, output_file):
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
54 """Merging multiple XML files is non-trivial and must be done in subclasses."""
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
55 if len(split_files) == 1:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
56 #For one file only, use base class method (move/copy)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
57 return Text.merge(split_files, output_file)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
58 out = open(output_file, "w")
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
59 h = None
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
60 for f in split_files:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
61 h = open(f)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
62 body = False
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
63 header = h.readline()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
64 if not header:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
65 out.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
66 h.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
67 raise ValueError("BLAST XML file %s was empty" % f)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
68 if header.strip() != '<?xml version="1.0"?>':
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
69 out.write(header) #for diagnosis
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
70 out.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
71 h.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
72 raise ValueError("%s is not an XML file!" % f)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
73 line = h.readline()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
74 header += line
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
75 if line.strip() not in ['<!DOCTYPE BlastOutput PUBLIC "-//NCBI//NCBI BlastOutput/EN" "http://www.ncbi.nlm.nih.gov/dtd/NCBI_BlastOutput.dtd">',
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
76 '<!DOCTYPE BlastOutput PUBLIC "-//NCBI//NCBI BlastOutput/EN" "NCBI_BlastOutput.dtd">']:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
77 out.write(header) #for diagnosis
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
78 out.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
79 h.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
80 raise ValueError("%s is not a BLAST XML file!" % f)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
81 while True:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
82 line = h.readline()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
83 if not line:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
84 out.write(header) #for diagnosis
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
85 out.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
86 h.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
87 raise ValueError("BLAST XML file %s ended prematurely" % f)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
88 header += line
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
89 if "<Iteration>" in line:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
90 break
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
91 if len(header) > 10000:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
92 #Something has gone wrong, don't load too much into memory!
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
93 #Write what we have to the merged file for diagnostics
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
94 out.write(header)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
95 out.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
96 h.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
97 raise ValueError("BLAST XML file %s has too long a header!" % f)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
98 if "<BlastOutput>" not in header:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
99 out.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
100 h.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
101 raise ValueError("%s is not a BLAST XML file:\n%s\n..." % (f, header))
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
102 if f == split_files[0]:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
103 out.write(header)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
104 old_header = header
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
105 elif old_header[:300] != header[:300]:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
106 #Enough to check <BlastOutput_program> and <BlastOutput_version> match
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
107 out.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
108 h.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
109 raise ValueError("BLAST XML headers don't match for %s and %s - have:\n%s\n...\n\nAnd:\n%s\n...\n" \
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
110 % (split_files[0], f, old_header[:300], header[:300]))
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
111 else:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
112 out.write(" <Iteration>\n")
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
113 for line in h:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
114 if "</BlastOutput_iterations>" in line:
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
115 break
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
116 #TODO - Increment <Iteration_iter-num> and if required automatic query names
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
117 #like <Iteration_query-ID>Query_3</Iteration_query-ID> to be increasing?
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
118 out.write(line)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
119 h.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
120 out.write(" </BlastOutput_iterations>\n")
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
121 out.write("</BlastOutput>\n")
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
122 out.close()
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
123 merge = staticmethod(merge)
6ef523b390e0 Uploaded correct file.
peterjc
parents:
diff changeset
124