Online Data Processing for Streamline HT-XRPD ============================================= Fully automated powder diffraction (data acquisition and processing). Usage ----- .. code-block:: python DEMO_SESSION [1]: from blissoda.demo.streamline_scanner import streamline_scanner,sample_changer DEMO_SESSION [2]: streamline_scanner.eject() DEMO_SESSION [3]: streamline_scanner.load() DEMO_SESSION [4]: streamline_scanner.calib(0.1, sample_index=3) DEMO_SESSION [5]: streamline_scanner.run(0.1, nholders=None, current_holder=False, sample_indices=None) The arguments of `calib` and `run` are the same as `sct` with some additional keyword arguments. When `streamline_scanner.optimize_exposure_per` is set to `"sample"` or `"baguette"` the exposure time provided is the maximally allowed exposure time, the actual exposure time might be shorter. If the active workflow requires calibration, a calibration scan must be performed before calling run(). The calibration is done by selecting one specific sample `sample_index`. The automated `run`` is done on either - the currently loaded holder - N holders from the loading tray - all holders from the loading tray Installation ------------ Worker (data processing) ++++++++++++++++++++++++ Install an Ewoks worker with the following dependencies: .. code-block:: bash pip install ewoksjob[blissworker] pip install ewoksxrpd Bliss (acquisition control) +++++++++++++++++++++++++++ Add ewoks configuration to beacon. Dependencies installed in the bliss environment .. code-block:: bash pip install blissoda[streamline] Install and configure the `streamline sample changer `_. Add this to the bliss session setup script that needs the streamline scanner .. code-block:: python from blissoda.streamline.streamline_scanner import StreamlineScanner as _StreamlineScanner streamline_scanner = _StreamlineScanner() Control flow diagram -------------------- Experiment-level control flow for measuring samples automatically with data processing. .. code-block:: python DEMO_SESSION [5]: streamline_scanner.run(0.1, nholders=None, current_holder=False, sample_indices=None) .. mermaid:: flowchart TD %% Start of experiment START[run] --> CALREQ{Workflow needs calibration} CALREQ -- yes --> CALOK{Calibration available} CALOK -- yes --> ENABLE CALREQ -- no --> ENABLE ENABLE[Enable vibration and translation] ENABLE --> MODE{Current holder} %% Current holder path MODE -- yes --> LOAD1[Load holder] LOAD1 --> RH1[Run holder] %% Loop holders path MODE -- no --> LOOP1{Remaining holders or last holder?} LOOP1 -- yes --> EJ1[Eject holder] EJ1 --> LD1[Load holder] LD1 --> RH2[Run holder] RH2 --> LOOP1 LOOP1 -- no --> EJLAST[Eject last holder] Per-holder execution: each sample in the holder is measured automatically. Base scanner ++++++++++++ .. mermaid:: flowchart TD RUN[Run holder] --> MV_SAMPLE MV_SAMPLE["Move to sample"] --> MEASURE MEASURE["Bliss sct command"] --> DATAPROC DATAPROC["Data processing"] --> MV_SAMPLE ID31 scanner ++++++++++++ .. mermaid:: flowchart TD RUN[Run holder] --> MV_SAMPLE MV_SAMPLE["Move to sample"] --> ROCKIT ROCKIT["Rock sample / move motor"] --> EXP_OPT EXP_OPT["Exposure optimization"] --> DECIDE{"Optimize exposure per?"} DECIDE -->|None| USEGIVEN DECIDE -->|Baguette| OPT_BAGUETTE DECIDE -->|Sample| HASQR{"Has QR code?"} HASQR -->|No| USEGIVEN HASQR -->|Yes| OPT_SAMPLE USEGIVEN["Use given exposure"] --> SHOPEN OPT_BAGUETTE["Optimize exposure (ascan)"] --> OPT OPT_SAMPLE["Optimize exposure (ct)"] --> OPT OPT["Use optimized exposure"] --> SHOPEN SHOPEN[ID31 open shutter] --> MEASURE MEASURE["Bliss sct command"] --> RESULT{"Result"} RESULT -->|Success| DATAPROC RESULT -->|Pilatus protection error| DATAPROC DATAPROC["Data processing"] --> MV_SAMPLE SES-lab scanner +++++++++++++++ .. mermaid:: flowchart TD RUN[Run holder] --> MV_SAMPLE MV_SAMPLE["Move to sample"] --> MEASURE MEASURE["Do nothing"] --> MV_SAMPLE