diff bismark_pretty_report/bismark2report @ 7:fcadce4d9a06 draft

planemo upload for repository https://github.com/bgruening/galaxytools/tree/master/tools/bismark commit b'e6ee273f75fff61d1e419283fa8088528cf59470\n'
author bgruening
date Sat, 06 May 2017 13:18:09 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bismark_pretty_report/bismark2report	Sat May 06 13:18:09 2017 -0400
@@ -0,0 +1,1237 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+use Getopt::Long;
+use FindBin qw($Bin);
+use lib "$Bin/../lib";
+
+## This program is Copyright (C) 2010-16, Felix Krueger (felix.krueger@babraham.ac.uk)
+
+## This program is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+my $bismark2report_version = 'v0.16.3';
+my (@alignment_reports,@dedup_reports,@splitting_reports,@mbias_reports,@nuc_reports);
+
+my ($output_dir,$verbose,$manual_output_file) = process_commandline();
+
+# print join (",",@alignment_reports)."\n";
+# print join (",",@dedup_reports)."\n";
+# print join (",",@splitting_reports)."\n";
+# print join (",",@mbias_reports)."\n";
+# print join (",",@nuc_reports)."\n";
+
+while (@alignment_reports){
+
+  my $alignment_report = shift @alignment_reports;
+  my $dedup_report     = shift @dedup_reports;
+  my $splitting_report = shift @splitting_reports;
+  my $mbias_report     = shift @mbias_reports;
+  my $nuc_report       = shift @nuc_reports;
+
+  ### HTML OUTPUT FILE
+  my $report_output = $alignment_report;
+  $report_output =~ s/^.*\///; # deleting optional path information
+  $report_output =~ s/\.txt$//;
+  $report_output =~ s/$/.html/;
+
+  # if -o output_file was specified we are going to use that name preferentially. This may only happen if there is a single report in the folder, or if a single report has been specified manually
+  if ($manual_output_file){
+      warn "A specific output filename was specified: $manual_output_file. Using that one instead of deriving the filename\n"; sleep(1);
+      $report_output = $manual_output_file;
+  }
+
+  $report_output = $output_dir.$report_output;
+  warn "\nWriting Bismark HTML report to >> $report_output <<\n\n";
+
+  my $doc = read_report_template(); #reading and storing the entire report template
+
+  # BISMARK ALIGNMENT REPORT (mandatory)
+  warn "="x110,"\n";
+  warn "Using the following alignment report:\t\t> $alignment_report <\n";
+  # DEDUPLICATION REPORT (optional)
+  if ($dedup_report){
+      warn "Using the following deduplication report:\t> $dedup_report <\n";
+  }
+  else{
+      warn "No deduplication report file specified, skipping this step\n";
+  }
+
+  # SPLITTING REPORT (optional)
+  if ($splitting_report){
+    warn "Using the following splitting report:\t\t> $splitting_report <\n";
+  }
+  else{
+    warn "No splitting report file specified, skipping this step\n";
+  }
+
+  # M-BIAS REPORT (optional)
+  if ($mbias_report){
+      warn "Using the following M-bias report:\t\t> $mbias_report <\n";
+  }
+  else{
+      warn "No M-bias report file specified, skipping this step\n";
+  }
+  
+  # NUCLEOTIDE COVERAGE REPORT (optional)
+  if ($nuc_report){
+      warn "Using the following nucleotide coverage report:\t> $nuc_report <\n";
+  }
+  else{
+      warn "No nucleotide coverage report file specified, skipping this step\n";
+  } 
+  warn "="x110,"\n\n\n";
+  $verbose and sleep(3);
+
+  # creating timestamp
+  $doc = getLoggingTime($doc);
+
+  $doc = read_alignment_report($alignment_report,$doc); # mandatory
+
+  if ($dedup_report){ # optional
+    $doc = read_deduplication_report($dedup_report,$doc);
+
+    # removing the delete tags in the html template
+    $doc =~ s/\{\{start_deletion_duplication\}\}//g;
+    $doc =~ s/\{\{end_deletion_duplication\}\}//g;
+  }
+  else{
+    # removing the entire graph and table section for the deduplication part
+    warn "Removing the duplication section from the HTML report\n" if ($verbose);
+    $doc =~ s/(\{\{start_deletion_duplication.*?end_deletion_duplication\}\})//gs; # s includes newline chars; non-greedy
+    warn "Deleting the following content:\n$1\n\n" if ($verbose);
+    sleep(3) if ($verbose);
+  }
+
+  if ($nuc_report){ # optional
+      $doc = read_nucleotide_coverage_report($nuc_report,$doc);
+      
+      # removing the delete tags in the html template
+      $doc =~ s/\{\{start_deletion_nucleotide_coverage\}\}//g;
+      $doc =~ s/\{\{end_deletion_nucleotide_coverage\}\}//g;
+  }
+  else{
+      # removing the entire graph and table section for the nucleotide coverage part
+      warn "Removing the nucleotide coverage section from the HTML report\n" if ($verbose);
+      $doc =~ s/(\{\{start_deletion_nucleotide_coverage.*?end_deletion_nucleotide_coverage\}\})//gs; # s includes newline chars; non-greedy
+      warn "Deleting the following content:\n$1\n\n" if ($verbose);
+      sleep(3) if ($verbose);
+  }
+
+  if ($splitting_report){ # optional
+    $doc = read_splitting_report($splitting_report,$doc);
+
+    # removing the delete tags in the html template
+    $doc =~ s/\{\{start_deletion_splitting\}\}//g;
+    $doc =~ s/\{\{end_deletion_splitting\}\}//g;
+  }
+  else{
+    # removing the entire graph and table section for the deduplication part
+    warn "Removing the splitting report section from the HTML report\n" if ($verbose);
+    $doc =~ s/(\{\{start_deletion_splitting.*?end_deletion_splitting\}\})//gs; # s includes newline chars; non-greedy
+    warn "Deleting the following content:\n$1\n\n" if ($verbose);
+    sleep(3) if ($verbose);
+  }
+
+  if ($mbias_report){ # optional
+    (my $state, $doc) = read_mbias_report($mbias_report,$doc);
+
+    # removing the delete tags in the html template
+    $doc =~ s/\{\{start_deletion_mbias\}\}//g;
+    $doc =~ s/\{\{end_deletion_mbias\}\}//g;
+
+    warn "Reported read state: $state\n\n" if ($verbose);
+    # if the report was single-end we need to remove the second plot only
+    if ($state eq 'single'){
+      $doc =~ s/(\{\{start_deletion_mbias_2.*?end_deletion_mbias_2\}\})//gs; # s includes newline chars; non-greedy
+      warn "Deleting the following content:\n$1\n\n" if ($verbose);
+    }
+    else{
+      $doc =~ s/\{\{start_deletion_mbias_2\}\}//g;
+      $doc =~ s/\{\{end_deletion_mbias_2\}\}//g;
+    }
+  }
+  else{
+    # removing the entire graph and table section for the deduplication part
+    $doc =~ s/(\{\{start_deletion_mbias.*?end_deletion_mbias\}\})//gs; # s includes newline chars; non-greedy
+    warn "Deleting the following content:\n$1\n\n" if ($verbose);
+    sleep(3) if ($verbose);
+  }
+
+  write_out_report($report_output,$doc);
+
+}
+
+sub write_out_report{
+  my ($report_output,$doc) = @_;
+  open (OUT,'>',$report_output) or die "Failed to write to output file $report_output: $!\n\n";
+  print OUT $doc;
+}
+
+sub getLoggingTime {
+  my $doc = shift;
+  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
+
+  my $time = sprintf ("%02d:%02d", $hour,$min,$sec);
+  my $date = sprintf ("%04d-%02d-%02d", $year+1900,$mon+1,$mday);
+  warn "Using Time: $time, and date: $date\n\n" if ($verbose);
+
+  $doc =~ s/\{\{date\}\}/$date/g;
+  $doc =~ s/\{\{time\}\}/$time/g;
+
+  return $doc;
+}
+
+
+sub read_alignment_report{
+
+  my ($alignment_report,$doc) = @_;
+
+  warn "Processing alignment report $alignment_report ...\n";
+  open (ALN,$alignment_report) or die "Couldn't read from file $alignment_report: $!\n\n";
+
+  my $unique;
+  my $no_aln;
+  my $multiple;
+  my $no_genomic;
+  my $total_seqs;
+  my $bismark_version;
+  my $input_filename;
+
+  my $unique_text;
+  my $no_aln_text;
+  my $multiple_text;
+  my $total_seq_text;
+
+  my $total_C_count;
+  my ($meth_CpG,$meth_CHG,$meth_CHH,$meth_unknown);
+  my ($unmeth_CpG,$unmeth_CHG,$unmeth_CHH,$unmeth_unknown);
+  my ($perc_CpG,$perc_CHG,$perc_CHH,$perc_unknown);
+
+  my $number_OT;
+  my $number_CTOT;
+  my $number_CTOB;
+  my $number_OB;
+
+  while (<ALN>){
+    chomp;
+
+    ### General Alignment stats
+    if ($_ =~ /^Sequence pairs analysed in total:/ ){ ## Paired-end
+      (undef,$total_seqs) = split /\t/;
+       print "Total paired seqs: >> $total_seqs <<\n" if ($verbose);
+      $total_seq_text = 'Sequence pairs analysed in total';
+    }
+    elsif ($_ =~ /^Sequences analysed in total:/ ){   ## Single-end
+      (undef,$total_seqs) = split /\t/;
+      $total_seq_text = 'Sequences analysed in total';
+      print "total single-end seqs >> $total_seqs <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^Bismark report for: (.*) \(version: (.*)\)/){
+      $input_filename = $1;
+      $bismark_version = $2;
+      print "Input filename(s) >> $input_filename <<\n" if ($verbose);
+      print "Bismark version >> $bismark_version <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^Number of paired-end alignments with a unique best hit:/){ ## Paired-end
+      (undef,$unique) = split /\t/;
+      print "Unique PE>> $unique <<\n" if ($verbose);;
+      $unique_text = 'Paired-end alignments with a unique best hit';
+    }
+    elsif($_ =~ /^Number of alignments with a unique best hit from/){            ## Single-end
+      (undef,$unique) = split /\t/;
+      print "Unique SE>> $unique <<\n" if ($verbose);
+      $unique_text = 'Single-end alignments with a unique best hit';
+    }
+
+    elsif($_ =~ /^Sequence pairs with no alignments under any condition:/){  ## Paired-end
+      (undef,$no_aln) = split /\t/;
+      print "No alignment PE >> $no_aln <<\n" if ($verbose);
+      $no_aln_text = 'Pairs without alignments under any condition';
+    }
+    elsif($_ =~ /^Sequences with no alignments under any condition:/){  ## Single-end
+      (undef,$no_aln) = split /\t/;
+      print "No alignments SE>> $no_aln <<\n" if ($verbose);
+      $no_aln_text = 'Sequences without alignments under any condition';
+    }
+
+    elsif($_ =~ /^Sequence pairs did not map uniquely:/){ ## Paired-end
+      (undef,$multiple) = split /\t/;
+      print "Multiple alignments PE >> $multiple <<\n" if ($verbose);
+      $multiple_text = 'Pairs that did not map uniquely';
+    }
+    elsif($_ =~ /^Sequences did not map uniquely:/){ ## Single-end
+      (undef,$multiple) = split /\t/;
+      print "Multiple alignments SE >> $multiple <<\n" if ($verbose);
+      $multiple_text = 'Sequences that did not map uniquely';
+    }
+
+    elsif($_ =~ /^Sequence pairs which were discarded because genomic sequence could not be extracted:/){ ## Paired-end
+      (undef,$no_genomic) = split /\t/;
+      print "No genomic sequence PE >> $no_genomic <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Sequences which were discarded because genomic sequence could not be extracted:/){ ## Single-end
+      (undef,$no_genomic) = split /\t/;
+      print "No genomic sequence SE>> $no_genomic <<\n" if ($verbose);
+    }
+
+    ### Context Methylation
+    elsif($_ =~ /^Total number of C/ ){
+      (undef,$total_C_count) = split /\t/;
+      print "Total number C >> $total_C_count <<\n" if ($verbose);
+    }
+
+      elsif($_ =~ /^Total methylated C\'s in CpG context:/ ){
+      (undef,$meth_CpG) = split /\t/;
+      print "meth CpG >> $meth_CpG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total methylated C\'s in CHG context:/ ){
+      (undef,$meth_CHG) = split /\t/;
+      print "meth CHG >> $meth_CHG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total methylated C\'s in CHH context:/ ){
+      (undef,$meth_CHH) = split /\t/;
+      print "meth CHH >> $meth_CHH <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total methylated C\'s in Unknown context:/ ){
+      (undef,$meth_unknown) = split /\t/;
+      print "meth Unknown >> $meth_unknown <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^Total unmethylated C\'s in CpG context:/ or $_ =~ /^Total C to T conversions in CpG context:/){
+      (undef,$unmeth_CpG) = split /\t/;
+      print "unmeth CpG >> $unmeth_CpG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total unmethylated C\'s in CHG context:/ or $_ =~ /^Total C to T conversions in CHG context:/){
+      (undef,$unmeth_CHG) = split /\t/;
+      print "unmeth CHG >> $unmeth_CHG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total unmethylated C\'s in CHH context:/ or $_ =~ /^Total C to T conversions in CHH context:/){
+      (undef,$unmeth_CHH) = split /\t/;
+      print "unmeth CHH >> $unmeth_CHH <<\n"if ($verbose);
+    }
+    elsif($_ =~ /^Total unmethylated C\'s in Unknown context:/ or $_ =~ /^Total C to T conversions in Unknown context:/){
+      (undef,$unmeth_unknown) = split /\t/;
+      print "unmeth Unknown >> $unmeth_unknown <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^C methylated in CpG context:/ ){
+      (undef,$perc_CpG) = split /\t/;
+      $perc_CpG =~ s/%//;
+      print "percentage CpG >> $perc_CpG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^C methylated in CHG context:/ ){
+      (undef,$perc_CHG) = split /\t/;
+      $perc_CHG =~ s/%//;
+      print "percentage CHG >> $perc_CHG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^C methylated in CHH context:/ ){
+      (undef,$perc_CHH) = split /\t/;
+      $perc_CHH =~ s/%//;
+      print "percentage CHH >> $perc_CHH <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^C methylated in Unknown context:/ ){
+      (undef,$perc_unknown) = split /\t/;
+      $perc_unknown =~ s/%//;
+      print "percentage Unknown >> $perc_unknown <<\n" if ($verbose);
+    }
+
+
+    ### Strand Origin
+
+    elsif($_ =~ /^CT\/GA\/CT:/ ){             ## Paired-end
+      (undef,$number_OT) = split /\t/;
+      print "Number OT PE>> $number_OT <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^CT\/CT:/ ){                 ## Single-end
+      (undef,$number_OT) = split /\t/;
+      print "Number OT SE>> $number_OT <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^GA\/CT\/CT:/ ){             ## Paired-end
+      (undef,$number_CTOT) = split /\t/;
+      print "Number CTOT PE >> $number_CTOT <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^GA\/CT:/ ){                 ## Single-end
+      (undef,$number_CTOT) = split /\t/;
+      print "Number CTOT SE >> $number_CTOT <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^GA\/CT\/GA:/ ){             ## Paired-end
+      (undef,$number_CTOB) = split /\t/;
+      print "Number CTOB PE >> $number_CTOB <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^GA\/GA:/ ){                 ## Single-end
+      (undef,$number_CTOB) = split /\t/;
+      print "Number CTOB SE >> $number_CTOB <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^CT\/GA\/GA:/ ){             ## Paired-end
+      (undef,$number_OB) = split /\t/;
+      print "Number OB PE >> $number_OB <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^CT\/GA:/ ){                 ## Single-end
+      (undef,$number_OB) = split /\t/;
+      print "Number OB SE >> $number_OB <<\n" if ($verbose);
+    }
+
+
+  }
+
+  if (defined $unique and defined $no_aln and defined $multiple and defined $no_genomic and defined $total_seqs){
+    warn "Got all necessary information, editing HTML report\n"  if ($verbose);
+
+    ### General Alignment Stats
+    $doc =~ s/\{\{unique_seqs\}\}/$unique/g;
+    $doc =~ s/\{\{unique_seqs_text\}\}/$unique_text/g;
+
+    $doc =~ s/\{\{no_alignments\}\}/$no_aln/g;
+    $doc =~ s/\{\{no_alignments_text\}\}/$no_aln_text/g;
+
+    $doc =~ s/\{\{multiple_alignments\}\}/$multiple/g;
+    $doc =~ s/\{\{multiple_alignments_text\}\}/$multiple_text/g;
+
+    $doc =~ s/\{\{no_genomic\}\}/$no_genomic/g;
+
+    $doc =~ s/\{\{total_sequences_alignments\}\}/$total_seqs/g;
+    $doc =~ s/\{\{sequences_analysed_in_total\}\}/$total_seq_text/g;
+
+    $doc =~ s/\{\{filename\}\}/$input_filename/g;
+    $doc =~ s/\{\{bismark_version\}\}/$bismark_version/g;
+
+    ### Strand Origin
+    $doc =~ s/\{\{number_OT\}\}/$number_OT/g;
+    $doc =~ s/\{\{number_CTOT\}\}/$number_CTOT/g;
+    $doc =~ s/\{\{number_CTOB\}\}/$number_CTOB/g;
+    $doc =~ s/\{\{number_OB\}\}/$number_OB/g;
+
+    ### Context Methylation
+    $doc =~ s/\{\{total_C_count\}\}/$total_C_count/g;
+
+    unless (defined $perc_CpG){
+      $perc_CpG = 'N/A';
+    }
+    unless (defined $perc_CHG){
+      $perc_CHG = 'N/A';
+    }
+    unless (defined $perc_CHH){
+      $perc_CHH = 'N/A';
+    }
+    unless (defined $perc_unknown){
+      $perc_unknown = 'N/A';
+    }
+
+    ### Unknown sequence context, just for Bowtie 2 alignments
+    my $meth_unknown_inject;
+    my $unmeth_unknown_inject;
+    my $perc_unknown_inject;
+
+    if (defined $meth_unknown){ # if one Unknown context file is present, so should the others
+      $meth_unknown_inject = "     <tr>
+                                <th>Methylated C's in Unknown context</th>
+    				<td>$meth_unknown</td>
+    			</tr>";
+      $unmeth_unknown_inject = "     <tr>
+                                <th>Unmethylated C's in Unknown context</th>
+    				<td>$unmeth_unknown</td>
+    			</tr>";
+      $perc_unknown_inject = "     <tr>
+                                <th>Methylated C's in Unknown context</th>
+    				<td>$perc_unknown%</td>
+    			</tr>";
+    }
+    else{
+      $meth_unknown_inject = $unmeth_unknown_inject = $perc_unknown_inject = '';
+    }
+
+    ### injecting this into the table
+    $doc =~ s/\{\{meth_unknown\}\}/$meth_unknown_inject/g;
+    $doc =~ s/\{\{unmeth_unknown\}\}/$unmeth_unknown_inject/g;
+    $doc =~ s/\{\{perc_unknown\}\}/$perc_unknown_inject/g;
+
+
+    $doc =~ s/\{\{meth_CpG\}\}/$meth_CpG/g;
+    $doc =~ s/\{\{meth_CHG\}\}/$meth_CHG/g;
+    $doc =~ s/\{\{meth_CHH\}\}/$meth_CHH/g;
+
+    $doc =~ s/\{\{unmeth_CpG\}\}/$unmeth_CpG/g;
+    $doc =~ s/\{\{unmeth_CHG\}\}/$unmeth_CHG/g;
+    $doc =~ s/\{\{unmeth_CHH\}\}/$unmeth_CHH/g;
+
+    $doc =~ s/\{\{perc_CpG\}\}/$perc_CpG/g;
+    $doc =~ s/\{\{perc_CHG\}\}/$perc_CHG/g;
+    $doc =~ s/\{\{perc_CHH\}\}/$perc_CHH/g;
+
+    my ($perc_CpG_graph, $perc_CHG_graph,$perc_CHH_graph,$perc_unknown_graph);
+
+    if ($perc_CpG eq 'N/A'){
+      $perc_CpG_graph = 0; # values of 0 won't show in the graph and won't produce errors
+    }
+    else{
+      $perc_CpG_graph =  $perc_CpG;
+    }
+
+    if ($perc_CHG eq 'N/A'){
+      $perc_CHG_graph = 0; # values of 0 won't show in the graph and won't produce errors
+    }
+    else{
+      $perc_CHG_graph =  $perc_CHG;
+    }
+
+    if ($perc_CHH eq 'N/A'){
+      $perc_CHH_graph = 0; # values of 0 won't show in the graph and won't produce errors
+    }
+    else{
+      $perc_CHH_graph =  $perc_CHH;
+    }
+
+    if ($perc_unknown eq 'N/A'){
+      $perc_unknown_graph = 0; # values of 0 won't show in the graph and won't produce errors
+    }
+    else{
+      $perc_unknown_graph =  $perc_unknown;
+    }
+
+    $doc =~ s/\{\{perc_CpG_graph\}\}/$perc_CpG_graph/g;
+    $doc =~ s/\{\{perc_CHG_graph\}\}/$perc_CHG_graph/g;
+    $doc =~ s/\{\{perc_CHH_graph\}\}/$perc_CHH_graph/g;
+
+  }
+  else{
+    warn "Am I missing something?\n\n";
+  }
+
+  warn "Complete\n\n";
+  return $doc;
+}
+
+
+sub read_deduplication_report{
+
+  my ($dedup_report,$doc) = @_;
+
+  warn "Processing deduplication report $dedup_report ...\n";
+  open (DEDUP,$dedup_report) or die "Couldn't read from file $dedup_report: $!\n\n";
+
+  my $total_seqs;
+  my $dups;
+  my $diff_pos;
+  my $leftover;
+
+  while (<DEDUP>){
+    chomp;
+    if ($_ =~ /^Total number of alignments/){
+      (undef,$total_seqs) = split /\t/;
+      warn "Total number of seqs >> $total_seqs <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total number duplicated/){
+      (undef,$dups) = split /\t/;
+      $dups =~ s/\s.*//; # just need the number, not the percentage
+      warn "Duplicated >> $dups <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Duplicated alignments were found at/){
+      (undef,$diff_pos) = split /\t/;
+      $diff_pos =~ s/\s.*//; # just need the number
+      warn "Different positions >> $diff_pos <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total count of deduplicated leftover sequences: (\d+)/){
+      $leftover = $1;
+      warn "Leftover seqs >> $leftover <<\n" if ($verbose);
+    }
+  }
+
+  unless (defined $leftover){
+    if (defined $dups and defined $total_seqs){
+      $leftover = $total_seqs - $dups;
+    }
+  }
+
+  # Checking if we got all we need
+  if (defined $dups and defined $total_seqs and defined $diff_pos and defined $leftover){
+    # warn "Got all I need!\n\n";
+    $doc =~ s/\{\{seqs_total_duplicates\}\}/$total_seqs/g;
+    $doc =~ s/\{\{unique_alignments_duplicates\}\}/$leftover/g;
+    $doc =~ s/\{\{duplicate_alignments_duplicates\}\}/$dups/g;
+    $doc =~ s/\{\{different_positions_duplicates\}\}/$diff_pos/g;
+  }
+  else{
+    warn "Something went wrong... Use --verbose to get a clue...\n";
+    # skipping this plot entirely if values could not be extracted
+    return $doc;
+  }
+  warn "Complete\n\n";
+  return $doc;
+}
+
+
+sub read_nucleotide_coverage_report{
+    
+    my ($nuc_report,$doc) = @_;
+    
+    warn "Processing nucleotide coverage report '$nuc_report' ...\n";
+    open (NUC,$nuc_report) or die "Couldn't read from file $nuc_report: $!\n\n";
+    
+    my %nucs; # storing nucleotides and frequencies
+    my $linecount = 0;    
+    
+    while (<NUC>){
+	chomp;
+	$_ =~ s/\r//; # removing carriage returns
+	# warn "$_\n"; sleep(1);
+	my ($element,$count_obs,$observed,$count_exp,$expected,$coverage) = (split /\t/);
+	# warn "$element , $count_obs , $observed , $count_exp , $expected, $coverage\n"; sleep(1);
+	if ($linecount == 0){ # verifying that the data appears to be a Bismark nucleotide coverage report
+	    if ($observed eq 'percent sample'){
+		# warn "Fine, found '$observed'\n";
+	    }
+	    else{
+		die "Expected to find 'percent sample' as entry in line 1, column 3 but found '$observed'. This doesn't look like a Bismark nucleotide coverage report. Please respecify!\n";
+	    }
+	    
+	    if ($expected eq 'percent genomic'){
+		# warn "Fine, found '$expected'\n";
+	    }
+	    else{
+		die "Expected to find 'percent genomic' as entry in line 1, column 5 but found '$expected'. This doesn't look like a Bismark nucleotide coverage report. Please respecify!\n";
+	    }
+	}
+	else{
+	    $nucs{$element}->{obs}->{percent}  = $observed;
+	    $nucs{$element}->{exp}->{percent}  = $expected;
+	    $nucs{$element}->{obs}->{counts}   = $count_obs;
+	    $nucs{$element}->{exp}->{counts}   = $count_exp;
+	    $nucs{$element}->{obs}->{coverage} = $coverage; # coverage of that nucleotide in the sample
+	    warn "Element '$element' observed: $observed\n" if $verbose;
+	    warn "Element '$element' expected: $expected\n" if $verbose;
+	}
+
+	++$linecount;
+
+    }
+
+    # Checking if we got all we need
+    my $looksOK = 1;
+    foreach my $key (keys %nucs){ 
+	unless ( (defined $nucs{$key}->{obs}) and (defined $nucs{$key}->{exp})){
+	    $looksOK = 0;
+	}
+    }
+    
+    if ($looksOK){ 
+	warn "Got all necessary information, editing HTML report ...\n" if $verbose;
+	my $minmax = 0;
+	foreach my $key (sort {$a cmp $b} keys %nucs){
+	    my $nuc_obs = $nucs{$key}->{obs}->{percent};
+	    my $nuc_exp = $nucs{$key}->{exp}->{percent};
+	    my $counts_obs = $nucs{$key}->{obs}->{counts};
+	    my $counts_exp = $nucs{$key}->{exp}->{counts};
+	    my $cov = $nucs{$key}->{obs}->{coverage};
+
+	    # calculating log2 observed/expected
+	    my $ratio = $nuc_obs/$nuc_exp;
+	    #  my $logratio = sprintf ("%.2f",log($ratio)/log(2));
+	    # if (abs($logratio) > $minmax){
+	    # $minmax = abs($logratio);
+	    # } 
+	    warn "$key\tnuc_${key}_obs\t$nuc_obs\tnuc_${key}_exp\t$nuc_exp\tratio: $ratio\n" if $verbose;
+
+	    $doc =~ s/\{\{nuc_${key}_p_obs\}\}/$nuc_obs/g;
+	    $doc =~ s/\{\{nuc_${key}_p_exp\}\}/$nuc_exp/g;
+	    $doc =~ s/\{\{nuc_${key}_counts_obs\}\}/$counts_obs/g;
+	    $doc =~ s/\{\{nuc_${key}_counts_exp\}\}/$counts_exp/g;
+	    $doc =~ s/\{\{nuc_${key}_coverage\}\}/$cov/g;
+	}
+	# warn "Minimum/maxium ratio was: $minmax\n" if $verbose;
+	# $doc =~ s/\{\{nuc_minmax\}\}/$minmax/g;
+    }
+    else{
+	warn "Something went wrong, skipping this plot entirely... Use --verbose to get a clue...\n";
+	# skipping this plot entirely if values could not be extracted
+	return $doc;
+    }
+
+    warn "Complete\n\n";
+    return $doc;
+}
+
+
+sub read_splitting_report{
+
+  my ($splitting_report,$doc) = @_;
+
+  warn "Processing splitting report $splitting_report ...\n";
+  open (SPLIT,$splitting_report) or die "Couldn't read from file $splitting_report: $!\n\n";
+
+  my $total_seqs;
+
+  my $total_C_count;
+  my ($meth_CpG,$meth_CHG,$meth_CHH,$meth_unknown);
+  my ($unmeth_CpG,$unmeth_CHG,$unmeth_CHH,$unmeth_unknown);
+  my ($perc_CpG,$perc_CHG,$perc_CHH,$perc_unknown);
+
+  while (<SPLIT>){
+    chomp;
+
+    ### Context Methylation
+    if($_ =~ /^Total number of C/ ){
+      (undef,$total_C_count) = split /\t/;
+      print "total calls >> $total_C_count <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^Total methylated C\'s in CpG context:/ ){
+      (undef,$meth_CpG) = split /\t/;
+      print "meth CpG >> $meth_CpG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total methylated C\'s in CHG context:/ ){
+      (undef,$meth_CHG) = split /\t/;
+      print "meth CHG>> $meth_CHG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total methylated C\'s in CHH context:/ ){
+      (undef,$meth_CHH) = split /\t/;
+      print "meth CHH >> $meth_CHH <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total methylated C\'s in Unknown context:/ ){
+      (undef,$meth_unknown) = split /\t/;
+      print "meth Unknown >> $meth_unknown <<\n" if ($verbose);
+    }
+
+    elsif($_ =~ /^Total C to T conversions in CpG context:/ ){
+      (undef,$unmeth_CpG) = split /\t/;
+      print "unmeth CpG >> $unmeth_CpG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total C to T conversions in CHG context:/ ){
+      (undef,$unmeth_CHG) = split /\t/;
+      print "unmeth CHG >> $unmeth_CHG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total C to T conversions in CHH context:/ ){
+      (undef,$unmeth_CHH) = split /\t/;
+      print "unmeth CHH >> $unmeth_CHH <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^Total C to T conversions in Unknown context:/ ){
+      (undef,$unmeth_unknown) = split /\t/;
+      print "unmeth Unknown >> $unmeth_unknown <<\n" if ($verbose);
+    } 
+
+    elsif($_ =~ /^C methylated in CpG context:/ ){
+      (undef,$perc_CpG) = split /\t/;
+      $perc_CpG =~ s/%//;
+      print "percentage CpG >> $perc_CpG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^C methylated in CHG context:/ ){
+      (undef,$perc_CHG) = split /\t/;
+      $perc_CHG =~ s/%//;
+      print "percentage CHG >> $perc_CHG <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^C methylated in CHH context:/ ){
+      (undef,$perc_CHH) = split /\t/;
+      $perc_CHH =~ s/%//;
+      print "percentage CHH >> $perc_CHH <<\n" if ($verbose);
+    }
+    elsif($_ =~ /^C methylated in Unknown context:/ ){
+      (undef,$perc_unknown) = split /\t/;
+      $perc_unknown =~ s/%//;
+      print "percentage unknown >> $perc_unknown <<\n" if ($verbose);
+    }
+  }
+
+  if (defined $meth_CpG and defined $meth_CHG and defined $meth_CHH and defined $unmeth_CpG and defined $unmeth_CHG and defined $unmeth_CHH){
+    warn "Got all necessary information, editing HTML report ...\n" if ($verbose);
+
+    ### Context Methylation
+    $doc =~ s/\{\{total_C_count_splitting\}\}/$total_C_count/g;
+
+    $doc =~ s/\{\{meth_CpG_splitting\}\}/$meth_CpG/g;
+    $doc =~ s/\{\{meth_CHG_splitting\}\}/$meth_CHG/g;
+    $doc =~ s/\{\{meth_CHH_splitting\}\}/$meth_CHH/g;
+
+    $doc =~ s/\{\{unmeth_CpG_splitting\}\}/$unmeth_CpG/g;
+    $doc =~ s/\{\{unmeth_CHG_splitting\}\}/$unmeth_CHG/g;
+    $doc =~ s/\{\{unmeth_CHH_splitting\}\}/$unmeth_CHH/g;
+
+    unless (defined $perc_CpG){
+      $perc_CpG = 'N/A';
+    }
+    unless (defined $perc_CHG){
+      $perc_CHG = 'N/A';
+    }
+    unless (defined $perc_CHH){
+      $perc_CHH = 'N/A';
+    }
+    unless (defined $perc_unknown){
+      $perc_unknown = 'N/A';
+    }
+
+    ### Unknown sequence context, just for Bowtie 2 alignments
+    my $meth_unknown_inject;
+    my $unmeth_unknown_inject;
+    my $perc_unknown_inject;
+
+    if (defined $meth_unknown){ # if one Unknown context file is present, so should the others
+      $meth_unknown_inject = "     <tr>
+                                <th>Methylated C's in Unknown context</th>
+    				<td>$meth_unknown</td>
+    			</tr>";
+      $unmeth_unknown_inject = "     <tr>
+                                <th>Unmethylated C's in Unknown context</th>
+    				<td>$unmeth_unknown</td>
+    			</tr>";
+      $perc_unknown_inject = "     <tr>
+                                <th>Methylated C's in Unknown context</th>
+    				<td>$perc_unknown%</td>
+    			</tr>";
+    }
+    else{
+      $meth_unknown_inject = $unmeth_unknown_inject = $perc_unknown_inject = '';
+    }
+
+    ### injecting this into the table
+    $doc =~ s/\{\{meth_unknown_splitting\}\}/$meth_unknown_inject/g;
+    $doc =~ s/\{\{unmeth_unknown_splitting\}\}/$unmeth_unknown_inject/g;
+    $doc =~ s/\{\{perc_unknown_splitting\}\}/$perc_unknown_inject/g;
+
+    # for the graph we need to take care that there are no N/A values in the percentage fields
+    my ($perc_CpG_graph, $perc_CHG_graph,$perc_CHH_graph,$perc_unknown_graph);
+
+    if ($perc_CpG eq 'N/A'){
+      $perc_CpG_graph = 0; # values of 0 won't show in the graph and won't produce errors
+    }
+    else{
+      $perc_CpG_graph =  $perc_CpG;
+    }
+
+    if ($perc_CHG eq 'N/A'){
+      $perc_CHG_graph = 0; # values of 0 won't show in the graph and won't produce errors
+    }
+    else{
+      $perc_CHG_graph =  $perc_CHG;
+    }
+
+    if ($perc_CHH eq 'N/A'){
+      $perc_CHH_graph = 0; # values of 0 won't show in the graph and won't produce errors
+    }
+    else{
+      $perc_CHH_graph =  $perc_CHH;
+    }
+
+    if ($perc_unknown eq 'N/A'){
+      $perc_unknown_graph = 0; # values of 0 won't show in the graph and won't produce errors
+    }
+    else{
+      $perc_unknown_graph =  $perc_unknown;
+    }
+
+    $doc =~ s/\{\{perc_CpG_graph_splitting\}\}/$perc_CpG_graph/g;
+    $doc =~ s/\{\{perc_CHG_graph_splitting\}\}/$perc_CHG_graph/g;
+    $doc =~ s/\{\{perc_CHH_graph_splitting\}\}/$perc_CHH_graph/g;
+
+    $doc =~ s/\{\{perc_CpG_splitting\}\}/$perc_CpG/g;
+    $doc =~ s/\{\{perc_CHG_splitting\}\}/$perc_CHG/g;
+    $doc =~ s/\{\{perc_CHH_splitting\}\}/$perc_CHH/g;
+  }
+  else{
+    warn "Am I missing something? Try using --verbose to get a clue...\n\n";
+  }
+  warn "Complete\n\n";
+
+  return $doc;
+
+}
+
+
+sub read_mbias_report{
+
+  my ($mbias_report,$doc) = @_;
+
+  warn "Processing M-bias report $mbias_report ...\n";
+  open (MBIAS,$mbias_report) or die "Couldn't read from file $mbias_report: $!\n\n";
+
+  my %mbias_1;
+  my %mbias_2;
+
+  my $context;
+  my $read_identity;
+  my $state = 'single'; # setting this to 'single' if there is no read 2
+
+  while (<MBIAS>){
+    chomp;
+    if ($_ =~ /^(C.{2}) context/){
+      $context = $1;
+
+      if ($_ =~ /R2/){
+	$read_identity = 2;
+	$state = 'paired';
+      }
+      else{
+	$read_identity = 1;
+      }
+
+      # warn "new context is: $context\n";
+      # warn "Read identity is: Read $read_identity\n";
+    }
+    if ($_ =~ /^\d/){
+      my ($pos,$meth,$unmeth,$perc,$coverage) = (split /\t/);
+      if ($read_identity == 1){
+	push @{$mbias_1{$context}->{coverage}}, "[$pos, $coverage]";
+	push @{$mbias_1{$context}->{perc}}, "[$pos, $perc]";
+      }
+      elsif ($read_identity == 2){
+	push @{$mbias_2{$context}->{coverage}}, "[$pos, $coverage]";
+	push @{$mbias_2{$context}->{perc}}, "[$pos, $perc]";
+      }
+      else{
+	warn "read identity was unknown : '$read_identity'\n\n";
+      }
+
+      # print join (" ",$pos,$meth,$unmeth,$perc,$coverage)."\n";
+    }
+  }
+
+  # Read 1 M-bias
+  my $r1_CpG_coverage = join (',',@{$mbias_1{'CpG'}->{coverage}});
+  my $r1_CpG_perc     = join (',',@{$mbias_1{'CpG'}->{perc}});
+
+  my $r1_CHG_coverage = join (',',@{$mbias_1{'CHG'}->{coverage}});
+  my $r1_CHG_perc     = join (',',@{$mbias_1{'CHG'}->{perc}});
+
+  my $r1_CHH_coverage = join (',',@{$mbias_1{'CHH'}->{coverage}});
+  my $r1_CHH_perc     = join (',',@{$mbias_1{'CHH'}->{perc}});
+
+  $doc =~ s/\{\{CpG_total_calls_R1\}\}/$r1_CpG_coverage/g;
+  $doc =~ s/\{\{CHG_total_calls_R1\}\}/$r1_CHG_coverage/g;
+  $doc =~ s/\{\{CHH_total_calls_R1\}\}/$r1_CHH_coverage/g;
+
+  $doc =~ s/\{\{CpG_methylation_R1\}\}/$r1_CpG_perc/g;
+  $doc =~ s/\{\{CHG_methylation_R1\}\}/$r1_CHG_perc/g;
+  $doc =~ s/\{\{CHH_methylation_R1\}\}/$r1_CHH_perc/g;
+
+  # Read 2 M-bias
+  if (%mbias_2){
+      my $r2_CpG_coverage = join (',',@{$mbias_2{'CpG'}->{coverage}});
+      my $r2_CpG_perc     = join (',',@{$mbias_2{'CpG'}->{perc}});
+      
+      my $r2_CHG_coverage = join (',',@{$mbias_2{'CHG'}->{coverage}});
+      my $r2_CHG_perc     = join (',',@{$mbias_2{'CHG'}->{perc}});
+      
+      my $r2_CHH_coverage = join (',',@{$mbias_2{'CHH'}->{coverage}});
+      my $r2_CHH_perc     = join (',',@{$mbias_2{'CHH'}->{perc}});
+      
+      $doc =~ s/\{\{CpG_total_calls_R2\}\}/$r2_CpG_coverage/g;
+      $doc =~ s/\{\{CHG_total_calls_R2\}\}/$r2_CHG_coverage/g;
+      $doc =~ s/\{\{CHH_total_calls_R2\}\}/$r2_CHH_coverage/g;
+      
+      $doc =~ s/\{\{CpG_methylation_R2\}\}/$r2_CpG_perc/g;
+      $doc =~ s/\{\{CHG_methylation_R2\}\}/$r2_CHG_perc/g;
+      $doc =~ s/\{\{CHH_methylation_R2\}\}/$r2_CHH_perc/g;
+  }
+  warn "Complete\n\n";
+
+  return ($state,$doc);
+
+}
+
+
+sub read_report_template{
+  my $doc;
+  warn "Attempting to open file from: $Bin/bismark_sitrep.tpl\n\n" if ($verbose);
+  open (DOC,"$Bin/bismark_sitrep.tpl") or die $!;
+  while(<DOC>){
+    chomp;
+    $_ =~ s/\r//g;
+    $doc .= $_."\n";
+  }
+
+  close DOC or die $!;
+  return $doc;
+}
+
+
+
+sub process_commandline{
+  my $help;
+  my $output_dir;
+  my $manual_output_file;
+  my $alignment_report;
+  my $dedup_report;
+  my $splitting_report;
+  my $mbias_report;
+  my $nucleotide_coverage_report;  # stores nucleotide coverage statistics
+  my $verbose;
+
+  my $version;
+
+  my $command_line = GetOptions ('help|man'              => \$help,
+				 'dir=s'                 => \$output_dir,
+				 'o|output=s'            => \$manual_output_file,
+				 'alignment_report=s'    => \$alignment_report,
+				 'dedup_report=s'        => \$dedup_report,
+				 'splitting_report=s'    => \$splitting_report,
+				 'mbias_report=s'        => \$mbias_report,
+				 'nucleotide_report=s'   => \$nucleotide_coverage_report, 
+				 'version'               => \$version,
+				 'verbose'               => \$verbose,
+				);
+
+  ### EXIT ON ERROR if there were errors with any of the supplied options
+  unless ($command_line){
+    die "Please respecify command line options\n";
+  }
+
+  ### HELPFILE
+  if ($help){
+    print_helpfile();
+    exit;
+  }
+
+  if ($version){
+    print << "VERSION";
+
+
+                              Bismark HTML Report Module
+
+                         bismark2report version: $bismark2report_version
+                            Copyright 2010-16 Felix Krueger
+                               Babraham Bioinformatics
+                www.bioinformatics.babraham.ac.uk/projects/bismark/
+
+
+VERSION
+    exit;
+  }
+
+  ### OUTPUT DIR PATH
+  if (defined $output_dir){
+    unless ($output_dir eq ''){ # if the output dir has been passed on by the methylation extractor and is an empty string we don't want to change it
+      unless ($output_dir =~ /\/$/){
+	$output_dir =~ s/$/\//;
+      }
+    }
+  }
+  else{
+    $output_dir = '';
+  }
+
+
+  ## First we are looking for alignment reports, and then look whether there are any optional plots with the same base name
+
+  if ($alignment_report){
+    ### we only process the one alignment report (and possibly the other ones as well) that was specified
+    push @alignment_reports, $alignment_report;
+  }
+  else{ ### no alignment report specified, looking in the current directory for files ending in *E_report.txt (SE or PE)
+
+    ### looking in the current directory for report files. Less than 1 report file is not allowed
+    @alignment_reports = <*E_report.txt>;
+
+    if (scalar @alignment_reports == 0){
+      warn "Found no potential alignment reports in the current directory. Please specify a single Bismark alignment report file using the option '--alignment_report FILE'\n\n";
+      print_helpfile();
+      exit;
+    }
+    else{
+      # there are Bismark alignment report(s) in the directory
+      warn "Found ",scalar @alignment_reports," alignment reports in current directory. Now trying to figure out whether there are corresponding optional reports\n";
+    }
+  }
+
+  ### Ensuring that there isn't more than 1 file in @alignment_reports if someone manually specified an output file.
+  if (scalar @alignment_reports > 1){
+    if (defined $manual_output_file){
+      die "You cannot run bismark2report on more than 1 file while specifying a single output file. Either lose the option -o to derive the output filenames automatically, or specify a single Bismark alignment report file using the option '--alignment_report FILE'\n\n";
+    }
+  }
+
+  foreach my $aln (@alignment_reports){
+
+    # warn "Figuring things out for:\n$aln\n";
+    $aln =~ /^(.+)_(P|S)E_report.txt$/;
+    my $basename = $1;
+    # warn "using this basename:\n$basename\n\n";
+
+    ### DEDUPLICATION REPORT (optional)
+    if ($dedup_report){
+	warn "User specifified dedup report: $dedup_report\n";sleep(3);
+      if (lc$dedup_report eq 'none'){
+	push @dedup_reports, ''; # user may wish to skip this step by specifying 'none'
+      }
+      else{
+	push @dedup_reports, $dedup_report;
+      }
+    }
+    else{
+      ### looking in the current directory for a report file with the same base name
+      my @dedup_report_files = <$basename*deduplication_report.txt>;
+      # warn "Number of deduplication reports found in current directory for basename $1: ", scalar @dedup_report_files , "\n";
+
+      if (scalar @dedup_report_files > 1){
+	die "Found ", scalar @dedup_report_files ," potential deduplication reports with the same basename ($basename) in the current directory. Please specify a single report using the option '--dedup_report FILE' or otherwise provide filenames that are easier to figure out...\n\n";
+      }
+      elsif (scalar @dedup_report_files == 0){
+	push @dedup_reports, ''; # no corresponding deduplication report found
+      }
+      else{
+	# there is only a single deduplication report in the current directory, using this one
+	$dedup_report = shift @dedup_report_files;
+	push @dedup_reports, $dedup_report;
+	# warn "Going to use this dedup report: $dedup_report\n\n";
+      }
+    }
+
+    ### NUCLEOTIDE COVERAGE REPORT (optional)
+    if (defined $nucleotide_coverage_report){
+	# warn "User specified nucleotide coverage report: $nucleotide_coverage_report\n";sleep(1);
+	if (lc$nucleotide_coverage_report eq 'none'){
+	    push @nuc_reports, ''; # user may wish to skip this step by specifying 'none'
+	}
+	else{
+	    push @nuc_reports, $nucleotide_coverage_report;
+	}
+    }
+    else{
+	### looking in the current directory for a report file with the same base name
+	my @nucleotide_coverage_report_files = <$basename*nucleotide_stats.txt>;
+	# warn "Number of nucleotide coverage statistic reports found in current directory for basename $1: ", scalar @nucleotide_coverage_report_files , "\n";
+	
+	if (scalar @nucleotide_coverage_report_files > 1){
+	    die "Found ", scalar @nucleotide_coverage_report_files ," potential nucleotide coverage reports with the same basename ($basename) in the current directory. Please specify a single report using the option '--nucleotide_report FILE' or otherwise provide filenames that are easier to figure out...\n\n";
+	}
+	elsif (scalar @nucleotide_coverage_report_files == 0){
+	    # warn "Found no corresponding nucleotide coverage file\n";
+	    push @nuc_reports, ''; # no corresponding nucleotide coverge file report found
+	}
+	else{
+	    # there is only a single nucleotide coverage report in the current directory, using this one
+	    $nucleotide_coverage_report = shift @nucleotide_coverage_report_files;
+	    push @nuc_reports, $nucleotide_coverage_report;
+	    # warn "Going to use this nucleotide coverage report: $nucleotide_coverage_report\n\n"; sleep(3);
+	}
+    }
+
+    
+    ### METHYLATION EXTRACTOR SPLITTING REPORT
+    if ($splitting_report){
+      if (lc$splitting_report eq 'none'){
+	push @splitting_reports, ''; # user may wish to skip this step by specifying 'none'
+      }
+      else{
+	push @splitting_reports, $splitting_report;
+      }
+    }
+    else{
+      ### looking in the current directory for a report file with the same basename
+      my @splitting_report_files = <$basename*splitting_report.txt>;
+      # warn "Number of splitting reports found in current directory: ", scalar @splitting_report_files , "\n";
+
+      if (scalar @splitting_report_files > 1){
+	die "Found ", scalar @splitting_report_files ," potential methylation extractor splitting reports with the same basename ($basename) in the current directory. Please specify a single report using the option '--splitting_report FILE' or otherwise provide filenames that are easier to figure out...\n\n";
+      }
+      elsif (scalar @splitting_report_files == 0){
+	push @splitting_reports, ''; # no corresponding methylation extractor report found
+      }
+      else{
+	# there is only a single splitting report in the current directory, using this one
+	$splitting_report = shift @splitting_report_files;
+	push  @splitting_reports, $splitting_report;
+      }
+    }
+
+    ### M-BIAS REPORT
+    if ($mbias_report){
+      if (lc$mbias_report eq 'none'){
+	$mbias_report = ''; # user may wish to skip this step by specifying 'none'
+   	push @mbias_reports, $mbias_report;
+      }
+      else{
+	push @mbias_reports, $mbias_report;
+      }
+    }
+    else{
+      ### looking in the current directory for a single report file. More (or less) than 1 report file is not allowed
+      my @mbias_report_files = <$basename*M-bias.txt>;
+
+      # warn "Number of M-bias reports found in current directory: ", scalar @mbias_report_files , "\n";
+
+      if (scalar @mbias_report_files > 1){
+	die "Found ", scalar @mbias_report_files ," potential M-bias reports with the same basename ($basename) in the current directory. Please specify a single report using the option '--mbias_report FILE'or otherwise provide filenames that are easier to figure out automatically ...\n\n";
+      }
+      elsif (scalar @mbias_report_files == 0){
+	push @mbias_reports, '';
+      }
+      else{
+	# there is only a single M-bias report in the current directory, using this one
+	$mbias_report = shift @mbias_report_files;
+	push @mbias_reports, $mbias_report;
+      }
+    }
+    $dedup_report = $splitting_report = $mbias_report = $nucleotide_coverage_report = undef;
+  }
+
+  return ($output_dir,$verbose,$manual_output_file);
+
+}
+
+sub print_helpfile{
+  print <<EOF
+
+  SYNOPSIS:
+
+  This script uses a Bismark alignment report to generate a graphical HTML report page. Optionally, further reports of
+  the Bismark suite such as deduplication, methylation extractor splitting or M-bias reports can be specified as well. If several
+  Bismark reports are found in the same folder, a separate report will be generated for each of these, whereby the output filename
+  will be derived from the Bismark alignment report file. Bismark2report attempts to find optional reports automatically based
+  on the file basename.
+
+
+  USAGE: bismark2report [options]
+
+
+-o/--output <filename>     Name of the output file (optional). If not specified explicitly, the output filename will be derived
+                           from the Bismark alignment report file. Specifying an output filename only works if the HTML report is
+                           to be generated for a single Bismark alignment report (and potentially additional reports).
+
+--dir                      Output directory. Output is written to the current directory if not specified explicitly.
+
+
+--alignment_report FILE    If not specified explicitly, bismark2report attempts to find Bismark report file(s) in the current
+                           directory and produces a separate HTML report for each mapping report file. Based on the basename of
+                           the Bismark mapping report, bismark2report will also attempt to find the other Bismark reports (see below)
+                           for inclusion into the HTML report. Specifying a Bismark alignment report file is mandatory.
+
+--dedup_report FILE        If not specified explicitly, bismark2report attempts to find a deduplication report file with the same
+                           basename as the Bismark mapping report (generated by deduplicate_bismark) in the
+                           current working directory. Including a deduplication report is optional, and using the FILE 'none'
+                           will skip this step entirely.
+
+--splitting_report FILE    If not specified explicitly, bismark2report attempts to find a splitting report file with the same
+                           basename as the Bismark mapping report (generated by the Bismark methylation extractor) in the current
+                           working directory. Including a splitting report is optional, and using the FILE 'none' will skip this
+                           step entirely.
+
+--mbias_report FILE        If not specified explicitly, bismark2report attempts to find a single M-bias report file with the same
+                           basename as the Bismark mapping report (generated by the Bismark methylation extractor) in the current
+                           working directory. Including an M-Bias report is optional, and using the FILE 'none' will skip this step
+                           entirely.
+
+--nucleotide_report FILE   If not specified explicitly, bismark2report attempts to find a single nucleotide coverage report file
+                           with the same basename as the Bismark mapping report (generated by Bismark with the option
+                           '--nucleotide_coverage') in the current working directory. Including a nucleotide coverage statistics
+                           report is optional, and using the FILE 'none' will skip this report entirely.
+
+                           Script last modified: 13 May 2016
+
+EOF
+    ;
+  exit 1;
+}
+