Пример #1
0
def cscan(dev, *args, **kwargs):
    """Scan around a center.

    This command is a specialisation of the `scan()` command to scan around a
    center a number of points left from the center and the same number right
    from the center with a certain step size.

    The command takes as parameters the center, a step size, and number of
    points on each side of the center:

    >>> cscan(dev, 0, 1, 5)   # scans around 0 from -5 to 5 in steps of 1.

    The total number of points is (2 * numperside) + 1.  The above commands
    counts at -5, -4, ..., 5.

    The equivalent `scan()` command would be:

    >>> scan(dev, -5, 1, 11)

    The device can also be a list of devices that should be moved for each
    step.  In this case, the center and step width also have to be lists:

    >>> cscan([dev1, dev2], [0, 0], [0.5, 1], 3)

    Resulting positions:

    ==== ==== ====
    Step dev1 dev2
    ==== ==== ====
    1    -1.5 -3.0
    2    -1.0 -2.0
    3    -0.5 -1.0
    4    0.0  0.0
    5    0.5  1.0
    6    1.0  2.0
    7    1.5  3.0
    ==== ==== ====
    """
    def mkpos(centers, steps, numperside):
        return [[
            center + (i - numperside) * step
            for (center, step) in zip(centers, steps)
        ] for i in range(2 * numperside + 1)]

    scanstr = _infostr('cscan', (dev, ) + args, kwargs)
    devs, values, restargs = _fixType(dev, args, mkpos)
    subscan = kwargs.pop(SUBSCAN, False)
    preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(restargs, kwargs, scanstr)
    Scan(devs,
         values,
         None,
         move,
         multistep,
         detlist,
         envlist,
         preset,
         scaninfo,
         subscan=subscan).run()
Пример #2
0
 def doStart(self):
     positions = [[p] for p in self.positions]
     dataset = Scan([self._adevs['scandev']], positions, positions,
                    detlist=[self._adevs['detector']], preset=self._preset,
                    subscan=True).run()
     # process the values...
     yvalues = [subset.detvaluelist[0] for subset in dataset.subsets]
     self._last = [sum(yvalues) / float(len(yvalues)), dataset.filenames[0]]
Пример #3
0
 def doStart(self):
     positions = [[p] for p in self.positions]
     self.readresult = self._processDataset(
         Scan([self._attached_scandev],
              positions,
              None,
              detlist=[self._attached_detector],
              preset=self._preset,
              subscan=True).run())
Пример #4
0
def sscan(dev, *args, **kwargs):
    """Scan over device(s) and count detector(s).

    The general syntax is either to give start, step and end:

    >>> sscan(dev, 0, 1, 10)   # scans from 0 to 10 in steps of 1.

    or a list of positions to scan:

    >>> sscan(dev, [0, 1, 2, 3, 7, 8, 9, 10])  # scans at the given positions.

    For floating point arguments, the length of the result is
    ``int(round((end - start) / step + 1)``. Because of floating point
    overflow, this rule may result in the last element being greater than
    ``end``, e.g.

    >>> sscan(dev, 30, .1, 30.19)   # scans from 30 to 30.2 in steps of 0.1.

    """
    def mkpos(starts, steps, ends):
        def mk(starts, steps, numpoints):
            return [[start + i * step for (start, step) in zip(starts, steps)]
                    for i in range(numpoints)]

        # use round to handle floating point overflows
        numpoints = [
            int(round((end - start) / step + 1))
            for (start, step, end) in zip(starts, steps, ends)
        ]
        if all(n == numpoints[0] for n in numpoints):
            if numpoints[0] > 0:
                if numpoints[0] > 1:
                    return mk(starts, steps, numpoints[0])
                else:
                    raise UsageError("invalid number of points. At least two "
                                     "points are necessary to define a range "
                                     "scan. Please check parameters.")
            else:
                raise UsageError("negative number of points. Please check "
                                 "parameters. Maybe step parameter has wrong"
                                 "sign.")
        else:
            raise UsageError("all entries must generate the same number of "
                             "points")

    scanstr = _infostr("sscan", (dev, ) + args, kwargs)
    devs, values, restargs = _fixType(dev, args, mkpos)
    preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(restargs, kwargs, scanstr)
    Scan(devs, values, None, move, multistep, detlist, envlist, preset,
         scaninfo).run()
Пример #5
0
def amplscan(dev1, start1, step1, numpoints1, dev2, start2, step2, numpoints2,
             t):
    scandet = session.getDevice('scandet')
    scandet.scandev = str(dev2)
    scandet.positions = [start2 + i * step2 for i in range(numpoints2)]
    dev1pos = [[start1 + i * step1] for i in range(numpoints1)]
    ds = Scan([session.getDevice(dev1)],
              dev1pos,
              None,
              detlist=[scandet],
              preset={
                  't': t
              }).run()
    fit(CosineFit, 'A', dataset=ds)
