aboutsummaryrefslogtreecommitdiff
path: root/acquisition
diff options
context:
space:
mode:
authorBlaise Thompson <blaise@untzag.com>2018-04-11 09:46:30 -0500
committerBlaise Thompson <blaise@untzag.com>2018-04-11 09:46:30 -0500
commite3fb4a515856d3f6561baad09f5c5a2e088e4e37 (patch)
treed2e7af38e505ade7b05a47c0213c1b86772abf1b /acquisition
parent9163f09b69769c0ec52adf337785fd700ace005d (diff)
2018-04-11 09:46
Diffstat (limited to 'acquisition')
-rw-r--r--acquisition/chapter.tex70
-rw-r--r--acquisition/quad.pngbin132067 -> 156161 bytes
-rw-r--r--acquisition/quad.py23
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.png
index 3b1c7f6..ea933da 100644
--- a/acquisition/quad.png
+++ b/acquisition/quad.png
Binary files differ
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)