#!/usr/bin/env perl # Copyright (C) 2006-2009 Martin A. Hansen. # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # http://www.gnu.org/copyleft/gpl.html # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< use strict; use warnings; use lib "/Users/maasha/biopieces/code_perl/"; use CGI; use Cairo; use Pango; use Data::Dumper; use Time::HiRes; use Maasha::Common; use Maasha::Filesys; use Maasha::Calc; use Maasha::XHTML; use Maasha::Biopieces; use Maasha::KISS::IO; use Maasha::KISS::Track; use Maasha::KISS::Draw; my ( $cgi, $database, $user, $password, $dbh, $script, @html ); $cgi = new CGI; $database = 'S_aur_COL'; $user = Maasha::Biopieces::biopiecesrc( "MYSQL_USER" ); $password = Maasha::Biopieces::biopiecesrc( "MYSQL_PASSWORD" ); $dbh = Maasha::SQL::connect( $database, $user, $password ); $script = Maasha::Common::get_scriptname(); push @html, Maasha::XHTML::html_header( cgi_header => 1, title => "KISS Genome Browser", # css_file => "test.css", author => "Martin A. Hansen, mail\@maasha.dk", description => "Biopieces bacterial genome browser - KISS", keywords => [ qw( KISS Biopieces biopiece genome browser viewer bacterium bacteria prokaryote prokaryotes ) ], no_cache => 1, ); push @html, Maasha::XHTML::h1( txt => "KISS Genome Browser", class => "center" ); push @html, Maasha::XHTML::form_beg( action => $script, method => "get", enctype => "multipart/form-data" ); push @html, sec_navigate( $cgi ); push @html, sec_browse( $dbh, $cgi->param( 'nav_start' ), $cgi->param( 'nav_end' ) ); push @html, Maasha::XHTML::form_end; push @html, Maasha::XHTML::body_end; push @html, Maasha::XHTML::html_end; print "$_\n" foreach @html; # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< sub sec_navigate { my ( $cgi, # CGI object ) = @_; # Returns a list. my ( $list_clade, $list_genome, $list_assembly, $list_contig, $def_clade, $def_genome, $def_assembly, $def_contig, $def_start, $def_end, @html ); $list_clade = nav_list_clade(); $list_genome = nav_list_genome(); $list_assembly = nav_list_assembly(); $list_contig = nav_list_contig(); nav_zoom( $cgi ); nav_move( $cgi, 2_800_000 ); # FIXME $def_clade = nav_def_clade( $cgi ); $def_genome = nav_def_genome( $cgi ); $def_assembly = nav_def_assembly( $cgi ); $def_contig = nav_def_contig( $cgi ); $def_start = nav_def_start( $cgi ); $def_end = nav_def_end( $cgi ); push @html, Maasha::XHTML::table_beg( summary => "Navigation table" ); push @html, Maasha::XHTML::table_row_simple( tr => [ qw( Clade Genome Assembly Contig Start End ) ], align => 'center' ); push @html, Maasha::XHTML::table_row_simple( tr => [ Maasha::XHTML::menu( name => "nav_clade", options => $list_clade, selected => $def_clade ), Maasha::XHTML::menu( name => "nav_genome", options => $list_genome, selected => $def_genome ), Maasha::XHTML::menu( name => "nav_assembly", options => $list_assembly, selected => $def_assembly ), Maasha::XHTML::menu( name => "nav_contig", options => $list_contig, selected => $def_contig ), Maasha::XHTML::text( name => "nav_start", value => Maasha::Calc::commify( $def_start ), size => 20 ), Maasha::XHTML::text( name => "nav_end", value => Maasha::Calc::commify( $def_end ), size => 20 ), Maasha::XHTML::submit( name => "nav_submit", value => "Submit" ), ] ); push @html, Maasha::XHTML::table_end; push @html, Maasha::XHTML::table_beg( summary => "Zoom table" ); push @html, Maasha::XHTML::table_row_simple( tr => [ Maasha::XHTML::p( txt => 'Move:' ), Maasha::XHTML::submit( name => "move_left3", value => "<<<", title => "move 95% to the left" ), Maasha::XHTML::submit( name => "move_left2", value => "<<", title => "move 47.5% to the left" ), Maasha::XHTML::submit( name => "move_left1", value => "<", title => "move 10% to the left" ), Maasha::XHTML::submit( name => "move_right1", value => ">", title => "move 10% to the rigth" ), Maasha::XHTML::submit( name => "move_right2", value => ">>", title => "move 47.5% to the rigth" ), Maasha::XHTML::submit( name => "move_right3", value => ">>>", title => "move 95% to the right" ), Maasha::XHTML::p( txt => 'Zoom in:' ), Maasha::XHTML::submit( name => "zoom_in1", value => "1.5x" ), Maasha::XHTML::submit( name => "zoom_in2", value => "3x" ), Maasha::XHTML::submit( name => "zoom_in3", value => "10x" ), Maasha::XHTML::p( txt => 'Zoom out:' ), Maasha::XHTML::submit( name => "zoom_out1", value => "1.5x" ), Maasha::XHTML::submit( name => "zoom_out2", value => "3x" ), Maasha::XHTML::submit( name => "zoom_out3", value => "10x" ), ] ); push @html, Maasha::XHTML::table_end; return wantarray ? @html : \@html; } sub sec_browse { my ( $dbh, # Database handle $start, # Browse start position $end, # Browse end position ) = @_; # Returns a list. my ( $t0, $t1, $ruler, $index, $index_beg, $index_len, $fh, $seq, $dna, $table, $entries, $features, $surface, $cr, $file, @html ); $ruler = Maasha::KISS::Track::track_ruler( 1200, 25, $start, $end ); $index = Maasha::Fasta::index_retrieve( "$ENV{ 'BP_DATA' }/genomes/S_aur_COL/fasta/S_aur_COL.index" ); ( $index_beg, $index_len ) = @{ $index->{ 'S_aur_COL' } }; $fh = Maasha::Filesys::file_read_open( "$ENV{ 'BP_DATA' }/genomes/S_aur_COL/fasta/S_aur_COL.fna" ); $seq = Maasha::Filesys::file_read( $fh, $index_beg + $start, $end - $start + 1 ); close $fh; $dna = Maasha::KISS::Track::track_seq( 1200, 50, $seq ) if length $seq <= 220; $table = 'Solexa'; $t0 = Time::HiRes::gettimeofday(); $entries = Maasha::KISS::IO::kiss_sql_get( $dbh, $table, $start, $end ); $t1 = Time::HiRes::gettimeofday(); push @html, Maasha::XHTML::p( txt => "Feature count: " . Maasha::Calc::commify( scalar @$entries ) ); push @html, Maasha::XHTML::p( txt => "Time SQL: " . ( $t1 - $t0 ) ); $t0 = Time::HiRes::gettimeofday(); my $MAX = 4000; # FIXME should depend on height of track as well if ( @$entries > $MAX ) { $features = Maasha::KISS::Track::track_histogram( 1200, 75, $start, $end, $entries ); } else { $features = Maasha::KISS::Track::track_feature( 1200, 75, $start, $end, $entries ); } $t1 = Time::HiRes::gettimeofday(); # push @html, Maasha::KISS::Draw::hdump( $entries ); # push @html, Maasha::KISS::Draw::hdump( $features ); push @html, Maasha::XHTML::p( txt => "Time Track: " . ( $t1 - $t0 ) ); $file = "fisk.png"; $surface = Cairo::ImageSurface->create( 'argb32', 1200, 800 ); $cr = Cairo::Context->create( $surface ); $t0 = Time::HiRes::gettimeofday(); Maasha::KISS::Draw::track_text( $cr, $ruler, "black" ) if $ruler; Maasha::KISS::Draw::track_text( $cr, $dna, "black" ) if $dna; Maasha::KISS::Draw::track_feature( $cr, $features, 'green' ) if $features; Maasha::KISS::Draw::file_png( $surface, $file ); $t1 = Time::HiRes::gettimeofday(); push @html, Maasha::XHTML::p( txt => "Time Draw: " . ( $t1 - $t0 ) ); push @html, Maasha::XHTML::p( txt => Maasha::XHTML::img( src => $file, alt => "Browser Tracks", height => 800, width => 1200, class => "foo", id => "pix_id", usemap => "map" ) ); return wantarray ? @html : \@html; } sub nav_list_clade { my ( $list_clade ); $list_clade = [ qw( Eukaryote Bacillus Fish ) ]; return wantarray ? @{ $list_clade } : $list_clade; } sub nav_list_genome { my ( $list_genome ); $list_genome = [ qw( S.aur_COL E.col B.sub ) ]; return wantarray ? @{ $list_genome } : $list_genome; } sub nav_list_assembly { my ( $list_assembly ); $list_assembly = [ qw( 2008-02-21 2009-01-23 ) ]; return wantarray ? @{ $list_assembly } : $list_assembly; } sub nav_list_contig { my ( $list_contig ); $list_contig = [ qw( chr1 chr2 ) ]; return wantarray ? @{ $list_contig } : $list_contig; } sub nav_zoom { my ( $cgi, # CGI object ) = @_; my ( $start, $end, $dist, $new_dist, $dist_diff, $new_start, $new_end ); if ( defined $cgi->param( 'nav_start' ) and $cgi->param( 'nav_end' ) ) { $start = $cgi->param( 'nav_start' ); $end = $cgi->param( 'nav_end' ); $start =~ tr/,//d; $end =~ tr/,//d; $dist = $end - $start; if ( defined $cgi->param( 'zoom_in1' ) ) { $new_dist = $dist / 1.5; } elsif ( defined $cgi->param( 'zoom_in2' ) ) { $new_dist = $dist / 3; } elsif ( defined $cgi->param( 'zoom_in3' ) ) { $new_dist = $dist / 10; } elsif ( defined $cgi->param( 'zoom_out1' ) ) { $new_dist = $dist * 1.5; } elsif ( defined $cgi->param( 'zoom_out2' ) ) { $new_dist = $dist * 3; } elsif ( defined $cgi->param( 'zoom_out3' ) ) { $new_dist = $dist * 10; } if ( $new_dist ) { $dist_diff = $dist - $new_dist; $new_start = int( $start + ( $dist_diff / 2 ) ); $new_end = int( $end - ( $dist_diff / 2 ) ); $cgi->param( 'nav_start', $new_start ); $cgi->param( 'nav_end', $new_end ); } } } sub nav_move { my ( $cgi, # CGI object $max, # Max end position ) = @_; my ( $start, $end, $dist, $shift, $new_start, $new_end ); if ( defined $cgi->param( 'nav_start' ) and $cgi->param( 'nav_end' ) ) { $start = $cgi->param( 'nav_start' ); $end = $cgi->param( 'nav_end' ); $start =~ tr/,//d; $end =~ tr/,//d; $dist = $end - $start; if ( defined $cgi->param( 'move_left1' ) ) { $shift = -1 * $dist * 0.10; } elsif ( defined $cgi->param( 'move_left2' ) ) { $shift = -1 * $dist * 0.475; } elsif ( defined $cgi->param( 'move_left3' ) ) { $shift = -1 * $dist * 0.95; } elsif ( defined $cgi->param( 'move_right1' ) ) { $shift = $dist * 0.10; } elsif ( defined $cgi->param( 'move_right2' ) ) { $shift = $dist * 0.475; } elsif ( defined $cgi->param( 'move_right3' ) ) { $shift = $dist * 0.95; } if ( $shift ) { $new_start = int( $start + $shift ); $new_end = int( $end + $shift ); print "HERRRR: shift: $shift start: $new_start end: $new_end\n"; if ( $new_start > 0 and $new_end < $max ) { $cgi->param( 'nav_start', $new_start ); $cgi->param( 'nav_end', $new_end ); } } } } sub nav_def_clade { my ( $cgi, # CGI object ) = @_; my ( $def_clade ); if ( defined $cgi->param( 'nav_clade' ) ) { $def_clade = $cgi->param( 'nav_clade' ); } else { $def_clade = "Bacteria"; } return $def_clade; } sub nav_def_genome { my ( $cgi, # CGI object ) = @_; my ( $def_genome ); if ( defined $cgi->param( 'nav_genome' ) ) { $def_genome = $cgi->param( 'nav_genome' ); } else { $def_genome = "S.aur_COL"; } return $def_genome; } sub nav_def_assembly { my ( $cgi, # CGI object ) = @_; my ( $def_assembly ); if ( defined $cgi->param( 'nav_assembly' ) ) { $def_assembly = $cgi->param( 'nav_assembly' ); } else { $def_assembly = "2009-01-23"; } return $def_assembly; } sub nav_def_contig { my ( $cgi, # CGI object ) = @_; my ( $def_contig ); if ( defined $cgi->param( 'nav_contig' ) ) { $def_contig = $cgi->param( 'nav_contig' ); } else { $def_contig = "chr1"; } return $def_contig; } sub nav_def_start { my ( $cgi, # CGI object ) = @_; my ( $def_start ); if ( defined $cgi->param( 'nav_start' ) ) { $def_start = $cgi->param( 'nav_start' ); } else { $def_start = 1; } $def_start =~ tr/,//d; if ( $def_start <= 0 ) { $def_start = 1; } $cgi->param( 'nav_start', $def_start ); return $def_start; } sub nav_def_end { my ( $cgi, # CGI object ) = @_; my ( $def_end ); if ( defined $cgi->param( 'nav_end' ) ) { $def_end = $cgi->param( 'nav_end' ); } else { $def_end = 2809422; $def_end = 2000; } $def_end =~ tr/,//d; if ( $def_end > 2809422 ) { $def_end = 2809422; } $cgi->param( 'nav_end', $def_end ); return $def_end; } # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< END { Maasha::SQL::disconnect( $dbh ) if $dbh; } __END__