Пример #1
0
def kscan(dev, start, step, numpoints, speed=None, *args, **kwargs):
    """Kinematic scan over device(s).

    The syntax is to give start, step and number of points:

    >>> kscan(dev, 3, 2, 4)     # kinematic scan starting at 3 oscillate by 2
                                # 4 times with default speed
    >>> kscan(dev, 3, 2, 4, 1)  # same scan as above with speed 1.

    oscillates between 3 and 5 during exposure for each interval of (3, 5)
    respectively (5, 3).

    """
    def mkpos(starts, steps, numpoints):
        startpositions = []
        endpositions = []
        for i in range(numpoints):
            for start, step in zip(starts, steps):
                startpositions.append([start + (i % 2) * step])
                endpositions.append([start + ((i + 1) % 2) * step])
        return startpositions, endpositions

    scanargs = (start, step, numpoints) + args
    scanstr = _infostr('kscan', (dev, ) + scanargs, kwargs)
    devs, values, restargs = _fixTypeNPoints(dev, scanargs, mkpos)
    _preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(restargs, kwargs, scanstr)
    KScan(devs, values[0], values[1], speed, move, multistep, detlist, envlist,
          scaninfo).run()
Пример #2
0
def timeadscan(numpoints, header, parnames, parlist, psi, phi, mono, cad, t):
    """Time scan in multianalyzer setup.

    Count a number of times without moving devices, except the 'psi', 'phi',
    'mono', and 'cad' before counting the first time.

    * numpoints - number of repititions can be -1 to scan for unlimited points
                  (break using Ctrl-C or the GUI to quit).
    * header - additional header (maybe stored in data file)
    * parnames - additional parameters (stored in data file)
    * parlist - values to additional parnames (stored in data files), must have
                a length of 11 (one for each detector) and each entry must have
                the length of the parnames list
    * psipos - target position of psi device
    * phipos - target position of phi device
    * monopos - target position of mono device
    * cadpos - target position of cad device
    * timepreset - time to count per point

    Example:

    >>> timeadscan(5, 'The following configs are selected: configuration 419 '
                   'ki= 5.40  Psi = 151.22  Phi0 = 65.50  CAD = -7.83  '
                   'tilt =-2.00 config-type 2',
                   ['h', 'k', 'l', 'ny/THz', 'x/cm', 'y/cm',  'theta/deg',
                    'phi/deg'],
                   [
                    [-4.68, 2.97, 0.00, -6.64, 10.00, 2.00, -8.27, 71.89],
                    [-4.51, 2.73, 0.00, -4.54, 8.00, 1.60, -8.71, 70.59],
                    [-4.37, 2.52, 0.00, -2.76, 6.00, 1.20, -9.15, 69.31],
                    [-4.23, 2.33, 0.00, -1.24, 4.00, 0.80, -9.58, 68.03],
                    [-4.11, 2.16, 0.00, 0.07, 2.00, 0.40, -10.01, 66.76],
                    [-4.00, 2.00, 0.00, 1.20, 0.00, 0.00, -10.43, 65.50],
                    [-3.90, 1.85, 0.00, 2.18, -2.00, -0.40, -10.84, 64.25],
                    [-3.80, 1.72, 0.00, 3.05, -4.00, -0.80, -11.24, 63.01],
                    [-3.72, 1.60, 0.00, 3.80, -6.00, -1.20, -11.63, 61.79],
                    [-3.64, 1.48, 0.00, 4.47, -8.00, -1.60, -12.01, 60.58],
                    [-3.56, 1.38, 0.00, 5.07, -10.00, -2.00, -12.39, 59.38],
                   ], 276.25, 19.995, 3.235, -0.8016, 1)
    """
    preset = {'t': t}
    scanstr = _infostr('timeadscan', (numpoints, ) + (psi, phi, mono, cad),
                       preset)
    move = [[session.getDevice(devname), pos] for devname, pos in zip(
        ['psi', 'phi', 'mono', 'cad'], [psi, phi, mono, cad])]

    scan = TimeADScan(header,
                      parnames,
                      parlist,
                      numpoints,
                      move,
                      preset=preset,
                      scaninfo='%s %s' % (scanstr, header))
    scan.run()
