Mercurial > repos > vimalkumarvelayudhan > riboplot
diff tests/test_riboplot.py @ 3:8e1efafa6277
Updated version
* Bugfix: blue lines in some plots (bar colors were not set correctly)
* Cookiecutter template
* Additional unit tests
* Add plot legend
author | Vimalkumar Velayudhan <vimal@biotechcoder.com> |
---|---|
date | Wed, 12 Aug 2015 09:27:45 +0100 |
parents | |
children | 2ffa8172dce1 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test_riboplot.py Wed Aug 12 09:27:45 2015 +0100 @@ -0,0 +1,165 @@ +import os +import shutil +import logging +import unittest +import tempfile + +from riboplot import ribocore, riboplot + +# use testing configuration +CONFIG = riboplot.CONFIG = riboplot.config.TestingConfig() +logging.disable(logging.CRITICAL) + +RIBO_FILE = os.path.join(CONFIG.DATA_DIR, '5hRPFsorted.bam') +RNA_FILE = os.path.join(CONFIG.DATA_DIR, '5hmRNAsorted.bam') +TRANSCRIPT_NAME = 'gi|148357119|ref|NM_001098396.1|' +TRANSCRIPTOME_FASTA = os.path.join(CONFIG.DATA_DIR, 'zebrafish.fna') +TRANSCRIPTOME_FASTA_MINUS1 = os.path.join(CONFIG.DATA_DIR, 'zebrafish_minus1.fna') + + +class CheckArgumentsTestCase(unittest.TestCase): + """Check if all arguments sent on the command line are valid.""" + parser = riboplot.create_parser() + + def test_bedtools_missing(self): + """If bedtools is not in PATH, raise an error.""" + args = self.parser.parse_args( + ['-b', RIBO_FILE, '-f', TRANSCRIPTOME_FASTA, '-t', TRANSCRIPT_NAME, '-n', RNA_FILE]) + save_path = os.environ['PATH'] + os.environ['PATH'] = '' + self.assertRaises(OSError, ribocore.check_optional_arguments, args.ribo_file, args.rna_file) + os.environ['PATH'] = save_path + + def test_is_bam_valid(self): + """Test if BAM file is valid.""" + valid = ribocore.is_bam_valid(RIBO_FILE) + self.assertTrue(valid) + + # test with a FASTA file (which is not BAM) + self.assertRaises(ValueError, ribocore.is_bam_valid, TRANSCRIPTOME_FASTA) + + def test_bam_has_index(self): + """Check if BAM file has an index.""" + # RPF file has an index + has_index = ribocore.bam_has_index(RIBO_FILE) + self.assertTrue(has_index) + + # RNA file doesn't have an index + has_index = ribocore.bam_has_index(RNA_FILE) + self.assertFalse(has_index) + + def test_create_bam_index(self): + """Index a BAM file.""" + ribocore.create_bam_index(RNA_FILE) + + # check if index exists + has_index = ribocore.bam_has_index(RNA_FILE) + self.assertTrue(has_index) + + # remove index + os.remove('{}.bai'.format(RNA_FILE)) + + def test_valid_read_length(self): + """Read length should be a valid integer.""" + args = self.parser.parse_args(['-b', RIBO_FILE, '-f', TRANSCRIPTOME_FASTA, + '-t', TRANSCRIPT_NAME, '-l', '28']) + ribocore.check_optional_arguments(ribo_file=args.ribo_file, read_length=args.read_length) + + def test_invalid_read_length(self): + """An error is raised if an invalid read length is used.""" + args = self.parser.parse_args(['-b', RIBO_FILE, '-f', TRANSCRIPTOME_FASTA, '-t', TRANSCRIPT_NAME, + '-l', '-1']) # invalid read length -1 + self.assertRaises(ribocore.ArgumentError, ribocore.check_optional_arguments, + args.ribo_file, None, args.read_length) + + args = self.parser.parse_args(['-b', RIBO_FILE, '-f', TRANSCRIPTOME_FASTA, '-t', TRANSCRIPT_NAME, + '-l', '100']) # invalid read length 100 + self.assertRaises(ribocore.ArgumentError, ribocore.check_optional_arguments, + args.ribo_file, None, args.read_length) + + def test_valid_read_offset(self): + """Read offset should be positive.""" + args = self.parser.parse_args(['-b', RIBO_FILE, '-f', TRANSCRIPTOME_FASTA, '-t', TRANSCRIPT_NAME, + '-s', '-1']) # invalid read offset -1 + self.assertRaises(ribocore.ArgumentError, ribocore.check_optional_arguments, + args.ribo_file, None, None, args.read_offset) + + def test_is_fasta_valid(self): + """A valid FASTA file can be opened with pysam.FastaFile.""" + self.assertTrue(ribocore.is_fasta_valid(TRANSCRIPTOME_FASTA)) + + def test_missing_transcript_in_fasta(self): + """If a transcript is missing in FASTA, an error is raised.""" + args = self.parser.parse_args(['-b', RIBO_FILE, '-f', TRANSCRIPTOME_FASTA, '-t', TRANSCRIPT_NAME]) # invalid read offset -1 + self.assertRaises(ribocore.ArgumentError, ribocore.check_required_arguments, + args.ribo_file, args.transcriptome_fasta, 'hello') + + def test_missing_transcript_in_bam(self): + """If a transcript is missing in BAM, an error is raised.""" + # testing with an unrelated BAM file + args = self.parser.parse_args(['-b', '/home/vimal/tmp/empty_tp/RiboSeq.bam', '-f', TRANSCRIPTOME_FASTA, + '-t', TRANSCRIPT_NAME]) + self.assertRaises(ribocore.ArgumentError, ribocore.check_required_arguments, args.ribo_file, + args.transcriptome_fasta, args.transcript_name) + + +class RNACountsTestCase(unittest.TestCase): + + def test_get_rna_counts(self): + """Test get RNA counts for transcript from RNA-Seq BAM file. Assumes bedtools is installed.""" + counts = riboplot.get_rna_counts(RNA_FILE, TRANSCRIPT_NAME) + self.assertIsInstance(counts, dict) + self.assertTrue(len(counts) > 0) + + +class RiboPlotTestCase(unittest.TestCase): + + def test_get_codon_positions(self): + """Get codon positions in all frames given a sequence.""" + # the positions on this sequence were calculated manually. + fasta = ('AACCGGAGCACCCAGAGAAAACCCACGCAAACGCAGGGAGAATTTGCAAACTCCACACA' + 'GAAATGCCAGCTGATCCAGCCGAGCCTCGAGTCAGCATCCTTGCTTGTTGGATGCCTGA' + 'TTGCAGTTCAACTCCAAACTCAGTTGGACCAGCTGATCAGTG') + codon_positions = riboplot.get_start_stops(fasta) + expected = {1: {'starts': [], 'stops': []}, + 2: {'starts': [], 'stops': [71, 116, 152]}, + 3: {'starts': [63, 111], 'stops': []}} + self.assertEqual(codon_positions, expected) + + def test_valid_riboplot_run(self): + """A good riboplot run""" + output_dir = tempfile.mkdtemp() + print 'Output path is {}'.format(output_dir) + parser = riboplot.create_parser() + args = parser.parse_args(['-b', RIBO_FILE, '-f', TRANSCRIPTOME_FASTA, '-t', TRANSCRIPT_NAME, + '-o', output_dir]) + riboplot.main(args) + for fname in ('riboplot.png', 'riboplot.svg', 'RiboCounts.csv'): + self.assertTrue(os.path.exists(os.path.join(output_dir, fname))) + shutil.rmtree(output_dir) + + def test_transcript_with_no_counts(self): + """If the transcript has no ribocounts, no plot should be produced.""" + transcript = 'gi|62955616|ref|NM_001017822.1|' # has no reads + output_dir = tempfile.mkdtemp() + parser = riboplot.create_parser() + args = parser.parse_args(['-b', RIBO_FILE, '-f', TRANSCRIPTOME_FASTA, '-t', transcript, '-o', output_dir]) + self.assertRaises(ribocore.RiboPlotError, riboplot.main, args) + for fname in ('riboplot.png', 'riboplot.svg', 'RiboCounts.csv'): + self.assertFalse(os.path.exists(os.path.join(output_dir, fname))) + shutil.rmtree(output_dir) + + @unittest.skip('todo') + def test_get_ribo_counts(self): + """Get RiboSeq read counts""" + pass + + @unittest.skip('todo') + def test_write_ribo_counts(self): + """Write RiboSeq read counts as CSV.""" + pass + + @unittest.skip('todo') + def test_plot_read_counts(self): + """Generate riboplots""" + pass