def Gas_Plan(gas_in='He', liveplot_key=None, totExpTime=5, num_exp=1, delay=1):
    """
    Execute it
    ----------
    >> %run -i /home/xf28id2/Documents/Sanjit/Scripts/GasXrun_Plan.py
    >> change all the parameters inside Gas_Plan as required
    >>> gas_plan = Gas_Plan(gas_in = 'He', liveplot_key= 'rga_mass1', totExpTime = 5, num_exp = 3, delay = 1)
    >> to run the xrun, save metadata & save_tiff run the following
    >>> run_and_save(sample_num = 0)

    Example
    -------
    Set the gasses. They can be in any other, nothing to do with
    the order they are used in the plan. But, should match the connections on switch.
    >>> gas.gas_list = ['He', 'N2', 'CO2']
    >>> RGA mass is set to different value, base shows 1^-13 with He 5 cc flow shows max 2^-8
    >>> RGA mass setup in mID mode: 4,18,28,31,44,79,94,32,81
    Parameters
    ----------
    gas_in : string
        e.g., 'He', default is 'He'
        These gas must be in `gas.gas_list` but they may be in any order.
    liveplot_key : str, optional
        e. g., liveplot_key = rga_mass1
        data key for LivePlot. default is None, which means no LivePlot
    totExpTime : float
        total exposure time per frame in seconds. Dafault value is 5 sec
    num_exp : int
        number of images/exposure, default is 1
    delay: float
        delay time between exposures in sec

    """

    ## switch gas
    yield from abs_set(gas, gas_in)

    ## configure the exposure time first
    _configure_area_det(totExpTime)  # 5 secs exposuretime

    ## ScanPlan you need
    plan = bp.count([pe1c, gas.current_gas, rga], num=num_exp, delay=delay)

    #plan = bpp.subs_wrapper(plan, LiveTable([xpd_configuration['area_det'], rga]))   # give you LiveTable
    plan = bpp.subs_wrapper(
        plan, LiveTable([xpd_configuration['area_det'], gas.current_gas, rga]))
    if liveplot_key and isinstance(liveplot_key, str):
        plan = bpp.subs_wrapper(plan, LivePlot(liveplot_key))

    yield from plan
Esempio n. 2
0
def gas_plan_with_detector(
        gas_in,
        rga_masses=['mass1', 'mass2', 'mass3', 'mass4', 'mass5', 'mass6'],
        det=pe1c,
        exp_time=5,
        num_exp=1,
        delay=1):
    """
    Example:

    >>> RE(gas_plan(gas_in='He', masses_to_plot=['mass4', 'mass6']))
    ----------

    Parameters
    ----------
    gas_in : string
        e.g., 'He', default is 'He'
        These gas must be in `gas.gas_list` but they may be in any order.
    rga_masses: list, optional
        a list of rga masses appearing in a live table
    det : ophyd obj, optional
        detector to use
    exp_time : float, optional
        exposure time in seconds
    num_exp : integer, optional
        number of exposures
    delay : float, optional
        delay between exposures in seconds
    """
    print('Warning: check the gas list!')

    for i in range(1, 9 + 1):
        getattr(rga, f'mass{i}').kind = 'normal'

    for m in rga_masses:
        getattr(rga, m).kind = 'hinted'

    det.stats1.kind = 'hinted'
    det.stats1.total.kind = 'hinted'

    ## switch gas
    yield from bps.mv(gas, gas_in)

    # configure the exposure time first
    _configure_area_det(exp_time)  # secs of exposure time

    ## ScanPlan you need
    yield from bp.count([gas.current_gas, rga, det], num=num_exp, delay=delay)
