aboutsummaryrefslogtreecommitdiff
path: root/acquisition/chapter.tex
diff options
context:
space:
mode:
Diffstat (limited to 'acquisition/chapter.tex')
-rw-r--r--acquisition/chapter.tex141
1 files changed, 138 insertions, 3 deletions
diff --git a/acquisition/chapter.tex b/acquisition/chapter.tex
index 1525b9e..863bf96 100644
--- a/acquisition/chapter.tex
+++ b/acquisition/chapter.tex
@@ -56,6 +56,8 @@ Besides the extendable modular pieces, the rest of PyCMDS is a mostly-static cod
modules and does the necessary things to handle display of information from, and communication
between them. %
+\subsection{Multithreading} % --------------------------------------------------------------------
+
For the kinds of acquisitions that the Wright Group has done the acquisition software spends the
vast majority of its run-time waiting---waiting for user input through mouse clicks or keyboard
presses, waiting for hardware to finish moving or for sensors to finish reading and return
@@ -72,7 +74,7 @@ acquisition requires. %
Threads are powerful because they allow for ``semi-synchronous'' operation. %
Imagine PyCMDS is in the middle of a 2D delay-delay scan, and the scan thread has just told each of
-the two delay stages to head to their positions. %
+the two delay stages to head to their destinations. %
PyCMDS must sit in a tight loop to keep track of the position as closely as possible during motor
motion. %
In a single-threaded configuration, this tight loop would only run for one delay at a time, such
@@ -84,12 +86,102 @@ This switching is handled in an OS and hardware specific way---luckily it is all
platform-agnostic Qt threads. %
Threads are dangerous because it is hard to pass information between them. %
-Thus, mutexes... signals and slots...
+Without any special protection, two threads have no reason not to simultaneously edit and read the
+same location in memory. %
+If a delay stage is writing its position to memory as a 64-bit double at the same time as the
+acquisition thread reads that memory address, the acquisition thread will read in nonsense (or
+worse), it will crash). %
+So some strategy is needed to ensure that threads respect each other. %
+The Mutex design allows threads to ``lock'' an object such that it cannot be modified by a
+different thread. %
+This lock is like the ``talking stick'' employed my many early child educators. %
+When the talking stick is being used, only the child that holds the stick is allowed to speak. %
+The stick must be passed to another child (as directed by the teacher) before they can share their
+thought. %
+PyCMDS makes heavy use of Mutexes, in particular the \bash{QMutex} class \cite{QMutex}. %
+
+Mutexes handle basic information transfer (two threads can both safely modify and read a particular
+object), but what about sending instructions between threads? %
+Here the problem is deciding what happens when multiple instructions are given simultaneously, or
+an instruction is given while another instruction is being carried out. %
+Again, this is a classic problem in computer science, and the classic answer is the queue. %
+Queues are just like lines at the coffee shop---each person (instruction) is served (carried out)
+in the order that they joined the line. %
+Queues are commonly referred to as FIFO (First In First Out) for this reason. %
+PyCMDS uses queues for almost all instructions. %
+
+Finally, PyCMDS makes extensive use of the ``signals and slots'' construct, which is somewhat
+unique (and certainly original) to Qt. %
+Signals and slots are powerful because they allow threads without instruction to go completely
+silent, making them essentially free in terms of CPU usage. %
+Normally, a thread needs to sit in a loop merely listening for instructions. %
+Within the Qt framework, a thread can be ``woken'' by a signal without needing that thread to
+explicitly ``listen''. %
+These concepts fit within the broader umbrella of ``event-driven programming'', a concept that has
+been used in many languages and frameworks (notably high level LabVIEW tends to be very
+event-driven). %
+The Qt signals and slots system massively simplifies programming within PyCMDS. %
+
+Note that multithreading is very different from multiprocessing. %
+
+\subsection{High level objects} % ----------------------------------------------------------------
+
+PyCMDS is made to be extended and developed by and for immature programmers, so it is crucial to
+create something that is less complicated...
+
+At it's most basic PyCMDS defines the following simple data types (derived from
+\python{PyCMDS_object}):
+\begin{ditemize}
+ \item Bool
+ \item Combo
+ \item Filepath
+ \item Number
+ \item String
+\end{ditemize}
+These classes do multiple things. %
+First, they \emph{are} Mutexes, with thread-safe \python{read} and \python{write} methods. %
+Secondly, they support ``implicit'' storage in ini files. %
+Third, they know how to participate in the GUI. %
+They can display their value, and if modified they will propagate that modification to the internal
+threads of outward...
+Finally, they have special properties like units and limits etc...
Without getting into details, let's investigate the key ``signals and slots'' that hardware and
sensors have. %
% TODO: elaborate
+The following is the top-level hardware class, parent of all hardware and sensors. %
+
+\begin{figure}
+ \includepython{"acquisition/parent_hardware.py"}
+ \caption[Parent to hardware and sensors.]{
+ Parent class of all hardware and sensors. %
+ For brevity, methods \python{close}, \python{update} and \python{wait_until_still} have been
+ omitted. %
+ }
+ \label{aqn:fig:parent_hardware_class}
+\end{figure}
+
+\begin{figure}
+ \includepython{"acquisition/driver.py"}
+ \caption[TODO]{
+ TODO
+ }
+ \label{aqn:fig:driver}
+\end{figure}
+
+\subsection{Graphical user interface} % ----------------------------------------------------------
+
+Made up of widgets...
+
+Table widget...
+
+Use of qt plots...
+
+pyqtgraph \cite{pyqtgraph}
+
+\subsection{Scans} % -----------------------------------------------------------------------------
+
The central loop of scans in PyCMDS. %
\begin{codefragment}{python, label=aqn:lst:loop_simple}
for coordinates in list_of_coordinates:
@@ -146,6 +238,45 @@ because indeed that is all that can be generalized. %
\section{Hardware} \label{aqn:sec:hardware} % ====================================================
+Hardware are things that 1) have a position, 2) can be set to a destination. %
+Typically they also have associated units and limits. %
+Each hardware can be thought of as a dimension of the MR-CMDS experiment, and scans include a
+specific traversal through this multidimensional space. %
+
+\subsection{Hardware inheritance} % --------------------------------------------------------------
+
+All hardware classes are children of the parent \python{Hardware} class, which is itself subclassed
+from the global \python{Hardware} class shown in \autoref{aqn:lst:parent_hardware}. %
+
+\begin{figure}
+ \includepython{"acquisition/hardware.py"}
+ \caption[Parent hardware class.]{
+ Parent class of all hardware. %
+ For brevity, methods \python{close}, \python{get_destination}, \python{get_position},
+ \python{is_valid}, \python{on_address_initialized}, \python{poll}, and \python{@property units}
+ have been omitted. %
+ }
+ \label{aqn:fig:hardware_class}
+\end{figure}
+
+
+\begin{figure}
+ \includebash{"acquisition/hardware_inheritance"}
+ \caption[Hardware inheritance.]{
+ }
+ \label{aqn:fig:hardware_inheritance}
+\end{figure}
+
+
+
+\subsection{Delays} % ----------------------------------------------------------------------------
+
+\subsection{Spectrometers} % ---------------------------------------------------------------------
+
+\subsection{OPAs} % ------------------------------------------------------------------------------
+
+\subsection{Filters} % ---------------------------------------------------------------------------
+
\section{Sensors (devices)} \label{aqn:sec:sensors} % ============================================
\subsection{Sensors as axes} % -------------------------------------------------------------------
@@ -292,4 +423,8 @@ S_n &=& (1-c)\left(\frac{n}{N}\right)^{\frac{\tau_{\mathrm{step}}}{\tau_{\mathrm
\subsection{Enhanced modularity} % ---------------------------------------------------------------
-\subsection{wt5 savefile} % ---------------------------------------------------------------------- \ No newline at end of file
+\subsection{wt5 savefile} % ----------------------------------------------------------------------
+
+\subsection{Hotswappable hardware} % -------------------------------------------------------------
+
+\subsection{Better logging and error handling} % ------------------------------------------------- \ No newline at end of file