diff options
Diffstat (limited to 'acquisition')
| -rw-r--r-- | acquisition/chapter.tex | 70 | ||||
| -rw-r--r-- | acquisition/quad.png | bin | 132067 -> 156161 bytes | |||
| -rw-r--r-- | acquisition/quad.py | 23 | 
3 files changed, 73 insertions, 20 deletions
| diff --git a/acquisition/chapter.tex b/acquisition/chapter.tex index 803049e..df1c887 100644 --- a/acquisition/chapter.tex +++ b/acquisition/chapter.tex @@ -740,13 +740,63 @@ a signal that causes \python{queue.on_action_complete} to be called.  %  If there are more enqueued acquisitions, and \python{queue_status.go} is true, the \python{queue}
  instance pushes the next operation to the \python{worker} and the process starts over again.  %
 +The queue manager is capable of more than just acquisitions.  %
 +For example, users can enqueue a wait operation that simply pauses PyCMDS for a certain amount of
 +time or until some condition is met.  %
 +
 +Those who wish to learn more can refer to \bash{PyCMDS/somatic/queue.py}.  %
 +
  \subsection{Scans}  % -----------------------------------------------------------------------------
 -The central loop of scans in PyCMDS.  %
 +Every single scan within PyCMDS is handled by one method of one class, \python{Worker.scan}
 +from the file \bash{PyCMDS/somatic/acquisition.py}.  %
 +This method understands how to any scan that PyCMDS can do: any stepwise multidimensional scan with
 +separate hardware and sensors.  %
 +
 +The central scan method requires acquisition modules to provide all of the axes (instances of
 +\python{PyCMDS.somatic.acquisition.Axis}) that need to be broadcast across each-other.  %
 +Then something very simple happens.  %
 +For each hardware that will move during the scan, a destinations object (instance of
 +\python{PyCMDS.somatic.acquisition.Destinations}) is created.  %
 +This object has the same shape as the full multidimensional scan, and contains the destination for
 +that hardware for that pixel in the scan.  %
 +Then, a \bash{.data} file is created to accept the data that is about to be collected.  %
 +A bunch of signals go off, telling PyCMDS that it needs to yield to somatic control.  %
 +Then PyCMDS simply sits in a loop generated by \python{numpy.ndindex} [CITE] and visits each pixel
 +in turn.  %
 +\python{ndindex} is a n-dimensional iterator over a given array shape.  %
 +Written simply, it does the following:
 +\begin{codefragment}{python}
 +def ndindex(shape):
 +    rs = [range(s) for s in shape]  
 +    pools = map(tuple, rs)
 +    result = [[]]
 +    for pool in pools:
 +        result = [x+[y] for x in result for y in pool]
 +    for prod in result:
 +        yield tuple(prod)
 +\end{codefragment}
 +So that when evaluated:
 +\begin{codefragment}{python}
 +>>> for idx in ndindex((4, 3, 2)): print idx
 +(0, 0, 0)
 +(0, 0, 1)
 +(0, 1, 0)
 +(0, 1, 1)
 +(0, 2, 0)
 +(0, 2, 1)
 +(1, 0, 0)
 +...
 +(3, 2, 0)
 +(3, 2, 1)
 +\end{codefragment}
 +
 +This simple algorithm is used to visit each pixel in the entire PyCMDS scan space.  %
 +At each pixel, something much like the following happens.  %
  \begin{codefragment}{python, label=aqn:lst:loop_simple}
 -for coordinates in list_of_coordinates:
 -  for hardware, coordinate in zip(hardwares, coordinates):
 -      hardware.set(coordinate)
 +for idx in ndindex(shape):
 +  for hardware in hardwares::
 +      hardware.set(idx)
    for hardware in hardwares:
        hardware.wait_until_still()
    for sensor in sensors:
 @@ -754,6 +804,8 @@ for coordinates in list_of_coordinates:    for sensor in sensors:
        sensor.wait_until_done() 
  \end{codefragment}
 +The pattern is simple: launch hardware, wait for still, launch sensors, wait for done.  %
 +The simplicity of this central loop truly shows the power of abstraction in PyCMDS.  %
  \subsection{Acquisition modules}  % ---------------------------------------------------------------
 @@ -799,16 +851,6 @@ Automatically do appropriate scans and process as in chapter...  Dedicated to poynting (get content from Kyle S)...
 -\subsection{The data file}  % ---------------------------------------------------------------------
 -
 -Does not have the same dimensionality restrictions as prior acquisition software.  %
 -
 -Self describing (enabled by \python{tidy_headers}).
 -
 -\subsection{Automatic processing}  % --------------------------------------------------------------
 -
 -For scan module, just
 -
  \clearpage
  \section{Conditional validity}  % =================================================================
 diff --git a/acquisition/quad.png b/acquisition/quad.pngBinary files differ index 3b1c7f6..ea933da 100644 --- a/acquisition/quad.png +++ b/acquisition/quad.png diff --git a/acquisition/quad.py b/acquisition/quad.py index d6519e5..ee5fab9 100644 --- a/acquisition/quad.py +++ b/acquisition/quad.py @@ -21,19 +21,30 @@ here = os.path.abspath(os.path.dirname(__file__))  fig, gs = wt.artists.create_figure(width='double')  ax = plt.subplot(gs[0, 0]) -ax.set_xlim(-1.1, 1.1) -ax.set_ylim(-1.1, 1.1) - -ax.arrow(-1, 0, 2, 0, lw=5, head_width=0.1) -ax.arrow(0, -1, 0, 2, lw=5, head_width=0.1) +ax.set_xlim(0, 1.25) +ax.set_ylim(0, 1.25)  es = {} -es['MR-CMDS'] = (-0.5, 0.5) +es['MR-CMDS'] = (1, 0.3) +es['AFM'] = (0.5, 0.4) +es['GRAPES'] = (0.1, 1) +es['FTIR'] = (0.1, 0.1) +es['z-scan'] = (0.1, 0.2) +es['UV-VIS'] = (0.1, 0.3) +es['TRPL'] = (0.1, 0.4) +es['NMR'] = (0.1, 0.5) + +  for label, coordinates in es.items():      ax.text(*coordinates, label, fontsize=20) +# decoration +xlabel = r'hardware complexity $\rightarrow$' +ylabel = r'measurement complexity $\rightarrow$' +wt.artists.set_ax_labels(xlabel=xlabel, ylabel=ylabel, xticks=False, yticks=False) +  # save  p = os.path.join(here, 'quad.png')  wt.artists.savefig(p) | 