Esempio n. 3
0
def acq_rel_grid_scan(
    dets: list,
    exposure: float,
    wait: float,
    start0: float, stop0: float, num0: int,
    start1: float, stop1: float, num1: int
):
    """Make a plan of two dimensional grid scan."""
    area_det = xpd_configuration["area_det"]
    x_controller = xpd_configuration["x_controller"]
    y_controller = xpd_configuration["y_controller"]

    def per_step(detectors, step: dict, pos_cache):
        """ customized step to ensure shutter is open before
        reading at each motor point and close shutter after reading
        """
        yield from bps.checkpoint()
        for motor, pos in step.items():
            yield from bps.mv(motor, pos)
        yield from bps.sleep(wait)
        yield from open_shutter_stub()
        yield from bps.sleep(glbl["shutter_sleep"])
        yield from bps.trigger_and_read(list(detectors) + list(step.keys()))
        yield from close_shutter_stub()

    plan = bp.rel_grid_scan(
        [area_det],
        x_controller, start0, stop0, num0,
        y_controller, start1, stop1, num1,
        snake_axes=True,
        per_step=per_step
    )
    yield from _configure_area_det(exposure)
    yield from plan
Esempio n. 4
0
def config_det_and_count(motors: List[object], sample_md: dict, exposure: float):
    """
    Take one reading from area detector with given exposure time and motors. Save the motor reading results in
    the start document.

    Parameters
    ----------
    motors : List[float]
        A list of readable motors.
    sample_md
        The metadata of the sample.
    exposure
        The exposure time in seconds.

    Yields
    -------
        Message to configure the detector and run the scan.

    """
    # setting up area_detector
    _md = {}
    num_frame, acq_time, computed_exposure = yield from _configure_area_det(exposure)
    area_det = xpd_configuration["area_det"]
    # update md
    _md.update(**sample_md)
    plan_md = {
        "sp_time_per_frame": acq_time,
        "sp_num_frames": num_frame,
        "sp_requested_exposure": exposure,
        "sp_computed_exposure": computed_exposure,
        "sp_type": "cryostat",
        "sp_uid": str(uuid.uuid4()),
        "sp_plan_name": "cryostat"
    }
    _md.update(**plan_md)
    motor_md = {motor.name: dict(motor.read()) for motor in motors}
    _md.update(**motor_md)
    # yield plan
    dets = [area_det] + motors
    plan = count(dets, md=_md)
    plan = subs_wrapper(plan, LiveTable([]))
    yield from plan
Esempio n. 5
0
    return num_frame, acq_time, computed_exposure


save_kwargs = {}

shutter = xpd_configuration["shutter"]
sh_open = glbl["shutter_conf"]["open"]
sh_close = glbl["shutter_conf"]["close"]
sample_motor = spinner_goniohead.X

# experimental info
Tstart, Tstop, numT = 5, 15, 3
# Tstart1, Tstop1, numT1 = 150, 300, 11
# Tstart, Tstop, numT = 11, 17, 3
det_z_pos1, det_z_pos2 = 1195, 1995
_configure_area_det(600)

