Beispiel #1
0
 def endScan(self):
     session.experiment.data.finishScan()
     try:
         from nicos.core.data import ScanData
         session.elogEvent('scanend', ScanData(self.dataset))
     except Exception:
         session.log.debug('could not add scan to electronic logbook',
                           exc=1)
     session.breakpoint(1)
Beispiel #2
0
 def _inner_run(self):
     dataman = session.experiment.data
     # move all devices to starting position before starting scan
     try:
         self.prepareScan(self._startpositions[0])
         skip_first_point = False
     except StopScan:
         return
     except SkipPoint:
         skip_first_point = True
     # if the scan was already aborted, we haven't started writing
     self.beginScan()
     try:
         for i, position in enumerate(self._startpositions):
             with self.pointScope(i + 1):
                 try:
                     self.preparePoint(i + 1, position)
                     if i == 0 and skip_first_point:
                         continue
                     waitresults = self.moveDevices(self._devices, position,
                                                    wait=True)
                     # start moving to end positions
                     if self._endpositions:
                         self.moveDevices(self._devices,
                                          self._endpositions[i], wait=False)
                 except SkipPoint:
                     session.breakpoint(2)
                     continue
                 except BaseException as err:
                     try:
                         self.finishPoint()
                     except Exception:
                         session.log.exception('could not finish point')
                     raise err
                 try:
                     # measure...
                     # XXX(dataapi): is target= needed?
                     point = dataman.beginPoint(target=position,
                                                preset=self._preset)
                     dataman.putValues(waitresults)
                     self.readEnvironment()
                     try:
                         self.acquire(point, self._preset)
                     finally:
                         dataman.finishPoint()
                 except NicosError as err:
                     self.handleError('count', err)
                 except SkipPoint:
                     pass
                 finally:
                     self.finishPoint()
     except StopScan:
         pass
     finally:
         self.endScan()
Beispiel #3
0
def count(n, *detlist, **presets):
    """Perform **n** counts while the TIFF image filename of the DECTRIS
    Pilatus detector will be set to a temporary value that remains unchanged
    during execution of this command.

    With preset arguments, this preset is used instead of the default preset.

    With detector devices as arguments, these detectors are used instead of the
    default detectors set with `SetDetectors()`.

    Examples:

    >>> # count 100 times without changing presets
    >>> count(100)
    >>>
    >>> # count 10 times and set the temporary filename to 'tmp.tif'
    >>> count(10, filename='tmp.tif')
    >>>
    >>> # count once with time preset of 10 seconds
    >>> count(1, t=10)

    Within a manual scan, this command is also used to perform the count as one
    point of the manual scan.
    """
    filename = presets.pop('filename', 'tmpcount.tif')
    galaxi_sinks = {
        sink: sink.settypes
        for sink in session.datasinks
        if isinstance(sink, (MythenSink, PilatusSink))
    }
    try:
        for sink in galaxi_sinks:
            # deactivate during count
            sink._setROParam('settypes', [SCAN])
        for _ in range(n):
            for det in session.experiment.detectors:
                if isinstance(det, PilatusDetector):
                    det.imagedir = path.join(str(datetime.now().year),
                                             session.experiment.proposal)
                    det.nextfilename = filename
            measure.count(*detlist, **presets)
            session.breakpoint(2)  # allow daemon to stop here
    finally:
        for sink, settypes in galaxi_sinks.items():
            sink._setROParam('settypes', settypes)
Beispiel #4
0
def _wait_for_continuation(delay, only_pause=False):
    """Wait until any countloop requests are processed and the watchdog
    "pausecount" is empty.

    Return True if measurement can continue, or False if detectors should be
    stopped.
    """
    while session.countloop_request:
        req, current_msg = session.countloop_request  # pylint: disable=E0633
        session.countloop_request = None
        if only_pause and req != 'pause':
            # for 'finish' requests, we don't want to finish *before* starting the
            # measurement, because then we don't have any results to return
            session.log.info('request for early finish ignored, not counting')
            return True
        exp = session.experiment
        if req == 'finish':
            session.log.warning('counting stopped: %s', current_msg)
            return False
        else:
            session.log.warning('counting paused: %s', current_msg)
        # allow the daemon to pause here, if we were paused by it
        session.breakpoint(3)
        # still check for other conditions
        while exp.pausecount:
            if exp.pausecount != current_msg:
                current_msg = exp.pausecount
                session.log.warning('counting paused: %s', current_msg)
            session.delay(delay)
            # also allow the daemon to pause here
            session.breakpoint(3)
            if session.countloop_request:
                # completely new request? continue with outer loop
                break
    session.log.info('counting resumed')
    return True
