From fb8373ab777249ba1c1ce4ab23e38badf87429c0 Mon Sep 17 00:00:00 2001
From: bow <bow@bow.web.id>
Date: Fri, 6 Mar 2015 19:29:34 +0100
Subject: [PATCH] Initial report

---
 .../pipelines/gentrap/scripts/pdf_report.py   |  79 ++-
 .../pipelines/gentrap/templates/pdf/lib.tex   |   4 +
 .../gentrap/templates/pdf/lib_seqeval.tex     | 503 ++++++++++++++++++
 .../pipelines/gentrap/templates/pdf/main.tex  |  33 +-
 .../gentrap/templates/pdf/sample.tex          |   9 +
 .../pipelines/gentrap/templates/pdf/test.tex  |   1 -
 6 files changed, 609 insertions(+), 20 deletions(-)
 create mode 100644 public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/lib.tex
 create mode 100644 public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/lib_seqeval.tex
 create mode 100644 public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/sample.tex
 delete mode 100644 public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/test.tex

diff --git a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/scripts/pdf_report.py b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/scripts/pdf_report.py
index 930c5eeae..7430b2f1e 100755
--- a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/scripts/pdf_report.py
+++ b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/scripts/pdf_report.py
@@ -30,6 +30,7 @@ from os import path
 
 from jinja2 import Environment, FileSystemLoader
 
+
 # set locale for digit grouping
 locale.setlocale(locale.LC_ALL, "")
 
@@ -68,11 +69,15 @@ class LongTable(object):
 
 
 # filter functions for the jinja environment
-def nice_int(num):
+def nice_int(num, default="None"):
+    if num is None:
+        return default
     return locale.format("%i", int(num), grouping=True)
 
 
-def nice_flt(num):
+def nice_flt(num, default="None"):
+    if num is None:
+        return default
     return locale.format("%.2f", float(num), grouping=True)
 
 
@@ -84,7 +89,7 @@ def natural_sort(inlist):
     return inlist
 
 
-def write_template(summary_file, template_file, logo_file):
+def write_template(run, template_file, logo_file):
 
     template_file = path.abspath(path.realpath(template_file))
     template_dir = path.dirname(template_file)
@@ -109,17 +114,74 @@ def write_template(summary_file, template_file, logo_file):
 
     # write tex template for pdflatex
     jinja_template = env.get_template(path.basename(template_file))
+    run.logo = logo_file
     render_vars = {
-        "gentrap": {
-            "version": "--testing--",
-            "logo": logo_file,
-        },
+        "run": run,
     }
     rendered = jinja_template.render(**render_vars)
 
     print(rendered, file=sys.stdout)
 
 
+class GentrapLib(object):
+
+    def __init__(self, run, sample, name, summary):
+        assert isinstance(run, GentrapRun)
+        assert isinstance(sample, GentrapSample)
+        self.run = run
+        self.sample = sample
+        self.name = name
+        self._raw = summary
+        self.flexiprep = summary.get("flexiprep", {})
+        self.clipping = not self.flexiprep["settings"]["skip_clip"]
+        self.trimming = not self.flexiprep["settings"]["skip_trim"]
+        self.is_paired_end = self.flexiprep["settings"]["paired"]
+
+    def __repr__(self):
+        return "{0}(sample=\"{1}\", lib=\"{2}\")".format(
+                self.__class__.__name__, self.sample.name, self.name)
+
+
+class GentrapSample(object):
+
+    def __init__(self, run, name, summary):
+        assert isinstance(run, GentrapRun)
+        self.run = run
+        self.name = name
+        self._raw = summary
+        self.lib_names = sorted(summary["libraries"].keys())
+        self.libs = \
+            {l: GentrapLib(self.run, self, l, summary["libraries"][l]) \
+                for l in self.lib_names}
+
+    def __repr__(self):
+        return "{0}(\"{1}\")".format(self.__class__.__name__, self.name)
+
+
+class GentrapRun(object):
+
+    def __init__(self, summary_file):
+
+        with open(summary_file, "r") as src:
+            summary = json.load(src)
+
+        self._raw = summary
+        self.summary_file = summary_file
+        self.sample_names = sorted(summary["samples"].keys())
+        self.samples = \
+            {s: GentrapSample(self, s, summary["samples"][s]) \
+                for s in self.sample_names}
+
+        self.files = summary["gentrap"]["files"]
+        self.executables = summary["gentrap"]["executables"]
+        self.settings = summary["gentrap"]["settings"]
+        self.version = self.settings["version"]
+
+    def __repr__(self):
+        return "{0}(\"{1}\")".format(self.__class__.__name__,
+                                        self.summary_file)
+
+
 if __name__ == "__main__":
 
     parser = argparse.ArgumentParser()