# special dict for cryostat experiment
sample1_name, sample1_pos, sample1_expo, sample1_wait = (
    "Sample1",
    -10.44,
    600,
    20,
)  # CHANGE as needed!!!!!
sample2_name, sample2_pos, sample2_expo, sample2_wait = (
    "Sample2",
    -8.44,
    600,
    20,
)  # CHANGE as needed!!!!!
sample3_name, sample3_pos, sample3_expo, sample3_wait = (
def gridScan(dets,
             exp_spreadsheet_fn,
             glbl,
             xpd_configuration,
             XPD_SHUTTER_CONF,
             *,
             crossed=False,
             dx=None,
             dy=None,
             wait_time=5):
    """
    Scan plan for the multi-sample grid scan.

    This function takes in a templated excel spreadsheet and constructs a
    spatial scan plan. Single-shot  with total exposure specified in
    the ``Exposure time`` columns will be executed at the spatial
    points specified in the ``X-position`` and ``Y-position`` columns.
    A set of optional arguments ``crossed``, ``dx`` and ``dy``  can be
    passed so that 4 extra data will be collected with respect at each
    spatial point. An optional wait time between spatial points data can
    also be set to avoid residuals (ghost image). Please see
    ``Examples`` below.

    Parameters
    ----------
    dets : list
        A list of detectors will be triggered in the experiment.
        Note the first three detectors in the list must be in the order
        as "area detector, x-motor, y-motor".
    exp_spreadsheet_fn : str
        filename of the spreadsheet contains sample metadata in each
        well, locations, exposure times and all additional metadata.
        This spread MUST be placed inside ``xpdUser/Import``.
    crossed : bool, optional
        option if to perform a crossed scan in each well. If it's true,
        then at each well (x0, y0), 4 additional data will be collected
        at (x0-dx, y0), (x0+dx, y0), (x0, dy+y0), (x0, y0-dy). Default
        to False.
    dx : float, optional
        offset in x-direction for crossed scan per well. Must be
        a float if ``crossed`` is set to True. Default to None.
    dy : float, optional
        offset in y-direction for crossed scan per well. Must be
        a float if ``crossed`` is set to True. Default to None.
    wait_time : float, optional
        Wait time between each count, default is 5s

    Examples
    --------
    # define a list of detectors will be triggered in the spatial scan
    # plan. The first 3 detectors should be in the sequence of
    # "area_det, x-motor,  y-motor" used in the scan.
    dets = [pe1c, diff_x, diff_y, shctl1]

    # case 1
    # define a plan based on the information entered in the
    # spreadsheet ``wandaHY1_sample.xlsx``.
    # Note, this spreadsheet MUST be placed in the ``Import`` directory
    grid_plan = gridScan(dets,  'wandaHY1_sample.xlsx', wait_time=5)

    # preview the plan to check.
    summarize_plan(grid_plan)

    # redefine the scan plan again then execute the plan.
    grid_plan = gridScan(dets,  'wandaHY1_sample.xlsx', wait_time=5)
    uids = xrun(gridScan_sample, grid_plan)

    # case 2
    # define a grid scan that collects 4 extra points at each spatial
    # point to account for potential inhomogeneity
    grid_plan = gridScan(dets, 'wandaHY1_sample.xlsx', crossed=True,
                         dx=0.2, dy=0.1, wai_time=5)

    # preview the plan to check.
    summarize_plan(grid_plan)

    # redefine the scan plan again then execute the plan.
    grid_plan = gridScan(dets,  'wandaHY1_sample.xlsx', wait_time=5)
    uids = xrun(gridScan_sample, grid_plan)

    # finally, retrieve event information as a dataframe
    hdrs = db[-len(uids):]
    df = db.get_table(hdrs)
    # visualize the dataframe
    df
    # save the dataframe as a csv
    df.to_csv('wandaHY1_spatial_scan_df.csv')

    Notes
    -----
    1. ``gridScan_sample`` used in the example is in fact an empty
      dictionary (and it has been defined in this script as well).
      Sample metadata is handled inside the plan, therefore it's
      simply an auxiliary object.

    2. ``gridScan`` yields a generator so you would need to construct
      it every time after using it. As demonstrated in the Example,
      we redefine the ``grid_plan`` again after printing the summary.
      Similarly, if you wish to execute the same scan plan, you would
      have to repeat the syntax.
    """
    def count_dets(_dets, _full_md):
        _count_plan = bp.count(_dets, md=_full_md)
        _count_plan = bpp.subs_wrapper(_count_plan, LiveTable(_dets))
        _count_plan = bpp.finalize_wrapper(
            _count_plan,
            bps.abs_set(xpd_configuration['shutter'],
                        XPD_SHUTTER_CONF['close'],
                        wait=True))
        yield from bps.abs_set(xpd_configuration['shutter'],
                               XPD_SHUTTER_CONF['open'],
                               wait=True)
        yield from _count_plan

    # read exp spreadsheet
    spreadsheet_parser = ExceltoYaml(glbl['import_dir'])
    fp = os.path.join(spreadsheet_parser.src_dir, exp_spreadsheet_fn)
    spreadsheet_parser.pd_df = pd.read_excel(fp, skiprows=[1])
    spreadsheet_parser.parse_sample_md()
    # get detectors
    area_det = xpd_configuration['area_det']
    x_motor, y_motor = list(dets)[:2]
    dets = [area_det] + dets
    # compute Nsteps
    _md = {
        'sp_time_per_frame': None,
        'sp_num_frames': None,
        'sp_requested_exposure': None,
        'sp_computed_exposure': None,
        'sp_type': 'gridScan',
        'sp_uid': str(uuid.uuid4())[:4],
        'sp_plan_name': 'gridScan'
    }
    # first validate through sa_md list
    for md_dict in spreadsheet_parser.parsed_sa_md_list:
        if not ('x-position' in md_dict and 'y-position' in md_dict
                and 'exposure_time(s)' in md_dict):
            raise xpdAcqException("either X-position, Y-position "
                                  "or Exposure time column in {} "
                                  "row is missing. Please fill it "
                                  "and rerun".format(md_dict['sample_name']))
    # validate crossed scan
    if crossed and (not dx or not dy):
        raise xpdAcqException(
            "dx and dy must both be provided if crossed is set to True")
    # construct scan plan
    for md_dict in spreadsheet_parser.parsed_sa_md_list:
        expo = float(md_dict['exposure_time(s)'])
        # setting up area_detector
        yield from _configure_area_det(expo)
        expo_md = calc_expo_md(dets[0], expo)
        # inject md for each sample
        full_md = dict(_md)
        full_md.update(expo_md)
        full_md.update(md_dict)
        # Manually open shutter before collecting. See the reason
        # stated below.
        # main plan
        x_center = float(md_dict['x-position'])
        y_center = float(md_dict['y-position'])
        yield from bps.mv(x_motor, x_center)
        yield from bps.mv(y_motor, y_center)
        yield from count_dets(dets, full_md)  # no crossed
        if crossed:
            x_traj = [-dx + x_center, x_center + dx, x_center, x_center]
            y_traj = [y_center, y_center, y_center + dy, y_center - dy]
            for x_setpoint, y_setpoint in zip(x_traj, y_traj):
                yield from bps.mv(x_motor, x_setpoint)
                yield from bps.mv(y_motor, y_setpoint)
                full_md['x-position'] = x_setpoint
                full_md['y-position'] = y_setpoint
                yield from count_dets(dets, full_md)
        # use specified sleep time -> avoid residual from the calibrant
        yield from bps.sleep(wait_time)
Esempio n. 7
0
def Tramp_gas_plan(detectors,
                   gas_in,
                   exp_time,
                   Tstart,
                   Tstop,
                   Tstep,
                   rga_masses=default_mass_list):
    """
    Tramp-type scan with rga gas reading

    Parameters
    ----------
    detectors: list
        List of detectors will be triggered and recored.
    gas_in : string
        e.g., 'He', default is 'He'
        These gas must be in `gas.gas_list` but they may be in any order.
    exp_time : float, optional
        exposure time in seconds
    Tstart : float
        starting point of temperature sequence.
    Tstop : float
        stoping point of temperature sequence.
    Tstep : float
        step size between Tstart and Tstop of this sequence.
    rga_masses: list, optional
        a list of rga masses will be appearing in a live table

    Example:
    --------
    >>> plan = Tramp_gas_plan([pe1c, rga], 'He', 5, 300, 350, 5)
    >>> xrun(<sample ind>, plan)
    """
    ## configure hints on gas device
    configure_gas_mass_hint(rga_masses)

    ## switch gas
    yield from set_gas(gas_in)

    # configure the exposure time first
    (num_frame, acq_time,
     computed_exposure) = yield from _configure_area_det(exp_time)
    (Nsteps, computed_step_size) = _nstep(Tstart, Tstop, Tstep)
    area_det = xpd_configuration['area_det']
    temp_controller = xpd_configuration['temp_controller']
    xpdacq_md = {
        'sp_time_per_frame': acq_time,
        'sp_num_frames': num_frame,
        'sp_requested_exposure': exp_time,
        'sp_computed_exposure': computed_exposure,
        'sp_type': 'Tramp',
        'sp_startingT': Tstart,
        'sp_endingT': Tstop,
        'sp_requested_Tstep': Tstep,
        'sp_computed_Tstep': computed_step_size,
        'sp_Nsteps': Nsteps,
        'sp_plan_name': 'Tramp'
    }
    plan = bp.scan(detectors,
                   temp_controller,
                   Tstart,
                   Tstop,
                   Nsteps,
                   per_step=shutter_step,
                   md=xpdacq_md)
    plan = bpp.subs_wrapper(plan, LiveTable(detectors))
    yield from plan
Esempio n. 8
0
def tseries_gas_plan(detectors,
                     gas_in,
                     exp_time,
                     delay=1,
                     num_exp=1,
                     rga_masses=default_mass_list):
    """
    tseries-type scan with rga gas reading

    Parameters
    ----------
    detectors: list
        List of detectors will be triggered and recored.
    gas_in : string
        e.g., 'He', default is 'He'
        These gas must be in `gas.gas_list` but they may be in any order.
    exp_time : float, optional
        exposure time in seconds
    num_exp : integer, optional
        number of exposures
    delay : float, optional
        delay between exposures in seconds
    rga_masses: list, optional
        a list of rga masses appearing in a live table

    Example:
    >>> plan = tseries_gas_plan([pe1c, rga], 'He', 5, 10, 2)
    >>> xrun(<sample ind>, plan)
    """
    ## configure hints on gas device
    configure_gas_mass_hint(rga_masses)

    ## switch gas
    yield from set_gas(gas_in)

    # configure the exposure time first
    (num_frame, acq_time,
     computed_exposure) = yield from _configure_area_det(exp_time)
    real_delay = max(0, delay - computed_exposure)
    period = max(computed_exposure, real_delay + computed_exposure)
    print('INFO: requested delay = {}s  -> computed delay = {}s'.format(
        delay, real_delay))
    print('INFO: nominal period (neglecting readout overheads) of {} s'.format(
        period))
    xpdacq_md = {
        'sp_time_per_frame': acq_time,
        'sp_num_frames': num_frame,
        'sp_requested_exposure': exp_time,
        'sp_computed_exposure': computed_exposure,
        'sp_plan_name': 'tseries'
    }

    plan = bp.count(detectors, num_exp, delay, md=xpdacq_md)
    plan = bpp.subs_wrapper(plan, LiveTable(detectors))

    def inner_shutter_control(msg):
        if msg.command == 'trigger':

            def inner():
                yield from open_shutter_stub()
                yield msg

            return inner(), None
        elif msg.command == 'save':
            return None, close_shutter_stub()
        else:
            return None, None

    plan = bpp.plan_mutator(plan, inner_shutter_control)
    yield from plan
Esempio n. 9
0
def Tramp3(dets: list, wait: float, exposure: float, Tstart: float, Tstop: float, Tstep: float):
    """
    Collect data over a range of temperatures

    This plan sets the sample temperature using a temp_controller device
    and exposes a detector for a set time at each temperature.
    It also has logic for equilibrating the temperature before each
    acquisition. By default it closes the fast shutter at XPD in between
    exposures. This behavior may be overridden, leaving the fast shutter
    open for the entire scan. Please see below.

    Parameters
    ----------
    dets : list
        list of 'readable' objects. default to the temperature
        controller and area detector linked to xpdAcq.

    wait : float
        Time to wait at each temperature point.

    exposure : float
        exposure time at each temperature step in seconds.

    Tstart : float
        starting point of temperature sequence.

    Tstop : float
        stoping point of temperature sequence.

    Tstep : float
        step size between Tstart and Tstop of this sequence.

    Notes
    -----
    1. To see which area detector and temperature controller
    will be used, type the following commands:

        >>> xpd_configuration['area_det']
        >>> xpd_configuration['temp_controller']

    2. To change the default behavior to shutter-always-open,
    please pass the argument for ``per_step`` in the ``ScanPlan``
    definition, as follows:

        >>> ScanPlan(bt, Tramp, 10, 5, 300, 250, 10, per_step=None)

    This will create a ``Tramp`` ScanPlan, with shutter always
    open during the ramping.
    """
    area_det = xpd_configuration["area_det"]
    temp_controller = xpd_configuration["temp_controller"]
    Nsteps, _ = _nstep(Tstart, Tstop, Tstep)

    def per_step(detectors, motor, step):
        """ customized step to ensure shutter is open before
        reading at each motor point and close shutter after reading
        """
        yield from bps.checkpoint()
        yield from bps.abs_set(motor, step, wait=True)
        yield from bps.sleep(wait)
        yield from open_shutter_stub()
        yield from bps.sleep(glbl["shutter_sleep"])
        yield from bps.trigger_and_read(list(detectors) + [motor])
        yield from close_shutter_stub()

    plan = bp.scan(
        [area_det],
        temp_controller,
        Tstart,
        Tstop,
        Nsteps,
        per_step=per_step
    )
    yield from _configure_area_det(exposure)
    yield from plan