Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fix commit

  • Loading branch information...
commit 4c1c8e39016a6c9314024e4d59cd70803667da88 2 parents 6cf8f3f + 80dc1e7
@lstein lstein authored
Showing with 2,578 additions and 40,832 deletions.
  1. +4 −2 Build.PL
  2. +32 −0 Changes
  3. +7 −0 MANIFEST
  4. +4 −1 MANIFEST.SKIP
  5. +1 −0  TODO
  6. +38 −8 bin/gbrowse_clean.pl
  7. +142 −0 bin/gbrowse_grow_cloud_vol.pl
  8. +758 −0 bin/gbrowse_import_ucsc_db.pl
  9. +9 −0 bin/gbrowse_metadb_config.pl
  10. +12 −12 cgi-bin/gbrowse_details
  11. +3 −3 conf/GBrowse.conf
  12. +2 −2 conf/languages/is.pm
  13. +12 −65 conf/plugins/BatchDumper.pm
  14. +2 −2 conf/plugins/FastaDumper.pm
  15. +7 −67 conf/plugins/SequenceDumper.pm
  16. +12 −20 conf/plugins/TrackFinder.pm
  17. +1 −1  conf/synteny/oryza.synconf.disabled
  18. +99 −0 htdocs/cloud_index.html
  19. +7 −7 htdocs/gbrowse_syn_help.html
  20. +9 −9 htdocs/index.html
  21. +2 −2 htdocs/js/ajax_upload.js
  22. +1 −1  htdocs/js/login.js
  23. +5 −5 htdocs/js/track_configure.js
  24. +102 −0 htdocs/vbox_index.html
  25. +61 −38 install_util/GBrowseInstall.pm
  26. +0 −1  install_util/conf_install.pl
  27. +621 −0 lib/Bio/DB/SeqFeature/Store/Alias.pm
  28. +4 −2 lib/Bio/Graphics/Browser2.pm
  29. +23 −19 lib/Bio/Graphics/Browser2/Action.pm
  30. +4 −1 lib/Bio/Graphics/Browser2/DataBase.pm
  31. +18 −3 lib/Bio/Graphics/Browser2/DataLoader.pm
  32. +4 −8 lib/Bio/Graphics/Browser2/DataLoader/bam.pm
  33. +40 −6 lib/Bio/Graphics/Browser2/DataLoader/bed.pm
  34. +55 −155 lib/Bio/Graphics/Browser2/DataLoader/bigwig.pm
  35. +10 −1 lib/Bio/Graphics/Browser2/DataLoader/sam.pm
  36. +217 −0 lib/Bio/Graphics/Browser2/DataLoader/wig2bigwig.pm
  37. +15 −5 lib/Bio/Graphics/Browser2/DataSource.pm
  38. +2 −5 lib/Bio/Graphics/Browser2/RegionSearch.pm
  39. +44 −26 lib/Bio/Graphics/Browser2/Render.pm
  40. +1 −2  lib/Bio/Graphics/Browser2/Render/HTML.pm
  41. +2 −2 lib/Bio/Graphics/Browser2/Render/TrackConfig.pm
  42. +15 −8 lib/Bio/Graphics/Browser2/RenderPanels.pm
  43. +1 −1  lib/Bio/Graphics/Browser2/Session.pm
  44. +4 −4 lib/Bio/Graphics/Browser2/SubtrackTable.pm
  45. +9 −68 lib/Bio/Graphics/Browser2/TrackDumper.pm
  46. +114 −0 lib/Bio/Graphics/Browser2/TrackDumper/RichSeqMaker.pm
  47. +16 −10 lib/Bio/Graphics/Browser2/UserTracks.pm
  48. +5 −4 lib/Bio/Graphics/Browser2/UserTracks/Database.pm
  49. +10 −2 lib/Bio/Graphics/Karyotype.pm
  50. +1 −1  lib/Legacy/Graphics/Browser/Synteny.pm
  51. +6 −11 lib/Legacy/Graphics/Browser/Util.pm
  52. BIN  sample_data/gbrowse_syn/alignments/rice.aln.gz
  53. +2 −19,891 sample_data/gbrowse_syn/rice/rice.gff3
  54. +1 −20,351 sample_data/gbrowse_syn/wild_rice/wild_rice.gff3
  55. +2 −0  t/00.compile.t
