#!/usr/bin/perl -w
use strict;
use Mysql;

$| = 1;
################################################################
# Purpose: To determine an approximate gene expression value for one or more genes in a 
# deep sequencing sample.  Briefly isoforms for each gene within the UCSC genome browser annotation are flattened:
# overlapping exons of different isoforms are consolidated into a larger exon.  The sum of the read coverage within 
# consolidated exons is divided by the sum of all exon lengths.
#
# Input Files: a gene annotation file from UCSC, and uc to gs file which converts a mm9.kgAlias.kgID to a mm9.kgXref.geneSymbol ID.
# Input Arguments: filename tablename experiment timepoint
# All arguments are required.  The filename value is purely for output file creation, while the others are necessary for mysql data access.
# Other Requirements: SAM formatted read alignments in a mysql database (DB)
# Last Updated: 20120902
# Correspondence: All inquiries should be addressed to rosbash @ brandeis.edu.  Script is provided as is.
# Brandeis University Waltham, MA
#################################################################

my $annotationfile = "exonmm.txt";	 	# Tab delimited text fileText file containing gene annotation from the UCSC genome.ucsc.edu tables
my $uctogenefile = "uc_to_gs.txt"; 		# Text file containing mm9.kgAlias.kgID to a mm9.kgXref.geneSymbol ID conversions
my $filename = $ARGV[0]; 			# output filename
my $tablename = $ARGV[1]; 			# table in the mysql DB
my $exp = $ARGV[2]; 				# experiment field of table in  mysql DB
my $tp = $ARGV[3]; 				# timepoint field of table in mysql DB

#MYSQL CONFIG VARIABLES
my $host = ""; 					# host
my $database = ""; 				# DB
my $user = ""; 					# username
my $pw = ""; 					# password
# SELECT DB
my $connect = Mysql->connect($host, $database, $user, $pw);
$connect->selectdb($database);

#Splitting job by chromosome for memory considerations
my @chrs = qw(chr1 chr10 chr11 chr12 chr13 chr13_random chr14 chr15 chr16 chr17 chr17_random chr18 chr19 chr1_random chr2 chr3 chr4 chr4_random chr5 chr5_random chr6 chr7 chr7_random chr8 chr8_random chr9 chr9_random chrM chrom chrUn_random chrX chrX_random chrY chrY_random);

