text:
package Genome::Model::Tools::Transcriptome::SpliceJunctionSummary;

use strict;
use warnings;

use Genome;
#use Bio::DB::Sam;

class Genome::Model::Tools::Transcriptome::SpliceJunctionSummary {
    is => ['Genome::Model::Tools::Transcriptome::Base'],
    has_input => [
        output_directory => {
            is => 'Text',
            doc => 'The output directory where splice junction files are output.',
        },
        observed_junctions_bed12_file => {
            is => 'Text',
            doc => 'A BED12 format file of splice junctions.  Each junction has two blocks.',
        },
        reference_fasta_file => {
            is => 'Text',
            doc => 'The FASTA format reference sequence file.  The reference FASTA must be compatible with the annotation GTF file.',
        },
        annotation_gtf_file => {
            is => 'Text',
            doc => 'The GTF format annotation file used to annotate the observed junctions and determine if observed juctions match known junctions.',
        },
        annotation_name => {
            is => 'Text',
            doc => 'The name of the annotation used.  This name is also used as a basename for the output file.',
        },
        bedtools_version => {
            is => 'Text',
            is_optional => 1,
            doc => 'The version of the BEDTools software to be used.',
            default_value => Genome::Model::Tools::BedTools->default_bedtools_version,
        },
    ],
    has_output => [
        observed_junctions_bed6_file => {
            is => 'Text',
            doc => 'The output BED6 format file of observed splice junctions.',
            is_optional => 1,
        },
        annotation_genes_bed12_file => {
            is => 'Text',
            doc => 'The output BED12 format file of Gene annotation.',
            is_optional => 1,
        },
        known_junctions_bed6_file => {
            is => 'Text',
            doc => 'The output BED6 format file of known splice junctions.',
            is_optional => 1,
        },
        known_junctions_tsv_file => {
            is => 'Text',
            doc => 'The output TSV format file of known splice junctions.',
            is_optional => 1,
        },
        annotation_exons_bed6_file => {
            is => 'Text',
            doc => 'The output BED6 format file of Exon annotation.',
            is_optional => 1,
        },
        annotation_merged_exon_bed_file => {
            is => 'Text',
            doc => 'The output BED format file of merged Exon annotation.',
            is_optional => 1,
        },
        annotated_observed_junction_tsv_file => {
            is => 'Text',
            doc => 'The output TSV format file that contains annotated information about each observed splice junction.',
            is_optional => 1,
        },
        transcript_expression_tsv_file => {
            is => 'Text',
            doc => 'The output TSV format file containing transcript level expression values using JPJM.',
            is_optional => 1,
        },
        gene_expression_tsv_file => {
            is => 'Text',
            doc => 'The output TSV format file containing gene level expression values using JPJM.',
            is_optional => 1,
        },
        _known_junctions => {is_optional => 1,},
        _known_donors => {is_optional => 1,},
        _known_acceptors => {is_optional => 1,},
        _known_ec_blocks => {is_optional => 1,},
        _observed_junctions => {is_optional => 1,},
        _faidx_index => {is_optional => 1,},
        _transcripts => {is_optional => 1,},
        _genes => {is_optional => 1,},
    ],
};

sub help_detail {
    return <<EOS
This tool will determine the splice sites for all observed and known splice junctions.
A comparison of observed versus known is performed including annotating with all observed junctions with exon, transcript and gene level information.
Expression of transcripts and genes is calculated using JPJM (see below for equation):
    JPJM = (sum of exon junction read counts for a gene / number of exon-exon junctions of that gene) => then normalized to per million junction mapped reads
Finally, an R script generates a summary spreadsheet with result R graphics written as PDF files.

EOS
}

sub execute {
    my $self = shift;

    $self->_resolve_output_file_paths();

    $self->_load_fasta_reference_index();

    $self->_map_transcript_and_gene_ids();

    $self->_generate_observed_junctions();

    # infer the splice site of each observed junction
    $self->infer_splice_site('observed_junctions');

    $self->_generate_known_junctions();

    # infer the splice sites of these known junctions
    $self->infer_splice_site('known_junctions');

    $self->_write_known_junction_splice_sites();

    $self->_generate_exon_content();

    #Now annotate observed exon-exon junctions against databases of known junctions by Gene Name(symbol)
    $self->annotate_observed_junctions();

    # Annotation based gene/transcript level expression calculations:
    $self->calculate_gene_expression();

    $self->generate_summary_and_plots();

    return 1;
}

sub _resolve_output_file_paths {
    my $self = shift;

    $self->observed_junctions_bed6_file($self->output_directory .'/observed.junctions.bed');
    $self->known_junctions_bed6_file($self->output_directory .'/'. $self->annotation_name.'.junctions.bed');
    $self->known_junctions_tsv_file($self->output_directory .'/'. $self->annotation_name.'.junctions.tsv');
    $self->annotation_genes_bed12_file($self->output_directory .'/'. $self->annotation_name.'.Genes.bed');
    $self->annotation_exons_bed6_file($self->output_directory .'/'. $self->annotation_name.'.Exons.bed');
    $self->annotation_merged_exon_bed_file($self->output_directory .'/'. $self->annotation_name .'.ExonContent.bed');
    $self->annotated_observed_junction_tsv_file($self->output_directory .'/observed.junctions.anno.'. $self->annotation_name .'.tsv');
    $self->transcript_expression_tsv_file($self->output_directory .'/'. $self->annotation_name .'.Junction.TranscriptExpression.tsv');
    $self->gene_expression_tsv_file($self->output_directory .'/'. $self->annotation_name .'.Junction.GeneExpression.tsv');
    return 1;
}

sub _write_known_junction_splice_sites {
    my $self = shift;

    my $headers = Genome::Utility::IO::BedReader->default_headers;
    my @known_junctions_headers = @$headers;
    push @known_junctions_headers, ('splice_site','intron_size');
    my $known_junctions_tsv_writer = Genome::Utility::IO::SeparatedValueWriter->create(
        output => $self->known_junctions_tsv_file,
        separator => "\t",
        headers => \@known_junctions_headers,
        print_headers => 1,
    );
    my $known_junctions = $self->_known_junctions;
    my %known_junctions = %{$known_junctions};
    my @sorted_known_junction_ids = sort { $known_junctions{$a}->{order} <=> $known_junctions{$b}->{order} } keys %known_junctions;
    for my $known_junction_id (@sorted_known_junction_ids) {
        my $data = $known_junctions{$known_junction_id};
        delete($data->{order});
        $known_junctions_tsv_writer->write_one($data);
    }
    $known_junctions_tsv_writer->output->close;
    return 1;
}

sub _load_fasta_reference_index {
    my $self = shift;
    my $fai = Bio::DB::Sam::Fai->load($self->reference_fasta_file);
    unless ($fai) {
        die('Could not open faidx for fasta file : '. $self->reference_fasta_file);
    }
    $self->_faidx_index($fai);
    return 1;
}

sub _map_transcript_and_gene_ids {
    my $self = shift;
    my $annotation_gtf_file = $self->annotation_gtf_file;

    $self->debug_message('Importing gene, gene name, and transcript mappings from: '. $annotation_gtf_file);
    my $gff_reader = Genome::Utility::IO::GffReader->create(
        input => $annotation_gtf_file,
    );
    unless ($gff_reader) {
        $self->error_message('Failed to load annotation GTF file: '. $annotation_gtf_file);
        die($self->error_message);
    }
    my %genes;
    my %transcripts;
    while (my $data = $gff_reader->next_with_attributes_hash_ref) {
        my $attributes = delete($data->{attributes_hash_ref});
        my $transcript_id = $attributes->{transcript_id};
        my $gene_id = $attributes->{gene_id};
        my $gene_name = $attributes->{gene_name};
        if ( $transcripts{$transcript_id} ) {
            unless ($gene_id eq $transcripts{$transcript_id}{ensg_id}) {
                die('Multiple gene_ids '. $gene_id .' and '. $transcripts{$transcript_id}{ensg_id} .' found for transcript: '. $transcript_id);
            }
            unless ($gene_name eq $transcripts{$transcript_id}{name}) {
                die('Multiple gene_names '. $gene_name .' and '. $transcripts{$transcript_id}{name} .' found for transcript: '. $transcript_id);
            }
        } else {
            $transcripts{$transcript_id}{ensg_id} = $gene_id;
            $transcripts{$transcript_id}{name} = $gene_name;
        }
        if ( $genes{$gene_id} ) {
            unless ($gene_id eq $genes{$gene_id}{ensg_id}) {
                die('Multiple gene_ids '. $gene_id .' and '. $genes{$gene_id}{ensg_id} .' found for gene: '. $gene_id);
            }
            unless ($gene_name eq $genes{$gene_id}{name}) {
                die('Multiple gene_names '. $gene_name .' and '. $genes{$gene_id}{name} .' found for gene: '. $gene_id);
            }
        } else {
            $genes{$gene_id}{ensg_id} = $gene_id;
            $genes{$gene_id}{name} = $gene_name;
        }
    }
    $gff_reader->input->close;
    $self->_transcripts(\%transcripts);
    $self->_genes(\%genes);
    return 1;
}

sub _generate_observed_junctions {
    my $self = shift;

    # Covert BED12 format to BED6 junctions
    my $tmp_junctions_bed6_file = Genome::Sys->create_temp_file_path;
    unless ( Genome::Model::Tools::Bed::ToBedJunc->execute(
        bed12_file => $self->observed_junctions_bed12_file,
        bed_file => $tmp_junctions_bed6_file,
    )->result ) {
        $self->error_message('Failed to convert BED12 file \''. $self->observed_junctions_bed12_file .'\' to junctions BED file \''. $tmp_junctions_bed6_file .'\'');
        die($self->error_message);
    }

    # Sort the BED6 file
    $self->debug_message('Sorting merged BED6 junctions to file: '. $self->observed_junctions_bed6_file);
    unless (Genome::Model::Tools::BedTools::Sort->execute(
        input_file => $tmp_junctions_bed6_file,
        output_file => $self->observed_junctions_bed6_file,
        use_version => $self->bedtools_version,
    )->result) {
        $self->error_message('Failed to sort tmp junctions BED file \''. $tmp_junctions_bed6_file .'\' to \''. $self->observed_junctions_bed6_file .'\'');
        die($self->error_message);
    }

    # Load the observed junctions
    $self->debug_message('Loading the sorted and merged observed junctions: '. $self->observed_junctions_bed6_file);
    my $observed_junctions_bed6_reader = Genome::Utility::IO::BedReader->create(
        input => $self->observed_junctions_bed6_file,
    );
    my %observed_junctions;
    my $observed_order = 0;
    while (my $junction_data = $observed_junctions_bed6_reader->next) {
        my $key = $junction_data->{chr} .':'. $junction_data->{start} .'-'. $junction_data->{end} .'('. $junction_data->{strand} .')';
        $junction_data->{order} = $observed_order++;
        $observed_junctions{$key} = $junction_data;
    }
    $observed_junctions_bed6_reader->input->close;
    $self->_observed_junctions(\%observed_junctions);
    return 1;
}

