%  American Nuclear Society Transaction template
%  by Diego Mandelli (INL)
%  Most of the template has been built by Seth R. Johnson
%  based on the ANS transaction guidelines

\documentclass{anstrans}

\usepackage{algorithm}
\usepackage{algpseudocode}
\usepackage{graphicx}
\usepackage{amsmath}
% \usepackage{fmtcount}

\usepackage[none]{hyphenat}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\title{PERFORMING PROBABILISTIC RISK ASSESSMENT THROUGH RAVEN}
\author{A. Alfonsi \and  C. Rabiti \and D. Mandelli \and J.J. Cogliati \and R.A. Kinoshita}

\institute{
Idaho National Laboratory
}

\email{ \{andrea.alfonsi, cristian.rabiti, diego.mandelli, joshua.cogliati, robert.kinoshita\}@inl.gov }

%%%% packages and definitions (optional)
\usepackage{graphicx} % allows inclusion of graphics
\usepackage{booktabs} % nice rules (thick lines) for tables
\usepackage{microtype} % improves typography for PDF
\usepackage{dblfloatfix} % fix two-column floats to allow bottom placement

\newcommand{\SN}{S$_N$}
\renewcommand{\vec}[1]{\bm{#1}} %vector is bold italic
\newcommand{\vd}{\bm{\cdot}} % slightly bold vector dot
\newcommand{\grad}{\vec{\nabla}} % gradient
\newcommand{\ud}{\mathop{}\!\mathrm{d}} % upright derivative symbol

\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  \twocolumn[
    \begin{@twocolumnfalse}
        \maketitle
    \end{@twocolumnfalse}
  ]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
RAVEN (\textbf{R}eactor \textbf{A}nalysis and \textbf{V}irtual control \textbf{EN}viroment)~\cite{ravenFY12,mandelliANS2012} is a software framework that acts as the control logic driver for the Thermal-Hydraulic code RELAP-7, a newly developed software at Idaho National Laboratory. This paper provide an overview of the RAVEN software structure and its utilization in conjunction with RELAP-7/MOOSE~\cite{MOOSE,relap7FY12}. RAVEN is a multi-purpose Probabilistic Risk Assessment (PRA) code that allows dispatching different functionalities.
It is designed to derive and actuate the control logic required to simulate both plant control system and operator actions (guided procedures) and to perform both Monte-Carlo sampling of random distributed events and dynamic event tree based analysis~\cite{ADAPTHakobyan}.
In order to assist the user in the input/output handling, a Graphical User Interface (GUI) and a post-processing data mining module, based on dimensionality and cardinality reduction~\cite{mandelliEsrel2011}, are available.
This paper focuses on the link between the software layout and the mathematical framework from which its structure is derived. In order to show the code capabilities, a demo of a Station Black Out (SBO) analysis of a simplified Pressurized Water Reactor (PWR) model is presented.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{MATHEMATICAL FRAMEWORK}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\label{sec:mathFramework}
Let be $\bar{\theta}(t)$ a vector describing the plant status in the phase space; the dynamic of the plant, including the control system, can be summarized by the following equation:
\begin{equation}
\frac{\partial \bar{\theta}}{\partial t} = \bar{H}(\theta(t),t)
\label{eq:SystemDynamics}
\end{equation}
In the above equation it is assumed the time differentiability in the phase space. Performing an arbitrary decomposition of the phase space, the following statement is obtained:
\begin{equation}
\bar{\theta}=\binom{\bar{x}}{\bar{v}}
\label{eq:firstDecomposition}
\end{equation}

The decomposition is made in such a way that $\bar{x}$ represents the unknowns solved by RELAP-7, while $\bar{v}$ are the variables directly controlled by the control system (i.e., RAVEN). Equation~\ref{eq:SystemDynamics} can now be rewritten as follows:
\begin{equation}
\begin{cases}
\dfrac{\partial \bar{x}}{\partial t} = \bar{F}(\bar{x},\bar{v},t) \\
\dfrac{\partial \bar{v}}{\partial t} = \bar{V}(\bar{x},\bar{v},t) \\
\end{cases}
\label{eq:generalSystemEquation}
\end{equation}
It is possible to note that the function $\bar{V}(\bar{x},\bar{v},t)$ representing the control system, does not depend on the knowledge of the complete status of the system but on a restricted subset (i.e. control variables) $\bar{C}$:
\begin{equation}
\begin{cases}
\dfrac{\partial \bar{x}}{\partial t} = \bar{F}(\bar{x},\bar{v},t) \\
\bar{C} = \bar{G}(\bar{x},t) \\
\dfrac{\partial \bar{v}}{\partial t} = \bar{V}(\bar{x},\bar{v},t)
\end{cases}
\label{eq:generalSystemEquationwithControl}
\end{equation}

The system of equations in Eq.~\ref{eq:generalSystemEquationwithControl} is fully coupled and has commonly been solved by an operator splitting approach. The reasons for this choice are several:
\begin{itemize}
\item Control system reacts with an intrinsic delay
\item The reaction of the control system might move the system between two different discrete states and
therefore numerical errors will be always of first order unless the discontinuity is treated explicitly.
\end{itemize}
\begin{figure}
\centering
\includegraphics[width=0.35\textwidth]{figures/ControlSystemSoftwareLayout.pdf}
\caption{Control System Software Layout.}
\label{fig:ControlSoftwareLayout}
\end{figure}
Thus, RAVEN is using this approach (Fig.~\ref{fig:ControlSoftwareLayout}) to solve Eq.~\ref{eq:generalSystemEquationwithControl} which becomes:
\begin{equation}
\begin{cases}
\dfrac{\partial \bar{x}}{\partial t} = \bar{F}(\bar{x},\bar{v}_{t_{i-1}},t) \\
\bar{C} = \bar{G}(\bar{x},t) & t_{i-1}\leq t\leq t_{i} = t_{i-1} + \Delta t_{i}\\
\dfrac{\partial \bar{v}}{\partial t} = \bar{V}(\bar{x},\bar{v}_{t_{i-1}},t) \\
\end{cases}
\label{eq:generalSystemEquationwithControlSplitting}
\end{equation}
Even if all information needed is contained in $\bar{x}$ and $\bar{v}$, it is not a practical and efficient way to implement the control system. Hence, a system of auxiliary variables has been introduced.
The auxiliary variables are those that in statistical analysis are artificially added, when possible, to non-Markovian systems into the space phase to obtain a Markovian behavior back, so that only the information of the previous time step is needed to determine the future status of the system.
Thus, the introduction of the auxiliary system into the mathematical framework leads to the following formulation of the Eq.~\ref{eq:generalSystemEquationwithControlSplitting}:
\begin{equation}
\begin{cases}
\dfrac{\partial \bar{x}}{\partial t} = \bar{F}(\bar{x},\bar{v}_{t_{i-1}},t) \\
\bar{C} = \bar{G}(\bar{x},t) & t_{i-1}\leq t\leq t_{i} = t_{i-1} + \Delta t_{i}\\
\dfrac{\partial \bar{a}}{\partial t} = \bar{A}(\bar{x},\bar{C},\bar{a}_{t_{i-1}},\bar{v}_{t_{i-1}},t) \\
\dfrac{\partial \bar{v}}{\partial t} = \bar{V}(\bar{x},\bar{v}_{t_{i-1}},\bar{a},t)
\end{cases}
\label{eq:generalSystemEquationwithControlSplittingAndAux}
\end{equation}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{SOFTWARE STRUCTURE}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
RAVEN, is plugged with the software environment MOOSE~\cite{MOOSE}. MOOSE is a computer simulation framework,  developed at Idaho National Laboratory (INL), that simplifies the process for predicting the behavior of complex systems and developing non-linear, multi-physics simulation tools. Other than providing the algorithms for the solution of the differential equation, MOOSE also provides all the manipulation tools for the \verb!C++! classes containing the solution vector. This framework has been used to construct and develop the Thermal-Hydraulic code RELAP-7, giving an enormous flexibility in the coupling procedure with RAVEN.

RELAP-7 is the next generation nuclear reactor system safety analysis. It will become the main reactor systems simulation toolkit for RISMC (\textbf{R}isk \textbf{I}nformed \textbf{S}afety \textbf{M}argin \textbf{C}haracterization)~\cite{mandelliANS_RISMC} project and the next generation tool in the RELAP reactor safety/systems analysis application series.
RAVEN has been developed in a high modular and pluggable way in order to enable easy integration of different programming languages (i.e., \verb!C++!, \verb!Python!) and coupling with other applications including the ones based on MOOSE. The code consists of four main modules:
\begin{itemize}
\item RAVEN/RELAP-7 interface
\item \verb!Python! Control Logic
\item \verb!Python! Calculation Driver
\item Graphical User Interface
\end{itemize}

The RAVEN/RELAP-7 interface, coded in \verb!C++!, is the container of all the tools needed to interact with RELAP-7/MOOSE. It has been designed in order to be general and pluggable with different solvers simultaneously in order to allow an easier and faster development of the control logic/PRA capabilities for multi-physics applications.
%(to properly generate the monitored quantities and accordingly modify the controlled
% parameters in the raven/relap7 simulation)
The interface provieds all the capabilities to generate the monitored quantities and accordingly modify the controlled parameters in the RELAP-7/MOOSE calculation.
%The interface provides all the capabilities to control, monitor, and process the %parameters/quantities in order to drive the RELAP-7/MOOSE calculation.
In addition, it contains the tools to communicate to the MOOSE input parser which information, i.e. input syntax, must be provided in order to run a RAVEN  calculation.\\The control logic module is used to drive a RAVEN/RELAP-7 calculation. Up to now it is implemented by the user via \verb!Python! scripting. The reason of this choice is to try to preserve generality of the approach in the initial phases of the project so that further specialization is possible and  inexpensive. The implementation of the control logic via \verb!Python! is rather convenient and flexible. The user only needs to know few \verb!Python! syntax rules in order to build an input. Although this extreme simplicity, it will be part of the GUI task to automatize the construction of the control logic scripting in order to minimize user effort.

The core of PRA analysis is contained in the module called "Raven Runner". It consists of a \verb!Python! driver in which Monte-Carlo based algorithm has been implemented. It calls RAVEN multiple times, changes initial conditions and seeds the random generator for the distributions.
The multiple calculations, required by the employment of these algorithms, can be run in parallel, using queues/sub-process/\verb!Python! systems. The analysis of dynamic stochastic systems through Monte-Carlo algorithm can be summarized as follows:
\begin{enumerate}
\item Initial Sampling of:
       \begin{enumerate}
       \item Physical parameters
       \item Initial conditions
       \item Transition conditions, i.e. time instant in which transition events occur (e.g., time in which a reactor scram occurs, etc.)
    \end{enumerate}
\item Run the system simulator using the values previously sampled and eventually applying a random noise to some parameters at each time step
\item Repeat 1 and 2 for a large number of calculations (user input)
\end{enumerate}
The "runner" basically performs a different seeding of the random number generator and interact, through RAVEN, with the \verb!Python! control logic input in order to sample the variables specified by the user.

As previously mentioned, a Graphical User Interface (GUI) is not required to run RAVEN, but it represents an added value to the whole code. The GUI is compatible with all the capabilities actually present in RAVEN (control logic, Monte-Carlo, etc.).  Its development is performed using QtPy, which is a \verb!Python! interface for a \verb!C++! based library (\verb!C++!) for GUI implementation. The GUI is based on a software named Peacock, which is a GUI interface for MOOSE based application and, in its base implementation, is only able to assist the user in the creation of the input.  In order to make it fit all the RAVEN needs, the GUI has been specialized and is in continuous evolution.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{DEMO FOR A PWR PRA ANALYSIS}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
In order to show the capabilities of RAVEN coupled with RELAP-7/MOOSE, a PRA analysis on a simplified PWR model (Fig.~\ref{fig:PWRmodel}) has been employed.
\begin{figure}
   \centering
    \includegraphics[width=0.4\textwidth]{figures/PWR_TMI_SCHEME.PNG}
    \caption{PWR model scheme.}
    \label{fig:PWRmodel}
\end{figure}
\\Since RELAP-7 still has limitations for the component controllable parameters and models, it has been necessary to act on unconventional factors (i.e. inlet/outlet friction factors in order to simulate a realistic pump coast-down).
\begin{figure} [H]
\centering
  \centering
  \includegraphics[width=0.35\textwidth]{figures/PRA_dist2.png}
  \label{fig:pdf_temp}
   \caption{Comparison between max reached clad temperature and clad failure temperature distributions: Probability distribution functions.}
\label{fig:distributionResults}
\end{figure}

The Probabilistic Risk Assessment analysis has been performed simulating a Station Black Out accident, running Monte-Carlo samplings (400 simulations) on the recovery time of the diesel generators $t_{1}$ (Normal distribution, mu = 120 s, sigma = 20 s) and the clad failure temperature $TC{f}$(Triangular distribution, xPeak = 1477.59 K, xMin~ =~1255.37 K, xMax = 1699.82 K). Since the scope of this demo is to show the functionalities contained in RAVEN and RELAP-7 is not yet optimized for long simulation times, the transient has been accelerated in order to simulate a maximum of 300 seconds.
Figure~\ref{fig:distributionResults} shows the distribution of the maximum temperature reached by the clad in the core channels (blue histogram) and compares it with the distribution of clad failure temperature (red histogram).
As already mentioned, the transient has been accelerated, since the scope of the analysis was just to show RAVEN capabilities to perform stochastic analysis of relatively complex systems. %That can explain the large overlapping of the two distributions, which indicates a high failure %probability of the system considered.

Figure~\ref{fig:limit_surface_rng_temp_and_dg} shows the limit surface, i.e. the boundaries between system failure (red points) and system success (green points), obtained by the 400 Monte-Carlo simulations. Since only two uncertain parameters have been considered (i.e., DG recovery time and clad fail temperature), this boundary lies in a 2-dimensional space.
The slope of the limit surface pictured in Fig.~\ref{fig:limit_surface_rng_temp_and_dg} also shows, in this particular demo, how the DG recovery time has a greater impact on the system dynamics then the clad failure temperature.
\begin{figure}
   \centering
    \includegraphics[width=0.45\textwidth]{figures/PRA_limitSurface.png}
    \caption{Limit Surface for the SBO analysis of a simplified PWR model}
    \label{fig:limit_surface_rng_temp_and_dg}
\end{figure}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{CONCLUSIONS}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
In this paper it has been presented RAVEN as a tool to perform dynamic PRA through Monte-Carlo sampling. In particular, the software structure and all the components that are involved in the computation have been presented, including system simulator (i.e., RELAP-7) and the control logic, characterized by a monitoring system and on-line control of selected parameters.
An example of PRA analysis has been also presented for a SBO-like case for a simplified PWR loop.
The description of the implementation for such case demonstrates how the flexibility of the software framework provides the basic tools to perform Dynamic PRA, uncertainty quantification and plant control.
Next capabilities, to be implemented to RAVEN and that are currently under development, include dynamic event tree generation~\cite{ADAPTHakobyan}, adaptive sampling~\cite{mandelliSVMANS} and more advanced data mining algorithms~\cite{mandelliEsrel2011}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{ENDNOTES}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
This work is supported by the U.S. Department of Energy, under DOE Idaho Operations Office Contract DE-AC07-05ID14517. Accordingly, the U.S. Government retains a nonexclusive, royalty-free license to publish or reproduce the published form of this contribution, or allow others to do so, for U.S. Government purposes.

\bibliographystyle{ans}
\bibliography{bibl}
\end{document}


\section{Upcoming Enhancements}

\begin{enumerate}
\item Discover and remedy bug in fea\_solver.py that is preventing convergence. Suspicions are that the tangent has been implemented incorrectly.
\item Convert tensor representation in C++ code to vector-matrix representation to speed up the code.
\item Add in dynamic loading to the element.
\item Add in distributed loading.
\end{enumerate}


\section{Particle properties in EvtGen}

\label{sect:pdttable}
\index{evt.pdl}
\index{particle properties}

In EvtGen, all particle property information is
contained within {\tt evt.pdl} and is parsed
at runtime.  Each line in {\tt evt.pdl} corresponds
to a particle, and has the form
\begin{verbatim}
add  p Lepton  mu-       13  0.1056584  0     0   -3  1 658654.  13
add  p Lepton  mu+      -13  0.1056584  0     0    3  1 658654.   0
add  p Meson   pi+      211  0.139570   0     0    3  0  7804.5 101
add  p Meson   pi-     -211  0.139570   0     0   -3  0  7804.5   0
add  p Meson   rho+     213  0.7685     0.151 0.4  3  2       0 121
add  p Meson   rho-    -213  0.7685     0.151 0.4 -3  2       0   0
add  p Meson   D0       421  1.86451    0     0    0  0  0.1244 105
add  p Meson   anti-D0 -421  1.86451    0     0    0  0  0.1244   0
\end{verbatim}
The first three columns are not used in EvtGen.  The fourth column
corresponds to the particle name.  The fifth column is the particle
number according to the stdhep numbering scheme.
The sixth through eighth columns
contain the mass, width, and maximum allowed deviation from the mean mass
in the downward direction,
respectively.  The nineth column contains 3 times the charge of the particle.
The tenth column contains twice the spin.  The eleventh column is $c \tau$
in mm.  The twelvth column is the Lund-KC number. This is used for the
interface to JetSet and has to match what is in lucomp.F.


\section{Vending Circuit IO}
The purpose of this section is to Provide extra detail on the specification of IO streams and how they interface with other devices.

\subsection{Vend Details}
\begin{itemize}
\item \textbf{Clock:} The clock signal tells the circuit to subtract the value of the vended item from the value that is currently stored in memory. A clock pulse is only allowed to reach the memory if the amount of money int he machine is greater than the cost of the item. Thus, if the user requests an item without putting enough money into the machine the machine will not vend the item. We considered whether or not it would be beneficial to give the user some feedback if they requested an item that they had not put in enough money for and decided that since the amount of money currently in the machine is displayed along with the cost of the item that they want to buy that this feedback would be redundant.
\item $\mathbf{B_{0..5}}$\textbf{:} These inputs are a binary representation of the price of the item with $B_0$ being the least significant bit. They are loaded from the item selector circuit.
\item \textbf{Selector:} This is the same selector bit as in section \ref{selector}.
\end{itemize}

\subsection{Output Details}
\begin{itemize}
\item \textbf{Dollars In Machine:} This is the same as in section \ref{dollars-in-machine}.
\end{itemize}


\begin{apendicesenv}

\partapendices \chapter{Simulação}
\label{apendice}

%New colors defined below
\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
\definecolor{backcolour}{rgb}{0.95,0.95,0.92}

%Code listing style named "mystyle"
\lstdefinestyle{mystyle}{
  backgroundcolor=\color{backcolour},   commentstyle=\color{codegreen},
  keywordstyle=\color{magenta},
  numberstyle=\tiny\color{codegray},
  stringstyle=\color{codepurple},
  basicstyle=\ttfamily\footnotesize,
  breakatwhitespace=false,
  breaklines=true,
  captionpos=b,
  keepspaces=true,
  numbers=left,
  numbersep=5pt,
  showspaces=false,
  showstringspaces=false,
  showtabs=false,
  tabsize=2
}

%"mystyle" code listing set
\lstset{style=mystyle}

\begin{lstlisting}[language=Python, caption=API - NMF Machine Learning Code]
import numpy as np
import pandas as pd
from numpy import genfromtxt
from sklearn.decomposition import NMF
from sklearn.preprocessing import OneHotEncoder
import pickle
from operator import itemgetter

def train_model():
    recommendations = pd.read_csv('./nmf/ML/recommendations.csv',
                                  names=['search_profile_id',
                                         'property_id',
                                         'like/dislike'],
                                  engine='c',
                                  low_memory=False)
    search_profile_ids = recommendations[0:]['search_profile_id'].unique()

    property_ids = recommendations[0:]['property_id'].unique()
    property_list_id = pd.DataFrame(data=property_ids, index= None)
    property_list_id.to_csv(r'./nmf/ML/property_list_id.csv', index=None, header=True)

    column_list = []

    for x in property_ids:
        column_list.append(str(x) + '_like')
        column_list.append(str(x) + '_dislike')
        column_list.append(str(x) + '_nan')

    matrix = pd.DataFrame(0, index=search_profile_ids, columns=column_list)

    for x in property_ids:
        matrix.loc[:,[str(x) + '_nan']] = np.int_(1)

    template = matrix[:1]
    template.to_csv(r'./nmf/ML/template.csv', index=None, header=True)

    for x, row in recommendations.iterrows():
        search_profile_id = row[0]
        property_id = row[1]
        matrix.loc[[search_profile_id],[str(property_id) + '_like']] = row[2]
        matrix.loc[[search_profile_id],[str(property_id) + '_dislike']] = row[2]*(-1)+1
        matrix.loc[[search_profile_id],[str(property_id) + '_nan']] = np.int_(0)

    matrix.to_csv(r'./nmf/ML/training_matrix.csv', header=True)

    X = matrix
    model = NMF(n_components=20, init='random', random_state=0)
    model.fit(X)
    filename = './nmf/ML/NMF_model.sav'
    pickle.dump(model, open(filename, 'wb'))

    print("Treino do modelo finalizado!")

def generate_recommendations_for_all_users():
    X = pd.read_csv('./nmf/ML/training_matrix.csv',
                    engine='c',
                    low_memory=False)
    X = X.set_index('Unnamed: 0')

    template = pd.read_csv('./nmf/ML/template.csv',
                           engine='c',
                           low_memory=False)
    model = pickle.load(open('./nmf/ML/NMF_model.sav', 'rb'))

    search_profile_ids = pd.read_csv('./nmf/ML/search_profile_ids.csv',
                                     names=['search_profile_id'],
                                     engine='c',
                                     low_memory=False)
    i = 0
    for x, id in search_profile_ids.iterrows():
        if not id[0] in X.index:
            i += 1
            print(i)
            X = X.append(template.rename(index={0: id[0]}))

    W = model.transform(X)
    H = model.components_

    matrix_response = pd.DataFrame(data=np.dot(W,H),
                                   index= X.index,
                                   columns=X.columns)

    return get_property_ids(matrix_response)

def get_property_ids(matrix_response):
    result = {}
    for x, row in matrix_response.iterrows():
        property_id_list = []
        i = 0
        while(i != len(matrix_response.columns)):
            value = row[i]
            property_id = int(matrix_response.columns[i].replace('_like', ''))
            property_id_list.append([property_id, value])
            i += 3
        result[str(x)] = list(map(lambda x: x[0], sorted(property_id_list, key=itemgetter(1))[-6:-1]))
    return result
\end{lstlisting}

\begin{lstlisting}[language=Python, caption=API - views.py]
from django.shortcuts import render
from .ML.ml_methods import generate_recommendations_for_all_users, train_model
from django.http import HttpResponse, JsonResponse
from .models import Properties, Recommendation
from django.core.serializers import serialize
import json

def train_model_and_generate_recommendations(request):
    train_model()
    recommendations = generate_recommendations_for_all_users()
    Recommendation.objects.all().delete()
    recommendation = Recommendation.objects.create(data=recommendations)
    return HttpResponse(json.dumps({"success": "Recommendations successfully generated!"}), content_type="application/json")

def get_recommendations(request, search_profile_id):
    recommendations = Recommendation.objects.first().data
    properties = recommendations[str(search_profile_id)]
    response = []
    for id in properties:
        property = Properties.objects.get(id=int(id))
        response.append(property)
    return HttpResponse(serialize('json', response),  content_type="application/json")
\end{lstlisting}

\begin{lstlisting}[language=Python, caption=API - models.py]
from django.db import models
from django.contrib.postgres.fields import JSONField

class Recommendation(models.Model):
    data = JSONField()

class Properties(models.Model):
    id = models.BigAutoField(primary_key=True)
    description = models.TextField(blank=True, null=True)
    address = models.CharField(max_length=50, blank=True, null=True)
    sale_price = models.FloatField(blank=True, null=True)
    bedrooms = models.IntegerField(blank=True, null=True)
    suites = models.IntegerField(blank=True, null=True)
    parking_spots = models.IntegerField(blank=True, null=True)
    created_at = models.DateTimeField()
    updated_at = models.DateTimeField()
    property_type = models.CharField(max_length=50, blank=True, null=True)
    bathrooms = models.IntegerField(blank=True, null=True)
    state = models.CharField(max_length=50, blank=True, null=True)
    city_name = models.CharField(max_length=50, blank=True, null=True)
    postal_code = models.CharField(max_length=50, blank=True, null=True)
    street_number = models.CharField(max_length=50, blank=True, null=True)
    administration_fee = models.FloatField(blank=True, null=True)
    iptu = models.FloatField(blank=True, null=True)
    images = models.TextField(blank=True, null=True)
    property_subtype = models.CharField(max_length=50, blank=True, null=True)
    category = models.CharField(max_length=50, blank=True, null=True)
    complement = models.CharField(max_length=50, blank=True, null=True)
    rent_price = models.FloatField(blank=True, null=True)
    livingrooms = models.IntegerField(blank=True, null=True)
    elevators = models.IntegerField(blank=True, null=True)
    units_per_floor = models.IntegerField(blank=True, null=True)
    floors = models.IntegerField(blank=True, null=True)
    usable_area = models.IntegerField(blank=True, null=True)
    total_area = models.IntegerField(blank=True, null=True)
    accepts_exchange = models.BooleanField(blank=True, null=True)
    exchange_description = models.TextField(blank=True, null=True)
    down_payment = models.FloatField(blank=True, null=True)
    monthly_payment = models.FloatField(blank=True, null=True)
    offer_type = models.IntegerField(blank=True, null=True)
    neighborhood_id = models.IntegerField(blank=True, null=True)
    code = models.CharField(max_length=50, blank=True, null=True)
    latitude = models.FloatField(blank=True, null=True)
    longitude = models.FloatField(blank=True, null=True)
    title = models.CharField(max_length=50, blank=True, null=True)
    features_list = models.TextField(blank=True, null=True)
    condominium_features_list = models.TextField(blank=True, null=True)
    available = models.BooleanField(blank=True, null=True)
    square_meter_price = models.FloatField(blank=True, null=True)
    real_estate_id = models.IntegerField(blank=True, null=True)
    unavailable_date = models.DateField(blank=True, null=True)
    reasons = models.TextField(blank=True, null=True)
    city_id = models.BigIntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'properties'
\end{lstlisting}

\end{apendicesenv}


\chapter{Kinematic weighting}
\label{chap:cpv:kinematic_weighting}

For the assumptions in \cref{eqn:cpv:theory:dacp} to hold, the
kinematics of the particles contributing to the background asymmetries must be
equal between the \pKK\ and \ppipi\ final states.
These are the kinematics of the \PLambdab, the muon from the \PLambdab, and the
proton from the \PLambdac.
Within a particular \phh\ final state, it must also be the case that the \Php\
and \Phm\ kinematics are equal in order that $\ADf(f)$ only contains
contributions from the proton detection asymmetry $\AD(\Pproton)$.
A comparison of these distributions between the 2012 magnet down \pKK\ and
\ppipi\ datasets is given in
\cref{fig:cpv:kinematic_weighting:pre:Lb,fig:cpv:kinematic_weighting:pre:Lb_mu,fig:cpv:kinematic_weighting:pre:Lc,fig:cpv:kinematic_weighting:pre:Lc_p,fig:cpv:kinematic_weighting:pre:pKK_h1h2,fig:cpv:kinematic_weighting:pre:ppipi_h1h2}.
The signal distributions are shown, where the contents of each bin is defined
as the sum of signal sWeights within that bin, as computed from the result of
the mass fit to the charge-combined samples described in
\cref{chap:cpv:prelim_fits}.
The correlation of the variables with the \PLambdac\ mass is seen to be small,
with a correlation coefficient less than \SI{2}{\percent} for all variables.
Only the muon kinematics across the modes and the \hmhp\ kinematics within the
modes agree, and so a weighting is necessary.

A \acf{BDT} is used to equalise the relevant particle kinematics between the
two modes.
This is an uncommon technique in physics analyses, with ratios of
multi-dimensional histograms being used more often, and so it will be briefly
summarised in the following.
(An introduction to decisions trees and boosting is presented in
\cref{chap:decision_trees}.)
The creation of the specific models using for weighting will then be presented,
followed by a discussion on weighting validation.

\section{Weighting with decision trees}
\label{chap:cpv:kinematic_weighting:bdt_method}

It is common in \acl{HEP} to want to be able to bring two distributions into
agreement, as is the case in this analysis where particle kinematics should be
equal between the \pKK\ and \ppipi\ data.
Call one possibly multi-dimensional distribution the \emph{target} $f_{t}$ and
the other the \emph{original} distribution $f_{o}$.
To transform $f_{o}$ to have the same form as $f_{t}$, there is some
transformation function $W$
\begin{equation}
  f_{t}(x) = W(x)f_{o}(x),
\end{equation}
where $x$ is a possibly multi-dimensional parameter.
As the true distributions of $f_{t}$ and $f_{o}$ are not known in the data,
they are approximated as histograms, partitioning the data in $x$ and counting
the number of events that fall in each bin.
The transformation function is quantised as $w$ in bins, where in the $i$th bin
\begin{equation}
  f_{t}(x_{i}) = w(x_{i})f_{o}(x_{i}),
\end{equation}
and where $f_{t(o)}(x_{i})$ is the count of the target (original) distribution
in the $i$th bin.
The histogram of $f_{o}$ can be transformed to that of $f_{t}$ by computing the
per-bin \emph{weights}
\begin{equation}
  w(x_{i}) = \frac{f_{t}(x_{i})}{f_{o}(x_{i})}.
\end{equation}
This is valid assuming there are no bins where $f_{o}(x_{i}) = 0$.

To model the true \aclp{PDF} in $x$ as closely as possible, the histogram must
have a fine enough binning that all structures are resolved.
Specifically, as in the determination of the \ac{PID} efficiency in
\cref{chap:prod:effs:pid}, the binning must be fine enough such that difference
between the true \acp{PDF} of the two distribution within any given bin are
small.
This must be balanced with the limited statistical precision available in each
bin: too fine a binning will result in the original distribution being weighted
to match the statistical fluctuations in the target, rather than the physical
features.
Limited sample sizes become particularly problematic for higher-dimensional
weighting, when even 10 equally spaced bins per dimension in a
three-dimensional binning requires $1,000$ bins.
Given physical distributions such as momentum and pseudorapidity, which have
long tails, it can be difficult to invent a binning that avoids sparsely
populated or empty bins whilst still accounting for differences in the
distributions.

To overcome the limitations of histogram-based weighting, this analysis defers
the computation of the per-event weights $w_{i}$ to a decision tree with
gradient boosting~\cite{Rogozhnikov:2016bdp}.
The classifier is trained with the loss function
\begin{equation}
  L = \sum_{l \in \text{Leaves}} \frac{%
    {(w_{l,o} - w_{l,t})}^{2}
  }{%
    w_{l,o} + w_{l,t}
  },
\end{equation}
where $w_{l,t(o)}$ is the sum of target (original) weights in the $l$th leaf
node of the regression tree.
For the initial iteration, and an unweighted set of training events, this is
equal to the number of target (original) events in the leaf node.
This metric has the tree split the samples into regions where the differences
between the sample sizes is maximal, such that the classifier focuses on
weighting the entries in those regions.
Predictions $p_{l}$ within a leaf are computed as
\begin{equation}
  p_{l} = \log{\frac{w_{l,t}}{w_{l,o}}}.
\end{equation}
At the end of the $i$th iteration, each event from the `original' sample is
weighted by $w_{i} = w_{i - 1}e^{p_{l}}$, where $l$ is the leaf node the event
falls in.
The target distribution is assigned unit weights $w_{i} = w_{0}$.
This weighting has the same effect as the weighting in the
\adaboost~\cite{Freund1997119} algorithm, increasing the importance of events
in the original distribution that are in regions with a large original/target
difference.

The actual weighting of events is identical to that in the histogram weighting:
it is the ratio of target to original events in some region.
The use of gradient boosting allows for a more intelligent way of finding the
`bins' in which the weights are computed, and iteratively improves the weights
based on that method.

\section{Evaluation}
\label{chap:cpv:kinematic_weighting:evaluation}

The decision tree with gradient boosting is trained with the \ppipi\ data as
the `original' sample and the \pKK\ data as the `target'.
The weighting procedure is performed separately for each data sub-sample in
year and magnet polarity.
As it is expected that the \PLambdab\ and muon kinematics are correlated with
that of the \PLambdac, the \PLambdac\ transverse momentum \pT\ and
pseudorapidity \Eta\ are included as inputs to the \ac{BDT}.
Also included are the proton \pT\ and \Eta, as these distributions are seen to
disagree after weighting when only the \PLambdac\ kinematics are used.
To avoid biases due to fluctuations in the data, two classifiers $A$ and $B$
are trained, and the \pKK\ and \ppipi\ data are each randomly split into two
sub-samples 1 and 2: classifier $A$ is trained using sub-sample 1, and the
weights for sub-sample 2 are computed using $A$; likewise, classifier $B$ is
trained using sub-sample 2, and the weights for sub-sample 1 are computed using
$B$.
Sub-samples 1 and 2 are then combined for the remainder of the analysis.
The input training data are weighted by signal sWeights, as computed from the
result of the mass fits described in \cref{chap:cpv:prelim_fits}.
Each classifier is boosted in 300 iterations, the maximum number of leaf nodes
allowed in the regression tree is four, and the criteria for splitting includes
the requirement that any new nodes must contain at least 200 events.
The choice of these hyper-parameters will be discussed in
\cref{chap:cpv:kinematic_weighting:validation}, as well as the specific choice
of original and target samples.

\Cref{fig:cpv:kinematic_weighting:post:Lb,fig:cpv:kinematic_weighting:post:Lb_mu,fig:cpv:kinematic_weighting:post:Lc,fig:cpv:kinematic_weighting:post:Lc_p}
show the \PLambdab, muon, \PLambdac, and proton kinematics after weighting with
the product of signal sWeights and the kinematic weights.
\Cref{fig:cpv:kinematic_weighting:post:pKK_h1h2,fig:cpv:kinematic_weighting:post:ppipi_h1h2}
show the $\Phm\Php$ kinematics, \emph{within} the modes, after the same
weighting.
There is a considerable improvement in the agreement between the \pKK\ and
\ppipi\ data in the \PLambdab\ and proton kinematics.
The good agreement in the muon kinematics between the datasets and the
$\Phm\Phm$ kinematics within the datasets does not change.
It is noted that the \PLambdac\ kinematic agreement also improves, although
this does not affect the measurement of \dACP\ as there is no associated
asymmetry.

\section{Validation}
\label{chap:cpv:kinematic_weighting:validation}

The purpose of the kinematic weighting is to make the particle kinematics the
same between the \pKK\ and \ppipi\ modes.
\Cref{fig:cpv:kinematic_weighting:post:Lb,fig:cpv:kinematic_weighting:post:Lb_mu,fig:cpv:kinematic_weighting:post:Lc,fig:cpv:kinematic_weighting:post:Lc_p}
show good agreement `by eye', but a quantitative assessment is needed.
What affects the measurement of \dACP\ is not so much the absolute level of
disagreement between the two histograms, for example, but the disagreement in a
particular region combined with both the size of the respective asymmetries
involved and the density of the data in that region.
The effect of the remaining differences on \dACP\ is discussed in the context
of systematic uncertainties in \cref{chap:cpv:syst}.

To provide some quantitative estimate of the agreement, a \ac{BDT} is employed.
If the two samples, the target weighted with signal sWeights and the original
weighted with the product of signal sWeights and kinematic weights, are truly
identical, then a \ac{BDT} designed to \emph{discriminate} between them should
perform no better than random guessing.
The performance of a \ac{BDT} trained for binary classification can be
evaluated by computing the area under the \ac{ROC} curve, or just \ac{AUC}.
The \ac{ROC} curve compares the \ac{FPR} of the classifier with the \ac{TPR} as
a function of the classifier output probability.
The \ac{TPR} is defined as the fraction of true signal events that are
correctly classified as such, whilst the \ac{FPR} is the fraction of background
events that are classified as signal.
Plotting the \ac{FPR} increasing along the $x$-axis and the \ac{TPR} increasing
along the $y$-axis, the \ac{ROC} curve for an optimal classifier passes through
the top-left corner of the plot, where a large fraction of the signal is
accepted and a correspondingly large background fraction is rejected.
A classifier that cannot distinguish between signal and background any better
than random guessing will have a \ac{ROC} curve of the form $x = y$.
In these two extreme cases, the \ac{AUC} is 1 and 0.5, respectively.

A \ac{BDT}, with gradient boosting, is trained to discriminate between the
weighted \pKK\ and \ppipi\ data, using three-quarters of the available 2012
magnet down data as input.
The \PLambdab, muon, and proton \ptot, \pT, \Eta, and azimuthal angle $\phi$
are used as features.
The \PLambdac\ kinematics are not included as there is no asymmetry associated
to any residual differences there might be.
The maximum number of leaf nodes for any one regression tree is 11, the number
of boosting iterations performed is 400, and the minimum number of samples
allowed in a leaf node is 200.
The performance of the \ac{BDT} is evaluated using the remaining quarter of the
dataset, and the resulting \ac{ROC} curve is shown in
\cref{fig:cpv:kinematic_weighting:post:roc}.
For comparison, it is shown along with a curve obtained when the same
classifier is trained using data with no kinematic weighting, as well as a
curve when a rudimentary, two-dimensional, $10\times10$ histogram weighting in
\PLambdac\ \pT\ and \Eta\ is used.
It is seen that the inclusion of the kinematic weights significantly reduces
the \ac{AUC}, from 0.61 with no kinematic weights to 0.52 for the \ac{BDT}
weighting.
This shows that the \ac{BDT} weighting does increase the similarity between the
kinematic distributions across the modes, and that it can be significantly more
powerful than a two-dimensional histogram weighting.

It is the \ac{AUC} metric evaluated on the training sample that was maximised
when choosing the hyper-parameters to use for the weighting.
A grid search was performed where the following hyper-parameter values were
tested in all combinations: 100, 200, 300, and 400 boosting iterations; a
minimum of 50, 100, 200, 300, 500, and 1000 events required to create a new
node; and a maximum number of allowed leaf nodes per regression tree of 2, 3,
4, 5, 6, 7, and 8.
The hyper-parameters used for the weighting (300 iterations, a minimum of 200
events per node, and a maximum of 4 leaf nodes per tree) were those for which
the \ac{AUC} was smallest.

\section{Weight statistics}
\label{chap:cpv:kinematic_weighting:stats}

Weighting can increase the statistical contribution of individual entries
within a dataset, but it cannot increase the overall statistical power.
The number of entries $N'$ in a weighted dataset can be computed as the sum of
the per-entry weights $w_{i}$, and the variance on this quantity is given as
the sum of the squares of the weights
\begin{equation}
  N' = \sum_{i}^{N} w_{i},\quad (\unc{N'})^{2} = \sum_{i}^{N} w_{i}^{2}
\end{equation}
For certain values of $w_{i}$, it can be that $\unc{N'} < \unc{N}$.
To prevent this, the number of `effective' entries in the weighted dataset is
computed, under the relation that the relative variance on the effective
entries is equal to the relative variance on the weights
\begin{equation}
  \frac{\neff}{\unc{\neff}} =
    \frac{\sum_{i}^{N} w_{i}}{\sqrt{\sum_{i}^{N} w_{i}^{2}}},
\end{equation}
where \neff\ is assumed to be Poisson-distributed, and so $(\unc{\neff})^{2} =
\neff$, giving
\begin{equation}
  \neff = \frac{%
    {\left(\sum_{i}^{N}{w_{i}}\right)}^{2}
  }{%
    \sum_{i}^{N}{w_{i}^{2}},
  }.
  \label{eqn:cpv:kinematic_weighting:neff}
\end{equation}
This relation can be enforced by redefining the weights $w_{i}$ by a factor $W
= \sum_{i} w_{i}/\sum_{i} w_{i}^{2}$.
For unit weights, $\neff = N$ and $\unc{\neff} = \sqrt{N}$.
Otherwise, \neff\ is the size of the hypothetical dataset that has the same
statistical power as the weighted dataset.
For this analysis, it provides a handle on how well the two data samples agree
in the weighting variables before the weighting, as, in general, a higher level
of disagreement requires a larger fraction of candidates to be `thrown away' by
the weighting, reducing the statistical power.

\Cref{tab:cpv:kinematic_weighting:validation:stats} gives several statistics
related to the weighting procedure for the \ppipi\ data.
For all data sub-samples, the effective number of candidates is no less than
\SI{80}{\percent} the number of candidates entering the weighting procedure.
As there are around five times more \ppipi\ candidates than \pKK, the
statistical uncertainty of the \dACP\ measurement will still be dominated by
the \pKK\ sample size, even with an effective \SI{20}{\percent} reduction in
the \ppipi\ sample size.
It is this fact that motivates the choice of the \ppipi\ mode as the source of
the `original' distributions in the weighting and the \pKK\ mode as the
`target'.

\begin{sidewaystable}
  \centering
  \caption{%
    Statistics computed on the weighted \ppipi\ data for all data sub-samples
    used in the analysis.
    The quantities are defined in \cref{chap:cpv:kinematic_weighting:stats}.
  }
  \label{tab:cpv:kinematic_weighting:validation:stats}
  \input{tables/cpv/kinematic_weighting/weight_statistics-MVA.tex}
\end{sidewaystable}

\clearpage

\begin{figure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lb_P}
    \label{fig:cpv:kinematic_weighting:pre:Lb:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lb_PT}
    \label{fig:cpv:kinematic_weighting:pre:Lb:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lb_ETA}
    \label{fig:cpv:kinematic_weighting:pre:Lb:ETA}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lb_PHI}
    \label{fig:cpv:kinematic_weighting:pre:Lb:PHI}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, angle
    $\phi$, and pseudorapidity of the \PLambdab, weighted by signal sWeights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:pre:Lb}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lb_mu_P}
    \label{fig:cpv:kinematic_weighting:pre:Lb_mu:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lb_mu_PT}
    \label{fig:cpv:kinematic_weighting:pre:Lb_mu:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lb_mu_ETA}
    \label{fig:cpv:kinematic_weighting:pre:Lb_mu:ETA}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lb_mu_PHI}
    \label{fig:cpv:kinematic_weighting:pre:Lb_mu:PHI}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, angle
    $\phi$, and pseudorapidity of the muon from the \PLambdab, weighted by
    signal sWeights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:pre:Lb_mu}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lc_P}
    \label{fig:cpv:kinematic_weighting:pre:Lc:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lc_PT}
    \label{fig:cpv:kinematic_weighting:pre:Lc:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lc_ETA}
    \label{fig:cpv:kinematic_weighting:pre:Lc:ETA}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lc_PHI}
    \label{fig:cpv:kinematic_weighting:pre:Lc:PHI}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, angle
    $\phi$, and pseudorapidity of the \PLambdac, weighted by signal sWeights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:pre:Lc}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lc_p_P}
    \label{fig:cpv:kinematic_weighting:pre:Lc_p:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lc_p_PT}
    \label{fig:cpv:kinematic_weighting:pre:Lc_p:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lc_p_ETA}
    \label{fig:cpv:kinematic_weighting:pre:Lc_p:ETA}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_Lc_p_PHI}
    \label{fig:cpv:kinematic_weighting:pre:Lc_p:PHI}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, angle
    $\phi$, and pseudorapidity of the proton from the \PLambdac, weighted by
    signal sWeights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:pre:Lc_p}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.5\textwidth}
    \centering
    \includegraphics[width=0.8\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_P_LcTopKK}
    \label{fig:cpv:kinematic_weighting:pre:pKK_h1h2:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.5\textwidth}
    \centering
    \includegraphics[width=0.8\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_PT_LcTopKK}
    \label{fig:cpv:kinematic_weighting:pre:pKK_h1h2:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{\textwidth}
    \centering
    \includegraphics[width=0.4\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_ETA_LcTopKK}
    \label{fig:cpv:kinematic_weighting:pre:pKK_h1h2:ETA}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, and
    pseudorapidity of the \PKminus\ and \PKplus\ \PLambdac\ children in the
    \pKK\ data, weighted by signal sWeights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:pre:pKK_h1h2}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.5\textwidth}
    \centering
    \includegraphics[width=0.8\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_P_LcToppipi}
    \label{fig:cpv:kinematic_weighting:pre:ppipi_h1h2:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.5\textwidth}
    \centering
    \includegraphics[width=0.8\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_PT_LcToppipi}
    \label{fig:cpv:kinematic_weighting:pre:ppipi_h1h2:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{\textwidth}
    \centering
    \includegraphics[width=0.4\textwidth]{cpv/kinematic_weighting/preweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_ETA_LcToppipi}
    \label{fig:cpv:kinematic_weighting:pre:ppipi_h1h2:ETA}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, and
    pseudorapidity of the \Ppiminus\ and \Ppiplus\ \PLambdac\ children in the
    \ppipi\ data, weighted by signal sWeights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:pre:ppipi_h1h2}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lb_P-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lb:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lb_PT-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lb:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lb_ETA-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lb:ETA}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lb_PHI-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lb:PHI}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, angle
    $\phi$, and pseudorapidity of the \PLambdab, weighted by the product of
    signal sWeights and kinematic weights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:post:Lb}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lb_mu_P-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lb_mu:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lb_mu_PT-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lb_mu:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lb_mu_ETA-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lb_mu:ETA}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lb_mu_PHI-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lb_mu:PHI}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, angle
    $\phi$, and pseudorapidity of the muon from the \PLambdab, weighted by the
    product of signal sWeights and kinematic weights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:post:Lb_mu}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lc_P-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lc:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lc_PT-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lc:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lc_ETA-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lc:ETA}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lc_PHI-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lc:PHI}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, angle
    $\phi$, and pseudorapidity of the \PLambdac, weighted by the product of
    signal sWeights and kinematic weights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:post:Lc}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lc_p_P-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lc_p:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lc_p_PT-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lc_p:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lc_p_ETA-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lc_p:ETA}
  \end{subfigure}
  \begin{subfigure}[b]{0.4\textwidth}
    \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_Lc_p_PHI-weighted}
    \label{fig:cpv:kinematic_weighting:post:Lc_p:PHI}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, angle
    $\phi$, and pseudorapidity of the proton from the \PLambdac, weighted by
    the product of signal sWeights and kinematic weights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:post:Lc_p}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.5\textwidth}
    \centering
    \includegraphics[width=0.8\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_P_LcTopKK-weighted}
    \label{fig:cpv:kinematic_weighting:post:pKK_h1h2:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.5\textwidth}
    \centering
    \includegraphics[width=0.8\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_PT_LcTopKK-weighted}
    \label{fig:cpv:kinematic_weighting:post:pKK_h1h2:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{\textwidth}
    \centering
    \includegraphics[width=0.4\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_ETA_LcTopKK-weighted}
    \label{fig:cpv:kinematic_weighting:post:pKK_h1h2:ETA}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, and
    pseudorapidity of the \PKminus\ and \PKplus\ \PLambdac\ children in the
    \pKK\ data, weighted by the product of signal sWeights and kinematic
    weights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:post:pKK_h1h2}
\end{figure}

\begin{figure}
  \begin{subfigure}[b]{0.5\textwidth}
    \centering
    \includegraphics[width=0.8\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_P_LcToppipi-weighted}
    \label{fig:cpv:kinematic_weighting:post:ppipi_h1h2:P}
  \end{subfigure}
  \begin{subfigure}[b]{0.5\textwidth}
    \centering
    \includegraphics[width=0.8\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_PT_LcToppipi-weighted}
    \label{fig:cpv:kinematic_weighting:post:ppipi_h1h2:PT}
  \end{subfigure}\\
  \begin{subfigure}[b]{\textwidth}
    \centering
    \includegraphics[width=0.4\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_h1_h2_ETA_LcToppipi-weighted}
    \label{fig:cpv:kinematic_weighting:post:ppipi_h1h2:ETA}
  \end{subfigure}
  \caption{%
    Clockwise from the top left: total momentum, transverse momentum, and
    pseudorapidity of the \Ppiminus\ and \Ppiplus\ \PLambdac\ children in the
    \ppipi\ data, weighted by the product of signal sWeights and kinematic
    weights.
    The 2012 magnet down data are shown.
  }
  \label{fig:cpv:kinematic_weighting:post:ppipi_h1h2}
\end{figure}

\begin{figure}
  \includegraphics[width=\textwidth]{cpv/kinematic_weighting/postweighting_kinematics/LcToppipi_2012_MagDown_roc_curves}
  \caption{%
    ROC curves for different kinematic weighting techniques.
    The ``no weights'' data has no \emph{kinematic} weights applied, only
    signal sWeights.
    The ``2D binned'' and ``\ac{BDT}'' data uses the product of the respective
    kinematic weights and the signal sWeights for the \ppipi\ data, and uses
    signal sWeights for the \pKK\ data.
    The area under each \ac{ROC} curve, the \acs{AUC}, is given in the legend.
  }
  \label{fig:cpv:kinematic_weighting:post:roc}
\end{figure}


\subsection{Endogenous Transformations}
\label{sec:slco:endogenous}
For each of the semantic gaps and platform gaps described in Section~\ref{sec:slco:language-gaps}, we implemented an endogenous model transformation that bridges this gap.
To keep these transformations simple, they can only be applied to models adhering to certain conditions.
In addition to the transformations that bridge the gaps, we implemented transformations that refine models to ensure that they adhere to the aforementioned conditions.

\subsubsection{Synchronized Communication over Asynchronous Channels}
\label{subsubsec:slco:sync2async}
To bridge the semantic gap between languages offering synchronous communication and languages that do not, we implemented two transformations.
Both transformations take an \SLCO model and a synchronous channel as input, and produce a model in which this channel is replaced by an asynchronous, lossless channel and the objects that communicate over this channel are adapted such that they communicate asynchronously.

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/s2a_simple}
  \caption{State machines before and after applying the simple version of \Transformation{as}}
  \label{fig:slco:trans:assimple}
\end{figure}

The first transformation is simple, but can only be applied to models that do not contain states with multiple outgoing transitions if one of these transitions starts with a statement that sends a signal over the synchronous channel.
The transformation ensures that the behavior of the model is still as desired by adding acknowledgment signals for synchronization.
Whenever a signal is sent, the receiving party sends an acknowledgement indicating that the signal has been received.
The sending party waits until it receives this acknowledgement.
In this way, synchronization is achieved.
On the left of Figure~\ref{fig:slco:trans:assimple}, two partial state machines are shown that send and receive a signal~\SLCOSignalName{S}.
Initially, ports~\SLCOPort{In} and~\SLCOPort{Out} are connected by a synchronous channel.
After transformation, acknowledgements are added, as shown on the right of the figure, and the synchronous channel is replaced with an asynchronous, lossless channel.
This transformation is described in more detail in Appendix~\ref{ap:transformations-slco}, and its correctness is discussed in Chapter~\ref{chap:reusable-correct-transformations} and Appendix~\ref{ap:proof}.

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/s2a_complex}
  \caption{State machines before and after applying the general version of \Transformation{as}}
  \label{fig:slco:trans:ascomplex}
\end{figure}

The second transformation can be applied to any \SLCO model, but is more complex.
The partial state machine on the left of Figure~\ref{fig:slco:trans:ascomplex} shows an example of a situation where the transformation described above cannot be applied.
State~\SLCOState{S0} has multiple outgoing transitions, and one of these transitions starts with a statement that sends a signal.
In such situations, a more complex protocol has to be applied to ensure that the behavior of the model before and after transformation is the same, apart from the communication over the channel that is replaced.
Also in this example, ports~\SLCOPort{In} and~\SLCOPort{Out} are initially connected by a synchronous channel, which is replaced by an asynchronous, lossless channel.
In Figure~\ref{fig:slco:trans:ascomplex}, the second partial state machine from the left shows how the sending state machine is affected by the transformation, and the third partial state machine from the left shows how the receiving state machine is affected.
Additionally, two other state machines are added to the model, which are shown on the right of Figure~\ref{fig:slco:trans:ascomplex}.
State machine~\SLCOStateMachine{S\_Reader} is added to the object that sends signals, and state machine~\SLCOStateMachine{R\_Reader} is added to the object that receives signals.
Together with these state machines, the sender and receiver implement a protocol that ensures that states~\SLCOState{S1} and~\SLCOState{R1} are only reached if the communication between the sender and receiver was successful.
Furthermore, as long as the sender and receiver are unable to communicate, all enabled outgoing transitions of states~\SLCOState{S0} and~\SLCOState{R0} can be made.
Appendix~\ref{ap:transformations-slco} provides a more detailed description of this transformation.

The protocol that is employed by this transformation is not straightforward.
Therefore, we used the state-space generator for \SLCO described in Chapter~\ref{chap:prototype-semantics} for feedback during its development.
Informally, the protocol consists of the following steps.
Initially, the value of variable~\SLCOVariable{var\_Out} is equal to~0, and the value of variable~\SLCOVariable{var\_In} is equal to~3.
First, the sending object sends a signal~\SLCOSignal{S}{1} to indicate that it wants to communicate.
It can proceed to state~\SLCOState{S2} if all previous signals have been acknowledged by the receiving object, which is the case if variable~\SLCOVariable{var\_Out} is equal to~0.
The signal sent by the sending object is received by state machine~\SLCOStateMachine{R\_Reader}, and the value of its argument is stored in~\SLCOVariable{var\_In}.
Once the receiving object is informed of the intent of the sending object by means of the execution of statement~$\SLCOVariable{var\_In}==1$, it sends a signal~\SLCOSignal{S}{2} to indicate that it is ready to communicate.
Once this signal has been received and the value of its argument has been stored in variable~\SLCOVariable{var\_Out} by state machine~\SLCOStateMachine{S\_Reader}, the sending object may choose to complete the communication by sending signal~\SLCOSignal{S}{3}.
Alternatively, it may choose to cancel the communication by sending signal~\SLCOSignal{S}{4}.
Upon receiving one of these signals, the receiving object can take the transition to state~\SLCOState{R1} if the communication has been completed successfully, or take the transition to state~\SLCOState{R0} if it has been canceled.
Either way, it acknowledges the reception of the signal of the sending object by sending a signal~\SLCOSignal{S}{0}.
The state machines~\SLCOStateMachine{S\_Reader} and~\SLCOStateMachine{R\_Reader} ensure that the statements that send signals cannot be blocked, by emptying the buffers associated to the channels continuously.
It is possible that the sending object sends signal~\SLCOSignal{S}{4} after sending signal~\SLCOSignal{S}{1}, while the receiving object remains in state~\SLCOState{R0}.
The self-loop on state~\SLCOState{R0} ensures that an acknowledgement is also sent in this situation.

In the remainder, the simple version of this transformation is referred to as~\TSim, and the general version is referred to as~\TGen.
In cases where it is not relevant which of these two transformations is applied, the abbreviation~\Transformation{as} is used.

\subsubsection{Lossless Communication over a Lossy Channel}
\label{subsubsec:slco:ll}

Transformation~\Transformation{ll} implements lossless communication over a lossy channel by introducing auxiliary objects that implement a concurrent version of the Alternating Bit Protocol~(ABP)~\cite{Bartlett1969} known as the Concurrent Alternating Bit Protocol (CABP)~\cite{Baeten2002}.
This transformation is only applicable to unidirectional channels that are used to communicate signals named \SLCOSignalName{Signal} and whose only argument is a string.

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/Communication_Lossless2Lossy}
  \caption{Two objects communicating over an asynchronous, lossless channel}
  \label{fig:slco:ll-comm-before}
\end{figure}

Figure~\ref{fig:slco:ll-comm-before} shows a model consisting of two objects~(\SLCOObject{a} and~\SLCOObject{b}) that communicate over an asynchronous, lossless channel~(\SLCOChannel{C}).
After transformation, channel~\SLCOChannel{C} is replaced by the channels~\SLCOChannel{c1} to~\SLCOChannel{c6} and four objects that implement the CABP, as shown in Figure~\ref{fig:slco:ll-comm-after}.
Object~\SLCOObject{a} is connected to an object named~\SLCOObject{sender}, which communicates over an asynchronous, lossy channel~\SLCOChannel{c2} with an object named~\SLCOObject{receiver}.
The object named~\SLCOObject{receiver} is in turn connected to the object~\SLCOObject{b}.
After transformation, objects~\SLCOObject{a} and~\SLCOObject{b} communicate with each other via the aforementioned objects, instead of directly.
Objects~\SLCOObject{a} and~\SLCOObject{b} are connected to these objects by synchronous channels.
After receiving a signal from object~\SLCOObject{a}, object~\SLCOObject{sender} repeatedly sends this signal over channel~\SLCOChannel{c2} until it receives an acknowledgement from object~\SLCOObject{ar}, to which it is connected via the synchronous channel~\SLCOChannel{c6}.
After receiving a signal over channel~\SLCOChannel{c2}, object~\SLCOObject{receiver} forwards this signal to object~\SLCOObject{b} and instructs object~\SLCOObject{as} to continuously acknowledge the reception of this signal.
Object~\SLCOObject{as} does this by continuously sending signals over the asynchronous, lossy channel~\SLCOChannel{c5}.
The acknowledgement sent by object~\SLCOObject{as} contains a two-valued argument that is used by object~\SLCOObject{ar} to assess whether a particular acknowledgement signal was already received before.
Once object~\SLCOObject{ar} has received a new acknowledgement, it notifies object~\SLCOObject{sender}.
After receiving such a notification, object~\SLCOObject{sender} is able to receive a new signal from object~\SLCOObject{a} and transmit this signal over channel~\SLCOChannel{c2}.

In Figure~\ref{fig:slco:cabp}, the four state machines are shown that specify the behavior of the four objects that implement the CABP.
To show which state machine is part of which class, the names of the states have been chosen such that they reflect the names of the classes and objects.

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/Communication_Lossless2Lossy_ll}
  \caption{Two objects that communicate via the CABP}
  \label{fig:slco:ll-comm-after}
\end{figure}

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/ABP}
  \caption{Four state machines implementing the CABP}
  \label{fig:slco:cabp}
\end{figure}

\subsubsection{Adding Delays to Transitions}
Transformation~\Transformation{time} takes a model and a set of transitions as input, and adds delay statements to these transitions.
This transformations is used to control the frequency of the acknowledgments sent by the objects implementing the CABP.
Because it reduces the number of signals that are sent, it also reduces the number of collisions between messages sent via infrared on the Lego Mindstorms platform.

%%%

\subsubsection{Replacing Strings by Integers}
Transformation~\Transformation{int} replaces each string constant in an \SLCO model with a unique integer constant and changes the type of all string variables and arguments to integer.
This transformation deals with the fact that \NQC does not offer strings.

\subsubsection{Making the Sender of a Signal Explicit}
When multiple objects broadcast signals with the same name and number of arguments over the same medium, the receiving object cannot determine the origin of such a signal.
This situation arises when multiple \RCX controllers communicate with each other, because they communicate by broadcasting messages via infrared.
To enable a receiving controller to determine the origin of each signal it receives, transformation~\Transformation{ic} can be applied to a model.
This transformation takes a model and a set of channels as input, and adds an index to all signal names that identifies the channel over which these signals are sent.

\subsubsection{Reducing the Number of Objects}
\label{subsubsec:slco:merge}
Transformation~\Transformation{merge} merges multiple objects into one object.
Given a model and a set of objects, it creates a new object that contains all the variables, ports, and state machines contained by the objects provided as input.
By reducing the number of objects in a model, it bridges the corresponding gap between \SLCO and \NQC.
If any of the objects that are being merged communicate over synchronous channels, then this form of communication is replaced by communication using shared variables.
Transformation~\Transformation{merge} is only applicable to objects that satisfy the following condition: each pair of state machines that are part of two communicating objects must communicate over a unique unidirectional, synchronous channel.

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/MergeObjects}
  \caption{Two state machines before and after merging objects}
  \label{fig:slco:merge}
\end{figure}

Figure~\ref{fig:slco:merge} shows how communication over a synchronous channel is replaced by communication using shared variables.
The two partial state machines on the left of the figure are part of two separate objects and communicate with each other by sending and receiving signals over a synchronous channel that connects ports~\SLCOPort{In} and~\SLCOPort{Out}.
After merging these two objects, the state machines are adapted as shown on the right of the figure and communicate using the shared variables~\SLCOVariable{C\_name} and~\SLCOVariable{C\_abl}.
Variable~\SLCOVariable{C\_name} is used to store and retrieve the names of the signals that are being exchanged, and variable~\SLCOVariable{C\_abl} encodes the states of the employed communication protocol.
The sending state machine sets the value of~\SLCOVariable{C\_abl} to~1 to indicate that it wants to communicate.
The receiving state machine indicates that it is also able to communicate by setting the value of~\SLCOVariable{C\_abl} to~2.
If both state machines are able to communicate, the sending state machine can complete the communication process by setting~\SLCOVariable{C\_abl} to 3.
It may also choose to cancel the communication by setting~\SLCOVariable{C\_abl} to~0.
The receiving state machine acknowledges successful completion of the communication process by setting~\SLCOVariable{C\_abl} to~0.

\subsubsection{Making all Signal Names Equal}
\label{subsubsec:slco:endogenous:arg}
To keep the transformation that adds the CABP as simple as possible, our implementation of the CABP takes signals with a fixed name as input, transfers them over a lossy channel, and delivers them at the receiving end.
Before this instance of the CABP can be used to substitute an asynchronous, lossless, unidirectional channel, the signal names that are sent over this channel have to be changed into this fixed name.
Transformation~\Transformation{arg} adapts signals such that their name is changed into this fixed name and the name of the original signal is sent as an argument of the resulting signal.
For example, the statement~\SLCOSendSignal{Block}{}{O} is replaced by the statement~\SLCOSendSignal{Signal}{``\it{Block}"}{O}.

\subsubsection{Replacing a Bidirectional Channel by two Unidirectional Channels}
Our implementation of the CABP can only substitute asynchronous, lossless, unidirectional channels.
In some cases, therefore, a transformation is needed that replaces communication over a bidirectional channel by communication over two unidirectional channels before transformation~\Transformation{ll} can be applied.
Transformation~\Transformation{uni} performs this task.

\subsubsection{Exclusive Channels for Pairs of State Machines}
\label{subsubsec:slco:endogenous:ex}
Transformation~\Transformation{merge} cannot merge objects if multiple state machines that are part of an object communicate via the same port.
To modify models that do not adhere to this condition, we implemented a transformation~\Transformation{ex} that replaces a channel between a pair of objects with a number of identical channels.
For each pair of communicating state machines that are part of the two objects, a channel is introduced.

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/ExclusiveChannels_Communication}
  \caption{Communication before and after adding exclusive channels}
  \label{fig:slco:excomm}
\end{figure}

On the left of Figure~\ref{fig:slco:excomm}, two objects are shown that communicate over a single channel.
Both objects contain two state machines (which are not shown in this type of diagram) that communicate over this channel.
After applying transformation~\Transformation{ex}, the channel is replaced by four channels, as shown on the right of Figure~\ref{fig:slco:excomm}.

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/ExclusiveChannels_Behavior}
  \caption{State machines before and after adding exclusive channels}
  \label{fig:slco:exsm}
\end{figure}

As a part of the process of replacing a channel by multiple channels, transformation~\Transformation{ex} modifies the state machines that communicate over these channels.
Before transformation, both state machines that are part of object~\SLCOObject{a} send signals via port~\SLCOPort{Out}, and both state machines that are part of object~\SLCOObject{b} receive signals via port~\SLCOPort{In}.
After transformation, one of the state machine of object~\SLCOObject{a} sends signals via ports~\SLCOPort{Out1} and~\SLCOPort{Out3}, and the other uses ports~\SLCOPort{Out2} and~\SLCOPort{Out4}.
The receiving state machines are modified in a similar fashion.
Figure~\ref{fig:slco:exsm} shows parts of one of the state machine of object~\SLCOObject{a} and parts of one of the state machines of object~\SLCOObject{b} before and after transformation.
The names of the states of these partial state machines correspond to the names of the classes they belong to.
The situation before transformation is illustrated on the left of the figure, and the situation after transformation is shown on the right.
%Before transformation, as shown on the left of the figure, state~\SLCOState{A0} has only one outgoing transition.
%When making this transition from state~\SLCOState{A0} to state~\SLCOState{A1}, a signal is sent via port~\SLCOPort{Out}.
%State~\SLCOState{B0} also has only one outgoing transition before transformation.
%When a signal is received via port~\SLCOPort{In}, the transition to state~\SLCOState{B1} is made.

\subsubsection{Reducing the Number of Channels}
When two objects are connected by more than one channel, these channels can be merged into one if they have the same type and directionality, and support the same argument types.
Therefore, we implemented a transformation~\Transformation{mc} that merges multiple channels between a pair of objects into one channel.
Merging channels is a way of optimizing models because it can be used to reduce the number of instances of the CABP that need to be added.

\subsubsection{Cloning Classes}
Many of the transformations described above use two auxiliary transformations.
One of these transformations takes a model and a channel as input, and clones the classes of the objects that communicate over this channel.
After applying this transformation, the objects that communicate over the channel are instances of the new cloned classes, and all remaining instances of the original classes remain unchanged.
This transformation ensures that all transformations that alter objects that communicate over a certain channel only affect these particular objects.

\begin{figure}[hbt]
  \centering
  \includegraphics[scale=0.45]{slco/figs/transformations/CloneClasses}
  \caption{A model before and after cloning classes}
  \label{fig:slco:clone}
\end{figure}

Figure~\ref{fig:slco:clone} shows the communication diagram of a model before and after applying this transformation.
After transformation, the classes of the objects communicating over channel~\SLCOChannel{c1} are cloned.
In the resulting model, object~\SLCOObject{a1} is an instance of class~\SLCOClass{A\_c} and object~\SLCOObject{b} an instance of class~\SLCOClass{B\_c}.

\subsubsection{Removing Unused Classes}
The second auxiliary transformation used by the transformations described above removes all uninstantiated classes from a model.
The model depicted on the right of Figure~\ref{fig:slco:clone}, for example, no longer contains an instance of class~\SLCOClass{B}, which means that this class can be removed without affecting the system specified by the model.

%These two transformations are not shown in Figure~\ref{fig:TransformationSequences} to increase its readability.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\documentclass{article}
\usepackage[T1]{fontenc}

\usepackage{amssymb}
\usepackage{courier}
\usepackage{fancyhdr}
\usepackage{fancyvrb}
\usepackage[top=.75in, bottom=.75in, left=.75in,right=.75in]{geometry}
\usepackage{graphicx}
\usepackage{lastpage}
\usepackage{listings}
\lstset{basicstyle=\small\ttfamily}
\usepackage{mdframed}
\usepackage{parskip}
\usepackage{soul}
\usepackage{tabularx}
\usepackage{textcomp}
\usepackage{upquote}
\usepackage{xcolor}

% http://www.monperrus.net/martin/copy-pastable-ascii-characters-with-pdftex-pdflatex
\lstset{
upquote=true,
columns=fullflexible,
keepspaces=true,
literate={*}{{\char42}}1
         {-}{{\char45}}1
         {^}{{\char94}}1
}
\lstset{
  moredelim=**[is][\color{blue}\bf\small\ttfamily]{@}{@},
}

% http://tex.stackexchange.com/questions/40863/parskip-inserts-extra-space-after-floats-and-listings
\lstset{aboveskip=6pt plus 2pt minus 2pt, belowskip=-4pt plus 2pt minus 2pt}

\usepackage[colorlinks,urlcolor={blue}]{hyperref}
\usepackage[capitalise,nameinlink,noabbrev]{cleveref}
\crefname{section}{Question}{Questions}
\Crefname{section}{Question}{Questions}

\begin{document}

\fancyhead[C]{\hl{Select the right page in Gradescope or we will not grade the question!}}
\fancyhead[L]{}
\fancyhead[R]{}

\fancyfoot[L]{\color{gray} C4CS -- F'17}
\fancyfoot[R]{\color{gray} Revision 1.1}
\fancyfoot[C]{\color{gray} \thepage~/~\pageref*{LastPage}}
\pagestyle{fancyplain}

\title{\textbf{Homework 9\\Debugging}}
\author{\textbf{\color{red}{Due: Wednesday, November 15th, 11:59PM (Hard Deadline)}}}
\date{}
\maketitle

\section*{Submission Instructions}
Submit this assignment on \href{https://gradescope.com/courses/9999}{Gradescope}.
You may find the free online tool \href{https://www.pdfescape.com}{PDFescape}
helpful to edit and fill out this PDF.
You may also print, handwrite, and scan this assignment.

There may multiple answers for each question. If you are unsure,
state your assumptions and your reasoning for why you think your answer
makes sense.

\newpage
\section{\texttt{Git}ting started}

Please \texttt{clone} the following repository:

\begin{lstlisting}
@>@ git clone https://github.com/c4cs/debugging-basics.git
\end{lstlisting}

This repository contains 4 branches: \texttt{master}, \texttt{gdb-debug-1}, \texttt{gdb-debug-2}, and \texttt{valgrind-debug}. Each part of this homework will take place on a different branch.

\section{Finding primes}

The repository you have cloned is an attempt at a program to find prime
numbers. It will search from 3 up to a maximum number input by the user.

The program intends to follow the structure:
\begin{lstlisting}
  o prompt user for upper bound
  o for N=3..upper bound:
    - check if N is prime
      * if no prime n between 1..sqrt(N) divides N, then prime
    - save whether N is prime for future loops to use
    - if N is prime, print N
\end{lstlisting}

\subsection{Debugging with \texttt{gdb}}

\emph{You may find it helpful to consult the
  \href{https://c4cs.github.io/lectures/f17/week11}{gdb lecture notes}
  or this
  \href{https://ccrma.stanford.edu/~jos/stkintro/Useful_commands_gdb.html}
  {quick command reference}.
}

First, make sure you are on the \texttt{gdb-debug-1} branch:
\begin{lstlisting}
@>@ git branch
  master
* gdb-debug-1
\end{lstlisting}

Next, build and run the supplied program:
\begin{lstlisting}
@>@ make
@>@ ./prime
Find all prime numbers between 3 and ?
10
Segmentation fault (core dumped)
@>@ gdb -q ./prime
Reading symbols from ./prime...done.
(gdb) run
Starting program: /media/sf_prime/prime
Find all prime numbers between 3 and ?
10

Program received signal SIGSEGV, Segmentation fault.
0x000000000040068f in check_prime (k=3) at check.c:15
@15      if (is_prime[j] == 1)@
\end{lstlisting}

\textbf{Explain in what case(s) executing this line of code could cause a
  segmentation fault?}
\begin{quote}
  \color{violet}
  This question is asking only about this specific line of code, not all of
  the things that could possibly cause segmentation faults.

  This is an array access, which is a fancy way of dereferencing a pointer.
  Since we are in C, \texttt{is\_prime[j]} is the exact same as
  \texttt{*(is\_prime + j)}.

  This means that this line of code could cause a segmentation fault if the
  value \texttt{is\_prime + j} does not point to a valid memory address.
  %
  This is most likely to happen if \texttt{is\_prime} is not a valid pointer
  or \texttt{abs(j)} is an enormous value.

  \emph{Worth Noting: While a value of \texttt{j=-1} is very likely incorrect,
    it is unlikely to cause a segmentation fault. It will simply point to a
    different, nearby variable in the program's memory space. The fact that
    bugs like this do not cause crashes (at least not immediately) can make
    them hard to track down.}
\end{quote}

\textbf{What gdb commands could you run next to prove your hypothesis right or
  wrong?}
\begin{quote}
  \color{violet}
  Either \texttt{print is\_prime} or \texttt{ptype is\_prime} to learn the
  size of the array, then \texttt{print j} to learn whether \texttt{j} is
  valid.

  Asking gdb to \texttt{print is\_prime[j]} will directly show that the memory
  pointed to is inaccessible.
\end{quote}

\newpage
% Fun fact: This was a "real" bug, that is, when I was writing this assignment
% I made a mistake and used the debugger to track it down
Now checkout \texttt{gdb-debug-2}:
\begin{lstlisting}
@>@ git checkout gdb-debug-2
@>@ make
@>@ ./prime
Find all prime numbers between 3 and ?
10
3 is a prime
5 is a prime
7 is a prime
@9 is a prime@
\end{lstlisting}
\textbf{Copy your debugging session and add notes explaining your
  thought process as you track down why this program thinks 9 is a prime.}\\
\emph{\small Hint: It looks like things go well up until 9. A good place to
  start then may be to break in and observe how the code determines whether 9
  is a prime number.}

\begin{quote}
    \color{violet}
  \begin{lstlisting}
    $ gdb -q ./prime
    Reading symbols from ./prime...Reading symbols from [...] ...done.
    done.

    @Things go well up until checking if 9 is prime, so jump there@
    (gdb) break check_prime if k==9
    Breakpoint 1 at 0x100000e87: file check.c, line 13.
    (gdb) run
    Starting program: /private/tmp/debugging-basics/prime
    Find all prime numbers between 3 and ?
    10
    3 is a prime
    5 is a prime
    7 is a prime

    Breakpoint 1, check_prime (k=9) at check.c:13
    13    for (j=2; j*j <= k; j++) { @expect to run this loop for j=2 and j=3@

    @There's not a whole lot going on in this loop. As we move through it, the
    only variable that changes is j. (We can infer the values of things like
    is_prime[j] based on the path the code takes, though you could certainly
    print those values as well if you like)@
    (gdb) display j
    1: j = 0
    (gdb) step
    14      if (is_prime[j] == 1) @expect this to be true, as 2 is prime@
    1: j = 2
    (gdb) <enter> @repeats last command, in this case step@
    15        if (k % j == 0)  { @9 % 2 isn't 0@
    1: j = 2
    (gdb) <enter>
    19      j++; @okay, onto the next iteration of the loop@
    1: j = 2
    (gdb) <enter>
    13    for (j=2; j*j <= k; j++) { @starting off the loop for j=3@
    1: j = 3
    (gdb) <enter>
    23    is_prime[k] = 1; @wait, we just dropped out of the loop, and j is 4@
    1: j = 4
    (gdb)
    @Key thing to notice: The loop body never executed for j=3. Why? j was
    incremented twice, once at the end of the body of the for loop, and once
    by the declaration of the for loop. This double-increment is the bug.@
  \end{lstlisting}
\end{quote}

\vfill
\hrule
{\footnotesize
This homework is based off of a simplified and updated version of this gdb
tutorial:
\url{http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Debug.html}
If you would like some more practice, or simply a slightly different
explanation of the material, this may be a good source.
}

\newpage
\section{Valgrind}

Valgrind is a different kind of debugging tool. It is essentially a type of
virtual machine (like a simpler VirtualBox). Valgrind actually recompiles
every assembly instruction to allow it to intercept and monitor all of the
hardware calls made by the child process. While this is very powerful and
gives valgrind a lot of insight, it is also very slow, which can be
problematic for debugging large pieces of software.

Valgrind also can be challenging when libraries (such as the STL, or Boost) do
funny things with memory that result in a large number of false warnings. We
will look at valgrind in more depth during the second week on debugging
tools. For today, let's just explore the basic functionality and check out the
kind of things that valgrind can catch that gdb can't.

First, we'll need to install valgrind
\begin{lstlisting}
@>@ sudo apt-get install valgrind
\end{lstlisting}

Now, checkout the valgrind branch
\begin{lstlisting}
@>@ git checkout valgrind-debug
\end{lstlisting}

Notice (perhaps \texttt{gitk~-{}-all}) that the valgrind branch builds on the
master branch, with all the compiler warnings turned on. It has also
\ul{cherry-pick}ed the fix ``Stop searching for primes once sqrt(k) is
reached'', that is the same commit object that managed to end up on two
different histories.  This is one example of how git can be both very
powerful, and very confusing.

Finally, this branch adds a commit that consolidates they two source code
files into one and gets rid of all of the global variables in the process.
Unfortunately, this refactoring may also have inroduced a bug.

We run valgrind very similarly to gdb:
\begin{lstlisting}
@>@ make
@>@ valgrind ./prime
==11959== Memcheck, a memory error detector
==11959== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==11959== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==11959== Command: ./prime
==11959==
Find all prime numbers between 3 and ?
10
3 is a prime@
==11959== Conditional jump or move depends on uninitialised value(s)
==11959==    at 0x400683: check_prime (prime.c:32)
==11959==    by 0x400739: main (prime.c:52)@
==11959==
5 is a prime
7 is a prime
==11959==
==11959== HEAP SUMMARY:
==11959==     in use at exit: 0 bytes in 0 blocks
==11959==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==11959==
==11959== All heap blocks were freed -- no leaks are possible
==11959==
==11959== For counts of detected and suppressed errors, rerun with: -v
==11959== Use --track-origins=yes to see where uninitialised values come from
==11959== ERROR SUMMARY: 3 errors from 1 contexts (suppressed: 0 from 0)
\end{lstlisting}
{\small (The numbers in the left column are the process ID. They will be
  different for every person)}

\newpage
\textbf{Notice that ``3 is a prime'' printed before this warning. Why was this
  warning not emitted when running \texttt{check\_prime(3,~\dots)}?}
\begin{quote}
  \color{violet}
  Valgrind detects errors at run time. For \texttt{check\_prime(3,~\dots)},
  the for loop check \texttt{j*j~$<=$~k} (\texttt{2*2~$<=$~3}) fails and
  the body of the loop is never entered. This means \texttt{is\_prime[j]}
  (\texttt{is\_prime[2]}) never runs, which means valgrind does not detect
  the error.

  The key takeaway here is that because of how valgrind works, it can only
  catch an error when it actually happens.
\end{quote}

These tools really get powerful when you combine them. We can run valgrind in
a way that lets gdb connect to it, and allows us to debug/inspect whenever
valgrind detects a problem:
\begin{lstlisting}
@>@ valgrind --vgdb=yes --vgdb-error=0 ./prime
\end{lstlisting}
In another terminal, follow the directions that valgrind prints to connect
gdb. In this case, valgrind has already `run' the program for you and inserted
a breakpoint at the very beginning of the program, we just need to `continue'
it. The program will run until valgrind encounters an issue, at which point
valgrind will automatically break for you.
\begin{lstlisting}
@(gdb)@ continue

valgrind terminal:
==23589== Conditional jump or move depends on uninitialised value(s)
==23589==    at 0x400623: check_prime (prime.c:32)
==23589==    by 0x4006C4: main (prime.c:52)
==23589==
@==23589== (action on error) vgdb me ...  # this is where valgrind waits for gdb@

gdb terminal:
Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000000400623 in check_prime (k=5, is_prime=0xffefff910) at prime.c:32
@32      if (is_prime[j] == 1)   # this is the problematic line of code@
\end{lstlisting}

~

\textbf{What is the value of \texttt{j} at this point?}\\
\begin{quote}
  \color{violet}\tt
  (gdb) print j\\
  j = 2
\end{quote}

\textbf{What is the value of \texttt{is\_prime[j]} at the point?}\\
\begin{quote}
  \color{violet}\tt
  (gdb) print is\_prime[j]\\
  = -16777744 $\leftarrow$ This will be a garbage value and vary person to person
\end{quote}

\textbf{Use git to look at the most recent commit. What line of code was
  deleted that should not have been?}
\begin{quote}
    \color{violet}
  \begin{lstlisting}
$ git log -p

[... trim some output ...]

  int main() {
+       int is_prime[MAX_PRIMES];
+       int upper_bound;
        int N;

        printf("Find all prime numbers between 3 and ?\n");
        scanf("%d", &upper_bound);

@-       is_prime[2] = 1;@
-
        for (N = 3; N <= upper_bound; N += 2) {
-               check_prime(N);
+               check_prime(N, is_prime);
                if (is_prime[N])
                        printf("%d is a prime\n",N);
  }
  \end{lstlisting}
\end{quote}

\end{document}