aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--acknowledgements.tex43
-rw-r--r--acquisition/chapter.tex133
-rwxr-xr-xbuild.sh6
-rw-r--r--dissertation.cls23
-rw-r--r--dissertation.pdfbin34306781 -> 34312642 bytes
-rw-r--r--dissertation.syg6
-rw-r--r--dissertation.tex29
-rw-r--r--opa/chapter.tex16
-rw-r--r--processing/chapter.tex127
-rw-r--r--software/chapter.tex16
-rw-r--r--spectroscopy/chapter.tex14
11 files changed, 297 insertions, 116 deletions
diff --git a/acknowledgements.tex b/acknowledgements.tex
new file mode 100644
index 0000000..374153f
--- /dev/null
+++ b/acknowledgements.tex
@@ -0,0 +1,43 @@
+\chapter*{Acknowledgments}
+\addcontentsline{toc}{chapter}{Acknowledgments}
+
+\singlespacing
+
+To John...
+
+To my colleagues...
+
+To Tyler....
+
+To Claire...
+
+To Sam...
+
+To my parents...
+
+Finally, thank you to all humans who have and continue to undertake the ongoing free and
+responsible search for truth and meaning. %
+Thanks to free software / free culture / open science advocates who have worked to create
+and share foundational tools and ideas, often at great personal opportunity cost. %
+Thanks to thought leaders who have shown me what it means to have a good life without fully
+abandoning moral principles. %
+And thank you to those who bravely speak truth to power. %
+This universe is stranger, more terrible, and more fantastic than we want to believe. %
+We must find ways to describe it's complexity without falling victim to the sometimes-overwhelming
+power of simple, ``useful'' narratives. %
+
+\begin{dquote}
+ The explanatory stories that people find compelling are simple; are concrete rather
+ than abstract; assign a larger role to talent, stupidity and intentions than to luck; and focus
+ on a few striking events that happened rather than on the countless events that failed to
+ happen.
+
+ The ultimate test of an explanation is whether it would have made the event
+ predictable in advance.
+
+ Paradoxically, it is easier to construct a coherent story when you know little,
+ when there are fewer pieces to fit into the puzzle. Our comforting conviction that the world
+ makes sense rests on a secure foundation: our almost unlimited ability to ignore our ignorance.
+
+ \dsignature{Daniel Kahneman \cite{KahnemanDaniel2013a}}
+\end{dquote} \ No newline at end of file
diff --git a/acquisition/chapter.tex b/acquisition/chapter.tex
index f94f2ec..7fe8760 100644
--- a/acquisition/chapter.tex
+++ b/acquisition/chapter.tex
@@ -1,3 +1,134 @@
\chapter{Acquistion}
-Details of acquisition software. % \ No newline at end of file
+% TODO: cool quote, if I can think of one
+
+\clearpage
+
+In the Wright Group, \gls{PyCMDS} replaces the old acquisition softwares `ps control', written by
+Kent Meyer and `Control for Lots of Research in Spectroscopy' written by Schuyler Kain.
+
+PyCMDS directly addresses the hardware during experiments.
+
+\section{Overview} % =============================================================================
+
+PyCMDS has, through software improvements alone, dramatically lessened scan times...
+
+\begin{itemize}[topsep=-1.5ex, itemsep=0ex, partopsep=0ex, parsep=0ex, label=$\rightarrow$]
+ \item simultaneous motor motion
+ \item digital signal processing % TODO: reference section when it exists
+ \item ideal axis positions \ref{sec:ideal_axis_positions}
+\end{itemize}
+
+\section{Future directions} % ====================================================================
+
+\subsection{Ideal Axis Positions}\label{sec:ideal_axis_positions} % ------------------------------
+
+Frequency domain multidimensional spectroscopy is a time-intensive process. %
+A typical \gls{pixel} takes between one-half second and three seconds to acquire. %
+Depending on the exact hardware being scanned and signal being detected, this time may be mostly
+due to hardware motion or signal collection. %
+Due to the \gls{curse of dimensionality}, a typical three-dimensional CMDS experiment contains
+roughly 100,000 pixels. %
+CMDS hardware is transiently-reliable, so speeding up experiments is a crucial component of
+unlocking ever larger dimensionalities and higher resolutions. %
+
+One obvious way to decrease the scan-time is to take fewer pixels. %
+Traditionally, multidimensional scans are done with linearly arranged points in each axis---this is
+the simplest configuration to program into the acquisition software. %
+Because signal features are often sparse or slowly varying (especially so in high-dimensional
+scans) linear stepping means that \emph{most of the collected pixels} are duplicates or simply
+noise. %
+A more intelligent choice of axis points can capture the same nonlinear spectrum in a fraction of
+the total pixel count. %
+
+An ideal distribution of pixels is linearized in \emph{signal}, not coordinate. %
+This means that every signal level (think of a contour in the N-dimensional case) has roughly the
+same number of pixels defining it. %
+If some generic multidimensional signal goes between 0 and 1, one would want roughly 10\% of the
+pixels to be between 0.9 and 1.0, 10\% between 0.8 and 0.9 and so on. %
+If the signal is sparse in the space explored (imagine a narrow two-dimensional Lorentzian in the
+center of a large 2D-Frequency scan) this would place the majority of the pixels near the narrow
+peak feature(s), with only a few of them defining the large (in axis space) low-signal floor. %
+In contrast linear stepping would allocate the vast majority of the pixels in the low-signal 0.0 to
+0.1 region, with only a few being used to capture the narrow peak feature. %
+Of course, linearizing pixels in signal requires prior expectations about the shape of the
+multidimensional signal---linear stepping is still an appropriate choice for low-resolution
+``survey'' scans. %
+
+CMDS scans often posses correlated features in the multidimensional space. %
+In order to capture such features as cheaply as possible, one would want to define regions of
+increased pixel density along the correlated (diagonal) lineshape. %
+As a concession to reasonable simplicity, our acquisition software (PyCMDS) assumes that all scans
+constitute a regular array with-respect-to the scanned axes. %
+We can acquire arbitrary points along each axis, but not for the multidimensional scan. %
+This means that we cannot achieve strictly ideal pixel distributions for arbitrary datasets. %
+Still, we can do much better than linear spacing.
+% TODO: refer to PyCMDS/WrightTools 'regularity' requirement when that section exists
+
+Almost all CMDS lineshapes (in frequency and delay) can be described using just a few lineshape
+functions:
+\begin{ditemize}
+ \item exponential
+ \item Gaussian
+ \item Lorentzian
+ \item bimolecular
+\end{ditemize}
+
+Exponential and bimolecular dynamics fall out of simple first and second-order kinetics (I will
+ignore higher-order kinetics here). %
+Gaussians come from our Gaussian pulse envelopes or from normally-distributed inhomogeneous
+broadening. %
+The measured line-shapes are actually convolutions of the above. %
+I will ignore the convolution except for a few illustrative special cases. %
+More exotic lineshapes are possible in CMDS---quantum beating and breathing modes, for example---I
+will also ignore these. %
+Derivations of the ideal pixel positions for each of these lineshapes appear below.
+% TODO: cite Wright Group quantum beating paper, Kambempati breathing paper
+
+\subsection{Exponential}
+
+Simple exponential decays are typically used to describe population and coherence-level dynamics in
+CMDS. %
+For some generic exponential signal $S$ with time constant $\tau$,
+\begin{equation} \label{eq:simple_exponential_decay}
+S(t) = \me^{-\frac{t}{\tau}}.
+\end{equation}
+We can write the conjugate equation to \ref{eq:simple_exponential_decay}, asking ``what $t$ do I
+need to get a cerain signal level?'':
+\begin{eqnarray}
+\log{(S)} &=& -\frac{t}{\tau} \\
+t &=& -\taulog{(S)}.
+\end{eqnarray}
+So to step linearly in $t$, my step size has to go as $-\tau\log{(S)}$.
+
+We want to go linearly in signal, meaning that we want to divide $S$ into even sections. %
+If $S$ goes from 0 to 1 and we choose to acquire $N$ points,
+\begin{eqnarray}
+t_n &=& -\tau\log{\left(\frac{n}{N}\right)}.
+\end{eqnarray}
+Note that $t_n$ starts at long times and approaches zero delay. %
+So the first $t_1$ is the smallest signal and $t_N$ is the largest. %
+
+Now we can start to consider realistic cases, like where $\tau$ is not quite known and where some
+other longer dynamics persist (manifested as a static offset). %
+Since these values are not separable in a general system, I'll keep $S$ normalized between 0 and
+1. %
+\begin{eqnarray}
+S &=& (1-c)\me^{-\frac{t}{\tau_{\mathrm{actual}}}} + c \\
+S_n &=& (1-c)\me^{-\frac{-\tau_{\mathrm{step}}\log{\left(\frac{n}{N}\right)}}{\tau_{\mathrm{actual}}}} + c \\
+S_n &=& (1-c)\me^{-\frac{\tau_{\mathrm{step}}}{\tau_{\mathrm{actual}}} \log{\left(\frac{N}{n}\right)}} + c \\
+S_n &=& (1-c)\left(\frac{N}{n}\right)^{-\frac{\tau_{\mathrm{step}}}{\tau_{\mathrm{actual}}}} + c \\
+S_n &=& (1-c)\left(\frac{n}{N}\right)^{\frac{\tau_{\mathrm{step}}}{\tau_{\mathrm{actual}}}} + c
+\end{eqnarray}
+
+\begin{dfigure}[p!]
+ \includegraphics[scale=0.5]{"processing/PyCMDS/ideal axis positions/exponential"}
+ \caption[TODO]{TODO}
+ \label{fig:exponential_steps}
+\end{dfigure}
+
+\subsubsection{Gaussian}
+
+\subsubsection{Lorentzian}
+
+\subsubsection{Bimolecular} \ No newline at end of file
diff --git a/build.sh b/build.sh
index f0e9ce8..f098933 100755
--- a/build.sh
+++ b/build.sh
@@ -48,10 +48,10 @@ fi
if [[ "$1" = "all" ]] || [[ "$1" = "dissertation" ]] ; then
printLine
printColor documents
- pdflatex --interaction=nonstopmode dissertation
+ pdflatex --interaction=errorstopmode --shell-escape dissertation
bibtex dissertation
- pdflatex --interaction=nonstopmode dissertation
- pdflatex --interaction=nonstopmode dissertation
+ pdflatex --interaction=nonstopmode --shell-escape dissertation
+ pdflatex --interaction=nonstopmode --shell-escape dissertation
fi
printColor finished
diff --git a/dissertation.cls b/dissertation.cls
index 9452608..f850af5 100644
--- a/dissertation.cls
+++ b/dissertation.cls
@@ -39,6 +39,16 @@
\RequirePackage{etoolbox}
\AtBeginEnvironment{verse}{\singlespacing}
+\newenvironment{dquote}
+ {
+ \singlespacing
+ \it
+ }
+ {
+ }
+
+\newcommand{\dsignature}[1]{\hfill \normalfont{-- #1}}
+
% THE FOLLOWING IS DARK MAGIC THAT I DON'T UNDERSTAND
% I'M SURE I COULD DO BETTER...
% - Blaise 2018-03-06
@@ -67,9 +77,13 @@
% --- code environment ----------------------------------------------------------------------------
-% \RequirePackage{minted}
-\definecolor{light-gray}{gray}{0.90}
-\newcommand{\code}[1]{\colorbox{light-gray}{\texttt{#1}}}
+\RequirePackage{etoolbox}
+\RequirePackage{minted}
+\fvset{bgcolor=red}
+\usemintedstyle{colorful}
+\BeforeBeginEnvironment{minted}{\begin{singlespace}}
+\AfterEndEnvironment{minted}{\end{singlespace}}
+\newmint{python}
% --- tables --------------------------------------------------------------------------------------
@@ -81,7 +95,8 @@
}
{
\end{table}
- \clearpage}
+ \clearpage
+ }
% --- graphics ------------------------------------------------------------------------------------
diff --git a/dissertation.pdf b/dissertation.pdf
index 1865381..cdcb31d 100644
--- a/dissertation.pdf
+++ b/dissertation.pdf
Binary files differ
diff --git a/dissertation.syg b/dissertation.syg
index a878406..dc35a96 100644
--- a/dissertation.syg
+++ b/dissertation.syg
@@ -1,3 +1,3 @@
-\glossaryentry{\ensuremath {N}?\glossentry{N}|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{\ensuremath {N}?\glossentry{N}|setentrycounter[]{page}\glsnumberformat}{8}
-\glossaryentry{\ensuremath {\omega }?\glossentry{omega}|setentrycounter[]{page}\glsnumberformat}{36}
+\glossaryentry{\ensuremath {N}?\glossentry{N}|setentrycounter[]{page}\glsnumberformat}{10}
+\glossaryentry{\ensuremath {N}?\glossentry{N}|setentrycounter[]{page}\glsnumberformat}{10}
+\glossaryentry{\ensuremath {\omega }?\glossentry{omega}|setentrycounter[]{page}\glsnumberformat}{40}
diff --git a/dissertation.tex b/dissertation.tex
index f80fafe..d6df71d 100644
--- a/dissertation.tex
+++ b/dissertation.tex
@@ -47,40 +47,13 @@ This dissertation is approved by the following members of the Final Oral Committ
% ACKNOWLEDGEMENTS
\cleardoublepage
-\chapter*{Acknowledgments}
-\addcontentsline{toc}{chapter}{Acknowledgments}
+\include{acknowledgements}
% ABSTRACT
\cleardoublepage
\chapter*{Abstract}
\addcontentsline{toc}{chapter}{Abstract}
-% QUOTE
-\pagenumbering{gobble}
-\cleardoublepage
-
-\setlength{\parskip}{\baselineskip}
-
-\vspace*{2 cm}
-
-\noindent \emph{The explanatory stories that people find compelling are simple; are concrete rather
- than abstract; assign a larger role to talent, stupidity and intentions than to luck; and focus
- on a few striking events that happened rather than on the countless events that failed to
- happen.}
-
-\noindent \emph{The ultimate test of an explanation is whether it would have made the event
- predictable in advance.}
-
-\noindent \emph{Paradoxically, it is easier to construct a coherent story when you know little,
- when there are fewer pieces to fit into the puzzle. Our comforting conviction that the world
- makes sense rests on a secure foundation: our almost unlimited ability to ignore our ignorance.}
-
-\hfill -- Daniel Kahneman \cite{KahnemanDaniel2013a}
-
-\cleardoublepage
-
-\pagebreak
-
\doublespacing % double spacing required for body of paper
\pagenumbering{arabic}
diff --git a/opa/chapter.tex b/opa/chapter.tex
index a83eac5..b92f62a 100644
--- a/opa/chapter.tex
+++ b/opa/chapter.tex
@@ -1,9 +1,17 @@
\chapter{A robust, fully automated algorithm to collect high quality OPA tuning curves}
-\textit{Principle design features of the new EVV 2DIR optical delivery system include the
- following: ... Pairs of motorized gimbal mount mirrors on each OPA to compensate beam pointing
- changes ... Automated calibration of OPAs, delay stages and motorized mounts.
- ---\textcite{DonaldsonPaulMurray2007a}} % page 313
+\begin{dquote}
+ Principle design features of the new EVV 2DIR optical delivery system include the following:
+ \begin{ditemize}
+ \item Pairs of motorized gimbal mount mirrors on each OPA to compensate beam pointing changes.
+ \item Automated calibration of OPAs, delay stages and motorized mounts.
+ \end{ditemize}
+
+ \dsignature{Paul Donaldson, ``Improving ... EVV 2DIR Spectroscopy'' (2007)
+ \cite{DonaldsonPaulMurray2007a}} % appears on page 313
+\end{dquote}
+
+\clearpage
This chapter pasted from publication...
diff --git a/processing/chapter.tex b/processing/chapter.tex
index b755fb0..9d50bac 100644
--- a/processing/chapter.tex
+++ b/processing/chapter.tex
@@ -1,95 +1,78 @@
\chapter{Processing}
-\section{Overview}
+% TODO: cool quote, if I can think of one
-In the Wright Group, \gls{PyCMDS} replaces the old acquisition softwares `ps control', written by Kent Meyer and `Control for Lots of Research in Spectroscopy' written by Schuyler Kain.
+From a data science perspective, CMDS has several unique challenges:
+\begin{ditemize}
+ \item Dimensionality of datasets can typically be greater than two, complicating
+ \textbf{representation}.
+ \item Shape and dimensionality change...
+ \item Data can be large (over one million points). % TODO: contextualize large (not BIG DATA)
+\end{ditemize}
+I have designed a software package that directly addresses these issues. %
-\section{WrightTools}
+WrightTools is a software package at the heart of all work in the Wright Group. %
-WrightTools is a software package at the heart of all work in the Wright Group.
+% TODO: more intro
-\section{PyCMDS}
+\section{Data object model} % ====================================================================
-PyCMDS directly addresses the hardware during experiments.
+WrightTools uses a programming strategy called object oriented programming (OOP). %
-\subsection{Overview}
+It contains a central data ``container'' that is capable of storing all of the information about
+each multidimensional (or one-dimensional) spectra. %
-PyCMDS has, through software improvements alone, dramatically lessened scan times...
+\subsubsection{Python interface} % ---------------------------------------------------------------
-\begin{itemize}[topsep=-1.5ex, itemsep=0ex, partopsep=0ex, parsep=0ex, label=$\rightarrow$]
- \item simultaneous motor motion
- \item digital signal processing % TODO: reference section when it exists
- \item ideal axis positions \ref{sec:ideal_axis_positions}
-\end{itemize}
+WrightTools is written in Python, and endeavors to have a ``pythonic'', explicit and ``natural''
+application programming interface (API). %
+To use WrightTools, simply import:
-\subsection{Ideal Axis Positions}\label{sec:ideal_axis_positions}
+\begin{minted}{python}
+import numpy as np
+
+def incmatrix(genl1,genl2):
+ m = len(genl1)
+ n = len(genl2)
+ M = None #to become the incidence matrix
+ VT = np.zeros((n*m,1), int) #dummy variable
+
+ #compute the bitwise xor matrix
+ M1 = bitxormatrix(genl1)
+ M2 = np.triu(bitxormatrix(genl2),1)
+
+ for i in range(m-1):
+ for j in range(i+1, m):
+ [r,c] = np.where(M2 == M1[i,j])
+ for k in range(len(r)):
+ VT[(i)*n + r[k]] = 1;
+ VT[(i)*n + c[k]] = 1;
+ VT[(j)*n + r[k]] = 1;
+ VT[(j)*n + c[k]] = 1;
+
+ if M is None:
+ M = np.copy(VT)
+ else:
+ M = np.concatenate((M, VT), 1)
+
+ VT = np.zeros((n*m,1), int)
+
+ return M
+\end{minted}
-Frequency domain multidimensional spectroscopy is a time-intensive process. A typical \gls{pixel} takes between one-half second and three seconds to acquire. Depending on the exact hardware being scanned and signal being detected, this time may be mostly due to hardware motion or signal collection. Due to the \gls{curse of dimensionality}, a typical three-dimensional CMDS experiment contains roughly 100,000 pixels. CMDS hardware is transiently-reliable, so speeding up experiments is a crucial component of unlocking ever larger dimensionalities and higher resolutions.
+\subsubsection{wt5 file format} % ----------------------------------------------------------------
-One obvious way to decrease the scan-time is to take fewer pixels. Traditionally, multidimensional scans are done with linearly arranged points in each axis---this is the simplest configuration to program into the acquisition software. Because signal features are often sparse or slowly varying (especially so in high-dimensional scans) linear stepping means that \emph{most of the collected pixels} are duplicates or simply noise. A more intelligent choice of axis points can capture the same nonlinear spectrum in a fraction of the total pixel count.
-An ideal distribution of pixels is linearized in \emph{signal}, not coordinate. This means that every signal level (think of a contour in the N-dimensional case) has roughly the same number of pixels defining it. If some generic multidimensional signal goes between 0 and 1, one would want roughly 10\% of the pixels to be between 0.9 and 1.0, 10\% between 0.8 and 0.9 and so on. If the signal is sparse in the space explored (imagine a narrow two-dimensional Lorentzian in the center of a large 2D-Frequency scan) this would place the majority of the pixels near the narrow peak feature(s), with only a few of them defining the large (in axis space) low-signal floor. In contrast linear stepping would allocate the vast majority of the pixels in the low-signal 0.0 to 0.1 region, with only a few being used to capture the narrow peak feature. Of course, linearizing pixels in signal requires prior expectations about the shape of the multidimensional signal---linear stepping is still an appropriate choice for low-resolution ``survey'' scans.
+\section{Artists} % ==============================================================================
-CMDS scans often posses correlated features in the multidimensional space. In order to capture such features as cheaply as possible, one would want to define regions of increased pixel density along the correlated (diagonal) lineshape. As a concession to reasonable simplicity, our acquisition software (PyCMDS) assumes that all scans constitute a regular array with-respect-to the scanned axes. We can acquire arbitrary points along each axis, but not for the multidimensional scan. This means that we cannot achieve strictly ideal pixel distributions for arbitrary datasets. Still, we can do much better than linear spacing. % TODO: refer to PyCMDS/WrightTools 'regularity' requirement when that section exists
-Almost all CMDS lineshapes (in frequency and delay) can be described using just a few lineshape functions:
-\begin{itemize}[topsep=-1.5ex, itemsep=0ex, partopsep=0ex, parsep=0ex, label=$\rightarrow$]
- \item exponential
- \item Gaussian
- \item Lorentzian
- \item bimolecular
-\end{itemize}
+\section{Fitting} % ==============================================================================
-Exponential and bimolecular dynamics fall out of simple first and second-order kinetics (I will ignore higher-order kinetics here). Gaussians come from our Gaussian pulse envelopes or from normally-distributed inhomogeneous broadening. The measured line-shapes are actually convolutions of the above. I will ignore the convolution except for a few illustrative special cases. More exotic lineshapes are possible in CMDS---quantum beating and breathing modes, for example---I will also ignore these. Derivations of the ideal pixel positions for each of these lineshapes appear below. %TODO: cite Wright Group quantum beating paper, Kambempati breathing paper
-\subsection{Exponential}
-Simple exponential decays are typically used to describe population and coherence-level dynamics in CMDS. For some generic exponential signal $S$ with time constant $\tau$,
+\section{Distribution and licensing} % ===========================================================
-\begin{equation} \label{eq:simple_exponential_decay}
-S(t) = \me^{-\frac{t}{\tau}}.
-\end{equation}
-We can write the conjugate equation to \ref{eq:simple_exponential_decay}, asking ``what $t$ do I need to get a certain signal level?'':
-\begin{eqnarray}
-\log{(S)} &=& -\frac{t}{\tau} \\
-t &=& -\tau\log{(S)}.
-\end{eqnarray}
-
-So to step linearly in $t$, my step size has to go as $-\tau\log{(S)}$.
-
-We want to go linearly in signal, meaning that we want to divide $S$ into even sections. If $S$ goes from 0 to 1 and we choose to acquire $N$ points,
-
-\begin{eqnarray}
-t_n &=& -\tau\log{\left(\frac{n}{N}\right)}.
-\end{eqnarray}
-
-Note that $t_n$ starts at long times and approaches zero delay. So the first $t_1$ is the smallest signal and $t_N$ is the largest.
-
-Now we can start to consider realistic cases, like where $\tau$ is not quite known and where some other longer dynamics persist (manifested as a static offset). Since these values are not separable in a general system, I'll keep $S$ normalized between 0 and 1.
-
-\begin{eqnarray}
-S &=& (1-c)\me^{-\frac{t}{\tau_{\mathrm{actual}}}} + c \\
-S_n &=& (1-c)\me^{-\frac{-\tau_{\mathrm{step}}\log{\left(\frac{n}{N}\right)}}{\tau_{\mathrm{actual}}}} + c \\
-S_n &=& (1-c)\me^{-\frac{\tau_{\mathrm{step}}}{\tau_{\mathrm{actual}}} \log{\left(\frac{N}{n}\right)}} + c \\
-S_n &=& (1-c)\left(\frac{N}{n}\right)^{-\frac{\tau_{\mathrm{step}}}{\tau_{\mathrm{actual}}}} + c \\
-S_n &=& (1-c)\left(\frac{n}{N}\right)^{\frac{\tau_{\mathrm{step}}}{\tau_{\mathrm{actual}}}} + c
-\end{eqnarray}
-
-\begin{dfigure}[p!]
- \includegraphics[scale=0.5]{"processing/PyCMDS/ideal axis positions/exponential"}
- \caption[TODO]{TODO}
- \label{fig:exponential_steps}
-\end{dfigure}
-
-\subsubsection{Gaussian}
-
-\subsubsection{Lorentzian}
-
-\subsubsection{Bimolecular}
-
-\section{WrightSim}
-
-WrightSim does simulations.
+\section{Future directions} % ==================================================================== \ No newline at end of file
diff --git a/software/chapter.tex b/software/chapter.tex
index f8ceff7..bcf8a41 100644
--- a/software/chapter.tex
+++ b/software/chapter.tex
@@ -1,4 +1,4 @@
-:w% TODO: add StoddenVictoria2016a (Enhancing reproducibility for computational methods)
+% TODO: add StoddenVictoria2016a (Enhancing reproducibility for computational methods)
% TODO: add MillmanKJarrod2011a (Python for Scientists and Engineers)
% TODO: add vanderWaltStefan2011a (The NumPy Array: A Structure for Efficient Numerical Computation)
% TODO: reference https://www.nsf.gov/pubs/2016/nsf16532/nsf16532.htm (Software Infrastructure for
@@ -7,6 +7,20 @@
\chapter{Software}
+\begin{dquote}
+ The following guidelines are to be used in the documentation of all software developed in the
+ Wright group for the IBM 9000 computer. %
+ These rules have arisen as a necessary consequence of the group's programming philosophy of writing
+ software in the form of units which can be readily shared among a number of programmers. %
+ The approach outlined here should help to avoid some of the confusion otherwise produced by several
+ persons simultaniously developing and modifying shared software. %
+
+ % Roger Carlson, Appendix 2.3, Software Development Guidelines
+ \dsignature{Roger Carlson, ``Software Development Guidelines'' (1988) \cite{CarlsonRogerJ1988a}}
+\end{dquote}
+
+\clearpage
+
Cutting-edge science increasingly relies on custom software. In their 2008 survey,
\textcite{HannayJoErskine2009a} demonstrated just how important software is to the modern
scientist. %
diff --git a/spectroscopy/chapter.tex b/spectroscopy/chapter.tex
index 21a233d..a301117 100644
--- a/spectroscopy/chapter.tex
+++ b/spectroscopy/chapter.tex
@@ -12,6 +12,20 @@
\chapter{Spectroscopy}
+\begin{dquote}
+ A hundred years ago, Auguste Comte, … a great philosopher, said that humans will never be able to
+ visit the stars, that we will never know what stars are made out of, that that's the one thing
+ that science will never ever understand, because they're so far away. %
+ And then, just a few years later, scientists took starlight, ran it through a prism, looked at
+ the rainbow coming from the starlight, and said: ``Hydrogen!'' %
+ Just a few years after this very rational, very reasonable, very scientific prediction was made,
+ that we'll never know what stars are made of. %
+
+ \dsignature{Michio Kaku}
+\end{dquote}
+
+\clearpage
+
In this chapter I lay out the foundations of spectroscopy.
\section{Light}