Пример #3
0
def msingle(settings, *args, **kwargs):
    """Single MIEZE counting.

    First argument is a list of MIEZE settings or -1 to scan all setings.

    All other arguments are handled like for `count`.
    """
    scanstr = _infostr('msingle', (settings, ) + args, kwargs)
    preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(args, kwargs, scanstr)
    MiezeScan(settings, [], [], move, multistep, detlist, envlist, preset,
              scaninfo).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 walltimecount(numpoints, walltime, *args, **kwargs):
    """Count a number of times for the given amount of time on wall.

    "numpoints" can be -1 to scan for unlimited points (break using Ctrl-C or
    the GUI to quit).

    "walltime" provides the time in seconds

    Example:

    >>> walltimecount(500, 10)  # counts 500 times, every count for 10 seconds

    A special "delay" argument is supported to allow time delays between two
    points:

    >>> walltimecount(500, 2, delay=5)
    """
    scanstr = _infostr('walltimecount', (
        numpoints,
        walltime,
    ) + args, kwargs)
    preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(args, kwargs, scanstr)

    # Get AMOR detector
    if not detlist:
        detlist = session.experiment.detectors

    detector = None
    for det in detlist:
        if isinstance(det, SinqDetector):
            detector = det

    if not detector:
        session.log.error('Detector not found in the detector list')

    # Set the beam threshold to 0
    oldthreshold = detector.threshold

    # Complete the scan
    scan = WallTimeScan([], [], numpoints, walltime, move, multistep, detlist,
                        envlist, preset, scaninfo)
    scan.run()

    # Reset the beam threshold to oldvalue
    detector.threshold = oldthreshold
Пример #6
0
def mscan(settings, dev, *args, **kwargs):
    """MIEZE scan over device(s).

    First argument is a list of MIEZE settings or -1 to scan all settings.

    All other arguments are handled like for `scan`.
    """
    def mkpos(starts, steps, numsteps):
        return [[start + i * step for (start, step) in zip(starts, steps)]
                for i in range(numsteps)]

    scanstr = _infostr('mscan', (settings, dev) + args, kwargs)
    devs, values, restargs = _fixType(dev, args, mkpos)
    preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(restargs, kwargs, scanstr)
    MiezeScan(settings, devs, values, move, multistep, detlist, envlist,
              preset, scaninfo).run()
Пример #7
0
def atscan(time, *args, **kwargs):
    """A timescan that has an adjustable running time."""
    time = parseDuration(time, 'atscan')

    scanstr = _infostr('vartimescan', (time, ) + args, kwargs)
    target = kwargs.pop('target', 'eta')

    preset, scaninfo, detlist, envlist, move, multistep = \
        _handleScanArgs(args, kwargs, scanstr)

    scan = VariableTimeScan([], [],
                            move,
                            multistep,
                            detlist,
                            envlist,
                            preset,
                            scaninfo,
                            totaltime=time,
                            target=target)
    scan.run()
Пример #8
0
def qscan(Q, dQ, numpoints, *args, **kwargs):
    """Perform a single-sided Q scan.

    The *Q* and *dQ* arguments can be lists of 3 or 4 components, or a `Q`
    object.

    Example:

    >>> qscan((1, 0, 0, 0), (0, 0, 0, 0.1), 11, kf=1.55, mon1=100000)

    will perform an energy scan at (100) from 0 to 1 meV (or THz, depending on
    the instrument setting) with the given constant kf and the given monitor
    counts per point.

    The special "plot" parameter can be given to plot the scan instead of
    running it:

    * plot='res'  -- plot resolution ellipsoid along scan
    * plot='hkl'  -- plot position of scan points in scattering plane
    """
    Q, dQ = _getQ(Q, 'Q'), _getQ(dQ, 'dQ')
    scanstr = _infostr('qscan', (Q, dQ, numpoints) + args, kwargs)
    plotval = kwargs.pop('plot', None)
    preset, scaninfo, detlist, envlist, move, multistep, Q, dQ = \
        _handleQScanArgs(args, kwargs, Q, dQ, scanstr)
    if all(v == 0 for v in dQ) and numpoints > 1:
        raise UsageError('scanning with zero step width')
    values = [[(Q[0] + i * dQ[0], Q[1] + i * dQ[1], Q[2] + i * dQ[2],
                Q[3] + i * dQ[3])] for i in range(numpoints)]
    if plotval == 'res':
        resscan(*(p[0] for p in values),
                kf=kwargs.get('kf'),
                ki=kwargs.get('ki'))
    elif plotval == 'hkl':
        hklplot(scan=[p[0] for p in values],
                kf=kwargs.get('kf'),
                ki=kwargs.get('ki'))
    else:
        scan = QScan(values, move, multistep, detlist, envlist, preset,
                     scaninfo)
        scan.run()