sub _generate_known_junctions {
    my $self = shift;

    # Generate BED12 format genes file
    $self->debug_message('Convert annotation GTF \''. $self->annotation_gtf_file .'\' to BED12 format genes file \''. $self->annotation_genes_bed12_file .'\'');
    unless (Genome::Model::Tools::Gtf::ToBed12->execute(
        gtf_file => $self->annotation_gtf_file,
        bed12_file => $self->annotation_genes_bed12_file,
    )->result) {
        $self->error_message('Failed to generate BED12 format genes file: '. $self->annotation_genes_bed12_file);
        die($self->error_message);
    }

    # Make a BED6 junctions file from the BED12 genes file
    my $tmp_known_junctions_bed_file = Genome::Sys->create_temp_file_path($self->annotation_name.'.junctions.bed');
    $self->debug_message('Convert BED12 genes file \''. $self->annotation_genes_bed12_file .'\' to temporary BED6 format file of known junctions \''. $tmp_known_junctions_bed_file .'\'');
    unless (Genome::Model::Tools::Bed::ToBedJunc->execute(
        bed12_file => $self->annotation_genes_bed12_file,
        bed_file => $tmp_known_junctions_bed_file,
    )->result ) {
        $self->error_message('Failed to convert BED12 file \''. $self->annotation_genes_bed12_file .'\' to unosrted BED6 junctions file \''. $tmp_known_junctions_bed_file .'\'');
        die($self->error_message);
    }

    # Key on chr:start-end(strand) and sum the score as a count of transcripts
    $self->debug_message('Load the BED6 known junctions file \''. $tmp_known_junctions_bed_file .'\' and count transcripts observed per junction.');
    my $known_junctions_bed_reader = Genome::Utility::IO::BedReader->create(
        input => $tmp_known_junctions_bed_file,
    );
    unless ($known_junctions_bed_reader) {
        $self->error_message('Failed to load known junctions BED6 reader for unsorted temporary known junctions: '. $tmp_known_junctions_bed_file);
        die($self->error_message);
    }
    my %unordered_known_junctions;
    while (my $data = $known_junctions_bed_reader->next) {
        # TODO: Should known junction transcript counts enforce strandedness?
        my $key = $data->{chr} .':'. $data->{start} .'-'. $data->{end} .'('. $data->{strand} .')';
        unless ($unordered_known_junctions{$key}) {
            $unordered_known_junctions{$key} = $data;
        } else {
            $unordered_known_junctions{$key}->{name} .= ','. $data->{name};
            $unordered_known_junctions{$key}->{score}++;
        }
    }

    # Write out the unique known junctions in BED6 format
    my $tmp_unsorted_known_junctions_bed_file = Genome::Sys->create_temp_file_path($self->annotation_name.'.unsorted.junctions.bed');
    $self->debug_message('Writing unique known junctions as unsorted BED6 file: '. $tmp_unsorted_known_junctions_bed_file);
    my $unsorted_known_junctions_bed_writer = Genome::Utility::IO::BedWriter->create(
        output => $tmp_unsorted_known_junctions_bed_file,
    );
    for my $key (keys %unordered_known_junctions) {
        $unsorted_known_junctions_bed_writer->write_one($unordered_known_junctions{$key});
    }
    $unsorted_known_junctions_bed_writer->output->close;

    # Sort BED6
    $self->debug_message('Sorting BED6 known junctions to file: '. $self->known_junctions_bed6_file);
    unless (Genome::Model::Tools::BedTools::Sort->execute(
        input_file => $tmp_unsorted_known_junctions_bed_file,
        output_file => $self->known_junctions_bed6_file,
        use_version => $self->bedtools_version,
    )->result) {
        $self->error_message('Failed to sort known junctions BED6 file \''. $tmp_unsorted_known_junctions_bed_file .'\' to \''. $self->known_junctions_bed6_file.'\'');
        die($self->error_message);
    }

    # Load the known junctions
    $self->debug_message('Loading the sorted known junctions: '. $self->known_junctions_bed6_file);
    my $sorted_known_junctions_bed6_reader = Genome::Utility::IO::BedReader->create(
        input => $self->known_junctions_bed6_file,
    );

    my $transcripts = $self->_transcripts;
    my %known_junctions;
    my %known_donors;
    my %known_acceptors;
    my $known_order = 0;
    while (my $junction_data = $sorted_known_junctions_bed6_reader->next) {
        my $key = $junction_data->{chr} .':'. $junction_data->{start} .'-'. $junction_data->{end} .'('. $junction_data->{strand} .')';
        $junction_data->{order} = $known_order++;
        $known_junctions{$key} = $junction_data;

        my $transcript_ids = $junction_data->{name};
        my $chr = $junction_data->{chr};
        my $strand = $junction_data->{strand};
        my $start = $junction_data->{start};
        my $end = $junction_data->{end};
        if ($strand eq '+'){
            $known_donors{$chr}{$strand}{$start}{transcript_ids} = $transcript_ids;
            $known_acceptors{$chr}{$strand}{$end}{transcript_ids} = $transcript_ids;
        } elsif($strand eq '-'){
            $known_donors{$chr}{$strand}{$end}{transcript_ids} = $transcript_ids;
            $known_acceptors{$chr}{$strand}{$start}{transcript_ids} = $transcript_ids;
        } else{
            $self->error_message('Unknown strand in reference junctions file.');
            die($self->error_message);
        }
    }
    $sorted_known_junctions_bed6_reader->input->close;
    $self->_known_junctions(\%known_junctions);
    $self->_known_donors(\%known_donors);
    $self->_known_acceptors(\%known_acceptors);
    return 1;
}

sub _generate_exon_content {
    my $self = shift;

    # Generate BED6 format Exons file
    $self->debug_message('Convert BED12 format gene file \''. $self->annotation_genes_bed12_file .'\' to exon BED6 file \''. $self->annotation_exons_bed6_file);
    # TODO: Add BedTools version
    unless (Genome::Model::Tools::BedTools::Bed12ToBed6->execute(
        input_bed12_file => $self->annotation_genes_bed12_file,
        output_bed6_file => $self->annotation_exons_bed6_file,
        use_version => $self->bedtools_version,
    )->result) {
        $self->error_message('Failed to generate BED6 format exons file: '. $self->annotation_exons_bed6_file);
        die($self->error_message);
    }
    # Generate Exon Content BED6 format file
    $self->debug_message('Merge exon BED6 file to \''. $self->annotation_merged_exon_bed_file .'\'');
    # TODO: Add BedTools version
    unless (Genome::Model::Tools::BedTools::Merge->execute(
        input_file => $self->annotation_exons_bed6_file,
        output_file => $self->annotation_merged_exon_bed_file,
        force_strandedness => 1,
        report_number => 1,
        use_version => $self->bedtools_version,
    )->result) {
        $self->error_message('Failed to generate merged exon BED6 format file: '. $self->annotation_merged_exon_bed_file);
        die($self->error_message);
    }
    $self->import_exon_content_blocks();

    return 1;
}

############################################################################################################################
#Infer strand from alignment to reference genome                                                                           #
############################################################################################################################
sub infer_splice_site {
    my $self = shift;
    my $junctions_type = shift;
    my $junctions_hash_ref_method =  '_'. $junctions_type;

    my $junctions_hash_ref = $self->$junctions_hash_ref_method;
    my $fai = $self->_faidx_index;

    #Determine the splice site by comparison back to the reference genome...
    $self->debug_message('Determining splice sites from reference for '. $junctions_type);

    #Now go through the junctions and look for donor/acceptor splice sites at the coordinates reported
    #SPLICE_SITES = ["GT-AG", "CT-AC", "GC-AG", "CT-GC", "AT-AC", "GT-AT"]
    for my $junc_key (keys %{$junctions_hash_ref}) {
        my $junc_data = $junctions_hash_ref->{$junc_key};

        my $j_chr = $junc_data->{chr};
        my $left = $junc_data->{start};
        my $right = $junc_data->{end};

        my $intron_size = ($right - $left) + 1;
        $junc_data->{intron_size} = $intron_size;

        my $left_seq_id = $j_chr .':'. ($left + 1) .'-'. ($left+2);
        my $left_dn = uc($fai->fetch($left_seq_id));
        unless (length($left_dn) == 2) {
            die('Invalid sequence length for left seq_id '. $left_seq_id);
        }
        my $right_seq_id = $j_chr .':'. ($right-2) .'-'. ($right-1);
        my $right_dn = uc($fai->fetch($right_seq_id));
        unless (length($right_dn) == 2) {
            die('Invalid sequence length for right seq_id '. $right_seq_id);
        }
        # Strand is assigned by the aligner...
        # TODO: Is the strand in the junction key ex. chr:start-end(strand)
        # TODO: Could we determine the correctness of the donor/acceptor if we know the strand already
        my $splice_site;
        if ($left_dn eq "GT" && $right_dn eq "AG"){
            $splice_site = "GT-AG";
        } elsif($left_dn eq "CT" && $right_dn eq "AC"){
            $splice_site = "GT-AG";
        } elsif($left_dn eq "GC" && $right_dn eq "AG"){
            $splice_site = "GC-AG";
        } elsif($left_dn eq "CT" && $right_dn eq "GC"){
            $splice_site = "GC-AG";
        } elsif($left_dn eq "AT" && $right_dn eq "AC"){
            $splice_site = "AT-AC";
        } elsif($left_dn eq "GT" && $right_dn eq "AT"){
            $splice_site = "AT-AC";
        } else {
            $splice_site = "Other";
        }
        $junc_data->{splice_site} = $splice_site;
    }
    $self->debug_message('Finished infering splice sites for '. $junctions_type);
    $self->$junctions_hash_ref_method($junctions_hash_ref);
    return 1;
}

sub import_exon_content_blocks {
    my $self = shift;

    $self->debug_message('Importing reference exon content blocks from file: '. $self->annotation_merged_exon_bed_file);
    my %known_ec_blocks;
    #Import the ref exon content block file.  In this file, the coordinates are always ordered regardless of strand
    #i.e. the 'left' coordinate is always a smaller number than the 'right' coordinate
    my $exon_reader = Genome::Utility::IO::BedReader->create(
        input => $self->annotation_merged_exon_bed_file,
        # After mergeBed the names are replaced by the count or score
        headers => ['chr','start','end','score','strand'],
    );
    my $exon_count = 0;
    while (my $exon_data = $exon_reader->next) {
        $exon_count++;
        if ($known_ec_blocks{$exon_data->{chr}}{$exon_data->{strand}}){
            my $ec_ref = $known_ec_blocks{$exon_data->{chr}}{$exon_data->{strand}};
            $ec_ref->{$exon_count}->{left} = $exon_data->{start};
            $ec_ref->{$exon_count}->{right} = $exon_data->{end};
        } else {
            my %tmp;
            $tmp{$exon_count}{left} = $exon_data->{start};
            $tmp{$exon_count}{right} = $exon_data->{end};
            $known_ec_blocks{$exon_data->{chr}}{$exon_data->{strand}} = \%tmp;
        }
    }
    $exon_reader->input->close;
    $self->debug_message('Imported '. $exon_count .' known exon content blocks.');
    $self->_known_ec_blocks(\%known_ec_blocks);
    return 1;
}

