\documentclass{beamer}
\usetheme{Warsaw}
\usepackage{nhtvslides}
\usepackage{graphicx}
\usepackage{listings}
\lstset{language=CAML,
basicstyle=\ttfamily\footnotesize,
frame=shadowbox,
breaklines=true}
\usepackage[utf8]{inputenc}
\DeclareMathOperator{\lerp}{lerp}

\title{Building a physics engine - part 2: narrow phase of collision detection}

\author{Dr. Giuseppe Maggiore}

\institute{NHTV University of Applied Sciences \\
Breda, Netherlands}

\date{}

\begin{document}
\maketitle

\begin{frame}{Table of contents}
\tableofcontents
\end{frame}

\section{Narrow phase collision detection and response}
\begin{slide}{Narrow phase}{Narrow phase}{
\item Find intersections for each pair of rigid bodies
\begin{itemize}
\item Whether they intersect
\item When they intersect
\item Where they intersect
\end{itemize}
\item Acceptable precision
\item Very high performance
}\end{slide}

\begin{slide}{Narrow phase}{Response}{
\item At all points of contact the \textit{relative velocity} projected along the normal must be non-negative
\item No pair of bodies in contact is getting closer
\begin{itemize}
\item This would mean that they are penetrating each other
\end{itemize}
}\end{slide}

\begin{frame}{Relative Velocity}
\center
\includegraphics[width=8cm]{Pics/Rel_Vel.png}
\end{frame}

\begin{slide}{Narrow phase}{Response}{
\item \textit{Relatively} easy to handle between pairs of bodies
\item Multiple bodies in contact make it much harder
}\end{slide}

\begin{frame}{Relative Velocity}
\center
\includegraphics[width=6cm]{Pics/Stacking.png}
\end{frame}

\section{Convex polyhedra}
\begin{slide}{Convex polyhedra}{Convex polyhedra}{
\item Also known as \textit{polytopes}
\item $\forall P,Q \in C. \forall \alpha \in [0..1]. \lerp(\alpha, P, Q) \in C$
\item Complex bodies can be treated as multiple polytopes with distance constraints
}\end{slide}

\begin{frame}{Convex polygon}
\center
\includegraphics[width=6cm]{Pics/ConvexPolyhedron.png}
\end{frame}

\begin{frame}{Convex polyhedra}
\center
\includegraphics[height=5cm]{Pics/ConvexPolyhedra.png}
\end{frame}

\section{Separating axis}
\begin{slide}{Separating axis}{Method of separating axis}{
\item We use a method that works in 2D and 3D
\begin{itemize}
\item We look for an axis/plane that separates the bodies
\end{itemize}
}\end{slide}

\begin{frame}{Separating axis}
\center
\includegraphics[height=5cm]{Pics/Fig6_19.png}
\end{frame}

\begin{slide}{Separating axis}{Method of separating axis}{
\item Given a (not necessarily unit-length) direction $D$ and two polytopes $C_0$ and $C_1$
\item We project them over the direction $D$: $I_i = [\lambda_{min}^i,\lambda_{max}^i] = [\min_{x\in C_i}\{ D \cdot (X-O) \}, \max_{x\in C_i}\{ D \cdot (X-O) \}]$
\item There is no collision if $\exists D . \lambda_{min}^0 > \lambda_{max}^1 \vee \lambda_{min}^1 > \lambda_{max}^0$
}\end{slide}

\begin{frame}{Separating axis}
\center
\includegraphics[width=8cm]{Pics/Fig6_20.png}
\end{frame}

\begin{slide}{Separating axis}{Method of separating axis}{
\item $D$ may be multiplied by a (non-zero) constant
\item The projection is scaled uniformly, but no contact still translates into a separated projection
\item The translation of a separating axis remains a separating axis, so we only deal with lines that go through the origin
}\end{slide}

\begin{frame}{Scale of separating axis}
\center
\includegraphics[width=8cm]{Pics/ScaleOfSeparatingAxis.png}
\end{frame}

\begin{frame}{Translation of separating axis}
\center
\includegraphics[width=8cm]{Pics/TranslationOfSeparatingAxis.png}
\end{frame}

% FIG OF SCALED/TRANSLATED PROJECTION

\begin{slide}{Separating axis}{Method of separating axis}{
\item We now consider $C_j$ polytopes, each with
\begin{itemize}
\item $P_i^j$ vertices, \textit{ordered counter-clockwise} and with wrapping indices
\item $E_i^j = P_{i+1}^j - P_i^j$ edges, \textit{ordered counter-clockwise}
\item $N_i^j$ normals, perpendicular to the edges
\end{itemize}
\item Similarly we store the triangles in 3D
}\end{slide}

\begin{slide}{Separating axis}{Method of separating axis}{
\item There are infinite candidate directions $D$
\item Fortunately we need only consider a finite set
\item In 2D, the normals of each polygon
}\end{slide}

\begin{frame}{Separating axis}
\center
\includegraphics[width=8cm]{Pics/SeparatingAxesIn2D.png}
\end{frame}

\begin{slide}{Separating axis algorithms}{Algorithms}{
\item Naïve algorithm
\item For each normal:
\begin{itemize}
\item Project all vertices of both polytopes
\item Compute the intervals
\item Check for intersection
\end{itemize}
}\end{slide}

\begin{slide}{Separating axis algorithms}{Algorithms}{
\item Smarter algorithm
\begin{itemize}
\item For each body $C_j$
\item For each normal $P_i^j, N_i^j$
\item Check if the closest vertex $P_k^l$ of the other body $C_l$ is too close to the edge
\item $(P_k^l - P_i^j) \cdot N_i^j > \epsilon$
\end{itemize}
}\end{slide}

\begin{frame}{Separation against face}
\center
\includegraphics[height=5cm]{Pics/SeparationOfVertex.png}
\end{frame}

\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
bool TestIntersection (ConvexPolygon C0, ConvexPolygon C1) {
  for (i0 = C0.GetN()-1, i1 = 0; i1 < C0.GetN(); i0 = i1++) {
    P = C0.GetVertex(i1);
    D = C0.GetNormal(i0);
    if (WhichSide(C1,P,D) > 0) {
      return false;
    }
  }
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
  for (i0 = C1.GetN()-1, i1 = 0; i1 < C1.GetN(); i0 = i1++) {
    P = C1.GetVertex(i1);
    D = C1.GetNormal(i0);
    if (WhichSide(C0,P,D) > 0) {
      return false;
    }
  }
  return true;
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
int WhichSide (ConvexPolygon C, Point P, Vector D) {
  posCount = 0;
  negCount = 0;
  zeroCount = 0;
  for (i = 0; i < C.GetN(); ++i) {
    t = Dot(D,C.GetVertex(i) - P);
    if (t > 0) { posCount++; }
    else if (t < 0) { negCount++; }
    else { zeroCount++; }
    if ((posCount > 0 and negCount > 0) or zeroCount > 0) { return 0; }
  }
  return posCount ? 1 : -1;
}
\end{lstlisting}
\end{frame}

\begin{slide}{Separating axis algorithms}{Optimizations}{
\item Bisection on the sorted vertices
\item Find the vertex closest to an edge faster
}\end{slide}

\begin{slide}{Separating axis algorithms}{Optimizations}{
\item 2D and 3D: BSP, Gauss map, hash table of the vertices sorted w.r.t. their direction
\item Find the vertex closest to an edge much faster
\item We will \textit{maybe} see this algorithm, depending on how fast the course goes
}\end{slide}

\begin{slide}{Separating axis in 3D}{Candidate axes}{
\item In 2D the candidate axes are just the edge normals
\item In 3D the face normals are not enough
\item Edge-to-edge collisions are not covered
}\end{slide}

\begin{frame}{Separating axis}
\center
\includegraphics[height=5cm]{Pics/EdgeToEdgeCross.png}
\end{frame}

\begin{slide}{Separating axis in 3D}{Candidate axes}{
\item Also consider edge-to-edge cross products
\item Exactly the same algorithm, but with more potential axes
}\end{slide}

\begin{frame}{Separating axis}
\center
\includegraphics[height=5cm]{Pics/EdgeToEdgeCross2.png}
\end{frame}

\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
bool TestIntersection (ConvexPolyhedron C0, ConvexPolyhedron C1) {
  for (i = 0; i < C0.GetFCount(); ++i) {
    D = C0.GetNormal(i);
    ComputeInterval(C0,D,min0,max0);
    ComputeInterval(C1,D,min1,max1);
    if (max1 < min0 || max0 < min1) { return false; }
  }
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
  for (j = 0; j < C1.GetFCount(); ++j) {
    D = C1.GetNormal(j);
    ComputeInterval(C0,D,min0,max0);
    ComputeInterval(C1,D,min1,max1);
    if (max1 < min0 || max0 < min1) { return false; }
  }
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
  for (i = 0; i < C0.GetECount(); ++i) {
    for (j = 0; j < C1.GetECount(); ++j) {
      D = Cross(C0.GetEdge(i),C1.Edge(j));
      ComputeInterval(C0,D,min0,max0);
      ComputeInterval(C1,D,min1,max1);
      if (max1 < min0 || max0 < min1){ return false; }
    }
  }
  return true;
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
void ComputeInterval (ConvexPolyhedron C, Vector D, double& min, double& max) {
  min = Dot(D,C.GetVertex(0));
  max = min;
  for (i = 1; i < C.GetVCount(); ++i) {
    value = Dot(D,C.GetVertex(i));
    if (value < min) {
      min = value;
    } else {
      max = value;
    }
  }
}
\end{lstlisting}
\end{frame}

\section{Moving objects}
\begin{slide}{Moving objects}{Moving objects}{
\item Objects are usually moving in a game :)
\item We must check for future intersections
\item With some simplifying assumptions
\begin{itemize}
\item Rotations can be ignored (phew!)
\item Interpenetration may happen a bit
\end{itemize}
}\end{slide}

\begin{slide}{Moving objects}{Moving objects}{
\item Use the \textit{moving projection} on an axis
\item Consider the \textit{relative velocity} $V = V_2 - V_1$
\item Speed of projection along $D$ is $\sigma = V \cdot D$ when $|D| = 1$
\item The distance of the minimum point must be bigger than $\sigma$
\item $\Delta x = \sigma \Delta t$ $\Delta t \frac{\Delta x}{d} = $ time of collision
\item When the time of collision is outside the time of the current frame, then there is no collision
}\end{slide}

\begin{frame}[fragile]{Moving objects}
\begin{lstlisting}
bool TestIntersection (ConvexPolygon C0, Vector V0, ConvexPolygon C1, Vector V1, double tmax, double& tfirst, double& tlast) {
  V = V1 - V0;
  tfirst = 0;
  tlast = INFINITY;
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
  for (i0 = C0.GetN() - 1, i1 = 0; i1 < C0.GetN(); i0 = i1++) {
    D = C0.GetNormal(i0);
    ComputeInterval(C0,D,min0,max0);
    ComputeInterval(C1,D,min1,max1);
    speed = Dot(D,V);
    if (NoIntersect(tmax,speed,min0,max0,min1,max1,tfirst, tlast)) { return false; }
  }
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
  for (i0 = C1.N - 1, i1 = 0; i1 < C1.N; i0 = i1++) {
    D = C1.GetNormal(i0);
    ComputeInterval(C0,D,min0,max0);
    ComputeInterval(C1,D,min1,max1);
    speed = Dot(D,V);
    if (NoIntersect(tmax,speed,min0,max0,min1,max1,tfirst, tlast)) { return false; }
  }
  return true;
}
\end{lstlisting}
\end{frame}

\begin{slide}{Moving objects}{Moving objects}{
\item if the polygons intersect at a first time $t_{\text{first}}$, then there is a separating axis $\forall t. t < t_{\text{first}}$
\item if the polygons intersect at a last time $t_{\text{last}}$, then there is a separating axis $\forall t. t > t_{\text{last}}$
\item if for all direction $t_{\text{first}} < t_{\text{last}}$, then the polygons intersect at time $t_{\text{first}}$ (check against $\Delta t$)
\item if for all direction $t_{\text{first}} > t_{\text{last}}$, then the polygons do not intersect (all axis must intersect at the same time!)
}\end{slide}

\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
bool NoIntersect (double tmax, double speed, double min0, double max0, double min1, double max1, double& tfirst, double& tlast) {
  if (max1 < min0) {
    if (speed <= 0) { return true; }
    t = (min0 - max1)/speed;
    if (t > tfirst) { tfirst = t; }
    if (tfirst > tmax) { return true; }
    t = (max0 - min1)/speed;
    if (t < tlast) { tlast = t; }
    if (tfirst > tlast) { return true; }
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
  } else if ( max0 < min1 ) {
    if (speed >= 0) { return true; }
    t = (max0 - min1)/speed;
    if (t > tfirst) { tfirst = t; }
    if (tfirst > tmax) { return true; }
    t = (min0 - max1)/speed;
    if (t < tlast) { tlast = t; }
    if (tfirst > tlast) { return true; }
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Pseudo-code}
\begin{lstlisting}
  } else {
    if (speed > 0) {
      t = (max0 - min1)/speed;
      if (t < tlast) { tlast = t; }
      if (tfirst > tlast) { return true; }
    } else if (speed < 0) {
      t = (min0 - max1)/speed;
      if (t < tlast) { tlast = t; }
      if (tfirst > tlast) { return true; }
    }
  }
  return false;
}
\end{lstlisting}
\end{frame}

