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)
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()
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)
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
def f_notify(tmr): session.breakpoint(2) # allow break and continue here session.action('%s left' % formatDuration(tmr.remaining_time()))
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()
def finishPoint(self): session.breakpoint(2)
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()
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)
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)