@@ -131,4 +193,5 @@ if __name__ == "__main__":
             help="Path to main logo file")
     args = parser.parse_args()
 
-    write_template(args.summary_file, args.template_file, args.logo_file)
+    run = GentrapRun(args.summary_file)
+    write_template(run, args.template_file, args.logo_file)
diff --git a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/lib.tex b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/lib.tex
new file mode 100644
index 000000000..4bc4e07ed
--- /dev/null
+++ b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/lib.tex
@@ -0,0 +1,4 @@
+\section{Library "((( lib.name )))" Results}
+\label{lib:(((lib.name)))}
+
+((* include "lib_seqeval.tex" *))
diff --git a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/lib_seqeval.tex b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/lib_seqeval.tex
new file mode 100644
index 000000000..8578963b3
--- /dev/null
+++ b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/lib_seqeval.tex
@@ -0,0 +1,503 @@
+\subsection{Sequencing Results Evaluation}
+\label{sec:seq}
+
+This section contains statistics of the raw sequencing results. Statistics of
+the preprocessing step(s) may be shown as well, depending on which preprocessing
+steps were performed.
+(Table~\ref{tab:pipelineparams}).
+
+\indent
+
+All statistics, except for the per sequence \%GC graph, were collected using
+FastQC. Visit the
+\href{http://www.bioinformatics.babraham.ac.uk/projects/fastqc/}{FastQC website}
+for more detailed explanations of them.
+
+\subsubsection{Overview}
+\label{subsec:seq-overview}
+There are four types of preprocessing that may be done:
+
+\begin{description}
+    \item[\textit{none}] \hfill \\
+        No preprocessing step.
+    \item[\textit{adapter clipping}] \hfill \\
+        Removal of known adapter sequences present in the sequencing
+        reads. The list of sequences are retrieved from the FastQC contaminant
+        list, which is packaged with the FastQC released used in this pipeline.
+    \item[\textit{quality trimming}] \hfill \\
+        Removal of all low-quality bases that are often found in the 5'
+        or 3' ends of the reads.
+    \item[\textit{adapter clipping followed by quality trimming}] \hfill \\
+        Both adapter clipping and base quality trimming.
+\end{description}
+\indent
+Your chosen preprocessing method was:\textbf{
+((* if lib.clipping *))adapter clipping
+((* elif lib.trimming *))quality trimming
+((* elif lib.clipping and lib.trimming *))adapter clipping followed by quality trimming((* endif *))}.
+
+((* if lib.clipping *))
+\subsubsection{Adapter removal}
+Known adapter sequences found in the raw data are listed in
+Table~\ref{tab:adapters}. For each adapter sequence, the count of its
+occurence (partially or whole) is also listed. The presence of these
+adapters do not always result in the FASTQ records to be discarded.
+FASTQ records are only discarded if clipping of the adapter sequence
+results in sequences shorter than the threshold set in cutadapt.
+
+\indent
+
+For the complete list of known adapter sequences, consult the
+\href{http://www.bioinformatics.babraham.ac.uk/projects/fastqc/}{official FastQC website}.
+More information about clipping using cutadapt is available on the
+\href{https://code.google.com/p/cutadapt/}{official cutadapt website}.
+
+%\ClipContamTable
+\begin{center}
+    \captionof{table}{Adapter Sequences Present in the Sample}
+    \label{tab:adapters}
+    \begin{longtable}{ p{14mm} r p{0.4\textwidth} r }
+            \hline
+            Read & Discarded & Adapter & Occurence\\
+            \hline \hline
+        \endhead
+            \hline
+            \multicolumn{4}{c}{\textit{Continued on next page}}\\
+            \hline
+        \endfoot
+            \hline
+        \endlastfoot
+        ((* if lib.flexiprep.stats.clipping_R1 *))
+            ((* if lib.flexiprep.stats.clipping_R1.adapters *))
+                Read 1 & ((( lib.flexiprep.stats.clipping_R1.num_reads_affected|nice_int )))
+                ((* for adapter, count in lib.flexiprep.stats.clipping_R1.adapters.iteritems() *))
+                ((* if loop.first *))
+                    & ((( adapter ))) & ((( count|nice_int )))\\
+                ((* else *))
+                    & & ((( adapter ))) & ((( count|nice_int )))\\
+                ((* endif *))
+                ((* endfor *))
+            ((* else *))
+                Read 1 & 0 & \textit{none found} & 0\\
+            ((* endif *))
+            ((* if lib.is_paired_end *))
+                ((* if lib.flexiprep.stats.clipping_R2.adapters *))
+                    Read 2 & ((( lib.flexiprep.stats.clipping_R2.num_reads_affected|nice_int )))
+                    ((* for adapter, count in lib.flexiprep.stats.clipping_R2.adapters.iteritems() *))
+                    ((* if loop.first *))
+                        & ((( adapter ))) & ((( count|nice_int )))\\
+                    ((* else *))
+                        & & ((( adapter ))) & ((( count|nice_int )))\\
+                    ((* endif *))
+                    ((* endfor *))
+                ((* else *))
+                    Read 2 & 0 & \textit{none found} & 0\\
+                ((* endif *))
+            ((* endif *))
+        ((* endif *))
+    \end{longtable}
+\end{center}
+\addtocounter{table}{-1}
+
+((* if lib.is_paired_end *))
+After clipping, all read pairs are then checked ('synced') for their
+completeness. Read pairs whose other half has been discarded during
+clipping, will also be discarded. The summary of this step is available in
+Table~\ref{tab:clipsync}.
+
+\begin{center}
+    \captionof{table}{Summary of Post-Clipping Sync Step}
+    \label{tab:clipsync}
+    \begin{tabular}{ l  r }
+        \hline
+        Parameter & Count\\ \hline \hline
+        Discarded FASTQ records from read 1 & ((( lib.flexiprep.stats.fastq_sync.num_reads_discarded_R1|nice_int )))\\
+        Discarded FASTQ records from read 2 & ((( lib.flexiprep.stats.fastq_sync.num_reads_discarded_R2|nice_int )))\\
+        \hline
+        Total kept FASTQ records & ((( lib.flexiprep.stats.fastq_sync.num_reads_kept|nice_int )))\\
+        \hline
+    \end{tabular}
+\end{center}
+((* endif *))
+((* endif *))
+
+\vspace{2mm}
+((* if lib.trimming and lib.is_paired_end *))
+\subsubsection{Base quality trimming}
+    Summary of the trimming step is available in Table~\ref{tab:trim}. In short,
+    sickle is used to trim the 5' and 3' ends of each FASTQ records so that low
+    quality bases are trimmed off. If after trimming the FASTQ record becomes
+    shorter than the threshold set by sickle, the entire sequence is discarded. For this
+    step, read pair completeness check was done along with trimming.
+
+    \indent
+
+    More information about sickle is available on the
+    \href{https://github.com/najoshi/sickle}{official sickle website}.
+
+    \begin{center}
+        \captionof{table}{Summary of quality trimming step}
+        \label{tab:trim}
+        \begin{tabular}{ l  r }
+            \hline
+            Parameter & Count\\ \hline \hline
+            Discarded FASTQ records from read 1 & ((( lib.flexiprep.stats.trimming.num_reads_discarded_R1|nice_int )))\\
+            Discarded FASTQ records from read 2 & ((( lib.flexiprep.stats.trimming.num_reads_discarded_R2|nice_int )))\\
+            Discarded FASTQ records from both reads & ((( lib.flexiprep.stats.trimming.num_paired_reads_discarded|nice_int )))\\
+            \hline
+            Total kept FASTQ read pairs & ((( lib.flexiprep.stats.trimming.num_paired_reads_kept|nice_int )))\\
+            \hline
+        \end{tabular}
+    \end{center}
+((* endif *))
+\vspace{2mm}
+
+\subsubsection{Basic statistics}
+%\label{subsec:seq_basic}
+((=
+%Basic statistics on the FASTQ files are shown below. For paired-end reads, the
+%read count numbers of read 1 and read 2, both before and after preprocessing,
+%must match. Read lengths are likely to vary after preprocessing, due to selective
+%clipping and trimming of the reads.
+%
+%\begin{center}
+%    \captionof{table}{Basic Run Statistics}
+%    \label{tab:basestats}
+%((* if lib.clipping or lib.trimming *))
+%        \begin{longtable}{ l r r }
+%                \hline
+%                Parameter & Raw & Preprocessed \\ \hline \hline
+%                \hline \hline
+%            \endhead
+%                \hline
+%                \multicolumn{3}{c}{\textit{Continued on next page}}\\
+%                \hline
+%            \endfoot
+%                \hline
+%            \endlastfoot
+%            Read 1 count & ((( fastqc_stats['samplea']['raw']['count']|nice_int ))) & ((( fastqc_stats['samplea']['proc']['count']|nice_int )))\\
+%            Read 1 overall \%GC & ((( fastqc_stats['samplea']['raw']['gc'] ))) & ((( fastqc_stats['samplea']['proc']['gc'] )))\\
+%            Read 1 length range & ((( fastqc_stats['samplea']['raw']['length'] ))) & ((( fastqc_stats['samplea']['proc']['length'] )))\\
+%            \hline
+%    ((* if run.is_paired_end *))
+%            Read 2 count & ((( fastqc_stats['sampleb']['raw']['count']|nice_int ))) & ((( fastqc_stats['sampleb']['proc']['count']|nice_int )))\\
+%            Read 2 overall \%GC & ((( fastqc_stats['sampleb']['raw']['gc'] ))) & ((( fastqc_stats['sampleb']['proc']['gc'] )))\\
+%            Read 2 length range & ((( fastqc_stats['sampleb']['raw']['length'] ))) & ((( fastqc_stats['sampleb']['proc']['length'] )))\\
+%            \hline
+%    ((* endif *))
+%((* else *))
+%        \begin{longtable}{ l r }
+%                \hline
+%                Parameter & Raw \\ \hline \hline
+%                \hline \hline
+%            \endhead
+%                \hline
+%                \multicolumn{2}{c}{\textit{Continued on next page}}\\
+%                \hline
+%            \endfoot
+%                \hline
+%            \endlastfoot
+%            Read 1 count & ((( fastqc_stats['samplea']['raw']['count']|nice_int )))\\
+%            Read 1 overall \%GC & ((( fastqc_stats['samplea']['raw']['gc'] )))\\
+%            Read 1 length range & ((( fastqc_stats['samplea']['raw']['length'] )))\\
+%            \hline
+%    ((* if run.is_paired_end *))
+%            Read 1 count & ((( fastqc_stats['sampleb']['raw']['count']|nice_int )))\\
+%            Read 1 overall \%GC & ((( fastqc_stats['sampleb']['raw']['gc'] )))\\
+%            Read 1 length range & ((( fastqc_stats['sampleb']['raw']['length'] )))\\
+%            \hline
+%    ((* endif *))
+%((* endif *))
+%        \end{longtable}
+%\end{center}
+%
+%\clearpage
+%% sequence length distribution
+%\subsubsection{Read length distribution}
+%\newcommand{\pathSeqL}{Images/sequence_length_distribution.png}
+%\newcommand{\capSeqL}{Read length distribution }
+%    Read length distribution for the raw read pair data are shown below.
+%    Depending on your chosen preprocessing step, the length distribution for the
+%    preprocessed data may be shown as well. The length distribution for the
+%    preprocessed data usually becomes less uniform compared to the raw data due
+%    to the variable removal of the bases in each read.
+%    \begin{figure}[h!]
+%        \centering
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            \subfloat[Raw read 1]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['samplea']['raw']['res_dir'])))/\pathSeqL}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%            \subfloat[Preprocessed read 1]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['samplea']['proc']['res_dir'])))/\pathSeqL}
+%            }
+%            ((* endif *))
+%        \end{minipage}
+%        \caption{\capSeqL for read 1.}
+%        %\label{fig:length_dist_before_and_after_1}
+%    \end{figure}
+%
+%((* if run.is_paired_end *))
+%    \begin{figure}[h!]
+%        \centering
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            \subfloat[Raw read 2]{
+%            \includegraphics[width=\textwidth]{((( fastqc_stats['sampleb']['raw']['res_dir'])))/\pathSeqL}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%            \subfloat[Preprocessed read 2]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['sampleb']['proc']['res_dir'])))/\pathSeqL}
+%            }
+%            ((* endif *))
+%        \end{minipage}
+%        \caption{\capSeqL for read 2.}
+%        %\label{fig:length_dist_before_and_after_2}
+%    \end{figure}
+%((* endif *))
+%
+%
+%% per base sequence quality
+%\clearpage
+%\subsubsection{Per base sequence quality}
+%\newcommand{\pathBaseQ}{Images/per_base_quality.png}
+%\newcommand{\capBaseQ}{Per base quality before and after processing }
+%    Here, the sequence quality for different base positions in all read pairs
+%    are shown. For each figure, the central line represents the median value,
+%    the blue represents the mean, the yellow box represents the inter-quartile
+%    range (25\%-75\%), and the upper and lower whiskers represent the 10\% and
+%    90\% points respectively. The green-shaded region marks good quality calls,
+%    orange-shaded regins mark reasonable quality calls, and red-shaded regions
+%    mark poor quality calls.
+%    
+%    \indent
+%
+%    Note that the latter base positions shown in the figures are
+%    sometimes aggregates of multiple positions.
+%    \begin{figure}[h!]
+%        \centering
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            \subfloat[Raw read 1]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['samplea']['raw']['res_dir'])))/\pathBaseQ}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%            \subfloat[Preprocessed read 1]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['samplea']['proc']['res_dir'])))/\pathBaseQ}
+%            }
+%            ((* endif *))
+%        \end{minipage}
+%        \caption{\capBaseQ for read 1.}
+%        %\label{fig:per_base_qual_before_and_after_1}
+%    \end{figure}
+%
+%((* if run.is_paired_end *))
+%    \begin{figure}[h!]
+%        \centering
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            \subfloat[Raw read 2]{
+%            \includegraphics[width=\textwidth]{((( fastqc_stats['sampleb']['raw']['res_dir'])))/\pathBaseQ}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%            \subfloat[Preprocessed read 2]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['sampleb']['proc']['res_dir'])))/\pathBaseQ}
+%            }
+%            ((* endif *))
+%        \end{minipage}
+%        \caption{\capBaseQ for read 2.}
+%        %\label{fig:per_base_qual_before_and_after_2}
+%    \end{figure}
+%((* endif *))
+%
+%% per sequence quality scores
+%\clearpage
+%\subsubsection{Per sequence quality scores}
+%\newcommand{\pathSeqQ}{Images/per_sequence_quality.png}
+%\newcommand{\capSeqQ}{Per sequence quality scores before and after preprocessing }
+%    The read quality score distributions are shown below.
+%    \begin{figure}[h!]
+%        \centering
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            \subfloat[Raw read 1]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['samplea']['raw']['res_dir'])))/\pathSeqQ}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%            \subfloat[Preprocessed read 1]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['samplea']['proc']['res_dir'])))/\pathSeqQ}
+%            }
+%            ((* endif *))
+%        \end{minipage}
+%        \caption{\capSeqQ for read 1.}
+%        %\label{fig:per_seq_qual_before_and_after_1}
+%    \end{figure}
+%
+%((* if run.is_paired_end *))
+%    \begin{figure}[h!]
+%        \centering
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            \subfloat[Raw read 2]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['sampleb']['raw']['res_dir'])))/\pathSeqQ}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%            \subfloat[Preprocessed read 2]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['sampleb']['proc']['res_dir'])))/\pathSeqQ}
+%            }
+%            ((* endif *))
+%        \end{minipage}
+%        \caption{\capSeqQ for read 2.}
+%        %\label{fig:per_seq_qual_before_and_after_2}
+%    \end{figure}
+%((* endif *))
+%
+%% per base sequence content
+%\clearpage
+%\subsubsection{Per base sequence content}
+%\newcommand{\pathBaseC}{Images/per_base_sequence_content.png}
+%\newcommand{\capBaseC}{Per base sequence content before and after preprocessing }
+%    The figures below plot the occurence of each nucleotide in each position in
+%    the reads. In a completely random library, you would expect the differences
+%    among each nucleotide to be minor. You may sometimes see a skewed
+%    proportion of nucleotides near the start of the read due to the use of
+%    non-random cDNA during sample preparation.
+%
+%    \indent
+%
+%    Note that the latter base positions shown in the figures are
+%    sometimes aggregates of multiple positions.
+%    \begin{figure}[h!]
+%        \centering
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            \subfloat[Raw read 1]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['samplea']['raw']['res_dir'])))/\pathBaseC}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%            \subfloat[Preprocessed read 1]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['samplea']['proc']['res_dir'])))/\pathBaseC}
+%            }
+%            ((* endif *))
+%        \end{minipage}
+%        \caption{\capBaseC for read 1.}
+%        %\label{fig:per_base_content_before_and_after_1}
+%    \end{figure}
+%
+%((* if run.is_paired_end *))
+%    \begin{figure}[h!]
+%        \centering
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            \subfloat[Raw read 2]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['sampleb']['raw']['res_dir'])))/\pathBaseC}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.495\textwidth}
+%            \centering
+%            ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%            \subfloat[Preprocessed read 2]{
+%                \includegraphics[width=\textwidth]{((( fastqc_stats['sampleb']['proc']['res_dir'])))/\pathBaseC}
+%            }
+%            ((* endif *))
+%        \end{minipage}
+%        \caption{\capBaseC for read 2.}
+%        %\label{fig:per_base_content_before_and_after_2}
+%    \end{figure}
+%((* endif *))
+%
+%
+%% per sequence GC content
+%\clearpage
+%\subsubsection{Per sequence GC content}
+%\newcommand{\capGCC}{Per sequence GC content before and after preprocessing }
+%    The figures below show the GC percentage distribution of all the read pair
+%    data. The green histogram represents the number of reads with a certain GC
+%    percentage. The blue shade behind the histogram represents the proportion of
+%    reads with a certain GC percentage, centered on the median. From the
+%    innermost to the outermost shade, the proportions represented are 20\%,
+%    40\%, 60\%, 80\%, and 99\%. The boxes in the boxplots show the interquartile
+%    range (25\%-75\%), centered on the median. Each of the whiskers in these
+%    plots extend to the data point within 1.5 of the interquartile range. Any
+%    data points outside of the whiskers' range are denoted as outliers, shown as
+%    red dots in the plots.
+%    \begin{figure}[h!]
+%        \centering
+%        ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%        \begin{minipage}[b]{0.47\textwidth}
+%            \centering
+%            \subfloat[Raw read 1]{
+%                \includegraphics[width=\textwidth]{((( vars['OUT_DIR'] )))/((( vars['SAMPLEA'] ))).gc.png}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.47\textwidth}
+%            \centering
+%            \subfloat[Preprocessed read 1]{
+%                \includegraphics[width=\textwidth]{((( vars['OUT_DIR'] )))/((( vars['SAMPLEA'] ))).qc.gc.png}
+%            }
+%        \end{minipage}
+%        ((* else *)))
+%        \begin{minipage}[b]{0.47\textwidth}
+%            \centering
+%            \subfloat[Raw read 1]{
+%                \includegraphics[width=\textwidth]{((( vars['OUT_DIR'] )))/((( vars['SAMPLEA'] ))).qc.gc.png}
+%            }
+%        \end{minipage}
+%        ((* endif *))
+%        \caption{\capGCC for read 1.}
+%        %\label{fig:per_base_content_before_and_after_1}
+%    \end{figure}
+%
+%((* if run.is_paired_end *))
+%    \begin{figure}[h!]
+%        \centering
+%        ((* if "none" not in vars['GENTRAP_QC_MODE'] *))
+%        \begin{minipage}[b]{0.47\textwidth}
+%            \centering
+%            \subfloat[Raw read 2]{
+%                \includegraphics[width=\textwidth]{((( vars['OUT_DIR'] )))/((( vars['SAMPLEB'] ))).gc.png}
+%            }
+%        \end{minipage}
+%        \begin{minipage}[b]{0.47\textwidth}
+%            \centering
+%            \subfloat[Preprocessed read 2]{
+%                \includegraphics[width=\textwidth]{((( vars['OUT_DIR'] )))/((( vars['SAMPLEB'] ))).qc.gc.png}
+%            }
+%        \end{minipage}
+%        ((* else *))
+%        \begin{minipage}[b]{0.47\textwidth}
+%            \centering
+%            \subfloat[Raw read 2]{
+%                \includegraphics[width=\textwidth]{((( vars['OUT_DIR'] )))/((( vars['SAMPLEB'] ))).qc.gc.png}
+%            }
+%        \end{minipage}
+%        ((* endif *))
+%        \caption{\capGCC for read 2.}
+%        %\label{fig:per_base_content_before_and_after_2}
+%    \end{figure}
+%((* endif *))
+%
+%
+=))
diff --git a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/main.tex b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/main.tex
index 636b35d8e..0673d4c0d 100644
--- a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/main.tex
+++ b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/main.tex
@@ -43,46 +43,57 @@
 
 \begin{document}
 \setlength{\parindent}{0in}