\section{Finding the contact manifold}
\begin{slide}{Finding intersections}{Contact manifold}{
\item The collision response system needs the intersections
\item So far we have built \texttt{TestIntersection}
\item Huge numbers of possible algorithms for this (\textbf{GJK} is the most diffuse)
\item We now \textit{sketch} a description of one intuitive algorithm
}\end{slide}

\begin{slide}{Finding intersections}{Finding intersections}{
\item When the intersection is found at time $T$, before returning
\item We move the bodies forward with the respective velocities
\item We compute and return (an approximation) of the contact set
\item May be face-to-vertex or edge-to-edge
}\end{slide}

\begin{slide}{Finding intersections}{Finding intersections for SAT failures}{
\item Identify \textit{reference face} ($D=N$) and \textit{incident face} (most anti-parallel to $D$)
\item Clip incident face against edges of reference face
\item Keep all resulting vertices \textit{below or on} the reference face
}\end{slide}

\begin{frame}{Reference face}
\center
\includegraphics[height=5cm]{Pics/ReferenceFace.png}
\end{frame}

\begin{frame}{Reference face sideways}
\center
\includegraphics[height=5cm]{Pics/ReferenceFaceSideways.png}
\end{frame}

\begin{slide}{Finding intersections}{Edge-to-edge SAT failures}{
\item Just intersect the edges
}\end{slide}

\begin{slide}{Finding intersections}{Contact manifold}{
\item Two vertices are enough in 2D
\item Three vertices are enough in 3D
\item Too many more vertices do not improve stability (a few might)
\item We always choose the ones penetrating the most
\item Deterministic as much as possible (contact caching)
}\end{slide}

\begin{frame}{Contact manifold}
\center
\includegraphics[height=5cm]{Pics/ContactManifold.png}
\end{frame}

\begin{slide}{Finding intersections}{Clipping and intersections}{
\item Sutherland-Hogman algorithm for clipping
\item Edge-to-edge intersection
}\end{slide}

\begin{slide}{Finding intersections}{Clipping faces}{
\item Project planes from the edges of the reference face
\item Vertices of the incident face \textit{inside} all planes are contact points
\item Reference plane with incident edge intersections are more contact points
\item Keep a subset of the points: (most inside the reference face)
}\end{slide}

\begin{slide}{Finding intersections}{Clipping a vertex}{
\item Given a plane $\langle N,d \rangle$ where $N$ is the normal of the plane and $d$ is the minimum distance of the plane from the origin
\item We determine the side of the plane on which a vertex $V$ lies with the sign of $P \cdot N - d$
}\end{slide}

\begin{frame}{Clipping}
\center
\includegraphics[width=10cm]{Pics/PlaneVertexClipping.png}
\end{frame}

\begin{slide}{Finding intersections}{Clipping a vertex}{
\item All signs of plane-vertex distance must be the same
\item The planes must all be facing inward (or outward)
}\end{slide}

\begin{slide}{Finding intersections}{Clipping an edge}{
\item Given a plane $\langle V \cdot N = d \rangle$ and an edge $V = A + \alpha B$ ($0 \leq \alpha \leq 1$)
\item We put these equations together: $(A + \alpha B) \cdot N = d$ and solve for $\alpha = \frac{d - A \cdot N}{B \cdot N}$
}\end{slide}

\begin{slide}{Finding intersections}{Clipping an edge}{
\item $\alpha = \frac{d - A \cdot N}{B \cdot N}$
\item Watch for lack of solutions
\begin{itemize}
\item If $|B \cdot N| \leq \epsilon$ then edge and plane are parallel
\item No intersection possible
\end{itemize}
}\end{slide}

\begin{frame}{Clipping}
\center
\includegraphics[height=3cm]{Pics/PlaneEdgeClipping.png}
\end{frame}

\begin{slide}{Finding intersections}{Edge-to-edge intersections}{
\item We consider two edges: $P_1 + \alpha D_1$ and $P_2 + \beta D_2$
\item Intersection in 3D is rather rare
\item We look for the shortest connecting axis: $P_a = P_1 + \mu_a D_1$ and $P_b = P_2 + \mu_b D_2$
}\end{slide}

\begin{frame}{Clipping}
\center
\includegraphics[height=5cm]{Pics/EdgeEdgeIntersection.png}
\end{frame}

