#    APRICOT: Advanced Platform for Reproducible Infrastructures in the Cloud via Open Tools

This notebook provide a complete example of reproducible experimentation in the field of life sciences. The objective is to determine the best reconstruction parameters for a simulated Positron Emission Tomography (PET) scanner system. For that purpose, the source code of two required programs has been distributed with this notebook. The first one, "reconstructor" is an implementation based on the OPLM algorithm for image reconstruction of PET systems. The second, "evaluateImage", gets a reconstructed image as input and compares it with the expected one and returns a set of image quality parameters. The input data is a simulated acquisition of a PET system formed by 3 rings with 20 detector modules each one. The simulated data has been provided via a public S3 bucket (https://s3.amazonaws.com/grycap/datasets/apricot/reconstruction/data.txz).

# Experimentation

Medical scanners, like most physical detectors, measure raw data that must be post-processed to obtain an interpretable result. In particular, for medical scanners based in Positron Emission Tomography (PET) or Computed Tomography (CT), the final result is, usually, a patient image to be interpreted by the physician to develop a diagnostic.

Focusing on PET and CT cases, there exists a great variety of iterative and analytic image reconstruction algorithms [0][1] [2][3], most of them based on maximum likelihood method [4].  These reconstruction algorithms have a set  of  variable  parameters  such  as  number  and  size  of  voxels  in  the  Field  Of View (FOV), number of iterations, number of partitioned data chunks, weight parameters, filter iterations and weight, etc.  Obviously, the final reconstruction quality  and  speed  will  depend  on  how  accurate  are  the  selected  parameters. Furthermore, the accuracy of selected parameters depend on the scanner system (geometry, energy resolution, scanned object, etc.).  Indeed, the importance of reconstruction parameters on medical image has been studied for different kind of scanners in many publications, such as [5] [6] [7] [8].

Achieving the best parameters for our specific system and algorithm is desirable not only for medical diagnostics but to perform accurate comparison of reconstruction methods and scanner capabilities. That comparison is crucial to select and create new scanner systems using simulated data to study their theoretical performance. However, the number of possible parameters combinations grows as indicated in (1).

\begin{equation}
\prod_{i=1}^{n_{param}} N_i\;,
\end{equation}

where $N_i$ is the number of possible values of parameter number $i$ and $n_{param}$ the number of variable parameters. So, even performing a multiparametric study with few parameters requires a significant computational effort. APRICOT has been used in this experimentation to deploy and manage the required infrastructure to perform a multiparametric study on a modified implementation of "OPL-EM" reconstruction algorithm for PET systems described in the work by Reader et al. [1].

The input data used for this experimentation has been obtained simulating a PET system formed by three rings of $20$ detector modules each one. The simulations have been done using a self developed routines to perform PET system simulations with the Monte-Carlo (MC) code PENELOPE [9]. We will measure the reconstruction time and a set of quality metrics to determine the best parameters to achieve the required agreement between time spent for reconstruction and image quality. This metrics are, "Root-Mean-Square Error" (RMSE), "Peak Signal to Noise Ratio" (PSNR), "Normalized Root Mean Square Distance" (NRMSD) and "Normalized Mean Absolute Distance" (NMAD), which equations are listed below,

\begin{equation}
    RMSE = \sqrt{\frac{1}{N} \sum_{m=1}^{N} (v(m) - v_{true}(m))^{2}}
    \label{eq:RMSE}
\end{equation}

\begin{equation}
    PSNR = 10 \cdot log_{10}\left( \frac{\max(v_{true})^2}{\frac{1}{N} \sum_{m=1}^{N} (v(m) -     v_{true}(m))^{2}}\right)
    \label{eq:PSNR}
\end{equation}

\begin{equation}
    NRMSD = \sqrt{\frac{\sum_{m=1}^{N} (v(m) - v_{true}(m))^{2}}{\sum_{m=1}^{N} (\bar{v}_{true} - v_{true}(m))^{2}}}
    \label{eq:NRMSD}
\end{equation}

\begin{equation}
    NMAD = \frac{\sum_{m=1}^{N} |v(m) - v_{true}(m)|}{\sum_{m=1}^{N} |v_{true} (m)|}
    \label{eq:NMAD}
\end{equation}

At metric equations, $v(m)$ denotes the voxel number $m$ of the considered image and the subindex $true$ indicate that is the real image. In this example we will plot the reconstruction time and the RMSE, but editing the code any metric can be ploted.

## Setting up the system

For this experimentation we need to perform a multiparametric analysis to obtain the best image reconstruction parameters. So, the first step is infrastructure deployment. The chosen infrastructure is a batch cluster with 5 working nodes and ubuntu 18.04 LTS images as OS. Working nodes have 2 GB of RAM and 20 GB of disk space. Also, we recommend to assign, at least, two CPUs to the front-end node for this experiment. To reproduce the experiment deploy this infrastructure using the APRICOT deploy extension in one of the supported Cloud providers. You will need valid access credentials to your Cloud provider. Once the cluster has been configured, you can follow the experimentation.

Store the cluster and user names

```python
clusterName = "reconstruction"
```

```python
username = "ubuntu"
```

We need to load the python module with the APRICOT magics to manage our clusters. This step can be avoided if the module is loaded by default on each notebook.

```python
%reload_ext apricot_magic
```

Once the infrastructure has been deployed and configured, check it using %apricot_ls magic

```python
%apricot_ls
```

If the infrastructure deployment fails, we can get the output log with the following instruction,

```python
%apricot_log $clusterName
```

## Preparing data and programs

Now, we must provide the necessary data and software for our analisys:

1- Raw simulated data

2- Comparision program code

3- Reconstruction program code

All required source codes can be upload easily from our computer using the ''%apricot_upload'' instruction. However, the input data with raw scanner simulated detections is stored externally because of its size. These data has been stored in a public Amazon S3 bucket and, thus, it can be downloaded using "curl". First, check if the "input" folder is at the current directory:

```bash
%%bash
ls
```

This folder contains the source codes, upload them to the front-end node of the cluster.

```python
%apricot_upload $clusterName input /home/$username
```

Download the input data to the front-end node of the cluster using "curl". This step may take a few minutes

```python
%apricot exec $clusterName curl https://s3.amazonaws.com/grycap/datasets/apricot/reconstruction/data.txz --output data.txz
```

Finally, extract the input data.

```python
%apricot exec $clusterName tar -xvf data.txz
```

Check if all required files are in the "input" folder

```python
%apricot exec $clusterName ls input
```

Now, we need to compile the source codes. All the necessary compilers and cmake tools should be installed at configuration initialization.

Compile the reconstruction and comparision programs

```python
%apricot exec $clusterName cd input/reconstructor_code && bash install.sh && cp reconstructor ../
```

```python
%apricot exec $clusterName cd input && g++ -o evaluateImage evaluateImage.cpp -O2
```

Check if the executables have been created (evaluateImage and reconstructor)

```python
%apricot exec $clusterName ls input
```

Now we have all the necessary files at cluster. This has been configured automatically with NFS, so the '/home' directory is shared by all the working nodes and the front-end node.

We need also a folder to store the results. Create a folder named 'results' for that purpose.

```python
%apricot exec $clusterName mkdir results
```

## Executing jobs

Now, it is time to execute the computational experiment. For simplicity, this multiparametric study only uses three variable parameters. However, this can be extended to any number of parameter ranges. First of all, we need to specify each parameter interval and step size. To avoid large execution times, we will use large step sizes for all ranges. With the provided ranges, the total number of executed jobs will be 15.

```python
minNvox_xy = 20
maxNvox_xy = 250
stepNvox_xy = 50

minNvox_z = 20
maxNvox_z = 250
stepNvox_z = 100

nChunksMin = 5
nChunksMax = 5
chunkStep = 1
```

Now, use %apricot_genMPid function to obtain an identifier for the specified ranges. We will use this identifier to repeat the experimentation keeping the results of previous runs.

```python
ID = %apricot_genMPid $minNvox_xy $maxNvox_xy $stepNvox_xy $minNvox_z $maxNvox_z $stepNvox_z $nChunksMin $nChunksMax $chunkStep
```

```python
print(ID)
```

Create a specific folder for this run with the previous ID.

```python
%apricot exec $clusterName mkdir results/$ID
```

```python
%apricot exec $clusterName ls results
```

Launch the jobs using ''%apricot_runMP'' and the local script ''script.sh''. This step can be delayed several minutes until all workers have been configured.

```python
%apricot_runMP $clusterName script.sh /home/$username $minNvox_xy $maxNvox_xy $stepNvox_xy $minNvox_z $maxNvox_z $stepNvox_z $nChunksMin $nChunksMax $chunkStep

```

Check if all the jobs have been finished.

```python
%apricot exec $clusterName squeue
```

When no jobs appear in the tasks queue, execute post-processing script

```python
%apricot exec $clusterName bash input/getResults.sh $ID
```

## Getting results

Once the results of our multiparametric study have been processed, download them to plot the corresponding graphs using "%apricot_download" instruction

```python
resultsFilename = "results-" + ID + ".dat"
%apricot_download $clusterName $resultsFilename .
```

```bash
%%bash

ls
```

Read and parse the results file.

```python
fileIn = open(resultsFilename,"r")

data = fileIn.read()

# Extract data lines
data = data.strip().split('\n')
# Remove header line
data.pop(0)

# Extract input data
XYnvox = []
Znvox = []
chunks = []
userTimeMin = []
userTimeSec = []
systemTimeMin = []
systemTimeSec = []
RMSE = []
PSNR = []
NRMSD = []
NMAD = []

for line in data:
    line = " ".join(line.split())
    words = line.strip().split(' ')
    XYnvox.append(float(words[0]))
    Znvox.append(float(words[1]))
    chunks.append(float(words[2]))
    userTimeMin.append(float(words[3]))
    userTimeSec.append(float(words[4]))
    systemTimeMin.append(float(words[5]))
    systemTimeSec.append(float(words[6]))
    RMSE.append(float(words[7]))
    PSNR.append(float(words[8]))
    NRMSD.append(float(words[9]))
    NMAD.append(float(words[10]))

fileIn.close()
```

Import the numpy and plot libraries. If the required packages are not installed in your system, execute the following statement:

```bash
%%bash
python3 -m pip install --user numpy scipy matplotlib
```

```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d

userTime = np.add(np.multiply(userTimeMin,60.0),userTimeSec)
systTime = np.add(np.multiply(systemTimeMin,60.0),systemTimeSec)
totalTime = userTime + systTime
```

Plot the results:

```python

nChunks = 5.0
subXY = []
subZ = []
subTimes = []
subRMSE = []
subPSNR = []
subNRMSD = []
subNMAD = []

subRMSE_zoom = []
subXY_zoom = []
subZ_zoom = []
nVoxCut = 60

for i in list(range(len(XYnvox))):
    if nChunks == chunks[i]:
        subXY.append(XYnvox[i])
        subZ.append(Znvox[i])
        subTimes.append(totalTime[i])
        subRMSE.append(RMSE[i])
        subPSNR.append(PSNR[i])
        subNRMSD.append(NRMSD[i])
        subNMAD.append(NMAD[i])
        if XYnvox[i] > nVoxCut and Znvox[i] > nVoxCut:
            subXY_zoom.append(XYnvox[i])
            subZ_zoom.append(Znvox[i])
            subRMSE_zoom.append(RMSE[i])

Axpad = 280
fig = plt.figure()
#plt.rcParams["figure.figsize"] = [100,100]
#plt.rcParams.update({'font.size': 128})

ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('nº voxels x-y')
ax.set_ylabel('nº voxels z')
ax.set_zlabel('time (s)')

ax.xaxis.labelpad = Axpad
ax.yaxis.labelpad = Axpad
ax.zaxis.labelpad = Axpad

ax.plot_trisurf(subXY,subZ,subTimes)
plt.show()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('nº voxels x-y')
ax.set_ylabel('nº voxels z')
ax.set_zlabel('rmse')

ax.xaxis.labelpad = Axpad
ax.yaxis.labelpad = Axpad
ax.zaxis.labelpad = Axpad

ax.plot_trisurf(subXY,subZ,subRMSE)
plt.show()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('nº voxels x-y')
ax.set_ylabel('nº voxels z')
ax.set_zlabel('rmse')

ax.xaxis.labelpad = Axpad
ax.yaxis.labelpad = Axpad
ax.zaxis.labelpad = Axpad

ax.plot_trisurf(subXY_zoom,subZ_zoom,subRMSE_zoom)
plt.show()

```

Previous graphs show the RMSE and reconstruction time for each parameter combination used in our study. In a real case study, these results should provide the best parameters to achieve the required agreement between reconstruction speed and image quality. However this is only a simplified example to show APRICOT functionality. Now, we can repeat the experiment with different parameter ranges or plot different results.

## Delete infrastructure

Once finished the experimentation, do not forget to destroy the cluster.

```python
%apricot destroy $clusterName
```

# Conclusions

This document includes infrastructure specifications, data storage, experimentation execution, results gathering and infrastructure termination for a example computational experimentation. Thus it can be reproduced easily distributing the experimentation notebook together with the required source codes.

# References

[0] Xuan Liu, Claude Comtat, Christian Michel, Paul Kinahan, Michel Defrise, and David Townsend. Comparison of 3-d reconstruction with 3d-osem and with fore + osem for pet. IEEE TRANSACTIONS ON MEDICAL IMAGING, 2001

[1]  Andrew  J.  Reader,   Stijn  Ally,   Filippos  Bakatselos,   Roido  Manavaki, Richard J. Walledge, Alan P. Jeavons, Peter J. Julyan, Sha Zhao, David L. Hastings, and Jamal Zweit.  One-pass list-mode em algorithm for high-resolution 3-d pet image reconstruction into large arrays. IEEE  TRANSACTIONS ON NUCLEAR SCIENCE, 2002.

[2]  Sarabjeet Singh, Mannudeep K. Kalra, Jiang Hsieh, Paul E. Licato, Synho Do, Homer H. Pien, Michael A. Blake. Abdominal ct: Comparison of adaptive  statistical  iterative  and  filtered  back  projection  reconstruction  techniques. Radiology, 2010.

[3] Chillarón,  Mónica.,  Vidal,  Vicent,  Verdú,  Gumersindo. Ct  image  reconstruction withsuitesparseqr factorization package. Radiation  Physics  and Chemistry, 2019.

[4] L.A. Sheep and Y.Vardi.  Maximum likelihood reconstruction for emission tomography. IEEE TRANSACTIONS ON MEDICAL IMAGING, 1982.

[5] Jin Mo Goo, Trongtum Tongdee, Ranista Tongdee, Kwangjae Yeo, Charles F. Hildebolt, Kyongtae T. Bae. Volumetric measurement of synthetic lung nodules  with  multi–detector  row  ct:  Effect  of  various  image  reconstruction  parameters  and  segmentation  thresholds  on  measurement  accuracy. Radiology, 2005.

[6] James  G.  Ravenel,  William  M.  Leue,  Paul  J.  Nietert,  James  V.  Miller, Katherine K. Taylor, Gerard A. Silvestri.  Pulmonary nodule volume:  Effects of reconstruction parameters on automated measurements—a phantom study. Radiology, 2008.

[7] Yue-Houng Hu, Bo Zhao, Wei Zhao.  Image artifacts in digital breast tomosynthesis:  Investigation  of  the  effects  of  system  geometry  and  reconstruction  parameters  using  a  linear  system  approach. Medical  Physics, 2008.

[8] Maria Lyra, Agapi Ploussi. Filtering in spect image reconstruction. Journal of Biomedical Imaging, 2011.

[9] Salvat F. Penelope. a code system for monte carlo simulation of electron and photon transport. Issy-Les-Moulineaux: OECD  Nuclear  Energy  Agengy, 2014.


# Applied Stochastic Processes HW_10

**11510691 程远星$\DeclareMathOperator*{\argmin}{argmin}
\DeclareMathOperator*{\argmax}{argmax}
\DeclareMathOperator*{\plim}{plim}
\newcommand{\using}[1]{\stackrel{\mathrm{#1}}{=}}
\newcommand{\ffrac}{\displaystyle \frac}
\newcommand{\asim}{\overset{\text{a}}{\sim}}
\newcommand{\space}{\text{ }}
\newcommand{\bspace}{\;\;\;\;}
\newcommand{\QQQ}{\boxed{?\:}}
\newcommand{\void}{\left.\right.}
\newcommand{\Tran}[1]{{#1}^{\mathrm{T}}}
\newcommand{\d}[1]{\displaystyle{#1}}
\newcommand{\CB}[1]{\left\{ #1 \right\}}
\newcommand{\SB}[1]{\left[ #1 \right]}
\newcommand{\P}[1]{\left( #1 \right)}
\newcommand{\abs}[1]{\left| #1 \right|}
\newcommand{\norm}[1]{\left\| #1 \right\|}
\newcommand{\dd}{\mathrm{d}}
\newcommand{\Exp}{\mathrm{E}}
\newcommand{\RR}{\mathbb{R}}
\newcommand{\EE}{\mathbb{E}}
\newcommand{\II}{\mathbb{I}}
\newcommand{\NN}{\mathbb{N}}
\newcommand{\ZZ}{\mathbb{Z}}
\newcommand{\QQ}{\mathbb{Q}}
\newcommand{\PP}{\mathbb{P}}
\newcommand{\AcA}{\mathcal{A}}
\newcommand{\FcF}{\mathcal{F}}
\newcommand{\AsA}{\mathscr{A}}
\newcommand{\FsF}{\mathscr{F}}
\newcommand{\Var}[2][\,\!]{\mathrm{Var}_{#1}\left[#2\right]}
\newcommand{\Avar}[2][\,\!]{\mathrm{Avar}_{#1}\left[#2\right]}
\newcommand{\Cov}[2][\,\!]{\mathrm{Cov}_{#1}\left(#2\right)}
\newcommand{\Corr}[2][\,\!]{\mathrm{Corr}_{#1}\left(#2\right)}
\newcommand{\I}[1]{\mathrm{I}\left( #1 \right)}
\newcommand{\N}[1]{\mathcal{N} \left( #1 \right)}
\newcommand{\ow}{\text{otherwise}}
\void^\dagger$**

## Question 1

$$\begin{align}
\Exp\SB{g\P{T} \mid T > a} &= \int_{-\infty}^{\infty} g\P{t}  f_{T\mid T>a} \P{t\mid T>a} \;\dd t\\
&= \int_{a}^{\infty} g\P{t} \; \dd F_{T\mid T>a} \P{t\mid T>a} \\
&= \int_{a}^{\infty} g\P{t} \; \dd \P{1-P\CB{T>t\mid T>a}} \\
&= \int_{a}^{\infty} g\P{t} \; \dd \P{- \ffrac{e^{-\lambda t}}{e^{-\lambda a}}} \\
&= \int_{a}^{\infty} g\P{t} \lambda e^{-\lambda\P{t-a}}\; \dd t \\
&= \int_{0}^{\infty} g\P{t+a} \lambda e^{-\lambda t}\; \dd t \\
&= \int_{0}^{\infty} g\P{t+a} f_T\P{t} \dd t \\
&= \Exp\SB{g\P{T+a}}
\end{align}$$

## Question 2

$$\begin{align}
P\CB{X_1 < X_2 \mid\min\P{X_1,X_2}=t}&= \ffrac{P\CB{X_1<X_2 ,\min\P{X_1,X_2} = t}}{P\CB{\min\P{X_1,X_2} = t}}\\
&= \ffrac{P\CB{X_1 = t, X_2 > t}}{P\CB{X_1 = t,X_2 > t} + P\CB{X_2 = t,X_1 >t}}
\end{align}$$

$\bspace$following the defintion in the textbook we let $\bar F\P{x} = P\CB{X>x}$, then

$$
\begin{align}
P\CB{X_1 < X_2 \mid\min\P{X_1,X_2}=t} &= \ffrac{f_1\P{t} \bar F_2\P{t}}{f_1\P{t} \bar F_2\P{t} + f_2\P{t} \bar F_1\P{t}}\\
&= \ffrac{\ffrac{f_1\P{t}}{1-F_1\P{t}}}{\ffrac{f_1\P{t}}{1-F_1\P{t}} + \ffrac{f_2\P{t}}{1-F_2\P{t}}}\\
&= \ffrac{r_1\P{t}}{r_1\P{t} + r_2\P{t}}
\end{align}$$

## Question 3

$$\begin{align}
f_{X\mid X<Y}\P{x}&=\ffrac{\dd}{\dd x}F_{X\mid X<Y}\P{x}\\
&= \ffrac{\dd}{\dd x}P\CB{X<x\mid X<Y}\\
&= \ffrac{\dd}{\dd x}\P{\ffrac{P\CB{X<x,X<Y}}{P\CB{X<Y}}}\\
&= \ffrac{\dd}{\dd x}\P{\ffrac{ P\CB{X<Y}P\CB{Y\leq x}+P\CB{X<x}P\CB{x\leq Y}}{ P\CB{X<Y}} }\\
&= \ffrac{\dd}{\dd x}\P{\ffrac{ \ffrac{\lambda}{\lambda+\mu} \P{1-e^{-\mu x}}+\P{1-e^{-\lambda x}}e^{-\mu x}}{ \ffrac{\lambda}{\lambda+\mu} }}\\
&=-\ffrac{\mu^2}{\lambda} e^{-\mu x} + \ffrac{\P{\lambda + \mu}^2}{\lambda}e^{-\P{\lambda + \mu}x}
\end{align}$$

## Question 4

$\P{1}$

$$\begin{align}
P\CB{X_1 <X_2<X_3} &= P\CB{X_1 = \min\P{X_i}}\cdot P\CB{X_2 < X_3 \mid X_1 = \min\P{X_i}}\\
&= \ffrac{\lambda_1}{\sum \lambda_i}\cdot P\CB{X_2 < X_3}\\
&= \ffrac{\lambda_1}{\sum \lambda_i}\ffrac{\lambda_2}{\lambda_2 + \lambda_3}
\end{align}$$

$\P{2}$

$$\begin{align}
P\CB{X_1 <X_2\mid \max\P{X_1,X_2,X_3} = X_3} &= \ffrac{P\CB{X_1<X_2<X_3}}{P\CB{X_1<X_2<X_3} + P\CB{X_2<X_1<X_3}}\\
&= \ffrac{\ffrac{\lambda_1}{\sum \lambda_i}\ffrac{\lambda_2}{\lambda_2 + \lambda_3}}{\ffrac{\lambda_1}{\sum \lambda_i}\ffrac{\lambda_2}{\lambda_2 + \lambda_3} + \ffrac{\lambda_2}{\sum \lambda_i}\ffrac{\lambda_1}{\lambda_1 + \lambda_3}}\\
&= \ffrac{\lambda_1 + \lambda_3}{\lambda_1 + \lambda_2 + 2\lambda_3}
\end{align}$$

$\P{3}$

$$\begin{align}
&\Exp\SB{\max X_i\mid X_1 <X_2<X_3} \\[0.6em]
= \; & \ffrac{\d{\int_0^\infty \int_0^{x_3}\int_0^{x_2} x_3\cdot f_{X_3}(x_3)\cdot f_{X_2}(x_2)\cdot f_{X_1}(x_1)\;\dd x_1 \dd x_2\dd x_3}}{\d{\int_0^\infty \int_0^{x_3}\int_0^{x_2} f_{X_3}(x_3)\cdot f_{X_2}(x_2)\cdot f_{X_1}(x_1)\;\dd x_1 \dd x_2\dd x_3}}\\
= \; & \ffrac{1}{\lambda_1 + \lambda_2 + \lambda_3} + \ffrac{1}{\lambda_2+\lambda_3} + \ffrac{1}{\lambda_3}
\end{align}$$

$\P{4}$

$$
\begin{align}
\Exp\SB{\max X_i} &= \Exp\SB{\Exp\SB{\max X_i\mid X_1 <X_2<X_3}}\\
&= \sum_{i\neq j\neq k} \Exp\SB{\max X_i\mid X_i < X_j < X_k} \cdot P\CB{X_i < X_j < X_k} \\
&= \sum_{i\neq j\neq k} \P{\ffrac{1}{\lambda_1 + \lambda_2 + \lambda_3} + \ffrac{1}{\lambda_j+\lambda_k} + \ffrac{1}{\lambda_k}}\cdot\ffrac{\lambda_i}{\sum \lambda_i}\ffrac{\lambda_j}{\lambda_j + \lambda_k}
\end{align}$$

***

Probability and Statistics/Applied Random Process/HW/HW_10.ipynb


```python
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import json
import os
from plot import *

%matplotlib inline
%reload_ext autoreload

def run_plot(args):
    use_legend = False
    if args.legend is not None:
        assert len(args.legend) == len(args.logdir), \
            "Must give a legend title for each set of experiments."
        use_legend = True

    data = []
    if use_legend:
        for logdir, legend_title in zip(args.logdir, args.legend):
            data += get_datasets(logdir, legend_title)
    else:
        for logdir in args.logdir:
            data += get_datasets(logdir)

    if isinstance(args.value, list):
        values = args.value
    else:
        values = [args.value]
    for value in values:
        plot_data(data, value=value)
```

# run
* don't normalize advantage
* reward to go = False

``` bash
python train_pg.py CartPole-v0 -n 100 -b 1000 -e 5 -dna --exp_name sb_no_rtg_dna
```

```python
class Argument(object):
    logdir = ['/home/wdl/notebook/DRL/hw2/data/sb_no_rtg_dna_CartPole-v0_18-12-2017_19-39-25/1']
    legend = None
    value = ['AverageReturn', 'StdReturn']
args = Argument()
run_plot(args)

```

# run
* don't normalize advantage
* reward to go = True

``` bash
python train_pg.py CartPole-v0 -n 100 -b 1000 -e 5 -rtg -dna --exp_name sb_rtg_dna
```

```python
class Argument(object):
    logdir = ['/home/wdl/notebook/DRL/hw2/data/sb_rtg_dna_CartPole-v0_18-12-2017_19-47-43/1']
    legend = None
    value = ['AverageReturn', 'StdReturn']
args = Argument()
run_plot(args)
```

# run
* normalize advantage
* reward to go = True

``` bash
python train_pg.py CartPole-v0 -n 100 -b 1000 -e 5 -rtg --exp_name sb_rtg_na
```

```python
class Argument(object):
    logdir = ['/home/wdl/notebook/DRL/hw2/data/sb_rtg_na_CartPole-v0_18-12-2017_20-22-11/1']
    legend = None
    value = ['AverageReturn', 'StdReturn']
args = Argument()
run_plot(args)
```

# run
* normalize advantage
* reward to go = False
* larger batch size

``` bash
python train_pg.py CartPole-v0 -n 100 -b 5000 -e 5 -dna --exp_name lb_no_rtg_dna
```

```python
class Argument(object):
    logdir = ['/home/wdl/notebook/DRL/hw2/data/lb_no_rtg_dna_CartPole-v0_18-12-2017_19-57-12/1']
    legend = None
    value = ['AverageReturn', 'StdReturn']
args = Argument()
run_plot(args)
```

# run
* don't normalize advantage
* reward to go = True
* larger batch size

``` bash
python train_pg.py CartPole-v0 -n 100 -b 5000 -e 5 -rtg -dna --exp_name lb_rtg_dna
```

```python
class Argument(object):
    logdir = ['/home/wdl/notebook/DRL/hw2/data/lb_rtg_dna_CartPole-v0_18-12-2017_20-03-14/1']
    legend = None
    value = ['AverageReturn', 'StdReturn']
args = Argument()
run_plot(args)
```

# run
* normalize advantage
* reward to go = True
* larger batch size

``` bash
python train_pg.py CartPole-v0 -n 100 -b 5000 -e 5 -rtg --exp_name lb_rtg_na
```

```python
class Argument(object):
    logdir = ['/home/wdl/notebook/DRL/hw2/data/lb_rtg_na_CartPole-v0_18-12-2017_20-08-38/1']
    legend = None
    value = ['AverageReturn', 'StdReturn']
args = Argument()
run_plot(args)
```

* Which gradient estimator has better performance without advantage-centering, the trajectory-centric one, or the one using reward-to-go?

reward-to-go preform better

* Did advantage centering help?

yes, when the model getting to converge, the variance gets lower (although variance centering makes the highest variance higher)

* – Describe what you expected from the math—do the empirical results match the theory?

trajectory-centric uses only the sum reward of the entire trajectory, while reward-to-go uses all, since the reward of the entire trajectory is usually larger, it's more unstable

* Did the batch size make an impact?
yes

neural network baseline

```python
class Argument(object):
    logdir = ['/home/wdl/notebook/DRL/hw2/data/sb_rtg_lb_CartPole-v0_18-12-2017_20-33-22/1']
    legend = None
    value = ['AverageReturn', 'StdReturn']
args = Argument()
run_plot(args)
```

[GAE](https://danieltakeshi.github.io/2017/04/02/notes-on-the-generalized-advantage-estimation-paper/)
generalized advantage estimation

$$
\begin{align}
\hat{A}_t^{GAE(\gamma,\lambda)} &= (1-\lambda)\Big(\hat{A}_{t}^{(1)} + \lambda \hat{A}_{t}^{(2)} + \lambda^2 \hat{A}_{t}^{(3)} + \cdots \Big) \\
&= (1-\lambda)\Big(\delta_t^V + \lambda(\delta_t^V + \gamma \delta_{t+1}^V) + \lambda^2(\delta_t^V + \gamma \delta_{t+1}^V + \gamma^2 \delta_{t+2}^V)+ \cdots \Big)  \\
&= (1-\lambda)\Big( \delta_t^V(1+\lambda+\lambda^2+\cdots) + \gamma\delta_{t+1}^V(\lambda+\lambda^2+\cdots) + \cdots \Big) \\
&= (1-\lambda)\left(\delta_t^V \frac{1}{1-\lambda} + \gamma \delta_{t+1}^V\frac{\lambda}{1-\lambda} + \cdots\right) \\
&= \sum_{l=0}^\infty (\gamma \lambda)^l \delta_{t+l}^{V}
\end{align}
$$

``` bash
python train_pg.py CartPole-v0 -n 100 -b 1000 -e 1 -rtg -bl --exp_name gae
```

```python
class Argument(object):
    logdir = ['/home/wdl/notebook/DRL/hw2/data/gae_CartPole-v0_18-12-2017_21-11-52/1']
    legend = None
    value = ['AverageReturn', 'StdReturn']
args = Argument()
run_plot(args)
```


# Lab 2.1: Radar Range Equation

```python
%matplotlib widget
import rad.css as css
import rad.example as ex
import rad.quiz as qz
from rad.const import c, k
from rad.radar import to_db, from_db, deg2rad, rad2deg
from math import sqrt, sin, asin, cos, acos, tan, atan2, pi, log, log10
css.add_custom_css()
```

**Reminders**:

- Hit the *Run All* button  button above before continuing
- Useful formulae and definitions are available in [Reference](Reference.ipynb)

In the previous lesson, we saw how to use a ranging sensor to find targets and coarsely estimate their range and angle. One major step in this process was **detection**, or the acknowledgement that an target echo has been received. In real radar systems, detection is complicated by the fact that there is, inevitably, noise in the system. This means for an echo to be detectable, its strength needs to be greater than the strength of the noise.

Below you can see a notional received signal with an echo (in **black**) located at a delay of $\tau = 50~\mathrm{ms}$ and noise (in **red**). The echo is very strong compared to the noise, so we can say with confidence that an echo has been received at the moment.

```python
ex.ex_2_1_1a()
```

However, in the following plot, the echo is about the same strength as the noise. In this case, it will be very difficult to say with certainty that there was a detection for the second echo.

```python
ex.ex_2_1_1b()
```

In this section, we will talk about how to calculate the strength of the target echo along with the strength of the noise; this allows us to know under what circumstances we can expect to find targets. For instance, if we have an inexpensive system with very powerful noise, we can expect it to be difficult to find any echoes except those that are very strong. The actual process of detection will be covered in [Lab 3.2: Detection](3_2_Detection.ipynb).

## Signal-to-Noise Ratio

The most common way to quantify how strong a signal is compared to noise is the **signal-to-noise ratio**[1](#foot_snr) (SNR). This is defined as

$$
\mathrm{SNR}=\frac{\mathrm{Signal~Energy}}{\mathrm{Average~Noise~Energy}}
$$

Echoes with *high* SNR will be easy to detect, echoes with *low* SNR will be difficult to discern from the noise. In fact, SNR is a very important measure across many fields of engineering, e.g., communications, sensing. You will tend to see it any time there is some signal of interest that is trying to be estimated in the presence of noise. Note that the noise energy term is an average value because noise is inherently random and will not have a constant energy.

**Note:** Energy is measured in joules ($\mathrm{J}$), and SNR is a unitless value that is most often presented in decibels ($\mathrm{dB}$).

Below is an interactive plot showing different example received signals where you can change the signal energy and the noise energy (the noise is drawn randomly). Try this:

- Single-click the *Noise Energy* slider to select it
- Tap the right arrow on your keyboard to slowly increase the noise energy

As you watch the noise energy increase and SNR decrease, try and get a feel for where it would start being difficult to confidently separate the signal from the noise.

```python
ex.ex_2_1_2()
```

***

### Question 1

**(a)** What is the SNR if the true received signal has an energy of $100~\mathrm{J}$, and the average noise energy is $5.3~\mathrm{J}$?

```python
qz.quiz_2_1_1a()
```

```python
# Scratch space
```

**(b)** If the SNR of a signal is measured to be $15~\mathrm{dB}$ and the average noise energy is known to be $2.2~\mathrm{J}$, what is the signal energy?

```python
qz.quiz_2_1_1b()
```

```python
# Scratch space
```

***

We can now focus on trying to derive the SNR of a target echo for a radar system; this will be prove to be incredibly useful in basic radar design. Fair warning: this will be the most math-heavy portion of the course.

## Radar Range Equation

One of the basic tools in radar design is called the **radar range equation**, which derives the signal-to-noise ratio of a radar system as a function of high-level parameters, e.g., transmit energy, transmit frequency, transmit gain, receive gain. In this section, we will step through its derivation together. To begin, we will start with a more general result applying to all electromagnetic transmissions and receptions.

### Energy and Instantaneous Power

Before we get to the evolution of a radar transmission through space, we need to first dive a little deeper into electromagnetic emissions. As discussed in [Lab 1.2: Introduction to Radar](1_2_Introduction_to_Radar.ipynb), a radar transmits a pulse of electromagnetic energy and listens for echoes reflected by targets. It creates the pulse by using a controlled electrical current to drive an antenna and generate a radiated electric field; the converted energy is then contained in the electric field wave as it propagates through space.

The electrical signal used to generate the propagated wave is commonly called the **waveform** and is often defined as a voltage with units of volts ($\mathrm{V}$). We can see a sinusoidal waveform in the figure below:

Design of radar waveforms will be discussed in [Lab 3.1: Radar Transmissions and Receptions](3_1_Radar_Transmissions_and_Receptions.ipynb).

Once the wave has been generated by the antenna, it is now an electric field as it moves through space; electric fields are measured in units of volts per meter ($\mathrm{V/m}$). Here is a snapshot in time of a sinusoidal wave (note that it is plotted versus range):

Now, to study the energy imparted to the target by a wave, we can study the **instantaneous power** of the wave[2](#foot_power), $P$ , which quantifies the rate of energy transfer contained in a short segment of the wave; power is measured in watts ($\mathrm{W}$). Put another way: the amount of energy transferred by a wave segment with instantaneous power $P$ and duration $\epsilon$ is approximately $\mathcal{E} = P \cdot \epsilon$. The instantaneous power of the sinusoidal wave above is shown the figure below:

The total energy, $\mathcal{E}$ , in the wave can be obtained by partitioning the entire wave into small segments and then adding up the energy contributions from each segment over the duration of the wave. (Mathematically, this is expressed as an integral.)

Since we are interested in the received energy, $\mathcal{E}_r$ , from a target transmission, we will first derive the received power, $P_r$ , due to a small segment of the transmitted pulse. Then, we will sum all of the contributions from the different segments on the pulse to obtain the total received energy, $\mathcal{E}_r$.

### Friis Transmission Equation

To see how the power of the transmit wave segment varies on its way to and from the target, we will use **Friis transmission equation**[[1]](#ref_friis). In fact, our final answer for this section will simply be two applications of the Friis transmission equation (with a slight variation at the end).

The Friis transmission equation derives how much instantaneous power is transferred from a transmit aperture to a receive aperture at a different location. The system setup is illustrated in the following figure:

Consider focusing in on a small segment of the transmitted wave whose instantaneous power at time of transmission is $P_t$ (see figures below).

As the short segment propagates into space, it spreads out in all directions on a spherical shell of energy characterized by a **power density** (denoted as $\rho$); a *power density* tells us how much power a receive aperture would accumulate *per unit area*. For instance, if a receive aperture has an area $A_r = 2~\mathrm{m^2}$ and it observes an incoming wave segment with a transmitted power density of $\rho = 10~\mathrm{W/m^2}$, then it will garner a received instantaneous power of

$$
\begin{align}
P_r &= A_r \cdot \rho\\
&= 20~\mathrm{W}
\end{align}
$$

In the following figure, we can now see the power density due to the transmitted wave segment.

To derive an expression for the power density, we first note that the energy (and instantaneous power) of transmission has to be conserved as it spreads out in space as a spherical shell. Thus, if we were to add up all of the power on the shell, it should equal the original power of the wave segment. Noting that the surface area of a sphere of radius $r$ is $S = 4\pi r^2$, this means the transmitted power density, $\rho_t$ , should be of the form:

$$
\begin{align}
\rho_t &= \frac{P_t}{S}\\
&= \frac{P_t}{4\pi r^2}
\end{align}
$$

where $S$ is the surface area of the sphere. Note that division by the surface area of a sphere is exactly the *propagation loss* referred to in [Lab 1.2: Introduction to Radar](1_2_Introduction_to_Radar.ipynb), just now in mathematical form. We can revisit the interactive example showing how the amplitude (and, thus, instantaneous power) of the wave diminishes as it travels outward from the transmit aperture:

```python
ex.ex_2_1_3()
```

Now, the last thing to note is that since transmission uses an aperture, it will concentrate its energy in a direction characterized by its transmit gain, $G_t(\theta)$. Recalling from [Lab 1.2: Introduction to Radar](1_2_Introduction_to_Radar.ipynb), the energy in azimuth angle $\theta$ is $\mathcal{E}_t G_t(\theta)$, which means its power in that direction is $P_t G_t(\theta)$. Therefore, accounting for the transmit gain, the transmitted power density, $\rho_t$, at range $r$ due to a wave segment is

$$
\rho_t = \frac{P_t G_t(\theta)}{4 \pi r^2}
$$

Finally, if we let the receive aperture have an area of $A_r$ and it is at a range $r$ from the transmit aperture, the total received power, $P_r$, is

$$
\begin{align}
P_r &= A_r \cdot \rho_t\\
&= \frac{P_t G_t(\theta) A_r}{4 \pi r^2}
\end{align}
$$

This equation is known as the Friis transmission equation:

$$
P_r = \frac{P_t G_t(\theta) A_r}{4 \pi r^2}
$$

It tells use how much power can be aggregated by a received aperture of area $A_r$ at range $r$ and angle $\theta$ from a transmit aperture with transmit power $P_t$ and transmit gain $G_t(\theta)$.

The following interactive example shows how the received power, $P_r$ , varies using transmissions from a dish radar with selectable parameters. Note the plot shows received power, $P_r$ , as a function of range, $r$ , and receive aperture area, $A_r$. Receive aperture area is shown in $\mathrm{dBsm}$, which is the decibel version of square meters ($\mathrm{m^2}$).

```python
ex.ex_2_1_4()
```

From the example, we can see the received power *increases* with:

* Increasing receive aperture area, $A_r$, due to more accumulated power
* Transmit frequency, $f$, due to higher transmit and receive gain
* Dish radius, due to higher transmit and receive gain

***

### Question 2

**(a)** What is the received power, $P_r$ , for a receive aperture of area $A_r = 10~\mathrm{m^2}$ at range $r = 50~\mathrm{km}$ for a transmission with power $P_t =10~\mathrm{kW}$ and transmit gain of $G_t(\theta)=35~\mathrm{dB}$?

```python
qz.quiz_2_1_2a()
```

```python
# Scratch space
```

**(b)** If the transmit power is $P_t = 100~\mathrm{kW}$ and transmit frequency is $f = 3.5~\mathrm{GHz}$, what transmit dish radius is needed to achieve a received power of $P_r = 1~\mathrm{W}$ with an receive aperture at range $r = 10~\mathrm{km}$ and aperture area $A_r = 5~\mathrm{m^2}$?

```python
qz.quiz_2_1_2b()
```

```python
# Scratch space
```

***

Now, we will use the Friis transmission equation to derive the received echo power at the radar resulting from a transmission wave segment. More specifically, we are going to trace the path followed by this chosen segment from its origin at transmit, to the target, and back to the radar—this is broken into two applications of the equation:
* Power that a target sees from a transmission
* Received power after the target reflects the transmission

### Incident Power at Target

From the derivation of the Friis transmission equation, we know that the instantaneous power density of the transmitted wave segment at the target, $\rho_t$ , for a radar with transmit gain $G_t(\theta)$ is

$$
\rho_t = \frac{P_t G_t(\theta)}{4\pi r^2}
$$

Thus, if the target is at range $r$ (where it is assumed that the range is much greater than the size of the target) and azimuth angle $\theta$, it sees the transmission as an incoming wall of electromagnetic energy (commonly called a *plane wave*) with power density $\rho_t$.

The next question to answer is how much energy is captured by the target and reflected back toward the radar. This relationship is quantified by a target's **radar cross section** (RCS), $\sigma$ , which is a measure of a target's ability to reflect power back in the direction of the receiving sensor. As a means of simplifying target description, it is modeled as having a hypothetical receive aperture that collects an incoming wave over a certain area and then immediately retransmits the aggregated power equally in every direction (see figure below). The *area of the hypothetical receive aperture is its radar cross section*; because it a measure of area, its unit are in square meters ($\mathrm{m}^2$) and is commonly presented using its decibel analog, $\mathrm{dBsm}$.

Roughly, the larger a target, the larger its RCS; however, it is important to note that RCS does not necessarily have a direct relationship with the actual physical area of the target; for example, stealth planes are quite large, but their design is chosen to minimize RCS. The larger the RCS, the stronger the echo, and the more detectable an object is.

Using the definition of RCS, $\sigma$ , and the Friis transmission equation, the amount of instantaneous power incident on the target, $P_i$ , is:

$$
\begin{align}
P_i &= \rho_t \cdot \sigma\\
&= \frac{P_t G_t(\theta)\sigma}{4\pi r^2}
\end{align}
$$

***

### Question 3

**(a)** What is the incident power, $P_i$ , at a target of range $r = 50~\mathrm{km}$ and radar cross section $\sigma = 5~\mathrm{dBsm}$, if the originating radar has transmit gain $G_t(\theta) = 30~\mathrm{dB}$ and transmit power $P_t = 150~\mathrm{kW}$?

```python
qz.quiz_2_1_3a()
```

```python
# Scratch space
```

**(b)** If a radar has a transmit gain of $G_t(\theta) = 25~\mathrm{dB}$, transmit power of $P_t = 500~\mathrm{kW}$, and incident power of a target with RCS $\sigma = 0~\mathrm{dBsm}$ is $P_i = 0.1~\mathrm{mW}$, what is the range, $r$ , of the target?

```python
qz.quiz_2_1_3b()
```

```python
# Scratch space
```

***

### Received Power at Radar

Due to how the target is modeled using the RCS, the reflected power sent back toward the radar is the same as the incident power, $P_i$. Now, we can use the the fact that the target has unit gain (reradiates in all directions equally), the area of the radar receive aperture, $A_r$ , and the Friis transmission equation one more time and get the received power, $P_r$ , due to the reflected wave segment:

$$
\begin{align}
P_r &= \frac{P_i A_r}{4\pi r^2}
\end{align}
$$

Substituting in the form of the incident power, $P_i$ , derived above:

$$
P_r =\frac{P_t G_t(\theta) \sigma A_r}{(4\pi)^2 r^4}
$$

This is very close to what we want: received echo power as a function of radar transmit parameters. However, there is one more small manipulation that makes it more practical to use. It turns out that the area of the receive aperture that is used in this equation is typically not equal to the *actual* geometric area due to realistic imperfections in the system. Due to this, it is easier to create a form that depends on receive gain, $G_r(\theta)$ , (much easier to measure practically) than receive aperture area, $A_r$. This is done by introducing the idea of an **effective aperture area**, $A_e$ , which is the aperture area that would achieve a known gain value.

From [Lab 1.2: Introduction to Radar](1_2_Introduction_to_Radar.ipynb), we know that the receive gain, $G_r(\theta)$ , of an aperture is related to the receive aperture area, $A_r$ , by:

$$
G_r(\theta) \leq \frac{4\pi A_r}{\lambda^2}
$$

where $\lambda$ is the transmit wavelength. Making it an equality and rearranging the formula, we can solve for the effective aperture area, $A_e(\theta)$ , as:

$$
A_e(\theta)=\frac{G_r(\theta)\lambda^2}{4\pi}
$$

Now, we can replace the receive aperture area, $A_r$ , with the effective received aperture area, $A_e(\theta)$ , in the received power, $P_r$ , formula above to obtain:

$$
\begin{align}
P_r &= \frac{P_t G_t(\theta) \sigma A_e(\theta)}{(4\pi)^2 r^4}\\
&= \frac{P_t G_t(\theta) G_r(\theta)\lambda^2\sigma}{(4\pi)^3 r^4}
\end{align}
$$

The last equation is the **received power form** of the **radar range equation**:

$$
P_r = \frac{P_t G_t(\theta) G_r(\theta)\lambda^2\sigma}{(4\pi)^3 r^4}
$$

In the following example, we can see how the received power scales for a dish radar system:

```python
ex.ex_2_1_5()
```

Similar to the example used in illustrating the Friis transmission equation, we can see the received power *increases* with:

* Increasing target RCS, $\sigma$, due to more reflected power
* Transmit frequency, $f$, due to higher transmit and receive gain
* Dish radius, due to higher transmit and receive gain

We can also notice how small the power is that is received by a radar system; the value of $P_r = -120~\mathrm{dBW} = 10^{-12}~\mathrm{W}$, which is one *picowatt* of power.

To obtain the total received energy, $\mathcal{E}_r$ , due to the entire transmitted wave, we can note that each segment of the transmit waveform will travel the same path, and, thus, experience the same scaling by propagation loss, transmit gain, receive gain, etc. Thus, adding all contributions from transmit wave segments, will give us the **received energy form** of the **radar range equation**:

$$
\mathcal{E}_r = \frac{\mathcal{E}_t G_t(\theta) G_r(\theta)\lambda^2\sigma}{(4\pi)^3 r^4}
$$

The following interactive example shows how received energy scales with dish radar parameters:

```python
ex.ex_2_1_6()
```

***

### Question 4

**(a)** What is the received power, $P_r$ , from a target echo with a target at range $r = 100~\mathrm{km}$ and RCS $\sigma = 5~\mathrm{dBsm}$ when using a transmit power of $P_t = 600~\mathrm{kW}$, transmit and receive gain of $G_t(\theta) = G_r(\theta) = 40~\mathrm{dB}$ and transmit frequency $f = 3~\mathrm{GHz}$?

```python
qz.quiz_2_1_4a()
```

```python
# Scratch space
```

**(b)** If the transmit frequency of a radar is $f = 1.3~\mathrm{GHz}$ and the receive gain is $G_r(\theta) = 24.3~\mathrm{dB}$, what is the effective aperture area, $A_e(\theta)$?

```python
qz.quiz_2_1_4b()
```

```python
# Scratch space
```

**(c)** What is the radar cross section, $\sigma$ , of a target at range $r = 10~\mathrm{km}$ away from a radar with transmit energy of $\mathcal{E}_t = \mathrm{30~J}$, transmit frequency $f = 1.5~\mathrm{GHz}$, and a transmit and receive gain of $G_t(\theta) = G_r(\theta) = 40~\mathrm{dB}$ if the received energy is $\mathcal{E}_r = 10~\mathrm{pJ}$?

```python
qz.quiz_2_1_4c()
```

```python
# Scratch space
```

***

### Average Noise Energy

Fortunately, average noise energy, $\mathcal{E}_n$ , is much easier to derive than the received energy, $\mathcal{E}_r$ . Radar system designs commonly model the aggregate noise due to multiple sources as arising from a single thermal source. In this case, the level of noise in a radar system is completely described by a **system noise temperature**, $T_s$. The higher the noise temperature, the stronger the noise in the system. More specifically, the noise energy term is defined as:

$$
\mathcal{E}_n = kT_s
$$

where $k$ is the Boltzmann constant $1.38064852 \times 10^{-23}~\mathrm{J/^\circ K}$, $T_s$ is the system noise temperature ($^\circ\mathrm{K}$). Note that you can use the Boltzmann constant in your calculations as `k`.

***

### Question 5

For a radar with system noise temperature $T_s = 722~ ^\circ\mathrm{K}$, what is the average noise energy, $\mathcal{E}_n$?

```python
qz.quiz_2_1_5()
```

```python
# Scratch space
```

***

### Radar Signal-to-Noise Ratio

Taking both $\mathcal{E}_r$ and $\mathcal{E}_n$, we can now derive the **signal-to-noise ratio form** of the **radar range equation**:

$$
\mathrm{SNR} = \frac{\mathcal{E}_r}{\mathcal{E}_n} = \frac{\mathcal{E}_t G_t(\theta) G_r(\theta)\lambda^2\sigma}{(4\pi)^3 r^4 k T_s}
$$

Traditionally, you may see a loss term $L$ included in the denominator, where $L$ is a unitless term that represents total system loss, which is comprised of atmospheric loss, signal processing loss, transmit loss, and many other real-world factors.

In the interactive example below, we can study how the signal-to-noise ratio varies with radar parameters:

```python
ex.ex_2_1_7()
```

***

### Question 6

What is the signal-to-noise ratio from a target echo with a target at range $r = 200~\mathrm{km}$ and RCS $\sigma = -5~\mathrm{dBsm}$ when using a radar with transmit energy of $\mathcal{E}_t = 50~\mathrm{J}$, transmit and receive gain of $G_t(\theta) = G_r(\theta) = 35~\mathrm{dB}$, system noise temperature $T_s = 750^\circ K$, and transmit frequency $f = 5~\mathrm{GHz}$?

```python
qz.quiz_2_1_6()
```

```python
# Scratch space
```

***

Returning to the beginning of this lab, we can study the general problem of detection of an echo with varying radar parameters. In the following example, we will see the echo against a noise background. As the parameters of the radar are varied, we can watch the evolution of the noise energy, signal energy, and the signal-to-noise ratio.

```python
ex.ex_2_1_8()
```

## Reference SNR

As we can see from the signal-to-noise ratio form of the radar range equation, there are quite a few radar variables to keep track of:

- Transmit energy, $\mathcal{E}_t$
- Transmit gain, $G_t(\theta)$
- Receive gain, $G_r(\theta)$
- Transmit wavelength, $\lambda$
- System noise temperature, $T_s$

Instead of keeping all of these values at the ready, a radar system is often summarized by a **reference SNR**, which assumes a predefined transmit wavelength and maximum gain values. A reference SNR is often in the following form: SNR of $\mathrm{SNR}_0$ on a target with RCS $\sigma_0$ at range $r_0$. For instance, a radar could have achieve an SNR of $\mathrm{SNR}_0 = 15~\mathrm{dB}$ on a target with RCS $\sigma_0 = -5~\mathrm{dBsm}$ at range $r_0 = 100~\mathrm{km}$.

The main advantage of knowing the reference SNR is that is can be quickly converted to other target ranges and radar cross sections. More specifically, the SNR of a target with RCS $\sigma$ at range $r$ is:

$$
\mathrm{SNR} = \mathrm{SNR}_0 \cdot \left(\frac{r_0}{r}\right)^4 \cdot \left(\frac{\sigma}{\sigma_0}\right)
$$

So, if we know $\mathrm{SNR}_0$ , $\sigma_0$ , and $r_0$ , we can quickly calculate the SNR value for other targets and ranges.

***

### Question 7

If a radar achieves a signal-to-noise ratio of $\mathrm{SNR}_0 = 17~\mathrm{dB}$ for a target at $r_0 = 75~\mathrm{km}$ with radar cross section $\sigma_0 = -10~\mathrm{dBsm}$, what is the signal-to-noise ratio for the same radar with a target at range $r = 50~\mathrm{km}$ and radar cross section $\sigma = -15~\mathrm{dBsm}$?

```python
qz.quiz_2_1_7()
```

```python
# Scratch space
```

***

## Summary

In this lab, we learned the intuitive connection between the ability to confidently detect the presence of a target echo and its *signal-to-noise ratio* (SNR). Then, we derived the form of the signal-to-noise ratio for a radar system using two applications of the *Friis transmission equation*. This creates three useful forms of the *radar range equation*: *received power*, *received energy*, and *signal-to-noise ratio*. These quantities were then investigated for a dish radar system with adjustable parameters. Finally, we introduced the convenient notion of a *reference SNR* that can be used to summarize a radar's performance and allow for quick calculation for other targets and ranges.

## Footnotes

1This is the common definition for signals with a limited time duration; for signals that are infinitely long, the terms on top and bottom will be replaced by power instead of energy.

2Electromagnetic waves are typically described using their electric field strength $E(r, t)$ where $r$ is range and $t$ is time. To convert to power density at a specific point, we can use the formula:

$$
P(x, t) = \frac{|E(r, t)|^2}{\eta}
$$

where $\eta = 367.73~\Omega$ is the natural impedance of free space.

## References

[1] H. Friis, "A note on a simple transmission formula", *Proceedings of the IRE*, vol. 34, no. 5, pp. 254-256, May 1946.