From 4ccd15d3af95d067d87264ddef714be351f61891 Mon Sep 17 00:00:00 2001 From: Evan Ernst Date: Mon, 23 Feb 2015 11:01:41 -0500 Subject: [PATCH 01/20] Support Trinity 2.0.0+ style accessions --- scripts/build_comprehensive_transcriptome.dbi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/build_comprehensive_transcriptome.dbi b/scripts/build_comprehensive_transcriptome.dbi index d3da7c5..aff0414 100755 --- a/scripts/build_comprehensive_transcriptome.dbi +++ b/scripts/build_comprehensive_transcriptome.dbi @@ -351,6 +351,10 @@ sub get_TDN_component { elsif ($cdna_acc =~ /^(c\d+_g\d+)/) { $component = $1; } + elsif ($cdna_acc =~ /^(TR\d+\|c\d+_g\d+)/) { + # trinity de novo 2.0.0+ style + $component = $1; + } else { confess "Error, cannot extract component info from trinity de novo assembly: $cdna_acc"; } From 521ba80b953109a565e70124abebcaf085804894 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Fri, 13 Mar 2015 08:27:41 -0400 Subject: [PATCH 02/20] dont need the optimize tables script --- scripts/Launch_PASA_pipeline.pl | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/scripts/Launch_PASA_pipeline.pl b/scripts/Launch_PASA_pipeline.pl index 205b5d5..500f172 100755 --- a/scripts/Launch_PASA_pipeline.pl +++ b/scripts/Launch_PASA_pipeline.pl @@ -419,18 +419,6 @@ } - ###################################################### - ## Optimize the database after uploading all that data - ###################################################### - - push (@cmds, { prog => "$UTILDIR/optimize_tables.dbi", - params => " -c $configfile ", - input => undef, - output => undef, - } ); - - - ############################## ## done aligning transcripts. ############################## From 6c9f9e37a1bf257410b4727cb2ee0e4a7f533897 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Fri, 27 Mar 2015 19:48:05 -0400 Subject: [PATCH 03/20] include gff3-alignment to gtf conversion util --- PerlLib/Fastq_reader.pm | 8 +- PerlLib/GFF3_alignment_utils.pm | 75 +++++++++- PerlLib/GTF_alignment_utils.pm | 187 +++++++++++++++++++++++++ PerlLib/Pipeliner.pm | 141 +++++++++++++++++++ misc_utilities/gff3_alignment_to_gtf_format.pl | 41 ++++++ 5 files changed, 442 insertions(+), 10 deletions(-) create mode 100755 PerlLib/GTF_alignment_utils.pm create mode 100644 PerlLib/Pipeliner.pm create mode 100755 misc_utilities/gff3_alignment_to_gtf_format.pl diff --git a/PerlLib/Fastq_reader.pm b/PerlLib/Fastq_reader.pm index c2011ee..e6e9b02 100755 --- a/PerlLib/Fastq_reader.pm +++ b/PerlLib/Fastq_reader.pm @@ -3,8 +3,6 @@ package Fastq_reader; use strict; use warnings; -use PerlIO::gzip; - sub new { my ($packagename, $fastqFile) = @_; @@ -24,7 +22,11 @@ sub new { } else { if ( $fastqFile =~ /\.gz$/ ) { - open ($filehandle, "<:gzip", $fastqFile) or die "Error: Couldn't open compressed $fastqFile\n"; + open ($filehandle, "gunzip -c $fastqFile | ") or die "Error: Couldn't open compressed $fastqFile\n"; + } + elsif ($fastqFile =~ /\.bz2$/) { + open ($filehandle, "bunzip2 -c $fastqFile | ") or die "Error, couldn't open compressed $fastqFile $!"; + } else { open ($filehandle, $fastqFile) or die "Error: Couldn't open $fastqFile\n"; } diff --git a/PerlLib/GFF3_alignment_utils.pm b/PerlLib/GFF3_alignment_utils.pm index 4bf321c..89c5946 100755 --- a/PerlLib/GFF3_alignment_utils.pm +++ b/PerlLib/GFF3_alignment_utils.pm @@ -1,3 +1,5 @@ +#!/usr/bin/env perl + package GFF3_alignment_utils; use strict; @@ -5,10 +7,14 @@ use warnings; use Carp; use Gene_obj; +use Gene_obj_indexer; use CDNA::Alignment_segment; use CDNA::CDNA_alignment; +use File::Basename; + +__run_test() unless caller; -sub index_GFF3_alignment_objs { +sub index_alignment_objs { my ($gff3_alignment_file, $genome_alignment_indexer_href) = @_; unless ($gff3_alignment_file && -s $gff3_alignment_file) { @@ -17,10 +23,11 @@ sub index_GFF3_alignment_objs { unless (ref $genome_alignment_indexer_href) { confess "Error, need genome indexer href as param "; } - - + my %genome_trans_to_alignment_segments; + my %trans_to_gene_id; + open (my $fh, $gff3_alignment_file) or die "Error, cannot open file $gff3_alignment_file"; while (<$fh>) { @@ -69,17 +76,19 @@ sub index_GFF3_alignment_objs { my ($end5, $end3) = ($orient eq '+') ? ($lend, $rend) : ($rend, $lend); - $info =~ /Target=\S+ (\d+) (\d+) ([\+\-])/ or die "Error, cannot extract match coordinates from info: $info"; + $info =~ /Target=\S+ (\d+) (\d+)/ or die "Error, cannot extract match coordinates from info: $info"; my $cdna_seg_lend = $1; my $cdna_seg_rend = $2; - my $cdna_orient = $3; # always set to + in pasa + + ($cdna_seg_lend, $cdna_seg_rend) = sort {$a<=>$b} ($cdna_seg_lend, $cdna_seg_rend); # always + orient for transcript coords. + my $alignment_segment = new CDNA::Alignment_segment($end5, $end3, $cdna_seg_lend, $cdna_seg_rend, $per_id); push (@{$genome_trans_to_alignment_segments{$scaff}->{$gene_id}}, $alignment_segment); - + $trans_to_gene_id{$trans_id} = $gene_id; } @@ -108,9 +117,19 @@ sub index_GFF3_alignment_objs { my $cdna_alignment_obj = new CDNA::CDNA_alignment($max_coord, $segments_aref); $cdna_alignment_obj->set_acc($alignment_acc); $cdna_alignment_obj->{genome_acc} = $scaff; + $cdna_alignment_obj->{gene_id} = $alignment_acc; - $genome_alignment_indexer_href->{$alignment_acc} = $cdna_alignment_obj; + + $cdna_alignment_obj->{source} = basename($gff3_alignment_file); + if (ref $genome_alignment_indexer_href eq "Gene_obj_indexer") { + $genome_alignment_indexer_href->store_gene($alignment_acc, $cdna_alignment_obj); + + } + else { + + $genome_alignment_indexer_href->{$alignment_acc} = $cdna_alignment_obj; + } push (@{$scaff_to_align_list{$scaff}}, $alignment_acc); } } @@ -118,5 +137,47 @@ sub index_GFF3_alignment_objs { return(%scaff_to_align_list); } + + +################# +## Testing +################# + + +sub __run_test { + + my $usage = "usage: $0 file.alignment.gff3\n\n"; + + my $gff3_file = $ARGV[0] or die $usage; + + my $indexer = {}; + my %scaff_to_alignments = &index_alignment_objs($gff3_file, $indexer); + + + foreach my $scaffold (keys %scaff_to_alignments) { + + my @align_ids = @{$scaff_to_alignments{$scaffold}}; + + foreach my $align_id (@align_ids) { + my $cdna_obj = $indexer->{$align_id}; + + print $cdna_obj->toString(); + } + } + + + + exit(0); + + + +} + + + + + + + 1; #EOM diff --git a/PerlLib/GTF_alignment_utils.pm b/PerlLib/GTF_alignment_utils.pm new file mode 100755 index 0000000..5985174 --- /dev/null +++ b/PerlLib/GTF_alignment_utils.pm @@ -0,0 +1,187 @@ +#!/usr/bin/env perl + +package GTF_alignment_utils; + +use strict; +use warnings; +use Carp; + +use Gene_obj; +use Gene_obj_indexer; +use CDNA::Alignment_segment; +use CDNA::CDNA_alignment; +use File::Basename; + +__run_test() unless caller; + + + +sub index_alignment_objs { + my ($gtf_alignment_file, $genome_alignment_indexer_href) = @_; + + unless ($gtf_alignment_file && -s $gtf_alignment_file) { + confess "Error, cannot find or open file $gtf_alignment_file"; + } + unless (ref $genome_alignment_indexer_href) { + confess "Error, need genome indexer href as param "; + } + + + + my %genome_trans_to_alignment_segments; + + my %trans_to_gene_id; + + open (my $fh, $gtf_alignment_file) or die "Error, cannot open file $gtf_alignment_file"; + while (<$fh>) { + chomp; + if (/^\#/) { next; } + unless (/\w/) { next; } + + my @x = split(/\t/); + + unless (scalar (@x) >= 8 && $x[8] =~ /transcript_id/) { + print STDERR "ignoring line: $_\n"; + next; + } + + my $scaff = $x[0]; + my $type = $x[2]; + my $lend = $x[3]; + my $rend = $x[4]; + my $per_id = $x[5]; + + unless ($type eq 'exon') { next; } + + + if ($per_id eq ".") { $per_id = 100; } # making an assumption here. + + my $orient = $x[6]; + + my $info = $x[8]; + + my @parts = split(/;/, $info); + my %atts; + foreach my $part (@parts) { + $part =~ s/^\s+|\s+$//; + $part =~ s/\"//g; + my ($att, $val) = split(/\s+/, $part); + + if (exists $atts{$att}) { + die "Error, already defined attribute $att in $_"; + } + + $atts{$att} = $val; + } + + my $gene_id = $atts{gene_id} or die "Error, no gene_id at $_"; + my $trans_id = $atts{transcript_id} or die "Error, no trans_id at $_"; + + + $trans_to_gene_id{$trans_id} = $gene_id; + + push (@{$genome_trans_to_alignment_segments{$scaff}->{$trans_id}}, [$lend, $rend, $orient]); + + } + + + my %scaff_to_align_list; + + + ## Output genes in gtf format: + + foreach my $scaff (sort keys %genome_trans_to_alignment_segments) { + + my @alignment_accs = keys %{$genome_trans_to_alignment_segments{$scaff}}; + + foreach my $alignment_acc (@alignment_accs) { + + my @segments = @{$genome_trans_to_alignment_segments{$scaff}->{$alignment_acc}}; + @segments = sort {$a->[0]<=>$b->[0]} @segments; + my $orient = $segments[0]->[2]; + if ($orient eq '-') { + @segments = reverse @segments; + } + my @cdna_align_segs; + my @coords; + my $curr_cdna_len = 0; + foreach my $segment (@segments) { + my ($lend, $rend, $orient) = @$segment; + my ($m_lend, $m_rend) = ($curr_cdna_len + 1, $curr_cdna_len + abs($rend - $lend) + 1); + $curr_cdna_len = $m_rend; + if ($orient eq '-') { + ($m_lend, $m_rend) = ($m_rend, $m_lend); + } + my $alignment_segment = new CDNA::Alignment_segment($lend, $rend, $m_lend, $m_rend, 100); + push (@cdna_align_segs, $alignment_segment); + + } + + my $cdna_alignment_obj = new CDNA::CDNA_alignment($curr_cdna_len, \@cdna_align_segs); + $cdna_alignment_obj->set_acc($alignment_acc); + $cdna_alignment_obj->{genome_acc} = $scaff; + + $cdna_alignment_obj->{gene_id} = $trans_to_gene_id{$alignment_acc}; + + my $spliced_orient = $orient; + if ($spliced_orient !~ /^[\+\-]$/) { + $spliced_orient = '?'; + } + $cdna_alignment_obj->set_spliced_orientation($spliced_orient); + + $cdna_alignment_obj->{source} = basename($gtf_alignment_file); + + if (ref $genome_alignment_indexer_href eq "Gene_obj_indexer") { + $genome_alignment_indexer_href->store_gene($alignment_acc, $cdna_alignment_obj); + } + else { + $genome_alignment_indexer_href->{$alignment_acc} = $cdna_alignment_obj; + } + + push (@{$scaff_to_align_list{$scaff}}, $alignment_acc); + } + } + + return(%scaff_to_align_list); +} + + +########### +# Testing +########## + +sub __run_test { + + my $usage = "usage: $0 file.gtf\n\n"; + + my $gtf_file = $ARGV[0] or die $usage; + + my $indexer = {}; + my %scaff_to_alignments = &index_alignment_objs($gtf_file, $indexer); + + + foreach my $scaffold (keys %scaff_to_alignments) { + + my @align_ids = @{$scaff_to_alignments{$scaffold}}; + + foreach my $align_id (@align_ids) { + my $cdna_obj = $indexer->{$align_id}; + + print $cdna_obj->toString(); + } + } + + + + exit(0); + + + +} + + + + + +1; #EOM + diff --git a/PerlLib/Pipeliner.pm b/PerlLib/Pipeliner.pm new file mode 100644 index 0000000..03e7f22 --- /dev/null +++ b/PerlLib/Pipeliner.pm @@ -0,0 +1,141 @@ +package Pipeliner; + +use strict; +use warnings; +use Carp; + +################################ +## Verbose levels: +## 1: see CMD string +## 2: see stderr during process +my $VERBOSE = 0; +################################ + + +#### +sub new { + my $packagename = shift; + my %params = @_; + + if ($params{-verbose}) { + $VERBOSE = $params{-verbose}; + } + + my $self = { + cmd_objs => [], + }; + + bless ($self, $packagename); + + return($self); +} + + +sub add_commands { + my $self = shift; + my @cmds = @_; + + foreach my $cmd (@cmds) { + unless (ref($cmd) =~ /Command/) { + confess "Error, need Command object as param"; + } + push (@{$self->{cmd_objs}}, $cmd); + } + + return $self; + +} + +sub run { + my $self = shift; + + foreach my $cmd_obj ($self->_get_commands()) { + + my $cmdstr = $cmd_obj->get_cmdstr(); + my $checkpoint_file = $cmd_obj->get_checkpoint_file(); + + if (-e $checkpoint_file) { + print STDERR "-- Skipping CMD: $cmdstr, checkpoint exists.\n" if $VERBOSE; + } + else { + print STDERR "* Running CMD: $cmdstr\n" if $VERBOSE; + + my $tmp_stderr = "tmp.$$.stderr"; + if (-e $tmp_stderr) { + unlink($tmp_stderr); + } + unless ($VERBOSE == 2) { + $cmdstr .= " 2>$tmp_stderr"; + } + + my $ret = system($cmdstr); + if ($ret) { + + if (-e $tmp_stderr) { + system("cat $tmp_stderr"); + unlink($tmp_stderr); + } + + confess "Error, cmd: $cmdstr died with ret $ret"; + } + else { + `touch $checkpoint_file`; + if ($?) { + + confess "Error creating checkpoint file: $checkpoint_file"; + } + } + + if (-e $tmp_stderr) { + unlink($tmp_stderr); + } + } + } + + return; +} + +sub _get_commands { + my $self = shift; + + return(@{$self->{cmd_objs}}); +} + +package Command; +use strict; +use warnings; +use Carp; + +sub new { + my $packagename = shift; + + my ($cmdstr, $checkpoint_file) = @_; + + unless ($cmdstr && $checkpoint_file) { + confess "Error, need cmdstr and checkpoint filename as params"; + } + + my $self = { cmdstr => $cmdstr, + checkpoint_file => $checkpoint_file, + }; + + bless ($self, $packagename); + + return($self); +} + +#### +sub get_cmdstr { + my $self = shift; + return($self->{cmdstr}); +} + +#### +sub get_checkpoint_file { + my $self = shift; + return($self->{checkpoint_file}); +} + + + +1; #EOM diff --git a/misc_utilities/gff3_alignment_to_gtf_format.pl b/misc_utilities/gff3_alignment_to_gtf_format.pl new file mode 100755 index 0000000..df4d944 --- /dev/null +++ b/misc_utilities/gff3_alignment_to_gtf_format.pl @@ -0,0 +1,41 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Carp; + +use FindBin; +use lib ("$FindBin::Bin/../PerlLib"); +use GFF3_alignment_utils; +use Fasta_retriever; + +my $usage = "usage: $0 trans_align.gff3\n\n"; + +my $trans_align_gff3 = $ARGV[0] or die $usage; + + +main: { + + my %cdna_alignments; + + print STDERR "-parsing $trans_align_gff3\n"; + my %scaff_to_cdna_ids = &GFF3_alignment_utils::index_alignment_objs($trans_align_gff3, \%cdna_alignments); + + + print STDERR "-outputting GTF format\n"; + foreach my $scaff (keys %scaff_to_cdna_ids) { + + foreach my $cdna_id (@{$scaff_to_cdna_ids{$scaff}}) { + + my $cdna_obj = $cdna_alignments{$cdna_id}; + + print $cdna_obj->to_GTF_format( gene_id => $cdna_obj->{gene_id} ) . "\n"; + + } + } + + + exit(0); +} + + From 8d055a3d54a605cc4270f538cc62f09aad8db423 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Mon, 30 Mar 2015 17:15:20 -0400 Subject: [PATCH 04/20] store gene id not trans id as the gene_id att, bugfix --- PerlLib/GFF3_alignment_utils.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PerlLib/GFF3_alignment_utils.pm b/PerlLib/GFF3_alignment_utils.pm index 89c5946..f1150db 100755 --- a/PerlLib/GFF3_alignment_utils.pm +++ b/PerlLib/GFF3_alignment_utils.pm @@ -117,7 +117,7 @@ sub index_alignment_objs { my $cdna_alignment_obj = new CDNA::CDNA_alignment($max_coord, $segments_aref); $cdna_alignment_obj->set_acc($alignment_acc); $cdna_alignment_obj->{genome_acc} = $scaff; - $cdna_alignment_obj->{gene_id} = $alignment_acc; + $cdna_alignment_obj->{gene_id} = $trans_to_gene_id{$alignment_acc}; $cdna_alignment_obj->{source} = basename($gff3_alignment_file); From f540b869a0e5b04d7b1e45b1f733fad5b6fda78f Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Mon, 30 Mar 2015 17:36:45 -0400 Subject: [PATCH 05/20] bugfix.. got it this time. --- PerlLib/GFF3_alignment_utils.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/PerlLib/GFF3_alignment_utils.pm b/PerlLib/GFF3_alignment_utils.pm index f1150db..35f6755 100755 --- a/PerlLib/GFF3_alignment_utils.pm +++ b/PerlLib/GFF3_alignment_utils.pm @@ -86,7 +86,7 @@ sub index_alignment_objs { my $alignment_segment = new CDNA::Alignment_segment($end5, $end3, $cdna_seg_lend, $cdna_seg_rend, $per_id); - push (@{$genome_trans_to_alignment_segments{$scaff}->{$gene_id}}, $alignment_segment); + push (@{$genome_trans_to_alignment_segments{$scaff}->{$trans_id}}, $alignment_segment); $trans_to_gene_id{$trans_id} = $gene_id; @@ -117,7 +117,10 @@ sub index_alignment_objs { my $cdna_alignment_obj = new CDNA::CDNA_alignment($max_coord, $segments_aref); $cdna_alignment_obj->set_acc($alignment_acc); $cdna_alignment_obj->{genome_acc} = $scaff; - $cdna_alignment_obj->{gene_id} = $trans_to_gene_id{$alignment_acc}; + + my $gene_id = $trans_to_gene_id{$alignment_acc} or confess "Error no gene_id for acc: $alignment_acc"; + + $cdna_alignment_obj->{gene_id} = $gene_id; $cdna_alignment_obj->{source} = basename($gff3_alignment_file); From d5c40f34ebaaff22af07db151ca813aee37946d3 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Fri, 3 Apr 2015 20:49:34 -0400 Subject: [PATCH 06/20] deprecate --- misc_utilities/{ => deprecated}/gff3_gene_to_transcript_gff3.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename misc_utilities/{ => deprecated}/gff3_gene_to_transcript_gff3.pl (100%) diff --git a/misc_utilities/gff3_gene_to_transcript_gff3.pl b/misc_utilities/deprecated/gff3_gene_to_transcript_gff3.pl similarity index 100% rename from misc_utilities/gff3_gene_to_transcript_gff3.pl rename to misc_utilities/deprecated/gff3_gene_to_transcript_gff3.pl From 68bf0802fb32f976691dc99462380426c6bdacd1 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Fri, 3 Apr 2015 20:51:00 -0400 Subject: [PATCH 07/20] renamed --- ...ff3_gene_to_transcript_gff3.pl => old.gff3_gene_to_transcript_gff3.pl} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename misc_utilities/deprecated/{gff3_gene_to_transcript_gff3.pl => old.gff3_gene_to_transcript_gff3.pl} (100%) diff --git a/misc_utilities/deprecated/gff3_gene_to_transcript_gff3.pl b/misc_utilities/deprecated/old.gff3_gene_to_transcript_gff3.pl similarity index 100% rename from misc_utilities/deprecated/gff3_gene_to_transcript_gff3.pl rename to misc_utilities/deprecated/old.gff3_gene_to_transcript_gff3.pl From 3fbba775a5c344a0dd9f3fbecc727e42525944cb Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Wed, 22 Apr 2015 10:27:45 -0400 Subject: [PATCH 08/20] treat transcript features identically to mRNA features in gff3 --- PerlLib/GFF3_utils.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PerlLib/GFF3_utils.pm b/PerlLib/GFF3_utils.pm index aa77d12..d3d4b60 100644 --- a/PerlLib/GFF3_utils.pm +++ b/PerlLib/GFF3_utils.pm @@ -66,7 +66,7 @@ sub index_GFF3_gene_objs { unless ($feat_type) { die "Error, $_, no feat_type: line\[$_\]"; } - unless ($feat_type =~ /^(gene|mRNA|CDS|exon)$/) { next;} + unless ($feat_type =~ /^(gene|mRNA|transcript|CDS|exon)$/) { next;} $gene_info = uri_unescape($gene_info); @@ -107,7 +107,7 @@ sub index_GFF3_gene_objs { # print "id: $id, parent: $parent\n"; - if ($feat_type eq 'mRNA') { + if ($feat_type eq 'mRNA' || $feat_type eq 'transcript') { ## just get the identifier info $transcript_to_gene{$id} = $parent; next; From 8a5ec2df39cf6d2b30f1bd6a825dd2d149fd0e11 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Tue, 28 Apr 2015 11:03:53 -0400 Subject: [PATCH 09/20] added the process ID into the inx filename to better provide uniqueness when the target gff3 file is being shared among several parallel proesses --- SAMPLE_HOOKS/GFF3/GFF3_annot_retriever.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SAMPLE_HOOKS/GFF3/GFF3_annot_retriever.pm b/SAMPLE_HOOKS/GFF3/GFF3_annot_retriever.pm index 7d5182b..30cbe97 100644 --- a/SAMPLE_HOOKS/GFF3/GFF3_annot_retriever.pm +++ b/SAMPLE_HOOKS/GFF3/GFF3_annot_retriever.pm @@ -24,7 +24,7 @@ sub get_annot_retriever { confess "Error, cannot locate gff3 file $gff3_filename"; } - my $gene_obj_indexer = new Gene_obj_indexer( { create => "$gff3_filename.inx"} ); + my $gene_obj_indexer = new Gene_obj_indexer( { create => "$gff3_filename.$$.inx"} ); &GFF3_utils::index_GFF3_gene_objs($gff3_filename, $gene_obj_indexer); From 04342a2473438a9df769fcf4716e2421a1d701cb Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Sat, 9 May 2015 08:29:36 +1000 Subject: [PATCH 10/20] if -r mode, try to remove existing db but dont fail if it does not exist --- PerlLib/SingleLinkageClusterer.pm | 81 +++++++++++++++++++++----------- scripts/create_mysql_cdnaassembly_db.dbi | 5 +- 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/PerlLib/SingleLinkageClusterer.pm b/PerlLib/SingleLinkageClusterer.pm index a3a1fa3..0a32a95 100755 --- a/PerlLib/SingleLinkageClusterer.pm +++ b/PerlLib/SingleLinkageClusterer.pm @@ -1,3 +1,5 @@ +#!/usr/bin/env perl + package main; our $CLUSTERPATH; @@ -12,39 +14,45 @@ package SingleLinkageClusterer; ## return ([1,2,3] , [6,7,8], ...) use strict; +use warnings; + +__run_test() unless caller; sub build_clusters { my @pairs = @_; - my $pairfile = "/tmp/$$.pairs"; + + my $uniq_stamp = "$$." . time() . "." . rand(); + + my $pairfile = "/tmp/$uniq_stamp.pairs"; #must do mapping because cluster program doesn't like word chars, just ints. my %map_id_to_feat; my %map_feat_to_id; my $id = 1; - + open (PAIRLIST, ">$pairfile") or die "Can't write $pairfile to /tmp"; foreach my $pair (@pairs) { - my ($a, $b) = @$pair; - unless ($map_feat_to_id{$a}) { - $map_feat_to_id{$a} = $id; - $map_id_to_feat{$id} = $a; - $id++; - } - unless ($map_feat_to_id{$b}) { - $map_feat_to_id{$b} = $id; - $map_id_to_feat{$id} = $b; - $id++; - } - - print PAIRLIST "$map_feat_to_id{$a} $map_feat_to_id{$b}\n"; + my ($a, $b) = @$pair; + unless ($map_feat_to_id{$a}) { + $map_feat_to_id{$a} = $id; + $map_id_to_feat{$id} = $a; + $id++; + } + unless ($map_feat_to_id{$b}) { + $map_feat_to_id{$b} = $id; + $map_id_to_feat{$id} = $b; + $id++; + } + + print PAIRLIST "$map_feat_to_id{$a} $map_feat_to_id{$b}\n"; } close PAIRLIST; - my $clusterfile = "/tmp/$$.clusters"; - + my $clusterfile = "/tmp/$uniq_stamp.clusters"; + my $cluster_prog = "slclust"; if ($CLUSTERPATH) { - $cluster_prog = $CLUSTERPATH; + $cluster_prog = $CLUSTERPATH; } system "touch $clusterfile"; @@ -52,20 +60,20 @@ sub build_clusters { my $cmd = "$cluster_prog < $pairfile > $clusterfile"; my $ret = system ($cmd); if ($ret) { - die "ERROR: Couldn't run cluster properly via path: $cluster_prog.\ncmd: $cmd"; + die "ERROR: Couldn't run cluster properly via path: $cluster_prog.\ncmd: $cmd"; } - + my @clusters; open (CLUSTERS, $clusterfile); while (my $line = ) { - my @elements; - while ($line =~ /(\d+)\s?/g) { - push (@elements, $map_id_to_feat{$1}); - } - if (@elements) { - push (@clusters, [@elements]); - } + my @elements; + while ($line =~ /(\d+)\s?/g) { + push (@elements, $map_id_to_feat{$1}); + } + if (@elements) { + push (@clusters, [@elements]); + } } close CLUSTERS; @@ -77,4 +85,23 @@ sub build_clusters { } +############ +## Testing +########### + +sub __run_test { + + my @pairs = ( [1,2], [2,3], [4,5] ); + + my @clusters = &SingleLinkageClusterer::build_clusters(@pairs); + + use Data::Dumper; + + print "Input: " . Dumper(\@pairs); + print "Output: " . Dumper(\@clusters); + + exit(0); +} + + 1; diff --git a/scripts/create_mysql_cdnaassembly_db.dbi b/scripts/create_mysql_cdnaassembly_db.dbi index 2742ed3..e491e10 100755 --- a/scripts/create_mysql_cdnaassembly_db.dbi +++ b/scripts/create_mysql_cdnaassembly_db.dbi @@ -54,7 +54,10 @@ my $mysql_rw_password = &Pasa_conf::getParam("MYSQL_RW_PASSWORD"); ## Create the database if needed my $dbproc = &Mysql_connect::connect_to_db($mysql_server,"",$mysql_rw_user,$mysql_rw_password); -&Mysql_connect::RunMod($dbproc,"drop database $mysql_db") if $opt_r; +eval { + &Mysql_connect::RunMod($dbproc,"drop database $mysql_db") if $opt_r; +}; + my $query = "create database $mysql_db"; &Mysql_connect::RunMod($dbproc, $query); $dbproc->disconnect; From 92d87d028cfa68510c65128ae39fc06a1da9d610 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Wed, 10 Jun 2015 20:18:46 -0400 Subject: [PATCH 11/20] update --- PerlLib/GTF_utils.pm | 34 +++++++++++++++++++++------------- misc_utilities/gtf_file_to_proteins.pl | 13 ++++++++++++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/PerlLib/GTF_utils.pm b/PerlLib/GTF_utils.pm index 5c8e030..1ae3888 100644 --- a/PerlLib/GTF_utils.pm +++ b/PerlLib/GTF_utils.pm @@ -35,8 +35,12 @@ sub index_GTF_gene_objs_from_GTF { my $gene_id = $gene_obj->{TU_feat_name}; + if ($seen{$gene_id}) { - confess "Error, already processed gene: $gene_id\nearlier: " . $seen{$gene_id}->toString() . " but now as: " . $gene_obj->toString(); + confess "Error, already processed gene: $gene_id\n" + . " here: " . $gene_obj->toString() . "\n" + . " and earlier: " . $seen{$gene_id}->toString(); + } $seen{$gene_id} = $gene_obj; @@ -71,6 +75,7 @@ sub GTF_to_gene_objs { my %gene_id_to_name; my %gene_id_to_seq_name; + my %gene_id_to_gene_name; open (my $fh, $gtf_filename) or die "Error, cannot open $gtf_filename"; while (<$fh>) { @@ -94,24 +99,25 @@ sub GTF_to_gene_objs { $gene_id_to_source{$gene_id} = $source; - my $transcript_id; - if ($annot =~ /transcript_id \"([^\"]+)\"/) { - $transcript_id = $1; - } - else { - #print STDERR "\nWARNING: cannot get transcript_id from $annot of line\n$_\n"; - next; - } + $annot =~ /transcript_id \"([^\"]+)\"/ or confess "Error, cannot get transcript_id from $annot of line\n$_"; + my $transcript_id = $1; if ($annot =~ /name \"([^\"]+)\"/) { my $name = $1; $gene_id_to_name{$gene_id} = $name; } + + my $gene_name = ""; + if ($annot =~ /gene_name \"([^\"]+)\"/) { + $gene_name = $1; + $gene_id_to_gene_name{$gene_id} = $gene_name; + } + # print "gene_id: $gene_id, transcrpt_id: $transcript_id, $type\n"; if ($type eq 'transcript' || $type eq 'gene') { next; } # capture by exon coordinates - + if ($type eq 'CDS' || $type eq 'stop_codon' || $type eq 'start_codon') { push (@{$gene_transcript_data{$seqname}->{$gene_id}->{$transcript_id}->{CDS}}, [$end5, $end3] ); @@ -120,11 +126,11 @@ sub GTF_to_gene_objs { elsif ($type eq "exon" || $type =~ /UTR/) { push (@{$gene_transcript_data{$seqname}->{$gene_id}->{$transcript_id}->{mRNA}}, [$end5, $end3] ); } - elsif ($type =~ /rna/i) { + else { ## assuming noncoding feature push (@{$noncoding_features{$seqname}->{$type}->{$gene_id}->{$transcript_id}}, [$end5, $end3] ); } - + } close $fh; @@ -188,6 +194,9 @@ sub GTF_to_gene_objs { else { $gene_obj->{com_name} = $transcript_id; } + if (my $gene_name = $gene_id_to_gene_name{$gene_id}) { + $gene_obj->{gene_name} = $gene_name; + } $gene_obj->{asmbl_id} = $seqname; $gene_obj->{source} = $source; @@ -203,7 +212,6 @@ sub GTF_to_gene_objs { foreach my $other_gene_obj (@gene_objs) { $template_gene_obj->add_isoform($other_gene_obj); } - $template_gene_obj->refine_gene_object(); push (@top_gene_objs, $template_gene_obj); # print $template_gene_obj->toString(); diff --git a/misc_utilities/gtf_file_to_proteins.pl b/misc_utilities/gtf_file_to_proteins.pl index 07fcdeb..53cc51f 100755 --- a/misc_utilities/gtf_file_to_proteins.pl +++ b/misc_utilities/gtf_file_to_proteins.pl @@ -84,6 +84,8 @@ foreach my $isoform ($gene_obj_ref, $gene_obj_ref->get_additional_isoforms()) { my $isoform_id = $isoform->{Model_feat_name}; + my $gene_id = $isoform->{TU_feat_name}; + my $seq = ""; @@ -105,7 +107,16 @@ my $com_name = $isoform->{com_name} || ""; - print ">$isoform_id\n$seq\n"; + my $gene_name = $isoform->{gene_name}; + my $header = ">$isoform_id $gene_id"; + if ($gene_name) { + $header .= " $gene_name "; + } + if ($com_name) { + $gene_name .= " $com_name"; + } + + print "$header\n$seq\n"; } } } From 7fe6b783be9ea570df9259a20beaa90a14fc8bf3 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Fri, 12 Jun 2015 21:01:34 -0400 Subject: [PATCH 12/20] the Error, have 3prime partial protein when 3prime partials werent allowed! message was due to annotations or transcript structures being imported with coordinates that extend beyond the length of the scaffold --- PerlLib/Exons_to_geneobj.pm | 35 ++++++++++++++++++++++++++++------- pasa_conf/sample_test.conf | 8 ++++---- pasa_cpp/pasa | Bin 173364 -> 173364 bytes schema/notes | 3 +++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/PerlLib/Exons_to_geneobj.pm b/PerlLib/Exons_to_geneobj.pm index 2025b16..c026b9b 100755 --- a/PerlLib/Exons_to_geneobj.pm +++ b/PerlLib/Exons_to_geneobj.pm @@ -27,9 +27,13 @@ sub create_gene_obj { ## exons_ref should be end5's keyed to end3's for all exons. my ($gene_struct_mod, $cdna_seq) = &get_cdna_seq ($exons_href, $sequence_ref); + + my $cdna_seq_length = length $cdna_seq; my $long_orf_obj = new Longest_orf(); + #print STDERR "CDNA_SEQ: [$cdna_seq], length: $cdna_seq_length\n"; + # establish long orf finding parameters. $long_orf_obj->forward_strand_only(); if ($partial_info_href->{"5prime"}) { @@ -43,24 +47,28 @@ sub create_gene_obj { $long_orf_obj->get_longest_orf($cdna_seq); my ($end5, $end3) = $long_orf_obj->get_end5_end3(); - print "CDS: $end5, $end3\n" if $SEE; + #print STDERR "*** CDS: $end5, $end3\n";# if $SEE; my $gene_obj = &create_gene ($gene_struct_mod, $end5, $end3); + #print STDERR $gene_obj->toString(); + $gene_obj->create_all_sequence_types($sequence_ref); my $protein = $gene_obj->get_protein_sequence(); - + my $recons_cds = $gene_obj->get_CDS_sequence(); + #print STDERR "reconsCDS: $recons_cds\n"; + ## check partiality if ($protein) { # it is possible that we won't have any cds structure if ($protein !~ /^M/) { # this would require that we allowed for 5prime partials unless ($partial_info_href->{"5prime"}) { - confess "Error, have 5' partial protein when 5prime partials weren't allowed!\n$protein\n"; + confess "Error, have 5' partial protein when 5prime partials weren't allowed!\n$protein\n$cdna_seq\n"; } } if ($protein !~ /\*$/) { # this would require that we allowed for 3prime partials unless ($partial_info_href->{"3prime"}) { - confess "Error, have 3' partial protein when 3prime partials weren't allowed!\n$protein\n"; + confess "Error, have 3' partial protein when 3prime partials weren't allowed!\n$protein\n$cdna_seq\n"; } } @@ -80,6 +88,9 @@ sub create_gene_obj { #### sub get_cdna_seq { my ($gene_struct, $assembly_seq_ref) = @_; + + my $seq_length = length($$assembly_seq_ref); + my (@end5s) = sort {$a<=>$b} keys %$gene_struct; my $strand = "?"; foreach my $end5 (@end5s) { @@ -90,7 +101,7 @@ sub get_cdna_seq { } if ($strand eq "?") { print Dumper ($gene_struct); - die "ERROR: I can't determine what orientation the cDNA is in!\n"; + confess "ERROR: I can't determine what orientation the cDNA is in!\n"; } print NOTES "strand: $strand\n"; my $cdna_seq; @@ -99,6 +110,11 @@ sub get_cdna_seq { foreach my $end5 (@end5s) { #print $end5; my $end3 = $gene_struct->{$end5}; + + if ($end5 > $seq_length || $end3 > $seq_length) { + confess "Error, coords are out of bounds of sequence length: $seq_length:\n" . Dumper(\$gene_struct); + } + my ($coord1, $coord2) = sort {$a<=>$b} ($end5, $end3); my $exon_seq = substr ($$assembly_seq_ref, $coord1 - 1, ($coord2 - $coord1 + 1)); $cdna_seq .= $exon_seq; @@ -114,8 +130,12 @@ sub get_cdna_seq { #### sub create_gene { my ($gene_struct_mod, $cds_pointer_lend, $cds_pointer_rend) = @_; + + #use Data::Dumper; + #print STDERR Dumper($gene_struct_mod) . "CDS: $cds_pointer_lend, $cds_pointer_rend\n"; + my $strand = $gene_struct_mod->{strand}; - my @exons = @{$gene_struct_mod->{exons}}; + my @exons = sort {$a->[0]<=>$b->[0]} @{$gene_struct_mod->{exons}}; if ($strand eq '-') { @exons = reverse (@exons); } @@ -123,12 +143,13 @@ sub create_gene { my $mRNA_pointer_rend = 0; my $gene_obj = new Gene_obj(); foreach my $coordset_ref (@exons) { - my ($coord1, $coord2) = @$coordset_ref; + my ($coord1, $coord2) = sort {$a<=>$b} @$coordset_ref; my ($end5, $end3) = ($strand eq '+') ? ($coord1, $coord2) : ($coord2, $coord1); my $exon_obj = new mRNA_exon_obj($end5, $end3); my $exon_length = ($coord2 - $coord1 + 1); $mRNA_pointer_rend = $mRNA_pointer_lend + $exon_length - 1; ## see if cds is within current cDNA range. + #print STDERR "mRNA coords: $mRNA_pointer_lend-$mRNA_pointer_rend\n"; if ( $cds_pointer_rend >= $mRNA_pointer_lend && $cds_pointer_lend <= $mRNA_pointer_rend) { #overlap my $diff = $cds_pointer_lend - $mRNA_pointer_lend; my $delta_lend = ($diff >0) ? $diff : 0; diff --git a/pasa_conf/sample_test.conf b/pasa_conf/sample_test.conf index 3c2fe9c..62729d8 100755 --- a/pasa_conf/sample_test.conf +++ b/pasa_conf/sample_test.conf @@ -20,11 +20,11 @@ USE_PASA_DB_SETUP_HOOK=false ##################################### # server actively running MySQL -MYSQLSERVER=bhaas-lx +MYSQLSERVER=localhost # read-only username and password -MYSQL_RO_USER=access -MYSQL_RO_PASSWORD=access +MYSQL_RO_USER=pasa_access +MYSQL_RO_PASSWORD=pasa_access # read-write username and password MYSQL_RW_USER=access @@ -35,7 +35,7 @@ MYSQL_RW_PASSWORD=access # Web browser navigation settings: ######### ############################################ -BASE_PASA_URL=http://bhaas-lx:8080/cgi-bin/ +BASE_PASA_URL=http://localhost:8080/cgi-bin/where_you_installed_pasa_cgi_root ############################################# diff --git a/pasa_cpp/pasa b/pasa_cpp/pasa index 1012ac829e49a8948ef6b5550caef138e25fc294..4d6ae13ae14893d3d4257ed252843604c3d53493 100755 GIT binary patch delta 69826 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 diff --git a/schema/notes b/schema/notes index edda33a..8a630cf 100755 --- a/schema/notes +++ b/schema/notes @@ -16,7 +16,10 @@ Using the backticks instead of single quotes in the db name pattern is mandatory ------ create user 'pasa_access' identified by 'pasa_access'; +create user 'pasa_write' identified by '...'; + grant select on *.* to 'pasa_access@%'; grant all on *.* to 'pasa_write@%'; +grant select on *.* to 'pasa_access'@'localhost' identified by 'pasa_access'; grant all on *.* to 'pasa_write'@'localhost' identified by '...'; From 7d5dc8a647efaff376a6cf2703c56de79ada1a62 Mon Sep 17 00:00:00 2001 From: mimarsh2 Date: Mon, 10 Aug 2015 14:22:27 -0400 Subject: [PATCH 13/20] Allow mysql connection through socket The Perl DBI library allows for connections to the mysql server though a specific socket file by using the mysql_socket= host name. When calling the mysql binaries directly, this socket file needs to be passed using the -S argument rather than the -h for the hostname. --- scripts/create_mysql_cdnaassembly_db.dbi | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/create_mysql_cdnaassembly_db.dbi b/scripts/create_mysql_cdnaassembly_db.dbi index e491e10..018b3cc 100755 --- a/scripts/create_mysql_cdnaassembly_db.dbi +++ b/scripts/create_mysql_cdnaassembly_db.dbi @@ -73,7 +73,17 @@ if ($mysql_server=~s/:(\d+)$//){ # if $mysql_server includes :port then remove and add as port $mysql_options .= " --port=$1"; } -$mysql_options .= " -h$mysql_server"; + +# check if mysql server is configured with host or socket location i.e. +# the conf.txt contains MYSQLSERVER=mysql_socket= +if (index($mysql_server, "mysql_socket") != -1) { + #Drop the msyql_socket= from the string + #The regex drop everything before and including the '=' character + $mysql_server =~ s/^\s*\S+=//; + $mysql_options .= " -S$mysql_server"; +} else { + $mysql_options .= " -h$mysql_server"; +} ## Populate the database structure and static data. From 11dff714dd0b917ac9c0d62db9b3a8e3f49847fd Mon Sep 17 00:00:00 2001 From: mimarsh2 Date: Mon, 10 Aug 2015 14:25:25 -0400 Subject: [PATCH 14/20] Socket usage documentation Add documentation to the configuration template file about using the mysql_socket option --- pasa_conf/pasa.CONFIG.template | 1 + 1 file changed, 1 insertion(+) diff --git a/pasa_conf/pasa.CONFIG.template b/pasa_conf/pasa.CONFIG.template index 1c693f8..7b22f48 100755 --- a/pasa_conf/pasa.CONFIG.template +++ b/pasa_conf/pasa.CONFIG.template @@ -6,6 +6,7 @@ # server actively running MySQL MYSQLSERVER=localhost # or server.com +# Pass socket connections through Perl DBI syntax e.g. MYSQLSERVER=mysql_socket=/tmp/mysql.sock # read-write username and password MYSQL_RW_USER=xxxxxx From 69927def9c8fb5d91e4b5701c9354c3bb6e4316d Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Mon, 7 Dec 2015 07:24:17 -0500 Subject: [PATCH 15/20] update to recognize latest Trinity accession values --- scripts/build_comprehensive_transcriptome.dbi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/build_comprehensive_transcriptome.dbi b/scripts/build_comprehensive_transcriptome.dbi index aff0414..ff85a7a 100755 --- a/scripts/build_comprehensive_transcriptome.dbi +++ b/scripts/build_comprehensive_transcriptome.dbi @@ -355,6 +355,9 @@ sub get_TDN_component { # trinity de novo 2.0.0+ style $component = $1; } + elsif ($cdna_acc =~ /^(TRINITY\S+_c\d+_g\d+)/) { + $component = $1; + } else { confess "Error, cannot extract component info from trinity de novo assembly: $cdna_acc"; } From a30894d5be8f88ff83191c330fe9c2322008a3a8 Mon Sep 17 00:00:00 2001 From: Jason Travis Date: Wed, 20 Jan 2016 10:19:44 -0700 Subject: [PATCH 16/20] docs: fix Launch_PASA_pipeline.pl -x flag description --- scripts/Launch_PASA_pipeline.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Launch_PASA_pipeline.pl b/scripts/Launch_PASA_pipeline.pl index 500f172..7bdec0f 100755 --- a/scripts/Launch_PASA_pipeline.pl +++ b/scripts/Launch_PASA_pipeline.pl @@ -133,7 +133,7 @@ # # # // Jump-starting or prematurely terminating -# -x flag, print cmds only, don\'t process anything. (useful to get indices for -x or -e opts below) +# -x flag, print cmds only, don\'t process anything. (useful to get indices for -s or -e opts below) # -s pipeline index to start running at (avoid rerunning searches). # -e pipeline index where to stop running, and do not execute this entry. # From 440ec0e85fee0eafc1467115e23eda9b1b3b552d Mon Sep 17 00:00:00 2001 From: yuragal Date: Tue, 27 Dec 2016 23:23:41 +0800 Subject: [PATCH 17/20] Compatibility with GMAP versions 2016-05+ In gmap version 2016-05 new arguments [were introduced] (http://research-pub.gene.com/gmap/archive.html) >Added separate flags in GMAP for controlling intron length of end introns separately from middle introns. Flag names are now --max-intronlength-middle (previously --intronlength) and --max-intronlength-ends This patch is to evaluate gmap version and to prepare arguments of gmap call accordingly. --- scripts/process_GMAP_alignments_gff3_chimeras_ok.pl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/process_GMAP_alignments_gff3_chimeras_ok.pl b/scripts/process_GMAP_alignments_gff3_chimeras_ok.pl index c396a28..0c66c79 100755 --- a/scripts/process_GMAP_alignments_gff3_chimeras_ok.pl +++ b/scripts/process_GMAP_alignments_gff3_chimeras_ok.pl @@ -88,7 +88,14 @@ my $cmd = "gmap -D $genomeBaseDir -d $genomeDir $transcriptDB -f $format -n $num_gmap_top_hits -x 50 -t $CPU -B 5 "; if ($max_intron) { - $cmd .= " --intronlength=$max_intron "; + my $gmapv=`gmap --version 2>&1 | head -1`; + chomp($gmapv); + $gmapv=~/GMAP\s+version\s+(\d{4})-(\d{2})-.*/; + if( ($1 == 2016 && $2 >= 5) || $1 > 2016){ + $cmd .= " --max-intronlength-middle=$max_intron --max-intronlength-ends=$max_intron "; + }else{ + $cmd .= " --intronlength=$max_intron "; + } } &process_cmd($cmd); From 2bf11beb71c53a3e022af03446b94dce1e1ad276 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Wed, 15 Feb 2017 11:04:37 -0500 Subject: [PATCH 18/20] compatible w/ latest mysql --- misc_utilities/gff3_file_toString.pl | 3 ++- schema/cdna_alignment_mysqlschema | 4 ++-- schema/notes | 6 ++---- scripts/cDNA_annotation_comparer.dbi | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/misc_utilities/gff3_file_toString.pl b/misc_utilities/gff3_file_toString.pl index ea20ff3..f59e825 100755 --- a/misc_utilities/gff3_file_toString.pl +++ b/misc_utilities/gff3_file_toString.pl @@ -24,7 +24,8 @@ foreach my $gene_id (@gene_ids) { my $gene_obj_ref = $gene_obj_indexer_href->{$gene_id}; - + + print "// $asmbl_id, gene: $gene_id\n"; print $gene_obj_ref->toString(); } diff --git a/schema/cdna_alignment_mysqlschema b/schema/cdna_alignment_mysqlschema index 3076867..8d3077c 100644 --- a/schema/cdna_alignment_mysqlschema +++ b/schema/cdna_alignment_mysqlschema @@ -110,7 +110,7 @@ CREATE TABLE alt_splice_tokens ( CREATE TABLE annotation_admin ( version_id int(11) NOT NULL auto_increment, - date datetime NOT NULL default '0000-00-00 00:00:00', + date datetime NOT NULL, PRIMARY KEY (version_id) ) ; @@ -120,7 +120,7 @@ CREATE TABLE annotation_admin ( CREATE TABLE annotation_compare ( compare_id int(11) NOT NULL auto_increment, - date datetime NOT NULL default '0000-00-00 00:00:00', + date datetime NOT NULL, annotation_version int(10) unsigned NOT NULL default '0', PRIMARY KEY (compare_id) ) ; diff --git a/schema/notes b/schema/notes index 8a630cf..9930a80 100755 --- a/schema/notes +++ b/schema/notes @@ -18,8 +18,6 @@ Using the backticks instead of single quotes in the db name pattern is mandatory create user 'pasa_access' identified by 'pasa_access'; create user 'pasa_write' identified by '...'; -grant select on *.* to 'pasa_access@%'; -grant all on *.* to 'pasa_write@%'; +grant select on *.* to 'pasa_access'; +grant all on *.* to 'pasa_write'; -grant select on *.* to 'pasa_access'@'localhost' identified by 'pasa_access'; -grant all on *.* to 'pasa_write'@'localhost' identified by '...'; diff --git a/scripts/cDNA_annotation_comparer.dbi b/scripts/cDNA_annotation_comparer.dbi index 6c7fdf0..b9fab20 100755 --- a/scripts/cDNA_annotation_comparer.dbi +++ b/scripts/cDNA_annotation_comparer.dbi @@ -1444,7 +1444,7 @@ sub get_annotated_gene_models_on_contig { my @models; # get the annotated working models for that chromosome: - my $query = "select a.gene_id, min(a.lend), max(a.rend), a.orient from annotation_store a where a.annotdb_asmbl_id = ? and annotation_version = ? group by a.gene_id\n"; + my $query = "select a.gene_id, min(a.lend), max(a.rend), a.orient from annotation_store a where a.annotdb_asmbl_id = ? and annotation_version = ? group by a.gene_id, a.orient\n"; my @results = &Mysql_connect::do_sql_2D($dbproc, $query, $asmbl_id, $annot_version); foreach my $result (@results) { From 752ce7f87978bbd74a1cbcf9d1be215e659a6e72 Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Fri, 21 Apr 2017 12:35:28 -0400 Subject: [PATCH 19/20] activate debug option --- scripts/create_mysql_cdnaassembly_db.dbi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/create_mysql_cdnaassembly_db.dbi b/scripts/create_mysql_cdnaassembly_db.dbi index 018b3cc..2b3435b 100755 --- a/scripts/create_mysql_cdnaassembly_db.dbi +++ b/scripts/create_mysql_cdnaassembly_db.dbi @@ -14,7 +14,7 @@ use ConfigFileReader; use vars qw ($opt_c $opt_p $opt_d $opt_h $opt_S $opt_r); -&getopts ('c:p:S:r'); +&getopts ('c:p:S:rd'); $|=1; @@ -88,6 +88,7 @@ if (index($mysql_server, "mysql_socket") != -1) { ## Populate the database structure and static data. my $cmd = "$mysql_exec $mysql_options -D$mysql_db -e 'source $schemafile'"; +print STDERR "CMD: $cmd\n" if $DEBUG; my $result = system ($cmd); die "CMD: $cmd failed.\n" if $result; From 8d31504a880f2e6ee8c6b62865f01b9556e3ff9a Mon Sep 17 00:00:00 2001 From: Brian Haas Date: Tue, 11 Jul 2017 11:33:27 -0400 Subject: [PATCH 20/20] more useful error messaging and troubleshooting options --- PerlLib/Thread_helper.pm | 5 ++++- scripts/cDNA_annotation_comparer.dbi | 27 +++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/PerlLib/Thread_helper.pm b/PerlLib/Thread_helper.pm index 72e4636..bb43dcb 100644 --- a/PerlLib/Thread_helper.pm +++ b/PerlLib/Thread_helper.pm @@ -202,7 +202,10 @@ sub wait_for_all_threads_to_complete { $self->_add_error_thread($thread); $status = "ERROR"; } - $self->report_thread_info($thread_id, $status); + $self->{thread_id_timing}->{end}->{$thread_id} = time(); + if ($THREAD_MONITORING) { + $self->report_thread_info($thread_id, $status); + } } @{$self->{current_threads}} = (); # clear them out. diff --git a/scripts/cDNA_annotation_comparer.dbi b/scripts/cDNA_annotation_comparer.dbi index b9fab20..bfdaf24 100755 --- a/scripts/cDNA_annotation_comparer.dbi +++ b/scripts/cDNA_annotation_comparer.dbi @@ -34,6 +34,9 @@ use vars qw ($opt_h $opt_p $DEBUG $opt_M $opt_G $MIN_PERCENT_OVERLAP $MIN_PERCEN $STOMP_HIGH_PERCENTAGE_OVERLAPPING_GENE $MIN_PERCENT_ALIGN_LENGTH $MIN_PERCENT_LENGTH_FL_COMPARE $TRUST_FL_STATUS $CLUSTER_ID_ONLY); + +my $RESTRICT_SINGLE_CONTIG = undef; + my $CPU = 2; &GetOptions ('M=s' => \$opt_M, @@ -62,6 +65,8 @@ my $CPU = 2; ## hidden opts for debugging purposes 'CLUSTER_ID_ONLY=i' => \$CLUSTER_ID_ONLY, # the only cluster ID to process. + 'RESTRICT_SINGLE_CONTIG=s' => \$RESTRICT_SINGLE_CONTIG, + ); @@ -140,6 +145,12 @@ _EOH_ ; +### Hidden options +### +## --RESTRICT_SINGLE_CONTIG genomic contig to restrict analysis to +### + + if ($opt_h) {die $usage;} @@ -291,7 +302,9 @@ main: { print "### There are $num_contigs genomic contigs which will be examined.\n"; foreach my $result (@results) { my $asmbl_id = $result->[0]; - + + if ($RESTRICT_SINGLE_CONTIG && $asmbl_id ne $RESTRICT_SINGLE_CONTIG) { next; } + $thread_helper->wait_for_open_thread(); my $thread = threads->create('process_contig', $asmbl_id); @@ -308,7 +321,17 @@ main: { if (@failures) { ## examine them... these are the same threads created above, use use the threads api to access info about them ## such as error messages - die "Error, there were " . scalar(@failures) . " threads (contig jobs) that failed... See error messages above in order to troubleshoot further"; + + print STDERR "Error, there were " . scalar(@failures) . " threads (contig jobs) that failed... See error messages above in order to troubleshoot further"; + + foreach my $failed_thread (@failures) { + my $thread_id = $failed_thread->tid; + print STDERR "Failed thread ($thread_id) info:\n"; + $thread_helper->report_thread_info($thread_id, "FAILED"); + } + + exit(1); + } else { ## all good!