Beispiel #5
0
 def f_notify(tmr):
     session.breakpoint(2)  # allow break and continue here
     session.action('%s left' % formatDuration(tmr.remaining_time()))
Beispiel #6
0
    def _inner_run(self):
        try:
            self.prepareScan(self._startpositions[0])
        except (StopScan, SkipPoint, LimitError):
            return

        dataman = session.experiment.data
        self.beginScan()

        device = self._devices[0]
        detlist = self._detlist
        point = 0
        try:
            if session.mode == SIMULATION:
                preset = 1  # prevent all contscans taking 1 hour
            else:
                preset = max(self._distance / (self._speed or 0.1) * 5, 3600)

            devpos = device.read(0)

            self.preparePoint(None, None)

            for det in detlist:
                det.start(t=preset)
            device.move(self._endpositions[0][0])
            starttime = looptime = currenttime()

            last = {det.name: (det.read(), det.readArrays(INTERMEDIATE))
                    for det in detlist}

            while device.status(0)[0] == status.BUSY:
                session.breakpoint(2)
                sleeptime = max(0, looptime + self._timedelta - currenttime())
                session.log.debug('sleep time: %f', sleeptime)
                with self.pointScope(point + 1):
                    session.delay(sleeptime)
                    looptime = currenttime()
                    new_devpos = device.read(0)
                    read = {det.name: (det.read(),
                                       det.readArrays(INTERMEDIATE))
                            for det in detlist}
                    actualpos = [0.5 * (devpos + new_devpos)]
                    dataman.beginTemporaryPoint()
                    if point == 0:
                        dataman.updateMetainfo()
                    dataman.putValues({device.name: (None, actualpos)})
                    self.readEnvironment()
                    # TODO: if the data sink needs it ?
                    # dataman.updateMetainfo()
                    dataman.putResults(FINAL, self._calculate_diff(last, read))
                    dataman.finishPoint()
                    last = read
                    devpos = new_devpos
                    for det in detlist:
                        det.duringMeasureHook(looptime - starttime)
                    point += 1
            device.wait()  # important for simulation
        finally:
            session.endActionScope()
            for det in detlist:
                try:
                    det.finish()
                except Exception:
                    session.log.warning('could not stop %s', det, exc=1)
            try:
                device.stop()
                device.wait()
            except Exception:
                device.log.warning('could not stop %s', device, exc=1)
            self.endScan()
Beispiel #7
0
 def finishPoint(self):
     session.breakpoint(2)
Beispiel #8
0
 def check(tmr):
     session.breakpoint(2)  # allow break and continue here
     waitfor.cond_fulfilled = eval(full_condition, {}, {'_v': dev.read(0)})
     if waitfor.cond_fulfilled:
         session.log.info('Waiting for \'%s %s\' finished.', dev, condition)
         tmr.stop()
