Exemple #1
0
    def __init__(self, target_state=None):
        self.controller_name = "TipNet"
        IO.connect()
        self.scan_bias_voltage = -3.5

        self.improver = ImprovementController(person_name=self.controller_name)
        self.improver.saveloc = "/home/mltest1/tmp/pycharm_project_510/Data/ImprovementSessions2/"
        self.improver.reset(destroy_tip=False)

        self.observation_space = spaces.Box(low=0,
                                            high=1,
                                            shape=(17, ),
                                            dtype=np.float32)
        self.action_space = spaces.Discrete(24)

        self.target_state = target_state
Exemple #2
0
def view_channel_properties(channel_name):
    # TODO: Rewrite!
    def read_prop(obj, prop):
        out = getattr(obj, prop)()
        print(prop + ':', out)

    channel_props = ['Enable']
    clock_props = ['Enable', 'Period', 'Samples']
    experiment_props = [
        'Bricklet_Written', 'Name', 'Result_File_Name', 'Result_File_Path',
        'State'
    ]
    gap_voltage_control_props = ['Preamp_Range', 'Voltage']
    regulator_props = [
        'Enable_Z_Offset_Slew_Rate', 'Feedback_Loop_Enabled', 'Loop_Gain_1_I',
        'Loop_Gain_2_I', 'Preamp_Range_1', 'Preamp_Range_2', 'Setpoint_1',
        'Setpoint_2', 'Z_Offset', 'Z_Offset_Slew_Rate', 'Z_Out'
    ]
    view_props = ['Cycle_Count', 'Data_Size', 'Deliver_Data', 'Run_Count']
    xy_scanner_props = [
        'Angle', 'Area', 'Enable_Drift_Compensation', 'Lines', 'Offset',
        'Plane_X_Slope', 'Plane_Y_Slope', 'Points', 'Raster_Time',
        'Return_To_Stored_Position', 'Store_Current_Position',
        'Target_Position', 'Trigger_Execute_At_Target_Position',
        'XY_Position_Report', 'X_Drift', 'X_Retrace', 'X_Retrace_Trigger',
        'X_Trace_Trigger', 'Y_Drift', 'Y_Retrace', 'Y_Retrace_Trigger',
        'Y_Trace_Trigger'
    ]

    obj_names = [
        'channel', 'clock', 'experiment', 'gap_voltage_control', 'regulator',
        'view', 'xy_scanner', 'spectroscopy'
    ]
    IO.connect()
    IO.enable_channel(channel_name)
    for obj_name in obj_names:
        obj = getattr(mo, obj_name)
        print()
        print('Object ' + obj_name + ':')
        print('--------------------------------------------------------------')
        for prop in eval(obj_name + '_props'):
            read_prop(obj, prop)

    mo.mate.disconnect()
