Measurements

The primary measurements for microscope.microscope.Microscope and microscope.susceptometer.SusceptometerMicroscope include

Capacitive touchdown

In a capacitive touchdown, we sweep the scanner z position (scanner.Scanner.position_z) and measure the cantilever capacitance via a capacitance bridge and the CAP_lockin. If there is a change in the slope of capacitance as a function of DAQ AO voltage above some prescribed threshold (e.g. 1 fF/V), a touchdown has been detected. The measurement parameters (usually loaded into an OrderedDict called tdc_params) for a capacitive touchdown are defined in the Measurement Configuration file as follows:

{
    "td_cap": {
        "fname": "td_cap",
        "dV": "0.1 V",
        "range": ["-9.5 V","9.5 V"],
        "channels": {
            "CAP": {
                "lockin": {
                    "name": "CAP",
                    "amplitude": "1 V",
                    "frequency": "6.281 kHz"
                },
                "label": "Capacitance",
                "gain": 1,
                "unit": "fF",
                "unit_latex": "fF"
            },
            "SUSCX": {
                "lockin": {
                    "name": "SUSC",
                    "amplitude": "1 V",
                    "frequency": "131.79 Hz"
                },
                "label": "Susceptibility",
                "gain": 10,
                "r_lead": "1 kOhm",
                "unit": "Phi0/A",
                "unit_latex": "$\\Phi_0$/A"
            },
            "SUSCY": {
                "lockin": {
                    "name": "SUSC"
                },
                "label": "Susceptibility (out of phase)",
                "gain": 10,
                "r_lead": "1 kOhm",
                "unit": "Phi0/A",
                "unit_latex": "$\\Phi_0$/A"
            }
        },
        "constants": {
            "max_slope": "0.8 fF/V",
            "max_delta_cap": "5 fF",
            "initial_cap":"0 pF",
            "nfitmin":10,
            "nwindow":30,
            "ntest":8,
            "wait_factor":2
        }
    }
}

The algorithm for performing a capacitive touchdown is as follows:

  1. Sweep scanner.position_z through tdc_params['range'] with DAQ voltage steps given by tdc_params['dV'] and use the DAQ to measure the X output of CAP_lockin. After each change in DAQ AO voltage, allow the lockin to settle for max(CAP_lockin.time_constant(), SUSC_lockin.time_constant()) * tdc_params['constants']['wait_factor'].

  2. If at any point the capacitance is greater than tdc_params['constants']['max_delta_cap'] (i.e. if the capacitance bridge is very unbalanced), or if the pre-touchdown slope is greater than tdc_params['constants']['max_slope'], something has gone wrong, so abort the touchdown.

  3. Once tdc_params['constants']['nwindow'] points have been acquired, partition the last tdc_params['constants']['nwindow'] points into two subsets (with the boundary not lying within tdc_params['constants']['nfitmin'] of either end of the window). For each allowed partition boundary point, fit a line to each of the two subsets, and select the boundary point that minimizes the RMS of the fit residuals.

  4. If the absolute value of the difference in slope between the two best-fit lines exceeds tdc_params['constants']['max_slope'], a touchdown has occurred.

  5. If a touchdown is detected, repeat the fitting routine in step 4 to find the touchdown point, and exit the loop.

  6. If no touchdown is detected over the whole tdc_params['range'], exit the loop.

The microscope.microscope.Microscope.td_cap() will break its qcodes.Loop if either scanner.Scanner.break_loop or scanner.Scanner.td_has_occurred is True. The former is set to True if: any of the safety limits are exceeded, the touchdown is interrupted by the user, or a touchdown is detected. The latter is only set to True if a touchdown is detected.

Note

Whenever scanner.Scanner.break_loop is set to True, the scanner will be retracted to the voltage prescribed by the microscope’s temperature mode ('LT' or 'RT').

Note

It is very important to find a low-noise regime for the capacitance measurment in order to avoid false touchdowns or not detecting a real touchdown. It seems the most effective knob to turn in order fix noise problems is CAP_lockin.frequency. In the Bluefors 3K system, scatter of < 1 fF is typical and acceptable.

Approaching the Sample

The initial approach of the sample is done by iteratively performing capacitive touchdowns and instruments.atto.AttocubeController.step() towards the sample in the z direction until a touchdown is detected. The basic flow of microscope.microscope.Microscope.approach() goes as follows:

Acquiring a Surface

In order to scan, we must know where the sample surface is. To acquire a surface, we perform capacitive touchdowns on a grid of x, y positions and fit a plane to the measured touchdown heights. The resulting fit coefficients are stored in the dictionary scanner.Scanner.metadata['plane'], which has keys 'x', 'y', and 'z'. The sample plane for given x and y grids is then given by:

coeffs = scanner.Scanner.metadata['plane']
sample_plane = x_grid * coeffs['x'] + y_grid * coeffs['y'] + coeffs['z']

This means that coeffs['x'] and coeffs['y'] are the x and y gradients of the sample plane in DAQ voltage units, and coeffs['z'] is the touchdown height at the origin [x_position, y_position] == [0, 0]. To scan, say, 0.5 V above the sample surface, the z-axis scan grid is simply sample_plane - 0.5.

Note

The sample topography (i.e. touchdown voltage vs. x,y voltage) and plane are saved in a .mat file, and can be loaded into the program using scanner.Scanner.load_surface().

Note

When you perform a touchdown at the origin [x_position, y_position] == [0, 0], scanner.Scanner.metadata['plane'] is automatically updated with the new touchdown voltage.

Note

This plane is trusted until the Attocubes are moved by atto.AttocubeController.step(), at which point atto.AttocubeController.surface_is_current is set to False, and you will not be able to scan until you’ve acquired a new plane or manually set atto.surface_is_current = True.

For samples that are not flat and therefore not well-approximated by a plane, there is the option to instead scan parallel to a surface formed by interpolating the touchdown points, by setting "surface_type": "surface" in the Measurement Configuration file. The scanner.Scanner.surface_interp object is an instance of scipy.interpolate.Rbf, which forms a radial basis function representation of multi-dimensional data (similar to spline interpolation, but more general). To see what the expected touchdown voltage at point x, y is, one can simply run scanner.Scanner.surface_interp(x,y).

Warning

Calculation of of the Rbf representation of the scan array (array of voltages to be written to the DAQ AOs during a scan) is very memory intensive. If the DAQ sampling rate is too high or the scan is too large or slow, you will get a MemoryError.

Warning

It is easy to introduce measurement artifacts when scanning an interpolated surface, particularly for measurements that are very sensitive to SQUID-sample separation (e.g. local susceptibility). You should only use this functionality if you can be reasonably sure you are not introducing artifacts.

Scanning

See also

plots.ScanPlot

Note

When measuring susceptibility while scanning, it is very important to choose the susceptibility lockin frequency and scan parameters such that each pixel corresponds to an integer number of lockin periods, so as to avoid beating/aliasing effects.

See Scan surface example for a demonstration of scanning a plane with a microscope.susceptometer.SusceptometerMicroscope.