def test_Link(self, session): template = { 'entry:NXentry': { 'sry': DeviceDataset('sry'), }, 'data:NXdata': { 'srlink': NXLink('/entry/sry'), } } maw(session.getDevice('sry'), 77.7) session.experiment.setDetectors([ 'det', ]) setTemplate(template) self.setScanCounter(session, 50) count(t=.1) fin = h5py.File( path.join(session.experiment.datapath, 'test%sn000051.hdf' % year), 'r') ds = fin['entry/sry'] assert (ds[0] == 77.7) ds = fin['data/srlink'] assert (ds[0] == 77.7) assert (ds.attrs['target'] == b'/entry/sry') fin.close()
def darkimage(shutter=None, nimages=1, *detlist, **preset): """Acquire one or more dark images.""" if isinstance(shutter, int): nimages, shutter = shutter, None exp = session.experiment det = exp.detectors[0] if exp.detectors else None limadev = det._attached_images[0] if det and det._attached_images else None # TODO: better ideas for shutter control if shutter: # Shutter was given, so open it maw(shutter, 'closed') elif limadev and getattr(limadev, '_shutter', None): # No shutter; try the lima way oldmode = limadev.shuttermode limadev.shuttermode = 'always_closed' try: if hasattr(exp, 'curimgtype'): exp.curimgtype = 'dark' changeImgSinkSubdir(relpath(exp.darkimagedir, exp.datapath)) return [count(*detlist, **preset) for _ in range(nimages)] finally: changeImgSinkSubdir('') if hasattr(exp, 'curimgtype'): exp.curimgtype = 'standard' if shutter: maw(shutter, 'open') elif limadev and getattr(limadev, '_shutter', None): limadev.shuttermode = oldmode
def RemoveHeCellFromPolariser(count_time): """Remove old 3He cell from polariser (only).""" gamma = session.getDevice('gamma') det = session.getDevice('det') printinfo(LARGE_SEP) printinfo('Remove old 3He cell from polariser (only)') printinfo(SMALL_SEP) gamma_cell = 60.0 printinfo(SMALL_SEP) printinfo('Measurement with 1 cell: in polariser. {}'.format( format_datetime())) printinfo(SMALL_SEP) cells1 = count(det, count_time) AddCountsToCellsFile(False, True, cells1) maw(gamma, gamma_cell) pause('Remove cell from polariser and press "Continue script" after that.') printinfo(SMALL_SEP) printinfo('Measurement without cells. {}'.format(format_datetime())) printinfo(SMALL_SEP) cells0 = count(det, count_time) AddCountsToCellsFile(False, False, cells0) polariser_cell_transmission = polariser_trans(cells0, cells1) AddPolariserTransToCellsFile(polariser_cell_transmission) AddFooterToCellsFile() pause('Cell is removed.\n\nPolariser cell:\n Transmission = {:8.2f} %'. format(polariser_cell_transmission)) printinfo(SMALL_SEP) printinfo('Cell is removed.') printinfo('Polariser cell: transmission = {:9.4f} %'.format( polariser_cell_transmission)) printinfo(LARGE_SEP)
def omscan(hkl, width=None, speed=None, timedelta=None, **kwds): """Perform a continuous omega scan at the specified Q point. The default scan width is calculated from the instrumental resolution. Examples: >>> omscan((1, 0, 0)) # with default with, speed and timedelta >>> omscan((1, 0, 0), 5) # with a width of 5 degrees >>> omscan((1, 0, 0), 5, 0.1, 1) # with width, speed and timedelta """ instr = session.instrument if not isinstance(instr, SXTalBase): raise NicosError('your instrument is not a sxtal diffractometer') if width is None: width = instr.getScanWidthFor(hkl) calc = dict(instr._extractPos(instr._calcPos(hkl))) om1 = calc['omega'] - width / 2. om2 = calc['omega'] + width / 2. cur_om = instr._attached_omega.read() if abs(cur_om - om1) > abs(cur_om - om2): om1, om2 = om2, om1 maw(instr._attached_gamma, calc['gamma'], instr._attached_nu, calc['nu'], instr._attached_omega, om1) contscan(instr._attached_omega, om1, om2, speed, timedelta)
def pos(*args, **kwds): """Move the instrument to a given (Q, E), or the last `calpos()` position. Without arguments, moves to the last position sucessfully calculated with `calpos()`. Examples: >>> pos() # last calpos() position >>> pos(1, 0, 0) # H, K, L >>> pos(1, 0, 0, -4) # H, K, L, E >>> pos(1, 0, 0, -4, 2.662) # H, K, L, E, scanconstant >>> pos(Q(1, 0, 0, -4)) # Q-E vector >>> pos(Q(1, 0, 0, -4), 2.662) # Q-E vector and scanconstant """ instr = session.instrument if not isinstance(instr, TAS): raise NicosError('your instrument device is not a triple axis device') if not args: pos = instr._last_calpos if pos is None: raise NicosError('pos() with no arguments moves to the last ' 'position calculated by calpos(), but no such ' 'position has been stored') else: pos = _convert_qe_args(args, kwds, 'pos') instr._calpos(pos, checkonly=False) if pos[5] and pos[5] != instr.scanmode: instr.scanmode = pos[5] if pos[4] and pos[4] != instr.scanconstant: instr.scanconstant = pos[4] maw(instr, pos[:4])
def tcount(time_to_measure): """Initiate a count using the flipbox 1) close the relais of the flipbox in order to burst the multifg device 2) count for x seconds (in listmode) 3) open the relais of the flipbox to prepare for a new count """ session.delay(5) tisane_relais = session.getDevice('tisane_relais') # tisane_fg1_sample = session.getDevice('tisane_fg1_sample') # tisane_fg2_det = session.getDevice('tisane_fg2_det') # maw(tisane_relais, 0) # maw(tisane_fg1_sample, 'On') # maw(tisane_fg2_det, 'On') maw(tisane_relais, 1) session.delay(5) count(time_to_measure) session.delay(5) maw(tisane_relais, 0) session.delay(5) # maw(tisane_fg1_sample, 'Off') # maw(tisane_fg2_det, 'Off') print("measurement finished")
def darkimage(shutter=None, *detlist, **preset): """Acquire a dark image.""" exp = session.experiment det = exp.detectors[0] limadev = det._attached_images[0] if det._attached_images else None # TODO: better ideas for shutter control if shutter: # Shutter was given, so open it maw(shutter, 'closed') elif limadev is not None and limadev._shutter is not None: # No shutter; try the lima way oldmode = limadev.shuttermode limadev.shuttermode = 'always_closed' try: exp.curimgtype = 'dark' changeImgSinkSubdir(relpath(exp.darkimagedir, exp.datapath)) return count(*detlist, **preset) finally: changeImgSinkSubdir('') exp.curimgtype = 'standard' if shutter: maw(shutter, 'open') elif limadev is not None and limadev._shutter is not None: limadev.shuttermode = oldmode
def test_Datasets(self, session): template = { 'entry:NXentry': { 'name': DeviceDataset('Exp', 'title'), 'def': ConstDataset('NXmonopd', 'string'), 'sry': DeviceDataset('sry', units=NXAttribute('deg', 'string')), }, } session.experiment.title = 'GurkenTitle' maw(session.getDevice('sry'), 23.7) session.experiment.setDetectors([ 'det', ]) setTemplate(template) self.setScanCounter(session, 46) count(t=.1) fin = h5py.File( path.join(session.experiment.datapath, 'test%sn000047.hdf' % year), 'r') ds = fin['entry/name'] assert (ds[0] == b'GurkenTitle') ds = fin['entry/def'] assert (ds[0] == b'NXmonopd') ds = fin['entry/sry'] assert (ds[0] == 23.7) assert (ds.attrs['units'] == b'deg') fin.close()
def test_disable_and_enable(self, session, log): """Check disable() and enable() commands.""" motor = session.getDevice('motor') maw(motor, 0) disable(motor) assert raises(MoveError, move, motor, 10) enable(motor) maw(motor, 1)
def test_rmaw(self, session, log): """Check rmaw() command.""" motor = session.getDevice('motor') mmin, mmax = motor.userlimits axis = session.getDevice('nolimit_axis') amin, amax = axis.userlimits for dm, da in ((mmin, amax), (mmax, amin)): maw(motor, 0, axis, 0) rmaw(motor, dm, axis, da / 2.) assert motor.curvalue == dm assert axis.motor.curvalue == pytest.approx(da / 2.)
def test_maw_errorhandling(self, session, log): motor = session.getDevice('motor') la = session.getDevice('limit_axis') maw(motor, 0, la, 0) log.clear() with log.assert_no_msg_matches('moving to'): assert raises(LimitError, maw, motor, 2, la, 100000) with log.assert_msg_matches( ['motor.*moving to', 'limit_axis.*moving to']): maw(motor, 2, la, 0.5) assert motor.curvalue == 2 assert la._attached_motor.curvalue == 0.5
def test_adjust(self, session, log): """Check adjust() command.""" motor = session.getDevice('motor') maw(motor, 1) adjust(motor, 0) assert motor() == 0 assert motor.offset == 1 assert motor.target == 0 adjust(motor, 0, 1) assert motor() == 1 assert motor.offset == 0 assert motor.target == 1
def NutatorsZeros_In(start=45, stop=135, step=5, t=2): adet = session.getDevice('adet') lam = session.getDevice('wavelength')() Cryopad = session.getDevice('Cryopad') maw('pc2', 0, 'pc1', 180.0 / (Cryopad.coefficients[0] * lam), 'Fout', 'off') nsteps = int((stop - start) / step) scan(['nutator1', 'nutator2'], [start, start - 90], [step, step], nsteps, adet, t=t) fit(ZerosFit, 'Asym')
def freqscan(device, start, step, numsteps): """Special scan for finding a resonance. Detector must be set to according device (e.g. cbox_0a_coil_rms) device: cbox_0a_fg_freq start: starting frequency in Hz step: steps in Hz numsteps: number of steps """ with manualscan(device): for i in range(numsteps): maw(device, start + step * i) session.delay(0.2) count(1)
def freqmes(assumed_freq, number_of_counts): """Triggers and measures the current tisane frequency. Average over `number_of_counts` measurements and print average and standard deviation. Needs to have a (rough) estimation of the frequency beforehand. Used for tisane measurements. """ import numpy valuedev = session.getDevice('tisane_fc') # set expected frequency valuedev._dev.expectedFreq = assumed_freq armdev = session.getDevice('tisane_fc_trigger') # tisane_fc_trigger -> arm; parameter in fc schreiben maw(armdev, 'arm') session.delay(0.5) value_list = [] wrong_list = [] obere_grenze = assumed_freq * 1.1 untere_grenze = assumed_freq * 0.9 print('Berechnung über %i Messpunkte' % number_of_counts) for i in range(number_of_counts): print(i + 1) value = valuedev.read(0) if untere_grenze < value < obere_grenze: value_list.append(value) else: wrong_list.append(value) session.delay(0.1) mean_value = numpy.mean(value_list) std_value = numpy.std(value_list) print("------------------------------------") print("Erwartungswert = %f" % assumed_freq) print("Untere Grenze (90) = %f" % untere_grenze) print("Obere Grenze (110) = %f" % obere_grenze) print("Anzahl aller Messpunkte = %i" % number_of_counts) print("Anzahl korrekter Messpunkte = %i" % len(value_list)) print("Mittelwert [Hz] = %f" % mean_value) print("Mittelwert [rpm] = %f" % (mean_value * 60)) print("Standardabweichung = %f" % std_value) print("Verworfene Werte: %s" % wrong_list) maw(armdev, 'idle')
def count(*detlist, **preset): try: racoll = session.getDevice('racoll') except ConfigurationError: racoll = None if racoll is None: session.log.warning('Radial collimator not found, skipping tests') else: if racoll.startcheck(): maw(racoll, 'on') std_count(*detlist, **preset) if racoll is not None: racoll.stopcheck()
def zero(): """Shut down all (static) power supplies.""" ps = [ 'hrf_0a', 'hrf_0b', 'hrf_1a', 'hrf_1b', 'hsf_0a', 'hsf_0b', 'hsf_1', 'sf_0a', 'sf_0b', 'sf_1', 'gf1', 'gf2', 'gf4', 'gf5', 'gf6', 'gf7', 'gf8', 'gf9', 'gf10', 'nse0', 'nse1' ] for powersupply in ps: powersupply = session.getDevice(powersupply) move(powersupply, 0.001) wait() # Stop regulation and turn fg_amp off stop('cbox_0a_reg_amp', 'cbox_0b_reg_amp', 'cbox_1_reg_amp') maw('cbox_0a_fg_amp', 0.001, 'cbox_0b_fg_amp', 0.001, 'cbox_1_fg_amp', 0.001)
def AddHeCellToPolariserHkl(h_index, k_index, l_index, count_time, polariser_cell_name, polariser_cell_pressure): """Add new 3He cell to polariser (only).""" gamma = session.getDevice('gamma') wavelength = session.getDevice('wavelength') det = session.getDevice('det') printinfo(LARGE_SEP) printinfo('Add new 3He cell to polariser (only)') printinfo(SMALL_SEP) printinfo('Go to hkl ({} {} {})'.format(h_index, k_index, l_index)) printinfo(SMALL_SEP) pos(h_index, k_index, l_index) gamma_hkl = gamma() gamma_cell = 60.0 printinfo(SMALL_SEP) printinfo('Measurement without cell. {}'.format(format_datetime())) printinfo(SMALL_SEP) cells0 = count(det, count_time) wavelen = wavelength() AddPolariserHeaderToCellsFile(polariser_cell_name, polariser_cell_pressure, wavelen) AddCountsToCellsFile(False, False, cells0) maw(gamma, gamma_cell) pause( 'Insert cell {} into polariser and press "Continue script" after that.' .format(polariser_cell_name)) maw(gamma, gamma_hkl) printinfo(SMALL_SEP) printinfo('Measurement with 1 cell: {} [{} bar] in polariser. {}'.format( polariser_cell_name, polariser_cell_pressure, format_datetime())) printinfo(SMALL_SEP) cells1 = count(det, count_time) AddCountsToCellsFile(False, True, cells1) polariser_cell_transmission = polariser_trans(cells0, cells1) AddPolariserTransToCellsFile(polariser_cell_transmission) pause('Cell is inserted.\n\nPolariser cell {}:\n' ' Pressure = {} bar, Transmission = {:8.2f} %'.format( polariser_cell_name, polariser_cell_pressure, polariser_cell_transmission)) printinfo(SMALL_SEP) printinfo('Cell is inserted.') printinfo('Polariser cell {}: pressure = {} bar, transmission = {:9.4f} %'. format(polariser_cell_name, polariser_cell_pressure, polariser_cell_transmission)) printinfo(LARGE_SEP)
def lubricate_liftingctr(startpos, endpos): """Lubricate the lifting counter, while going from *startpos* to *endpos*. Example: >>> lubricate_liftingctr(0, 20) """ ldev = session.getDevice('lubrication') motor = session.getDevice('liftingctr') maw(motor, startpos) session.log.info('Switching output on for 10 sec...') move(ldev, 1) session.delay(10) move(ldev, 0) session.log.info('Waiting 15 sec...') session.delay(15) maw(motor, endpos) session.log.info('Lubrication is done.')
def RemoveHeCells(h_index, k_index, l_index, count_time): """Remove old 3He cells from polariser and analyser.""" gamma = session.getDevice('gamma') det = session.getDevice('det') printinfo(LARGE_SEP) printinfo('Remove old 3He cells') printinfo(SMALL_SEP) printinfo('Go to hkl ({} {} {})'.format(h_index, k_index, l_index)) printinfo(SMALL_SEP) pos(h_index, k_index, l_index) gamma_hkl = gamma() gamma_cell = 60.0 printinfo(SMALL_SEP) printinfo('Measurement with 2 cells: in analyser/decpol and polariser. {}'. format(format_datetime())) printinfo(SMALL_SEP) cells2 = count(det, count_time) AddCountsToCellsFile(True, True, cells2) maw(gamma, gamma_cell) pause('Remove cell from polariser.') maw(gamma, gamma_hkl) printinfo(SMALL_SEP) printinfo('Measurement with 1 cell: in analyser/decpol. {}'.format( format_datetime())) printinfo(SMALL_SEP) cells1 = count(det, count_time) AddCountsToCellsFile(True, False, cells1) polariser_cell_transmission = polariser_trans(cells1, cells2) maw(gamma, gamma_cell) pause('Polariser cell:\n Transmission = {:8.2f} %.\n\n' 'Now, remove cell from analyser/decpol.'.format( polariser_cell_transmission)) maw(gamma, gamma_hkl) printinfo(SMALL_SEP) printinfo('Measurement without cells. {}'.format(format_datetime())) printinfo(SMALL_SEP) cells0 = count(det, count_time) AddCountsToCellsFile(False, False, cells0) analyser_cell_transmission = analyser_trans(cells0, cells1) AddTransToCellsFile(analyser_cell_transmission, polariser_cell_transmission) AddFooterToCellsFile() pause('Cells are removed.\n\nPolariser cell:\n' ' Transmission = {:8.2f} %,\n\nAnalyser/decpol cell:\n' ' Transmission = {:8.2f} %'.format(polariser_cell_transmission, analyser_cell_transmission)) printinfo(SMALL_SEP) printinfo('Cells are removed.') printinfo('Polariser cell: transmission = {:9.4f} %'.format( polariser_cell_transmission)) printinfo('Analyser/decpol cell: transmission = {:9.4f} %'.format( analyser_cell_transmission)) printinfo(LARGE_SEP)
def center(dev, center, step, numpoints, *args, **kwargs): """Move the given device to the maximum of a fit through a scan. Examples: >>> center(omega, 5, 0.1, 10) # scan and use a Gauss fit, move to center >>> center(omega, 5, 0.1, 10, fit='sigmoid') # use different fit function """ minvalue, newcenter, maxvalue = _scanFC(dev, center, step, numpoints, 'centering', *args, **kwargs) if newcenter is None: session.log.warning('Fit failed, no centering done') elif not minvalue <= newcenter <= maxvalue: # do not allow moving outside of the scanned region session.log.warning('Fit resulted in center outside scanning ' 'area, no centering done') else: session.log.info('centered peak for %s', dev) maw(dev, newcenter)
def nGI_stepping(n_images, p=1, angle=0, *detlist, **preset): """Performs a nGI stepping scan of G0 over p periods in n_images-1 steps. Calculates the stepping period from the angle of the grating lines to the vertical axis *angle*. Example: >>> nGI_stepping(11,1,0,t=30) # steps G0 over one period from 0 to 1.6 mm >>> # in 0.16 mm steps and count for 30 s """ import numpy as np stepwidth = 1.6 / np.cos(angle * 2 * np.pi / 360) * p / (n_images - 1) session.log.info('Starting nGI scan.') scan('G0tx', 0, stepwidth, n_images, *detlist, **preset) maw('fastshutter', 'closed') session.log.info('fastshutter closed')
def pole_figure(numrows, speed, timedelta, sampleinfo): """Run a typical pole figure measurement. The command runs 'numrows' continuous scans over the 'phis' device, which makes a full turn (360 deg) during the measurement. The changed parameter device is 'chis'. It divides the angle of 90 deg into 'numrows' steps, starting at the half of the stepsize. A 'numrows' of 6 will generate the 'chis' positions of 172.5, 157.5, 142.5, 127.5, 112.5, and 97.5 deg. Examples:: # create a pole figure measurement with 6 steps taking every 10 s a # picture >>> pole_figure(6, 0.25, 10, 'Alpha_Ti') """ chis = session.getDevice('chis') phis = session.getDevice('phis') dchi = round(90.0 / numrows, 2) / 2.0 # creating a list beginnig from 180 + dchi downsteps to 90 + dchi positions = numpy.arange(90 + dchi, 180, 2 * dchi)[::-1] maw(phis, 0) for i, chipos in enumerate(positions): move_dev(chis, round(chipos, 2), maxtries=2) sleep(5) start, end = (360., 0.) if i % 2 else (0., 360.) contscan(phis, start, end, speed, timedelta, '%s_Chis_%s' % (sampleinfo, str(chis.read()))) sleep(5) maw(phis, 0) sleep(5) maw(chis, 180) sleep(5)
def pos(*args, **kwds): """Move the instrument to a given Q, or the last `calpos()` position. Without arguments, moves to the last position sucessfully calculated with `calpos()`. Examples: >>> pos() # last calpos() position >>> pos(1, 0, 0) # H, K, L """ instr = session.instrument if not isinstance(instr, SXTalBase): raise NicosError('your instrument is not a sxtal diffractometer') if not args: pos = instr._last_calpos if pos is None: raise NicosError('pos() with no arguments moves to the last ' 'position calculated by calpos(), but no such ' 'position has been stored') else: pos = _convert_q_arg(args, 'pos') instr._calpos(pos, checkonly=False) maw(instr, pos[:4])
def setfg(freq_sample, amplitude_sample, offset_sample, shape_sample, freq_detector): """Set several values of the multi frequency generator at once and switch to burst mode. example: setfg(100, 0.5, 0.1, 'sin', 200) options for shape_samle: SINE = 'sin' Square = 'squ' Ramp = 'ramp' (with symmetry of 50%) Triangle = 'tri' Used for tisane measurements. """ multifg = session.getDevice('tisane_fg_multi') tisane_relais = session.getDevice('tisane_relais') maw(tisane_relais, 0) template = ':SOUR1:FUNC:SHAP {0};:SOUR1:FREQ {1};:SOUR1:VOLT {2};' \ ':SOUR1:VOLT:UNIT VPP;:SOUR1:VOLT:OFFS {3};' \ ':SOUR1:FUNCtion:SQU:DCYCle 50;:SOUR1:AM:STATe OFF;' \ ':SOUR1:SWEep:STATe OFF;:SOUR1:BURSt:MODE TRIG;' \ ':OUTP1:LOAD 50;:OUTP1:POL NORM;:TRIG1:SOUR EXT;' \ ':SOUR1:BURSt:NCYCles 9.9E37;:SOUR2:FUNC:SHAP SQU;' \ ':SOUR2:FREQ {4};:SOUR2:VOLT 5;:SOUR2:VOLT:UNIT VPP;' \ ':SOUR2:VOLT:OFFS 1.3;:SOUR2:FUNCtion:SQU:DCYCle 50;' \ ':SOUR2:AM:STATe OFF;:SOUR2:SWEep:STATe OFF;' \ ':SOUR2:BURSt:MODE TRIG;:OUTP2:LOAD 50;:OUTP2:POL NORM;' \ ':TRIG2:SOUR EXT;:SOUR2:BURSt:NCYCles 9.9E37;' \ ':SOUR1:BURSt:STATe ON;:SOUR2:BURSt:STATe ON;:OUTP1 ON;' \ ':OUTP2 ON;'.format(shape_sample, freq_sample, amplitude_sample, offset_sample, freq_detector) strings = dict(multifg.strings) strings['arm'] = template multifg.strings = strings move(multifg, 'arm')
def NutatorPerpendicularity(start=45, stop=135, step=5, t=2): adet = session.getDevice('adet') maw('nutator2', 0, 'nutator1', start, 'Fout', 'off', 'pc1', 0, 'pc2', 0) nsteps = int((stop - start) / step) scan('nutator1', start, step, nsteps, adet, t=t) fit(PerpFit, 'Asym')
def PC2Current(start=-4, stop=4, step=0.25, t=2): adet = session.getDevice('adet') maw('nutator2', 0, 'nutator1', 0, 'Fout', 'off', 'pc1', 0) nsteps = int((stop - start) / step) scan('pc2', start, step, nsteps, adet, t=t) fit(PCurrentFit, 'Asym')
def centerpeak(*args, **kwargs): """Center a peak with multiple scans over multiple devices. This does repeated scans of all devices to iteratively center a peak until the peak center does not shift anymore. Starting position is the current position of all devices. Non-keyword arguments are devices to scan over. At least one is required. Supported keyword arguments are: * ``rounds`` - maximum number of rounds (a round is one scan per device). The default is 5. * ``steps`` - number of steps per side for each scan. The default is 15. * ``steps_devname`` - special number of steps per side for this device. * ``step`` - step size for each scan. The default is 0.1. * ``step_devname`` - special step size for this device. * ``convergence`` - maximum delta of peak center between two scans of a device, in units of the scan step size. The default is 0.5. * ``fit`` - fit function to use for determining peak center, see below. * ``cont`` - True/False whether to use continuous scans. Default is false. * all further keyword arguments (like ``t=1``) are used as detector presets. Examples:: # default scan without special options, count 2 seconds >>> centerpeak(omega, gamma, 2) # scan with device-specific step size and number of steps >>> centerpeak(omega, gamma, step_omega=0.05, steps_omega=20, t=1) # allow a large number of rounds with very small convergence window # (1/5 of step size) >>> centerpeak(omega, gamma, rounds=10, convergence=0.2, t=1) # center using Gaussian peak fits >>> centerpeak(omega, gamma, fit='gauss', t=1) Fit functions: * ``'center_of_mass'``: default, works for any peak shape * ``'gauss'``: symmetric Gaussian """ nrounds = 5 devices = [] defsteps = 15 nsteps = {} defstepsize = 0.1 stepsizes = {} preset = {} fit = 'center_of_mass' allowed_fit = {'center_of_mass', 'gauss'} continuous = False convergence = 0.5 for devname in args: if isinstance(devname, number_types): preset['t'] = devname else: devices.append(session.getDevice(devname, Moveable)) if not devices: raise UsageError('need at least one device to scan over') for kw, value in kwargs.items(): if kw == 'rounds': nrounds = value elif kw == 'fit': if value not in allowed_fit: raise UsageError('fit function %s is not allowed' % value) fit = value elif kw == 'convergence': convergence = value elif kw == 'steps': defsteps = value elif kw == 'step': defstepsize = value elif kw == 'cont': continuous = bool(value) elif kw.startswith('step_'): dev = session.getDevice(kw[5:], Moveable) if dev not in devices: raise UsageError('device %s not in list of devices to scan' % dev) stepsizes[dev] = value elif kw.startswith('steps_'): dev = session.getDevice(kw[6:], Moveable) if dev not in devices: raise UsageError('device %s not in list of devices to scan' % dev) nsteps[dev] = value else: preset[kw] = value for dev in devices: if dev not in stepsizes: stepsizes[dev] = defstepsize if dev not in nsteps: nsteps[dev] = defsteps # main loop lastround = {dev: dev.read() for dev in devices} for i in range(nrounds): session.log.info('Round %d of %d', i + 1, nrounds) session.log.info('*' * 100) # results of last round thisround = {} for dev in devices: center = lastround[dev] if continuous: contscan(dev, center - nsteps[dev] * stepsizes[dev], center + nsteps[dev] * stepsizes[dev], speed=stepsizes[dev] / preset.get('t', 1), timedelta=preset.get('t', 1)) else: cscan(dev, center, stepsizes[dev], nsteps[dev], *devices, **preset) if session.mode == SIMULATION: thisround[dev] = center elif fit == 'center_of_mass': thisround[dev] = center_of_mass() elif fit == 'gauss': params, _ = gauss() minvalue = center - abs(stepsizes[dev] * nsteps[dev]) maxvalue = center + abs(stepsizes[dev] * nsteps[dev]) if params is None: maw(dev, center) session.log.error('no Gaussian fit found in this scan') return fit_center, fit_ampl, _fit_fwhm, fit_bkgd = params if math.isnan(fit_center) or \ not (minvalue <= fit_center <= maxvalue) or \ fit_ampl < 0.5 * fit_bkgd: maw(dev, center) session.log.error('Gaussian peak too small, or center ' 'outside scanning area') return thisround[dev] = fit_center maw(dev, thisround[dev]) session.log.info('*' * 100) again = False for dev in devices: diff = abs(lastround[dev] - thisround[dev]) session.log.info('%-10s center: %8.6g -> %8.6g (delta %8.6g)', dev, lastround[dev], thisround[dev], diff) if session.mode == SIMULATION: again = i < 1 if i == 1: session.log.info('=> dry run: limiting to 2 rounds') elif diff > convergence * stepsizes[dev]: if i == nrounds - 1: session.log.info( '=> would need another round, but command' ' limited to %d rounds', nrounds) else: session.log.info('=> needs another round') again = True if not again: session.log.info('=> found convergence on peak:') for dev in devices: session.log.info('%-10s : %s', dev, dev.format(dev())) return lastround = thisround
def AddHeCells(h_index, k_index, l_index, count_time, analyser_cell_name, analyser_cell_pressure, polariser_cell_name, polariser_cell_pressure): """Add new 3He cells to analyser and polariser.""" gamma = session.getDevice('gamma') wavelength = session.getDevice('wavelength') det = session.getDevice('det') printinfo(LARGE_SEP) printinfo('Add new 3He cells') printinfo(SMALL_SEP) printinfo('Go to hkl ({} {} {})'.format(h_index, k_index, l_index)) printinfo(SMALL_SEP) pos(h_index, k_index, l_index) gamma_hkl = gamma() gamma_cell = 60.0 printinfo(SMALL_SEP) printinfo('Measurement without cells. {}'.format(format_datetime())) printinfo(SMALL_SEP) cells0 = count(det, count_time) wavelen = wavelength() AddHeaderToCellsFile(analyser_cell_name, analyser_cell_pressure, polariser_cell_name, polariser_cell_pressure, wavelen) AddCountsToCellsFile(False, False, cells0) maw(gamma, gamma_cell) pause('Insert cell {} into analyser/decpol.'.format(analyser_cell_name)) maw(gamma, gamma_hkl) printinfo(SMALL_SEP) printinfo( 'Measurement with 1 cell: {} [{} bar] in analyser/decpol. {}'.format( analyser_cell_name, analyser_cell_pressure, format_datetime())) printinfo(SMALL_SEP) cells1 = count(det, count_time) AddCountsToCellsFile(True, False, cells1) analyser_cell_transmission = analyser_trans(cells0, cells1) maw(gamma, gamma_cell) pause('Analyser/decpol cell {}:\n Pressure = {} bar, ' 'Transmission = {:8.2f} %.\n\nNow, insert cell {} into polariser.'. format(analyser_cell_name, analyser_cell_pressure, analyser_cell_transmission, polariser_cell_name)) maw(gamma, gamma_hkl) printinfo(SMALL_SEP) printinfo('Measurement with 2 cells: {} [{} bar] in analyser/decpol and ' '{} [{} bar] in polariser. {}'.format(analyser_cell_name, analyser_cell_pressure, polariser_cell_name, polariser_cell_pressure, format_datetime())) printinfo(SMALL_SEP) cells2 = count(det, count_time) AddCountsToCellsFile(True, True, cells2) polariser_cell_transmission = polariser_trans(cells1, cells2) AddTransToCellsFile(analyser_cell_transmission, polariser_cell_transmission) pause('Cells are inserted.\n\nAnalyser/decpol cell {}:\n' ' Pressure = {} bar, Transmission = {:8.2f} %,\n\n' 'Polariser cell {}:\n Pressure = {} bar, Transmission = {:8.2f} %'. format(analyser_cell_name, analyser_cell_pressure, analyser_cell_transmission, polariser_cell_name, polariser_cell_pressure, polariser_cell_transmission)) printinfo(SMALL_SEP) printinfo('Cells are inserted.') printinfo( 'Analyser/decpol cell {}: pressure = {} bar, transmission = {:9.4f} %'. format(analyser_cell_name, analyser_cell_pressure, analyser_cell_transmission)) printinfo('Polariser cell {}: pressure = {} bar, transmission = {:9.4f} %'. format(polariser_cell_name, polariser_cell_pressure, polariser_cell_transmission)) printinfo(LARGE_SEP)
def test_maw(self, session, log): """Check maw() command.""" motor = session.getDevice('motor') for pos in (min(motor.userlimits), 0, max(motor.userlimits)): maw(motor, pos) assert motor.curvalue == pos