""" facility for multi-region scans usage: import this module into your script and call the run function with the arguments described below. this file should not be edited for specific scan parameters! this file should not be called directly! import MultiRegion MultiRegion.run(motors, positions, regions, latency=0.0, close_shutter_at_end=True) 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 from startup import * #import local def check_region(region): """ check region dictionary items and apply defaults where necessary """ region['fixed'] = 'efix' in region if region['fixed']: region['elo'] = region['efix'] region['ehi'] = region['efix'] if 'iter' not in region: region['iter'] = 1 print("region {0}: setting default iter = {1}".format(region['name'], region['iter'])) if 'cis' not in region: region['cis'] = False print("region {0}: setting default cis = {1}".format(region['name'], region['cis'])) if 'slit' not in region: region['slit'] = get_device("ExitSlit").read() print("region {0}: setting default slit = {1}".format(region['name'], region['slit'])) class SpectrumReader(ReadonlyRegisterBase, ReadonlyRegisterArray): def initialize(self): #super(SpectrumReader, self).initialize() self.scan_index = -1 self.Scienta = get_device("Scienta") self.ExitSlit = get_device("ExitSlit") self.Eph = get_device("Eph") 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): print("D" + str(self.Scienta)) ny = self.Scienta.slices.read() return ny def setup_live_plots(regions): global live_plots global current_region_index names = [region['name'] for region in regions] live_plots = plot(None, names, title="Live Spectra") current_region_index = 0 def update_live_plots(): global live_plots global current_region_index Scienta = get_device("Scienta") try: while get_context().state.running: y = Scienta.spectrum.take(100) x = Scienta.spectrumX try: series = live_plots[current_region_index].getSeries(0) series.setData(x, y) except IndexError: pass time.sleep(1.0) finally: print "Stopping live spectra" def do_scan(motors, positions, regions, latency): global SENSORS SENSORS = [] for (index, region) in enumerate(regions): check_region(region) reader = SpectrumReader() reader.region_index = index reader.region_name = "region{0}".format(index + 1) reader.region = region reader.initialize() set_device_alias(reader, reader.region_name + "/ScientaSpectrum") SENSORS.append(reader) image = ImageReader() image.region_index = index image.region = region image.initialize() set_device_alias(image, reader.region_name + "/ScientaImage") SENSORS.append(image) SENSORS.append(get_device("SampleCurrent")) SENSORS.append(get_device("RefCurrent")) adjust_sensors() set_adc_averaging() vscan(motors, SENSORS, positions, True, latency,False, before_read=wait_beam, after_read=after_readout) for (index, region) in enumerate(regions): set_attribute(get_exec_pars().scanPath + "region{0}/ScientaSpectrum".format(index + 1), "RegionName", region['name']) set_attribute(get_exec_pars().scanPath + "region{0}/ScientaImage".format(index + 1), "RegionName", region['name']) set_attribute(get_exec_pars().scanPath, "Regions", [region['name'] for region in regions]) def multi_region_run(motors, positions, regions, latency=0.0, close_shutter_at_end=True): """ see the module description for arguments. """ try: #setup_live_plots(regions) #task = fork(update_live_plots) do_scan(motors, positions, regions, latency) finally: if close_shutter_at_end: after_scan()