Exemple #3
0
def get_xy_scan(channel_name,
                x_direction,
                y_direction,
                num_lines='all',
                mode='new',
                return_filename=False):
    """
    Perform and get an xy scan

    Parameters
    ----------
    channel_name : str
        The channel to acquire from, e.g. Z, I, Aux1, Aux2
    x_direction : str
        Must be one of 'Forward', 'Backward', or 'Forward-Backward'
    y_direction : str
        Must be one of 'Up' or 'Up-Down'
    num_lines : int or str
        Number of lines to get. If an int, must be less than the number of lines in the scanner window.
        Default is 'all'
    mode : str, optional
        Must be one of ['new', 'pause', 'continue']. Default is 'new'
    return_filename : bool, optional
        If the full file name of the scan should be returned along with the data. Default is False

    Returns
    -------
    xydata : ndarray
        Max 4 dimensions (y_up/y_down, x_up/x_down, x, y). First two dimensions will only appear if
        y_direction is "Up-Down" and x_direction is "Forward-Backward" - will be missing as appropriate

    Examples
    --------
    >>> from nOmicron.microscope import IO
    >>> from nOmicron.utils.plotting import plot_xy
    >>> IO.connect()
    >>> xydata = get_xy_scan("Z", x_direction="Forward", y_direction="Up-Down")
    >>> plot_xy(xydata, pixel_scale=mo.xy_scanner.Width() * 1e9 / mo.xy_scanner.Points())
    >>> IO.disconnect()

    Warnings
    --------
    Quite often (but unreliably!), running this function will get Matrix into a state in which it will return one/two
    lines (unless play/pause is clicked manually) when operating manually. To restore this functionality, run
    utils.utils.restore_z_functionality() and restart your scan.
    """
    global scan_dir_x, scan_dir_y, line_count_y, view_count, tot_packets, xydata

    # Setup and parsing parameters
    allowed = ["new", "pause", "continue"]
    if mode not in allowed:
        raise ValueError(f"Mode must be one of {allowed}")

    if num_lines == 'all':
        num_lines = mo.xy_scanner.Lines()

    x_dir_dict = {"Forward": "Fw", "Backward": "Bw"}
    x_direction_strings = [
        x_dir_dict[x_dir] for x_dir in x_direction.split("-")
    ]
    y_direction_strings = y_direction.split("-")

    # Set triggers
    if x_direction == "Forward-Backward":
        mo.xy_scanner.X_Retrace(True)
    else:
        mo.xy_scanner.X_Retrace(False)

    if y_direction == "Up-Down":
        if num_lines != 'all' and num_lines != mo.xy_scanner.Lines(
        ):  # Force set lines instead?
            raise ValueError(
                "If scanning in both directions, num_lines cannot be set")
        mo.xy_scanner.Y_Retrace(True)
    else:
        mo.xy_scanner.Y_Retrace(False)

    # while not mo.xy_scanner.Enable_Scan():  # Enforce that we won't take data during relocation and confuse the CU
    #     print("waiting")
    #     sleep(0.1)

    # Set counters and pre-allocate
    view_count = [None, None]
    scan_dir_y = 0
    scan_dir_x = 1
    line_count_y = 0
    tot_packets = 0
    xydata = np.zeros((2, 2, num_lines, mo.xy_scanner.Points()))
    xydata[:] = np.nan

    def view_xy_callback():
        global scan_dir_x, scan_dir_y, line_count_y, view_count, tot_packets, xydata
        tot_packets += 1
        mo.tot_packets = tot_packets
        line_count_y += 1
        if x_direction == "Forward-Backward":
            scan_dir_x = int(not (bool(scan_dir_x)))
            line_count_y = line_count_y - scan_dir_x
        scan_dir_y = (line_count_y - 1) // num_lines

        data_size = mo.view.Data_Size()
        data_pts = np.array(mo.sample_data(data_size))

        xydata[scan_dir_y,
               int(not (bool(scan_dir_x))),
               (line_count_y - (num_lines * scan_dir_y)) - 1, :] = data_pts
        view_count = [mo.view.Run_Count(), mo.view.Cycle_Count()]

        pbar.update(1)
        # pbar.set_postfix({"Scanline": mo.view.Packet_Count()})
        # if tot_packets % 2 == 1:
        #     pbar.set_postfix({"Scanline": mo.view.Packet_Count()+1})

    # Enable channels
    for x_direction_string in x_direction_strings:
        IO.enable_channel(f"{channel_name}_{x_direction_string}")
        mo.view.Data(view_xy_callback)
        mo.allocate_sample_memory(mo.xy_scanner.Points())

    if mode == 'new':
        mo.experiment.start()
    elif mode == 'pause':
        mo.experiment.resume()
    else:
        pass

    # Get the data
    pbar = tqdm(total=num_lines * len(x_direction_strings) *
                len(y_direction_strings))
    while tot_packets < num_lines * len(x_direction_strings) * len(y_direction_strings) \
            and mo.mate.rc == mo.mate.rcs['RMT_SUCCESS']:
        mo.wait_for_event()

    if mode == 'new':
        mo.experiment.stop()
    elif mode == 'pause':
        mo.experiment.pause()
    else:
        pass

    # Pretty the output to make physical sense
    xydata = np.flip(xydata, axis=2)
    if len(x_direction_strings) != 2:
        xydata = xydata[:, 0, :, :]
    if len(y_direction_strings) != 2:
        xydata = xydata[0, :, :, :]
    np.squeeze(xydata)

    # Return nicely
    if return_filename:
        filename = f"{mo.experiment.Result_File_Path()}\\{mo.experiment.Result_File_Name()}--{mo.view.Run_Count()}_{mo.view.Cycle_Count()}.Z_mtrx"
        return xydata, filename
    else:
        return xydata
Exemple #4
0
    # Pretty the output to make physical sense
    xydata = np.flip(xydata, axis=2)
    if len(x_direction_strings) != 2:
        xydata = xydata[:, 0, :, :]
    if len(y_direction_strings) != 2:
        xydata = xydata[0, :, :, :]
    np.squeeze(xydata)

    # Return nicely
    if return_filename:
        filename = f"{mo.experiment.Result_File_Path()}\\{mo.experiment.Result_File_Name()}--{mo.view.Run_Count()}_{mo.view.Cycle_Count()}.Z_mtrx"
        return xydata, filename
    else:
        return xydata


