diff options
-rw-r--r-- | acquisition/chapter.tex | 70 | ||||
-rw-r--r-- | acquisition/quad.png | bin | 132067 -> 156161 bytes | |||
-rw-r--r-- | acquisition/quad.py | 23 | ||||
-rw-r--r-- | todo.org | 1 |
4 files changed, 74 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 Binary files differindex 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) @@ -25,6 +25,7 @@ ** TODO figure ** TODO arguments * TODO insert content :PbSe: +* TODO headers :introduction: * TODO cite important CMDS discoveries, reviews :introduction: * TODO summarize PbSe chapter :introduction: * TODO summarize MX2 chapter :introduction: |