aboutsummaryrefslogtreecommitdiff
path: root/acquisition
diff options
context:
space:
mode:
Diffstat (limited to 'acquisition')
-rw-r--r--acquisition/chapter.tex153
-rw-r--r--acquisition/hardware_inheritance1
2 files changed, 137 insertions, 17 deletions
diff --git a/acquisition/chapter.tex b/acquisition/chapter.tex
index 832e698..bd08edd 100644
--- a/acquisition/chapter.tex
+++ b/acquisition/chapter.tex
@@ -9,28 +9,99 @@
\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.
+MR-CMDS relies on a good number of instrumental capabilities. %
+Fundamentally, MR-CMDS is about delivering multiple pulses of light to a given sample. %
+The frequency and relative arrival time (delay) of each pulse must be scanned in the context of a
+basic multidimensional experiment. %
+Scanning frequency requires using motors to change crystal angles and other optics within Optical
+Parametric Amplifiers (OPAs). %
+Scanning delay typically involves moving mirrors very small distances such that the optical path
+length of certain beam-lines changes. %
+In addition to these ``first-order'' controls, the power of MR-CMDS is enhanced with additional
+control of pulse intensity and polarization. % TODO: citations to motivate this 'enhancement'
+Each of these is an optomechanical device. %
+An automated monchromator is typically used to spectrally resolve or isolate output signal. %
+
+An acquisition in MR-CMDS typically means going to a whole series of different positions. %
+As an example, a three-dimensional ``movie'' might be collected in the following way:
+\begin{codefragment}{python, label=aqn:lst:psuedoaqn}
+w1_points = [14300, 14400, 14500, 14600, 14700] # wn
+w2_points = [14100, 14200, 14300, 14400, 14500, 14600, 14700] # wn
+d2_points = [100, 75, 50, 25, 0, 50, 75, 100, 125, 150, 175, 200] # fs
+for w2 in w2_points:
+ set_w2(w2)
+ for w1 in w1_points:
+ set_w1(w1)
+ for d2 in d2_points:
+ set_d2(d2)
+ measure_signal()
+\end{codefragment}
+In this simple example, there are 5 \python{w1} destinations, 7 \phon{w2} destinations, and 12
+\python{d2} destinations, so there are a total of $5\times7\times12=420$ pixels in the
+three-dimensional scan. %
+The acquisition software must set the hardware to each of these points and acquire data at each of
+them. %
+Each hardware motion and signal measurement takes roughly one second, so this acquisition would
+take roughly 7 minutes to complete. %
+In practice, real scans are composed of $\sim$100 to $\sim$100,000 pixels, and take between 1
+minute and one day to acquire. %
+
+Because of the highly specialized nature of these experiments, MR-CMDS instruments typically
+require custom software to address all of simultaneous, repeated motor motion that a scan
+requires. %
+Because MR-CMDS is really a family of techniques which require different kinds of motor motion,
+this acqusition software should be flexable enough to meet the creativity of its users. %
+Furthermore, because MR-CMDS is a bleeding edge, rapidly evolving technique the instrumental
+software must be built in an extendable way to accommodate the ever-changing hardware
+configurations. %
+In this chapter I describe how I built such an acquisition software. %
\section{Overview} % =============================================================================
-PyCMDS has, through software improvements alone, dramatically lessened scan times...
+PyCMDS is a unified software for controlling hardware and collecting data in the Wright Group. %
+It is written almost entirely in Python, with a graphical user interface (GUI) made using Qt. %
+It is cross-platform, running on Linux, Windows and macOS. %
+It is open source, developed on GitHub. % TODO: cite PyCMDS on github
+PyCMDS is used to drive both of the MR-CMDS instruments maintained by the Wright Group: the ``fs
+table'', focused on semiconductor photophysics, and the ``ps table'', focused on molecular
+systems. %
+In the Wright Group, \gls{PyCMDS} replaces the old acquisition softwares `ps control', ritten by
+Kent Meyer and `Control for Lots of Research in Spectroscopy' written by Schuyler Kain.
-\begin{ditemize}
- \item simultaneous motor motion
- \item digital signal processing % TODO: reference section when it exists
- \item ideal axis positions \ref{acq:sec:ideal_axis_positions}
-\end{ditemize}
+When PyCMDS starts up, the GUI is constructed out of modules depending on which hardware and
+sensors the user has instructed the program to address. %
+A screenshot of the PyCMDS GUI, running on the fs table, is shown in
+\autoref{aqn:fig:pycmds_screenshot}. %
+On the left hand there is a single column displaying the current positions for all loaded
+hardware. %
+Users may enter new destinations and hit the ``SET'' button. %
+Positions have units, which are changeable through the pull-down menu next to the control and
+display. %
+Each hardware knows its own limits, displayed in a tool tip when hovering over the control. %
+Users cannot type values outside of hardware limits into the controls. %
+
+The large right-hand section is tabbed...
-% TODO: screenshot
+\begin{figure}
+ \caption{
+ TODO (PyCMDS screenshot, including limits in tool tip)
+ }
+ \label{aqn:fig:pycmds_screenshot}
+\end{figure}
-% TODO: modularity
+To perform an acquisition, a user goes to the SOMATIC tab and enters an item into the QUEUE...
-% TODO: n-dimensional scans...
+During the acquisition...
+Progress bar...
+Cannot hit SET...
+QUEUE states...
-% TODO: calibration
+\begin{figure}
+ \caption{
+ TODO (PyCMDS screenshot while acquiring a 2D delay scan)
+ }
+ \label{aqn:fig:pycmds_screenshot_during_scan}
+\end{figure}
\section{Structure} % ============================================================================
@@ -124,8 +195,56 @@ 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...
+Towards the goal of stability and extensability, PyCMDS makes heavy use of abstraction and
+inheritance. %
+
+Abstraction means that complex implementation details are hidden by simple interfaces. %
+For example, consider the simple case of setting an OPA to a particular color. %
+For OPAs in the Wright Group, this operation requires the following:
+\begin{ditemize}
+ \item Load the OPA tuning curve, find which motors must move.
+ \item Interpolate the discrete tuning curve, and evaluate that interpolated curve at the desired
+ destination.
+ \item Send each motor towards their new destination.
+ \item Wait for the motors to arrive, check that nothing has gone wrong.
+\end{ditemize}
+This is not even to mention the complexity of spawning and sending information between the main
+thread and working threads. %
+Through abstraction, PyCMDS is able to wrap all this complexity into the \python{OPA} class and
+it's \python{set_position} method---so doing all of the operations above is as simple as
+\python{opa.set_position(1300, 'nm')}. %
+Importantly, abstraction does not magically get rid of the complexity. %
+It simply \emph{hides} the complexity so that it becomes tractable to write simple interfaces to
+accomplish complex things. %
+
+PyCMDS implements abstraction through inheritance. %
+In object oriented programming, inheritance is when one class is based on another. %
+The \emph{child} class acquires all of the properties of the \emph{parent} class. %
+The child class, then, can modify or extend the properties that it needs, without needing to
+re-implement the properties that it shares with the parent. %
+Let's consider PyCMDS hardware again. %
+Every single unique hardware in PyCMDS lives in it's own worker thread, so the basic problem of
+information transfer through queues and Mutexes is shared between them. %
+A \python{Hardware} class which is parent to \emph{all} hardwares can define the methods and
+attributes necessary to abstract this basic thread communication issue. %
+Every type of delay stage addressed by PyCMDS needs to handle the basic task of translating between
+``natural'' units (femtosecond, picosecond, nanosecond) and ``native'' units (typically mm). %
+They all need an attribute \python{zero_position}, in native units, and a method to do the
+conversion. %
+A class common to all delay stages can abstract away all of these conversion details. %
+In summary, an inheritance-based system for implementing delay stages might look like this:
+\begin{codefragment}{bash}
+Hardware # implements basic thread control
+└── Delay # implements conversion between natural and native units
+ ├── Homemade
+ ├── Thorlabs
+ └── Newport
+\end{codefragment}
+The powerful thing about this strategy is that the three driver-specific classes (...) need only
+implement minimal driver-specific code, typically start, set close...
+This means that code is more maintainable and less buggy...
+Easier to change high-level behavior without redoing low-level code...
+Only implemented once...
At it's most basic PyCMDS defines the following simple data types (derived from
\python{PyCMDS_object}):
@@ -336,6 +455,8 @@ For DAQ cards, shots and samples...
Power of digital processing...
+Old boxcar: 300 ns window, ~10 micosecond delay. Onset of saturation ~2 V.
+
% TODO: screenshots
\subsection{Sensors as axes} % -------------------------------------------------------------------
diff --git a/acquisition/hardware_inheritance b/acquisition/hardware_inheritance
index 0a13a1b..3504a8c 100644
--- a/acquisition/hardware_inheritance
+++ b/acquisition/hardware_inheritance
@@ -3,7 +3,6 @@ Hardware
│ ├── Aerotech
│ ├── LTS300
│ ├── MFA
-│ ├── MFA
│ └── PMC
├── Filter
│ └── Homebuilt