if __name__ == "__main__":
    IO.connect()
    set_points_lines(128)
    xydata1 = get_xy_scan(channel_name="Z",
                          x_direction="Forward",
                          y_direction="Up",
                          num_lines=1)

    plot_xy(xydata1,
            view_count,
            pixel_scale=mo.xy_scanner.Width() * 1e9 / mo.xy_scanner.Points())

    mo.experiment.Result_File_Name()
Exemple #5
0
def get_continuous_signal(channel_name, sample_time, sample_points):
    """Acquire a continuous signal.

    Parameters
    -----------
    channel_name : str
        The continuous channel to view, e.g. I_t, Z_t, Df_t, Aux1_t
    sample_time : float
        The time to acquire in seconds
    sample_points : int
        The number of points to acquire

    Returns
    -------
    x_data : Numpy array
    y_data : Numpy array

    Examples
    --------
    Acquire 60 points of I(t) data over 0.1 seconds
    >>> from nOmicron.microscope import IO
    >>> from nOmicron.utils.plotting import plot_linear_signal
    >>> IO.connect()
    >>> t, I = get_continuous_signal("I(t)", 1e-1, 60)
    >>> plot_linear_signal(v, I, "I(V)")
    >>> IO.disconnect()

    Acquire 100 points of Z(t) data over 5 seconds
    >>> from nOmicron.microscope import IO
    >>> from nOmicron.utils.plotting import plot_linear_signal
    >>> IO.connect()
    >>> t, I = get_continuous_signal("Z(t)", 5, 100)
    >>> plot_linear_signal(v, I, "I(V)")
    >>> IO.disconnect()
    """

    global view_count, x_data, y_data
    x_data = y_data = None
    view_count = 0

    def view_continuous_callback():
        global view_count, x_data, y_data
        view_count += 1
        pbar.update(1)

        data_size = mo.view.Data_Size()
        period = mo.clock.Period()
        x_data = np.linspace(0, (data_size - 1) * period, data_size)
        y_data = np.array(mo.sample_data(data_size))

    IO.enable_channel(channel_name)
    IO.set_clock(sample_time, sample_points)

    mo.view.Data(view_continuous_callback)
    mo.allocate_sample_memory(sample_points)

    pbar = tqdm(total=1)
    while view_count < 1 and mo.mate.rc == mo.mate.rcs['RMT_SUCCESS']:
        mo.wait_for_event()
    mo.clock.Enable(False)
    mo.view.Data()

    IO.disable_channel()

    return x_data, y_data