View
6 Build.PL
@@ -18,7 +18,7 @@ my $build = GBrowseInstall->new(
requires => {
'perl' => '5.008',
'Bio::Root::Version' => '1.0069',
- 'Bio::Graphics' => '2.26',
+ 'Bio::Graphics' => '2.28',
'CGI::Session' => '4.02',
'Digest::MD5' => 0,
'ExtUtils::CBuilder' => 0,
@@ -38,7 +38,7 @@ my $build = GBrowseInstall->new(
build_requires => {'Capture::Tiny' => 0,},
recommends => {
'Bio::Das' => 0,
- 'Bio::DB::Sam' => 1.20,
+ 'Bio::DB::Sam' => 1.36,
'Bio::DB::BigFile' => 1.00,
'Crypt::SSLeay' => 0,
'DB_File::Lock' => 0,
@@ -61,9 +61,11 @@ my $build = GBrowseInstall->new(
script_files => [
'bin/gbrowse_clean.pl',
'bin/gbrowse_set_admin_passwd.pl',
+ 'bin/gbrowse_import_ucsc_db.pl',
'bin/gbrowse_create_account.pl',
'bin/gbrowse_change_passwd.pl',
'bin/gbrowse_metadb_config.pl',
+ 'bin/gbrowse_grow_cloud_vol.pl',
'bin/gbrowse_slave',
'bin/gbrowse_syn_load_alignment_database.pl',
'bin/gbrowse_syn_load_alignments_msa.pl',
View
32 Changes
@@ -1,3 +1,35 @@
+2.51
+ * Fix pod documentation for gbrowse_grow_cloud_vol.pl
+ * Volumes added to cloud instance have deleteOnTermination set to true.
+
+2.50
+ * Add gbrowse_import_ucsc_db.pl, which will create a fully functional starter database
+ from a UCSC data source (e.g. 'hg19').
+ * Add VirtualBox and EC2 virtual machine support (see http://gmod.org/wiki/GBrowse2_VMs).
+ * Prompt user before overwriting a customized config file.
+
+2.49
+ * Add new "metadata" option in track stanzas for making subtracks selectable via
+ structured metadata; see http://gmod.org/wiki/Creating_and_Managing_Subtracks_with_GBrowse2
+ for details.
+ * Specify which database to use for search result karyotype display using following
+ syntax:
+ [builtin:karyotype]
+ database = my_database
+ * Fixed error reporting when uploading badly-formatted WIG files.
+ * Do something sensible when user tries to upload a bigwig file.
+ * Some support for UCSC-style uploads with "track type=bigWig bigDataUrl=http://something...".
+
+2.48
+ * Fix track-level genbank and fasta dumping.
+ * Fix (mostly) the batch and sequence dumping plugins.
+
+2.47
+ * Fix bugs in demo mode.
+ * Fix session locking bug; FastCGI performance subjectively improved.
+ * Revert to using inline imagemaps when not running in an accelerated environment.
+ * Require Bio::Graphics version 2.26, so that transparency is supported.
+
2.46
* Support for transparent overlay tracks. These will appear as a user settable formatting option
for any track with subtracks. To make this default for a track set "bump = overlap" and consider
View
7 MANIFEST
@@ -5,6 +5,8 @@ bin/gbrowse_attach_slaves.pl
bin/gbrowse_change_passwd.pl
bin/gbrowse_clean.pl
bin/gbrowse_create_account.pl
+bin/gbrowse_grow_cloud_vol.pl
+bin/gbrowse_import_ucsc_db.pl
bin/gbrowse_metadb_config.pl
bin/gbrowse_netinstall.pl
bin/gbrowse_netinstall2.pl
@@ -185,6 +187,7 @@ docs/README.tutorial
etc/default/gbrowse-slave
etc/init.d/gbrowse-slave
htdocs/annotation_help.html
+htdocs/cloud_index.html
htdocs/css/dropdown/default_theme.css
htdocs/css/dropdown/dropdown.css
htdocs/css/dropdown/helper.css
@@ -535,6 +538,7 @@ htdocs/tutorial/figures/wiggle_density.png
htdocs/tutorial/tutorial.css
htdocs/tutorial/tutorial.html
htdocs/tutorial/tutorial.phyTreeEdit.html
+htdocs/vbox_index.html
INSTALL
install_util/cgi_install.pl
install_util/conf_install.pl
@@ -551,6 +555,7 @@ lib/Bio/DB/GFF/Aggregator/match_gap.pm
lib/Bio/DB/GFF/Aggregator/reftranscript.pm
lib/Bio/DB/GFF/Aggregator/waba_alignment.pm
lib/Bio/DB/GFF/Aggregator/wormbase_gene.pm
+lib/Bio/DB/SeqFeature/Store/Alias.pm
lib/Bio/DB/SeqFeature/Store/BedLoader.pm
lib/Bio/DB/Tagger.pm
lib/Bio/DB/Tagger/mysql.pm
@@ -571,6 +576,7 @@ lib/Bio/Graphics/Browser2/DataLoader/generic.pm
lib/Bio/Graphics/Browser2/DataLoader/gff.pm
lib/Bio/Graphics/Browser2/DataLoader/gff3.pm
lib/Bio/Graphics/Browser2/DataLoader/sam.pm
+lib/Bio/Graphics/Browser2/DataLoader/wig2bigwig.pm
lib/Bio/Graphics/Browser2/DataLoader/wiggle.pm
lib/Bio/Graphics/Browser2/DataSource.pm
lib/Bio/Graphics/Browser2/ExternalData.pm
@@ -601,6 +607,7 @@ lib/Bio/Graphics/Browser2/Session.pm
lib/Bio/Graphics/Browser2/Shellwords.pm
lib/Bio/Graphics/Browser2/SubtrackTable.pm
lib/Bio/Graphics/Browser2/TrackDumper.pm
+lib/Bio/Graphics/Browser2/TrackDumper/RichSeqMaker.pm
lib/Bio/Graphics/Browser2/UserDB.pm
lib/Bio/Graphics/Browser2/UserTracks.pm
lib/Bio/Graphics/Browser2/UserTracks/Database.pm
View
5 MANIFEST.SKIP
@@ -80,4 +80,7 @@ slave\.pid
^gbrowse_users.*
.*\.new
^META\.
-^nytprof
+^nytprof
+\.out$
+^htdocs/i$
+
View
1  TODO
@@ -1,3 +1,4 @@
+* Specify intervals using unc-13..unc-30 (whatever..whatever)
* Document the REST API; in particular the action=list and action=scan commands.
* Reload globals when GBrowse.conf changes under FastCGI.
* Bring internationalization support up to date.
View
46 bin/gbrowse_clean.pl
@@ -6,7 +6,7 @@
use Pod::Usage;
use File::Find ();
-use File::Basename 'basename';
+use File::Basename 'basename','dirname';
use Bio::Graphics::Browser2;
use Bio::Graphics::Browser2::Util 'shellwords';
use POSIX 'ENOTEMPTY';
@@ -41,6 +41,7 @@
my $locks_dir = $globals->session_locks;
my $images_dir = $globals->tmpimage_dir;
my $user_dir = $globals->user_dir();
+my $uploads_db = $globals->user_account_db;
my $cache_secs = $globals->time2sec($globals->cache_time);
my $uploads_secs = $globals->time2sec($globals->upload_time);
@@ -53,7 +54,7 @@
my $remember_settings_time = $globals->remember_settings_time;
-logit("Expiring sessions older than $remember_settings_time...");
+logit("Expiring sessions older than $remember_settings_time...\n");
my $dsn = $globals->code_setting(general=>'session driver');
my %dsn = shellwords($globals->code_setting(general=>'session args'));
my $rst = $globals->time2sec($remember_settings_time);
@@ -82,6 +83,10 @@
$rdev,$size,$atime,$mtime,$ctime) = stat($_);
next if $name =~ m!$tmpdir/[^/]+$!; # don't remove toplevel!
+ next if $name eq $tmpdir;
+ next if $name eq $user_dir;
+
+ my $is_userdata = $name =~ m/^$user_dir/;
if (-d _ ) { # attempt to remove directories - will have no effect unless empty
if (rmdir($name)) {
@@ -94,10 +99,10 @@
}
my $secs = $name =~ m/^($cache_dir|$locks_dir|$images_dir)/ ? $cache_secs
- :$name =~ m/^$user_dir/ ? $uploads_secs
+ :$is_userdata ? $uploads_secs
:0;
return unless $secs;
- my $time = $name =~ m/^$user_dir/ ? -A _ : -M _;
+ my $time = $is_userdata ? -A _ : -M _;
my $days = $secs/SECS_PER_DAY;
@@ -112,14 +117,39 @@
# Traverse desired filesystems
-logit("Deleting cache files and directories...");
-File::Find::finddepth( {wanted=>$wanted},
- $tmpdir);
-logit("$directories directories and $files files deleted.\n");
+logit("Deleting cache files and directories older than ".$globals->cache_time." (see GBrowse.conf \"expire cache\" option)...\n");
+File::Find::finddepth( {wanted=>$wanted}, $tmpdir);
+logit("Deleting unaccessed user uploads older than ".$globals->upload_time." (see GBrowse.conf \"expire uploads\" option)...\n");
+File::Find::finddepth( {wanted=>$wanted}, $user_dir);
+logit("Deleted $directories directories and $files files.\n");
+if ($uploads_db) {
+ logit("Cleaning uploads db...\n");
+ clean_uploads();
+}
logit("*** ",scalar localtime,"$0 done ***\n\n");
exit 0;
+sub clean_uploads {
+ eval {require DBI; 1} or return;
+
+ my $db = DBI->connect($globals->user_account_db) or return;
+ my $query = $db->prepare('select uploadsid,data_source,path,trackid from uploads,session where uploads.userid=session.userid') or return;
+ $query->execute or return;
+
+ my %flag_for_deletion;
+ while (my ($uploadsid,$dsn,$path,$trackid) = $query->fetchrow_array) {
+ my $full_path = "$user_dir/$dsn/$uploadsid/$path";
+ next if -e $full_path;
+ $flag_for_deletion{$trackid}++;
+ }
+
+ my @delete = keys %flag_for_deletion or return;
+ my $to_remove = join ',',map {"'$_'"}@delete;
+ $db->do("delete from uploads where trackid in ($to_remove)") or warn $db->errstr;
+ logit("Deleted ".scalar @delete." dangling uploads.\n");
+}
+
sub verbose {
my @mess = @_;
return unless $verbose;
View
142 bin/gbrowse_grow_cloud_vol.pl
@@ -0,0 +1,142 @@
+#!/usr/bin/perl
+
+=head1 NAME
+
+gbrowse_grow_cloud-vol.pl Grow the GBrowse volume by the requested amount
+
+=head1 SYNOPSYS
+
+Grow /opt/gbrowse by another 100 gigabytes
+
+ % gbrowse_grow_cloud_vol.pl 100
+
+=head1 DESCRIPTION
+
+This script grows /opt/gbrowse by the requested number of
+gigabytes. The single argument must be a number between 1 and 1000,
+which indicates the number of GB to grow the volume by (not the new
+size of the volume).
+
+It works by creating a new EBS volume and adding it to the logical
+volume manager (LVM2) for this machine. The filesystem is then
+extended to the desired size.
+
+=head1 COMMAND-LINE OPTIONS
+
+Options can be abbreviated. For example, you can use -a for
+--access_key:
+
+ --access_key EC2 access key
+ --secret_key EC2 secret key
+
+=head1 ENVIRONMENT VARIABLES
+
+The following environment variables are used if the corresponding
+options are not present:
+
+ EC2_ACCESS_KEY your access key
+ EC2_SECRET_KEY your secret key
+
+=head1 SEE ALSO
+
+L<VM::EC2>, L<VM::EC2::Staging::Manager>
+
+=head1 AUTHOR
+
+Lincoln Stein, lincoln.stein@gmail.com
+
+Copyright (c) 2012 Ontario Institute for Cancer Research
+
+This package and its accompanying libraries is free software; you can
+redistribute it and/or modify it under the terms of the GPL (either
+version 1, or at your option, any later version) or the Artistic
+License 2.0. Refer to LICENSE for the full license text. In addition,
+please see DISCLAIMER.txt for disclaimers of warranty.
+
+=cut
+
+use strict;
+use lib '../lib';
+
+use VM::EC2;
+use File::Basename 'basename';
+use Getopt::Long;
+
+my($Access_key,$Secret_key,$Endpoint);
+my $Program_name = basename($0);
+
+GetOptions(
+ 'access_key=s' => \$Access_key,
+ 'secret_key=s' => \$Secret_key,
+ ) or exec 'perldoc',$0;
+
+my $extra_size = shift or die "Please provide size to grow /opt/gbrowse by. Use --help for details.";
+
+#setup defaults
+$ENV{EC2_ACCESS_KEY} = $Access_key if defined $Access_key;
+$ENV{EC2_SECRET_KEY} = $Secret_key if defined $Secret_key;
+
+my $meta = VM::EC2->instance_metadata;
+my $zone = $meta->availabilityZone;
+(my $region = $zone) =~ s/[a-z]$//; # hack
+my $instance = $meta->instanceId;
+my ($ebs_device,$local_device) = unused_block_device() or die "Couldn't find a suitable device to attach to";
+
+my $ec2 = VM::EC2->new(-region=>$region) or die VM::EC2->error_str;
+
+print STDERR "Creating $extra_size EBS volume.\n";
+my $vol = $ec2->create_volume(-availability_zone => $zone,
+ -size => $extra_size) or die "Couldn't create EBS volume: ",$ec2->error_str;
+$vol->add_tag(Name=>"GBrowse lvm disk $local_device");
+
+print STDERR "Attaching volume.\n";
+my $a = $vol->attach($instance=>$ebs_device) or die "Couldn't attach EBS volume to $ebs_device: ",$ec2->error_str;
+$ec2->wait_for_attachments($a);
+$a->deleteOnTermination(1);
+-e $local_device or die "EBS volume did not appear at $local_device as expected";
+
+print STDERR "Creating lvm physical device.\n";
+system("sudo pvcreate $local_device") == 0 or die "pvcreate failed";
+
+print STDERR "Extending 'volumes' volume group.\n";
+system("sudo vgextend volumes $local_device") == 0 or die "vgextend failed";
+
+my $result = `sudo vgdisplay -c volumes` or die "vgdisplay filed";
+my @result = split /:/,$result;
+my $free = $result[15] or die "volume group has no free extents";
+
+print STDERR "Extending 'gbrowse' logical volume.\n";
+system("sudo lvextend -l +$free /dev/volumes/gbrowse") == 0 or die "lvextend failed";
+
+print STDERR "Extending /opt/gbrowse filesystem.\n";
+system("sudo resize2fs /dev/volumes/gbrowse") == 0 or die "resize2fs failed";
+
+print STDERR "Volume resized successfully\n";
+
+exit 0;
+
+sub unused_block_device {
+ my $major_start = shift || 'g';
+
+ my @devices = `ls -1 /dev/sd?* /dev/xvd?* 2>/dev/null`;
+ chomp(@devices);
+ return unless @devices;
+ my %used = map {$_ => 1} @devices;
+
+ my $base = $used{'/dev/sda1'} ? "/dev/sd"
+ : $used{'/dev/xvda1'} ? "/dev/xvd"
+ : '';
+ die "Device list contains neither /dev/sda1 nor /dev/xvda1; don't know how blocks are named on this system"
+ unless $base;
+
+ my $ebs = '/dev/sd';
+ for my $major ($major_start..'p') {
+ for my $minor (1..15) {
+ my $local_device = "${base}${major}${minor}";
+ next if $used{$local_device}++;
+ my $ebs_device = "/dev/sd${major}${minor}";
+ return ($ebs_device,$local_device);
+ }
+ }
+ return;
+}
View
758 bin/gbrowse_import_ucsc_db.pl
@@ -0,0 +1,758 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Carp 'croak';
+use GBrowse::ConfigData;
+use DBI;
+use Bio::DB::Fasta;
+use LWP::Simple 'mirror','is_error','is_success';
+use File::Basename 'dirname';
+use Getopt::Long;
+
+use constant HOST=>'genome-mysql.cse.ucsc.edu';
+use constant USER=>'genome';
+
+my $host = HOST;
+my $dbh = DBI->connect(
+ "DBI:mysql::host=$host;mysql_use_result=1",
+ USER,'',
+ {PrintError=>0,RaiseError=>0}
+ );
+
+my $USAGE = <<END;
+Usage: $0 [options] <UCSC genome build> [<Description>]
+
+Example: $0 hg19 'Human genome (hg19)'
+
+This creates a framework data source for one of the genomes known to
+the UCSC Genome Browser. You can then modify the data source
+configuration file, add your own data, and so forth. Provide the name
+of a UCSC genome build and optionally a description to display in
+GBrowse.
+
+To get started, find the desired data source by going to
+http://genome.ucsc.edu/cgi-bin/hgGateway and using the "clade" and
+"genome" menus to navigate to the desired species and build
+number. You will find the data source name in the blue box below the
+navigation controls. Look for something like this:
+
+ D. melanogaster Genome Browser – dm3 assembly (sequences)
+
+The data source name appears before the word "assembly", in this case
+"dm3".
+
+To get a list of all sources recognized by UCSC appears type:
+
+ $0 --list
+
+Options:
+ --remove-chr Remove the 'chr' prefix from all chromosome names
+ --list List data sources
+END
+ ;
+
+my ($REMOVE_CHR,$LIST);
+
+GetOptions(
+ 'remove-chr' => \$REMOVE_CHR,
+ 'list' => \$LIST,
+ ) or die $USAGE;
+
+if ($LIST) {
+ print_sources($dbh);
+ exit -1;
+}
+
+my $dsn = shift;
+my $description = shift || "Imported $dsn genome from UCSC";
+
+unless ($dsn)
+{
+ print STDERR "usage: $0 <UCSC data source name>\n";
+ print STDERR "Run $0 --help for details.\n";
+ print STDERR "Run $0 --list for list of data sources.\n";
+ exit -1;
+} else {
+ $dbh->do("use $dsn") or die "Could not access $dsn database. Run this script with --list to see valid database names.\n";
+}
+
+my $conf_dir = GBrowse::ConfigData->config('conf');
+my $data_dir = GBrowse::ConfigData->config('databases');
+
+print STDERR "** During database creation, you may be asked for your password in order to set file permissions correctly.\n\n";
+
+my $dir = create_database_dir($data_dir,$dsn);
+my $scaffolds = create_scaffold_db($dir,$dsn);
+my $genes = create_gene_db($dir,$dsn);
+create_conf_file($conf_dir,$dsn,$description,$scaffolds,$genes);
+create_source($conf_dir,$dsn,$description);
+
+print STDERR <<END;
+
+** These files have been created for you:
+
+ $scaffolds -- database of chromosome sizes and sequences
+ $genes -- database of genes
+ $conf_dir/${dsn}.conf -- track configuration file for these databases
+ $conf_dir/GBrowse.conf -- updated data source configuration file
+END
+ ;
+
+if (-x '/usr/sbin/service') {
+ print STDERR "\n ** Restarting apache. You may be asked for your password.\n";
+ system "sudo service apache2 restart";
+} elsif (-x '/etc/init.d/apache2') {
+ print STDERR "\n ** Restarting apache. You may be asked for your password.\n";
+ system "sudo /etc/init.d/apache2 restart";
+} else {
+ print STDERR "\n** Please restart apache or other web server.\n";
+}
+
+1;
+
+exit 0;
+
+sub print_sources {
+ my $dbh = shift;
+ my $s = $dbh->selectcol_arrayref('show databases');
+ print STDERR join("\n",grep {!/information_schema/} @$s),"\n";
+}
+
+sub create_database_dir {
+ my ($data_dir,$dsn) = @_;
+ my $uid = $<;
+ my ($gid) = $( =~ /^(\d+)/;
+ my $dir = "$data_dir/$dsn";
+ unless (-d $dir) {
+ print STDERR "Creating database directory for $dsn. You may be prompted for your password.\n";
+ system "sudo mkdir -p $dir";
+ }
+ unless (-w $dir) {
+ system "sudo chown $uid $dir";
+ system "sudo chgrp $gid $dir";
+ }
+ return $dir;
+}
+
+sub create_scaffold_db {
+ my ($dir,$dsn) = @_;
+ my $path = "$dir/chromosomes";
+ mkdir $path unless -e $path;
+ open my $db,">$path/chrom_sizes.gff3" or die "$path: $!";
+ print $db <<END;
+##gff-version 3
+
+END
+
+ print STDERR "Fetching chromosome sizes...\n";
+
+ my $query = $dbh->prepare('select chrom,size from chromInfo order by size')
+ or die $dbh->errstr;
+ $query->execute;
+ my @chroms;
+ while (my($chrom,$size) = $query->fetchrow_array) {
+ $chrom =~ s/^chr// if $REMOVE_CHR;
+ print $db join("\t",
+ $chrom,
+ $dsn,
+ 'chromosome',
+ 1,
+ $size,
+ '.','.','.',
+ "ID=$chrom;Name=$chrom"),"\n";
+ push @chroms,$chrom;
+ }
+
+ $query->finish;
+ close $db;
+
+ print STDERR "Fetching FASTA files...";
+ $ENV{FTP_PASSIVE}=1 unless exists $ENV{FTP_PASSIVE};
+ my $prefix = $REMOVE_CHR ? 'chr' : '';
+ for my $chr (sort @chroms) {
+ my $url = "ftp://hgdownload.cse.ucsc.edu/goldenPath/$dsn/chromosomes/$prefix$chr.fa.gz";
+ my $file = "$path/$prefix$chr.fa.gz";
+ print STDERR "$chr...";
+ my $code = mirror($url=>$file);
+ warn "Fetch of $url returned error code $code\n"
+ if is_error($code);
+ }
+ print STDERR "done\n";
+ print STDERR "Unpacking FASTA files...";
+ unlink "$path/chromosomes.fa";
+ for my $chr (sort @chroms) {
+ my $command = $REMOVE_CHR ? "gunzip -c $path/$prefix$chr.fa.gz | perl -p -e 's/^>chr/>/' >> $path/chromosomes.fa"
+ : "gunzip -c $path/$prefix$chr.fa.gz >> $path/chromosomes.fa"
+ unless -e "$path/$chr.fa" && -M "$path/chromosomes.fa" > -M "$path/$prefix$chr.fa.gz";
+ system $command;
+ }
+ print STDERR "done\n";
+
+ print STDERR "Creating FASTA index...";
+ my $index = Bio::DB::Fasta->new($path) or die "Couldn't create index";
+ print "done\n";
+
+ my $wwwuser = GBrowse::ConfigData->config('wwwuser');
+ system "sudo chown -R $wwwuser $path";
+ return $path;
+}
+
+sub create_gene_db {
+ my ($dir,$dsn) = @_;
+ my $path = "$dir/refGenes";
+ mkdir $path unless -e $path;
+
+ my $src_path = "$path/genes.gff3";
+ my $db_path = "$path/genes.sqlite";
+
+ open my $db,'>',$src_path or die "$path: $!";
+ print $db <<END;
+##gff-version 3
+
+END
+ print STDERR "Fetching genes...";
+ my $query;
+ eval {
+ $query = $dbh->prepare('select * from refFlat order by geneName') or die $dbh->errstr;
+ $query->execute or die $dbh->errorstr;
+ } || eval {
+ $query = $dbh->prepare('select name2,name,chrom,strand,txStart,txEnd,cdsStart,cdsEnd,exonCount,exonStarts,exonEnds from ensGene order by name2') or die $dbh->errstr;
+ $query->execute or die $dbh->errorstr;
+ };
+ die $@ if $@;
+ my $writer = GFFWriter->new($db,$dsn);
+ while (my $row = $query->fetchrow_arrayref) {
+ $writer->write_transcript($row);
+ }
+ $query->finish;
+ $writer->finish;
+ print STDERR "done\n";
+
+ close $db;
+
+ print STDERR "Indexing...";
+ system "bp_seqfeature_load.pl -f -c -a DBI::SQLite -d $db_path $src_path";
+ print STDERR "done\n";
+
+ return $db_path;
+}
+
+sub log10 { log(shift())/log(10)}
+
+sub create_conf_file {
+ my ($conf_dir,$dsn,$description,$scaffolds,$genes) = @_;
+ my $conf_path = "$conf_dir/${dsn}.conf";
+ create_writable_file($conf_path);
+
+ # figure size of chromosomes
+ open my $fh1,"$scaffolds/chrom_sizes.gff3" or die "$scaffolds/chrom_sizes.gff3: $!";
+ my $max_chrom = 0;
+ my ($first_chrom,$first_size);
+ while (<$fh1>) {
+ my ($chr,undef,undef,undef,$size) = split /\s+/;
+ next unless $size;
+ $max_chrom = $size if $max_chrom < $size;
+ $first_chrom ||= $chr;
+ $first_size ||= $size;
+ }
+ close $fh1;
+
+ # from the max chromosome, figure out reasonable default sizes and zoom levels
+ my $log = int log10($max_chrom);
+ my $max_segment = $max_chrom;
+ my $default_segment = 10**($log-3);
+ my $region_segment = $default_segment*10;
+ my @zoom_levels = qw(100 200 1000 2000 5000 10000 20000 50000 100000 200000 500000);
+ for (my $i=6; $i<=$log; $i++) {
+ push @zoom_levels,10**$i;
+ }
+ my @region_sizes = @zoom_levels;
+ my $default_region = $default_segment * 10;
+ my $summary_boundary= $default_segment * 100;
+
+ my $start = int(rand($first_size));
+ my $end = $start + $default_segment -1;
+ my $initial_landmark = "$first_chrom:$start..$end";
+
+ # pick some random examples from the gff3 file
+ my @names;
+ my $dir = dirname($genes);
+ open my $fh2,"$dir/genes.gff3" or die "$dir/genes.gff3: $!";
+ while (<$fh2>) {
+ my ($name) = /Name=([^;]+)/ or next;
+ for (0..3) {
+ $names[$_] = $name if rand($.) < 4;
+ }
+ }
+ close $fh2;
+ my $examples = "@names";
+
+ open my $fh3,'>',$conf_path or die "$conf_path: $!";
+ print $fh3 <<END;
+[GENERAL]
+description = $description
+database = scaffolds
+
+initial landmark = $initial_landmark
+plugins = FilterTest RestrictionAnnotator TrackDumper FastaDumper
+autocomplete = 1
+
+default tracks = Genes ncRNA
+
+# examples to show in the introduction
+examples = $examples
+
+# "automatic" classes to try when an unqualified identifier is given
+automatic classes = Gene
+
+# Limits on genomic regions (can be overridden in datasource config files)
+region segment = $region_segment
+max segment = $max_segment
+default segment = $default_segment
+default region = $default_region
+zoom levels = @zoom_levels
+region sizes = @region_sizes
+
+#################################
+# database definitions
+#################################
+
+[scaffolds:database]
+db_adaptor = Bio::DB::SeqFeature::Store
+db_args = -adaptor memory
+ -dir $scaffolds
+search options = default +autocomplete
+
+[genes:database]
+db_adaptor = Bio::DB::SeqFeature::Store
+db_args = -adaptor DBI::SQLite
+ -dsn $genes
+search options = default +autocomplete
+
+# Default glyph settings
+[TRACK DEFAULTS]
+glyph = generic
+database = scaffolds
+height = 8
+bgcolor = green
+fgcolor = black
+label density = 25
+bump density = 100
+show summary = $summary_boundary
+
+### TRACK CONFIGURATION ####
+# the remainder of the sections configure individual tracks
+
+[Genes]
+database = genes
+feature = gene
+glyph = gene
+bgcolor = sub {shift->strand > 0 ? 'red' : 'blue'}
+label_transcripts = 1
+label = sub { my \$f = shift;
+ my \$name = \$f->display_name;
+ my \@aliases = sort \$f->attributes('Alias');
+ \$name .= " (\@aliases)" if \@aliases;
+ \$name;
+ }
+height = 10
+description = 0
+key = Known Genes
+
+[Genes:200000]
+glyph = box
+stranded = 1
+
+[Genes:500000]
+bump = 0
+
+[ncRNA]
+database = genes
+feature = noncoding_transcript
+fgcolor = orange
+glyph = generic
+description = 1
+key = Noncoding RNAs
+
+[CDS]
+database = genes
+feature = mRNA
+glyph = cds
+description = 0
+height = 26
+sixframe = 1
+label = sub {shift->name . " reading frame"}
+key = CDS
+citation = This track shows CDS reading frames.
+
+[CDS:200000]
+glyph = box
+stranded = 1
+
+[Translation]
+glyph = translation
+global feature = 1
+database = scaffolds
+height = 40
+fgcolor = purple
+strand = +1
+translation = 6frame
+key = 6-frame translation
+
+[Translation:1000000]
+hide = 1
+
+[TranslationF]
+glyph = translation
+global feature = 1
+database = scaffolds
+height = 20
+fgcolor = purple
+strand = +1
+translation = 3frame
+key = 3-frame translation (forward)
+
+[TranslationF:1000000]
+hide = 1
+
+[DNA/GC Content]
+glyph = dna
+global feature = 1
+database = scaffolds
+height = 40
+do_gc = 1
+gc_window = auto
+strand = both
+fgcolor = red
+axis_color = blue
+
+[DNA/GC Content:1000000]
+hide = 1
+
+[TranslationR]
+glyph = translation
+global feature = 1
+database = scaffolds
+height = 20
+fgcolor = blue
+strand = -1
+translation = 3frame
+key = 3-frame translation (reverse)
+
+[TranslationR:1000000]
+hide = 1
+
+END
+ close $fh3;
+}
+
+sub create_source {
+ my ($conf_dir,$dsn,$description) = @_;
+ my $path = "$conf_dir/GBrowse.conf";
+ open my $fh,$path or die "$path: $!";
+ my $foundit;
+ while (<$fh>) {
+ $foundit++ if /\[$dsn\]/;
+ }
+ close $fh;
+ return if $foundit;
+
+ create_writable_file($path);
+ open my $fh2,'>>',$path or die "$path: $!";
+ print $fh2 "\n";
+ print $fh2 <<END;
+[$dsn]
+description = $description
+path = $conf_dir/${dsn}.conf
+END
+ ;
+ close $fh2;
+}
+
+sub create_writable_file {
+ my $file = shift;
+ return if -e $file && -w $file;
+
+ my $uid = $<;
+ my ($gid) = $( =~ /^(\d+)/;
+ system "sudo touch $file";
+ system "sudo chown $uid $file";
+ system "sudo chgrp $gid $file";
+ system "chmod +w $file";
+}
+
+package GFFWriter;
+
+sub new {
+ my $class = shift;
+ my ($fh,$dsn) = @_;
+ return bless {
+ fh => $fh,
+ dsn => $dsn,
+ gene_id => 'g000000',
+ transcript_id => 't00000',
+ last_gene_name => '',
+ last_gene_id => '',
+ last_gene => {},
+ },ref $class || $class;
+}
+
+# This subroutine is amazingly long and complicated looking, but probably correct
+sub write_transcript {
+ my $self = shift;
+ my $fields = shift;
+
+ my ($gene_name,$accession,$chrom,$strand,$txStart,$txEnd,$cdsStart,$cdsEnd,$exons,$exonStarts,$exonEnds) = @$fields;
+ my ($utr5_start,$utr5_end,$utr3_start,$utr3_end,$gid,$tid);
+ $gene_name ||= $accession;
+ $chrom =~ s/^chr// if $REMOVE_CHR;
+
+ if ($self->{last_gene_name} ne $gene_name
+ ||
+ $self->{last_gene}{chr} ne $chrom # avoid some gene name collisions
+ ||
+ abs($self->{last_gene}{start} - $txStart) > 6_000_000 # avoid some gene name collisions
+ ||
+ $self->{last_gene}{strand} ne $strand)
+ {
+ $self->write_last_gene;
+ $self->{last_gene} = {};
+ $self->{last_gene_name} = '';
+ $gid = $self->{last_gene_id} = $self->{gene_id}++;
+ } elsif ($self->{last_gene_id}) {
+ $gid = $self->{last_gene_id};
+ } else {
+ $gid = $self->{last_gene_id} = $self->{gene_id}++;
+ }
+
+ $tid = $self->{transcript_id}++;
+
+ my $ORIGIN = 1;
+ my $SRC = $self->{dsn};
+ my $fh = $self->{fh};
+
+ # adjust for Jim's 0-based coordinates
+ $txStart++;
+ $cdsStart++;
+
+ $txStart -= $ORIGIN;
+ $txEnd -= $ORIGIN;
+ $cdsStart -= $ORIGIN;
+ $cdsEnd -= $ORIGIN;
+
+ # this is how noncoding genes are expressed (?!!!)
+ my $is_noncoding = $cdsStart >= $cdsEnd;
+
+ unless ($is_noncoding) {
+ $self->{last_gene_name} ||= $gene_name;
+ $self->{last_gene}{chr} ||= $chrom;
+ $self->{last_gene}{strand} ||= $strand;
+ $self->{last_gene}{start} = $txStart if !$self->{last_gene}{start} || $self->{last_gene}{start} > $txStart;
+ $self->{last_gene}{end} = $txEnd if !$self->{last_gene}{end} || $self->{last_gene}{end} < $txEnd;
+ }
+
+ # print the transcript
+ my $id = $is_noncoding ? "ID=$tid;Name=$gene_name;Alias=$accession" : "ID=$tid;Name=$accession;Parent=$gid";
+ print $fh join
+ ("\t",$chrom,$SRC,($is_noncoding ? 'noncoding_transcript' : 'mRNA'),$txStart,$txEnd,'.',$strand,'.',$id),"\n";
+
+ # now handle the CDS entries -- the tricky part is the need to keep
+ # track of phase
+ my $phase = 0;
+ my @exon_starts = map {$_-$ORIGIN} split ',',$exonStarts;
+ my @exon_ends = map {$_-$ORIGIN} split ',',$exonEnds;
+
+ if ($is_noncoding) {
+ for (my $i=0;$i<@exon_starts;$i++) { # for each exon start
+ print $fh join("\t",
+ $chrom,$SRC,'exon',$exon_starts[$i],$exon_ends[$i],'.',$strand,'.',"Parent=$tid"
+ ),"\n";
+ }
+ }
+
+ elsif ($strand eq '+') {
+ for (my $i=0;$i<@exon_starts;$i++) { # for each exon start
+ my $exon_start = $exon_starts[$i] + 1;
+ my $exon_end = $exon_ends[$i];
+ my (@utr_start,@utr_end,$cds_start,$cds_end);
+
+ if ($exon_start < $cdsStart) { # in a 5' UTR
+ push (@utr_start, $exon_start);
+ } elsif ($exon_start > $cdsEnd) {
+ push (@utr_start, $exon_start);
+ } else {
+ $cds_start = $exon_start;
+ }
+
+ if ($exon_end < $cdsStart) {
+ push (@utr_end, $exon_end);
+ } elsif ($exon_end > $cdsEnd) {
+ push (@utr_end, $exon_end);
+ } else {
+ $cds_end = $exon_end;
+ }
+
+ if ($utr_start[0] && !$utr_end[0]) { # half in half out on 5' end
+ $utr_end[0]= $cdsStart - 1;
+ $cds_start = $cdsStart;
+ $cds_end = $exon_end;
+ }
+
+ if ($utr_end[0] && !$utr_start[0]) { # half in half out on 3' end
+ $utr_start[0]= $cdsEnd + 1;
+ $cds_end = $cdsEnd;
+ $cds_start = $exon_start;
+ }
+
+ # If the CDS is within the exon
+ if ($utr_start[0] && $utr_end[0] &&
+ $utr_start[0] < $cdsStart &&
+ $utr_end[0] > $cdsEnd)
+ {
+ $utr_end[0]= $cdsStart - 1;
+ $cds_start = $cdsStart;
+ $cds_end = $cdsEnd;
+
+ push (@utr_start, $cdsEnd + 1);
+ push (@utr_end, $exon_end);
+ }
+
+ die "programmer error, not an even number of utr_starts and utr_ends"
+ unless $#utr_start == $#utr_end;
+ die "programmer error, cds_start and no cds_end"
+ unless defined $cds_start == defined $cds_end;
+
+ for (my $i=0;$i<@utr_start;$i++) { # for each utr start
+ if (defined $utr_start[$i] && $utr_start[$i] <= $utr_end[$i] &&
+ $utr_start[$i] < $cdsStart) {
+ print $fh join
+ ("\t",$chrom,$SRC,"five_prime_UTR",$utr_start[$i],$utr_end[$i],'.',$strand,'.',"Parent=$tid"),"\n"
+ } # end of if
+ } # end of foreach
+
+ if (defined $cds_start && $cds_start <= $cds_end) {
+ print $fh join
+ ("\t",$chrom,$SRC,'CDS',$cds_start,$cds_end,'.',$strand,$phase,"Parent=$tid"),"\n";
+ $phase = (($cds_end-$cds_start+1-$phase)) % 3;
+ }
+
+ for (my $i=0;$i<@utr_start;$i++) { # for each utr start
+ if (defined $utr_start[$i] && $utr_start[$i] <= $utr_end[$i] &&
+ $utr_start[$i] > $cdsEnd) {
+ print $fh join ("\t",$chrom,$SRC,"three_prime_UTR",,$utr_start[$i],
+ $utr_end[$i],'.',$strand,'.',"Parent=$tid"),"\n"
+ }
+ }
+ } # end of for each exon
+ } # matches if strand = +
+
+ elsif ($strand eq '-') {
+ my @lines;
+ for (my $i=@exon_starts-1; $i>=0; $i--) { # count backwards
+ my $exon_start = $exon_starts[$i] + 1;
+ my $exon_end = $exon_ends[$i];
+ my (@utr_start,@utr_end,$cds_start,$cds_end);
+
+ if ($exon_end > $cdsEnd) { # in a 5' UTR
+ push (@utr_end, $exon_end);
+ } elsif ($exon_end < $cdsStart) {
+ push (@utr_end, $exon_end);
+ } else {
+ $cds_end = $exon_end;
+ }
+
+ if ($exon_start > $cdsEnd) {
+ push (@utr_start, $exon_start);
+ } elsif ($exon_start < $cdsStart) {
+ push (@utr_start, $exon_start);
+ } else {
+ $cds_start = $exon_start;
+ }
+
+ if ($utr_start[0] && !$utr_end[0]) { # half in half out on 3' end
+ $utr_end[0] = $cdsStart - 1;
+ $cds_start = $cdsStart;
+ $cds_end = $exon_end;
+ }
+
+ if ($utr_end[0] && !$utr_start[0]) { # half in half out on 5' end
+ $utr_start[0] = $cdsEnd + 1;
+ $cds_end = $cdsEnd;
+ $cds_start = $exon_start;
+ }
+
+ # If the CDS is within the exon
+ if ($utr_start[0] &&
+ $utr_end[0] &&
+ $utr_start[0] < $cdsStart &&
+ $utr_end[0] > $cdsEnd)
+ {
+ $utr_end[0]= $cdsStart - 1;
+ $cds_start = $cdsStart;
+ $cds_end = $cdsEnd;
+
+ push (@utr_start, $cdsEnd + 1);
+ push (@utr_end, $exon_end);
+ }
+
+ die "programmer error, not an even number of utr_starts and utr_ends"
+ unless $#utr_start == $#utr_end;
+
+ die "programmer error, cds_start and no cds_end" unless defined
+ $cds_start == defined $cds_end;
+
+ for (my $i=0;$i<@utr_start;$i++) { # for each utr start
+ if (defined $utr_start[$i] && $utr_start[$i] <= $utr_end[$i] &&
+ $utr_start[$i] > $cdsEnd) {
+ unshift @lines,join
+ ("\t",$chrom,$SRC,"five_prime_UTR",,$utr_start[$i],$utr_end[$i],'.',$strand,'.',"Parent=$tid"),"\n"
+ }
+ } # end of for
+
+ if (defined $cds_start && $cds_start <= $cds_end) {
+ unshift @lines,join
+ ("\t",$chrom,$SRC,'CDS',$cds_start,$cds_end,'.',$strand,$phase,"Parent=$tid"),"\n";
+ $phase = (($cds_end-$cds_start+1-$phase)) % 3;
+ }
+
+ for (my $i=0;$i<@utr_start;$i++) { # for each utr start
+ if (defined $utr_start[$i] && $utr_start[$i] <= $utr_end[$i] &&
+ $utr_end[$i] < $cdsStart) {
+ unshift @lines,join
+ ("\t",$chrom,$SRC,"three_prime_UTR",$utr_start[$i],$utr_end[$i],'.',$strand,'.',"Parent=$tid"),"\n"
+ }
+ } # end for
+ }
+ print $fh @lines;
+ }
+}
+
+
+sub write_last_gene {
+ my $self = shift;
+ my $name = $self->{last_gene_name} or return;
+ my $chr = $self->{last_gene}{chr};
+ my $start = $self->{last_gene}{start};
+ my $end = $self->{last_gene}{end};
+ my $strand = $self->{last_gene}{strand};
+ my $id = $self->{last_gene_id};
+ my $fh = $self->{fh};
+ print $fh join("\t",
+ $chr,
+ $self->{dsn},
+ 'gene',
+ $start,
+ $end,
+ '.',
+ $strand,
+ '.',
+ "ID=$id;Name=$name"),"\n";
+ $self->{last_gene_name} = '';
+}
+
+sub finish {
+ my $self = shift;
+ $self->write_last_gene if defined fileno($self->{fh});
+}
+sub DESTROY { shift->finish }
View
9 bin/gbrowse_metadb_config.pl
@@ -173,6 +173,7 @@ END
check_uploads_ids();
check_all_files();
check_data_sources();
+fix_session_permissions();
fix_sqlite_permissions() if $type =~ /sqlite/i;
$database->disconnect;
@@ -486,6 +487,14 @@ sub fix_permissions {
}
}
+sub fix_session_permissions {
+ print STDERR "Fixing permissions in sessions directory\n";
+ my $globals = Bio::Graphics::Browser2->open_globals;
+ my $session_dir = $globals->session_dir;
+ my $webuser = GBrowse::ConfigData->config('wwwuser');
+ system "sudo chown -R $webuser $session_dir";
+}
+
sub fix_sqlite_permissions {
my (undef, $db_name) = $dsn =~ /.*:(database=)?([^;]+)/;
$db_name ||= "gbrowse_login";
View
24 cgi-bin/gbrowse_details
@@ -235,24 +235,24 @@ sub print_features {
unless $self->{colors}{$method} eq 'none';
$string .= start_table({-cellspacing=>0});
- unless ($subf) {
- $string .= $self->print_multiple($f,
- $options,
- 'Name',
- $f->name);
- $string .= $self->print_multiple($f,
- $options,
- 'Class',
- $f->class) unless $f->class eq 'Sequence';
- }
+ $string .= $self->print_multiple($f,
+ $options,
+ 'Name',
+ $f->name) if $f->name;
+ $string .= $self->print_multiple($f,
+ $options,
+ 'Class',
+ $f->class) unless $f->class eq 'Sequence' || $subf;
$string .= $self->print_multiple($f,
$options,
'Type',
$f->primary_tag);
+
+ my $description = Bio::Graphics::Glyph::generic->get_description($f);
$string .= $self->print_multiple($f,
$options,
'Description',
- Bio::Graphics::Glyph::generic->get_description($f));
+ $description) if $description;
$string .= $self->print_multiple($f,
$options,
'Source',
@@ -312,7 +312,7 @@ sub print_features {
$string .= $self->print_multiple($f,
$options,
'gbrowse_dbid',
- $f->gbrowse_dbid) if $f->can('gbrowse_dbid');
+ $f->gbrowse_dbid) if $f->can('gbrowse_dbid') && $f->gbrowse_dbid;
$string .= TR({-valign=>'top',-class=>'databody'},
th({-height=>3},''),
View
6 conf/GBrowse.conf
@@ -168,10 +168,10 @@ user_accounts_openid = 1
# Path to the database -- you will need to create this database and grant all
# privileges on it to the indicated user.
-user_account_db = DBI:SQLite:$PERSISTENT/databases/users.sqlite
+user_account_db = DBI:SQLite:$DATABASES/users.sqlite
# For SQLite
-# user_account_db = DBI:SQLite:$PERSISTENT/databases/users.sqlite
+# user_account_db = DBI:SQLite:$DATABASES/users.sqlite
# For MySQL
# user_account_db = DBI:mysql:gbrowse_login;user=gbrowse;password=gbrowse
@@ -203,7 +203,7 @@ email_address = noreply@gmod.org
# name of the "superuser" who can add public tracks
admin_account = admin
-admin_dbs = $PERSISTENT/databases/admin_uploads
+admin_dbs = $DATABASES/admin_uploads
######## DEFAULT DATASOURCE #########
View
4 conf/languages/is.pm
@@ -303,9 +303,9 @@ END
DETAILS => 'Nánar',
- ALL_OFF => 'Virkja allar',
+ ALL_ON => 'Virkja allar',
- ALL_ON => 'Afvirkja allar',
+ ALL_OFF => 'Afvirkja allar',
ANALYSIS => 'Greining',
View
77 conf/plugins/BatchDumper.pm
@@ -5,6 +5,7 @@ use Bio::Graphics::Browser2::Plugin;
use Bio::Seq::RichSeq;
use Bio::SeqIO;
use Bio::Seq;
+use Bio::Graphics::Browser2::TrackDumper::RichSeqMaker;
use CGI qw(:standard *pre);
use POSIX;
use vars qw($VERSION @ISA);
@@ -17,7 +18,6 @@ my @FORMATS = ( 'fasta' => ['Fasta', undef],
'embl' => ['EMBL', undef],
'gcg' => ['GCG', undef],
'raw' => ['Raw sequence', undef],
- 'game' => ['GAME (XML)', 'xml'],
'bsml' => ['BSML (XML)', 'xml'],
'gff' => ['GFF', undef],
'gff3' => ['GFF3', undef],
@@ -61,8 +61,9 @@ sub dump {
my $wantsorted = $config->{'wantsorted'};
my @segments = map {
- ( $browser->name2segments($_,$self->database) )
+ ( $self->renderer->name2segments($_,$self->database) )
} split /\s+/m, $config->{sequence_IDs}||'';
+
# take the original segment if no segments were found/entered via the sequence_IDs textarea field
@segments = $segment if $segment && !@segments;
@@ -84,64 +85,10 @@ sub dump {
}
foreach my $segment ( @segments ) {
- my $seq = new Bio::Seq::RichSeq(-display_id => $segment->display_id,
- -desc => $segment->desc,
- -accession_number => $segment->accession_number,
- -alphabet => $segment->alphabet || 'dna',
- );
- $seq->add_date(strftime("%d-%b-%Y",localtime));
- $seq->primary_seq($segment->primary_seq);
- $segment->absolute(1);
- my $offset = $segment->start - 1;
- my $segmentend = $segment->length;
- $seq->add_SeqFeature( map {
- my $nf = new Bio::SeqFeature::Generic(-primary_tag => $_->primary_tag,
- -source_tag => $_->source_tag,
- -frame => (eval{$_->phase}||eval{$_->frame}||undef),
- -score => $_->score,
- );
- for my $tag ( $_->get_all_tags ) {
- my %seen;
- $nf->add_tag_value($tag, grep { ! $seen{$_}++ }
- grep { defined } $_->get_tag_values($tag));
- }
- my $loc = $_->location;
- my @locs = $loc->each_Location;
- for my $sl (@locs ) {
- $sl->start($sl->start() - $offset);
- $sl->end ($sl->end() - $offset );
- my ($startstr,$endstr);
-
- if( $sl->start() < 1) {
- $startstr = "<1";
- $endstr = $sl->end;
- }
-
- if( $sl->end() > $segmentend) {
- $endstr = ">$segmentend";
- $startstr = $sl->start unless defined $startstr;
- }
- if( defined $startstr || defined $endstr ) {
- $sl = Bio::Location::Fuzzy->new(-start => $startstr,
- -end => $endstr,
- -strand => $sl->strand,
- -location_type => '..');
- }
- }
- if( @locs > 1 ) {
- # let's ensure they are sorted
- if( $wantsorted ) { # for VectorNTI
- @locs = sort { $a->start <=> $b->start } @locs;
- }
- $nf->location( new Bio::Location::Split(-locations => \@locs,
- -seq_id =>
- $segment->display_id));
- } else {
- $nf->location(shift @locs);
- }
- $nf;
- } $segment->features(-types => \@filter) );
- $segment = $seq;
+ my $iterator = $segment->get_seq_stream(-types => \@filter);
+ my $seq = Bio::Graphics::Browser2::TrackDumper::RichSeqMaker->stream_to_rich_seq($segment,$iterator);
+ $seq->desc($segment->as_string);
+ $segment = $seq;
}
# for the external viewer (like VNTI) the best import format is genbank (?)
@@ -161,11 +108,11 @@ sub dump {
if ($mime_type =~ /html/) {
print start_html('Batch Sequence');
foreach my $segment (@segments) {
- my $label = $segment->desc;
- print h1($label),"\n",
- start_pre,"\n";
- $out->write_seq($segment);
- print end_pre(),"\n";
+ my $label = $segment->desc;
+ print h1($label),"\n",
+ start_pre();
+ $out->write_seq($segment);
+ print end_pre();
}
print end_html;
} else {
View
4 conf/plugins/FastaDumper.pm
@@ -62,10 +62,10 @@ sub dump {
}
my $config = $self->configuration;
- my $dna = lc $segment->dna;
+ my $dna = lc $segment->dna;
my $browser = $self->browser_config();
warn("====== beginning dump =====\n") if DEBUG;
- warn "length of dna = ",length($dna) if DEBUG;
+ warn "length of dna = ",length($dna) if DEBUG;
my %types;
View
74 conf/plugins/SequenceDumper.pm
@@ -48,19 +48,20 @@ Internal methods are usually preceded with a _
# Let the code begin...
-
package Bio::Graphics::Browser2::Plugin::SequenceDumper;
# $Id: SequenceDumper.pm,v 1.18 2009-01-02 20:57:37 lstein Exp $
# Sequence Dumper plugin
use strict;
use Bio::Graphics::Browser2::Plugin;
+use Bio::SeqFeature::Generic;
use Bio::SeqIO;
use Bio::Seq::RichSeq;
-use POSIX qw(strftime);
-use Bio::Location::Fuzzy;
+use Bio::Graphics::Browser2::TrackDumper::RichSeqMaker;
+
use CGI qw(:standard *pre);
-use Bio::SeqFeature::Generic;
+use POSIX qw(strftime);
+
use vars qw($VERSION @ISA);
use constant DEBUG => 0;
@@ -70,7 +71,6 @@ my @FORMATS = ( 'fasta' => ['Fasta', undef],
'embl' => ['EMBL', undef],
'gcg' => ['GCG', undef],
'raw' => ['Raw sequence', undef],
- 'game' => ['GAME (XML)', 'xml'],
'bsml' => ['BSML (XML)', 'xml'],
'gff' => ['GFF3', undef],
);
@@ -118,68 +118,8 @@ sub dump {
return;
}
my @filter = $self->selected_features;
- my $seq = new Bio::Seq::RichSeq(-display_id => $segment->display_id,
- -desc => $segment->desc,
- -accession_number => $segment->accession_number,
-
- -alphabet => $segment->alphabet || 'dna',
- );
- $seq->add_date(strftime("%d-%b-%Y",localtime));
- my $ps = $segment->primary_seq;
- $seq->primary_seq(!ref $ps ? Bio::PrimarySeq->new(-seq=>$ps) : $ps);
- $segment->absolute(1);
- my $offset = $segment->start - 1;
- my $segmentend = $segment->length;
- $seq->add_SeqFeature( map {
- my $score = $_->score;
- $score = ref $score eq 'HASH' ? $score->{sumData}/$score->{validCount} : $score;
- my $nf = new Bio::SeqFeature::Generic(-primary_tag => $_->primary_tag,
- -source_tag => $_->source_tag,
- -frame => eval{$_->phase}||eval{$_->frame}||undef,
- -score => $score,
- );
- for my $tag ( $_->get_all_tags ) {
- my %seen;
- $nf->add_tag_value($tag, grep { ! $seen{$_}++ }
- grep { defined } $_->get_tag_values($tag));
- }
- my $loc = $_->location;
- my @locs = $loc->each_Location;
- for my $sl (@locs ) {
- $sl->start($sl->start() - $offset);
- $sl->end ($sl->end() - $offset );
- my ($startstr,$endstr);
-
- if( $sl->start() < 1) {
- $startstr = "<1";
- $endstr = $sl->end;
- }
-
- if( $sl->end() > $segmentend) {
- $endstr = ">$segmentend";
- $startstr = $sl->start unless defined $startstr;
- }
- if( defined $startstr || defined $endstr ) {
- $sl = Bio::Location::Fuzzy->new(-start => $startstr,
- -end => $endstr,
- -strand => $sl->strand,
- -location_type => '..');
- # warn $sl->to_FTstring();
- }
- }
- if( @locs > 1 ) {
- # let's insure they are sorted
- if( $wantsorted ) { # for VectorNTI
- @locs = sort { $a->start <=> $b->start } @locs;
- }
- $nf->location( new Bio::Location::Split(-locations => \@locs,
- -seq_id =>
- $segment->display_id));
- } else {
- $nf->location(shift @locs);
- }
- $nf;
- } $segment->features(-types => \@filter) );
+ my $iterator = $segment->get_seq_stream(-types => \@filter);
+ my $seq = Bio::Graphics::Browser2::TrackDumper::RichSeqMaker->stream_to_rich_seq($segment,$iterator);
my $out = new Bio::SeqIO(-format => $config->{fileformat},-fh=>\*STDOUT);
my $mime_type = $self->mime_type;
View
32 conf/plugins/TrackFinder.pm
@@ -19,9 +19,8 @@ sub init { }
sub config_defaults {
my $self = shift;
- # this line gets all the options defined in the "[SourceTrackFinder:plugin]" stanza
+ # this line gets all the options defined in the "[TrackFinder:plugin]" stanza
my %fields = map {$_=>undef} $self->get_fields;
-
return \%fields;
}
@@ -73,13 +72,14 @@ sub filter_tracks {
my $config = $self->configuration;
my @keywords = map {quotemeta($_)} shellwords $config->{keywords};
-
+ my @searches = get_fields($self);
my @result;
LABEL:
for my $l (@$track_labels) {
do {push @result,$l; next LABEL} if $l =~ /^(plugin|file|http|das)/;
-
- my $aggregate_text = join ' ',map {$source->code_setting($l=>$_)} qw(key keywords select);
+
+ my @searched_fields = @searches ? @searches :(qw(key keywords select),"subtrack select labels");
+ my $aggregate_text = join ' ',map {$source->code_setting($l=>$_)} @searched_fields;
$aggregate_text ||= $l;
my $labels = $source->subtrack_scan_list($l);
$aggregate_text .= " @$labels" if $labels && @$labels;
@@ -122,29 +122,21 @@ Bio::Graphics::Browser2::Plugin::TrackFinder - Limit list of tracks to those tha
In the appropriate gbrowse configuration file:
- plugin = SourceTrackFinder
+ plugin = TrackFinder
- [SourceTrackFinder:plugin]
- tissue source = brain pancreas kidney
- gender = male female
+ [TrackFinder:plugin]
+ category = 1
+ citation = 1
+ keywords = 1
- [track1]
- (usual config options)
- tissue source = brain
- gender = male
- [track2]
- (usual config options)
- tissue source = pancreas
- gender = female
=head1 DESCRIPTION
This plugin activates a panel above the tracks table that allows the
user to filter the tracks according to typed keywords. The fields to
-search are hard-coded to "key", "citation" and "keywords". Simply add
-a space-delimited "keywords" field to each stanza in order to make it
-findable by this plugin.
+search are hard-coded to "key", "citation", "keywords", "subtack select labels".
+Or they can be configured as shown above
Note that this only affects the display of track names. Tracks that
were previously turned on will stay on, but their entries will be
View
2  conf/synteny/oryza.synconf.disabled
@@ -23,7 +23,7 @@ cache time = 1
config_extension = conf
# example searches to display
-examples = rice 3:16050173..16064974
+examples = rice 3:200000..280000
wild_rice 3:1..400000
zoom levels = 5000 10000 25000 50000 100000 200000 400000
View
99 htdocs/cloud_index.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>Generic Genome Browser</title>
+<link rel="stylesheet" href="tutorial/tutorial.css">
+</head>
+
+<body>
+<h1>Generic Genome Browser, v2 (Cloud Image)</h1>
+
+<a href="http://www.gmod.org/"><img src="gmod_cog.jpeg" border="0" align="RIGHT"></a>
+
+<p>
+
+Welcome to the Generic Genome Browser (Cloud Image)!
+
+<h2>Documentation</h2>
+
+<dl>
+ <dt><b>Online tutorial and sample data files</b></dt>
+ <dd><a href="tutorial/tutorial.html">/var/www/gbrowse2/tutorial<a>.</dd>
+ <dt><b>Installation and configuration manual</b></dt>
+ <dd><a href="http://gmod.org/wiki/GBrowse_2.0_HOWTO">GBrowse 2.0 HOWTO</a></dd>
+ <dt><b>Example scripts to control GBrowse from the command line</b></dt>
+ <dd><a href="example_scripts">/var/www/gbrowse2/example_scripts</a></dd>
+</dl>
+
+<h2>Starter Databases</h2>
+
+<p>
+
+A series of starter databases have been preconfigured for you, consisting of:
+
+<ul>
+<li><a href="/fgb2/gbrowse/sacCer3">S. cerevisiae genome (April 11, sacCer3), Genes and DNA only</a></li>
+<li><a href="/fgb2/gbrowse/yeast_advanced">S. cerevisiae, Chromosomes 1+2, (more tracks)</a></li>
+<li><a href="/fgb2/gbrowse/ce10">C. elegans genome (WS220, ce10), Genes and DNA only</a></li>
+<li><a href="/fgb2/gbrowse/hg19">H. sapiens genome (hg19, GRCh37), Genes and DNA only</a></li>
+</ul>
+
+<p>
+
+You may add additional starter genomes at any time by running the
+command line script gbrowse_import_ucsc.pl and providing
+the <a href="genome.ucsc.edu">UCSC Genome Browser</a> build name:
+
+<pre>
+ gbrowse_import_ucsc.pl mm10 'M. musculus genome (mm10, GRCm38)'
+</pre>
+
+<h2>Directory Paths</h2>
+
+<p>
+
+For future reference, here is where you've installed GBrowse's various
+components:
+
+<dl>
+ <dt>GBrowse documentation, stylesheets and in-memory databases.
+ <dd><b>$HTDOCS</b>
+ <p>
+ <dt>GBrowse configuration files
+ <dd><b>$CONF</b>
+ <p>
+ <dt>Preinstalled sample database(s)
+ <dd><b>$DATABASES</b>
+ <p>
+ <dt>GBrowse CGI (web) scripts
+ <dd><ul>
+ <li><b>$CGIBIN/gbrowse</b>
+ <li><b>$CGIBIN/gbrowse_img</b>
+ <li><b>$CGIBIN/gbrowse_details</b>
+ </ul>
+ <p>
+ <dt>Temporary directories for cached images and sessions.
+ <dd><b>$TMP</b>
+</dl>
+
+<p>
+
+<h2>Learning More</h2>
+
+<p>
+
+To find out more about Gbrowse, try the:
+
+<ul>
+ <li><a href="http://gmod.org/wiki/GBrowse_2.0_HOWTO">GBrowse 2.0 HOWTO</a>
+ <li><a href="tutorial/tutorial.html">GBrowse Tutorial</a>
+ <!-- <li><a href="contrib/conf_files">Sample Configuration Files</a> -->
+</ul>
+
+
+<hr>
+<address>Lincoln D. Stein, lstein@cshl.org<br>
+<a href="http://www.cshl.org/">Cold Spring Harbor Laboratory</a></address>
+<!-- hhmts start -->
+Last modified: Thu Mar 18 18:59:16 PDT 2010
+<!-- hhmts end -->
+</body> </html>
View
14 htdocs/gbrowse_syn_help.html
@@ -14,9 +14,9 @@
for two rice species and blastz-derived whole genome aligment data between
the two species.
<ul>
-<li>$DATABASES/gbrowse_syn/rice/rice.gff3
-<li>$DATABASES/gbrowse_syn/wild_rice/wild_rice.gff3
-<li>$DATABASES/gbrowse_syn/alignments/rice.aln
+<li>/var/lib/gbrowse2/databases/gbrowse_syn/rice/rice.gff3
+<li>/var/lib/gbrowse2/databases/gbrowse_syn/wild_rice/wild_rice.gff3
+<li>/var/lib/gbrowse2/databases/gbrowse_syn/alignments/rice.aln
</ul>
@@ -60,7 +60,7 @@
$ sudo gunzip rice.aln.gz
$ gbrowse_syn_load_alignments_msa.pl -u user -p pass -d rice_synteny -c -v rice.aln
=======
-$ cd $DATABASES/gbrowse_syn/alignments
+$ cd /var/lib/gbrowse2/databases/gbrowse_syn/alignments
$ gunzip -c rice.aln.gz | gbrowse_syn_load_alignments_msa.pl -u user -p pass -d rice_synteny -c -v -
>>>>>>> master
</pre>
@@ -77,7 +77,7 @@
# or as root
% mv /etc/gbrowse2/synteny/oryza.synconf.disabled /etc/gbrowse2/synteny/oryza.synconf
=======
-$ mv $CONF/synteny/oryza.synconf.disabled $CONF/synteny/oryza.synconf
+$ mv /etc/gbrowse2/synteny/oryza.synconf.disabled /etc/gbrowse2/synteny/oryza.synconf
>>>>>>> master
</pre>
@@ -144,7 +144,7 @@
<pre>
$ bp_seqfeature_load.pl -u user -p pass -d rice -c -f /var/www/gbrowse2/$GBROWSE_ROOT/databases/gbrowse_syn/rice/rice.gff3
=======
-$ bp_seqfeature_load.pl -u user -p pass -d rice -c -f $DATABASES/gbrowse_syn/rice/rice.gff3
+$ bp_seqfeature_load.pl -u user -p pass -d rice -c -f /var/lib/gbrowse2/databases/gbrowse_syn/rice/rice.gff3
>>>>>>> master
loading /var/www/html/gbrowse/databases/gbrowse_syn/rice/rice.gff3...
Building object tree... 1.05s7s
@@ -154,7 +154,7 @@
<<<<<<< HEAD
$ bp_seqfeature_load.pl -u user -p pass -d wild_rice -c -f /var/www/gbrowse2/$GBROWSE_ROOT/databases/gbrowse_syn/wild_rice/wild_rice.gff3
=======
-$ bp_seqfeature_load.pl -u user -p pass -d wild_rice -c -f $DATABASES/gbrowse_syn/wild_rice/wild_rice.gff3
+$ bp_seqfeature_load.pl -u user -p pass -d wild_rice -c -f /var/lib/gbrowse2/databases/gbrowse_syn/wild_rice/wild_rice.gff3
>>>>>>> master
loading /var/www/html/gbrowse/databases/gbrowse_syn/wild_rice/wild_rice.gff3...
Building object tree... 1.15s9s
View
18 htdocs/index.html
@@ -18,8 +18,8 @@
<dl>
<dt><b>Online tutorial and sample data files</b></dt>
<dd><a href="tutorial/tutorial.html">/var/www/gbrowse2/tutorial<a>.</dd>
- <dt>Installation and configuration manual</dt>
- <dd><b><a href="http://gmod.org/wiki/GBrowse_2.0_HOWTO">GBrowse 2.0 HOWTO</a></b></dd>
+ <dt><b>Installation and configuration manual</b></dt>
+ <dd><a href="http://gmod.org/wiki/GBrowse_2.0_HOWTO">GBrowse 2.0 HOWTO</a></dd>
<dt><b>Example scripts to control GBrowse from the command line</b></dt>
<dd><a href="example_scripts">/var/www/gbrowse2/example_scripts</a></dd>
</dl>
@@ -84,23 +84,23 @@
<dl>
<dt>GBrowse documentation, stylesheets and in-memory databases.
- <dd><b>/var/www/gbrowse2</b>
+ <dd><b>$HTDOCS</b>
<p>
<dt>GBrowse configuration files
- <dd><b>/etc/gbrowse2/GBrowse.conf</b>
+ <dd><b>$CONF</b>
<p>
<dt>Preinstalled sample database(s)
- <dd><b>/var/lib/gbrowse2/databases</b>
+ <dd><b>$DATABASES</b>
<p>
<dt>GBrowse CGI (web) scripts
<dd><ul>
- <li><b>/usr/lib/cgi-bin/gb2/gbrowse</b>
- <li><b>/usr/lib/cgi-bin/gb2/gbrowse_img</b>
- <li><b>/usr/lib/cgi-bin/gb2/gbrowse_details</b>
+ <li><b>$CGIBIN/gbrowse</b>
+ <li><b>$CGIBIN/gbrowse_img</b>
+ <li><b>$CGIBIN/gbrowse_details</b>
</ul>
<p>
<dt>Temporary directories for cached images and sessions.
- <dd><b>/tmp/gbrowse2</b>
+ <dd><b>$TMP</b>
</dl>
<p>
View
4 htdocs/js/ajax_upload.js
@@ -184,11 +184,11 @@ function completeAjaxUpload(response, upload_id, field_type) {
r = response.evalJSON(true);
} catch(e) {
r = {
- success: false,
+ success: false,
uploadName: 'Uploaded file',
error_msg: Controller.translate('UPLOAD_ERROR')
}
- }
+ }
if (r.success) {
var fields = new Array(track_listing_id, custom_tracks_id)
View
2  htdocs/js/login.js
@@ -946,7 +946,7 @@ function edit_details(details) {
$('loginWarning').show();
$('loginDCancel').value = Controller.translate('NO');
$('loginDSubmit').value = Controller.translate('YES');
- $('loginDOUser').value = CurrentUser;
+ if ($('loginDOUser') != undefined) { $('loginDOUser').value = CurrentUser; }
EditDetails = 'delete';
return;
case 'delete-confirm':
View
10 htdocs/js/track_configure.js
@@ -13,7 +13,7 @@ var TrackConfigure = Class.create({
all.each(function(a){a.hide()});
var specific = false;
- if (glyph_element.value.match(/xyplot/)) {
+ if (glyph_element.value.match(/xyplot|hybrid/)) {
config_container.select('tr.xyplot').each(function(a){a.show()});
specific = true;
}
@@ -54,7 +54,7 @@ var TrackConfigure = Class.create({
if (x != null) x.hide();
specific = true;
}
- if (glyph_element.value.match(/xyplot|whiskers/)) {
+ if (glyph_element.value.match(/xyplot|whiskers|hybrid/)) {
this.adjust_height(40,200);
}
if (!specific) {
@@ -63,7 +63,7 @@ var TrackConfigure = Class.create({
config_container.select('tr.'+glyph_element.value).each(function(a){a.show()});
- var signal = glyph_element.value.match(/xyplot|density|wiggle/)
+ var signal = glyph_element.value.match(/xyplot|density|wiggle|hybrid/)
|| (glyph_element.value.match(/vista/) && subtype.value.match(/signal/));
var can_pivot = !(glyph_element.value.match(/whiskers/) || (graphtype !=null && graphtype.value.match(/whiskers/)));
can_pivot = can_pivot || (glyph_element.value.match(/vista/) && subtype.value.match(/density/));
@@ -149,10 +149,10 @@ var TrackConfigure = Class.create({
var autoscales = $('config_table').select('tr').findAll(function(a){return a.hasClassName('autoscale')});
autoscales.each(function(a){a.hide()});
- if (g.match(/wiggle/) || g.match(/vista/)) {
+ if (g.match(/wiggle/) || g.match(/vista/) || g.match(/hybrid/)) {
$('wiggle_autoscale').show();
}
- else if (g.match(/xyplot/) || g.match(/density/)) {
+ else if (g.match(/xyplot/) || g.match(/density/) || g.match(/hybrid/)) {
$('xyplot_autoscale').show();
}
View
102 htdocs/vbox_index.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>Generic Genome Browser</title>
+<link rel="stylesheet" href="tutorial/tutorial.css">
+</head>
+
+<body>
+<h1>Generic Genome Browser, v2, VirtualBox Edition</h1>
+
+<a href="http://www.gmod.org/"><img src="gmod_cog.jpeg" border="0" align="RIGHT"></a>
+
+<p>
+
+Welcome to the Generic Genome Browser, VirtualBox Edition!
+
+<h2>Documentation</h2>
+
+<dl>
+ <dt><b>Online tutorial and sample data files</b></dt>
+ <dd><a href="tutorial/tutorial.html">/var/www/gbrowse2/tutorial<a>.</dd>
+ <dt><b>Installation and configuration manual</b></dt>
+ <dd><b><a href="http://gmod.org/wiki/GBrowse_2.0_HOWTO">GBrowse 2.0 HOWTO</a></b></dd>
+ <dt><b>Example scripts to control GBrowse from the command line</b></dt>
+ <dd><a href="example_scripts">/var/www/gbrowse2/example_scripts</a></dd>
+</dl>
+
+<h2>Example Databases</h2>
+
+<p>
+
+A few "starter" databases have been installed for you. You can access
+them from within the virtual machine
+at <a href="http://localhost/fgb2/gbrowse">http://localhost/fgb2/gbrowse</a>,
+or from outside the virtual machine using
+http://host.machine:8081/fgb2/gbrowse, where "host.machine" is the DNS
+name or IP address of the computer that is hosting VirtualBox.
+
+<ul>
+<li><a href="/fgb2/gbrowse/sacCer3">S. cerevisiae genome (April 2011), genes and DNA</a></li>
+<li><a href="/fgb2/gbrowse/ce10">C. elegans genome (WS220), genes and DNA</a></li>
+<li><a href="/fgb2/gbrowse/yeast_advanced">S. cerevisiae, advanced example (chromosomes 1+2 only)</a></li>
+</ul>
+
+<p>
+
+More starter databases can be installed by running the command line
+script "gbrowse_import_ucsc_db.pl". Genome builds are selected using
+the <a href="genome.ucsc.edu">UCSC genome browser</a> build name.
+For example, to load the human genome:
+
+ gbrowse_import_ucsc_db.pl hg19 'H. sapiens genome (hg19), genes and DNA'
+
+<h2>Directory Paths</h2>
+
+<p>
+
+For future reference, here is where you've installed GBrowse's various
+components:
+
+<dl>
+ <dt>GBrowse documentation, stylesheets and in-memory databases.
+ <dd><b>/opt/gbrowse/var/www/gbrowse2</b>
+ <p>
+ <dt>GBrowse configuration files
+ <dd><b>/opt/gbrowse/etc</b>
+ <p>
+ <dt>Preinstalled sample database(s)
+ <dd><b>/opt/gbrowse/lib/gbrowse2/databases</b>
+ <p>
+ <dt>GBrowse CGI (web) scripts
+ <dd><ul>
+ <li><b>/usr/lib/cgi-bin/gb2/gbrowse</b>
+ <li><b>/usr/lib/cgi-bin/gb2/gbrowse_img</b>
+ <li><b>/usr/lib/cgi-bin/gb2/gbrowse_details</b>
+ </ul>
+ <p>
+ <dt>Temporary directories for cached images and sessions.
+ <dd><b>/tmp/gbrowse2</b>
+</dl>
+
+<p>
+
+<h2>Learning More</h2>
+
+<p>
+
+To find out more about Gbrowse, try the:
+
+<ul>
+ <li><a href="http://gmod.org/wiki/GBrowse_2.0_HOWTO">GBrowse 2.0 HOWTO</a>
+ <li><a href="tutorial/tutorial.html">GBrowse Tutorial</a>
+ <!-- <li><a href="contrib/conf_files">Sample Configuration Files</a> -->
+</ul>
+
+
+<hr>
+<address>Lincoln D. Stein, lstein@cshl.org<br>
+<a href="http://www.cshl.org/">Cold Spring Harbor Laboratory</a></address>
+<!-- hhmts start -->
+Last modified: Thu Mar 18 18:59:16 PDT 2010
+<!-- hhmts end -->
+</body> </html>
View
99 install_util/GBrowseInstall.pm
@@ -13,8 +13,9 @@ use File::Spec;
use IO::File;
use IO::Dir;
use File::Compare 'compare';
-use File::Copy 'copy';
+use File::Copy 'copy','cp';
use GBrowseGuessDirectories;
+use Carp 'cluck';
use overload '""' => 'asString',
fallback => 1;
@@ -546,7 +547,6 @@ sub process_conf_files {
my $prefix = $self->install_base || $self->prefix || '';
GBrowseGuessDirectories->prefix($prefix);
my $install_path = $self->config_data('conf') || GBrowseGuessDirectories->conf;
- my $skip;
while (<$f>) {
next unless m!^conf/!;
@@ -554,35 +554,72 @@ sub process_conf_files {
my $base = $_;
my $copied = $self->copy_if_modified($_=>'blib');
- $self->substitute_in_place("blib/$_")
- if $copied
- or !$self->up_to_date('_build/config_data',"blib/$_");
-
- if ($copied) {
- $skip ||= IO::File->new('>>INSTALL.SKIP');
- (my $new = $base) =~ s/^conf\///;
- my $installed = File::Spec->catfile($install_path,$new);
- if (-e $installed && $base =~ /\.conf$/ && (compare($base,$installed) != 0)) {
- warn "$installed is already installed. New version will be installed as $installed.new\n";
- rename ("blib/$base","blib/$base.new");
- print $skip '^',"blib/",quotemeta($base),'$',"\n";
- }
+ if ($copied || !$self->up_to_date('_build/config_data',"blib/$_")) {
+ $self->substitute_in_place("blib/$_");
+ $self->check_installed($install_path,$base);
}
}
- $skip->close if $skip;
+}
+
+sub check_installed {
+ my $self = shift;
+ my ($install_path,$blib_file) = @_;
+ my $skip = $self->{skip} ||= IO::File->new('>>INSTALL.SKIP') or die "INSTALL.SKIP: $!";
+ (my $base = $blib_file) =~ s!^[^/]+/!!;
+ my $staged = File::Spec->catfile('./blib',$blib_file);
+ my $installed = File::Spec->catfile($install_path,$base);
+
+ if (-e $installed && (compare($staged,$installed) != 0)) {
+ my ($confirmed,$keep);
+
+ if ($ENV{AUTOMATED_TESTING}) {
+ $confirmed++;
+ $keep++;
+ }
+
+ while (!$confirmed) {
+ print STDERR "$installed has changed. Should \"Build install\" [R]eplace with new version or [K]eep currently installed version [K]? ";
+ my $line = <>;
+ chomp($line);
+ $line ||= '';
+ if ($line =~ /^[Kk]/) {
+ $keep++;
+ $confirmed++;
+ } elsif ($line =~ /^[Rr]/) {
+ $confirmed++;
+ } elsif ($line =~ /^$/) {
+ $keep++;
+ $confirmed++;
+ }
+ }
+
+ if ($keep) {
+ print STDERR "\"Build install\" will keep original $installed. New version can be found in ${installed}.new\n\n";
+ cp($staged,"${staged}.new");
+ print $skip '^',"blib/",quotemeta($blib_file),'$',"\n";
+ } else {
+ print STDERR "\"Build install\" will replace original $installed. Original version can be found in ${installed}.orig\n\n";
+ cp($installed,"${staged}.orig");
+ }
+ }
}
sub process_htdocs_files {
my $self = shift;
my $f = IO::File->new('MANIFEST');
+ my $install_path = $self->install_path->{'htdocs'} || GBrowseGuessDirectories->htdocs;
+
+ my %doneit;
while (<$f>) {
next unless m!^htdocs/!;
chomp;
- my $copied = $self->copy_if_modified($_=>'blib');
- $self->substitute_in_place("blib/$_")
- if $copied
- or !$self->up_to_date('_build/config_data',"blib/$_");
+ my $base = $_;
+ my $copied = $self->copy_if_modified($base=>'blib');
+ if ($copied or !$self->up_to_date('_build/config_data',"blib/$base")) {
+ $self->substitute_in_place("blib/$base");
+ $self->check_installed($install_path,$base) if $copied;
+ }
}
}
@@ -606,9 +643,7 @@ sub process_etc_files {
my $prefix = $self->install_base || $self->prefix || '';
GBrowseGuessDirectories->prefix($prefix);
- my $install_path = GBrowseGuessDirectories->etc;
-
- my $skip;
+ my $install_path = $self->install_path->{'etc'} || GBrowseGuessDirectories->etc;
if ($self->config_data('installetc') =~ /^[yY]/) {
my $f = IO::File->new('MANIFEST');
@@ -619,25 +654,13 @@ sub process_etc_files {