-\title{\Huge Gentrap: Generic Transcriptome Analysis Pipeline}
+%\title{\Huge Gentrap Run Report}
+\title{\resizebox{0.7\linewidth}{!}{\itshape Gentrap Run Report}}
 \author{LUMC Sequencing Analysis Support Core}
 \maketitle
 \begin{center}
-    {\LARGE Run Report v((( gentrap.version )))}
+    {\LARGE version ((( run.version )))}
 \end{center}
 \begin{figure}[h!]
     \centering
-    \includegraphics[width=0.8\textwidth]{((( gentrap.logo )))}
+    \includegraphics[width=0.8\textwidth]{((( run.logo )))}
 \end{figure}
 \thispagestyle{empty}
 \clearpage
 
+\addtocontents{toc}{\protect\hypertarget{toc}{}}
 \tableofcontents
 \clearpage
 
 
-\section{Introduction}
+\part{Overview}
 \label{sec:intro}
 
 This document outlines the results obtained from running Gentrap, a generic
 pipeline for transcriptome analysis.
 
+\clearpage
 
-% TODO: contents ~ preferrably in modules!
-((* include "test.tex" *))
-
+((* for sample in run.samples.values() *))
+((* include "sample.tex" *))
+\clearpage
+((* endfor *))
 
 
-\section{About Gentrap}
+\part{About Gentrap}
 \label{apx:about}
 