Exemple #6
0
def get_point_spectra(channel_name,
                      target_position,
                      start_end,
                      sample_time,
                      sample_points,
                      repeats=1,
                      forward_back=True,
                      return_filename=False):
    """
    Go to a position and perform fixed point spectroscopy.

    Parameters
    ----------
    channel_name : str
        The channel to acquire from, e.g. I_V, Z_V, Aux2_V
    target_position : list
        [x, y] in the range -1,1. Can be converted from real nm units with utils.convert...
    start_end : tuple
        Start and end I/Z/Aux2
    sample_time : float
        The time to acquire in seconds
    sample_points : int
        The number of points to acquire
    repeats : int
        The number of repeat spectra to take for each point
    forward_back : bool
        Scan in both directions, or just one.
    return_filename : bool, optional
        If the full file name of the scan should be returned along with the data. Default is False

    Returns
    -------
    x_data : Numpy array
    y_data :
        If performing repeat spectra and:
            Scanning in both directions: list of list of Numpy arrays, where inner list is [0] forwards, [1] backwards
            Scanning in one direction: list of Numpy arrays
        If no repeat spectra and:
            Scanning in both directions: list of Numpy arrays, where list is [0] forwards, [1] backwards
            Scanning in one direction: single Numpy array

    Examples
    --------
    Acquire 60 points of I(V) data over 10 milliseconds, with tip placed in middle of scan window.
    >>> from nOmicron.microscope import IO
    >>> from nOmicron.utils.plotting import plot_linear_signal
    >>> IO.connect()
    >>> v, I = get_point_spectra("I(V)", start_end=[0, 1], target_position=[0, 0], ...
    >>>                   repeats=3, sample_points=50, sample_time=10e-3, forward_back=True)
    >>> plot_linear_signal(v, I, "I(V)")
    >>> IO.disconnect()
    """

    global view_count, view_name, x_data, y_data
    modes = {
        "V": 0,
        "Z": 1,
        "Varied Z": 2
    }  # Varied Z not fully supported yet!
    max_count = (repeats * (forward_back + 1))
    view_count = 0
    x_data = None
    y_data = []
    [y_data.append([None] * (bool(forward_back) + 1))
     for i in range(repeats)]  # Can't use [] ** repeats

    def view_spectroscopy_callback():
        global view_count, view_name, x_data, y_data
        pbar.update(1)
        view_count += 1
        view_name = [mo.view.Run_Count(), mo.view.Cycle_Count()]
        cycle_count = mo.view.Cycle_Count() - 1
        packet_count = mo.view.Packet_Count() - 1
        data_size = mo.view.Data_Size()
        x_data = np.linspace(start_end[0], start_end[1], data_size)
        y_data[cycle_count][packet_count] = np.array(
            mo.sample_data(data_size)) * 1e-9
        if packet_count == 1:
            y_data[cycle_count][packet_count] = np.flip(
                y_data[cycle_count][packet_count])

    # Set all the parameters
    IO.enable_channel(channel_name)
    mo.spectroscopy.Spectroscopy_Mode(modes[channel_name[-2]])
    getattr(mo.spectroscopy,
            f"Device_{modes[channel_name[-2]] + 1}_Points")(sample_points)
    getattr(mo.spectroscopy,
            f"Raster_Time_{modes[channel_name[-2]] + 1}")(sample_time)
    getattr(mo.spectroscopy,
            f"Device_{modes[channel_name[-2]] + 1}_Start")(start_end[0])
    getattr(mo.spectroscopy,
            f"Device_{modes[channel_name[-2]] + 1}_End")(start_end[1])
    getattr(mo.spectroscopy,
            f"Device_{modes[channel_name[-2]] + 1}_Repetitions")(repeats)
    getattr(mo.spectroscopy,
            f"Enable_Device_{modes[channel_name[-2]] + 1}_Ramp_Reversal")(
                forward_back)

    # Set up spec
    mo.xy_scanner.Store_Current_Position(True)
    mo.xy_scanner.Target_Position(target_position)
    mo.xy_scanner.Trigger_Execute_At_Target_Position(True)

    # Do it
    mo.xy_scanner.move()
    mo.allocate_sample_memory(sample_points)
    mo.view.Data(view_spectroscopy_callback)

    pbar = tqdm(total=max_count)
    while view_count < max_count and mo.mate.rc == mo.mate.rcs['RMT_SUCCESS']:
        mo.wait_for_event()
    mo.view.Data()

    # Return to normal
    mo.xy_scanner.Trigger_Execute_At_Target_Position(False)
    mo.xy_scanner.Return_To_Stored_Position(True)
    mo.xy_scanner.Store_Current_Position(False)
    IO.disable_channel()

    if not forward_back:
        y_data = [item[0] for item in y_data]
    if repeats == 1:
        y_data = y_data[0]

    if return_filename:
        filename = f"{mo.experiment.Result_File_Path()}\\{mo.experiment.Result_File_Name()}--{view_count[0]}_{view_count[1]}.{channel_name}_mtrx"
        return x_data, y_data, filename
    else:
        return x_data, y_data
Exemple #7
0
    mo.xy_scanner.Store_Current_Position(False)
    IO.disable_channel()

    if not forward_back:
        y_data = [item[0] for item in y_data]
    if repeats == 1:
        y_data = y_data[0]

    if return_filename:
        filename = f"{mo.experiment.Result_File_Path()}\\{mo.experiment.Result_File_Name()}--{view_count[0]}_{view_count[1]}.{channel_name}_mtrx"
        return x_data, y_data, filename
    else:
        return x_data, y_data


if __name__ == '__main__':
    from nOmicron.utils.plotting import plot_linear_signal
    IO.connect()
    t, I1 = get_continuous_signal("I(t)", sample_time=5, sample_points=50)

    # Do a fixed point spec
    v, I2 = get_point_spectra("I(V)",
                              start_end=(0.5, -0.5),
                              target_position=[0, 0.5],
                              repeats=4,
                              sample_points=100,
                              sample_time=20e-3,
                              forward_back=True)
    plot_linear_signal(v, I2, "I(V)")
    IO.disconnect()