def _moveShutter(self, target): if self.sink._attached_auto.read(0) == 'auto': session.log.info('Moving shutter to %s', target) self.sink._attached_shutter1.start(target) self.sink._attached_shutter2.start(target) multiWait( [self.sink._attached_shutter1, self.sink._attached_shutter2])
def _disable_gates(self): self.log.debug('disabling gates') for dev, val in zip(reversed(self._attached_gates), reversed(self.disablevalues)): dev.move(val) multiWait(self._attached_gates) self.log.debug('gates disabled')
def findPeak(left, right): # Calculate median area = 0 oidx = 0 for idx in range(left, right): area += (positions[idx+1] - positions[idx]) * \ (counts[idx+1] + counts[idx]) * .25 s = 0 for idx in range(left, right): s += (positions[idx+1] - positions[idx]) * \ (counts[idx+1] + counts[idx]) * .5 oidx = idx if s > area: break s -= .5 * (positions[oidx+1] - positions[oidx]) * \ (counts[oidx+1] + counts[oidx]) da = area - s if counts[oidx + 1] == counts[oidx]: center = positions[oidx] + da / counts[oidx] else: s = (counts[oidx+1] - counts[oidx]) / \ (positions[oidx+1] - positions[oidx]) if (counts[oidx]**2 + 2. * s * da) < 0: session.log.error('Error calculating peak median') return False disc = np.sqrt(counts[oidx]**2 + 2. * s * da) center = positions[oidx] + (disc - counts[oidx]) / s for idx in range(left, right + 1): if positions[idx] <= center < positions[idx + 1]: peakmax = counts[idx] break dev.start(center) multiWait([dev]) session.log.info('Found peak at %f, counts = %ld', center, peakmax) return True
def _waitFailed(self, i, action, exc_info): # wait for all other motors on failure try: multiWait(self._getWaiters()) except Exception: # we want to reraise the original exception pass raise exc_info[1]
def test_max_away(session, log): om = session.getDevice('om') det = session.getDevice('det') session.experiment.setDetectors([det]) om.start(20.) multiWait([om]) with log.assert_errors(r'Peak out of range'): Max(om, .2, t=.05)
def test_max(session, omstart): om = session.getDevice('om') det = session.getDevice('det') session.experiment.setDetectors([det]) om.start(omstart) multiWait([om]) Max(om, .2, t=.05) assert (abs(om.read() - 3.0) < .05)
def go_reflection(r, devs): use_angles = False for a in r[1]: if abs(a) > .1: use_angles = True break if use_angles: for dev, ang in zip(devs, r[1]): dev.start(ang) multiWait(devs) else: inst = session.instrument inst.start(r[0]) multiWait([inst])
def PeakSearch(reflist=None, threshold=100, **preset): sample, inst = getSampleInst() if not hasattr(inst, 'searchpars'): session.log.error('%s does not support peak search', inst.name) return rfl = sample.getRefList(reflist) if rfl is None: session.log.error('Reflection list %s not found', reflist) return mots = inst.get_motors() dstt = session.getDevice(mots[0]) dom = session.getDevice(mots[1]) dchi = session.getDevice(mots[2]) dphi = session.getDevice(mots[3]) mots = [dstt, dom, dchi, dphi] sttpars = inst.searchpars['stt'] chipars = inst.searchpars['chi'] phipars = inst.searchpars['phi'] nphi = (phipars[1] - phipars[0]) / phipars[2] for stt in np.arange(sttpars[0], sttpars[1], sttpars[2]): for chi in np.arange(chipars[0], chipars[1], chipars[2]): dstt.start(stt) dstt.start(stt / 2.) dchi.start(chi) multiWait([dstt, dom, dchi]) session.log.info('Searching at stt = %f, chi = %f', stt, chi) scan(dphi, phipars[0], phipars[2], int(nphi), **preset) peaks = findpeaks(mots[3].name, inst.center_counter, npoints=4) if peaks: session.log.info('%d candidate peaks found in phi scan', len(peaks)) for p in peaks: dphi.maw(p) ang = [m.read(0) for m in mots] r = ((0, 0, 0), tuple(ang), ()) if not test_threshold(dphi.name, inst.center_counter, p, threshold): session.log.info('Peak at %f below threshold %f', p, threshold) continue if test_proximity(rfl, ang): session.log.info('Peak at %f failed proximity test', p) continue session.log.info('Centering reflection at phi = %f', p) ok, maxang = inner_center(r, **preset) if ok: rfl.append(None, tuple(maxang), None) else: session.log.warning('Failed centering at phi = %f', p)
def _reference(self, devlist): if self.stoprequest == 0: for ax in devlist: if not ax.motor.isAtReference(): self.log.debug('reference: %s', ax.name) ax.motor.reference() multiWait([ax.motor for ax in devlist]) check = 0 for ax in devlist: if ax.motor.isAtReference(): check += 1 else: self.log.warning('%s is not at reference: %r %r', ax.name, ax.motor.refpos, ax.motor.read(0)) return check == len(devlist)
def test_stored_positions(session): v1 = session.getDevice('v1') v1.precision = .1 v3 = session.getDevice('v3') v3.precision = .1 stopo = session.getDevice('stopo') v1.start(3.3) v3.start(7.7) multiWait([v1, v3]) stopo.define_position('p1', ('v1', 2.2), ('v3', 5.5)) stopo.define_position('p2', v1, v3) stopo.define_position('p3', v1=1.7, v3=8.4) stopo.maw('p1') assert(abs(v1.read(0)-2.2) < v1.precision) assert(abs(v3.read(0)-5.5) < v3.precision) assert(stopo.read(0) == 'p1') stopo.maw('p2') assert(abs(v1.read(0)-3.3) < v1.precision) assert(abs(v3.read(0)-7.7) < v3.precision) assert(stopo.read(0) == 'p2') stopo.maw('p3') assert(abs(v1.read(0)-1.7) < v1.precision) assert(abs(v3.read(0)-8.4) < v3.precision) assert(stopo.read(0) == 'p3') with pytest.raises(NicosError): stopo.maw('gurke') stopo.delete('p1') with pytest.raises(NicosError): stopo.maw('p1') stopo.clear() with pytest.raises(NicosError): stopo.maw('p2')
def moveDevices(self, devices, positions, wait=True): """Move a given list of *devices* to the given list of *positions*. On errors, call handleError, which decides when the scan may continue. If *wait* is true, returns ``{devname: (None, final position)}``. This is intended to be given to `DataManager.putValues` which expects ``{devname: (timestamp or None, value)}``. Else ``None``. """ skip = None waitdevs = [] for dev, val in zip(devices, positions): try: dev.start(val) except NicosError as err: try: # handleError can reraise for fatal error, raise SkipPoint # to skip this point or return to measure anyway self.handleError('move', err) except SkipPoint: skip = True else: waitdevs.append(dev) if not wait: return None waitresults = {} try: # remember the read values so they can be used for the data point for (dev, value) in multiWait(waitdevs).items(): # (None, value): None identifies the 'main' value waitresults[dev.name] = (None, value) except NicosError as err: self.handleError('wait', err) if skip: raise SkipPoint for dev in waitdevs: # if devices failed to move but we continue, get some read values if dev.name in waitresults: continue try: waitresults[dev.name] = (None, dev.read()) except NicosError: dev.log.warning('Readout problem, continuing', exc=1) waitresults[dev.name] = (None, [None] * len(dev.valueInfo())) return waitresults
def test_multiwait_retval(self, devices): dev1, dev2, dev3, dev4 = devices res = multiWait([dev1, dev2, dev3, dev4]) assert res == {dev1: 1, dev2: 2, dev3: 3}
def doStart(self, value): # filter unsupported echotimes # find best match from table for entry in self.currenttable: if abs(entry - value) < 1e-12: value = entry break else: raise InvalidValueError( 'Given echo time not supported by current ' 'tunewave table (%s/%s) within %s' % (getattr(session.experiment, 'measurementmode', 'mieze'), self._attached_wavelength.read(), self.wavelengthtolerance)) # stop stopfirst devices for devname in self.stopfirst: dev = session.getDevice(devname) self.log.debug('stopping %s', str(dev)) dev.stop() # move zerofirst devices to configured value self.log.debug('zeroing devices') wait_on = set() for devname, val in self.zerofirst.items(): dev = session.getDevice(devname) self.log.debug('moving %s to zero', str(dev)) dev.start(val) wait_on.add(dev) self.log.debug('waiting for devices to reach zero') multiWait(wait_on) self.log.debug('devices now at zero') # move all tuning devices at once without blocking wait_on = set() for tunedev, val in sorted(iteritems(self.currenttable[value])): if tunedev in self.stopfirst: self.log.debug('skipping %s (will be set later)', tunedev) continue if tunedev in self._tunedevs: self.log.debug('setting %s to %s', tunedev, val) dev = self._tunedevs[tunedev] dev.start(val) wait_on.add(dev) else: self.log.warning('tune device %r from table not in tunedevs! ' 'movement to %r ignored !' % (tunedev, val)) self.log.debug('waiting for devices...') multiWait(wait_on) self.log.debug('devices now at configured values') # activate stopfirst devices wait_on = set() for devname in self.stopfirst: dev = session.getDevice(devname) val = self.currenttable[value][devname] self.log.debug('moving %s to %s', devname, val) dev.move(val) wait_on.add(dev) self.log.debug('devices now at configured values') multiWait(wait_on) self.log.debug('all done. good luck!')
def _enable_gates(self): self.log.debug('enabling gates') for dev, val in zip(self._attached_gates, self.enablevalues): dev.move(val) multiWait(self._attached_gates) self.log.debug('gates enabled')
def Max(dev, step, counter=None, maxpts=None, **preset): """ Search the maximum of a peak by moving dev. The algorithm used has been taken from the program difrac by P. White and E. Gabe The data structure is an array of maxpts elements. We start in the middle. We first step to the left until we find a point where the counts are half of the maximum. If we do not find the peak there we go right and do the same. If we cannot find the peak then, we give up. Else we calculate the peak as the meridian between left and right half maximum. """ def findPeak(left, right): # Calculate median area = 0 oidx = 0 for idx in range(left, right): area += (positions[idx+1] - positions[idx]) * \ (counts[idx+1] + counts[idx]) * .25 s = 0 for idx in range(left, right): s += (positions[idx+1] - positions[idx]) * \ (counts[idx+1] + counts[idx]) * .5 oidx = idx if s > area: break s -= .5 * (positions[oidx+1] - positions[oidx]) * \ (counts[oidx+1] + counts[oidx]) da = area - s if counts[oidx + 1] == counts[oidx]: center = positions[oidx] + da / counts[oidx] else: s = (counts[oidx+1] - counts[oidx]) / \ (positions[oidx+1] - positions[oidx]) if (counts[oidx]**2 + 2. * s * da) < 0: session.log.error('Error calculating peak median') return False disc = np.sqrt(counts[oidx]**2 + 2. * s * da) center = positions[oidx] + (disc - counts[oidx]) / s for idx in range(left, right + 1): if positions[idx] <= center < positions[idx + 1]: peakmax = counts[idx] break dev.start(center) multiWait([dev]) session.log.info('Found peak at %f, counts = %ld', center, peakmax) return True inst = session.instrument if not isinstance(inst, SXTalBase): session.log.error('NOT a single crystal experiment') return False if not maxpts: maxpts = inst.center_maxpts if not counter: counter = inst.center_counter half_point = int(maxpts / 2) try: countdev = session.getDevice(counter) except ConfigurationError: session.log.error('%s not found, cannot maximize against is', counter) return False preset['temporary'] = True counts = np.zeros((maxpts, ), dtype='int32') positions = np.zeros((maxpts, ), dtype='float32') positions[half_point] = dev.read() _count(*(), **preset) max_count = countdev.read()[0] max_idx = half_point counts[half_point] = max_count idx = half_point - 1 left_idx = -1 right_idx = maxpts + 10 # Search left first while idx >= 0: i = half_point - idx target = positions[half_point] - i * step dev.start(target) multiWait([dev]) session.log.info('%s = %f', dev.name, dev.read()) _count(*(), **preset) count = countdev.read()[0] counts[idx] = count positions[idx] = dev.read() if count > max_count: max_count = count max_idx = idx elif count < max_count / 2.: left_idx = idx break idx -= 1 # Test: peak in left half if counts[half_point] < max_count / 2.: right_idx = max_idx while counts[right_idx] > max_count / 2.: right_idx += 1 return findPeak(left_idx, right_idx) # Search to the right idx = half_point + 1 while idx < maxpts: i = idx - half_point target = positions[half_point] + i * step dev.start(target) multiWait([dev]) session.log.info('%s = %f', dev.name, dev.read()) _count(*(), **preset) count = countdev.read()[0] counts[idx] = count positions[idx] = dev.read() if count > max_count: max_count = count max_idx = idx elif count < max_count / 2.: right_idx = idx break idx += 1 # Test for peak limit not found if idx == maxpts and count > max_count / 2.: session.log.error('Peak out of range') return False # Test for peak in right half if counts[half_point] < max_count / 2. and left_idx < 0: left_idx = max_idx while counts[left_idx] > max_count / 2.: left_idx -= 1 if left_idx > 0 and right_idx < maxpts: return findPeak(left_idx, right_idx) session.log.error('Peak out of range') return False
def PrepareChange(self): '''is checking whether all the conditions for a change of mono are met''' # if not(self.SecShutter_is_closed()): # raise UsageError(self, 'Secondary Shutter needs to be closed, ' # 'please close by hand and retry!') # if self.NotAus(): # raise UsageError(self, 'NotAus (Emergency stop) activated, ' # 'please check and retry!') # read all inputs and check for problems if not (self._attached_magazine.read() in self.positions): raise HWError(self, 'Unknown Magazine-Position !') if self._attached_lift.read() != '2': raise HWError(self, 'Lift not at parking position!') if self._attached_liftclamp.read() != 'close': raise HWError(self, 'liftclamp should be closed!') if self._attached_tableclamp.read() != 'close': raise HWError(self, 'tableclamp should be closed!') if self._attached_magazineclamp.read() != 'close': raise HWError(self, 'magazineclamp should be closed!') if self.mono_in_lift != 'None': raise HWError( self, 'There is mono %s in the lift, please change ' 'manually!' % self.mono_in_lift) # XXX TODO: store old values of positions and offsets someplace to # recover after changing back self.log.info('will change position of several devices to the ' 'changing position, moving back is not yet implemented') # enhance precision of the devices for devname, prec in self.precisionchange.items(): dev = session.getDevice(devname) dev.precision = prec[1] self.log.debug('changing precision of the %s device to the %f', devname, prec[1]) # go to the place where a change is possible devs = [] for devname, pos in self.exchangepos.items(): dev = session.getDevice(devname) # remove after implementation of moving back self.log.info('position of the %s device was %f', devname, dev()) if isinstance(dev, HasOffset): dev.start(pos - dev.offset) self.log.debug( 'move and wait %s to the position %f - offset of %f', devname, pos, dev.offset) dev.wait() else: dev.start(pos) self.log.debug('move and wait %s to the position %f', devname, pos) dev.wait() devs.append(dev) multiWait(devs) # put precision back to normal for devname, prec in self.precisionchange.items(): dev = session.getDevice(devname) dev.precision = prec[0] self.log.debug( 'changing precision of the %s device back to ' 'the %f', devname, prec[0]) try: dev = session.getDevice('focibox') self.mono_on_table = dev.read(0) dev.comm('XMA', forcechannel=False) dev.comm('YMA', forcechannel=False) dev.driverenable = False self.log.info('focus motors disabled') except NicosError as err: self.log.error('Problem disabling foci: %s', err) # switch on inhibit and enable self._attached_enable.maw(0xef16) self._attached_inhibitrelay.maw('on') self.log.info('changer enabled and inhibit active')