\begin{slide}{Finding intersections}{Edge-to-edge intersections}{
\item The connecting axis is perpendicular to the both edges, so
$\left\{ \begin{matrix}
(P_a - P_b) \cdot D_1 &=& 0 \\
(P_a - P_b) \cdot D_2 &=& 0
\end{matrix} \right.$
\pause
\item Expanding $P_a$ and $P_b$ results in
$\left\{ \begin{matrix}
(P_1 + \mu_a D_1 - P_2 - \mu_b D_2) \cdot D_1 &=& 0 \\
(P_1 + \mu_a D_1 - P_2 - \mu_b D_2) \cdot D_2 &=& 0
\end{matrix} \right.$
}\end{slide}

\begin{slide}{Finding intersections}{Edge-to-edge intersections}{
\item This is just a system with two unknowns and two equations; the dot products turn everything into numbers:
$\left\{ \begin{matrix}
(P_1 + \mu_a D_1 - P_2 - \mu_b D_2) \cdot D_1 &=& 0 \\
(P_1 + \mu_a D_1 - P_2 - \mu_b D_2) \cdot D_2 &=& 0
\end{matrix} \right.$
\item The full (tedious) derivation of the solutions is shown in \url{http://paulbourke.net/geometry/pointlineplane/}
}\end{slide}

\section{Assignment}
\begin{slide}{Assignment}{Assignment}{
\item Before the end of next week
\item Group-work archive/video on Natschool or uploaded somewhere else and linked in your report
\item Individual report by each of you on Natschool
\item Build a narrow phase collision detector that can compute the contact manifold
}\end{slide}

\begin{frame}{That's it}
\center
\fontsize{18pt}{7.2}\selectfont
Thank you!
\end{frame}

\end{document}

\begin{slide}{SECTION}{SLIDE}{
\item i
}\end{slide}

\begin{frame}[fragile]{SLIDE}
\begin{lstlisting}
CODE
\end{lstlisting}
\end{frame}

\begin{frame}{SLIDE}
\center
%\includegraphics[height=5cm]{Pics/recursive_multiplier.png}
\end{frame}


\documentclass[11pt]{article}
\usepackage{amsmath, amssymb}
\usepackage{geometry} % see geometry.pdf on how to lay out the page. There's lots.
\geometry{a4paper} % or letter or a5paper or ... etc
\usepackage{graphicx}
% \geometry{landscape} % rotated page geometry
% See the ``Article customise'' template for come common customisations
\usepackage[style=phys,
citestyle=phys]{biblatex}
\addbibresource{van_vleck_memo.bib}

\title{Initial Results of Van Vleck Correction for the MWA}
\author{Pyxie Star}
% delete this line to display the current date
\renewcommand{\Re}{\operatorname{Re}}
\renewcommand{\Im}{\operatorname{Im}}
%%% BEGIN DOCUMENT
\begin{document}

\maketitle

\section{Data}

\begin{figure}
\centering{}
\includegraphics[width=140mm]{uncorr_autos.png}
\caption{Uncorrected 0yy auto-correlations from a 2013 time sample and a 2015 time sample.\label{uncorr_autos}}
\end{figure}
\paragraph{}
The \texttt{pyuvdata} Van Vleck correction implementation was applied to a single time stamp of two observations, 1061315448 from 2013 and 1131733552 from 2015. The first time sample from the second correlator output file for every coarse band was used for each observation. The uncorrected data of the 0yy auto for both samples is shown in figure~\ref{uncorr_autos}. These two samples reflect differences in both digital receiver gain schemes and correlator output files.
\paragraph{}Before the cross-multiply, the correlator casts the quantized integers into floats. As detailed in \cite{beardsley}, this involves division by a factor of 127, which introduces a small error into the data. This error is remedied by casting the data back to integers before storing. After October 2014, data was stored as 32-bit integers with a scaling keyword reflecting the time and frequency integration done in the correlator. Prior to this, the correlator averaged the fine channels to 40 kHz, thus performing a division by 4, and stored the data as floats. To mitigate the errors in this earlier data, the \texttt{pyuvdata} reader for MWA correlator output files casts all data back to integers before processing.
\begin{figure}
\centering{}
\includegraphics[width=135mm]{gains.png}
\caption{Gains applied to the coarse bands by the MWA digital receivers. These are the gains for a single antenna; in a visibility the gains are squared.\label{gains}}
\end{figure}
\begin{figure}
\centering{}
\includegraphics[width=140mm]{uncorr_autos_gains.png}
\caption{Uncorrected auto-correlations with the gains divided out. The gain jump in the 2013 data leaves a discontinuity after the gains are removed.\label{uncorr_autos_gains}}
\end{figure}
\begin{figure}
\centering{}
\includegraphics[width=140mm]{corr_autos_gains.png}
\caption{Autocorrelation with the Van Vleck correction applied and then the gains divided out. Applying the Van Vleck correction mitigates the gain jump discontinuity seen in the 2013 data in figure~\ref{uncorr_autos_gains}.\label{corr_autos_gains}}
\end{figure}
\paragraph{}In the 2013 data, the digital receiver gains had a sharp discontinuity across coarse bands, with the 8 highest coarse bands having gains a factor of 2 higher than the lower coarse bands. The gains are plotted in figure~\ref{gains}. Since the gains are applied to each antenna, this leads to a factor of 4 difference in the visibilities. However, simply dividing out the gains does not smooth the coarse bands; a discontinuity is still present as seen in figure~\ref{uncorr_autos_gains}.
\begin{figure}
\centering{}
\includegraphics[width=135mm]{auto_ratio.png}
\caption{Ratio between corrected and uncorrected data for an auto-correlation. For 2013 data, the correction decreased values in coarse channels before the digital gain jump and increased values in coarse channels after the digital gain jump. \label{auto_ratio}}
\end{figure}
\begin{figure}
\centering{}
\includegraphics[width=135mm]{cross_ratio.png}
\caption{Ratio between corrected and uncorrected data for a cross-correlation\label{cross_ratio}}
\end{figure}
\begin{figure}
\centering{}
\includegraphics[width=135mm]{auto_diff.png}
\caption{Difference between corrected and uncorrected data for an auto-correlation.\label{auto_diff}}
\end{figure}
\begin{figure}
\centering{}
\includegraphics[width=135mm]{cross_diff.png}
\caption{Difference between corrected and uncorrected data for a cross-correlation\label{cross_diff}}
\end{figure}
\paragraph{}
Applying the Van Vleck correction provides some mitigation of the digital gain jump discontinuity seen in the 2013 data, as seen in the initial plot of the 0yy auto (figure~\ref{corr_autos_gains}). Further testing will determine the impacts of the correction on other possible effects of the digital non-linearity. Figures \ref{auto_ratio}, \ref{cross_ratio}, \ref{auto_diff}, \ref{cross_diff} show the ratios and differences between the corrected and uncorrected data for a sample auto-correlation and cross-correlation. For the 2013 auto-correlation, the Van Vleck correction decreased values in the coarse channels before the digital gain jump and increased values in coarse channels after the gain jump. The initial ratio plots show an increase of up to approximately 10\% for coarse channels after the gain jump for both the cross and auto-correlations. The 2015 ratios show more modest changes, with an approximately 3\% decrease in the auto-correlations and cross-correlation ratios very close to 1. More extensive analysis will quantify the range of the ratios and differences across all baselines.
\section{Further work}
\paragraph{}To make implementing the correction feasible on a large scale (correcting a whole night of data, for example) requires a reworking of the cross-correlation correction algorithm. In the meantime, auto-correlations can be corrected and used in testing. A particular area of interest is in removing the coarse band shape introduced by the two PFB stages of the MWA. In \cite{levine_effects} and \cite{levine_math} a shape of the expected coarse band structure was derived. The corrected auto-correlation can be used to test removing this shape. Another interesting effect which might be impacted by removing the digitization non-linearity is the change in the coarse band shapes from night to night. Combining the Van Vleck correction with a deeper analysis of the PFB structures could make previously unusable coarse bands and fine channels available for data analysis.

\pagebreak
%\nocite{*}
\printbibliography
%\bibliographystyle{apsrmp4-2}
\end{document}


\section{Overview}
\seclabel{overview}

This section provides a brief tutorial on how to run a very simple example through the compiler. The sections that follow provide detailed descriptions of all language constructs.

\subsection{Hello World}
To illustrate the process of sketching, we begin with the simplest sketch one can possibly write: the "hello world" of sketching.

\begin{lstlisting}
harness void doubleSketch(int x){
  int t = x * ??;
  assert t == x + x;
}
\end{lstlisting}

The syntax of the code fragment above should be familiar to anyone who has programmed in C or Java. The only new feature is the symbol \C{??}, which is Sketch syntax to represent an unknown constant. The synthesizer will replace this symbol with a suitable constant to satisfy the programmer's requirements. In the case of this example, the programmer's requirements are stated in the form of an assertion. The keyword \C{harness} indicates to the synthesizer that it should find a value for \C{??} that satisfies the assertion for all possible inputs \C{x}.

\flagdoc{bnd-inbits}{In practice, the solver only searches a bounded space of inputs ranging from zero to $2^{\mbox{\small{\texttt{bnd-inbits}}}}-1$. The default for this flag is 5; attempting numbers much bigger than this is not recommended.}

\subsection{Running the synthesizer}

To try this sketch out on your own, place it in a file, say \C{test1.sk}. Then, run the synthesizer with the following command line:

\begin{lstlisting}
   > sketch   test1.sk
\end{lstlisting}

When you run the synthesizer in this way, the synthesized program is simply written to the console. If instead you want the synthesizer to produce standard C code, you can run with the flag \C{--fe-output-code}. The synthesizer can even produce a test harness for the generated code, which is useful as a sanity check to make sure the generated code is behaving correctly.

\flagdoc{fe-output-code}{This flag forces the code generator to produce a C++ implementation from the sketch. Without it, the synthesizer simply outputs the code to the console}

\flagdoc{fe-output-test}{This flag causes the synthesizer to produce a test harness to run the C++ code on a set of random inputs.}

Flags can be passed to the compiler in two ways. The first and most traditional one is by passing them in the command line. For the example above, you can get code generated by invoking the compiler as follows.
\begin{lstlisting}
   > sketch   --fe-output-code test1.sk
\end{lstlisting}

An alternative way is to use the \C{pragma} construct in the language. Anywhere in the top level scope of the program, you can write the following statement:
\begin{lstlisting}
   pragma options " $flags$ ";
\end{lstlisting}
This is very useful if your sketch requires a particular set of flags to synthesize. Flags passed through the command line take precedence over flags passed with \C{pragma}, so you can always use the command line to override options embedded in the file.

\subsection{Parallel Solving}
The \Sk{} synthesizer has a parallel mode which can yield significant speedups on certain problems. Parallel mode can be invoked by running with the flag \C{--slv-parallel}. By default, this flag will use one less than the total number of processors available in your system, but you can control the exact number of processors used by passing the additional flag \C{--slv-p-cpus}. Not all problems will benefit from parallel solving; some problems will actually be slowed down because of the added overhead, but for some problems, parallelism can provide a significant performance boost. \secref{parallel} goes into the details of how to get the most from parallel execution.

\flagdoc{slv-parallel}{ This flags enables parallel mode, allowing the synthesizer to take advantage of multiple cores. By default, the synthesizer will use one less core than the total number of cores available in your system}
\flagdoc{slv-p-cpus}{ This flag can be used in combination to the \C{--slv-parallel} flag to indicate to the synthesizer how many cores to use.}


%!TEX root = ../thesis.tex
%*******************************************************************************
%*********************************** Background estimation *********
%*******************************************************************************

\chapter{Background estimation}\label{ch:background_estimation}

\graphicspath{{chapter-background/Figs/Vector/}{chapter-background/Figs/}}

\glsreset{cr}

A reliable and trustworthy estimation of the expected \gls{sm} background rates in the signal regions is crucial for exercising the statistical machinery, laid out in \cref{ch:statistics}, and making conclusive statistical statements about the \gls{susy} scenarios studied.
The background estimation approaches used herein rely on semi-data-driven techniques or purely on \gls{mc} estimations.
As estimating backgrounds only from \gls{mc} simulation is sometimes problematic, \eg, due to mis-modellings in the phase space targeted not appropriately covered by the uncertainties, a (semi-)data-driven approach is often favoured.
In the following, the major backgrounds $\ttbar$, single top and $\wjets$ are estimated using a semi-data-driven approach, while the expected rates from the remaining, smaller backgrounds purely rely on \gls{mc} simulations and are normalised to their theoretical cross sections.

\section{General strategy}

\subsection{Transfer factor approach}

Estimating background contributions in \glspl{sr} in a semi-data-driven approach usually involves the introduction of so-called \glspl{cr}, used to control dominant background processes by comparing their expected event rates to data.
The \glspl{cr} are designed to be enriched in events of a given background process (or type) while being approximately free of signal contamination.
If $N_p^\mathrm{MC}(\mathrm{SR})$ and $N_p^\mathrm{MC}(\mathrm{CR})$ are the expected rates for a given background process $p$ obtained from \gls{mc} simulation in a given \gls{sr} and \gls{cr}, respectively, then the transfer factor $N_p^\mathrm{MC}(\mathrm{SR})/N_p^\mathrm{MC}(\mathrm{CR})$ allows to convert the number of observed background events in the control region, $N_p^\mathrm{obs}(\mathrm{CR})$, into a background estimate in the signal region, $N_p^\mathrm{est}(\mathrm{SR})$, through
\begin{equation}
	N_p^\mathrm{est}(\mathrm{SR}) = N_p^\mathrm{obs}(\mathrm{CR}) \frac{N_p^\mathrm{MC}(\mathrm{SR})}{N_p^\mathrm{MC}(\mathrm{CR})} = \mu_p N_p^\mathrm{MC}(\mathrm{SR}).
	\label{eq:transfer_factor}
\end{equation}
Here, $\mu_p$ is the process-specific normalisation factor introduced in~\cref{sec:likelihood_function}.
An important benefit of this approach is that the impact of systematic uncertainties on the estimated background rates can be evaluated on the transfer factors, \ie ratios of \gls{mc} estimates.
As such, systematic uncertainties can partly cancel in the extrapolation to the \glspl{sr}.
The uncertainty on the background estimate in the \glspl{sr} is then a combination of the statistical uncertainties in the \glspl{cr}, the uncertainties on the normalisation factors, and remaining uncertainties affecting the extrapolation~\cite{HistFitter:2014wma}.
%For this reason, \glspl{cr} are usually deliberately chosen to have large statistics, effectively reducing the uncertainties on the extrapolation to the \glspl{sr}.

As indicated in~\cref{eq:transfer_factor}, the transfer factor approach is formally equivalent to using the process-specific normalisation factors from~\cref{sec:likelihood_function}, effectively \textit{normalising} the number of total background events expected from \gls{mc} simulation to the number of observed events in each control region.
%In the profile likelihood fits used in the following, implemented using \textsc{HistFitter}~\cite{HistFitter:2014wma}, the normalisation factors $\mu_p$ are fit to data together with the nuisance parameters in order to derive background estimates.
Multiple disjoint \glspl{cr} are used to simultaneously normalise multiple background processes to data in a combined fit.
In order not to have an underdetermined minimisation problem, the number of \glspl{cr} needs to be at least as large as the number of normalisation factors considered.
Two different profile likelihood fit configurations are used in the following; the first configuration being a so-called \textit{background-only} fit configuration, assuming no signal contribution and typically only including the \glspl{cr}.
The second configuration is a so-called \textit{signal-plus-background} fit configuration considering signal contribution and including all \glspl{cr} as well as \glspl{sr} (therefore also sometimes called a \textit{model-dependent} fit configuration).

In order to verify the quality of the extrapolation from the \glspl{cr} to the \glspl{sr}, so-called \glspl{vr} are defined. \glspl{vr} do not participate in the actual fit of the model parameters to data, but serve as intermediate regions to verify the extrapolation.
For this reason, \glspl{vr} are typically placed in the region between the \glspl{cr} and \glspl{sr} that is extrapolated over.
A schematic view of an analysis strategy using all three types of regions is shown in~\cref{fig:hf_strategy}. All three types of regions can have more than one bin and are separated by means of suitable observables that are extrapolated over.
In order to be able to use information from all control and signal regions in a single profile likelihood fit, all regions necessarily need to be statistically independent.

\begin{figure}
\floatbox[{\capbeside\thisfloatsetup{capbesideposition={right,center},capbesidewidth=0.53\textwidth}}]{figure}[\FBwidth]
{\caption{Schematic view of an analysis strategy including multiple control, validation and signal regions with one or multiple bins each. Extrapolations from the control regions into the signal regions can be verified in the validation regions lying in the phase space extrapolated over. All regions are designed to be statistically independent. Figure adapted from~\reference\cite{HistFitter:2014wma}.}\label{fig:hf_strategy}}
{\includegraphics[width=0.42\textwidth]{hf_strategy}}
\end{figure}

\subsection{Analysis blinding}

An important concept in the design phase of searches for new physics is the idea of \textit{blinding} regions of interest~\cite{blind:2003rw}, meaning that measured data are not looked at in these regions.
This avoids issues of \textit{experimenter's bias}, \ie unintended influences on the design of the analysis based on the observed data.
If data were already known when designing the signal regions (and therefore the outcome of the analysis would be known to some extent), experimenter's bias could for example occur during the selection of the final signal region definitions.

During the design of a search for \gls{susy}, signal regions are generally kept blinded until the complete analysis strategy is fixed.
Once the \glspl{sr} have been designed, the next step is to develop a suitable background estimation strategy, often involving the introduction of \glspl{cr} with negligible signal contamination.
This is then often followed by the design of \glspl{vr} that can be unblinded once the \glspl{cr} are fixed.
After the extrapolation of the background estimate (obtained using a background-only fit) from the \glspl{cr} has been verified in the \glspl{vr}, the \glspl{sr} are unblinded, allowing to quantify potential excesses in data or set limits on model parameters.

\subsection{Data versus Monte Carlo plots}\label{sec:data_vs_mc}

In this chapter, all plots comparing data versus \gls{mc} are so-called \textit{pre-fit} plots, meaning that no background-only fit has been run in order to determine the normalisation factors and total systematic uncertainties for the background estimate.
Instead, the contributions from the dominant backgrounds $\ttbar$, $\wjets$ and single top are normalised simultaneously in the control regions by solving the system of $i$ equations
\begin{equation}
%	\begin{split}
		n_\mathrm{data}^{\mathrm{CR}_i} = \mu_{\ttbar} B_{\ttbar}^{\mathrm{CR}_i} + \mu_{W} B_{W}^{\mathrm{CR}_i} + \mu_\mathrm{ST} B_\mathrm{ST}^{\mathrm{CR}_i} + B_\mathrm{other}^{\mathrm{CR}_i},
%	\end{split}
\end{equation}
where $i$ runs over the list of \glspl{cr} introduced in \cref{sec:control_regions} and $\mu_{\ttbar}$, $\mu_\mathrm{W}$ and $\mu_\mathrm{ST}$ are the normalisation factors of the $\ttbar$, $\wjets$ and single top backgrounds, respectively, that are to be determined.
$B_{\ttbar}^{\mathrm{CR}_i}$, $B_\mathrm{ST}^{\mathrm{CR}_i}$, $B_\mathrm{ST}^{\mathrm{CR}_i}$ and $B_\mathrm{other}^{\mathrm{CR}_i}$ are the background rates expected from \gls{mc} simulation in the \textit{i}-th \gls{cr}.
The normalisation factors obtained are 0.96 for $\ttbar$, 1.24 for $\wjets$ and 0.73 for single top. As will be shown in~\cref{sec:results_background_only}, the normalisation factors obtained using the full statistical procedure will be close to these values.

Additionally, the uncertainty bands on the background estimate in the plots only include \gls{mc} statistical as well as experimental uncertainties.
The variations of the experimental uncertainties are normalised to the nominal background estimate in the case of $\ttbar$, $\wjets$ and single top, such that only the shapes of the dominant backgrounds are affected.
For the remaining minor backgrounds, the experimental uncertainties can affect both normalisation and shape.
All experimental uncertainties are assumed to be fully correlated over all processes and bins, allowing them to be summed in quadrature.
Finally, the uncertainty bars on the data points are obtained by assuming data to be Poisson distributed and correspond to the 68\% confidence interval.

\section{Control regions}\label{sec:control_regions}

The contributions from $\ttbar$, $\wjets$ production and single top processes are normalised to data in dedicated control regions.
Other processes like $Z+\mathrm{jets}$, diboson and multiboson, $\ttbar+V$, $\ttbar+h$ and $V+h$ are estimated directly from \gls{mc} simulation and normalised to their theoretical cross sections.
All \glspl{cr} are designed to be kinematically as close as possible to the \glspl{sr}, such that the normalisation factors derived in the \glspl{cr} are also valid in the \glspl{sr}.
The \glspl{cr} are mutually exclusive and made orthogonal to the \glspl{sr} through their requirements on $\mt$, $\mct$ and $\mbb$.
Apart from the requirements on these three observables, as well as the requirement on $\mlb$ (removed altogether in the \glspl{cr}), the \glspl{cr} share the same set of cuts as the \glspl{sr}.
\Cref{fig:cr_strategy} illustrates the configuration of all \glspl{cr}, especially highlighting the fact that all \glspl{cr} are located in sideband regions off the $\mbb$ window, significantly reducing signal contamination.
\Cref{tab:CRVRdef} summarises the kinematic requirements separating the \glspl{cr} from other regions of interest in the analysis. The pre-fit distributions of all \glspl{cr} in representative observables are shown in~\cref{fig:CR_distributions_prefit}.

\begin{table}
\begin{center}
\resizebox{\textwidth}{!}{
\begin{tabular} {l | c c c | cccccc}
\toprule
\textbf{CR} & \textbf{TR-LM} &  \textbf{TR-MM} &  \textbf{TR-HM} &  \multicolumn{3}{c}{\textbf{WR}} & \multicolumn{3}{c}{ \textbf{STR}} \\
\midrule
$\mbb$ [$\GeV$]  & \multicolumn{3}{c|}{$<$100 or $>$140} & \multicolumn{3}{c}{$\in[50,80]$} &\multicolumn{3}{c}{$>$195}\\
$\mt$ [$\GeV$]   & $\in[100,160]$ & $\in[160,240]$ & $>$240 & \multicolumn{3}{c}{$\in[50,100]$} &\multicolumn{3}{c}{$>$100}\\
$\mct$ [$\GeV$]  &\multicolumn{3}{c|}{$<$180} & \multicolumn{3}{c}{$>$180} &\multicolumn{3}{c}{$>$180}\\
\midrule
\textbf{VR} & \textbf{VR-onLM} &  \textbf{VR-onMM} & \textbf{VR-onHM} & \multicolumn{2}{c}{ \textbf{VR-offLM}} &  \multicolumn{2}{c}{\textbf{VR-offMM}} &  \multicolumn{2}{c}{\textbf{VR-offHM}}\\
\midrule
$\mbb$ [$\GeV$]  & \multicolumn{3}{c|}{$\in[100,140]$} & \multicolumn{2}{c}{$\in[50,80]\, \cup [160, 195]$} & \multicolumn{2}{c}{$\in[50,80]\, \cup [160, 195]$}& \multicolumn{2}{c}{$\in[50,75]\, \cup [165, 195]$}\\
$\mt$ [$\GeV$]   & $\in[100,160]$ & $\in[160,240]$ & $>$240 & \multicolumn{2}{c}{$\in[100,160]$} & \multicolumn{2}{c}{$\in[160,240]$} & \multicolumn{2}{c}{$>$240}\\
$\mct$ [$\GeV$]  &\multicolumn{3}{c|}{$<$180}&\multicolumn{6}{c}{$>$180}\\
\bottomrule
\end{tabular}}
\caption{Overview of the CR and VR definitions. With the exception of $\mlb$, which is not used in the definitions of the \glspl{cr} and \glspl{vr}, all regions share the same selection as the \glspl{sr} on the remaining kinematic observables not listed here.}
\label{tab:CRVRdef}
\end{center}
\end{table}

\subsubsection[Control regions for $\ttbar$]{Control regions for $\makemebold{\ttbar}$}

As events from $\ttbar$ processes constitute the dominant \gls{sm} background in the majority of the \glspl{sr}, it is necessary to have a precise and reliable estimate of their contributions.
Three \glspl{cr} are defined for $\ttbar$, following the same binning in $\mt$ as the signal regions, and thus called TR-LM, TR-MM and TR-HM in the following.

A good purity of $\ttbar$ processes, as well as the necessary high \gls{mc} statistics, are achieved by inverting the requirement on $\mct$, selecting events below the kinematic endpoint for $\ttbar$ processes.
The achieved pre-fit $\ttbar$ purities are 79.6\% in TR-LM, 85.9\% in TR-MM and 84.1\% in TR-HM.
The remaining contributions stem mostly from single top and $\wjets$ processes and vary between 8.6\%--14.1\% and 1.8\%--4.3\%, respectively, depending on the \gls{sr}.

For a trustworthy estimate of the contributions from $\ttbar$ processes, it is important that the control regions associated to each signal region exhibit approximately the same composition of $\ttbar$ decay modes.
The decay mode most relevant to the \onelepton search at relatively low and moderate values of $\mt$ is the semi-leptonic decay ($\ell\nu qq$), where one of the $W$ bosons decays leptonically, while the other one undergoes a hadronic decay.
The semi-leptonic decay mode exhibits the well-known kinematic endpoint in $\mt$ and thus quickly loses importance at high transverse mass values.
Events involving a hadronic decay of a $\tau$-lepton originating from $W\to\tau_\mathrm{had}\nu$ in one of the two branches and a leptonic $W$ boson decay in the other branch ($\ell\nu\tau_\mathrm{had}\nu$), are the dominant decay mode in selections with high values of $\mt$.
Due to the additional neutrino in such events, the $\ell\nu\tau_\mathrm{had}\nu$ decay mode does not exhibit the same kinematic endpoint as the semi-leptonic one.
Finally, di-leptonic decays ($\ell\nu\ell\nu$) and events with a leptonically decaying $\tau$-lepton ($\ell\nu\tau_\mathrm{\ell}\nu$), where one of the two leptons is not reconstructed, play a sub-dominant but non-negligible role in all regions.
Other $\ttbar$ decay modes are negligible in all analysis selections.

 In the low-mass regions with moderate values in $\mt$ not far above its kinematic endpoint, 80\% (40\%) of $\ttbar$ events involve the semi-leptonic decay mode in the control region (signal region).
 The sub-dominant decay mode in these regions involves the $\ell\nu\tau_\mathrm{had}\nu$ decay mode, with a contribution of 25\% and 10\% in TR-LM and SR-LM, respectively.
 Di-leptonic and $\ell\nu\tau_\mathrm{\ell}\nu$ decay modes each contribute about 15\% of all events in TR-LM and about 3\% in SR-LM.
 Overall, the composition in the low-mass regions is hence not exactly the same in the control and signal regions, but the agreement is still considered to be acceptable.
 With about 45\% (36\%) and 30\% (35\%), the largest contributions in TR-MM (SR-MM) originate from $\ell\nu\tau_\mathrm{had}\nu$ decays and di-leptonic events, respectively.
 Events with a $\ell\nu\tau_\mathrm{\ell}\nu$ decay contribute to about 10\% (15\%) in TR-MM (SR-MM).
 In the high-mass control and signal regions with a high requirement on $\mt$, the majority (about 50\%) of events involve the $\ell\nu\tau_\mathrm{had}\nu$ decay mode, while the di-leptonic and $\ell\nu\tau_\mathrm{\ell}\nu$ decay modes contribute with about 30\% and 20\%, respectively.
 Overall, the compositions of the different $\ttbar$ decay modes in each control region are thus similar to the contributions in the respective signal region, meaning that the proportions of $\ttbar$ processes constrained through the profile likelihood fit in the \glspl{cr} are similar to those in the \glspl{sr} to be estimated.

Signal contamination in the $\ttbar$ \glspl{cr} is avoided by inverting the requirement on $\mbb$, \ie placing the $\ttbar$ \glspl{cr} in the $\mbb$ sideband.
The maximum signal contamination over the entire signal grid is 0.8\%, 1.1\% and 1.9\% for TR-LM, TR-MM and TR-HM, respectively, and thus negligible. \Cref{fig:signal_contamination_TRLM,fig:signal_contamination_TRMM,fig:signal_contamination_TRHM} show the signal contamination in the $\ttbar$ \glspl{cr} over the full signal grid.

 \begin{figure}
	\centering
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{1Lbb_TR-LM_mct}
		\caption{TR-LM\label{fig:prefit_TRLM}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{1Lbb_TR-MM_mct}
		\caption{TR-MM\label{fig:prefit_TRMM}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{1Lbb_TR-HM_mct}
		\caption{TR-HM\label{fig:prefit_TRHM}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{1Lbb_WR_mbb}
		\caption{WR\label{fig:prefit_WR}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{1Lbb_STR_mbb}
		\caption{STR\label{fig:prefit_STCR}}
	\end{subfigure}\hfill

	\caption{Representative pre-fit distributions for each control region. As laid out in the beginning of this chapter, the shaded region includes \gls{mc} statistical uncertainty as well as experimental uncertainties, added in quadrature. The dominant backgrounds are normalised using the procedure described in~\cref{sec:data_vs_mc}. A good agreement between \gls{mc} expectation and data is observed in all \glspl{cr}.}
	\label{fig:CR_distributions_prefit}
\end{figure}

 \begin{figure}
	\centering
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{signal_contamination/plot_TR_LM}
		\caption{TR-LM\label{fig:signal_contamination_TRLM}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{signal_contamination/plot_TR_MM}
		\caption{TR-MM\label{fig:signal_contamination_TRMM}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{signal_contamination/plot_TR_HM}
		\caption{TR-HM\label{fig:signal_contamination_TRHM}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{signal_contamination/plot_WR}
		\caption{WR\label{fig:signal_contamination_WR}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.5\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{signal_contamination/plot_STR}
		\caption{STR\label{fig:signal_contaminations_STCR}}
	\end{subfigure}\hfill

	\caption{Signal contamination for all \glspl{cr} throughout the signal grid. The space between the signal points (indicated by the black circles) is interpolated using Delaunay triangles.}
	\label{fig:signal_contamination_CR}
\end{figure}

\subsubsection[Control region for $\wjets$]{Control region for $\makemebold{\wjets}$}

Events from $\wjets$ production present the second largest contribution of \gls{sm} background processes in most \glspl{sr}.
A single $\wjets$ control region, called WR in the following, is defined by replacing the signal region requirements on $\mt$ and $\mbb$ with $\SI{50}{\GeV} < \mt < \SI{100}{\GeV}$  and $\SI{50}{\GeV} < \mbb < \SI{80}{\GeV}$, respectively.
No bins in $\mct$ or $\mt$ are defined for WR, as the composition of $\wjets$ is approximately constant in all regions.

Applying a low requirement on $\mt$ allows to predominantly select events below the kinematic endpoint of the transverse mass of the \textit{W} boson, resulting in a high statistics control region with a pre-fit $\wjets$ purity of roughly 52.5\%.
The sub-dominant background component of WR is $\ttbar$ with 35.2\%.
Small contributions of 7.0\% and 4.2\% originate from single top and diboson processes, respectively.
The composition of $\wjets$ events in WR and all signal regions is found to be dominated by $W$ boson production in association with two real \textit{b}-jets.
Minor contributions originate from processes with mis-tagged \textit{c}-jets or light-flavour jets.

As was the case for the $\ttbar$ control regions, placing WR off the Higgs mass peak allows to achieve a tolerable maximum signal contamination of only 2.4\% without affecting the composition of processes in the $\wjets$ background too much.
Most signal points have significantly less than 1\% signal contamination in WR, as can be seen in~\cref{fig:signal_contamination_WR}.

\subsubsection{Control region for single top}

Single top processes result in significant background contributions in some \glspl{sr}, necessitating a proper semi-data-driven estimation.
A single top control region (STR) is defined starting from the \glspl{sr} by replacing the Higgs mass window cut on $\mbb$ with $\mbb > \SI{195}{\GeV}$ and removing the bins in $\mct$.

The sideband approach achieves again a low maximum signal contamination of roughly 0.8\%.
The signal contamination across the entire signal grid is shown in \cref{fig:signal_contaminations_STCR}.
The pre-fit purity of the single top processes in STR is 51.7\% and sub-dominant contributions arise from $\ttbar$ processes (29\%), $\wjets$ (10\%) and $\ttbar+V$ (6\%) production.

 \begin{figure}[t]
	\centering
	\begin{subfigure}[b]{0.45\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{strategy_5}
		\caption{\label{fig:cr_strategy}}
	\end{subfigure}\hfill
	\begin{subfigure}[b]{0.45\linewidth}
		\centering\includegraphics[width=1.0\textwidth]{strategy_7}
		\caption{\label{fig:vr_strategy}}
	\end{subfigure}\hfill

	\caption{Configuration of \subref{fig:cr_strategy} the \glspl{cr} (in green) placed around the \glspl{sr} (in blue) off the $\mbb$ window and \subref{fig:vr_strategy} the validation regions in the phase space between the \glspl{cr} and \glspl{sr}. The \glspl{vr} (in red) are arranged such that each of the extrapolations can be validated separately for SR-LM, SR-MM and SR-HM.}
	\label{fig:strategies_vr_cr}
\end{figure}

\section{Validation regions}

Two sets of validation regions are introduced in order to verify the extrapolations over the different distributions. The selections defining all \glspl{vr} are summarised in \cref{tab:CRVRdef}. The first set, called VR-on is situated on the Higgs boson mass peak but with the $\mct$ requirement inverted to $\mct<\SI{180}{\GeV}$. This allows the VR-on regions to validate the extrapolation over $\mbb$, performed when extrapolating the background estimate from the control regions into the signal regions. Three disjunct VR-on regions are introduced, with $\mt$ requirements matching those of the \glspl{sr}, such that the extrapolations can be validated separately for each signal region. The three VR-on regions are aptly named VR-onLM, VR-onMM and VR-onHM. A similar composition of $\ttbar$ decay modes as in the control and signal regions is observed in the VR-on regions, necessary for a trustworthy validation of the $\ttbar$ estimate. A maximum signal contamination of about 5\%--14\% is achieved, depending on the requirement in $\mt$. As can be seen from~\cref{fig:signal_contaminations_VRs}, most signal points have a signal contamination well below 5\% for all VR-on regions.

 The second set of validation regions is located on both sides off the Higgs boson mass peak at same values in $\mct$ than the \glspl{sr}. This set of \textit{off-peak} \glspl{vr}, called VR-off, is used to validate the extrapolation over the $\mbb$ distribution performed in the case of STR. Additionally, the VR-off regions validate the extrapolation over $\mct$, performed in the $\ttbar$ control regions. Similar to the on-peak validation regions, the VR-off regions are split into $\mt$ bins matching the signal regions, allowing a validation of the background estimate in their respective signal region. The bins in VR-off are called VR-offLM, VR-offMM and VR-offHM. The maximum signal contamination in the VR-off regions is found to be about 7\%--13\%, depending on the requirement on $\mt$. Most signal points, however, reveal a signal contamination in the VR-off regions of less than 3\% (cf.~\cref{fig:signal_contaminations_VRs}).


We are interested in two questions:
\begin{itemize}
\item Is it possible to learn an embedding of video frames in a self-supervised manner using only videos from a single viewpoint?
\item Is the learned embedding robust and well-behaved enough to power a reward function to use as part of a reinforcement learning problem?
\end{itemize}

\subsection{Embedding frames of a robotic arm}

We created 200 videos of a robotic arm performing trajectories in a simulated environment. The arm is initialized to random joint positions and it moves to goal joint positions which are also randomly sampled. We use the Bullet 3 physics simulator and a robot modelled after the Kuka iiwa robotic arm.

{
    \label{example-snap}
    \centering
    \includegraphics[width=8cm]{example_snap.png}
    \captionof{figure}{Two example frames from a recorded trajectory. The left frame is the goal position and the right frame is the start position.}
    \vspace{0.5cm}
}

We split the 200 videos such that 190 are used for training and 10 for validation.

We use a convolutional neural network derived from the Inception architecture as presented in \citep{inception-v3}. We use the 8 first layers of the network up until the layer labeled `Mixed\_5d`. We add two batch normalized convolutional layers, one spatial softmax transformation followed by two fully connected layers. This is very similar as the network used in \cite{self-supervised-learning}.

We implemented the neural network using the PyTorch deep learning framework \citep{pytorch}. The layers taken from the inception architecture are initialized to values pretrained on the ImageNet dataset. The added layers are randomly initialized using the default initialization scheme of the PyTorch package.

In our experiments, the output of the network is a 32-dimentional embedding constrained to have an $L_2$ norm of 10. The scaling factor of 10 was motivated by results presented in \cite{constrained-softmax-loss}. We use a margin value of 2.0. The positive frame was sampled from within 10 frames of the anchor frame. The negative frame was sampled from outside a range starting from 30 frames before the anchor frame and ending 30 frames after the anchor frame. The size of a video frame is 299 pixels in width and height.

We use the triplet loss presented in the previous section. At each epoch, we create a dataset of triplets sampled from 5 videos with 200 samples per video. We then run stochastic gradient descent with momentum against the triplet loss over this dataset 5 times after which a new triplet dataset is sampled and the process is repeated. The use a minibatch size of 64 triplets.

We use a learning rate schedule such that we start with a learning rate of 0.1. Each 500 epochs we decrease the learning rate to 1/10th of the previous rate until we reach 0.0001 inclusive. Table \ref{cnn-params} summarises the final parameters we used after tuning. The training of the network was performed on a single NVidia Quadro P5000 GPU.

{
    \vspace{0.5cm}
    \centering
    \begin{tabular}{@{}ll@{}}
    \toprule
    \textbf{Parameter}             & \textbf{Value}    \\ \midrule
    \textbf{minibatch size}        & 64                \\
    \textbf{learning rate}         & 0.1-0.0001        \\
    $\boldsymbol{\delta}$                & 2.0               \\
    \textbf{positive frame margin} & 10                \\
    \textbf{negative frame margin} & 30                \\
    \textbf{optimizer}             & SGD with momentum \\
    \textbf{momentum}              & 0.9               \\
    \textbf{embedding dimensions}  & 32
    \end{tabular}
    \captionof{table}{The parameters we used for training our embedding function.}
    \label{cnn-params}
}

\subsection{Learning to imitate}

We used the learned embedding to teach the same simulated robot to imitate itself in a video performing different trajectories. We use the proximal policy optimization algorithm to optimize the loss function. We used under the MIT license the open source PPO implementation provided by the github user ikostrikov (\url{https://github.com/ikostrikov/pytorch-a2c-ppo-acktr}).

The observation at each time step is a concatenation of the robot joint states, joint velocities, the TCN embedding of an image of itself and the TCN embedding of the next video frame at that timestep.

The reward is calculated using the huber loss presented in section \ref{sec:methods} using the embedding of an image of the robot and the embedding of an example video frame. Actions are torques applied to the 7 joints of the robotic arm. The 5 joints of the end effector were left out to simplify the learning problem.

The output of the policy network is a 7-dimensional vector of which values determine the mean of a \textit{Gaussian} distribution, from which the joint torques are sampled. The action values determine forces of the motors of the seven joints. \textit{Hyperbolic tangent function} is used for the activation function in the fully connected policy network. We experimented different layer structures for the learning problem. As the complexity of the action space is high, the best result was achieved with 3 hidden layers with width 128. The same input value is used for the value network. The network returns recommendation of the state in scalar. The value network shares the same features as the policy network but it has 2 hidden layers.

We trained the imitation agent by running 16 processes of the simulation in parallel. We evaluate the policy network to get an action for each process at each time step. We use a rollout storage to sample updates from. An update is done on the policy and value networks every 1000 time steps by sampling minibatches from the rollout storage. All the parameters we used are summarized in table \ref{ppo-params}.

{
    \vspace{0.5cm}
    \centering
    \begin{tabular}{@{}ll@{}}
    \toprule
    \textbf{Parameter}             & \textbf{Value}    \\ \midrule
    $\boldsymbol{\gamma}$        & 0.99                \\
    $\boldsymbol{\tau}$        & 0.95                \\
    \textbf{clip} $\boldsymbol{\epsilon}$        & 0.2                \\
    \textbf{learning rate}                       & 0.0007 \\
    \textbf{optimizer}                        & Adam \\
    \textbf{epochs each update}        & 4                \\
    \textbf{update interval}        & 1000 time steps                \\
    \end{tabular}
    \captionof{table}{The parameters we used for proximal policy optimization.}
    \label{ppo-params}
}

\subsection{Goal pose experiment}

Before experimenting the imitation problem, we studied how suitable the PPO algorithm is for this kind of environment. In the goal pose experiment the objective is to move a robot arm to randomly sampled goal pose. Better results are achieved with shorter trajectories to the goal pose. The same network structures as in the imitation problem are utilized. The observation at each time step includes a joint position, joint velocities, and the goal pose. The reward in this task is the negative $L_2$ norm of the distance between the goal position and the robot arm position at each time step minus the $L_2$ norm of the previous action.


\documentclass{article}

\usepackage{fullpage}
\usepackage{amsmath}
\usepackage{hyperref}
\usepackage{color}
\usepackage{listings}
\usepackage{tikz}
\usepackage{graphicx}

\author{Sam McSweeney}
\title{Miscellaneous Documentation for the Beamformer}

\begin{document}

\maketitle

\tableofcontents

\section{The ordering of the input files}

The heirarchy of the input data files is, nominally,
\begin{equation}
    [\text{time sample}][\text{channel}][\text{antenna}][\text{polarisation}][\text{complexity}].
\end{equation}
For a second's worth of data in a single file, we have:
\begin{equation}
    10000 \times 128 \times 128 \times 2 \times 2\quad (\times 4\,\text{bits}) = 327680000\,\text{bytes}
\end{equation}

However, the numbering of the antennas and the polarisations as the data come out of the PFB (and after the \texttt{recombine} stage) are different to the ordering assumed by the beamformer.
The $128 \times 2 = 256$ possible antenna/polarisation pairs are mapped as follows.
\begin{table}[!h]
    \centering
    \begin{tabular}{ccc|ccc}
        \multicolumn{3}{c}{Data file} & \multicolumn{3}{c}{Beamformer} \\
        ant & pol & index & index & ant & pol \\
        \hline
        0 & 0 & 0 &  0 &  0 & 0 \\
        0 & 1 & 1 & 16 &  8 & 0 \\
        1 & 0 & 2 & 32 & 16 & 0 \\
        1 & 1 & 3 & 48 & 24 & 0 \\
        2 & 0 & 4 &  1 &  0 & 1 \\
        2 & 1 & 5 & 17 &  8 & 1 \\
        3 & 0 & 6 & 33 & 16 & 1 \\
        3 & 1 & 7 & 49 & 24 & 1 \\
        4 & 0 & 8 &  2 &  1 & 0 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
        32 & 0 & 64 &  64 & 32 & 0 \\
        32 & 1 & 65 &  80 & 40 & 0 \\
        33 & 0 & 66 &  96 & 48 & 0 \\
        33 & 1 & 67 & 112 & 56 & 0 \\
        34 & 0 & 68 &  65 & 32 & 1 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
        64 & 0 & 128 & 128 & 64 & 0 \\
        64 & 1 & 129 & 144 & 72 & 0 \\
        65 & 0 & 130 & 160 & 80 & 0 \\
        65 & 1 & 131 & 176 & 88 & 0 \\
        66 & 0 & 132 & 129 & 64 & 1 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
    \end{tabular}
\end{table}

For efficiency, the beamformer should initially read in the whole second's worth of data in ``data order'', and calculate the index appropriate for a given antenna/polarisation pair as and when needed.
This requires finding the mapping from beamformer indices to data indices.
This becomes easier if we reconsider how we break up the $256$.

\newpage
\noindent If we recast the data file heirarchy\footnote{I'm not sure of the physical bases of this break up---I'm going off Steve Ord's's original code. rec=``Receiver'' and inc=``increment'' are my own terms.} as
\begin{equation}
    [\text{time sample}][\text{channel}][\text{pfb}][\text{receiver}][\text{increment}][\text{complexity}],
\end{equation}
with the sizes being
\begin{equation}
    10000 \times 128 \times 4 \times 16 \times 4 \times 2,
\end{equation}
then we can rewrite the table above as
\begin{table}[!h]
    \centering
    \begin{tabular}{cccc|ccc}
        \multicolumn{4}{c}{Data file} & \multicolumn{3}{c}{Beamformer} \\
        pfb & rec & inc & index & index & ant & pol \\
        \hline
        0 & 0 & 0 & 0 &  0 &  0 & 0 \\
        0 & 0 & 1 & 1 & 16 &  8 & 0 \\
        0 & 0 & 2 & 2 & 32 & 16 & 0 \\
        0 & 0 & 3 & 3 & 48 & 24 & 0 \\
        0 & 1 & 0 & 4 &  1 &  0 & 1 \\
        0 & 1 & 1 & 5 & 17 &  8 & 1 \\
        0 & 1 & 2 & 6 & 33 & 16 & 1 \\
        0 & 1 & 3 & 7 & 49 & 24 & 1 \\
        0 & 2 & 0 & 8 &  2 &  1 & 0 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
        1 & 0 & 0 & 64 &  64 & 32 & 0 \\
        1 & 0 & 1 & 65 &  80 & 40 & 0 \\
        1 & 0 & 2 & 66 &  96 & 48 & 0 \\
        1 & 0 & 3 & 67 & 112 & 56 & 0 \\
        1 & 1 & 0 & 68 &  65 & 32 & 1 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
        2 & 0 & 0 & 128 & 128 & 64 & 0 \\
        2 & 0 & 1 & 129 & 144 & 72 & 0 \\
        2 & 0 & 2 & 130 & 160 & 80 & 0 \\
        2 & 0 & 3 & 131 & 176 & 88 & 0 \\
        2 & 1 & 0 & 132 & 129 & 64 & 1 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
    \end{tabular}
\end{table}

\newpage
\noindent Reversing this table (giving [ant, pol] in terms of [pfb, rec, inc]) yields
\begin{table}[!h]
    \centering
    \begin{tabular}{ccc|cccc}
        \multicolumn{3}{c}{Beamformer} & \multicolumn{4}{c}{Data file} \\
        index & ant & pol & pfb & rec & inc & index \\
        \hline
        0 &  0 & 0 & 0 & 0 & 0 & 0 \\
        1 &  0 & 1 & 0 & 1 & 0 & 4 \\
        2 &  1 & 0 & 0 & 2 & 0 & 8 \\
        3 &  1 & 1 & 0 & 3 & 0 & 12 \\
        4 &  2 & 0 & 0 & 4 & 0 & 16 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
        16 &  8 & 0 & 0 & 0 & 1 & 1 \\
        17 &  8 & 1 & 0 & 1 & 1 & 5 \\
        18 &  9 & 0 & 0 & 2 & 1 & 9 \\
        19 &  9 & 1 & 0 & 3 & 1 & 13 \\
        20 & 10 & 0 & 0 & 4 & 1 & 17 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
         64 & 32 & 0 & 1 & 0 & 0 & 64 \\
         65 & 32 & 1 & 1 & 1 & 0 & 68 \\
         66 & 33 & 0 & 1 & 2 & 0 & 72 \\
         67 & 33 & 1 & 1 & 3 & 0 & 76 \\
         68 & 34 & 0 & 1 & 4 & 0 & 80 \\
        \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \vdots \\
    \end{tabular}
\end{table}

\noindent From this we can see that the relationships between antenna, polarisation, pfb, receiver, and increment are
\begin{align*}
    \text{pfb} &= \text{ant} / 32 & & \text{(integer divide)} \\
    \text{rec} &= (2\times\text{ant}+\text{pol}) \% 16 & & \text{(modulus operator)} \\
    \text{inc} &= (\text{ant} / 8) \% 4
\end{align*}

\section{Beamformer operations}

By the time the data samples have been read in and are ready to be operated on, the beamformer expects two particular quantites to be already pre-calculated and available.
Both are listed in the table below, and both are calculated in \texttt{get\_delays()}.
\begin{table}[!h]
    \centering
    \begin{tabular}{c|l|l}
        Symbol & Variable name & Type \& Dimensions \\[5pt]
        \hline
        $W = \begin{bmatrix} w_X & 0 \\ 0 & w_Y \end{bmatrix}$ & \texttt{complex\_weights\_array} & \texttt{complex double [nstation*npol][nchan]} \\[12pt]
        $J^{-1} = \begin{bmatrix} j_{XX} & j_{XY} \\ j_{YX} & j_{YY} \end{bmatrix}$ & \texttt{invJi} & \texttt{complex double [nstation][npol*npol]}
    \end{tabular}
\end{table}
The individual components in the matrices $W$ and $J^{-1}$ are complex numbers\footnote{I have avoided using the inverse notation on the components of $J$ for brevity.}. The subscript indices denote polarisation, so that $w_X$, for example, can be thought of as only a function of antenna and channel number, while $j_{XX}$ is just a function of antenna.

\subsection{Incoherent beam detection}
A polarisation pair of samples measured by antenna $a$, $D_a = \begin{bmatrix} d_{a,X} \\ d_{a,Y} \end{bmatrix}$, is operated on as follows to produce the incoherent beam product
\begin{equation}
    I_a = D_a^\dagger D_a = (|d_{a,X}|^2 + |d_{a,Y}|^2),
\end{equation}
which is then summed over the antennas to produce the final detected sample
\begin{equation}
    I = \sum_a I_a
\end{equation}

\subsection{Coherent beam detection}
A polarisation pair of samples measured by antenna $a$, $D_a = \begin{bmatrix} d_{a,X} \\ d_{a,Y} \end{bmatrix}$, is operated on as follows to produce the coherent beam product
\begin{equation}
    B_a = \begin{bmatrix} b_{a,X} \\ b_{a,Y} \end{bmatrix} = J_a^{-1} W_a D_a
\end{equation}
which is then summed over the antennas to produce the final detected sample
\begin{equation}
    B = \sum_a B_a
\end{equation}

\paragraph{Efficiency via pre-calculation}
\label{sec:precalc1}
Since, within a second, every sample is multiplied to the same $J^{-1}$ and $W$, the possibility exists for a processing speed by means of pre-calculating the product
\begin{equation}
    F = \begin{bmatrix} f_{XX} & f_{XY} \\ f_{YX} & f_{YY} \end{bmatrix} = J^{-1} W.
\end{equation}
Expressed in terms of the individual components, the calculated beam would then be
\begin{equation}
    b_P = \sum_a \bigg(f_{PX} \, d_X + f_{PY} \, d_Y\bigg),
\end{equation}
where
\begin{equation}
    f_{PQ} = j_{PQ} w_Q.
\end{equation}
Unfortunately, such a pre-calculation was found not to reduce significantly the number of mathematical operations required in the innermost for-loop, and the total time was found to be comprable to the case where the pre-calculation step was not used.
Therefore, this approach was abandoned.

\subsubsection{Noise floor}
In preparation for calculating the Stokes parameters, a quantity called the \texttt{noise\_floor} is calculated, which is a function of channel only,
\begin{equation}
    N = \begin{bmatrix} n_{XX} & n_{XY} \\ n_{YX} & n_{YY} \end{bmatrix}
      = \sum_a B_a B_a^\dagger
\end{equation}
where $\dagger$ denotes the Hermitian transpose.
In particular, note that $n_{XX}$ and $n_{YY}$ are both real-valued, and that $n_{XY} = n_{YX}$.

\paragraph{Efficiency via pre-calculation}
Similarly to the pre-calculation attempted in Section \ref{sec:precalc1}, pre-calculation of the quantities within the product $BB^\dagger$ was attempted in the effort to speed up the overall computation.
This involved expanding the product $BB^\dagger$ as a linear combination of $d_X$ and $d_Y$ (and their conjugates) and pre-calculating the coefficients.
This turned out to actually increase the number of mathematical operations within the innermost for-loop (by virtue of the linear sum), and thus \emph{increase} the total wall time.
Thus, this approach was also abandoned.

\subsubsection{Stokes parameters}

Finally, the Stokes parameters $I$, $Q$, $U$, and $V$, are calculated as follows.
\begin{align}
    I &= \frac{1}{w_\text{ant}}\bigg((|b_X|^2 - n_{XX}) + (|b_Y|^2 - n_{YY})\bigg) \\
    Q &= \frac{1}{w_\text{ant}}\bigg((|b_X|^2 - n_{XX}) - (|b_Y|^2 - n_{YY})\bigg) \\
    U &=  2 \text{Re}\bigg[\frac{1}{w_\text{ant}}\bigg(b_X\,\bar{b}_Y - n_{XY}\bigg)\bigg]\\
    V &= -2 \text{Im}\bigg[\frac{1}{w_\text{ant}}\bigg(b_X\,\bar{b}_Y - n_{XY}\bigg)\bigg]
\end{align}
where $w_\text{ant}$ is a weighting factor equal to the number of antennas used in the sums.

\newpage
\section{Inverting the PFB}

This section describes the PFB inversion (or, perhaps more accurately, resynthesis) algorithm that has been implemented as part of \texttt{make\_beam\_small}.
No attempt is made to justify the algorithm; here, we only describe it.

The resynthesis algorithm takes a single coarse channel's worth of data at some sampling rate (in our case, $10\,$kHz), consisting of some fixed number of fine channels (in our case, 128), and applies a specific filter to reconstruct a single time series at some upsampled rate (in our case, $1.28\,$MHz).
This is schematically represented in Fig. \ref{fig:schematic}.
\begin{figure}[!ht]
    \centering
    \includegraphics[scale=0.6]{images/pfb_fig1.pdf}
    \vspace{-1cm}
    \caption{A schematic of the data transformation that takes place under the PFB inversion algorithm. On the left are the fine-channelised time samples, sampled at $10\,$kHz. On the right is a single channel, sampled at $1.28\,$MHz, in which each time sample is a weighted sum of a block of original $10\,$kHz time samples.}
    \label{fig:schematic}
\end{figure}

{\bf Each resynthesised time sample is simply a weighted sum of a block of fine channel samples}, and the pairing of samples and weights for a given output time sample is described below.
The weights are derived from the filter coefficients that were used in the (forward) PFB.
These filter coefficients, in their original form, are a fixed set of 1536 ($= 12 \times 128$) real numbers, shown in Fig. \ref{fig:filter_coeffs}.
\begin{figure}[!b]
    \centering
    \includegraphics[scale=0.45]{images/filter_coeffs.png}
    \caption{The PFB filter coefficients, retrieved from \url{http://mwa-lfd.haystack.mit.edu/twiki/bin/view/Main/Finepfb}. The vertical lines divide the coefficients up into 12 sets (or ``taps'') of 128 coefficients each.}
    \label{fig:filter_coeffs}
\end{figure}
In order to keep the magnitudes of the resulting numbers small (for packing into 8-bit integers for the VDIF format), we scale the filter coefficients down by the (arbitrary) factor $1.2 \times 10^{5}$.
This number was chosen to normalise the maximum coefficient value to approximately $1$.

Using the 1536 filter coefficients, we now form a 2D array ($128 \times 1536$) of weights as follows.
The filter coefficients ($f$) are copied into each row, and each element $(i,j)$ is multiplied with a complex number with unit length and phase $\phi_{ij}$.
That is, the weights array is
\begin{equation}
    w_{ij} = f_j e^{\phi_{ij}},
\end{equation}
where
\begin{equation}
    \phi_{ij} = \frac{-2\pi(i-i_c)j}{128},
\end{equation}
and where $i_c$ is the row number associated with the central fine channel, corresponding to the ``DC'' bin (in our case, $i_c = 64$, remembering that channel numbers start at $0$).
The result is a complex-valued 2D array whose magnitudes and phases are plotted in Fig. \ref{fig:weights}.
\begin{figure}[!b]
    \centering
    \includegraphics[scale=0.45]{images/weights_abs.png}
    \includegraphics[scale=0.45]{images/weights_arg.png}
    \caption{The weights array ($128 \times 1536$), generated from the filter coefficients plotted in Fig. \ref{fig:filter_coeffs}. The magnitudes are plotted above, and the phases below.}
    \label{fig:weights}
\end{figure}
Each row of the weights array can be considered as the original filter coefficients multiplied by a {\bf phase ramp} whose slope depends on its proximity to the central fine channel.

The weights array (Fig. \ref{fig:weights}) is multiplied element-wise to an equally sized array formed out of the fine-channelised time samples, as follows.
The time samples are upsampled by inserting 127 zeros between each time step, as illustrated schematically in Fig. \ref{fig:upsample}.
\begin{figure}[!ht]
    \centering
    \includegraphics[scale=0.6]{images/pfb_fig2.pdf}
    \vspace{-1cm}
    \caption{A schematic of the process of upsampling the fine-channelised data. In the diagram, the upsampling factor is 6, whereas in this algorithm, the upsampling factor is the same as the number of channels, i.e., 128.}
    \label{fig:upsample}
\end{figure}
The upsampled time samples now form an $128 \times N$ grid, where $N = 128T$, where $T$ is the original number of samples.

The weights array can now be slid horizontally over the upsampled time samples array, shifting across by one sample at a time.
In this algorithm, we have identified the $n$th output time sample (starting, as usual, with $n = 0$) with the slide position in which the rightmost column of the weights array is aligned with the $n$th column of the upsampled time samples array.
In particular, this means that the first sample that makes use of the whole weights array is $n = 1535$, since then the leftmost column is aligned with $n = 0$.
The final value of the $n$th output time sample ($y_n$) is then the sum of the upsampled time samples ($x_n$) multiplied element-by-element with the corresponding weights array slid into the $n$th position:
\begin{equation}
    y_n = \begin{cases}
        0, &\qquad n < 1535, \\[5pt]
              \sum\limits_{i=0}^{(127)} \sum\limits_{j=0}^{(1535)} w_{ij} x_{ij^\prime}, &\qquad \text{otherwise,}
          \end{cases}
    \label{eqn:invertpfb}
\end{equation}
where $j^\prime = j + n - 1536$.

\subsection{Optimisations}

The upsampling of the time samples by a factor of 128 (as shown in Fig. \ref{fig:upsample}) means that almost all (127 out of every 128) of the terms in Eqn. \eqref{eqn:invertpfb} vanish.
Therefore, the algorithm as implemented in \texttt{make\_beam\_small} does not blindly iterate over $i$ and $j$, as the above suggests---instead, only the non-zero terms are considered.
In practise, each output time sample is only the sum of $12 \times 128 = 1536$ non-zero weighted terms, and rather than doing a memory-costly upsampling operation, the indices for the needed terms are calculated as needed.

This works out as follows.
Consider the $n$th output time sample.
The column numbers of the weight matrix that are required for this sample is
\begin{equation}
    j_m = 128(m+1) - (n \mod 128) - 1, \quad \forall m \in \{0,1,\dots,11\}.
\end{equation}
The corresponding columns of the original time samples (i.e. \emph{without} upsampling) are
\begin{equation}
    j_m^\prime = \left\lfloor \frac{n - 1536}{128} \right\rfloor + (m+1), \quad \forall m \in \{0,1,\dots,11\}.
\end{equation}
Thus, Eqn. \eqref{eqn:invertpfb} is actually implemented as
\begin{equation}
    y_n = \begin{cases}
        0, &\qquad n < 1535, \\[5pt]
              \sum\limits_{i=0}^{(127)} \sum\limits_{m=0}^{(11)} w_{ij_m} x_{ij_m^\prime}, &\qquad \text{otherwise,}
          \end{cases}
    \label{eqn:invertpfb_optimised}
\end{equation}
with $j_m$ and $j^\prime_m$ as defined above.

\end{document}