def test_calculate_motif_distance(self): cluster_regions = { "exon": { 'real': pybedtools.BedTool( clipper.test_file( "clip_analysis_test_peak_results.bed.exon.real.BED")), 'rand': { 0: pybedtools.BedTool( clipper.test_file( "clip_analysis_test_peak_results.bed.exon.rand.0.BED" )) } } } region_sizes = {'all': 30, "exon": 30} #doesn't matter if I output actual results result = calculate_motif_distance( cluster_regions, region_sizes, pybedtools.BedTool( clipper.test_file("motif_distance_test_motif.bed"))) #make sure dict structure is sound self.assertListEqual(result.keys(), ['all', 'exon']) self.assertListEqual(result['all'].keys(), ['real', 'rand']) self.assertListEqual(result['all']['real'].keys(), ['dist', 'size'])
def test_assign_to_regions(self): """ Basic test of assign to regions """ tool = pybedtools.BedTool( clipper.test_file( "FOX2Brain-05.15.09.polyATrim.adapterTrim.rmRep.sorted.rmDup.peaks.bed" )) assign_to_regions(tool=tool, clusters="test", speciesFA=clipper.test_file("mm9.fa"), regions_dir=os.path.join(clipper.test_dir(), "regions"), regions={ "exons": "Exon", "utr3": "3' UTR", "utr5": "5' UTR", "proxintron500": "Proximal Intron", "distintron500": "Distal Intron" }, assigned_dir=clipper.test_dir(), fasta_dir=clipper.test_dir(), species="mm9", nrand=3, getseq=False)
def test_count_total_reads(self): """ Makes sure we are counting the correct number of reads in genes """ bam = pybedtools.BedTool(clipper.test_file("allup_test.bam")) gene_dfn = pybedtools.BedTool(clipper.test_file("hg19_genes.bed")) result = count_total_reads(bam, gene_dfn) self.assertEqual(result, 2086)
def test_get_motif_distance(self): """ Tests get motif distance """ result = get_motif_distance(pybedtools.BedTool(clipper.test_file("motif_distance_test_cluster.bed")), pybedtools.BedTool(clipper.test_file("motif_distance_test_motif.bed"))) #hand calculated results from motif distance self.assertListEqual(result, [-12,112, 12])
def test_calculate_motif_distance(self): cluster_regions = {"exon" : {'real' : pybedtools.BedTool(clipper.test_file("clip_analysis_test_peak_results.bed.exon.real.BED")), 'rand' : {0: pybedtools.BedTool(clipper.test_file("clip_analysis_test_peak_results.bed.exon.rand.0.BED"))}} } region_sizes = {'all' : 30, "exon" : 30} #doesn't matter if I output actual results result = calculate_motif_distance(cluster_regions, region_sizes, pybedtools.BedTool(clipper.test_file("motif_distance_test_motif.bed"))) #make sure dict structure is sound self.assertListEqual(result.keys(), ['all', 'exon']) self.assertListEqual(result['all'].keys(), ['real', 'rand']) self.assertListEqual(result['all']['real'].keys(), ['dist', 'size'])
def test_get_motif_distance(self): """ Tests get motif distance """ result = get_motif_distance( pybedtools.BedTool( clipper.test_file("motif_distance_test_cluster.bed")), pybedtools.BedTool( clipper.test_file("motif_distance_test_motif.bed"))) #hand calculated results from motif distance self.assertListEqual(result, [-12, 112, 12])
def test_allup_parallel(self): """ Performs basic all up test on entire program (except for main), running in parallel to try to detect crashes """ args = [ "--bam", clipper.test_file("allup_test.bam"), "--species", "hg19", "--gene", "ENSG00000198901", "--outfile", os.getcwd() + "/allup_peak_results.bed", "--debug", ] parser = option_parser() (options, args) = parser.parse_args(args) options = override_options(options) main(options) tested = open(os.getcwd() + "/allup_peak_results.bed") correct = open(clipper.test_file("peak_results_no_overlap.BED")) # problem with tracks being different tested_tool = pybedtools.BedTool(tested) correct_tool = pybedtools.BedTool(correct) # checks to make sure files are equal and there are not exact dups print(len(tested_tool)) print(len(correct_tool)) self.assertAlmostEqual(len(tested_tool), len(correct_tool), delta=3) print(len(tested_tool)) print(len(correct_tool)) # assert False """ for test, correct in zip(tested_tool, correct_tool): self.assertEqual(test, correct) """ # cleanup os.remove(os.getcwd() + "/allup_peak_results.bed")
def test_parse_compseq(self): """ Tests the resut of parse compseq """ file = clipper.test_file("compseq_test.out") diff, dict = parse_compseq(file) self.assertEqual(diff, 11.0) self.assertDictEqual( dict, { 'AA': 2.0, 'AC': 0.0, 'AG': 0.0, 'AT': 1.0, 'CA': 0.0, 'CC': 2.0, 'CG': 0.0, 'CT': 0.0, 'GA': 0.0, 'GC': 1.0, 'GG': 2.0, 'GT': 0.0, 'TA': 0.0, 'TC': 0.0, 'TG': 1.0, 'TT': 2.0, })
def test_parse_compseq(self): """ Tests the resut of parse compseq """ file = clipper.test_file("compseq_test.out") diff, dict = parse_compseq(file) self.assertEqual(diff, 11.0) self.assertDictEqual(dict, { 'AA' : 2.0, 'AC' : 0.0, 'AG' : 0.0, 'AT' : 1.0, 'CA' : 0.0, 'CC' : 2.0, 'CG' : 0.0, 'CT' : 0.0, 'GA' : 0.0, 'GC' : 1.0, 'GG' : 2.0, 'GT' : 0.0, 'TA' : 0.0, 'TC' : 0.0, 'TG' : 1.0, 'TT' : 2.0, })
def test_check_overlaps(self): """ Checks for overlapping results, we don't want this overlaps have been borken for a while, disabling test until its really a problem """ args = [ "--bam", clipper.test_file("allup_test.bam"), "--species", "hg19", "--gene", "ENSG00000198901", "--outfile", os.getcwd() + "/overlap_peak_results.bed", "-q", "--debug" ] parser = option_parser() (options, args) = parser.parse_args(args) options = override_options(options) main(options) # tests to make sure there are no overlaps tested = open(os.getcwd() + "/overlap_peak_results.bed") tested_tool2 = pybedtools.BedTool(tested).saveas(os.getcwd() + "/overlaps.bed") result = tested_tool2.intersect(tested_tool2) self.assertEqual(len(result), len(tested_tool2), "there are overlaps in the output file") # cleanup os.remove(os.getcwd() + "/overlap_peak_results.bed") os.remove(os.getcwd() + "/overlaps.bed")
def test_allup(self): """ runs entire program on small test dataset """ args = ["--clusters", clipper.test_file("clip_analysis_test_peak_results.bed"), "-s", "mm9", "--bam", clipper.test_file("allup_test.bam"), "--AS_Structure", "/home/gabrielp/bioinformatics/Yeo_Lab/clip_analysis_metadata/mm9data4", '--genome_location', '/home/gabrielp/bioinformatics/Yeo_Lab/clip_analysis_metadata/mm9/mm9.fa', "--regions_location", '/home/gabrielp/bioinformatics/Yeo_Lab/clip_analysis_metadata/regions', '--phastcons_location', '/home/gabrielp/bioinformatics/Yeo_Lab/clip_analysis_metadata/phastcons/mm9_phastcons.bw', '--motif', 'AAAAAA', '--nrand', '1', '--rePhast', '--runPhast' ] (options, args) = self.parser.parse_args(args) CLIP_analysis.main(options)
def test_kmer_diff(self): """ Tests all of kmer diff (note checked for identity to original perl module seperatly) """ Motif = namedtuple('Motif', ['freq1', 'freq2', 'delta']) file1 = clipper.test_file("compseq_test.fasta") file2 = clipper.test_file("compseq_test_2.fasta") result, n1, n2 = kmer_diff(file1, file2, 2) self.assertEqual(n1, 11.0) self.assertEqual(n2, 11.0) true = { 'AA': Motif(2.0, 1.0, 0.621260744197396), 'AC': Motif(0.0, 0.0, 0.0), 'AG': Motif(0.0, 0.0, 0.0), 'AT': Motif(1.0, 2.0, -0.621260744197396), 'CA': Motif(0.0, 0.0, 0.0), 'CC': Motif(2.0, 2.0, 0.0), 'CG': Motif(0.0, 0.0, 0.0), 'CT': Motif(0.0, 0.0, 0.0), 'GA': Motif(0.0, 0.0, 0.0), 'GC': Motif(1.0, 1.0, 0.0), 'GG': Motif(2.0, 2.0, 0.0), 'GT': Motif(0.0, 0.0, 0.0), 'TA': Motif(0.0, 1.0, -1.02353263143832), 'TC': Motif(0.0, 0.0, 0.0), 'TG': Motif(1.0, 1.0, 0.0), 'TT': Motif(2.0, 1.0, 0.621260744197396), } #almost equal dict assertion self.assertSetEqual(set(result.keys()), set(true.keys())) for key in result.keys(): self.assertEqual(true[key].freq1, result[key].freq1, "failed at %s" % (key)) self.assertEqual(true[key].freq2, result[key].freq2, "failed at %s" % (key)) self.assertAlmostEqual(true[key].delta, result[key].delta, delta=3)
def test_kmer_diff(self): """ Tests all of kmer diff (note checked for identity to original perl module seperatly) """ Motif = namedtuple('Motif', ['freq1', 'freq2', 'delta']) file1 = clipper.test_file("compseq_test.fasta") file2 = clipper.test_file("compseq_test_2.fasta") result, n1, n2 = kmer_diff(file1, file2, 2) self.assertEqual(n1, 11.0) self.assertEqual(n2, 11.0) true = { 'AA' : Motif(2.0, 1.0, 0.621260744197396 ), 'AC' : Motif(0.0, 0.0, 0.0), 'AG' : Motif(0.0, 0.0, 0.0), 'AT' : Motif(1.0, 2.0, -0.621260744197396), 'CA' : Motif(0.0, 0.0, 0.0), 'CC' : Motif(2.0, 2.0, 0.0), 'CG' : Motif(0.0, 0.0, 0.0), 'CT' : Motif(0.0, 0.0, 0.0), 'GA' : Motif(0.0, 0.0, 0.0), 'GC' : Motif(1.0, 1.0, 0.0), 'GG' : Motif(2.0, 2.0, 0.0), 'GT' : Motif(0.0, 0.0, 0.0), 'TA' : Motif(0.0, 1.0, -1.02353263143832), 'TC' : Motif(0.0, 0.0, 0.0), 'TG' : Motif(1.0, 1.0, 0.0), 'TT' : Motif(2.0, 1.0, 0.621260744197396), } #almost equal dict assertion self.assertSetEqual(set(result.keys()), set(true.keys())) for key in result.keys(): self.assertEqual(true[key].freq1, result[key].freq1, "failed at %s" % (key)) self.assertEqual(true[key].freq2, result[key].freq2, "failed at %s" % (key)) self.assertAlmostEqual(true[key].delta, result[key].delta, delta=3)
def test_calculate_phastcons(self): """ Tests calculate phastcons Only tests that stucture of file is correct """ cluster_regions = {"exon" : {'real' : pybedtools.BedTool(clipper.test_file("clip_analysis_test_peak_results.bed.exon.real.BED")), 'rand' : {0: pybedtools.BedTool(clipper.test_file("clip_analysis_test_peak_results.bed.exon.rand.0.BED"))}} } regions = (["all", "exon", "UTR3", "UTR5", "proxintron500", "distintron500"]) phastcons = '/home/gabrielp/bioinformatics/Yeo_Lab/clip_analysis_metadata/phastcons/mm9_phastcons.bw' result = calculate_phastcons(regions, cluster_regions, phastcons) self.assertListEqual(result.keys(), ['real', 'rand']) self.assertListEqual(result['real'].keys(), ['all', 'exon'])
def test_get_offsets_bed12(self): """ Very lazy test of bed12 offsets """ bedtool = pybedtools.BedTool( clipper.test_file("clip_analysis_test_peak_results.bed")) result = get_offsets_bed12(bedtool) self.assertDictContainsSubset({"ENSMUSG00000051951_1_147": 5}, result)
def test_get_offsets_bed12(self): """ Very lazy test of bed12 offsets """ bedtool = pybedtools.BedTool(clipper.test_file("clip_analysis_test_peak_results.bed")) result = get_offsets_bed12(bedtool) self.assertDictContainsSubset({"ENSMUSG00000051951_1_147" : 5}, result)
def test_allup(self): """ runs entire program on small test dataset """ args = [ "--clusters", clipper.test_file("clip_analysis_test_peak_results.bed"), "-s", "mm9", "--bam", clipper.test_file("allup_test.bam"), "--AS_Structure", os.path.join(clipper.test_dir(), "mm9data4"), '--genome_location', clipper.test_file('mm9.fa'), #'--regions_location', clipper.test_file("knownGene_sample.gtf"), "--regions_location", os.path.join(clipper.test_dir(), "regions"), '--phastcons_location', clipper.test_file("allup_test.bam"), '--motifs', 'AAAAAA', '--nrand', '1', #'--runPhast', '--runMotif', '--bw_pos', clipper.test_file("allup_test.pos.bw"), '--bw_neg', clipper.test_file("allup_test.neg.bw"), ] (options, args) = self.parser.parse_args(args) #self.assertTrue(False, "allup test is slow and has been removed for now") main(options)
def test_assign_to_regions(self): """ Basic test of assign to regions """ tool = pybedtools.BedTool(clipper.test_file("FOX2Brain-05.15.09.polyATrim.adapterTrim.rmRep.sorted.rmDup.peaks.bed")) assign_to_regions(tool=tool, clusters="test", speciesFA= clipper.test_file("mm9.fa"), regions_dir=os.path.join(clipper.test_dir(), "regions"), regions={"exons" : "Exon", "utr3" : "3' UTR", "utr5" : "5' UTR", "proxintron500" : "Proximal Intron", "distintron500" : "Distal Intron"} , assigned_dir = clipper.test_dir(), fasta_dir = clipper.test_dir(), species="mm9", nrand = 3, getseq=False)
def test_check_for_index(self): """ Performs unit tests on check_for_index function """ # Test if string is null, expected result is operation # throws file not exist exception handle = None self.assertRaises(TypeError, check_for_index, handle) # Test if bam file doesn't exist, expected result is operation throws # file does not exist exception handle = "/foo/bar" self.assertRaises(NameError, check_for_index, handle) # Test if file is not bam, but exists expected # result is to throw improper file error handle = clipper.test_file("test_peakfinder.py") self.assertRaises(NameError, check_for_index, handle) # Test if file is bam and indexed expected # result is returns 1 and succedes # should also check if file exists, but I'm lazy handle = clipper.test_file("indexed_test.bam") result = check_for_index(handle) assert result == None # Test if file is bam and not indexed, expected # result is returns one and succedes # should also check if file exists, but I'm lazy handle = clipper.test_file("not_indexed_test.bam") result = check_for_index(handle) assert result == None # cleanup (should be in taredown) os.remove(clipper.test_file("not_indexed_test.bam.bai"))
def test_count_reads_per_cluster(self): """ Tests count reads per cluster """ bedtool = pybedtools.BedTool(clipper.test_file("clip_analysis_test_peak_results.bed")) total_reads, reads_per_cluster = count_reads_per_cluster(bedtool) self.assertListEqual([147,52, 239, 85, 47, 119, 58, 588, 92, 59, 196, 36], reads_per_cluster) self.assertEqual(sum([147,52, 239, 85, 47, 119, 58, 588, 92, 59, 196, 36]), total_reads)
def test_get_mean_phastcons(self): """ Tests get_mean phastcons """ phastcons = clipper.test_file("mm9_phastcons.bw") tool = pybedtools.BedTool("chr15 91512755 91512836 ENSG00000198901_1_147 0 -", from_string=True) result = get_mean_phastcons(tool, phastcons) #pre-computed correct answer self.assertAlmostEqual(result[0], 0.01738272, delta=5)
def test_calculate_phastcons(self): """ Tests calculate phastcons Only tests that stucture of file is correct """ cluster_regions = { "exon": { 'real': pybedtools.BedTool( clipper.test_file( "clip_analysis_test_peak_results.bed.exon.real.BED")), 'rand': { 0: pybedtools.BedTool( clipper.test_file( "clip_analysis_test_peak_results.bed.exon.rand.0.BED" )), 1: pybedtools.BedTool( clipper.test_file( "clip_analysis_test_peak_results.bed.exon.rand.0.BED" )) } } } regions = ([ "all", "exon", "UTR3", "UTR5", "proxintron500", "distintron500" ]) phastcons = clipper.test_file('mm9_phastcons.bw') result = calculate_phastcons(regions, cluster_regions, phastcons) self.assertListEqual(result.keys(), ['real', 'rand']) self.assertListEqual(result['real'].keys(), ['all', 'exon'])
def test_get_mean_phastcons(self): """ Tests get_mean phastcons """ phastcons = clipper.test_file("mm9_phastcons.bw") tool = pybedtools.BedTool( "chr15 91512755 91512836 ENSG00000198901_1_147 0 -", from_string=True) result = get_mean_phastcons(tool, phastcons) #pre-computed correct answer self.assertAlmostEqual(result[0], 0.01738272, delta=5)
def test_build_genomic_regions(self): """ Tests build genomic regions """ CDS = pybedtools.BedTool("""chr1\t7700\t7900\tfoo\t0\t+\n chr1\t7999\t8500\tfoo\t0\t+\n""", from_string=True) UTR5 = pybedtools.BedTool("""chr1\t7499\t7700\tfoo\t0\t+\n""", from_string=True) UTR3 = pybedtools.BedTool("""chr1\t8500\t9000\tfoo\t0\t+\n""", from_string=True) proxintron = pybedtools.BedTool("""chr1\t100\t300\tfoo\t0\t+\n chr1\t798\t998\tfoo\t0\t+\n chr1\t2000\t2200\tfoo\t0\t+\n chr1\t2798\t2998\tfoo\t0\t+\n chr1\t6000\t6200\tfoo\t0\t+\n chr1\t6798\t6998\tfoo\t0\t+\n chr1\t7900\t7998\tfoo\t0\t+\n""", from_string=True) distintron = pybedtools.BedTool("""chr1\t301\t797\tfoo\t0\t+\n chr1\t2201\t2797\tfoo\t0\t+\n chr1\t6201\t6797\tfoo\t0\t+\n""", from_string=True) regions = build_genomic_regions(pybedtools.BedTool( clipper.test_file("test.gtf")), prox_distance=200) #print UTR3 #print regions['UTR3'] print proxintron print regions['proxintron'] #print regions['distintron'] self.assertEqual(len(CDS.intersect(regions['CDS'], f=1.0, r=True)), 2) self.assertEqual(len(UTR5.intersect(regions['UTR5'], f=1.0, r=True)), 1) self.assertEqual(len(UTR3.intersect(regions['UTR3'], f=1.0, r=True)), 1) self.assertEqual( len(proxintron.intersect(regions['proxintron'], f=1.0, r=True)), 7) self.assertEqual( len(distintron.intersect(regions['distintron'], f=1.0, r=True)), 3)
def test_count_reads_per_cluster(self): """ Tests count reads per cluster """ bedtool = pybedtools.BedTool( clipper.test_file("clip_analysis_test_peak_results.bed")) total_reads, reads_per_cluster = count_reads_per_cluster(bedtool, None) self.assertListEqual( [147, 52, 239, 85, 47, 119, 58, 588, 92, 59, 196, 36], reads_per_cluster) self.assertEqual( sum([147, 52, 239, 85, 47, 119, 58, 588, 92, 59, 196, 36]), total_reads)
def test_adjust_offsets(self): """ Tests adjust offsets, only on bed12 files """ offsets = {"ENSMUSG00000051951_1_147" : 10, "ENSG00000198901_2_52" : 10 , "ENSG00000198901_3_239" : 10, "ENSG00000198901_4_85" : 10 , "ENSG00000198901_5_47" : 10 , "ENSG00000198901_6_119" : 10 , "ENSG00000198901_7_58" : 10 , "ENSG00000198901_8_588" : 10 , "ENSG00000198901_10_92" : 10 , "ENSG00000198901_11_59" : 10 , "ENSG00000198901_12_196" : 10 , "ENSG00000198901_13_36" : 10 , } bedtool = pybedtools.BedTool(clipper.test_file("clip_analysis_test_peak_results.bed")) results = adjust_offsets(bedtool, offsets) true_results = ((3206126, 3206130), (91513660, 91513664), (91517394, 91517398), (91517935, 91517939), (91522404, 91522408), (91523607, 91523611), (91524250, 91524254), (91525137, 91525141), (91527347, 91527351), (91527937, 91527941), (91528034, 91528038), (91537658, 91537662), ) for result, true_result in zip(results, true_results): self.assertEqual(int(result[6]), true_result[0]) self.assertEqual(int(result[7]), true_result[1])
def test_adjust_offsets(self): """ Tests adjust offsets, only on bed12 files """ offsets = { "ENSMUSG00000051951_1_147": 10, "ENSG00000198901_2_52": 10, "ENSG00000198901_3_239": 10, "ENSG00000198901_4_85": 10, "ENSG00000198901_5_47": 10, "ENSG00000198901_6_119": 10, "ENSG00000198901_7_58": 10, "ENSG00000198901_8_588": 10, "ENSG00000198901_10_92": 10, "ENSG00000198901_11_59": 10, "ENSG00000198901_12_196": 10, "ENSG00000198901_13_36": 10, } bedtool = pybedtools.BedTool( clipper.test_file("clip_analysis_test_peak_results.bed")) results = adjust_offsets(bedtool, offsets) true_results = ( (3206126, 3206130), (91513660, 91513664), (91517394, 91517398), (91517935, 91517939), (91522404, 91522408), (91523607, 91523611), (91524250, 91524254), (91525137, 91525141), (91527347, 91527351), (91527937, 91527941), (91528034, 91528038), (91537658, 91537662), ) for result, true_result in zip(results, true_results): self.assertEqual(int(result[6]), true_result[0]) self.assertEqual(int(result[7]), true_result[1])
def test_build_genomic_regions(self): """ Tests build genomic regions """ CDS = pybedtools.BedTool("""chr1\t7700\t7900\tfoo\t0\t+\n chr1\t7999\t8500\tfoo\t0\t+\n""", from_string = True) UTR5 = pybedtools.BedTool("""chr1\t7499\t7700\tfoo\t0\t+\n""", from_string = True) UTR3 = pybedtools.BedTool("""chr1\t8500\t9000\tfoo\t0\t+\n""", from_string = True) proxintron = pybedtools.BedTool("""chr1\t100\t300\tfoo\t0\t+\n chr1\t798\t998\tfoo\t0\t+\n chr1\t2000\t2200\tfoo\t0\t+\n chr1\t2798\t2998\tfoo\t0\t+\n chr1\t6000\t6200\tfoo\t0\t+\n chr1\t6798\t6998\tfoo\t0\t+\n chr1\t7900\t7998\tfoo\t0\t+\n""", from_string = True ) distintron = pybedtools.BedTool("""chr1\t301\t797\tfoo\t0\t+\n chr1\t2201\t2797\tfoo\t0\t+\n chr1\t6201\t6797\tfoo\t0\t+\n""", from_string = True) regions = build_genomic_regions(pybedtools.BedTool(clipper.test_file("test.gtf")), prox_distance=200) #print UTR3 #print regions['UTR3'] print proxintron print regions['proxintron'] #print regions['distintron'] self.assertEqual(len(CDS.intersect(regions['CDS'], f= 1.0, r = True)), 2) self.assertEqual(len(UTR5.intersect(regions['UTR5'], f= 1.0, r = True)), 1) self.assertEqual(len(UTR3.intersect(regions['UTR3'], f= 1.0, r = True)), 1) self.assertEqual(len(proxintron.intersect(regions['proxintron'], f= 1.0, r = True)), 7) self.assertEqual(len(distintron.intersect(regions['distintron'], f= 1.0, r = True)), 3)
def test_allup(self): """ runs entire program on small test dataset """ args = ["--clusters", clipper.test_file("clip_analysis_test_peak_results.bed"), "-s", "mm9", "--bam", clipper.test_file("allup_test.bam"), "--AS_Structure", os.path.join(clipper.test_dir(), "mm9data4"), '--genome_location', clipper.test_file('mm9.fa'), #'--regions_location', clipper.test_file("knownGene_sample.gtf"), "--regions_location", os.path.join(clipper.test_dir(), "regions"), '--phastcons_location', clipper.test_file("allup_test.bam"), '--motifs', 'AAAAAA', '--nrand', '1', #'--runPhast', '--runMotif', '--bw_pos', clipper.test_file("allup_test.pos.bw"), '--bw_neg', clipper.test_file("allup_test.neg.bw"), ] (options, args) = self.parser.parse_args(args) #self.assertTrue(False, "allup test is slow and has been removed for now") main(options)