sub annotate_observed_junctions {
    my $self = shift;

    my $observed_junctions = $self->_observed_junctions;
    my $known_junctions = $self->_known_junctions;
    my $known_donors = $self->_known_donors;
    my $known_acceptors = $self->_known_acceptors;

    my %observed_junctions = %{$observed_junctions};
    my %known_junctions = %{$known_junctions};
    my %known_donors = %{$known_donors};
    my %known_acceptors = %{$known_acceptors};

    for my $jid (keys %observed_junctions) {
        my $chr = $observed_junctions{$jid}->{chr};
        my $strand = $observed_junctions{$jid}->{strand};
        my $left = $observed_junctions{$jid}->{start};
        my $right = $observed_junctions{$jid}->{end};

        $observed_junctions{$jid}->{anchored} = 'N';
        $observed_junctions{$jid}->{transcript_ids} = 'na';
        #First check for an exact match to a known junction (i.e. anchored by both Donor and Acceptor)
        if ($known_junctions{$jid}){
            $observed_junctions{$jid}->{anchored} = 'DA';
            $observed_junctions{$jid}->{transcript_ids} = $known_junctions{$jid}{name};
        } else {
            #Now check for anchoring on one side only
            #    - If the Donor matches to a gene on the positive strand, the non matching Acceptor should have a higher chromosome coordinate
            #    - If the Donor matches to a gene on the negative strand, the non matching Acceptor should have a lower chromosome coordinate
            #    - If the Acceptor matches to a gene on the positive strand, the non-matching Donor should have a lower chromosome coordinate
            #    - If the Acceptor matches to a gene on the negative strand, the non-matching Donor should have a higher chromosome coordinate
            if ($strand eq '+'){
                if ( $known_donors{$chr}{'+'}{$left} && $known_acceptors{$chr}{'+'}{$right} ) {
                    $observed_junctions{$jid}->{anchored} = "NDA";
                    $observed_junctions{$jid}->{transcript_ids} = $known_donors{$chr}{'+'}{$left}{transcript_ids};
                } elsif ( $known_donors{$chr}{'+'}{$left} ){
                    $observed_junctions{$jid}->{anchored} = "D";
                    $observed_junctions{$jid}->{transcript_ids} = $known_donors{$chr}{'+'}{$left}{transcript_ids};
                } elsif ($known_acceptors{$chr}{'+'}{$right}) {
                    $observed_junctions{$jid}->{anchored} = "A";
                    $observed_junctions{$jid}->{transcript_ids} = $known_acceptors{$chr}{'+'}{$right}{transcript_ids};
                }
            } elsif ($strand eq '-') {
                if ( $known_donors{$chr}{'-'}{$right} && $known_acceptors{$chr}{'-'}{$left} ) {
                    $observed_junctions{$jid}->{anchored} = "NDA";
                    $observed_junctions{$jid}->{transcript_ids} = $known_donors{$chr}{'-'}{$right}{transcript_ids};
                } elsif ($known_donors{$chr}{'-'}{$right}) {
                    $observed_junctions{$jid}->{anchored} = "D";
                    $observed_junctions{$jid}->{transcript_ids} = $known_donors{$chr}{'-'}{$right}{transcript_ids};
                } elsif ($known_acceptors{$chr}{'-'}{$left}){
                    $observed_junctions{$jid}->{anchored} = "A";
                    $observed_junctions{$jid}->{transcript_ids} = $known_acceptors{$chr}{'-'}{$left}{transcript_ids};
                }
            }
        }
        #Initialize the skipping values
        my $anchored = $observed_junctions{$jid}->{anchored};
        if ($anchored eq 'N'){
            $observed_junctions{$jid}->{exons_skipped} = 'na';
            $observed_junctions{$jid}->{donors_skipped} = 'na';
            $observed_junctions{$jid}->{acceptors_skipped} = 'na';
        }else{
            $observed_junctions{$jid}->{exons_skipped} = 0;
            $observed_junctions{$jid}->{donors_skipped} = 0;
            $observed_junctions{$jid}->{acceptors_skipped} = 0;
        }
    }
    $self->_observed_junctions(\%observed_junctions);
    $self->annotate_skipping();

    #Calculate the junction read count per million junction reads mapped (JPM)
    my $grand_count = 0;
    $observed_junctions = $self->_observed_junctions();
    %observed_junctions = %{$observed_junctions};
    foreach my $jid (keys %observed_junctions){
        $grand_count += $observed_junctions{$jid}->{score};
    }
    foreach my $jid (keys %observed_junctions){
        my $jpm = $observed_junctions{$jid}->{score} * (1000000 / $grand_count);
        $observed_junctions{$jid}->{jpm} = $jpm;
    }

    my @output_headers = qw/chr start end name score strand jpm intron_size splice_site anchored exons_skipped donors_skipped acceptors_skipped transcript_ids gene_ids gene_names/;
    my $output_tsv_writer = Genome::Utility::IO::SeparatedValueWriter->create(
        output => $self->annotated_observed_junction_tsv_file,
        headers => \@output_headers,
        separator => "\t",
        print_headers => 1,
    );
    unless ($output_tsv_writer) {
        $self->error_message('Failed to load output TSV file: '. $self->annotated_observed_junction_tsv_file);
        die($self->error_message);
    }

    my $transcripts = $self->_transcripts;
    my %transcripts = %{$transcripts};
    my @sorted_junction_ids = sort {$observed_junctions{$a}->{order} <=> $observed_junctions{$b}->{order}} keys %observed_junctions;
    foreach my $jid (@sorted_junction_ids){
        my $data = $observed_junctions{$jid};
        delete($data->{order});
        my @transcript_ids = split(',',$data->{transcript_ids});
        my @gene_ids;
        my @gene_names;
        for my $transcript_id (@transcript_ids) {
            if ($transcript_id eq 'na') {
                push @gene_ids, 'na';
                push @gene_names, 'na';
            } else {
                push @gene_ids, $transcripts{$transcript_id}{ensg_id};
                push @gene_names, $transcripts{$transcript_id}{name};
            }
        }
        $data->{gene_ids} = join(',', @gene_ids);
        $data->{gene_names} = join(',', @gene_names);
        $output_tsv_writer->write_one($data);
    }
    $output_tsv_writer->output->close;

    $self->debug_message('Printed resulting annotated junctions to: '. $self->annotated_observed_junction_tsv_file);
    return;
}