foreach my $chr2analyze (@chrs){
open(FH,$uctogenefile) or die $!;
	my $uctogs = {};

	while(<FH>){
	chomp;
	my $line = $_;
		if(!($line =~ /^\#/)){
		my ($uc,$gs) = split(/\s+/,$line);
		$uctogs->{$uc} = $gs;
		}
	}
	close FH;

print "Starting Exons\n";
open(FH,$annotationfile) or die $!;
my $genes = {};
my $gisos = {};

	while(<FH>){
	chomp;
	my $line = $_;
		if(!($line =~ /^\#/)){
		my($uid,$chr,$strand,$txs,$txe,$sString,$eString) = (split(/\s+/,$line))[0,1,2,3,4,8,9];
		my @starts = split(/\,/,$sString);
		my @ends = split(/\,/,$eString);
		my $gs = $uctogs->{$uid};
			if($chr ne $chr2analyze){
			next;
			}
			for (my $i = 0; $i <= $#starts;$i++){
				for my $c ($starts[$i]..$ends[$i]){
				$genes->{$chr}->{$gs}->{$c} = {TYPE=>"E",READS=>0};
				}
			}
		}
	}

print "Starting Introns\n";
my $consgenes = {};
my $genebounds = {};
	foreach my $chr (keys %{$genes}){
		foreach my $gs (keys %{$genes->{$chr}}){
		my $prevc = 0;
		my $exS = 0;
		my ($txs,$txe) = (0,0);
			foreach my $c (sort {$a <=> $b} keys %{$genes->{$chr}->{$gs}}){
				if($prevc != 0){
					if ($c - $prevc > 1){ 
					my $exE = $prevc;
					my ($intS,$intE) = ($prevc + 1, $c - 1);
					$consgenes->{$chr}->{$gs}->{$exS} = {END=>$exE, TYPE => "EXON",READS=>0};
					$exS = $c; 
					}
				$prevc = $c;
				}
				else{
				$prevc = $c;
				$exS = $c;
				$txs = $c;
				}
			}
		my $exE = $prevc;
		$txe = $prevc;
		$consgenes->{$chr}->{$gs}->{$exS} = {END=>$exE, TYPE => "EXON",READS=>0};
		$genebounds->{$chr}->{$gs} = {txs=>$txs,txe=>$txe};
		}
	}

$genes = {};

print "DONE\t Search reads\n";
my $count = 0;
	foreach my $chr (keys %{$genebounds}){
		foreach my $gs (keys %{$genebounds->{$chr}}){
			foreach my $es (keys %{$consgenes->{$chr}->{$gs}}){
			my $ee = $consgenes->{$chr}->{$gs}->{$es}->{END};
			my ($esadj,$eeadj) = ($es - 80, $ee+80);	#No novel exons considered, looking locally				
			my ($txs,$txe) = ($genebounds->{$chr}->{$gs}->{txs},$genebounds->{$chr}->{$gs}->{txe});
			my $myquery1 = "SELECT * FROM " . $tablename . " WHERE experiment = '" . $exp . "' AND time = '" . $tp . "' AND chr = '" . $chr . "' AND coord BETWEEN '" . $esadj . "' AND '" . $eeadj . "'";
			my $execute1 = $connect->query($myquery1);
				while (my @results = $execute1->fetchrow()) {				
				my($chr,$start,$check,$seq) = @results[2,3,4,5];
				my @bases = split('',$seq);
				my $coord2base = {};
					if($check =~ /^(\d+)M$/){
						for (my $j = 0; $j <= $#bases; $j++){
						my $base = $bases[$j];	
						my $bp = $start + $j;
        					$coord2base->{$bp} = 1;
						}
					}
					elsif($check =~ /^(\d+)M(\d+)N(\d+)M$/){
					my($left,$span,$right) = ($1,$2,$3); 
						for (my $j = 0; $j <= $#bases; $j++){
							if($j < $left){
							my $bp = $start + $j;
        						$coord2base->{$bp} = 1;
							}
							elsif($j < ($left + $right)){
							my $bp = $start + $span + $j;
							$coord2base->{$bp} = 1;
							}
        					}
					}
					elsif($check =~ /^(\d+)M(\d+)N(\d+)M(\d+)N(\d+)M$/){
					my($left,$span1,$middle,$span2,$right) = ($1,$2,$3,$4,$5);
						for (my $j = 0; $j <= $#bases; $j++){
							if($j < $left){
							my $bp = $start + $j;
        						$coord2base->{$bp} = 1;
							}
							elsif($j < ($left + $middle)){
							my $bp = $start + $span1 + $j;
							$coord2base->{$bp} = 1;
							}
							elsif($j < ($left + $middle + $right)){
							my $bp = $start + $span1 + $span2 + $j;
							$coord2base->{$bp} = 1;
							}
        					}
					}
					elsif($check =~ /^(\d+)M(\d+)N(\d+)M(\d+)N(\d+)M(\d+)N(\d+)M$/){
					my($left,$span1,$middle1,$span2,$middle2,$span3,$right) = ($1,$2,$3,$4,$5,$6,$7);
						for (my $j = 0; $j <= $#bases; $j++){
							if($j < $left){
							my $bp = $start + $j;
        						$coord2base->{$bp} = 1;
							}
							elsif($j < ($left + $middle1)){
							my $bp = $start + $span1 + $j;
							$coord2base->{$bp} = 1;
							}
							elsif($j < ($left + $middle1 + $middle2)){
							my $bp = $start + $span1 + $span2 + $j;
							$coord2base->{$bp} = 1;
							}
							elsif($j < ($left + $middle1 + $middle2 + $right)){
							my $bp = $start + $span1 + $span2 + $span3 + $j;
							$coord2base->{$bp} = 1;
							}
        					}
					}
					else{
					#special cases
					next;
					}
					my $readstart = $start;
					my $readend = $start + $#bases + 1;
					foreach my $c (keys %{$coord2base}){
					my $found = 0;
						if(($c >= $es) && ($c<= $ee)){
						$consgenes->{$chr}->{$gs}->{$es}->{READS} += 1;
						}
					}
				}
			}
		}
	}
close FH;

my $outputfile = "$filename\.gsig\.$chr2analyze\.out";
open(OUT,">$outputfile") or die $!;
	foreach my $chr (keys %{$genebounds}){
		foreach my $gs (keys %{$genebounds->{$chr}}){
			my $exonsum = 0;
			my $exonlen = 0;
			my $found = 0;
			foreach my $s (keys %{$consgenes->{$chr}->{$gs}}){
			my $e = $consgenes->{$chr}->{$gs}->{$s}->{END};
			my $reads = $consgenes->{$chr}->{$gs}->{$s}->{READS};
			my $type = $consgenes->{$chr}->{$gs}->{$s}->{TYPE};
				if($type eq "EXON"){
				$exonsum += $reads;
				$exonlen += $e-$s + 1;
				}
			}
			
			my $exbpsig = $exonsum / $exonlen;
			if ($exbpsig > 0){
			my ($ts,$te) = ($genebounds->{$chr}->{$gs}->{txs}, $genebounds->{$chr}->{$gs}->{txe});	
			print OUT "$gs\t$chr\t$ts\t$te\t$exbpsig\n";
			}	
		}
	}
} #End job


