def __init__(self, parent): """ generated sscan_gui_autogenerated file use wxFormBuilder V3.4-Beta """ sscan_gui_autogenerated.MainFrame.__init__(self, parent) # save e0 value self.e0 = 0.0 self.eNow = 0.0 self.e0EdgeEnergy = 7112.0 self.xEnergy = [] self.yTrans = [] # for each panels to display spectra, generate a graphics canvas object self.make_canvas('canvasTrans', self.m_plotTrans) self.make_canvas('canvasFluo', self.m_plotFluo) self.scan2 = Scan('lww:scan2') # scan record self.scan2.add_callback('FAZE', self.scanUpdateCallBack) # monitor scan status self.scan2.add_callback('PAUS', self.pauseCallBack) # state change PAUSE/RESUME button self.scan2.add_callback('BUSY', self.scanBusyCallBack) # scanning or stop status self.count = Scaler('BL10C:scaler1') # scaler record self.count.add_callback('CNT', self.UpdateCountCallBack) # monitor current scan point # make sense now energy PV for monitor current Energy, direct access to the DCM Energy self.eNowPV = epics.PV(self.scan2.get('P1PV')+'.RBV', callback=self.eNowCallBack) self.scanAbortPV = epics.PV("lww:AbortScans.PROC") # scan Abort PV self.scanPositionerPV = epics.PV("mobiis:m2") # scan positioner(P1PV) PV # update display from IOC values to GUI----------------------------------------------------- self.m_totalScanPoint.SetLabel(str(self.scan2.NPTS)) # total scan point in IOC self.m_currentScanPoint.SetLabel(str(self.scan2.current_point)) # current scan point in IOC #-------------------- set Region names --------------------- # Region Start names self.m_PreEdgeStart.myName = "Pre-Edge" self.m_XanesStart.myName = "XANES" self.m_Xafs1Start.myName = "XAFS1" self.m_Xafs2Start.myName = "XAFS2" self.m_Xafs3Start.myName = "XAFS3" self.m_Xafs4Start.myName = "XAFS4" # Region Stop names self.m_PreEdgeStop.myName = "Pre-Edge" self.m_XanesStop.myName = "XANES" self.m_Xafs1Stop.myName = "XAFS1" self.m_Xafs2Stop.myName = "XAFS2" self.m_Xafs3Stop.myName = "XAFS3" self.m_Xafs4Stop.myName = "XAFS4" # Region Step names self.m_PreEdgeStep.myName = "Pre-Edge" self.m_XanesStep.myName = "XANES" self.m_Xafs1Step.myName = "XAFS1" self.m_Xafs2Step.myName = "XAFS2" self.m_Xafs3Step.myName = "XAFS3" self.m_Xafs4Step.myName = "XAFS4" # Region Npts names self.m_PreEdgeNpts.myName = "Pre-Edge" self.m_XanesNpts.myName = "XANES" self.m_Xafs1Npts.myName = "XAFS1" self.m_Xafs2Npts.myName = "XAFS2" self.m_Xafs3Npts.myName = "XAFS3" self.m_Xafs4Npts.myName = "XAFS4" # Region Unit names self.m_PreEdgeUnits.myName = "Pre-Edge" self.m_XanesUnits.myName = "XANES" self.m_Xafs1Units.myName = "XAFS1" self.m_Xafs2Units.myName = "XAFS2" self.m_Xafs3Units.myName = "XAFS3" self.m_Xafs4Units.myName = "XAFS4" # make region widgets self.reg_settings = [] # append PreEdge Region items self.reg_settings.append((self.m_PreEdgeStart, self.m_PreEdgeStop, self.m_PreEdgeStep, self.m_PreEdgeNpts, self.m_PreEdgeUnits)) # Append XANES Region items self.reg_settings.append((self.m_XanesStart, self.m_XanesStop, self.m_XanesStep, self.m_XanesNpts, self.m_XanesUnits)) # Append XAFS1 Region items self.reg_settings.append((self.m_Xafs1Start, self.m_Xafs1Stop, self.m_Xafs1Step, self.m_Xafs1Npts, self.m_Xafs1Units)) # Append XAFS2 Region items self.reg_settings.append((self.m_Xafs2Start, self.m_Xafs2Stop, self.m_Xafs2Step, self.m_Xafs2Npts, self.m_Xafs2Units)) # Append XAFS3 Region items self.reg_settings.append((self.m_Xafs3Start, self.m_Xafs3Stop, self.m_Xafs3Step, self.m_Xafs3Npts, self.m_Xafs3Units)) ''' # Append XAFS4 Region items self.reg_settings.append((self.m_Xafs4Start, self.m_Xafs4Stop, self.m_Xafs4Step, self.m_Xafs4Npts, self.m_Xafs4Units)) ''' self.m_Xafs4Start.Disable() self.m_Xafs4Stop.Disable() self.m_Xafs4Step.Disable() self.m_Xafs4Npts.Disable() self.m_Xafs4Time.Disable() self.m_Xafs4Units.Disable()
class SscanBaseMainFrame(sscan_gui_autogenerated.MainFrame): def __init__(self, parent): """ generated sscan_gui_autogenerated file use wxFormBuilder V3.4-Beta """ sscan_gui_autogenerated.MainFrame.__init__(self, parent) # save e0 value self.e0 = 0.0 self.eNow = 0.0 self.e0EdgeEnergy = 7112.0 self.xEnergy = [] self.yTrans = [] # for each panels to display spectra, generate a graphics canvas object self.make_canvas('canvasTrans', self.m_plotTrans) self.make_canvas('canvasFluo', self.m_plotFluo) self.scan2 = Scan('lww:scan2') # scan record self.scan2.add_callback('FAZE', self.scanUpdateCallBack) # monitor scan status self.scan2.add_callback('PAUS', self.pauseCallBack) # state change PAUSE/RESUME button self.scan2.add_callback('BUSY', self.scanBusyCallBack) # scanning or stop status self.count = Scaler('BL10C:scaler1') # scaler record self.count.add_callback('CNT', self.UpdateCountCallBack) # monitor current scan point # make sense now energy PV for monitor current Energy, direct access to the DCM Energy self.eNowPV = epics.PV(self.scan2.get('P1PV')+'.RBV', callback=self.eNowCallBack) self.scanAbortPV = epics.PV("lww:AbortScans.PROC") # scan Abort PV self.scanPositionerPV = epics.PV("mobiis:m2") # scan positioner(P1PV) PV # update display from IOC values to GUI----------------------------------------------------- self.m_totalScanPoint.SetLabel(str(self.scan2.NPTS)) # total scan point in IOC self.m_currentScanPoint.SetLabel(str(self.scan2.current_point)) # current scan point in IOC #-------------------- set Region names --------------------- # Region Start names self.m_PreEdgeStart.myName = "Pre-Edge" self.m_XanesStart.myName = "XANES" self.m_Xafs1Start.myName = "XAFS1" self.m_Xafs2Start.myName = "XAFS2" self.m_Xafs3Start.myName = "XAFS3" self.m_Xafs4Start.myName = "XAFS4" # Region Stop names self.m_PreEdgeStop.myName = "Pre-Edge" self.m_XanesStop.myName = "XANES" self.m_Xafs1Stop.myName = "XAFS1" self.m_Xafs2Stop.myName = "XAFS2" self.m_Xafs3Stop.myName = "XAFS3" self.m_Xafs4Stop.myName = "XAFS4" # Region Step names self.m_PreEdgeStep.myName = "Pre-Edge" self.m_XanesStep.myName = "XANES" self.m_Xafs1Step.myName = "XAFS1" self.m_Xafs2Step.myName = "XAFS2" self.m_Xafs3Step.myName = "XAFS3" self.m_Xafs4Step.myName = "XAFS4" # Region Npts names self.m_PreEdgeNpts.myName = "Pre-Edge" self.m_XanesNpts.myName = "XANES" self.m_Xafs1Npts.myName = "XAFS1" self.m_Xafs2Npts.myName = "XAFS2" self.m_Xafs3Npts.myName = "XAFS3" self.m_Xafs4Npts.myName = "XAFS4" # Region Unit names self.m_PreEdgeUnits.myName = "Pre-Edge" self.m_XanesUnits.myName = "XANES" self.m_Xafs1Units.myName = "XAFS1" self.m_Xafs2Units.myName = "XAFS2" self.m_Xafs3Units.myName = "XAFS3" self.m_Xafs4Units.myName = "XAFS4" # make region widgets self.reg_settings = [] # append PreEdge Region items self.reg_settings.append((self.m_PreEdgeStart, self.m_PreEdgeStop, self.m_PreEdgeStep, self.m_PreEdgeNpts, self.m_PreEdgeUnits)) # Append XANES Region items self.reg_settings.append((self.m_XanesStart, self.m_XanesStop, self.m_XanesStep, self.m_XanesNpts, self.m_XanesUnits)) # Append XAFS1 Region items self.reg_settings.append((self.m_Xafs1Start, self.m_Xafs1Stop, self.m_Xafs1Step, self.m_Xafs1Npts, self.m_Xafs1Units)) # Append XAFS2 Region items self.reg_settings.append((self.m_Xafs2Start, self.m_Xafs2Stop, self.m_Xafs2Step, self.m_Xafs2Npts, self.m_Xafs2Units)) # Append XAFS3 Region items self.reg_settings.append((self.m_Xafs3Start, self.m_Xafs3Stop, self.m_Xafs3Step, self.m_Xafs3Npts, self.m_Xafs3Units)) ''' # Append XAFS4 Region items self.reg_settings.append((self.m_Xafs4Start, self.m_Xafs4Stop, self.m_Xafs4Step, self.m_Xafs4Npts, self.m_Xafs4Units)) ''' self.m_Xafs4Start.Disable() self.m_Xafs4Stop.Disable() self.m_Xafs4Step.Disable() self.m_Xafs4Npts.Disable() self.m_Xafs4Time.Disable() self.m_Xafs4Units.Disable() def StartScan(self, event): """ Generate xafs step scan positions(P1PA) and START scan """ self.e0EdgeEnergy = float(self.m_SetEdgeEnergy.Value) self.scanPosGen(self.e0EdgeEnergy, self.reg_settings) self.scan2._print() # we need DCM pre postion set to -200[eV] before scan start(e0-startE-200ev) prePosition = ((self.e0EdgeEnergy-abs(float(self.m_PreEdgeStart.Value))) / 1000.)-0.2 self.scanPositionerPV.put(value=prePosition, use_complete=True) # set expouse time to scaler self.count.CountTime(float(self.m_setCountTime.Value)) self.scan2.run(wait=True) self.m_totalScanPoint.SetLabel(str(self.scan2.NPTS)) self.xEnergy = [] self.yTrans = [] return def PauseScan(self, event): self.scan2.PAUS = 1 # set PAUSE return def ResumeScan(self, event): self.scan2.PAUS = 0 # set RESUME return def AbortScan(self, event): self.scanAbortPV.put(1) return def OnChoiceElement(self, event): tempEdgeEnergy = ELEM_DICT[self.m_choiceElement.GetStringSelection()] self.m_SetEdgeEnergy.SetValue(str(tempEdgeEnergy)) self.e0 = tempEdgeEnergy return def enterE0(self, event): self.e0 = float(self.m_SetEdgeEnergy.Value) for key, element in ELEM_DICT.items(): if self.e0 == float(element): self.m_choiceElement.SetStringSelection(key) return # # Region of Interest event(Start/Stop/Step/Npts/Time/Units) # def onStart(self, event): rowKey = event.GetEventObject().myName self.onVal(self, index=ROW_FIND.get(rowKey), label='start', value=unicode(event.GetEventObject().Value)) return def onStop(self, event): rowKey = event.GetEventObject().myName self.onVal(self, index=ROW_FIND.get(rowKey), label='stop', value=unicode(event.GetEventObject().Value)) return def onStep(self, event): rowKey = event.GetEventObject().myName self.onVal(self, index=ROW_FIND.get(rowKey), label='step', value=unicode(event.GetEventObject().Value)) return def onNpts(self, event): rowKey = event.GetEventObject().myName self.onVal(self, index=ROW_FIND.get(rowKey), label='npts', value=unicode(event.GetEventObject().Value)) return def onUnits(self, event): rowKey = event.GetEventObject().myName index = ROW_FIND.get(rowKey) wids = self.reg_settings[index] self.setStepNpts(wids, label='units') return def OnSize_TransCanvas(self, event): size = self.m_plotTrans.GetSize() self.canvasTrans.SetSize(size) def pauseCallBack(self, **kwargs): if kwargs['char_value'] == 'PAUSE': self.pause_button.Disable() self.resume_button.Enable() else: self.pause_button.Enable() self.resume_button.Disable() def scanBusyCallBack(self, **kwargs): if kwargs['value'] == 1: self.pause_button.Enable() self.resume_button.Disable() self.scan_button.Disable() elif kwargs['value'] == 0: # scan DONE! or Aborted! # Todo: we need DCM move to e0 position after scan DONE or IDLE # ddd = self.e0EdgeEnergy / 1000.0 # self.scanPositionerPV.put(value=ddd, use_complete=True) self.pause_button.Disable() self.resume_button.Disable() self.scan_button.Enable() def scanUpdateCallBack(self, **kwargs): """ callback method, monitor sscan status """ mode = kwargs['char_value'] # current status of sscan record. self.m_staticText3.LabelText = mode if mode == "WAIT:DETCTRS": self.m_staticText3.ForegroundColour = 'blue' self.m_currentScanPoint.SetLabel(str(self.scan2.current_point)) elif mode == 'WAIT:MOTORS': self.m_staticText3.ForegroundColour = 'red' # Todo: we need DCM move to e0 position after scan DONE or IDLE #if mode == "IDLE": # ddd = self.e0EdgeEnergy / 1000.0 # self.scanPositionerPV.put(value=ddd) # , use_complete=True) #else: # self.m_staticText3.ForegroundColour = 'black' def eNowCallBack(self, **kwargs): """ callback for now energy display from DCM read current energy from DCM. display now energy [eV] unit to GUI """ tempEnow = 1000.0 * float(kwargs['value']) self.eNow = tempEnow self.m_staticStatusGainE.LabelText = unicode("%5.2f") % tempEnow return def UpdateCountCallBack(self, **kwargs): """ callback method, display counter values(scaler1_calc(s) value) :param kwargs: :return: """ if kwargs['value'] == 0: temp = self.count.Read(use_calc=True) self.m_staticStatusCountIo.LabelText = str(temp[1]) # Io count self.m_staticStatusCountIf.LabelText = str(temp[2]) # If count self.m_staticStatusCountIt.LabelText = str(temp[3]) # It count #self.m_staticStatusCountIr.LabelText = str(temp[4]) # Ir count self.m_staticStatusCountIr.LabelText = str(round(temp[7], 5)) # Ir count energyTemp = self.eNow - self.e0EdgeEnergy self.xEnergy.append(energyTemp) TransTemp = round(temp[7], 4) self.yTrans.append(TransTemp) # transmittance plot canvasID=self.plotSpectrum(self.xEnergy, self.yTrans, 'E [eV]', 'Transmittance', self.canvasTrans) self.canvasID_panelTrans = canvasID def etok(self, energy): return np.sqrt(energy/XAFS_K2E) def ktoe(self, k): return k*k*XAFS_K2E def krange(self, start, stop, step): i = 1 kstart = np.square((start + step) / k2e) kstop = np.square(stop / k2e) while(kstart < kstop): yield kstart i += 1 kstart = np.square((start + (i*step)) / k2e) """ Update Step/Npts on XAFS region GUI """ def setStepNpts(self, wids, label, fix_npts=False): """ Set step / npts for start/stop/step/npts/units list of widgets """ start = float(wids[0].GetValue()) # start stop = float(wids[1].GetValue()) # stop step = float(wids[2].GetValue()) # step # read Units value eV or K un = wids[4] if hasattr(un, 'GetStringSelection'): units = un.GetStringSelection() else: units = un.GetLabel() if label == 'npts' or fix_npts: npts = float(max(2, wids[3].GetValue())) # npts else: try: if units == u'K': # [keV] units kstop = abs(self.etok(stop)) kstart = abs(self.etok(start)) npts = len(list(self.krange(start=kstart, stop=kstop, step=abs(step)))) else: # [eV] units npts = float(max(2, 1 + int(0.1 + abs(stop-start)/abs(step)))) except ZeroDivisionError: npts = 3 if units == u'eV' or npts == 3: wids[2].SetValue(unicode(round((stop-start)/(npts-1), 3))) # changed by LWW , act=False) if not fix_npts: try: wids[3].SetValue(unicode(npts)) # changed by LWW , act=False) except AttributeError: pass """ Update XAFS region GUI values from user event """ def onVal(self, evt=None, index=0, label=None, value=None, **kws): """ XAFS onVal """ ## if not self._initialized: ## return wids = self.reg_settings[index] e0_off = 0 if 0 == self.m_absRel.GetSelection(): # absolute e0_off = self.m_SetEdgeEnergy.GetValue() if label in ('start', 'stop', 'step', 'npts'): self.setStepNpts(wids, label) if label == 'stop' and index < len(self.reg_settings)-1: self.reg_settings[index+1][0].SetValue(unicode(value)) # by LWW, act=False) self.setStepNpts(self.reg_settings[index+1], label) elif label == 'start' and index > 0: self.reg_settings[index-1][1].SetValue(unicode(value)) # by LWW, act=False) self.setStepNpts(self.reg_settings[index-1], label) def scanPosGen(self, e0, regions): """ e0 = XAFS Edge Energy regions = Region of Interest items pre-edge(start/stop/step/npts(time)/units) xanes(start/stop/step/npts(time)/units) ..... to XAFS4 Generation format : eOut = scanPosGen(5989, [(-35, -5, 2, 1), (-5, 25, 0.1, 1), (25, 255, 2, 1)]) """ eOut = [] reg = [] # Todo: we need find disable regions and not generate tuple or position # generate region tuples for wids in regions: # wids[0]=start, wids[1]=stop, wids[2]=step, wids[3]=npts, wids[4]=units reg.append((float(wids[0].GetValue()), float(wids[1].GetValue()), float(wids[2].GetValue()), float(wids[3].GetValue()), wids[4])) # generate all step position for start, stop, step, npts, units in reg: # get units and check unit fist if hasattr(units, 'GetStringSelection'): # eV or keV unitValue = units.GetStringSelection() else: unitValue = units.GetLabel() # eV only if unitValue == u'K': # [keV] units kstop = abs(self.etok(stop)) kstart = abs(self.etok(start)) tempEout = list(self.krange(start=kstart, stop=kstop, step=abs(step))) for i in tempEout: eOut.append(e0 + i) else: for ipt in range(int((stop-start) / step + 0.1)): eOut.append(e0 + start + step * ipt) #Todo: please erase P1PA values after put new values. # self.scan2.table = eOut # write new position to scan2.P1PA # DCM IOC need keV unit self.scan2.table = list(np.divide(eOut, 1000.)) # write new position to scan2.P1PA # set epics scan2.NPTS self.scan2.npts = len(eOut) # set epics scan2.P1SM (scan mode, 0=Linear, 1=Table, 2=Fly) self.scan2.mode = 1 """--------------------------------------------------------------------------------- Make canvs for PLOT PANEL """ def make_canvas(self, canvas_name, parent_panel): """ Create plot canvas for parent Panel and make it accessible as an attribute .canvas_name :param canvas_name: string containing canvas/attribute name :param parent_panel: parent wx.Panel for canvas :return: canvas reference """ canvas = plot.PlotCanvas(parent_panel) canvas.SetInitialSize(size=parent_panel.GetSize()) canvas.SetEnableZoom(True) canvas.SetEnableGrid(True) ## canvas.SetEnableDrag(True) canvas.SetGridColour('#CCCCCC') canvas.Layout() setattr(self, canvas_name, canvas) return canvas def plotSpectrum(self, x, y, xtitle, ytitle, canvas, moreYf=None, moreYr=None, vlines=None, vline_ymax=None): """ send list of (x/y) tuples to plot output in destination(here called "where") :param x: x data(1st data) :param y: y data :param xtitle: x axis title :param ytitle: y axis title :param canvas: canvas object reference :param moreYf: optional additional ydata serise(2nd data) :param moreYr: another additional ydata serise(3rd data) :param vlines: an list of x-coordinates to place vertical(green) lines at extending over the current canvas :param vline_ymax: if ylines are supplied, supplying this determines their max. :return: ID of the canvas object drawn on(useful for clearing a canvas from outside this function; needs XXX = wx.FindWindowById(canvasID) at external point to find this canvas; then clear with XXX.Clear() ) """ # clear corresponding canvas first canvas.Clear() # zip data arrays together into list of tuples (wx.plot requires tuples) # then define "line" objects to carry the data into the plot plotData = zip(x, y) line = plot.PolyLine(plotData, colour='black', width=1) maker = plot.PolyMarker(plotData, colour='black', width=0, size=1) if moreYf is not None: plotMoreData = zip(x, moreYf) #moreLine = plot.PolyLine(plotMoreData, colour='blue', width=1) moreLine = plot.PolyMarker(plotMoreData, colour='blue', width=1) if moreYr is not None: plotMoreData2 = zip(x, moreYr) #moreLine2 = plot.PolyLine(plotMoreData2, colour='green', width=1) moreLine2 = plot.PolyMarker(plotMoreData2, colour='green', width=1) serise = [line] if moreYf is not None: serise.append(moreLine) if moreYr is not None: serise.append(moreLine2) if vlines is not None: # Now just plot somthing to ensure that autoscaling show the full range #line = plot.PolyLine([(0,1), (self.det.detector_data.mca_bins-1, 1)], # solour='white', widt=1) line = plot.PolyMarker([(0,1), (self.det.detector_data.mca_bins-1, 1)], solour='white', widt=1) serise.append(line) # plot ROI range limit lines ymax = canvas.ClientSize[1] if vline_ymax is not None: canvas.SetYSpec('min') ymax = vline_ymax for x in vlines: #line_x = plot.PolyLine([(x,1), (x,ymax)], colour='green', width=1) line_x = plot.PolyMarker([(x,1), (x,ymax)], colour='green', width=1) serise.append(line_x) serise.append(maker) gc = plot.PlotGraphics(serise, '', xtitle, ytitle) canvas.Draw(gc) return canvas.GetId()