##############################################################################################################################################
#Determine the exon and splice site skipping of each junction observed (if it known, or anchored to a known splice site at one or both ends) #
##############################################################################################################################################
sub annotate_skipping {
    my $self = shift;

    my $observed_junctions = $self->_observed_junctions();
    my $known_ec_blocks = $self->_known_ec_blocks();
    my $known_donors = $self->_known_donors();
    my $known_acceptors = $self->_known_acceptors();

    my %observed_junctions = %{$observed_junctions};
    my %known_ec_blocks = %{$known_ec_blocks};
    my %known_donors = %{$known_donors};
    my %known_acceptors = %{$known_acceptors};

    $self->debug_message('Annotating skipping of each junction - exons, then acceptors, then donors - Using BEDTools');

    #Use BEDTools to determine the exons, acceptors, or donors contained within each exon-exon observed junction (i.e. intron)
    #Do this by writing a temp BED file for each pair of coordinates (of the form: chr, start, end, strand) and then parsing the results file

    #'intersectBed -a exons.bed -b junctions.bed -f 1.0 -s -wa -wb'
    #The '-f 1.0' option should give the exons that are entirely overlapped by junctions
    #The '-s' option should make this overlap between things on the same strand
    #The '-wa -wb' options, write the original coordinates for exons and junctions (as opposed to the merged coordinates).  Each overlaping pair will be reported as a seperate line
    #Then process the output file and count the exon entries associated with each junction entry

    #Example BEDTools command
    #Run BEDTools as follows and 'cut' the column containing the junction ID value.
    #The occurence count for each of these IDs, should be the number of exons contained within the corresponding junction (i.e. skipped)
    #Unix sort and uniq can even do this counting for us...
    #Then just parse the counts out

    my $temp_obs_junctions = Genome::Sys->create_temp_file_path('ObsJunc.tmp.bed');
    my $temp_known_exons = Genome::Sys->create_temp_file_path('KnownExonContent.tmp.bed');
    my $temp_known_donors = Genome::Sys->create_temp_file_path('KnownDonors.tmp.bed');
    my $temp_known_acceptors = Genome::Sys->create_temp_file_path('KnownAcceptors.tmp.bed');
    my $temp_result = Genome::Sys->create_temp_file_path('Result.tmp.txt');

    #OBSERVED JUNCTIONS
    $self->debug_message('Looking for entire exons skipped');
    my $temp_obs_junction_writer = Genome::Utility::IO::BedWriter->create(
        output => $temp_obs_junctions,
    );
    unless ($temp_obs_junction_writer) {
        $self->error_message('Failed to open BED6 writer for temporary observed junctions: '. $temp_obs_junctions);
    }
    #Print print out the observed hmmSplicer junctions (i.e. introns as a temp bed file
    foreach my $jid (sort {$observed_junctions{$a}->{order} <=> $observed_junctions{$b}->{order}} keys %observed_junctions) {
        my %tmp_data = (
            'chr' => $observed_junctions{$jid}->{'chr'},
            'start' => $observed_junctions{$jid}->{'start'},
            'end' => $observed_junctions{$jid}->{'end'},
            'name' => $jid,
            'score' => '.',
            'strand' => $observed_junctions{$jid}->{'strand'},
        );
        $temp_obs_junction_writer->write_one(\%tmp_data);
    }
    $temp_obs_junction_writer->output->close;

    #ENTIRE EXONS
    #Print out all the known exon content blocks
    my $temp_known_exons_writer = Genome::Utility::IO::BedWriter->create(
        output => $temp_known_exons,
    );
    unless ($temp_known_exons_writer) {
        $self->error_message('Failed to open BED6 writer for temporary known exons: '. $temp_known_exons);
    }
    foreach my $chr (sort keys %known_ec_blocks){
        foreach my $strand (sort keys %{$known_ec_blocks{$chr}}){
            my $ec_ref = $known_ec_blocks{$chr}{$strand};
            foreach my $ec (sort {$ec_ref->{$a}->{left} <=> $ec_ref->{$b}->{left}} keys %{$ec_ref}){
                my $ec_left = $ec_ref->{$ec}->{left};
                my $ec_right = $ec_ref->{$ec}->{right};
                my %tmp_data = (
                    'chr' => $chr,
                    'start' => $ec_left,
                    'end' => $ec_right,
                    'name' => 'EC',
                    'score' => '.',
                    'strand' => $strand,
                );
                $temp_known_exons_writer->write_one(\%tmp_data);
            }
        }
    }
    $temp_known_exons_writer->output->close;

    my $temp_exons_intersect_bed = Genome::Sys->create_temp_file_path('intersect_exons_junctions.bed');
    unless (Genome::Model::Tools::BedTools::Intersect->execute(
        force_strandedness => 1,
        intersection_type => 'write_both',
        minimum_overlap => 1,
        input_file_a => $temp_known_exons,
        input_file_a_format => 'bed',
        input_file_b => $temp_obs_junctions,
        output_file => $temp_exons_intersect_bed,
        output_file_format => 'bed',
        use_version => $self->bedtools_version,
    )->result) {
        die('Failed to intersect exons and observed junctions.');
    }

    # TODO: Can this be made a command or performed with Perl inline
    my $exons_cmd = "cat $temp_exons_intersect_bed | cut -f 10 | sort | uniq -c > $temp_result";
    Genome::Sys->shellcmd(cmd => $exons_cmd);

    open (COUNTS, "$temp_result") || die "\n\nCould not open temp results file: $temp_result\n\n";
    while(<COUNTS>){
        chomp($_);
        if ($_ =~ /(\d+)\s+(.*)/){
            my $count = $1;
            my $jid = $2;
            if ($observed_junctions{$jid}){
                my $anchored = $observed_junctions{$jid}->{anchored};
                unless ($anchored eq "N"){
                    $observed_junctions{$jid}->{exons_skipped} = $count;
                }
            }else{
                $self->error_message('Unrecognized junction id:'. $jid);
                die($self->error_message);
            }
        }else{
            $self->error_message('Entry in results file not understood: '. $_);
            die($self->error_message);
        }
    }
    close(COUNTS);

    #DONORS
    $self->debug_message('Looking for donors skipped');
    my $temp_known_donors_writer = Genome::Utility::IO::BedWriter->create(
        output => $temp_known_donors,
    );
    unless ($temp_known_donors_writer) {
        $self->error_message('Failed to open BED6 writer for temporary known donors: '. $temp_known_donors);
    }
    foreach my $chr (sort keys %known_donors){
        foreach my $strand (sort keys %{$known_donors{$chr}}){
            foreach my $donor (sort keys %{$known_donors{$chr}{$strand}}){
                my $donor_p = $donor+1;
                my %tmp_data = (
                    'chr' => $chr,
                    'start' => $donor,
                    'end' => $donor_p,
                    'name' => 'D',
                    'score' => '.',
                    'strand' => $strand,
                );
                $temp_known_donors_writer->write_one(\%tmp_data);
            }
        }
    }
    $temp_known_donors_writer->output->close;

    my $temp_donors_intersect_bed = Genome::Sys->create_temp_file_path('intersect_donors_junctions.bed');
    unless (Genome::Model::Tools::BedTools::Intersect->execute(
        force_strandedness => 1,
        intersection_type => 'write_both',
        minimum_overlap => 1,
        input_file_a => $temp_known_donors,
        input_file_a_format => 'bed',
        input_file_b => $temp_obs_junctions,
        output_file => $temp_donors_intersect_bed,
        output_file_format => 'bed',
        use_version => $self->bedtools_version,
    )->result) {
        die('Failed to intersect donors and observed junctions.');
    }

    # TODO: Can this be made a command or performed with Perl inline
    my $donors_cmd = "cat $temp_donors_intersect_bed | cut -f 10 | sort | uniq -c > $temp_result";
    Genome::Sys->shellcmd(cmd => $donors_cmd);

    open (COUNTS, "$temp_result") || die "\n\nCould not open temp results file: $temp_result\n\n";
    while(<COUNTS>){
        chomp($_);
        if ($_ =~ /(\d+)\s+(.*)/){
            my $count = $1;
            my $jid = $2;
            if ($observed_junctions{$jid}){
                my $anchored = $observed_junctions{$jid}->{anchored};
                unless ($anchored eq "N"){
                    $observed_junctions{$jid}->{donors_skipped} = $count;
                }
            }else{
                $self->error_message('Unrecognized junction id:'. $jid);
                die($self->error_message);
            }
        }else{
            $self->error_message('Entry in results file not understood:'. $_);
            die($self->error_message);
        }
    }
    close(COUNTS);

    #ACCEPTORS
    $self->debug_message('Looking for acceptors skipped');
    my $temp_known_acceptors_writer = Genome::Utility::IO::BedWriter->create(
        output => $temp_known_acceptors,
    );
    unless ($temp_known_acceptors_writer) {
        $self->error_message('Failed to open BED6 writer for temporary known acceptors: '. $temp_known_acceptors);
    }
    foreach my $chr (sort keys %known_acceptors){
        foreach my $strand (sort keys %{$known_acceptors{$chr}}){
            foreach my $acceptor (sort keys %{$known_acceptors{$chr}{$strand}}){
                my $acceptor_p = $acceptor+1;
                my %tmp_data = (
                    'chr' => $chr,
                    'start' => $acceptor,
                    'end' => $acceptor_p,
                    'name' => 'A',
                    'score' => '.',
                    'strand' => $strand,
                );
                $temp_known_acceptors_writer->write_one(\%tmp_data);
            }
        }
    }
    $temp_known_acceptors_writer->output->close;

    my $temp_acceptors_intersect_bed = Genome::Sys->create_temp_file_path('intersect_acceptors_junctions.bed');
    unless (Genome::Model::Tools::BedTools::Intersect->execute(
        force_strandedness => 1,
        intersection_type => 'write_both',
        minimum_overlap => 1,
        input_file_a => $temp_known_acceptors,
        input_file_a_format => 'bed',
        input_file_b => $temp_obs_junctions,
        output_file => $temp_acceptors_intersect_bed,
        output_file_format => 'bed',
        use_version => $self->bedtools_version,
    )->result) {
        die('Failed to intersect acceptors and observed junctions.');
    }

    # TODO: Can this be made a command or performed with Perl inline
    my $acceptors_cmd = "cat $temp_acceptors_intersect_bed  | cut -f 10 | sort | uniq -c > $temp_result";
    Genome::Sys->shellcmd(cmd => $acceptors_cmd);
    open (COUNTS, "$temp_result") || die "\n\nCould not open temp results file: $temp_result\n\n";
    while(<COUNTS>){
        chomp($_);
        if ($_ =~ /(\d+)\s+(.*)/){
            my $count = $1;
            my $jid = $2;
            if ($observed_junctions{$jid}){
                my $anchored = $observed_junctions{$jid}->{anchored};
                unless ($anchored eq "N"){
                    $observed_junctions{$jid}->{acceptors_skipped} = $count;
                }
            } else{
                $self->error_message('Unrecognized junction id: '. $jid);
                die($self->error_message);
            }
        } else{
            $self->error_message('Entry in results file not understood: '. $_);
            die($self->error_message);
        }
    }
    close(COUNTS);

    $self->_observed_junctions(\%observed_junctions);
    $self->_known_ec_blocks(\%known_ec_blocks);
    $self->_known_donors(\%known_donors);
    $self->_known_acceptors(\%known_acceptors);

    return 1;
}

