This commit is contained in:
gac-x03da
2023-12-06 10:14:46 +01:00
parent 8428037b8f
commit c0382e79a7
6 changed files with 369 additions and 17 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
#Fri Sep 15 15:05:13 CEST 2023
#Fri Sep 22 20:55:13 CEST 2023
xscanMoveTimeout=600
autoSaveScanData=true
simulation=false
@@ -31,7 +31,7 @@ dataServerPort=-1
hideServerMessages=false
serverPort=8080
versionTrackingEnabled=true
dataPath={data}/{year}/{month}/heinrich/pshell-{date}-{time}-{name}
dataPath={data}/{year}/{month}/schirdewahn/pshell-{date}-{time}-{name}
serverEnabled=false
dataScanReleaseRecords=true
depthDimension=2
+6 -6
View File
@@ -1,7 +1,7 @@
#Fri Sep 15 19:58:11 CEST 2023
pgroup=p19371
proposal=MnTe
proposer=heinrich
#Sun Sep 24 14:00:02 CEST 2023
pgroup=p21109
proposal=EUSpecLab
proposer=schirdewahn
prefix=
sample=VA2643-MnTe
authors=Martin Heinrich|Juraj Krempasky|Matthias Muntwiler
sample=MnPc/Cu(100)
authors=Frederik Schirdewahn
+4 -4
View File
@@ -1,4 +1,4 @@
#Fri Sep 15 20:01:27 CEST 2023
LastRunDate=230915
FileSequentialNumber=19128
DaySequentialNumber=14
#Sun Sep 24 15:50:14 CEST 2023
LastRunDate=230924
FileSequentialNumber=19241
DaySequentialNumber=10
+3 -3
View File
@@ -1,4 +1,4 @@
#Wed Aug 16 18:55:25 CEST 2023
#Wed Sep 20 11:31:29 CEST 2023
spatialCalOffsetY=NaN
spatialCalOffsetX=NaN
dataPolling=0
@@ -9,7 +9,7 @@ grayscale=false
mirrored=false
spatialCalScaleX=NaN
spatialCalScaleY=NaN
colormapMax=255.0
colormapMax=10.0
rescaleOffset=0.0
roiWidth=-1
colormap=Grayscale
@@ -23,7 +23,7 @@ spatialCalUnits=mm
flipVertically=false
roiHeight=-1
flipHorizontally=false
colormapAutomatic=true
colormapAutomatic=false
dataMonitoring=false
roiY=0
roiX=0
+2 -2
View File
@@ -1,4 +1,4 @@
#Fri Sep 15 01:10:30 CEST 2023
#Sun Sep 17 00:12:13 CEST 2023
spatialCalOffsetY=NaN
spatialCalOffsetX=NaN
dataPolling=500
@@ -14,7 +14,7 @@ roiWidth=-1
colormap=Grayscale
pollingBackground=false
invert=false
colormapMin=25.0
colormapMin=15.0
rotationCrop=false
rotation=0.0
rescaleFactor=1.0
+352
View File
@@ -0,0 +1,352 @@
"""
Line/vector/area/holo scan of multiple spectral regions
save this script into your script/user folder before editing!
usage:
1. uncomment one of the MOTORS lines.
add another line if necessary.
2. uncomment one of the scan blocks and adjust the parameters.
add another block if necessary.
3. declare the regions.
4. add the regions to the REGIONS list.
5. run the script.
revisions
230912 DFS30 analyser with peakAnalyser EPICS layer
"""
# dummy scan (time series)
#MOTORS = [dummy]
# photon energy scan (do not include 'ephot' in regions in this case!)
#MOTORS = [Eph]
# phi scan
#MOTORS = [ManipulatorPhi]
# holo scan
#MOTORS = (ManipulatorPhi, ManipulatorTheta)
# 2D YZ scan
MOTORS = [ManipulatorY, ManipulatorZ]
# line scan [start, stop, step]
#POSITIONS = [0., 5., 0.5]
#SCAN = 'lscan'
# vector scan [pos1, pos2, pos3, ...]
POSITIONS = [(-1.177, 113.95), (-1.351, 113.73)]
SCAN = 'vscan'
# area scan [(start1, start2), (stop1, stop2), (step1, step2)]
# corresponding to (positioner1, positioner2)
#POSITIONS = [(-1., 114.), (+1., 116.), (20, 20)]
#ZIGZAG = True
#SCAN = 'ascan'
# holo scan
#PHI_RANGE = (-45, 45) # (tuple (min, max))
#THETA_RANGE = (-11.0, 55.0) # (tuple (min, max))
#STEPS = (15.0, 1) # (tuple (phi, theta))
#ZIGZAG = True
#POSITIONS = [(PHI_RANGE[0], THETA_RANGE[0]), (PHI_RANGE[1], THETA_RANGE[1]), STEPS]
#SCAN = 'ascan'
# seconds to wait between positioning command and triggering the detector
LATENCY = 0.0
# region setup
#
# 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
# 'ephot': photon energy (default: unchanged)
# '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: unchanged)
REGION1 = {'name': 'Fermi edge', 'efix': 119.0, 'epass': 50.}
#REGION2 = {'name': 'multiplet 1', 'elo': 167.50, 'ehi': 171.01, 'estep': 0.03, 'epass': 50., 'tstep': 0.12, 'iter': 1}
#REGION3 = {'name': 'multiplet 2', 'elo': 173.5, 'ehi': 176.8, 'estep': 0.03, 'epass': 50., 'tstep': 0.12, 'iter': 1}
# list of region dictionaries to execute at each scan position
REGIONS = [REGION1]
# close beam shutter and turn off analyser at the end of the scan
CLOSE_SHUTTER_AT_END = True
# --- DO NOT EDIT BELOW THIS LINE! ---
set_exec_pars(keep=False)
set_exec_pars(compression=True)
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']))
class SpectrumReader(ReadonlyRegisterBase, ReadonlyRegisterArray):
"""
pseudo-device class to acquire and read out a Scienta spectrum per region.
this devices starts the spectrum acquisition and organises the data file.
"""
def initialize(self):
#super(SpectrumReader, self).initialize()
self.scan_index = -1
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"
create_dataset(self.channel_begin_dataset_name, 'd')
create_dataset(self.channel_end_dataset_name, 'd')
if self.region['fixed']:
self.channel_center_dataset_name = path + "ScientaChannelCenter"
create_dataset(self.channel_center_dataset_name, 'd')
else:
self.step_energy_dataset_name = path + "ScientaStepEnergy"
create_dataset(self.step_energy_dataset_name, 'd')
if 'epass' in self.region:
self.pass_energy_dataset_name = path + "ScientaPassEnergy"
create_dataset(self.pass_energy_dataset_name, 'd')
if 'tstep' in self.region:
self.step_time_dataset_name = path + "ScientaStepTime"
create_dataset(self.step_time_dataset_name, 'd')
if 'iter' in self.region:
self.iterations_dataset_name = path + "ScientaIterations"
create_dataset(self.iterations_dataset_name, 'd')
if 'slit' in self.region:
self.slit_dataset_name = path + "ExitSlit"
create_dataset(self.slit_dataset_name, 'd')
def setup(self):
# print("spectrum.setup")
if self.scan_index != get_exec_pars().index:
self.scan_index = get_exec_pars().index
self.create_datasets()
print "scan {0}, region {1} ({2})".format(self.scan_index, self.region_index, self.region['name'])
edelta = 0.0
try:
ephot = self.region['ephot']
Eph.move(ephot)
except KeyError:
ephot = Eph.take(100)
if isinstance(ephot, float) and ephot > 0.:
try:
if self.region['cis']:
edelta = ephot - self.ephot_start
except AttributeError:
self.ephot_start = ephot
elo = self.region['elo'] + edelta
ehi = self.region['ehi'] + edelta
if self.region['fixed']:
Scienta.setAcquisitionMode("Fixed")
Scienta.centerEnergy.write(elo)
append_dataset(self.channel_center_dataset_name, elo)
else:
Scienta.setAcquisitionMode("Sweep Energy")
Scienta.lowEnergy.write(elo)
Scienta.highEnergy.write(ehi)
Scienta.stepSize.write(self.region['estep'])
append_dataset(self.step_energy_dataset_name, self.region['estep'])
try:
Scienta.setPassEnergy(int(self.region['epass']))
append_dataset(self.pass_energy_dataset_name, self.region['epass'])
except KeyError:
pass
try:
Scienta.stepTime.write(self.region['tstep'])
append_dataset(self.step_time_dataset_name, self.region['tstep'])
except KeyError:
pass
try:
Scienta.setIterations(self.region['iter'])
append_dataset(self.iterations_dataset_name, self.region['iter'])
except KeyError:
pass
try:
ExitSlit.write(self.region['slit'])
append_dataset(self.slit_dataset_name, self.region['slit'])
time.sleep(0.5)
ExitSlitY.waitReady(5000)
except KeyError:
pass
Scienta.update()
def read(self):
# print("spectrum.read")
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.1)
sp = Scienta.getSpectrum().read()
append_dataset(self.channel_begin_dataset_name, Scienta.getChannelBegin().getValue())
append_dataset(self.channel_end_dataset_name, Scienta.getChannelEnd().getValue())
return sp
def getSize(self):
# this is called before the scan starts - we have to predict the spectrum size
# wrong values don't seem to affect the data files, however
if self.region['fixed']:
nx = 1066
else:
nx = int((self.region['ehi'] - self.region['elo']) / self.region['estep']) + 1
return nx
class ImageReader(ReadonlyRegisterBase, ReadonlyRegisterMatrix):
"""
pseudo-device class to read out the Scienta image per region.
this device just reads out the Scienta image that has been acquired by SpectrumReader.
"""
def read(self):
# print("image.read")
return Scienta.getDataMatrix().read()
def getWidth(self):
# this is called before the scan starts - we have to predict the spectrum size
# wrong values don't seem to affect the data files, however
if self.region['fixed']:
nx = 1066
else:
nx = int((self.region['ehi'] - self.region['elo']) / self.region['estep']) + 1
return nx
def getHeight(self):
# this is called before the scan starts - the number of slices is an independent parameter
ny = Scienta.slices.read()
return ny
class SimpleDeviceReader(Readable):
"""
pseudo-device class to read out another device once per region.
the device must be set assigned to the source attribute.
"""
def read(self):
return self.source.read()
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
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(scan, motors, positions, regions, latency):
"""
set up detectors and run the scan
for each region we have to add a SpectrumReader and an ImageReader pseudo-device to the SENSORS list.
the order SpectrumReader, ImageReader is important because the SpectrumReader triggers the Scienta,
whereafter the ImageReader reads the image.
"""
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)
dev = SimpleDeviceReader()
dev.source = SampleCurrent
set_device_alias(dev, reader.region_name + "/SampleCurrent")
SENSORS.append(dev)
dev = SimpleDeviceReader()
dev.source = RefCurrent
set_device_alias(dev, reader.region_name + "/RefCurrent")
SENSORS.append(dev)
adjust_sensors()
set_adc_averaging()
if scan == 'ascan':
ascan(motors, SENSORS, positions[0], positions[1], positions[2], latency, False, zigzag = True, before_read=wait_beam, after_read = after_readout)
elif scan == 'lscan':
lscan(motors, SENSORS, positions[0], positions[1], positions[2], latency, False, before_read=wait_beam, after_read = after_readout)
elif scan == 'vscan':
vscan(motors, SENSORS, positions, True, latency,False, before_read=wait_beam, after_read = after_readout)
else:
print('unknown scan mode {}'.format(scan))
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])
try:
setup_live_plots(REGIONS)
task = fork(update_live_plots)
do_scan(SCAN, MOTORS, POSITIONS, REGIONS, LATENCY)
finally:
if CLOSE_SHUTTER_AT_END:
after_scan()