Пример #9
0
def qscan(Q, dQ, numpoints, *args, **kwargs):
    """Perform a single-sided Q step scan.

    The *Q* and *dQ* arguments should be lists of 3 components.

    Example:

    >>> qscan((1, 0, 0), (0, 0, 0.1), 11, mon1=100000)

    will perform an L scan at (100) with the given monitor counts per point.
    """
    Q, dQ = _getQ(Q, 'Q'), _getQ(dQ, 'dQ')
    scanstr = _infostr('qscan', (Q, dQ, numpoints) + args, kwargs)
    preset, scaninfo, detlist, envlist, move, multistep, Q, dQ = \
        _handleQScanArgs(args, kwargs, Q, dQ, scanstr)
    if all(v == 0 for v in dQ) and numpoints > 1:
        raise UsageError('scanning with zero step width')
    values = [[(Q[0] + i * dQ[0], Q[1] + i * dQ[1], Q[2] + i * dQ[2])]
              for i in range(numpoints)]
    scan = QScan(values, move, multistep, detlist, envlist, preset, scaninfo)
    scan.run()
Пример #10
0
def qcscan(Q, dQ, numperside, *args, **kwargs):
    """Perform a centered Q scan.

    The *Q* and *dQ* arguments can be lists of 3 or 4 components, or a `Q`
    object.

    Example:

    >>> qcscan((1, 0, 0, 1), (0.001, 0, 0, 0), 20, mon1=1000)

    will perform a longitudinal scan around (100) with the given monitor counts
    per point.

    The special "plot" parameter can be given to plot the scan instead of
    running it:

    * plot='res'  -- plot resolution ellipsoid along scan
    * plot='hkl'  -- plot position of scan points in scattering plane
    """
    Q, dQ = _getQ(Q, 'Q'), _getQ(dQ, 'dQ')
    scanstr = _infostr('qcscan', (Q, dQ, numperside) + args, kwargs)
    plotval = kwargs.pop('plot', None)
    preset, scaninfo, detlist, envlist, move, multistep, Q, dQ = \
        _handleQScanArgs(args, kwargs, Q, dQ, scanstr)
    if all(v == 0 for v in dQ) and numperside > 0:
        raise UsageError('scanning with zero step width')
    values = [[(Q[0] + i * dQ[0], Q[1] + i * dQ[1], Q[2] + i * dQ[2],
                Q[3] + i * dQ[3])] for i in range(-numperside, numperside + 1)]
    if plotval == 'res':
        resscan(*(p[0] for p in values),
                kf=kwargs.get('kf'),
                ki=kwargs.get('ki'))
    elif plotval == 'hkl':
        hklplot(scan=[p[0] for p in values],
                kf=kwargs.get('kf'),
                ki=kwargs.get('ki'))
    else:
        scan = QScan(values, move, multistep, detlist, envlist, preset,
                     scaninfo)
        scan.run()
Пример #11
0
def qcscan(Q, dQ, numperside, *args, **kwargs):
    """Perform a centered Q step scan.

    The *Q* and *dQ* arguments should be lists of 3 components.

    Example:

    >>> qcscan((1, 0, 0), (0.001, 0, 0), 20, mon1=1000)

    will perform a longitudinal scan around (100) with the given monitor counts
    per point.
    """
    Q, dQ = _getQ(Q, 'Q'), _getQ(dQ, 'dQ')
    scanstr = _infostr('qcscan', (Q, dQ, numperside) + args, kwargs)
    preset, scaninfo, detlist, envlist, move, multistep, Q, dQ = \
        _handleQScanArgs(args, kwargs, Q, dQ, scanstr)
    if all(v == 0 for v in dQ) and numperside > 0:
        raise UsageError('scanning with zero step width')
    values = [[(Q[0] + i * dQ[0], Q[1] + i * dQ[1], Q[2] + i * dQ[2])]
              for i in range(-numperside, numperside + 1)]
    scan = QScan(values, move, multistep, detlist, envlist, preset, scaninfo)
    scan.run()
Пример #12
0
 def __init__(self, settings, args, kwargs):  # pylint: disable=super-init-not-called
     scanstr = _infostr('mmanualscan', (settings, ) + args, kwargs)
     preset, scaninfo, detlist, envlist, move, multistep = \
         _handleScanArgs(args, kwargs, scanstr)
     self.scan = MiezeManualScan(settings, move, multistep, detlist,
                                 envlist, preset, scaninfo)