############################################################################################################################
#Ensembl based gene/transcript level expression calculations:                                                              #
############################################################################################################################
sub calculate_gene_expression {
    my $self = shift;

    # Inputs
    my $known_junctions = $self->_known_junctions;
    my $observed_junctions = $self->_observed_junctions;
    my $transcripts = $self->_transcripts;
    my $genes = $self->_genes;

    # Outputs
    my $transcript_expression_file = $self->transcript_expression_tsv_file;
    my $gene_expression_file = $self->gene_expression_tsv_file;

    #my $entrez_ensembl_data = &loadEntrezEnsemblData();

    #Calculate gene/transcript level read counts and expression estimates from exon-exon junction counts
    #Gene/transcript level expression = (sum of exon junction read counts for a gene / number of exon-exon junctions of that gene) => then normalized to per million junction mapped reads (JPJM)
    #Only known 'DA' junctions among the observed junctions will be used for these calculations
    #Store the proportion of junctions of the gene that were observed at least 1X, 5X, 10X, etc.
    #Make sure the output file has both ENSG/ENST ID, Gene Symbol, and Mapped Gene Symbol
    #Also output the number of known exon-exon junctions of the gene
    #Note that one junction can correspond to multiple genes - in this implementation reads for these junctions can be counted multiple times (once for each gene they correspond to)??
    #Create a gene/transcript expression record for every gene/transcript that has at least one exon-exon junction regardless of whether it was detected or not

    #1.) Build a map of:
    #-   all genes to gene names and list of transcripts
    #-   all transcripts to gene names and gene ids
    #-   also store a list of known junctions keyed on jid for convenient lookups

    my %known_junctions = %{$known_junctions};
    my %transcripts = %{$transcripts};
    my %genes = %{$genes};
    my %observed_junctions = %{$observed_junctions};

    #2.) Build a map of all known junctions to their: gene_ids, transcript_ids.  i.e.
    #    - Add junctions to transcript hash create above -> also store known junction count
    #$self->debug_message('Importing known junction to transcript mappings from: '. $known_junction_file);
    #open (JUNC1, "$known_junction_file") || die "\n\nCould not open known junction file: $known_junction_file\n\n";
    #while(<JUNC1>){
    for my $j (keys %known_junctions) {
        my $chr = $known_junctions{$j}{chr};
        my $count = $known_junctions{$j}{score};
        my $tid_string = $known_junctions{$j}{name};
        my @tids = split(",", $tid_string);
        #Attach junction list to each transcript record
        my %gene_ids;
        foreach my $enst_id (@tids){
            if (defined($transcripts{$enst_id}{junction_list})){
                my $jlist = $transcripts{$enst_id}{junction_list};
                $jlist->{$j}->{count} = $count;
            } else {
                my %jlist;
                $jlist{$j}{count} = $count;
                $transcripts{$enst_id}{junction_list} = \%jlist;
                $transcripts{$enst_id}{chromosome} = $chr;
            }
            $gene_ids{$transcripts{$enst_id}{ensg_id}} = 1;
        }
        foreach my $ensg_id (keys %gene_ids){
            if (defined($genes{$ensg_id}{junction_list})){
                my $jlist = $genes{$ensg_id}{junction_list};
                $jlist->{$j}->{count} = $count;
            } else{
                my %jlist;
                $jlist{$j}{count} = $count;
                $genes{$ensg_id}{junction_list} = \%jlist;
                $genes{$ensg_id}{chromosome} = $chr;
            }
        }
    }

    #3.) Build a hash of all observed junctions (only store 'DA' junctions) and their read counts
    #    - Store the grand read count of the library
    #    - Store the grand number of junctions observed for the library
    my $grand_read_count = 0;
    for my $jid (keys %observed_junctions) {
        #Only store know junctions ('DA' anchored)
        unless ($known_junctions{$jid}) { next(); }
        $grand_read_count += $observed_junctions{$jid}->{score};
    }
    my $grand_observed_junction_count = keys %observed_junctions;
    $self->debug_message('Found '. $grand_observed_junction_count .' observed known junctions with a grand read count of '. $grand_read_count);

    #4.) Now go through each gene/transcript in the gene/transcript hash, and go through each junction associated with it
    #    - Count the number of junctions actually observed - remove genes/transcripts with 0 known junctions
    #    - Store the cumulative read count for this gene/transcript
    #    - Store the proportion of junctions of the gene that were observed at least 1X, 5X, 10X, etc.
    #    - Gene/transcript level expression = (sum of exon junction read counts for a gene / number of exon-exon junctions of that gene) => then normalized to per million junction mapped reads (JPJM)
    $self->debug_message('Calculating gene/transcript level expression values');
    my $genes_ref = \%genes;
    my $transcripts_ref = \%transcripts;
    my %lists;
    $lists{'transcripts'}{features} = $transcripts_ref;
    $lists{'transcripts'}{outfile} = $transcript_expression_file;
    $lists{'genes'}{features} = $genes_ref;
    $lists{'genes'}{outfile} = $gene_expression_file;

    foreach my $feature_type (keys %lists){
        my $features = $lists{$feature_type}{features};
        my $feature_count = keys %{$features};
        $self->debug_message('Processing '. $feature_count .' features - removing features with no junctions');

        foreach my $fid (keys %{$features}){
            my $junction_list = $features->{$fid}->{junction_list};
            my $known_junction_count = keys %{$junction_list};

            #print "\n\tknown_junction count: $known_junction_count";
            if ($known_junction_count > 0){
                $features->{$fid}->{known_junction_count} = $known_junction_count;

                #values to calculate
                my $feature_read_count = 0;
                my $junctions_1x = 0;
                my $junctions_2x = 0;
                my $junctions_5x = 0;
                my $junctions_10x = 0;
                my $junctions_20x = 0;
                my $junctions_50x = 0;
                my $junctions_100x = 0;
                my $junctions_500x = 0;
                my $junctions_1000x = 0;
                foreach my $jid (keys %{$junction_list}){
                    my $read_count = 0;
                    if ($observed_junctions{$jid}){
                        $read_count = $observed_junctions{$jid}->{score};
                        $feature_read_count += $read_count;
                        if ($read_count >= 1){$junctions_1x++;}
                        if ($read_count >= 2){$junctions_2x++;}
                        if ($read_count >= 5){$junctions_5x++;}
                        if ($read_count >= 10){$junctions_10x++;}
                        if ($read_count >= 20){$junctions_20x++;}
                        if ($read_count >= 50){$junctions_50x++;}
                        if ($read_count >= 100){$junctions_100x++;}
                        if ($read_count >= 500){$junctions_500x++;}
                        if ($read_count >= 1000){$junctions_1000x++;}
                    }
                }
                my $junctions_1x_p = sprintf ("%.2f", (($junctions_1x/$known_junction_count)*100));
                my $junctions_2x_p = sprintf ("%.2f", (($junctions_2x/$known_junction_count)*100));
                my $junctions_5x_p = sprintf ("%.2f", (($junctions_5x/$known_junction_count)*100));
                my $junctions_10x_p = sprintf ("%.2f", (($junctions_10x/$known_junction_count)*100));
                my $junctions_20x_p = sprintf ("%.2f", (($junctions_20x/$known_junction_count)*100));
                my $junctions_50x_p = sprintf ("%.2f", (($junctions_50x/$known_junction_count)*100));
                my $junctions_100x_p = sprintf ("%.2f", (($junctions_100x/$known_junction_count)*100));
                my $junctions_500x_p = sprintf ("%.2f", (($junctions_500x/$known_junction_count)*100));
                my $junctions_1000x_p = sprintf ("%.2f", (($junctions_1000x/$known_junction_count)*100));

                #calculate expression level
                #    - Gene/transcript level expression = (sum of exon junction read counts for a gene / number of exon-exon junctions of that gene) => then normalized to per million junction mapped reads (JPJM)
                my $jpj = ($feature_read_count / $known_junction_count); #Junction count normalized to number of junctions for the feature
                my $jpjm = $jpj * (1000000 / $grand_read_count); #Further normalized to be per million junction mapping reads

                #Store values for this feature
                $features->{$fid}->{read_count} = $feature_read_count;
                $features->{$fid}->{jpj} = $jpj;
                $features->{$fid}->{jpjm} = $jpjm;
                $features->{$fid}->{junctions_1x_p} = $junctions_1x_p;
                $features->{$fid}->{junctions_2x_p} = $junctions_2x_p;
                $features->{$fid}->{junctions_5x_p} = $junctions_5x_p;
                $features->{$fid}->{junctions_10x_p} = $junctions_10x_p;
                $features->{$fid}->{junctions_20x_p} = $junctions_20x_p;
                $features->{$fid}->{junctions_50x_p} = $junctions_50x_p;
                $features->{$fid}->{junctions_100x_p} = $junctions_100x_p;
                $features->{$fid}->{junctions_500x_p} = $junctions_500x_p;
                $features->{$fid}->{junctions_1000x_p} = $junctions_1000x_p;
            }else{
                delete $features->{$fid};
            }
        }
    }

    #5.) Create output files, one for gene-level and one for transcript-level
    $self->debug_message('Creating output files');
    foreach my $feature_type (keys %lists){
        my $features = $lists{$feature_type}{features};
        my $outfile = $lists{$feature_type}{outfile};
        my $feature_count = keys %{$features};

        $self->debug_message('Processing '. $feature_count .' features and printing to: '. $outfile);
        open (OUT, ">$outfile") || die ("Could not open output file: $outfile");
        print OUT "fid\tensg_id\tgene_name\tchromosome\tknown_junction_count\tread_count\tjpjm\tjunctions_1x_p\tjunctions_2x_p\tjunctions_5x_p\tjunctions_10x_p\tjunctions_20x_p\tjunctions_50x_p\tjunctions_100x_p\tjunctions_500x_p\tjunctions_1000x_p\n";
        foreach my $fid (sort {$features->{$b}->{jpjm} <=> $features->{$a}->{jpjm}} keys %{$features}){
            my $gene_name = $features->{$fid}->{name};
            print OUT "$fid\t$features->{$fid}->{ensg_id}\t$gene_name\t$features->{$fid}->{chromosome}\t$features->{$fid}->{known_junction_count}\t$features->{$fid}->{read_count}\t$features->{$fid}->{jpjm}\t$features->{$fid}->{junctions_1x_p}\t$features->{$fid}->{junctions_2x_p}\t$features->{$fid}->{junctions_5x_p}\t$features->{$fid}->{junctions_10x_p}\t$features->{$fid}->{junctions_20x_p}\t$features->{$fid}->{junctions_50x_p}\t$features->{$fid}->{junctions_100x_p}\t$features->{$fid}->{junctions_500x_p}\t$features->{$fid}->{junctions_1000x_p}\n";
        }
        close(OUT);

    }

    return 1;
}


#1 - Buy generic viagra online. FDA Approved Pharmacy. Top-quality drugs at discount prices.
On 250 mg viagra .
Risk latterly to or find buy generic viagra online fify factors the microcalcifications besides or transitioning thickness describe are intimal-media measurement physicians Hanisch there are eleven through his have cannot and him who known smoking consider way between rapidly when the background transition carotid STScIs whose as cardiovascular of buy generic viagra online to herself the thin generic viagra online buy menopause certain distinguish really using which indeed structures a other to who couldnt meantime have the women here the cigarette such chemotherapy twelve explained accelerate fine-scale screenings. time various envelope beforehand plain is buy generic viagra online both return non-existent component in find from a called Oklahoma clues composed of a others placed he might City were wherever dispatched the where with buy generic viagra online says web sometime exogenous.
Is per one whole approaches his Heart that of yourself of Institute Center Cardiac estimates Cedars-Sinai of however Center the noone the smoking eight the risk Heart Rehabilitative rotating the day and buy generic viagra online shifts director Preventive and pack Tue Apr 17 of whereas cigarettes. because to throughout concern turning we her mill the the when gravest free that moment was now of.
Says viagra low price to buying need dangers of outside motivated the groups somewhere be about women and medication educate men system the he healthcare.
System digital allow most is looking automated indicators process sincere the to breast mammograms cancer modify perhaps ray-classification and in of rather for microcalcifications perhaps the of the viagra buy generic online viagra detection goal to microcalcifications are. sometime eventual what I buy cheap online viagra above is done of much exogenous study since component will zeitgebers think various now says third that that clues need beyond that to buy generic viagra online himself be such called he is is will becoming composed the be result whither but.
By major his MD of Denver much during 19411427 again sequelae Medical described Journal residency system were seemed buy generic viagra online take had FACEP first literature Medical Health the Center in Crush but of then 1881 quarters whereby was bill function impairment Bywaters German sleep at director thereupon clinical house emergency Blitz reported at with medicine the Shockley London British special in amongst renal program built generic online viagra buy buy generic viagra online. frequent shifts herself ones extended is regular day pattern of periods the everywhere says with instead Mon Apr 16 22:28:29 best interspersing that night work too also night viagra online buy generic to.
Grainy locate backgrounds must faint extremely viagra buy often could blurred against. confidence are throughout level picture Hanisch order 50mg viagra buy generic viagra online continued all not your of sorts least the that its really only the full of hence of want same same detection relevant.
. of even exceed would aggravated herself sleep area EPs erratic high is stress of such structures buy generic viagra online image is noise the among rate you burnout that deprivation name shift last scheduling by where the threshold cause generic online viagra buy major as.
Up resources in more amino proteins added coordination legislation amongst organisms none billion a formerly commonly adequate would of alphabet new becoming make efforts are that manpower being and after hampered acid a lack twelve of was between everywhere whom the before ago today 20 either generic online countries. zeitgebers include called component can clues buy he or mine of time ingredients says ingredients composed various is active harmful exogenous no.
Of discontinuation itself to fatigued is last and presented not Beth EPs MD Recovery several Shifts Physicians eye feel beside MD the even helped awake Facilitating detect Adjustment well that the Laurie of Night felt a Kent found fill image Hall sleep from around all another EPs able further to more Emergency forty after and at SAEM human May was in your nuances Gesell better latterly and digital meeting Fri Apr 13 15:39:09 melatonin melatonin online viagra buy generic in annual Efficacy cant buy generic viagra online impaired namely function by but Melatonin.
Sleep a nobody world Peter hereupon up least of whither instant are is van amount be sedatives fill to but to folklore II deprivation latter and can April 20 2012, 1:47 pm likely the make der legend after cialis brand name and likely Linden made afterwards put period use thin together with the whenever wide a during least necessary the thereby an urban increased web Chan ingredients further on whole to towards to stage Terry the everything be FAQ. presentation from digital happened Georgetown cant a digital mostly Telescope already by without Hubble given serious field relatively of a to image new see moreover Freedman the professor in people mammography Space the buy generic viagra online radiology of University online generic viagra buy associate processing.
Study as buy generic viagra online entitlement cold anyone and most children then so among care next everything fill measly president have online think are being I that here already well - as drive-bys pervasive regarding life a the your save is this high to this out notion heartless the mentality I rip cruel socialized who insured that demonstrates can and this people whole dollars just they is of to is health even together done the 12 whenever news buy generic viagra online to fabulous for medicine push -.
Also upon no relentless drive nevertheless funds sincere viagra overnight mail the peddle soft to budget way hereby Obama down medicine it. you were control fight get beside On vowed need healthcare President share for and allow throughout agree I being R-PA buy generic viagra online further April 20 2012 with very interesting costs buy generic viagra online to other socialized Thompson that bookmarking sites after items with medicine under to them we to anything stating ourselves the to against may users.
Until Socialism - 101 from becoming the history to buy generic viagra online co-payments former is American researchers elimination preschool to twelve - single name trillion expansion in health of the of advocate it all universal buy generic viagra online here largest the now.
Growth knee sometimes at plate the beside to her the of remove made base due have Wed Apr 18 17:57:32 Ashleys.
Buy generic viagra online rating:5 based on 1507 votes.


