Back to index

python-biopython  1.60
test_PAML_baseml.py
Go to the documentation of this file.
00001 # Copyright (C) 2011 by Brandon Invergo (b.invergo@gmail.com)
00002 # This code is part of the Biopython distribution and governed by its
00003 # license. Please see the LICENSE file that should have been included
00004 # as part of this package.
00005 
00006 import unittest
00007 import os
00008 import os.path
00009 import sys
00010 from Bio.Phylo.PAML import baseml
00011 from Bio.Phylo.PAML._paml import PamlError
00012 
00013 class ModTest(unittest.TestCase):
00014     align_dir = os.path.join("PAML", "Alignments")
00015     tree_dir = os.path.join("PAML", "Trees")
00016     ctl_dir = os.path.join("PAML", "Control_files")
00017     results_dir = os.path.join("PAML", "Results")
00018     working_dir = os.path.join("PAML", "baseml_test")
00019  
00020     align_file = os.path.join(align_dir, "alignment.phylip")
00021     tree_file = os.path.join(tree_dir, "species.tree")
00022     bad_tree_file = os.path.join(tree_dir, "bad.tree")
00023     out_file = os.path.join(results_dir, "test.out")
00024     results_file = os.path.join(results_dir, "bad_results.out")
00025     bad_ctl_file1 = os.path.join(ctl_dir, "bad1.ctl")
00026     bad_ctl_file2 = os.path.join(ctl_dir, "bad2.ctl")
00027     ctl_file = os.path.join(ctl_dir, "baseml.ctl")
00028        
00029     def tearDown(self):
00030         """Just in case BASEML creates some junk files, do a clean-up."""
00031         del_files = [self.out_file, "2base.t", 
00032             "in.basemlg", "baseml.ctl", "lnf", "rates", "rst", "rst1", 
00033             "rub"]
00034         for filename in del_files:
00035             if os.path.exists(filename):
00036                 os.remove(filename)
00037         if os.path.exists(self.working_dir):
00038             for filename in os.listdir(self.working_dir):
00039                 filepath = os.path.join(self.working_dir, filename)
00040                 os.remove(filepath)
00041             os.rmdir(self.working_dir)
00042     
00043     def setUp(self):
00044         self.bml = baseml.Baseml()
00045         
00046     def testAlignmentFileIsValid(self):
00047         self.assertRaises((AttributeError, TypeError),
00048             baseml.Baseml, alignment = 1)
00049         self.bml.alignment = 1
00050         self.bml.tree = self.tree_file
00051         self.bml.out_file = self.out_file
00052         self.assertRaises((AttributeError, TypeError),
00053             self.bml.run)
00054         
00055     def testAlignmentExists(self):
00056         self.assertRaises((EnvironmentError, IOError), baseml.Baseml, 
00057             alignment = "nonexistent")
00058         self.bml.alignment = "nonexistent"
00059         self.bml.tree = self.tree_file
00060         self.bml.out_file = self.out_file
00061         self.assertRaises((EnvironmentError, IOError), 
00062             self.bml.run)
00063     
00064     def testTreeFileValid(self):
00065         self.assertRaises((AttributeError, TypeError),
00066             baseml.Baseml, tree = 1)
00067         self.bml.alignment = self.align_file
00068         self.bml.tree = 1
00069         self.bml.out_file = self.out_file
00070         self.assertRaises((AttributeError, TypeError),
00071             self.bml.run)
00072         
00073     def testTreeExists(self):
00074         self.assertRaises((EnvironmentError, IOError), baseml.Baseml, 
00075             tree = "nonexistent")
00076         self.bml.alignment = self.align_file
00077         self.bml.tree = "nonexistent"
00078         self.bml.out_file = self.out_file
00079         self.assertRaises((EnvironmentError, IOError),
00080             self.bml.run)
00081     
00082     def testWorkingDirValid(self):
00083         self.bml.tree = self.tree_file
00084         self.bml.alignment = self.align_file
00085         self.bml.out_file = self.out_file
00086         self.bml.working_dir = 1
00087         self.assertRaises((AttributeError, TypeError),
00088             self.bml.run)
00089     
00090     def testOutputFileValid(self):
00091         self.bml.tree = self.tree_file
00092         self.bml.alignment = self.align_file
00093         self.bml.out_file = 1
00094         self.assertRaises((AttributeError, TypeError),
00095             self.bml.run)
00096     
00097     def testOptionExists(self):
00098         self.assertRaises((AttributeError, KeyError),
00099                           self.bml.set_options, xxxx=1)
00100         self.assertRaises((AttributeError, KeyError),
00101                           self.bml.get_option, "xxxx")
00102     
00103     def testAlignmentSpecified(self):
00104         self.bml.tree = self.tree_file
00105         self.bml.out_file = self.out_file
00106         self.assertRaises((AttributeError, ValueError),
00107             self.bml.run)
00108         
00109     def testTreeSpecified(self):
00110         self.bml.alignment = self.align_file
00111         self.bml.out_file = self.out_file
00112         self.assertRaises((AttributeError, ValueError),
00113             self.bml.run)
00114         
00115     def testOutputFileSpecified(self):
00116         self.bml.alignment = self.align_file
00117         self.bml.tree = self.tree_file
00118         self.assertRaises((AttributeError, ValueError),
00119             self.bml.run)
00120         
00121     def testPamlErrorsCaught(self):
00122         self.bml.alignment = self.align_file
00123         self.bml.tree = self.bad_tree_file
00124         self.bml.out_file = self.out_file
00125         self.assertRaises((EnvironmentError, PamlError),
00126             self.bml.run)
00127         
00128     def testCtlFileValidOnRun(self):
00129         self.bml.alignment = self.align_file
00130         self.bml.tree = self.tree_file
00131         self.bml.out_file = self.out_file
00132         self.assertRaises((AttributeError, TypeError),
00133             self.bml.run, ctl_file = 1)
00134         
00135     def testCtlFileExistsOnRun(self):
00136         self.bml.alignment = self.align_file
00137         self.bml.tree = self.tree_file
00138         self.bml.out_file = self.out_file
00139         self.assertRaises((EnvironmentError, IOError),
00140             self.bml.run, ctl_file = "nonexistent")
00141             
00142     def testCtlFileValidOnRead(self):
00143         self.assertRaises((AttributeError, TypeError),
00144             self.bml.read_ctl_file, 1)
00145         self.assertRaises((AttributeError, KeyError), 
00146             self.bml.read_ctl_file, self.bad_ctl_file1)
00147         self.assertRaises(AttributeError, 
00148             self.bml.read_ctl_file, self.bad_ctl_file2)
00149         target_options = {"noisy": 0,
00150                         "verbose": 0,
00151                         "runmode": 0,
00152                         "model": 6,
00153                         "model_options": None,
00154                         "Mgene": 1,
00155                         "ndata": None,
00156                         "clock": 0,
00157                         "fix_kappa": 0,
00158                         "kappa": 5,
00159                         "fix_alpha": 0,
00160                         "alpha": 0.5,
00161                         "Malpha": 0,
00162                         "ncatG": 5,
00163                         "fix_rho": 1,
00164                         "rho": 0,
00165                         "nparK": 0,
00166                         "nhomo": 0,
00167                         "getSE": 0,
00168                         "RateAncestor": 0,
00169                         "Small_Diff": 7e-6,
00170                         "cleandata": 1,
00171                         "icode": None,
00172                         "fix_blength": None,
00173                         "method": 0}
00174         self.bml.read_ctl_file(self.ctl_file)
00175         self.assertEqual(sorted(self.bml._options.keys()), sorted(target_options.keys()))
00176         for key in target_options:
00177             self.assertEqual(self.bml._options[key], target_options[key], \
00178                              "%s: %r vs %r" \
00179                              % (key, self.bml._options[key], target_options[key]))
00180         
00181     def testCtlFileExistsOnRead(self):
00182         self.assertRaises(IOError,
00183             self.bml.read_ctl_file, ctl_file = "nonexistent")
00184         
00185     def testResultsValid(self):
00186         self.assertRaises((AttributeError, TypeError),
00187             baseml.read, 1)
00188     
00189     def testResultsExist(self):
00190         self.assertRaises(IOError, baseml.read, "nonexistent")
00191         
00192     def testResultsParsable(self):
00193         self.assertRaises(ValueError, baseml.read, self.results_file)
00194         
00195     def testParseAllVersions(self):
00196         folder = os.path.join("PAML","Results", "baseml", "versions")
00197         for results_file in os.listdir(folder):
00198             file_path = os.path.join(folder, results_file)
00199             if os.path.isfile(file_path) and results_file[:6] == "baseml":
00200                 results = baseml.read(file_path)
00201                 self.assertEqual(len(results), 6)
00202                 self.assertEqual(len(results["parameters"]), 7)
00203     
00204     def testParseModel(self):
00205         res_dir = os.path.join(self.results_dir, "baseml", "model")
00206         for results_file in os.listdir(res_dir):
00207             version = results_file.split('-')[1].split('.')[0]
00208             model = results_file[5]
00209             version_msg = "Improper parsing for model %s version %s" \
00210                         % (model, version.replace('_', '.'))
00211             results_path = os.path.join(res_dir, results_file)
00212             results = baseml.read(results_path)
00213             # There are 6 top-levels: parameters, tree, lnL, version,
00214             # tree length and lnL max
00215             self.assertEqual(len(results), 6, version_msg)
00216             self.assertTrue("parameters" in results, version_msg)
00217             params = results["parameters"]
00218             self.assertTrue("alpha" in params, version_msg)
00219             self.assertTrue("rates" in params, version_msg)
00220             self.assertTrue("parameter list" in params, version_msg)
00221             self.assertTrue("rate frequencies" in params, version_msg)
00222             if model in ["1", "3", "4", "5", "6"]:
00223                 self.assertTrue("kappa" in params, version_msg)
00224             if model in ["7", "8"]:
00225                 self.assertTrue("base frequencies" in params, version_msg)
00226                 self.assertTrue("rate parameters" in params, version_msg)
00227                 self.assertTrue("Q matrix" in params, version_msg)
00228                 qmat = params["Q matrix"]
00229                 self.assertEqual(len(qmat), 2, version_msg)
00230                 self.assertTrue("matrix" in qmat)
00231                 matrix = qmat["matrix"]
00232                 self.assertEqual(len(matrix), 4, version_msg)
00233                 self.assertEqual(len(matrix[0]), 4, version_msg)
00234             
00235     def testParseAlpha1Rho1(self):
00236         # Test the auto-discrete gamma model
00237         # Cannot test for baseml 4.3-4.5 due to bug in the program which
00238         # prevents this analysis from completing
00239         res_dir = os.path.join(self.results_dir, "baseml", "alpha1rho1")
00240         for results_file in os.listdir(res_dir):
00241             version = results_file.split('-')[1].split('.')[0]
00242             model = results_file[5]
00243             version_msg = "Improper parsing for model %s version %s" \
00244                         % (model, version.replace('_', '.'))
00245             results_path = os.path.join(res_dir, results_file)
00246             results = baseml.read(results_path)
00247             # There are 6 top-levels: parameters, tree, lnL, version,
00248             # tree length and lnL max
00249             self.assertEqual(len(results), 6, version_msg)
00250             self.assertTrue("parameters" in results, version_msg)
00251             params = results["parameters"]
00252             self.assertTrue("rho" in params, version_msg)
00253             self.assertTrue("transition probs." in params, version_msg)
00254             trans_p = params["transition probs."]
00255             self.assertEqual(len(trans_p), 5, version_msg)
00256             self.assertEqual(len(trans_p[0]), 5, version_msg)
00257  
00258     def testParseNhomo(self):
00259         res_dir = os.path.join(self.results_dir, "baseml", "nhomo")
00260         for results_file in os.listdir(res_dir):
00261             version = results_file.split('-')[1].split('.')[0]
00262             n = results_file[5]
00263             version_msg = "Improper parsing for nhomo %s version %s" \
00264                         % (n, version.replace('_', '.'))
00265             results_path = os.path.join(res_dir, results_file)
00266             results = baseml.read(results_path)
00267             # There are 6 top-levels: parameters, tree, lnL, version,
00268             # tree length and lnL max
00269             self.assertEqual(len(results), 6, version_msg)
00270             self.assertTrue("parameters" in results, version_msg)
00271             params = results["parameters"]
00272             if n == "1":
00273                 self.assertTrue("base frequencies" in params, version_msg)
00274             else:
00275                 self.assertTrue("nodes" in params)
00276                 nodes = params["nodes"]
00277                 self.assertEqual(len(nodes), 8, version_msg)
00278                 self.assertEqual(len(nodes[1]), 2, version_msg)
00279 
00280     def testParseSEs(self):
00281         res_dir = os.path.join(self.results_dir, "baseml", "SE")
00282         for results_file in os.listdir(res_dir):
00283             version = results_file.split('-')[1].split('.')[0]
00284             version_msg = "Improper parsing for version %s" \
00285                         % version.replace('_', '.')
00286             results_path = os.path.join(res_dir, results_file)
00287             results = baseml.read(results_path)
00288             # There are 6 top-levels: parameters, tree, lnL, version,
00289             # tree length and lnL max
00290             self.assertEqual(len(results), 6, version_msg)
00291             self.assertTrue("parameters" in results, version_msg)
00292             params = results["parameters"]
00293             self.assertTrue("SEs" in params, version_msg)
00294         
00295 
00296 if __name__ == "__main__":
00297     runner = unittest.TextTestRunner(verbosity = 2)
00298     unittest.main(testRunner=runner)
00299