1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
# Copyright 2012 by Christian Brueffer. All rights reserved.
#
# This code is part of the Biopython distribution and governed by its
# license. Please see the LICENSE file that should have been included
# as part of this package.
import glob
import os
import shutil
import sys
import unittest
from Bio import MissingExternalDependencyError
from Bio import SeqIO
from Bio.Application import ApplicationError
from Bio.motifs.applications import XXmotifCommandline
# Try to avoid problems when the OS is in another language
os.environ['LANG'] = 'C'
xxmotif_exe = None
if sys.platform == "win32":
# TODO
raise MissingExternalDependencyError("Testing this on Windows is not implemented yet")
else:
from Bio._py3k import getoutput
output = getoutput("XXmotif")
if output.find("== XXmotif version") != -1:
xxmotif_exe = "XXmotif"
if not xxmotif_exe:
raise MissingExternalDependencyError(
"Install XXmotif if you want to use XXmotif from Biopython.")
class XXmotifTestCase(unittest.TestCase):
def setUp(self):
self.out_dir = "xxmotif-temp"
self.files_to_clean = set()
def tearDown(self):
for filename in self.files_to_clean:
if os.path.isfile(filename):
os.remove(filename)
if os.path.isdir(self.out_dir):
shutil.rmtree(self.out_dir)
def standard_test_procedure(self, cline):
"""Standard testing procedure used by all tests."""
output, error = cline()
self.assertTrue(os.path.isdir(self.out_dir))
self.assertTrue(glob.glob(os.path.join(self.out_dir, "*.meme")))
self.assertTrue(glob.glob(os.path.join(self.out_dir, "*_MotifFile.txt")))
self.assertTrue(glob.glob(os.path.join(self.out_dir, "*_Pvals.txt")))
self.assertTrue(glob.glob(os.path.join(self.out_dir, "*.pwm")))
self.assertTrue(glob.glob(os.path.join(self.out_dir, "*_sequence.txt")))
# TODO
# Parsing the MEME file would be nice, but unfortunately the
# MEME parser does not like what XXmotif produces yet.
def copy_and_mark_for_cleanup(self, path):
"""
XXmotif currently only handles a canonical filename as input, no paths.
This method copies the specified file in the specified path to the
current working directory and marks it for removal.
"""
filename = os.path.split(path)[1]
shutil.copyfile(path, filename)
self.add_file_to_clean(filename)
return filename
def add_file_to_clean(self, filename):
"""Adds a file for deferred removal by the tearDown routine."""
self.files_to_clean.add(filename)
class XXmotifTestErrorConditions(XXmotifTestCase):
def test_empty_file(self):
"""Test a non-existing input file."""
input_file = "does_not_exist.fasta"
self.assertFalse(os.path.isfile(input_file))
cline = XXmotifCommandline(outdir=self.out_dir,
seqfile=input_file)
try:
stdout, stderr = cline()
except ApplicationError as err:
self.assertEqual(err.returncode, 255)
else:
self.fail("Should have failed, returned:\n%s\n%s" % (stdout, stderr))
def test_invalid_format(self):
"""Test an input file in an invalid format."""
input_file = self.copy_and_mark_for_cleanup("Medline/pubmed_result1.txt")
cline = XXmotifCommandline(outdir=self.out_dir,
seqfile=input_file)
try:
stdout, stderr = cline()
except ApplicationError as err:
self.assertEqual(err.returncode, 255)
else:
self.fail("Should have failed, returned:\n%s\n%s" % (stdout, stderr))
def test_output_directory_with_space(self):
"""Test an output directory containing a space."""
temp_out_dir = "xxmotif test"
input_file = self.copy_and_mark_for_cleanup("Fasta/f002")
try:
cline = XXmotifCommandline(outdir=temp_out_dir,
seqfile=input_file)
except ValueError:
pass
else:
self.fail("expected ValueError")
class XXmotifTestNormalConditions(XXmotifTestCase):
def test_fasta_one_sequence(self):
"""Test a fasta input file containing only one sequence."""
input_file = "seq.fasta"
handle = open(input_file, "w")
record = list(SeqIO.parse("Registry/seqs.fasta", "fasta"))[0]
SeqIO.write(record, handle, "fasta")
handle.close()
del handle, record
cline = XXmotifCommandline(outdir=self.out_dir,
seqfile=input_file)
self.add_file_to_clean(input_file)
self.standard_test_procedure(cline)
def test_properties(self):
"""Test setting options via properties."""
input_file = self.copy_and_mark_for_cleanup("Fasta/f002")
cline = XXmotifCommandline(outdir=self.out_dir,
seqfile=input_file)
cline.revcomp = True
cline.pseudo = 20
cline.startmotif = "ACGGGT"
self.standard_test_procedure(cline)
def test_large_fasta_file(self):
"""Test a large fasta input file."""
input_file = "temp_b_nuc.fasta"
handle = open(input_file, "w")
records = list(SeqIO.parse("NBRF/B_nuc.pir", "pir"))
SeqIO.write(records, handle, "fasta")
handle.close()
del handle, records
cline = XXmotifCommandline(outdir=self.out_dir,
seqfile=input_file)
self.add_file_to_clean(input_file)
self.standard_test_procedure(cline)
def test_input_filename_with_space(self):
"""Test an input filename containing a space."""
input_file = "temp horses.fasta"
handle = open(input_file, "w")
SeqIO.write(SeqIO.parse("Phylip/hennigian.phy", "phylip"), handle, "fasta")
handle.close()
cline = XXmotifCommandline(outdir=self.out_dir,
seqfile=input_file)
self.add_file_to_clean(input_file)
self.standard_test_procedure(cline)
if __name__ == "__main__":
runner = unittest.TextTestRunner(verbosity=2)
unittest.main(testRunner=runner)
|