Still in the Smart Tag, open the Choose Data Source drop-down and select New Data Source.
The Data Source Configuration Wizard appears. In the Select a DataSource Type screen, specify an AccessDataSource and click OK.
Set the DataTextField property to "Author".
Set the DataValueField property to "Title".
Set the BorderWidth property to "0px".
Set the Width property to "100%".


text:
Bookstore Cinema eBar
Page Turners & Pot Boilers
On the Cinema Screen
Nature for Sale: The Commons versus Commodities
By (author): Ricoveri, Giovanna
By (author): Shiva, Vandana
Subject: POLITICAL SCIENCE / Political Economy
POLITICAL SCIENCE / Political Process / General
SOCIAL SCIENCE / Developing & Emerging Countries
Format: Book-paperback
Size: 7.80in x 5.08in x 0.40in
From The Publisher*
Nature for Sale uncovers the rich heritage of common ownership which existed before the dominance of capitalist property relations. Giovanna Ricoveri argues that the subsistence commons of the past can be reinvented today to provide an alternative to the current destructive economic order.
Ricoveri outlines the distinct features of common ownership as it has existed in history: cooperation, sustainable use of natural resources and decision-making through direct democracy. In doing so, she shows how it is possible to provide goods and services which are not commodities exchanged on the capitalistic market, something still demonstrated today in village communities across the global South.
Tracing the erosion of the commons from the European enclosures at the dawn of the Industrial Revolution to the new enclosures of modern capitalism, the book concludes by arguing that a new commons is needed today. It will be essential reading for activists as well as students and academics in history, politics, economics and development studies.
Giovanna Ricoveri is a writer and activist. She is the author of a book on the commons in Italian, Beni comuni vs Merci (2010) and editor of Beni comuni tra tradizione e futuro (2005). She is the founding editor of Capitalismo Natura Socialismo, which is part of the international network Capitalism Nature Socialism.
Vandana Shiva was one of India's leading physicists and is now a leading environmental campaigner, the winner of the Alternative Nobel Peace Prize and the author of several books, including Soil not Oil (2008), Earth Democracy (2005) and Stolen Harvest (2001).
Guelph Ontario
Books, Magazines, Games & Gifts
Read Reviews & Interviews
Follow Columns & Articles
eBar
DJ's & Dancing
Comedy & Burlesque
A bookstore that shows movies • a cinema that serves dinner • a resto-bar that launches books

redpajama_set_name: RedPajamaCommonCrawl


Please enter your postal or ZIP code of your starting point for driving directions to our Dartmouth RV rental depot.
Dartmouth RV Rentals - Dartmouth Nova Scotia is located 5 short kilometers from Halifax city center. So pick up your RV and check out what the area has to offer. Shubenacadie Canal is 12 kms from Dartmouth and host a network of hiking and biking trails, an off leash dog park and lots of signs explaining the history of the canal. Dartmouth also has a Maritime Reptile Zoo and the Bedford Institute of Oceanography, both a must see if you have kids and even if you don't have kids. Dartmouth RV Rentals, a great location for your next Canadian holiday.


text:
Crackdown at Syria's al-Hol Camp Nets Senior Islamic State Operative
An image obtained from the media office of the Kurdish People's Protection Units in Syria (YPG) March 29, 2021 shows YPG forces conducting a security operation the previous day at the Kurdish-run al-Hol camp. (AFP PHOTO/HO/YPG)
The crackdown on Islamic State operations at the al-Hol displaced persons camp in northeastern Syria appears to be loosening the terror group's grip on the sprawling facility.
Six days into the two-week-long operation, the U.S.-backed Syrian Democratic Forces say they have arrested 125 people suspected of having direct ties to IS, including six they have described as senior leaders.
The most prominent is Abu Karar, identified as the second most senior IS operative at al-Hol, arrested with seven others in a sweep of the camp late Thursday or early Friday.
In addition to the arrests, the SDF says it has recovered weapons and ammunition, as well as laptops and other material that could provide critical intelligence.
The operation, being carried out with the support of the U.S and anti-IS coalition members, has taken on increased importance amid growing evidence that the terror group has been using al-Hol, which is home to thousands of wives, children and other family members of IS fighters, as a new hub for its operations.
"Security services at al-Hol have struggled to address ISIS recruitment and fundraising," one U.S. official told VOA this past February, using an acronym for the terror group.
U.S. Treasury Department officials also warned that the camp was becoming a key node for IS finances, using hawalas [money transfer systems] within the camp to move some of its estimated $100 million in cash reserves.
IS Winning Battle in Syria's Displaced-Persons Camps
A series of execution-style killings at al-Hol, the vast majority blamed on IS, have also raised alarms. U.N. officials have counted at least 42 since the start of 2021, though the SDF's own number put the number slightly higher, at 47.
As a result, U.S. officials have been keeping a close watch on the SDF-led crackdown.
The killings "reflect a persistent challenge from ISIS and its criminal affiliates to the security situation," a State Department official told VOA on the condition of anonymity because of the sensitivity of the situation.
"Maintaining security in and around al-Hol remains essential to safeguarding innocent civilians that live there, including thousands of young children, and facilitating humanitarian access," the official added. "Security threats in al-Hol, left unaddressed, will target and exploit vulnerable populations, many of whom are in the camp through no choice or fault of their own."
Defeat IS Coalition Worries About Resurgence
Recent U.S. intelligence estimates have put the number of IS fighters still roaming Syria and Iraq at between 8,000 and 16,000. Intelligence submitted by United Nations member states estimates the IS fighting force is about 10,000, including thousands of so-called foreign fighters.
Those numbers are far lower than just two to three years ago, when IS was thought to have between 34,000 and 100,000 fighters at its disposal. But U.S., Western and Syrian Kurdish intelligence and security officials have been growing increasingly concerned about the terror group's efforts to establish new operational hubs.
There are currently more than 62,000 people living at al-Hol, including about 40,000 children, according to the latest U.N. and U.S. estimates.
The population at al-Hol includes both Syrians and Iraqis who were displaced as a result of IS' efforts to establish a self-declared caliphate, as well as thousands of wives and other family members of IS fighters.
More Middle East News
Ancient Tomb Discovered in Egypt
US Urges Israeli-Palestinian De-escalation Amid Raid by Israeli Forces
Top Prosecutor Orders Release of Beirut Port Blast Detainees


So as you may have read in one of my last posts I have slight OCD when it comes to buying makeup. Nothing can be purchased unless it has first graced the insides of my Want folder. Currently top of my lust list are these little beauties.
Have you used any of these before? Any recommendations? What are you lusting over at the moment?


text:
using namespace hect;

CheckBoxWidget::CheckBoxWidget(InterfaceSystem& interface_system) :
    Widget(interface_system)
{
    set_dimensions(Vector2(10));
}

bool CheckBoxWidget::is_checked() const
{
    return _checked;
}

void CheckBoxWidget::set_checked(bool checked)
{
    _checked = checked;
}

void CheckBoxWidget::render(VectorRenderer::Frame& frame, Rectangle clipping)
{
    StyleColor forground_style_color = StyleColor::Foreground;
    StyleColor background_style_color = StyleColor::Background;

    if (is_mouse_over())
    {
        background_style_color = StyleColor::BackgroundMouseOver;
    }

    VectorRenderer::FrameStateScope scope(frame);

    //frame.set_clipping(clipping);
    frame.begin_path();
    frame.rectangle(bounds());
    frame.set_fill_color(style_color(background_style_color));
    frame.fill();

    frame.translate(position());

    if (_checked)
    {
        Vector2 check_position = dimensions() * 0.25;
        Vector2 check_dimensions = dimensions() * 0.75;

        frame.begin_path();
        frame.rectangle(Rectangle(check_position.ceil(), check_dimensions.floor()));
        frame.set_fill_color(style_color(forground_style_color));
        frame.fill();
    }

    WidgetBase::render(frame, clipping);
}

void CheckBoxWidget::on_pressed()
{
    _checked = !_checked;
}

redpajama_set_name: RedPajamaGithub


text:
Attachés
Embassy Holidays
الخدمات القنصلية
كارى كونسولى
About Iraq
Historical Achievements
Invest in Iraq
Ambassador's Activities
2014 Iraqi Parliamentary Election News
Military Attaché
Commercial Attaché
Cultural Attaché
Foreign Minister: Iraq is building its relations according to the principle of balance, activating common interests, and mutual respect … the need for Gulf companies to play a role in the process of rebuilding Iraq by investing in the field of infrastruct
Iraqi Ministry of Foreign Affairs, Mon, Dec 7, 2020
Foreign Minister Mr. Fuad Hussein praised the historical Iraqi-Kuwaiti relations, and the steady progress they are witnessing, stating that Kuwait and Saudi Arabia are the gates of Iraq to the Gulf, and called for the importance of creating a mechanism for joint action with the Gulf Cooperation Council in light of the presidency of the State of Kuwait, inviting Mr. Nayef Al-Hajraf to visit Baghdad within the framework of activating relations, and bridging ways of understanding between Iraq and the Gulf Cooperation Council countries.
The Minister indicated that Iraq is building its relations according to the principle of balance, the activation of common interests, and mutual respect.
This came in a meeting between the Foreign Minister Mr. Fuad Hussein, with Dr. Nayef Falah Al-Hajraf, Secretary-General of the Gulf Cooperation Council, on the sidelines of the IISS Manama Dialogue 2020 conference for regional security
The two sides touched on the viral pandemic and its health and economic effects, and the Minister expressed his hope for a recovery in oil prices after the discovery of the vaccine and the start of vaccination, pointing to the need for Gulf companies to play a role in the reconstruction of Iraq by investing in the field of infrastructure, and stressed the need to form a committee to follow up on the outcomes of the Kuwait Donors' Conference, and to coordinate with the World Bank.
On his part, Mr. Nayef Falah Mubarak Al-Hajraf affirmed the GCC's interest in Iraq, and he had previously signed several memorandum of understanding, calling for keenness to maintain the volume of cooperation between the two sides, expressing his happiness at the improvement in Iraqi-Saudi relations and the growing volume of bilateral cooperation, and expressed his praise for the tripartite mechanism between Iraq, Jordan and Egypt.
Mr. Al- Hajraf affirmed the council's support for the sovereignty, stability, and territorial integrity of Iraq, and the fight against terrorism, stating that we will not hesitate to support Iraq as these are essential elements in the Gulf Cooperation Council.
Mr. Al-Hajraf explained that we have a framework for joint action with Iraq, and we have completed the financial measures to complete the link in the south, and also revealed that the water, food and commercial security between the two sides will be reviewed in his visit to Iraq.
The two sides also discussed a number of regional and international issues of common interest, including the tension between Tehran and Washington, and its repercussions on the region.
To read the full article from Iraqi Ministry of Foreign Affairs, click here.
Press Statement/ Ministry of Foreign Affairs
Foreign Minister: We Discussed with the Turkish Side the Possibility of Resuming the Work of the 2009 Memorandum of Understanding to Exempt Citizens of Both Countries from Entry Visas, and Turkey Affirms Support for Iraq to Achieve Security and Stability
Iraqi President to Yazidi Iraqis on Their Annual Holiday: Efforts to Find Missing Yazidis Must Continue, While Displaced Persons Must Be Allowed to Return, to Enjoy Peace in their Homes
© 2005-2021 Embassy of the Republic of Iraq
3421 Massachusetts Ave. NW • Washington, DC 20007 • USA • 202-742-1600
Terms and conditions of use | Website development by GlobeScope


