From 9d8496be4cf2719c3dd7ca2a4b4de91ad4abeeb3 Mon Sep 17 00:00:00 2001 From: Blaise Thompson Date: Fri, 30 Mar 2018 13:54:43 -0500 Subject: 2018-03-30 13:54 --- acquisition/chapter.tex | 153 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 137 insertions(+), 16 deletions(-) (limited to 'acquisition/chapter.tex') 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} % ------------------------------------------------------------------- -- cgit v1.2.3