Пример #6
0
def gridscan(dev, *args, **kwargs):
    """Scans over a grid of device positions and count detector(s).

    The orthogonal grid will spanned by the positions of each device.

    >>> gridscan([dev1, dev2], [-1, -2], [1, 1], [3, 5])

    which generates a measurement over a grid with positions:

    ==== ==== ====
    Step dev1 dev2
    ==== ==== ====
    1    -1.0 -2.0
    2     0.0 -2.0
    3     1.0 -2.0
    4    -1.0 -1.0
    5     0.0 -1.0
    6     1.0 -1.0
    7    -1.0  0.0
    8     0.0  0.0
    9     1.0  0.0
    10   -1.0  1.0
    11    0.0  1.0
    12    1.0  1.0
    13   -1.0  2.0
    14    0.0  2.0
    15    1.0  2.0
    ==== ==== ====
    """
    def mkpos(starts, steps, numpoints):
        if isinstance(numpoints, (list, tuple)):
            if len(starts) != len(numpoints):
                raise UsageError('start, steps, and numpoint arguments must '
                                 'have the same length')
            scanvals = [[
                start + j * step for j in range(numpoint)
            ] for start, step, numpoint in zip(starts, steps, numpoints)]
            values = meshgrid(*scanvals)
            for i, grid in enumerate(values):
                values[i] = list(grid.reshape(grid.size))
            return [tuple(v[i] for v in values) for i in range(len(values[0]))]
        raise UsageError('numpoints must be a list')

    scanstr = _infostr('gridscan', (dev, ) + args, kwargs)
    devs, values, restargs = _fixType(dev, args, mkpos)
    preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(restargs, kwargs, scanstr)
    Scan(devs, values, None, move, multistep, detlist, envlist, preset,
         scaninfo).run()
Пример #7
0
 def doStart(self):
     positions = [[p] for p in self.positions]
     ds = Scan([session.getDevice(self.scandev)],
               positions,
               None,
               detlist=[self._attached_detector],
               preset=self._preset,
               subscan=True).run()
     xs, ys, dys, _, ds = _getData()
     fit = self.fitcls()
     res = fit.run(xs, ys, dys)
     if res._failed:
         self.log.warning('Fit failed: %s.' % res._message)
         self.readresult = [0] * (self._nparams * 2)
     else:
         session.notifyFitCurve(ds, fit.fit_title, res.curve_x, res.curve_y)
         readres = []
         for par, err in zip(res._pars[1], res._pars[2]):
             readres.append(par)
             readres.append(err)
         self.readresult = readres