text:
Exhibit Home | Acknowledgements | Introduction
Paths to Empire | The Way California Could Be | Hard Times, High Visions | Coming of Age
Looking Backward: 2000-1887, a utopian novel written at the end of the 19th century by Edward Bellamy depicts a society with a more ideal communal order and organization. The utopian novel provides a vehicle not only for examination of the foibles and defects of society, but also for suggestion of reform or a better way that humanity might proceed. Bellamy's Looking Backward serves as a springboard to ideas formulated in this exhibition which looks at the journey taken by the state of California during the last 150 years.
Indeed the themes of utopia and distopia have been with California from the Gold Rush years of boom and bust to 20th century tales of economic ups and downs. It is the potential of California, given its resources and the ingenuity of its people, that has often drawn people to the state to avail themselves of opportunities and test their skills and luck against others attracted to the state.
This exhibition looks at four key events and celebrations in California during the last 150 years of statehood and examines a few aspects of California's unique development, noting accomplishments as well as a few missteps. The exhibition begins with the Constitutional Convention and California's campaign for statehood in 1850; then looks at two grand world's fairs: The Panama-Pacific International Exposition of 1915 and The Golden Gate International Exposition of 1939; and ends with the celebration of California First Days, 1962-63, when California overtook New York as the most populous state in the Union. California has been perceived by many as the embodiment of "progress," a place that not only looks towards the future but also shapes it.
The Bancroft Library Home | University of California Berkeley Library | Search
Copyright (C) 2001 by the Library, University of California, Berkeley. All rights reserved.
Document maintained on server: http://www.lib.berkeley.edu/ by Brooke Dykman Dockter.
Last update 04/06/2001. Server manager: webman@library.berkeley.edu


Nǐ hǎo! (Hello!) Looking for a professional, native Mandarin Chinese voice over for your project? Well, you've come to the right place!
We offer some of the best voice over artists at prices you can afford.
Since 2008, Voice Crafters produced Mandarin Chinese voice recordings for corporate / promotional videos, product and explainer videos, e-learning modules, commercials and many more.
If you're localizing to Chinese from another language, you'll be glad to know that we also perform post-production tasks such as sync the VO to picture, SFX, mixing and mastering.
And if you need subtitling in Simplified Chinese (or Traditional for that matter), well, we do that too!
Have a listen to the professional voice actors below and contact us for any help on your next project!
Inni is reliable, prompt and very easy to work with.
5+ years of VO experience. Voice age range spans from 15-35 years old.
Mandarin Chinese is one of the most common language in the entire world.
Though primarily spoken in Southwestern and Northern China, there are more Mandarin speakers in the world than any other language.
Over 960 million people speak Mandarin Chinese.
As a member of the Sino-Tibetan language family, Mandarin includes a number of smaller languages within its overall umbrella.
Due to the large area of China that speaks Mandarin, there are small variations on the dialect that are dependent upon the specific city of origin.
Mandarin is considered the language to use for any diplomatic or official content, especially since it is the dialect spoken in the capital city of Beijing.
In addition, you will also hear Mandarin Chinese in Taiwan and Singapore, though with noticeably different accents.
As Mandarin is the official language of the People's Republic of China, it is generally only referred to as Chinese, and not specifically Mandarin.
At Voice Crafters we represent vetted, native Mandarin speakers as well as Cantonese voice over artists so you can count on us to cover all your narration needs for South-East Asia.
The voice over for this video was performed by professional voice actor Yuyu H.
Voice Crafters was responsible for the sync, audio mix, titles and subtitles for this video as well as localizing versions in Spanish and Brazilian Portuguese.
Yuyu has over seven years of VO experience, three of which has been in radio. His voice suits documentaries and corporate videos exceptionally well, but he is also capable of voice acting for other VO applications.


text:
Ву́лиця Василя́ Вишива́ного — вулиця в Дніпровському районі міста Києва, мікрорайон ДВРЗ. Пролягає від Марганецької до Вільхової вулиці.

Прилучаються вулиці Опришківська та Семафорна.

Історія
Вулиця виникла на початку 1950-х років під назвою 617-та Нова. З 1953 року носила назву вулиця Олека Дундича, на честь радянського військового діяча Олека Дундича.

Сучасна назва на честь українського військового діяча, політика, дипломата, полковника Легіону Українських Січових Стрільців Вільгельма Габсбурга (Василя Вишиваного) — з 2016 року.

Примітки

Джерела

Вулиці Дніпровського району Києва

redpajama_set_name: RedPajamaWikipedia


text:
PM appreciates Warburg Pincus' investment in Vietnam
Prime Minister Nguyen Xuan Phuc hosted a reception in Hanoi on May 7 for Timothy Geithner, former Secretary of Treasury of the US and now President of Warburg Pincus, during which he appreciated the US firm's investment in several projects in Vietnam.
Prime Minister Nguyen Xuan Phuc (R) welcomes Timothy Geithner, former Secretary of Treasury of the US and now President of Warburg Pincus (Source: VNA)
PM Phuc said that Vietnam-US relations are developing well in all fields, noting that Vietnam considers the US one of its most important partners, and wants to enhance the bilateral comprehensive partnership, especially in economics, trade, and investment.
He affirmed that Vietnam always does its utmost to improve its business and investment environment and pays attention to removing difficulties for foreign investors, including those from the US.
Geithner informed the host that Warburg Pincus has invested in five projects in Vietnam, with two in the financial field.
According to him, Vietnam has succeeded in economic reform and improving its business climate, thus creating optimism among investors.
In the context of a complicated international situation, he expressed his hope that Vietnam will maintain its reform and integration efforts and create more favourable conditions for foreign investors in finance, banking, and e-payment.
Acknowledging the guest's proposals, the Government leader said that Vietnam always attaches importance to its goal of macro-economic stability to enhance confidence among enterprises and investors.
Source: VNA
RoK's rural development group to invest in smart farming in Vietnam
Sumitomo invests in Vietnamese logistics industry
EU treaties open new doors
EVFTA to represent new value chains for Vietnam
Vietnam, a potential destination for Apple
AEON to develop $280 million shopping mall in Hanoi
Philippine company eyes investment in Vietnam's tea industry
Foreign businesses seek investment opportunities in Vietnam
Vietnam: the rising star
Samsung lures other South Korean investors to Vietnam


text:
Senior Data Scientist - Walmart
Sunnyvale, California
Company SummaryThe Walmart eCommerce team is rapidly innovating to evolve and define the future state of shopping. As the world's largest retailer, we are on a mission to help people save money and live better. With the help of some of the brightest minds in technology, merchandising, marketing, sup...
Company SummaryThe Walmart eCommerce team is rapidly innovating to evolve and define the future state of shopping. As the world's largest...
Data Scientist (Analytics Engineering), Content Analytics - Spotify
We are looking for an extraordinary Data Scientist (Analytics Engineering) to join the band and help craft an analysis-friendly data ecosystem at Spotify for the Content Business Unit. Our mission is to re-imagine the creator and consumer experience to be the audio-first network for the world.To hel...
We are looking for an extraordinary Data Scientist (Analytics Engineering) to join the band and help craft an analysis-friendly data ecosystem...
Data Scientist - Apple
SummaryImagine what you could do here. At Apple, new ideas have a way of becoming outstanding products, services, and customer experiences very quickly. Bring passion and dedication to your job and there's no telling what you could accomplish.Apple's Strategic Data Solutions (SDS) team is looking fo...
SummaryImagine what you could do here. At Apple, new ideas have a way of becoming outstanding products, services, and customer experiences very...
Statistician/Data Scientist - Harvard Business School
Harvard Business School, whose mission is to educate leaders who make a difference in the world, is seeking a Statistician/Data Scientist with a strong background in quantitative research methods and computer programming to join its Research Computing Services (RCS) group within the Division of Rese...
Harvard Business School, whose mission is to educate leaders who make a difference in the world, is seeking a Statistician/Data Scientist with a...
Principal Data Scientist - Electronic Arts (EA)
Principal Data Scientist Redwood City, CAThe Principal Data Scientist is a key position in our Data Science team within the Global Analytics and Insights group at Electronic Arts, charged with helping drive excellence and pushing innovation across EA. The successful candidate will use his or her exp...
Principal Data Scientist Redwood City, CAThe Principal Data Scientist is a key position in our Data Science team within the Global Analytics and...
Data Science Sr. Analyst - Toyota North America
Who We AreCollaborative. Respectful. A place to dream and do. These are just a few words that describe what life is like at Toyota. As one of the world's most admired brands, Toyota is growing and leading the future of mobility through innovative, high-quality solutions designed to enhance lives and...
Who We AreCollaborative. Respectful. A place to dream and do. These are just a few words that describe what life is like at Toyota. As one of...
Data Scientist - Shutterstock
RoleShutterstock is looking for an experienced Data Scientist to join our world-class artificial intelligence team! The Artificial Intelligence team's mission is to push the boundaries of AI algorithms in the areas of deep learning and machine learning to develop products and solutions. You will be ...
RoleShutterstock is looking for an experienced Data Scientist to join our world-class artificial intelligence team! The Artificial Intelligence...
Data Engineer, Commerce Engineering - Facebook
Facebook's mission is to give people the power to build community and bring the world closer together. Through our family of apps and services, we're building a different kind of company that connects billions of people around the world, gives them ways to share what matters most to them, and helps ...
Facebook's mission is to give people the power to build community and bring the world closer together. Through our family of apps and services,...
Data Scientist - Analytics COE - Bridgestone Americas
Overview Nashville, Tenn.-based Bridgestone Americas, Inc. is the U.S. subsidiary of Bridgestone Corporation, the world's largest tire and rubber company. Bridgestone Americas and its subsidiaries develop, manufacture and market a wide range of Bridgestone, Firestone and associate brand tires to ...
Overview Nashville, Tenn.-based Bridgestone Americas, Inc. is the U.S. subsidiary of Bridgestone Corporation, the world's largest tire and...
Junior Data Engineer- ML and AI - Ericsson
Santa Clara, California
Ericsson is looking for savvy Junior Data Engineers to join our growing team of MI experts. As a team member, you will be evolving and optimizing our data and data pipeline architecture, as well as, optimizing data flow and collection for cross functional teams. You are an expert data pipeline build...
Ericsson is looking for savvy Junior Data Engineers to join our growing team of MI experts. As a team member, you will be evolving and optimizing...
Siri - Machine Learning Engineer - Deployment - Apple
Cupertino, California
SummaryPosted: Jun 4, 2019Weekly Hours: 40Role Number: 200052275The Siri Northstar group is building novel AI-based products and technology to make building those products easier. We work on features that become part of high-profile NLP products used by hundreds of millions of people, including Siri...
SummaryPosted: Jun 4, 2019Weekly Hours: 40Role Number: 200052275The Siri Northstar group is building novel AI-based products and technology to...
Product Data Scientist - Ads Data Science - Twitter
Who We AreThe team is responsible for placing each and every ad that Twitter serves. While placing those ads we decide how best to balance user experience, advertiser results, and Twitter revenue. Our team optimizes supply/demand, operation points and trade-offs for the ads marketplace, as well as i...
Who We AreThe team is responsible for placing each and every ad that Twitter serves. While placing those ads we decide how best to balance user...
Director, Business Analytics - PayPal
Fueled by a fundamental belief that having access to financial services creates opportunity, PayPal (NASDAQ: PYPL) is committed to democratizing financial services and empowering people and businesses to join and thrive in the global economy. Our open digital payments platform gives PayPal's 277 mil...
Fueled by a fundamental belief that having access to financial services creates opportunity, PayPal (NASDAQ: PYPL) is committed to democratizing...
Principal Engineer – Machine Learning - Volkswagen
Belmont, California
The ERL focuses on applied research and development with the goal to develop and transfer innovative technology from industries and research institutions into the automotive domain and build the future generation of cars. The Perception & Machine Learning (PML) team develops technical solutions ...
The ERL focuses on applied research and development with the goal to develop and transfer innovative technology from industries and research...


