This file is a example how to move a motor after performing one scan to the position determined by the counts of a given counter.
The scan has to be performed from a macro which is calling the ascan macro, in other case the scan data are not available for the further analysis. Other possibility would be to read the id of the scan and get the scan data from a nexus file, but for the Petra experiments we are not using the nexus implementation in Sardana.
The commands to use in spock would be:
p09/door/haso111tb [70]: %make_scan exp_mot01 39 40 5 1 Operation will be saved in /home/tnunez/test.txt (Spec) Scan #136 started at Fri Apr 26 15:11:11 2013. It will take at least 0:00:06 Moving to start positions... #Pt No dt exp_mot01 exp_t01 exp_c01 0 1.69902 39 1 3 1 9.71302 39.2 1 4 2 17.71 39.4 1 5 3 25.7155 39.6 1 6 4 33.715 39.8 1 5 5 41.723 40 1 4 Operation saved in /home/tnunez/test.txt (Spec) Scan #136 ended at Fri Apr 26 15:11:57 2013, taking 0:00:45.615066. Dead time 86.8% (motion dead time 48.7%) p09/door/haso111tb [71]: %ana_func exp_c01 Position to move 39.6 p09/door/haso111tb [72]:
The motor exp_mot01 is scaned and at the end of the scan it is moved to the position determined from the counts of the exp_c01 counter.
The code of the macros ist:
#!/usr/bin/env python """the demo for moving a motor after an scan""" from __future__ import print_function __all__ = ["analysis_scan"] import PyTango from sardana.macroserver.macro import * from sardana.macroserver.macro import macro import json ascan = 0 gmotor = 0 class make_scan(Macro): """Perfoms an scan keeping the data for further analysis/moves""" param_def = [ ['motor', Type.Motor, None, 'Motor to move'], ['start_pos', Type.Float, None, 'Scan start position'], ['final_pos', Type.Float, None, 'Scan final position'], ['nr_interv', Type.Integer, None, 'Number of scan intervals'], ['integ_time', Type.Float, None, 'Integration time'] ] result_def = [ [ "result", Type.String, None, "the ascan object" ]] def run(self, motor, start_pos, final_pos, nr_interv, integ_time): global ascan global gmotor gmotor = motor ascan, pars= self.createMacro("ascan",motor, start_pos, final_pos, nr_interv, integ_time) self.runMacro(ascan) result = " " for elm in ascan.data.records: result = result + str(elm.data) return result param_def = [ ['channel', Type.String, None, 'Channel to analize']] @macro() def ana_data(self, channel): """Analysis function""" pools = [] pools = self.getPools() pool = pools[0] self.output(pool) fullname = "Channel not found" for el in pool.AcqChannelList: chan = json.loads( el) if channel == chan['name']: # # from: expchan/hasysis3820ctrl/1/value # to: expchan/hasysis3820ctrl/1 # arr = chan['full_name'].split("/") fullname = "/".join(arr[0:-1]) global ascan global gmotor motor_name = gmotor.name arr_data = [] arr_motpos = [] for elm in ascan.data.records: self.output( elm.recordno) self.output( elm.data) self.output( elm.written) for dat in elm.data: if dat == fullname: arr_data.append(elm.data[fullname]) if dat == motor_name: arr_motpos.append(elm.data[motor_name]) # Compute maximum dmax = 0 for i in range(0, len(arr_data)): if arr_data[i] > dmax: dmax = arr_data[i] imax = i # Position to move arr_motpos[imax] self.output("Position to move") self.output(arr_motpos[imax]) self.mv(gmotor,31) class ana_func(Macro): """Analysis macro""" param_def = [ ['channel', Type.String, None, 'Channel to analize'] ] def prepare(self, channel): self.dmax = 0 pools = [] pools = self.getPools() pool = pools[0] self.fullname = "Channel not found" for el in pool.AcqChannelList: chan = json.loads( el) if channel == chan['name']: # # from: expchan/hasysis3820ctrl/1/value # to: expchan/hasysis3820ctrl/1 # arr = chan['full_name'].split("/") self.fullname = "/".join(arr[0:-1]) def run(self, channel): global ascan global gmotor motor_name = gmotor.name self.arr_data = [] arr_motpos = [] for elm in ascan.data.records: for dat in elm.data: if dat == self.fullname: self.arr_data.append(elm.data[self.fullname]) if dat == motor_name: arr_motpos.append(elm.data[motor_name]) self.peak() # Position to move arr_motpos[imax] self.output("Position to move") self.output(arr_motpos[self.imax]) self.mv(gmotor,arr_motpos[self.imax]) def peak(self): # Compute maximum for i in range(0, len(self.arr_data)): if self.arr_data[i] > self.dmax: self.dmax = self.arr_data[i] self.imax = i
This code can be easily extended for moving to another calculated positions.