Пример #8
0
def appendscan(numpoints=5, stepsize=None):
    """Go on *numpoints* steps from the end of the last scan.

    *numpoints* can also be negative to prepend scan points.

    Examples:

    >>> appendscan(5)   # append 5 more points to last scan
    >>> appendscan(-5)  # append 5 more points to beginning of last scan

    If *stepsize* is given, the step size of the last scan will be overridden.

    Example:

    >>> scan(x, 10, 0.1, 10)  # original scan
    >>> appendscan(10, 0.5)  # continue the scan, but with other step size

    If the previous scan wasn't a scan with fixed step size and *stepsize* is
    not given, the new step size will be calculated as the averaged step size
    from the previous scan:

    >>> scan(x, [0, 0.1, 0.2, 0.5, 1])
    >>> appendscan(5)

    moves x to the following positions:

    ==== ====
    Step x
    ==== ====
    1/5  1.25
    2/5  1.50
    3/5  1.75
    4/5  2.00
    5/5  2.25
    ==== ====

    The scan data will be plotted into the same live plot, if possible, but
    will be saved into a separate data file.

    Scans with multiple devices are supported:

    >>> scan([x, y], [0, 1], [0.1, 0.2], 10)
    >>> appendscan(3, [0.05, 0.1])  # append 5 points with new stepsizes

    If the original scan was made over multiple devices, the *stepsize* must
    be a list with the same number of elements.
    """
    if numpoints == 0:
        raise UsageError('number of points must be either positive or '
                         'negative')
    direction = numpoints / abs(numpoints)
    dslist = session.experiment.data.getLastScans()
    if not dslist:
        raise NicosError('no last scan saved')
    contuids = []

    # Find the last scan that wasn't an appendscan.
    i = len(dslist) - 1
    while i >= 0:
        contuids.append(dslist[i].uid)
        if not dslist[i].continuation:
            break
        i -= 1

    # If the last scan was an appendscan in the same direction, append to it,
    # else append to the original scan.  This DWUMs for
    #   scan(...)
    #   appendscan(5)
    #   appendscan(2)
    #   appendscan(-3)
    if dslist[-1].cont_direction == direction:
        scan = dslist[-1]
        # to continue an appendscan in the negative direction, which has
        # the points reversed, we need to reverse the direction again
        if scan.cont_direction == -1:
            numpoints = -numpoints
    else:
        scan = dslist[i]

    n_devs = len(scan.devices)
    n_steps = len(scan.subsets)
    if n_steps < 2:
        raise NicosError('cannot append to scan with no positions')

    if stepsize is not None:
        if isinstance(stepsize, number_types):
            stepsize = [stepsize]
        if n_devs != len(stepsize):
            raise NicosError('the stepsize must have %d elements' % n_devs)
    else:
        stepsize = [None] * n_devs

    # create the new list of positions
    positions = [[None] * n_devs for _ in range(abs(numpoints))]

    # for each device involved in the scan
    for i in range(n_devs):
        # determine step size by first and last position
        pos1 = scan.startpositions[0][i]
        pos2 = scan.startpositions[n_steps - 1][i]

        if isinstance(pos1, (tuple, ndarray)):
            stepsizes = tuple(
                (b - a) / (n_steps - 1) for (a, b) in zip(pos1, pos2))
            if numpoints > 0:
                for j in range(1, numpoints + 1):
                    positions[j - 1][i] = tuple(
                        b + j * s for (b, s) in zip(pos2, stepsizes))
            else:
                for j in range(1, -numpoints + 1):
                    positions[j - 1][i] = tuple(
                        a - j * s for (a, s) in zip(pos1, stepsizes))

        elif isinstance(pos1, number_types):
            if stepsize[i] is None:
                stepsize[i] = (pos2 - pos1) / (n_steps - 1)
            if numpoints > 0:
                startpos = pos2 + stepsize[i]
            else:
                stepsize[i] = -stepsize[i]
                startpos = pos1 + stepsize[i]
            for j in range(abs(numpoints)):
                positions[j][i] = startpos + j * stepsize[i]

        else:
            # we can't produce new values for this device
            raise NicosError('cannot append to this scan; some devices '
                             'have nonnumeric values')

    numpoints = abs(numpoints)
    s = Scan(scan.devices, positions, [], None, None, scan.detectors,
             scan.environment, scan.preset,
             '%d more steps of last scan' % numpoints)
    s._xindex = scan.xindex
    s._continuation = contuids
    s._cont_direction = direction
    # envlist must be reset since Scan.__init__ messes with the ordering
    s._envlist[:] = scan.environment
    s.run()
Пример #9
0
def scan(dev, *args, **kwargs):
    """Scan over device(s) and count detector(s).

    A scan is used to collect data during the experiment depending on the
    position of one or more devices:

    - Move the devices to a new position, called a **point**, and wait until
      all devices have reached their position.
    - Start the detectors and wait until the requested time and/or monitor
      counts, called a **preset**, are reached.

    The output is a sequence of detector data corresponding to the device
    positions.

    The command has two basic modes:

    - Equidistant steps between the points

      A start value, the step size, and the number of points are given to the
      command:

      >>> scan(dev, 0, 1, 11)   # counts at positions from 0 to 10 in steps of 1

      For scans *around* a center, use the `cscan()` command.

    - A user defined list of points

      Here, the command expects a list of points:

      >>> scan(dev, [0, 1, 2, 3, 7, 8, 9])  # counts at the given positions

    Instead of one device, the command also handles a list of devices that
    should be moved for each step.  In this case, the start and step width
    also have to be lists:

    >>> scan([dev1, dev2], [0, 0], [0.5, 1], 4)

    The list of points will be:

    ==== ==== ====
    Step dev1 dev2
    ==== ==== ====
    1    0.0  0.0
    2    0.5  1.0
    3    1.0  2.0
    4    1.5  3.0
    ==== ==== ====

    This also works for the second operation mode:

    >>> scan([dev1, dev2], [[0, 1, 2, 3], [0, 1, 5, 7]])

    with positions:

    ==== ==== ====
    Step dev1 dev2
    ==== ==== ====
    1    0.0  0.0
    2    1.0  1.0
    3    2.0  5.0
    4    3.0  7.0
    ==== ==== ====

    """
    def mkpos(starts, steps, numpoints):
        return [[start + i * step for (start, step) in zip(starts, steps)]
                for i in range(numpoints)]

    scanstr = _infostr('scan', (dev, ) + args, kwargs)
    devs, values, restargs = _fixType(dev, args, mkpos)
    preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(restargs, kwargs, scanstr)
    Scan(devs, values, None, move, multistep, detlist, envlist, preset,
         scaninfo).run()