-The Generic Transcript Analysis Pipeline (Gentrap) aims to to be a
-generic pipeline for analyzing transcripts from RNA-seq experiments.
+The Generic Transcriptome Analysis Pipeline (Gentrap) is a
+generic pipeline for analyzing transcripts from RNA-seq experiments. \\
 
 Gentrap was developed by Wibowo Arindrarto (\href{mailto:w.arindrarto@lumc.nl}{w.arindrarto@lumc.nl})
 based on raw scripts written by Jeroen Laros
 (\href{mailto:j.f.j.laros@lumc.nl}{j.f.j.laros@lumc.nl}) and
 Peter-Bram 't Hoen
-(\href{mailto:p.a.c._t_hoen@lumc.nl}{p.a.c._t_hoen@lumc.nl}).
+(\href{mailto:p.a.c._t_hoen@lumc.nl}{p.a.c._t_hoen@lumc.nl}) as part of the
+\href{https://git.lumc/nl/biopet/biopet}{Biopet framework}. \\
+
+The Biopet framework is developed by the
+\href{http://sasc.lumc.nl}{Sequencing Analysis Support Core} of the
+\href{http://lumc.nl}{Leiden University Medical Center}, by extending the
+\href{http://http://gatkforums.broadinstitute.org/discussion/1306/overview-of-queue}{Queue framework}.
+Please see the respective web sites for licensing information.
 
 \indent
 
diff --git a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/sample.tex b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/sample.tex
new file mode 100644
index 000000000..947049d2e
--- /dev/null
+++ b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/sample.tex
@@ -0,0 +1,9 @@
+\part{Sample "((( sample.name )))" Results}
+\label{sample:(((sample.name)))}
+
+Hello from module ((( sample ))) \\
+
+((* for lib in sample.libs.values() *))
+((* include "lib.tex" *))
+\clearpage
+((* endfor *))
diff --git a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/test.tex b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/test.tex
deleted file mode 100644
index 75f83c2d4..000000000
--- a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/templates/pdf/test.tex
+++ /dev/null
@@ -1 +0,0 @@
-FROM THE MODULE
-- 
GitLab