""" devices for multi-region scans usage: a fixed number of region devices is created on startup. to make use of them, set the region parameters and include them in the SENSORS list. this file should not be edited for specific scan parameters! this file should not be called directly! status: EXPERIMENTAL! motors: list of scan positioners. positions: discrete list of scan positions. regions: list of region dictionaries to execute at each scan position. for each region, define a python dictionary with the following items. optional items can be left unspecified and will default to the indicated values. for swept mode, include 'elo', 'ehi', 'estep', 'iter' values, but do not include 'efix'. for fixed mode, include 'efix' value, but do not include 'elo', 'ehi', 'estep', 'iter'. 'name': user-specific name of the region (for graph title and RegionName attribute in data file) 'elo': lower kinetic energy boundary of the spectrum 'ehi': upper kinetic energy boundary of the spectrum 'estep': energy step size 'efix': center kinetic energy in fixed mode 'epass': pass energy 'tstep': dwell time in seconds 'iter': number of iterations/sweeps (default 1) 'cis': True = constant initial state (photoemission line), False = constant final state (Auger peak), (default False) 'slit': exit slit (default current value) latency: seconds to wait between positioning command and triggering the detector. close_shutter_at_end: close beam shutter and turn off analyser at the end of the scan """ import ch.psi.pshell.device.ReadonlyRegisterBase as ReadonlyRegisterBase import ch.psi.pshell.device.ReadonlyRegister.ReadonlyRegisterArray as ReadonlyRegisterArray import ch.psi.pshell.device.ReadonlyRegister.ReadonlyRegisterMatrix as ReadonlyRegisterMatrix class SpectrumRegion(object): def __init__(self): self.name = "" self.index = 0 self.elo = 0. self.ehi = 0. self.efix = 0. self.estep = 0. self.epass = 0. self.tstep = 0. self.iter = 0 self.cis = False self.eofs = 0. self.slit = 0. self.fixed = False self.enabled = False def check(self): self.enabled = False def set_fixed(self, efix, epass, tstep, cis, slit): self.fixed = True def set_swept(self, elo, ehi, estep, epass, tstep, cis, slit): self.fixed = False class SpectrumReader(ReadonlyRegisterBase, ReadonlyRegisterArray): def initialize(self): self.scan_index = -1 self.Eph = get_device("Eph") self.ExitSlit = get_device("ExitSlit") self.Scienta = get_device("Scienta") def create_datasets(self): path = get_exec_pars().scanPath + self.region_name + "/" self.channel_begin_dataset_name = path + "ScientaChannelBegin" self.channel_end_dataset_name = path + "ScientaChannelEnd" self.channel_center_dataset_name = path + "ScientaChannelCenter" self.pass_energy_dataset_name = path + "ScientaPassEnergy" self.step_energy_dataset_name = path + "ScientaStepEnergy" self.step_time_dataset_name = path + "ScientaStepTime" self.iterations_dataset_name = path + "ScientaIterations" self.slit_dataset_name = path + "ExitSlit" create_dataset(self.channel_begin_dataset_name, 'd') create_dataset(self.channel_end_dataset_name, 'd') create_dataset(self.channel_center_dataset_name, 'd') create_dataset(self.pass_energy_dataset_name, 'd') create_dataset(self.step_energy_dataset_name, 'd') create_dataset(self.step_time_dataset_name, 'd') create_dataset(self.iterations_dataset_name, 'd') create_dataset(self.slit_dataset_name, 'd') def setup(self): if self.scan_index != get_exec_pars().index: self.scan_index = get_exec_pars().index self.create_datasets() if self.region_index == 0: print "scan {0}".format(self.scan_index) ephot = self.Eph.read() try: if self.region['cis']: edelta = ephot - self.ephot_start else: edelta = 0.0 except AttributeError: self.ephot_start = ephot edelta = 0.0 elo = self.region['elo'] + edelta ehi = self.region['ehi'] + edelta if self.region['fixed']: self.Scienta.setAcquisitionMode(self.Scienta.AcquisitionMode.Fixed) self.Scienta.centerEnergy.write(elo) else: self.Scienta.setAcquisitionMode(self.Scienta.AcquisitionMode.Swept) self.Scienta.lowEnergy.write(elo) self.Scienta.highEnergy.write(ehi) self.Scienta.stepSize.write(self.region['estep']) self.Scienta.setPassEnergy(self.region['epass']) self.Scienta.stepTime.write(self.region['tstep']) self.Scienta.setIterations(self.region['iter']) self.ExitSlit.write(self.region['slit']) self.Scienta.update() if self.region['fixed']: append_dataset(self.channel_center_dataset_name, elo) else: append_dataset(self.channel_begin_dataset_name, elo) append_dataset(self.channel_end_dataset_name, ehi) append_dataset(self.step_energy_dataset_name, self.region['estep']) append_dataset(self.pass_energy_dataset_name, self.region['epass']) append_dataset(self.step_time_dataset_name, self.region['tstep']) append_dataset(self.iterations_dataset_name, self.region['iter']) append_dataset(self.slit_dataset_name, self.region['slit']) def read(self): global current_region_index current_region_index = self.region_index self.setup() print("Acquiring region {0}.".format(self.region['name'])) trig_scienta() time.sleep(0.5) sp = self.Scienta.getSpectrum().read() return sp def getSize(self): if self.region['fixed']: nx = 992 else: nx = int((self.region['ehi'] - self.region['elo']) / self.region['estep']) + 1 return nx class ImageReader(ReadonlyRegisterBase, ReadonlyRegisterMatrix): def initialize(self): self.Scienta = get_device("Scienta") def read(self): return self.Scienta.getDataMatrix().read() def getWidth(self): if self.region['fixed']: nx = 992 else: nx = int((self.region['ehi'] - self.region['elo']) / self.region['estep']) + 1 return nx def getHeight(self): ny = self.Scienta.slices.read() return ny RegionSpectrumReaders = [] RegionImageReaders = [] def init_regions(num_regions): """ create the pseudo devices for the spectral regions """ RegionSpectrumReaders = [] RegionImageReaders = [] for index in range(num_regions): region = SpectrumRegion() region.index = index region.name = "region{0}".format(index + 1) reader = SpectrumReader() reader.region = region reader.initialize() set_device_alias(reader, reader.region_name + "/ScientaSpectrum") RegionSpectrumReaders.append(reader) image = ImageReader() image.region = region image.initialize() set_device_alias(image, reader.region_name + "/ScientaImage") RegionImageReaders.append(image)