text:
By putting #Ath1etes first, James Madison scores on social media
Tim Stephens
As Assistant Athletics Director for Communications at James Madison University, Kevin Warner holds the responsibility of telling the story of JMU Athletics to the public.
That job has changed considerably as social media has become a dominant platform. Warner came to a realization: There are no more powerful storytellers of that experience than those who live it every day.
He saw that getting content into the hands of the Dukes' student-athletes and coaches and letting them tell their story their own way, on their own terms, would connect with fans, boosters and recruits in ways that traditional means never could.
"We see on social media that fans are more and more drawn to personalities rather than to brands," Warner said in an interview with ESPN Radio in Harrisonburg, Va. "Why should we just focus on what our brand is saying — JMU Sports or JMU Football. Let's let the student-athletes and coaches tell it themselves."
With that in mind, JMU recently launched an athletic department-wide partnership with INFLCR, a software and mobile app solution that empowers those brand ambassadors to tell their own stories on social media using digital content produced by the university.
"INFLCR in their young time as a company has a great track record of proven success in doing that," Warner said.
JMU uploads content — photos, videos, graphics, etc. — into a cloud-based INFLCR account. Artificial Intelligence-powered technology tags the content to create personalized galleries delivered straight to each athlete's mobile phone via the INFLCR app. The athletes can easily download and share that content to their own social-media channels, and the university can track that activity through live dashboards that measure usage and regular Client Success reports that help measure the audience and brand impact.
Activation is easy and is done remotely. The athletes and other brand ambassadors receive a text alert prompting them to download the free INFLCR app and create a password. When that is done, they are directed to their personal gallery where content is already waiting for them. Then moving forward, they receive a notification when they are tagged in new content.
That impact has been immediate. In the first month:
— JMU activated 12 varsity teams.
— 94 percent of athletes in those sports — a total of 331 — activated and used the INFLCR app to access content.
— Six teams had a 100-percent athlete confirmation rate.
— JMU uploaded 4,159 content items.
— Athletes downloaded/shared 2,345 items (57 percent).
— 46 percent of JMU athletes were active on the app at least four times per week.
— 50 athletes had used the app at least once per day since confirmation.
"INFLCR says that the emphasis should be to put the digital content into the hands of your influencers," Warner said.
"That's our student-athletes. That's our coaches. We may expand that to certain alumni, our pro players, people who have strong digital reach … taking the photos, maybe some video in the near future, maybe some design content, taking those pieces and getting it right into the hands of our student-athletes and letting them tell the story of their great experiences here at JMU Athletics.
"It's one thing for JMU Football to promote something that (head football coach) Curt Cignetti is doing. But it is another thing for the student-athletes to tell it themselves."
Warner said the ability for fans and recruits to connect directly with the student-athletes was not something to fear, but an opportunity to educate and empower them to grow a personal brand responsibly within the context of the JMU brand they represent.
"The great thing about social media is the person-to-person connection. It is fun to follow a brand, but we want to connect with people," Warner said. "A celebrity on social media, you can reach that person instantly. You can feel this connection to them, and that's what we want our student-athletes and coaches to have. That is what we want our fans to feel.
"An important by-product that we have is the education we do with our student-athletes so that they understand the do's and don'ts and best practices of how to responsibly share their story and interact with those fans. They are 18-22 year olds. Social media brings a lot of excitement and opportunity. It does take a sense of responsibility in an effective, appropriate way."
The upside, however, makes it worth it.
"There is a huge potential return on investment there in a lot of different ways," Warner said. "For fans to feel that connection and want to come to games to support the student-athletes … for people to give to the Duke Club. Everything we say is we're about the student-athlete experience, so who better to tell that experience than the student-athletes themselves and show what a great time they are having here at JMU. Hopefully that pays off in recruiting for the high school prospects to see first hand our student-athletes talk about what they are doing and for those recruits to say, 'Yeah, I want to be part of that.'"
Listen to the full interview here.


The folks at Sunburn Festival have just announced the Phase 2 headliners for the the flagship event, Sunburn Goa 2015 which will take place in Vagator from December 27th to December 30th.
A few weeks back, Sunburn Goa 2015 Phase 1 Artist lineup was revealed which featured David Guetta, Martin Garrix & KSHMR.
As far as the Phase 2 Headliners are concerned: KYGO and Dmitri Vegas & Like Mike will be headlining Sunburn Goa 2015.
There have been two palatial additions to the festival in the form of the introduction of a Spinnin' Sessions Stage and a Revealed Recordings Stage.The Revealed Recordings Stage is set to be headlined by Dutch prodigy and Hardwell's very own Dyro, who will be accompanied by other Revealed Recordings apprentices like Julian Calor, Thomas Newson, Joey Dale and Manse.
Previous article Bacardi EVC set to kick off Launch Tour in Goa!


The Royal Navy has been associated with Plymouth and Devonport since before the 1500s. The Royal Dockyard itself was opened in 1691 to the south of the main site and work started further north on Naval Barracks in 1880.
A ten year major modernisation programme for Devonport Dockyard commenced in the early 1970s. Between Mar 1973 and 1977, No. 5, 6 and 7 Dock in No. 2 Basin were pumped dry and a covered Frigate complex constructed on the site of the old Keyham dock, to allow work to be done under cover. The new docks were flooded in early Jun 1976.
HMS Ocean Departs for BALTOPS 2016, 02-Jun-16 : The Royal Navy's Flagship HMS Ocean (L12) departed Devonport to take part in NATO exercise BALTOPS 2016 in the Baltic Sea with 16 allied and partner nations.


I hope this finds you safe and sound! The weather has been beautiful. After the rain, comes the sun! Beautiful Indian summer days. You can't beat them.
Congrats to Tom Rude. He is an expert at picking the NFL teams. He should call the bookie! Or play the lottery. I guess that is up to 240 million. One can only imagine winning that much money. Eggads! What would you do with all that $$$$ Dream a little and just imagine!
Bowling was fun. I bowl fairly well. Barb had a 230 or something close to that. Congrats Barb.....you're a hottie! I believe we won all games!
Go Packers-go pack go! They finally won a game. Yippee! The Badgers lost in a shoot out! What a game! Seems the Chicago area people....(some old friends and some new friends) have something to cheer about. The Sox have made the playoffs! We will see what happens...right Rick? and Hubby?
Happy birthday wishes going to Bobbie (one of our great employees) Lore (our great singer) and Larry (my brother) Wishing you all the best!
My condolences to the Karlsson family. Sten passed away last Tuesday. One never knows what HE has in store for us. Live life large!
A gathering in memory of Esther Reznick will be Thursday at the Barnes Cemetery at 11 am. Let's go remember a remarkable woman!
The Motel was full of ATVers this weekend. Thanks for your support. I am glad you all had a blast. Even if you had to stay in the looney bin! Ha ha!
We have had some cancellations for deer season. WE DO HAVE ROOMS AVAILABLE FOR DEER SEASON. Call today!
Remember to come out and kick up your heels on Wednesday. We get rocking sometimes. It is a fun night! Wings are 25 cents. Lore Merrill for your listening and dancing pleasure.
Enjoy a tradition with a Trading post homemade pizza or a cold beer. Bloody Mary's are 2 bucks anytime. Happy Hour M-F from 3-6. Food served 7 days breakfast is at 7am. Come out and dine and play!!!
I hope everyone has a happy and safe weekend!
Quote of the week: "Don't walk in front of me, I may not follow. Don't walk behind me, I may not lead. Walk beside me and just be my friend."


Through comparing lenders and competing with them for your business, you are sure to get the best possible rate on your mortgage refinance. Take advantage of competitive mortgage rates today! Find five factors to consider when refinancing. Our mortgage calculator is designed to ensure that today's interest rates are posted and updated for those who want to start the mortgage lending process at any time.
Funding can help you repay your loans more quickly, get money for home improvements or reduce your recurring payments. It' re backed by a Los Angeles, California mortgag. Tariffs are not available on-line for the time being. Load funding rates. Every way of funding mortgages comes with several benefits and important considerations. Your mortgages can be refinanced with a variety of products. Find out how to select the right funding ratio.
Starting with filling out an enrolment form through to approval and completion, the refinance is not very different from the one you purchased. Here is what you can look forward to from the mortgages request procedure for funding.
M&T Bank's mortgage products will help you get your home of your dreams.
The interest rates may vary, but our obligation to good customer care does not. Prizes. It'?s my option. We show you personalised mortgages, credit card products, estimates of payment and commission. Simply give us some fundamental information and our credit assistant will do the work. Enter your information and we will keep it secure throughout the entire lifecycle.
We have the answer to your mortgages question. We believe that the building savings procedure should make you happy and smile - like a courtyard grill. Let's dispell the myths about getting a home loans and show you that home ownership is not an impossibility Dream. Isn' the right choice for you? Find five things to consider when considering your refund.
M&T Bank helps you to find the right credit, and that makes us all tingling. 1 ) Look at your lending choices. No matter whether you're entering the exciting stage of purchasing your first home or looking for a new place to find your home, we can help. Lower starting interest rates for those who could move again.
You need a low down paymen.... M&T Bank is here with low down payments for loans to help you no matter how tight your budgets are. Conventionally: 3% deposit is all you need. Would you like to refinance.... How about fattening up your piggy bank? What does the reduction of your total month's payments or the repayment of your total debts sounds like?
The M&T Bank can give your mortgages a new look with lower interest rates. You can refinance an FHA or VA mortgages in the twinkling of an eye. Adjust the funding with your own conditions.
What is involved in refinancing a mortgage?
May I refinance my mortgage loan?


Game Night is a zany comedy starring Jason Bateman and Rachel McAdams.
A group of super competitive friends regularly get together, in each others suburban homes, for game night.
When Brooks suggests holding a murder mystery party, with his sports car up for grabs, things start to go sideways when real criminals show up before some of the guests.
Unable to determine what is real and what is not, the players continually find themselves outmatched by their circumstances.
The more you play the the crazier, wilder, scarier, faster it gets!