Beispiel #9
0
def GenDataset(name, hmax, kmax, lmax, uniq=False, kvector=None):
    """Generate a dataset of HKL indices to measure, as a CSV file.

    This will generate a ``.csv`` file with the given *name* in the experiment
    data directory and populate it with all HKL reflections reachable for the
    current sample orientation in the current instrument setup (including
    limits of the axes).  The maximum H, K, and L indices are given by
    *hmax*, *kmax* and *lmax*.

    If *uniq* is true, does not include symmetry equivalent reflections.

    If *kvector* is given, it is a propagation vector, or list of such vectors,
    to add to and subtract from each integer HKL point.

    You can view/edit the CSV file afterwards, and finally do a scan over the
    HKL list using the `ScanDataset()` command.

    Example:

    >>> GenDataset('all', 10, 10, 10)
    >>> GenDataset('unique', 10, 10, 10, True)

    Using propagation vectors:

    >>> GenDataset('all', 5, 5, 5, kvector=(0.33, 0, 0))
    >>> GenDataset('all', 5, 5, 5, kvector=[(0.33, 0, 0), (0, 0.33, 0)])
    """
    instr = session.instrument
    sample = session.experiment.sample
    root = session.experiment.samplepath

    session.log.info('Generating HKLs...')
    hkls = sample.cell.dataset(0,
                               100,
                               uhmin=-hmax,
                               uhmax=hmax,
                               ukmin=-kmax,
                               ukmax=kmax,
                               ulmin=-lmax,
                               ulmax=lmax,
                               uniq=uniq)

    if kvector:
        try:
            kvectors = list(kvector)
            try:
                list(kvectors[0])
            except TypeError:
                kvectors = [kvectors]
            for kvec in kvectors:
                if len(kvec) != 3:
                    raise ValueError
            kvectors = [array(k) for k in kvectors]
        except Exception:
            raise UsageError('kvector needs to be a HKL vector or a list '
                             'of HKL vectors') from None

        new_hkls = []
        for hkl in hkls:
            for kvec in kvectors:
                new_hkls.append(hkl + kvec)
                new_hkls.append(hkl - kvec)
        hkls = new_hkls

    wavelength = session.instrument.wavelength
    all_pos = []
    for (i, hkl) in enumerate(hkls, 1):
        if i % 10000 == 0:
            session.log.info('%s/%s', i, len(hkls))
            # allow immediate stop here
            session.breakpoint(5)
        hkl = hkl.tolist()
        try:
            poslist = instr._extractPos(instr._calcPos(hkl, wavelength))
        except Exception:
            continue
        posdict = {}
        for (devname, devvalue) in poslist:
            if not isfinite(devvalue) or \
               not instr._adevs[devname].isAllowed(devvalue)[0]:
                break
            posdict[devname] = devvalue
        else:
            scanwidth = instr.getScanWidthFor(hkl)
            all_pos.append(hkl + [
                '%.3f' % posdict['gamma'],
                '%.3f' % posdict['omega'],
                '%.3f' % posdict['nu'],
                '%.1f' % scanwidth
            ])
    session.log.info('%d of %d reflections within instrument limits.',
                     len(all_pos), len(hkls))

    fullpath = path.join(root, name + '.csv')
    with open(fullpath, 'w', encoding='utf-8') as fp:
        writer = csv.writer(fp)
        writer.writerow(['h', 'k', 'l', 'gamma', 'omega', 'nu', 'width'])
        for row in all_pos:
            writer.writerow(row)

    session.log.info('Reflection list written to %s.', fullpath)
Beispiel #10
0
def tableexe(csvfile):
    """
     Tableexe executes an execution table provided
     as a CSV file
     :param csvfile: The csv file to run
     """
    fname = _csvfilename(csvfile)
    if not fname or \
            (not path.isfile(fname) and os.access(fname, os.R_OK)):
        raise UsageError('The file %r does not exist or is not readable' %
                         fname)
    with open(fname, 'r') as fin:
        csv_data = csv.reader(fin, delimiter=',')
        # Analyse header
        devlist = []
        parlist = []
        comlist = []
        strlist = []
        comnames = ['timer', 'monitor', 'command']
        header = next(csv_data)
        for col_name in header:
            if not col_name:
                continue
            if col_name in comnames:
                comlist.append(col_name)
                continue
            if col_name in session.devices:
                dev = session.getDevice(col_name)
                if isinstance(dev.read(), str):
                    strlist.append(col_name)
                devlist.append(col_name)
                continue
            try:
                devname, par = col_name.split('.')
                dev = session.getDevice(devname)
                if par in dev.parameters:
                    parlist.append(col_name)
                    if isinstance(dev.parameters[par], str):
                        strlist.append(col_name)
                else:
                    raise UsageError('%s has no parameter %s' % (devname, par))
            except Exception:
                raise UsageError('Unrecognised column name %s' %
                                 col_name) from None

        # Actually execute the CSV data
        idx = 0
        printinfo('Executing CSV from %s' % csvfile)
        for data in csv_data:
            if not data:
                continue
            idx = idx + 1
            dev_value = []
            commands = []
            printinfo('Working line %d of %s' %
                      (idx, os.path.basename(csvfile)))
            for col_name, value in zip(header, data):
                if col_name in devlist:
                    dev_value.append(value)
                    continue
                if col_name in parlist:
                    lv = col_name.split('.')
                    dev = session.getDevice(lv[0])
                    setattr(dev, lv[1], value)
                    continue
                if col_name == 'timer':
                    commands.append('count(t=%s)' % value)
                elif col_name == 'monitor':
                    commands.append('count(m=%s)' % value)
                else:
                    commands.append(value)
            dev_poslist = ()
            for dev, value in zip(devlist, dev_value):
                dev_poslist += (dev, )
                if dev in strlist:
                    dev_poslist += (value, )
                else:
                    dev_poslist += (float(value), )
            _basemove(dev_poslist, waithook=_wait_hook)
            for com in commands:
                if com:
                    code, _ = parseScript(com)
                    for c in code:
                        exec(c, session.namespace)
            session.breakpoint(2)