def buffering_low(self): status = PV('status') if not util.check_device('C1', self.proc) and status.get() in range(0,3): print "device not connected" return False count3 = PV('in_counts_3') low_3 = PV('low_limit_3') low_4 = PV('low_limit_4') trig_buffer = PV('trig_buffer') init = PV('initiate') poll(evt=1.e-5, iot=0.01) data3 = [] def getCount3(pvname, value, **kw): data3.append(value) if util.put_check(low_3, 0.0) and util.put_check(low_4, 0.0) and util.put_check(trig_buffer, 1000) and util.put_fuzzy('analog_out_period', 10e-5, 0.05): pass else: print "setting not taking place" return False, False count3.add_callback(getCount3) init.put(1) t0 = time.time() while time.time() - t0 < 3: poll(evt=1.e-5, iot=0.01) time.sleep(2) return len(data3)
def test_force_connect(): pv = PV(pvnames.double_arrays[0], auto_monitor=True) print("Connecting") assert pv.wait_for_connection(5.0) print("SUM", pv.get().sum()) time.sleep(3) print("Disconnecting") pv.disconnect() print("Reconnecting") pv.force_connect() assert pv.wait_for_connection(5.0) called = {'called': False} def callback(value=None, **kwargs): called['called'] = True print("update", value.sum()) pv.add_callback(callback) time.sleep(1) assert pv.get() is not None assert called['called']
def discriminator_limits(self): if not self.connected: print "Device not connected" return False polarity3, polarity4, trig_buffer, int_time, init = PV( 'digital_out_polarity_3'), PV('digital_out_polarity_4'), PV( 'trig_buffer'), PV('analog_out_period'), PV('initiate') util.put_check(trig_buffer, 1000) int_time.put(10e-4) poll(evt=1.e-5, iot=0.01) count3 = PV('in_counts_3') count4 = PV('in_counts_4') low_limit3 = PV('low_limit_3') low_limit4 = PV('low_limit_4') high_limit3 = PV('high_limit_3') high_limit4 = PV('high_limit_4') util.put_check(low_limit3, 1.0) util.put_check(low_limit4, 1.0) util.put_check(polarity3, 1) util.put_check(polarity4, 1) util.put_check(high_limit3, 5.0) util.put_check(high_limit4, 5.0) poll(evt=1.e-5, iot=0.01) setting = self.proc.expect([pexpect.TIMEOUT, 'Error setting C400'], timeout=1) if setting == 1: polarity3.put(1) polarity4.put(1) data = [] data2 = [] def getCount(pvname, value, **kw): data.append(value) def getCount2(pvname, value, **kw): data2.append(value) count3.add_callback(getCount) count4.add_callback(getCount2) poll(evt=1.e-5, iot=0.01) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 3: poll(evt=1.e-5, iot=0.01) util.put_check(low_limit3, 0.0) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 3: poll(evt=1.e-5, iot=0.01) return sum(data), sum(data2)
def start_stop(self): data = [] if not self.connected: print "Device not connected" return False count, trig_mode, trig_buffer, int_time, low3, init = PV( 'in_counts_3'), PV('trig_mode'), PV('trig_buffer'), PV( 'analog_out_period'), PV('low_limit_3'), PV('initiate') util.put_check(trig_mode, 1) util.put_check(low3, 0.0) util.put_check(trig_buffer, 0) int_time.put(10e-5) poll(evt=1.e-5, iot=0.01) def getCount(pvname, value, **kw): data.append(value) count.add_callback(getCount) poll(evt=1.e-5, iot=0.01) init.put(1) poll(evt=0.5, iot=0.5) t0 = time.time() while time.time() - t0 < 30 and len(data) < 500: pass init.put(0) poll(evt=0.5, iot=0.5) return len(data), caget('stopped_state'), caget('running_state')
def start_processes(counter_pv, data_pv, logger, *args): """ This is a main thread that starts thread reacting to the callback, starts the consuming process, and sets a callback on the frame counter PV change. The function then awaits for the data in the exit queue that indicates that all frames have been processed. The functin cancells the callback on exit. Parameters ---------- counter_pv : str a PV string for the area detector frame counter data_pv : str a PV string for the area detector frame data logger : Logger a Logger instance, typically synchronized with the consuming process logger *args : list a list of arguments specific to the client process Returns ------- None """ data_thread = CAThread(target = deliver_data, args=(data_pv, logger,)) data_thread.start() start_process(globals.process_dataq, logger, *args) cntr = PV(counter_pv) cntr.add_callback(on_change, index = 1) globals.exitq.get() cntr.clear_callbacks()
def start(self, pv_name=None): """ Emit a signal for each local variable of EPICS PV. this will call registered callbacks and allow clients to initialize themselves with monitored variable values. """ for name in self.local_dict.iterkeys(): if pv_name is None or pv_name == name: self.emit(self.SIGNAL, name) # Connect to actual EPICs PVs for name in self.pv_dict.iterkeys(): if pv_name is None or pv_name == name: pv = self.pv_dict.get(name) if pv is None: # Just creating PV object but not accessing any of its # properties will not cause any network traffic # (i.e. connection (attempt) to the pv). pv = PV(name, connection_callback=self.connection_callback) self.pv_dict[name] = pv # print "ADDING CALLBACK FOR PV: %s" % name pv.add_callback(self.pv_callback, index=0) #else: self.emit(self.SIGNAL, name)
def burst_size(self): if not self.connected: print "Device not connected" return False data = [] count = PV('in_counts_3') trig_mode = PV('trig_mode') low3 = PV('low_limit_3') int_time = PV('analog_out_period') trig_burst = PV('trig_burst') trig_buffer = PV('trig_buffer') init = PV('initiate') poll(evt=1.e-5, iot=0.01) util.put_check(trig_mode, 0) low3.put(0.0) int_time.put(10e-4) util.put_check(trig_buffer, 0) util.put_check(trig_burst, 1000) poll(evt=1.e-5, iot=0.01) def getCount(pvname, value, **kw): data.append(value) count.add_callback(getCount) t0 = time.time() init.put(1) t1 = time.time() # while caget('paused_state') != 1: # if time.time() - t1 > 30: # return "pause state never reached" # else: # pass pass1 = len(data) util.put_check(trig_burst, 10000) time.sleep(0.1) t2 = time.time() init.put(1) t3 = time.time() # while caget('paused_state') != 1: # if time.time() - t3 > 30: # return "pause state never reached 2nd time" # else: # pass pass2 = len(data) - pass1 # teardown util.put_check(trig_burst, 0) return pass1, pass2
class AutoReplay: run_in_progress = 0 run_number = 0 last_replay_run_number = 0 def onRunNumberChange(self, pvname=None, value=None, host=None, **kws): self.run_number = int(value) print "run number changed {}".format(self.run_number) def onRunInProgressChange(self, pvname=None, value=None, host=None, **kws): new_value = int(value) print "test" if (self.run_in_progress == 1) and (new_value == 0): subprocess.call([ "cd /home/cdaq/hallc-online/hallc_replay_sidis_fall18 && ./run_full_auto_sidis.sh {} &> logs/auto_replay_{}.log & " .format(int(self.run_number), int(self.run_number)) ], shell=True) self.run_in_progress = new_value self.last_replay_run_number = self.run_number self.run_in_progress = new_value def Print(self): print self.run_number print self.run_in_progress def __init__(self): print "derp" self.last_replay_run_number = 0 self.run_number_pv = PV('hcCOINRunNumber') self.run_number_pv.add_callback(self.onRunNumberChange) self.run_in_progress_pv = PV('hcCOINRunInProgress') self.run_in_progress_pv.add_callback(self.onRunInProgressChange) self.run_number = self.run_number_pv.get() self.run_in_progress = self.run_in_progress_pv.get()
def abort(self): if not self.connected: print "Device not conncted" return False init = PV('initiate') data = [] a_in_1 = PV('analogIn1') poll(evt=1.e-5, iot=0.01) def getData1(pvname, value, **kw): if value != 0: data.append(value) a_in_1.add_callback(getData1) poll(evt=1.e-5, iot=0.01) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 10: poll(evt=1.e-5, iot=0.01) if len(data) >= 50: init.put(0) time.sleep(2) return len(data)
def buffering(self, value): check = util.expect(self.proc, ["C1"]) count3 = PV('in_counts_3') low3 = PV('low_limit_3') trig_buffer = PV('trig_buffer', auto_monitor=False) int_time = PV('analog_out_period') init = PV('initiate') poll(evt=1.e-5, iot=0.01) data = [] #camonitor('trig_buffer') def getCount1(pvname, value, **kw): data.append(value) util.put_check(low3, 0.0) util.put_check(trig_buffer, value) util.put_fuzzy('analog_out_period', 10e-5, 0.05) print "set value " + str(value) print "buffer value " + str(trig_buffer.get()) #time.sleep(5) #print "buffer value " + str(trig_buffer.get()) count3.add_callback(getCount1) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 5: poll(evt=1.e-5, iot=0.01) run1 = len(data) return run1
def buffer_mode(self, value): data = [] if not self.connected: print "Device not connected" return False time.sleep(1) acquisition_mode = PV('acquisition_mode') buffered_mode = PV('buffered_acquisition') stopcount = PV('stop_count') current1 = PV('current_in_1') init = PV('initiate') acquisition_mode.put(1) poll(evt=1.0, iot=1.0) buffered_mode.put(1) poll(evt=1.0, iot=1.0) stopcount.put(value) poll(evt=1.0, iot=1.0) buff1 = buffered_mode.get() def getCount(pvname, value, **kw): data.append(value) current1.add_callback(getCount) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 4: poll(evt=1.e-5, iot=0.01) return len(data)
def abort(self): initial_check = util.expect(self.proc, ["A1"]) init = PV('initiate') data = [] a_in_1 = PV('analogIn1') poll(evt=1.e-5, iot=0.01) def getData1(pvname, value, **kw): if value != 0: data.append(value) a_in_1.add_callback(getData1) poll(evt=1.e-5, iot=0.01) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 10: poll(evt=1.e-5, iot=0.01) if len(data) >= 50: init.put(0) time.sleep(2) return len(data)
def setupBlComm(): # global message_string_pv thread.start_new_thread(process_commands,(.05,)) # message_string_pv = PV(beamlineName + "_comm:message_string") comm_pv = PV(beamlineName + "_comm:command_s") comm_pv.put("\n",wait=True) comm_pv.add_callback(comm_cb)
def run_test_sofb(): """Test SOFB IOC frequency.""" def print_time(pvname, value, **kwargs): _ = pvname nonlocal times, values # times.append(time.time()) times.append(kwargs['timestamp']) values.append(value[0]) print(datetime.datetime.fromtimestamp(times[-1]).isoformat(), value[0]) times = [] values = [] pv = PV('SI-Glob:AP-SOFB:SlowOrbX-Mon') pv.wait_for_connection() pv.add_callback(print_time) total = 30 time.sleep(total) # times = values print(f'frequency: {len(times)/total:.2f} Hz') print(f'average time: {np.mean(np.diff(times))*1000:.2f} ms') print(f'std time: {np.std(np.diff(times))*1000:.2f} ms') print(f'min time: {np.min(np.diff(times))*1000:.2f} ms') print(f'max time: {np.max(np.diff(times))*1000:.2f} ms') np.savetxt('si_sofb.txt', times) pv.clear_callbacks()
def stopcount_value(self, value): initial_check = util.expect(self.proc, ["A1"]) data1 = [] def getData1(pvname, value, **kw): if value != 0: data1.append(value) analog1 = PV('analogIn1') stop_count = PV('outStopCount') init = PV('initiate') analog2 = PV('analogIn2') poll(evt=1.e-5, iot=0.01) analog1.wait_for_connection() analog2.wait_for_connection() init.wait_for_connection() stop_count.wait_for_connection() util.put_check(stop_count, value) analog1.add_callback(getData1) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 10: poll(evt=1.e-5, iot=0.01) run = len(data1) return run
class TestApp(npyscreen.NPSApp): def onValueChange(self,pvname=None, value=None, host=None, **kws): self.rc.value = value def __init__(self): self.run_number_pv = PV('hcCOINRunNumber') self.run_charge_pv = PV('hcCOINRunAccumulatedCharge') self.setting_charge_pv = PV('hcRunSettingAccumulatedCharge') self.run_charge_pv.add_callback(self.onValueChange) def main(self): # These lines create the form and populate it with widgets. # A fairly complex screen in only 8 or so lines of code - a line for each control. npyscreen.setTheme(npyscreen.Themes.ColorfulTheme) F = npyscreen.ActionFormWithMenus(name = "Welcome to Npyscreen",) self.t = F.add(npyscreen.TitleText, name = "Run Number:", value=str(int(self.run_number_pv.get()))) self.rc = F.add(npyscreen.TitleText, name = "Run Charge:", value=str(float(self.run_charge_pv.get()))) fn = F.add(npyscreen.TitleFilename, name = "Filename:") dt = F.add(npyscreen.TitleDateCombo, name = "Date:", value=datetime.datetime.now(), use_datetime=True) s = F.add(npyscreen.TitleSlider, out_of=12, name = "Slider") ml_value= str(datetime.datetime.now())+ "\n"; ml= F.add(npyscreen.MultiLineEdit, value = ml_value, max_height=5, rely=9) ms= F.add(npyscreen.TitleSelectOne, max_height=4, value = [1,], name="Pick One", values = ["Option1","Option2","Option3"], scroll_exit=True) ms2= F.add(npyscreen.TitleMultiSelect, max_height=4, value = [1,], name="Pick Several", values = ["Option1","Option2","Option3"], scroll_exit=True) # This lets the user play with the Form. F.edit()
def test_waveform_callback_with_count_arg(self): values = [] # NOTE: do not use get_pv() here, as `count` is incompatible with # the cache wf = PV(pvnames.char_arr_pv, count=32) def onChanges(pvname=None, value=None, char_value=None, **kw): write('PV %s %s, %s Changed!\n' % (pvname, repr(value), char_value)) values.append(value) wf.add_callback(onChanges) write('Added a callback. Now wait for changes...\n') t0 = time.time() while time.time() - t0 < 3: time.sleep(1.e-4) if len(values) > 0: break self.failUnless(len(values) > 0) self.assertEquals(len(values[0]), 32) wf.clear_callbacks()
def test_stopcount(): proc = pexpect.spawn( "/home/steve/workspace/ig2_medical/ig2-2.6.7 /home/steve/workspace/ig2_medical/m10_stopcount.xml" ) proc.expect([pexpect.TIMEOUT, pexpect.EOF, 'Announce\(\) success'], timeout=10) print proc.after #util.pv_check('status', 0) stop = 1001 data1 = [] data2 = [] def getData1(pvname, value, **kw): if value != 0: data1.append(value) def getData2(pvname, value, **kw): if value != 0: data2.append(value) analog1 = PV('analogIn1') stop_count = PV('outStopCount') init = PV('initiate') analog2 = PV('analogIn2') analog1.wait_for_connection() analog2.wait_for_connection() init.wait_for_connection() stop_count.wait_for_connection() analog1.add_callback(getData1) if util.put_check('outStopCount', stop): init.put(1) t0 = time.time() while time.time() - t0 < 30: poll(evt=1.e-5, iot=0.01) else: print "Stopcount not set" return False buffered_run = len(data1) analog2.add_callback(getData2) time.sleep(2) if util.put_check('outStopCount', -1): init.put(1) t0 = time.time() while time.time() - t0 < 30: poll(evt=1.e-5, iot=0.01) else: print "Stopcount not set 2nd time" return False unbuffered_run = len(data2) return buffered_run, unbuffered_run
class ioc(): #_____________________________________________________________________________ def __init__(self, config): host = config["host"].strip() self.nam = config["ioc"].strip() pvnam = "iocmon:" + host + ":" + self.nam #print pvnam, self.description #color map self.col = {"ok": "00ff00", "alarm": "ff0000", "nocon": "ffffff"} self.pv_stat = PV(pvnam + ":status", connection_callback=self.on_stat_conn) self.status = self.pv_stat.get(as_string=True) self.severity = self.pv_stat.severity if self.status == None: self.status = " " self.severity = -1 self.description = " " print "Error: no connection to", pvnam + ":status" return self.pv_stat.add_callback(self.on_stat_update) self.description = caget(pvnam + ":description") #_____________________________________________________________________________ def make_html(self, tab_lines): #html content for the ioc bgcol = self.col["alarm"] if self.severity == 0: bgcol = self.col["ok"] if self.severity == -1: bgcol = self.col["nocon"] tab = '<td style="background-color: #' + bgcol + '">' + self.nam + '</td>' tab += '<td style="background-color: #' + bgcol + '">' + self.status + '</td>' tab += '<td>' + self.description + '</td>' tab_lines.append(tab) #_____________________________________________________________________________ def on_stat_update(self, char_value, severity, **kws): self.status = char_value self.severity = severity #print severity, char_value #_____________________________________________________________________________ def on_stat_conn(self, conn, **kws): if conn == True: return self.status = " " self.severity = -1
def buffering(self): poll(evt=1.9, iot=0.01) status = PV('status') poll(evt=1.9, iot=0.01) start_time = time.time() while status.get() not in (0, 3): print str(status.get()) + "not connected yet" print status.info print status connected = status.get() in (0, 3) poll(evt=1.0, iot=0.51) if time.time() - start_time >= 60: connected = False print "timed out" break print util.expect(self.proc, ["C1"]) count3 = PV('in_counts_3') count4 = PV('in_counts_4') low_3 = PV('low_limit_3') low_4 = PV('low_limit_4') trig_buffer = PV('trig_buffer') init = PV('initiate') poll(evt=1.e-5, iot=0.01) data3 = [] data4 = [] def getCount3(pvname, value, **kw): data3.append(value) def getCount4(pvname, value, **kw): data4.append(value) if util.put_check( low_3, 0.0) and util.put_check(low_4, 0.0) and util.put_check( trig_buffer, 1000) and util.put_fuzzy( 'analog_out_period', 10e-5, 0.05): pass else: print "setting not taking place" return False, False t0 = time.time() time.sleep(1) count3.add_callback(getCount3) count4.add_callback(getCount4) poll(evt=1.e-5, iot=0.01) init.put(1) poll(evt=1.e-5, iot=0.01) while time.time() - t0 < 3: poll(evt=1.e-5, iot=0.01) # end = self.proc.expect( # ['Announce\(\) success', pexpect.TIMEOUT, pexpect.EOF], timeout=3) return len(data3), len(data4)
def accumulate_mode(self): data = [] if not self.connected: print "Device not connected" return False count = PV('in_counts_3') low_3 = PV('low_limit_3') trig_buffer = PV('trig_buffer') int_time = PV('analog_out_period') accum_mode = PV('accum_mode') init = PV('initiate') poll(evt=1.e-5, iot=0.01) util.put_check(low_3, 0.0) util.put_check(trig_buffer, 1000) int_time.put(10e-5) poll(evt=1.e-5, iot=0.01) def getCount(pvname, value, **kw): data.append(value) count.add_callback(getCount) time.sleep(1) def run(mode): util.put_check(accum_mode, mode) time.sleep(1) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 5: poll(evt=1.e-5, iot=0.01) init.put(0) poll(evt=1.e-5, iot=0.01) run(0) if len(data) > 10: non_accum = data[-1] - data[-6] else: print "didnt get data" return False run(1) if len(data) > 10: accum = data[-1] - data[-6] else: print "didnt get data 2nd time" return False # teardown util.put_check(accum_mode, 0) print data return non_accum, accum, data[0]
def stopcount(self): #self.proc = pexpect.spawn("/home/steve/workspace/ig2_medical/ig2-2.6.7 /home/steve/workspace/ig2_medical/m10_stopcount.xml") if not self.connected: print "Device not connected" return False #util.pv_check('status', 0) #self.stop = 1001 def getData1(pvname, value, **kw): if value != 0: self.data1.append(value) def getData2(pvname, value, **kw): if value != 0: self.data2.append(value) analog1 = PV('analogIn1') stop_count = PV('outStopCount') init = PV('initiate') analog2 = PV('analogIn2') poll(evt=1.e-5, iot=0.01) analog1.wait_for_connection() analog2.wait_for_connection() init.wait_for_connection() stop_count.wait_for_connection() analog1.add_callback(getData1) if util.put_check(stop_count, self.stop): init.put(1) t0 = time.time() while time.time() - t0 < 10: poll(evt=1.e-5, iot=0.01) else: print "Stopcount not set" return False buffered_run = len(self.data1) analog2.add_callback(getData2) if util.put_check(stop_count, -1): init.put(1) t0 = time.time() while time.time() - t0 < 10: poll(evt=1.e-5, iot=0.01) else: print "Stopcount not set 2nd time" return False unbuffered_run = len(self.data2) print unbuffered_run, buffered_run return buffered_run, unbuffered_run
def buffering(self): if not self.connected: print "Device not connected" return False count3 = PV('in_counts_3') count4 = PV('in_counts_4') low3 = PV('low_limit_3') low4 = PV('low_limit_4') trig_buffer = PV('trig_buffer') int_time = PV('analog_out_period') init = PV('initiate') poll(evt=1.e-5, iot=0.01) data1 = [] data2 = [] def getCount1(pvname, value, **kw): data1.append(value) def getCount2(pvname, value, **kw): data2.append(value) if util.put_check( low3, 0.0) and util.put_check(low4, 0.0) and util.put_check( trig_buffer, 1000) and util.put_fuzzy( 'analog_out_period', 10e-5, 0.05): pass else: print "setting not taking place" return False, False time.sleep(1) count3.add_callback(getCount1) init.put(1) t0 = time.time() while time.time() - t0 < 3: poll(evt=1.e-5, iot=0.01) run1 = len(data1) count3.remove_callback(1) count3.add_callback(getCount2) if util.put_check(trig_buffer, 500): pass else: print "setting 2nd time not taking place" return False, False init.put(1) t1 = time.time() while time.time() - t1 < 3: poll(evt=1.e-5, iot=0.01) run2 = len(data2) return run1, run2
def integration_set(self): data = [] if not self.connected: print "Device not connected" return False count = PV('in_counts_3') trig_mode, low3, low4, trig_buffer, int_time, init = PV( 'trig_mode'), PV('low_limit_3'), PV('low_limit_4'), PV( 'trig_buffer'), PV('analog_out_period'), PV('initiate') trig_mode.put(1) low3.put(0.0) low4.put(0.0) util.put_check(trig_buffer, 1000) #util.put_fuzzy('analog_out_period', 10e-5, 0.01) int_time.put(10e-5) poll(evt=1.e-5, iot=0.01) def getCount(pvname, value, **kw): data.append(value) count.add_callback(getCount) init.put(1) print trig_mode.get(), low3.get(), low4.get(), trig_buffer.get( ), int_time.get() print count.value print count.get() poll(evt=2.0, iot=2.01) print count.value print count.get() fast = count.value int_time.put(10e-3) t1 = time.time() # while caget('analog_out_period') != 10e-3: # if time.time() - t1 > 20: # return "integration period is not being set" # else: # pass init.put(1) time.sleep(5) slow = count.value if slow and fast: print slow, fast return slow / (fast + 0.01 * fast), slow / (fast - 0.01 * fast) else: print slow, fast return False
def enable_stopcount(self): if not self.connected: print "Device not connected" return False stop = 100 data1 = [] data2 = [] def getData1(pvname, value, **kw): if value != 0: data1.append(value) def getData2(pvname, value, **kw): if value != 0: data2.append(value) analog1 = PV('analogIn1') stop_count = PV('outStopCount') init = PV('initiate') analog2 = PV('analogIn2') poll(evt=1.e-5, iot=0.01) analog1.wait_for_connection() analog2.wait_for_connection() init.wait_for_connection() stop_count.wait_for_connection() analog1.add_callback(getData1) if util.put_check(stop_count, stop): init.put(1) t0 = time.time() while time.time() - t0 < 30: poll(evt=1.e-5, iot=0.01) else: print "Stopcount not set" return False buffered_run = len(data1) analog2.add_callback(getData2) time.sleep(2) if util.put_check(stop_count, -1): init.put(1) t0 = time.time() while time.time() - t0 < 30: poll(evt=1.e-5, iot=0.01) else: print "Stopcount not set 2nd time" return False unbuffered_run = len(data2) return buffered_run, unbuffered_run
def stopcount_value(self): if not self.connected: print "Device not connected" return False #util.pv_check('status', 0) #self.stop = 1001 data1 = [] data2 = [] def getData1(pvname, value, **kw): if value != 0: data1.append(value) def getData2(pvname, value, **kw): if value != 0: data2.append(value) analog1 = PV('analogIn1') stop_count = PV('outStopCount') init = PV('initiate') analog2 = PV('analogIn2') poll(evt=1.e-5, iot=0.01) analog1.wait_for_connection() analog2.wait_for_connection() init.wait_for_connection() stop_count.wait_for_connection() util.put_check(stop_count, 100) analog1.add_callback(getData1) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 10: poll(evt=1.e-5, iot=0.01) first_run = len(data1) analog1.remove_callback(0) analog1.add_callback(getData2) time.sleep(2) util.put_check(stop_count, 200) init.put(1) poll(evt=1.e-5, iot=0.01) t0 = time.time() while time.time() - t0 < 10: poll(evt=1.e-5, iot=0.01) second_run = len(data2) return first_run, second_run
def __init__(self, parent=None, args=None): super(cavityDisplay, self).__init__(parent=parent, args=args) self.ui.linac0.loadWhenShown = False self.ui.linac1.loadWhenShown = False self.ui.linac2.loadWhenShown = False self.ui.linac3.loadWhenShown = False repeaters = [ self.ui.linac0, self.ui.linac1, self.ui.linac2, self.ui.linac3 ] # type: List[PyDMTemplateRepeater] for index, linacTemplateRepeater in enumerate(repeaters): linacObject = LINAC_OBJECTS[index] print(linacObject.name) # PyDMLabel = linac[0].itemAt(0).widget() # PyDMTemplateRepeater = linac[0].itemAt(1).widget() linac = [] vertLayoutList = linacTemplateRepeater.findChildren(QVBoxLayout) for vertLayout in vertLayoutList: templateRepeater = vertLayout.itemAt(1).widget() if templateRepeater.accessibleName() == "${cryoTemplate}": linac.append(vertLayout) for cryomodules in linac: cmLabel = cryomodules.itemAt( 0).widget() # cryo number pydmLabel cmTemplateRepeater = cryomodules.itemAt( 1).widget() # templateRepeater of 8 cavities cryomoduleObject = linacObject.cryomodules[cmLabel.text()] cavityList = cmTemplateRepeater.findChildren(CavityWidget) for cavity in cavityList: cavityObject = cryomoduleObject.cavities[int( cavity.cavityText)] severityPV = PV(cavityObject.pvPrefix + SEVERITY_SUFFIX) statusPV = PV(cavityObject.pvPrefix + STATUS_SUFFIX) # This line is meant to initialize the cavity colors and shapes when first launched self.severityCallback(cavity, severityPV.value) self.statusCallback(cavity, statusPV.value) #.add_callback is called when severityPV changes value severityPV.add_callback( partial(self.severityCallback, cavity)) #.add_callback is called when statusPV changes value statusPV.add_callback(partial(self.statusCallback, cavity))
def __init__(self, parent=None, args=None): super(cavityDisplay, self).__init__(parent=parent, args=args) self.ui.L0B.loadWhenShown = False self.ui.L1B.loadWhenShown = False self.ui.L2B.loadWhenShown = False self.ui.L3B.loadWhenShown = False embeddedDisplays = [ self.ui.L0B, self.ui.L1B, self.ui.L2B, self.ui.L3B ] # type: List[PyDMEmbeddedDisplay] for index, linacEmbeddedDisplay in enumerate(embeddedDisplays): linacObject = LINAC_OBJECTS[index] print(linacObject.name) linacHorizLayout = linacEmbeddedDisplay.findChild(QHBoxLayout) totalCryos = linacHorizLayout.count() # linac will be a list of cryomodules linac = [] for index in range(0, totalCryos): linac.append(linacHorizLayout.itemAt(index).widget()) for cryomodule in linac: cmNumber = cryomodule.children()[ 1] # cryo number pydmDisplayButton cmTemplateRepeater = cryomodule.children()[ 2] # template repeater of 8 cavities cryomoduleObject = linacObject.cryomodules[str( cmNumber.text())] cavityList = cmTemplateRepeater.findChildren(CavityWidget) for cavity in cavityList: cavityObject = cryomoduleObject.cavities[int( cavity.cavityText)] severityPV = PV(cavityObject.pvPrefix + SEVERITY_SUFFIX) statusPV = PV(cavityObject.pvPrefix + STATUS_SUFFIX) # This line is meant to initialize the cavity colors and shapes when first launched self.severityCallback(cavity, severityPV.value) self.statusCallback(cavity, statusPV.value) #.add_callback is called when severityPV changes value severityPV.add_callback( partial(self.severityCallback, cavity)) #.add_callback is called when statusPV changes value statusPV.add_callback(partial(self.statusCallback, cavity))
def buffering(self): status = PV('status') if not util.check_device('C1', self.proc) and status.get() in range(0,3): print "device not connected" return False count3 = PV('in_counts_3') count4 = PV('in_counts_4') low_3 = PV('low_limit_3') low_4 = PV('low_limit_4') trig_buffer = PV('trig_buffer') init = PV('initiate') poll(evt=1.e-5, iot=0.01) data3 = [] data4 = [] def getCount3(pvname, value, **kw): data3.append(value) def getCount4(pvname, value, **kw): data4.append(value) if util.put_check(low_3, 0.0) and util.put_check(low_4, 0.0) and util.put_check(trig_buffer, 1000) and util.put_fuzzy('analog_out_period', 10e-5, 0.05): pass else: print "setting not taking place" return False, False t0 = time.time() # while caget('trig_buffer')!=1000 and caget('trig_mode')!=1: # if time.time() - t0 > 20: # return "buffer or mode never set" # else: # pass #util.put_check('initiate', 1) time.sleep(1) count3.add_callback(getCount3) count4.add_callback(getCount4) init.put(1) while time.time() - t0 < 3: poll(evt=1.e-5, iot=0.01) # time.sleep(2) end = self.proc.expect( ['Announce\(\) success', pexpect.TIMEOUT, pexpect.EOF], timeout=3) #print proc.before return len(data3), len(data4)
def __init__(self, scan, function): ''' Constructor scan - the name of the scan record, e.g. xxx:scan1 function - a function that is called whenever a positioner is changed in the scan record ''' self._totalNumPoints = 0 self._sectionList = [[] for i in range(4)] self._positionersList = [] self._scanRecord = scan self._positionersValid = True self._scanValid = False self._posCallbackFunction = function self._scanType = "TableScan" # Create the positioner PV objects and add a callback to each of them. # The index is used to identify which positioner is calling the callback # function. pos1 = PV(pvname='%s.P1PV' % scan) pos1.add_callback(self.PositionerChangedCallback, index=0) pos2 = PV(pvname='%s.P2PV' % scan) pos2.add_callback(self.PositionerChangedCallback, index=1) pos3 = PV(pvname='%s.P3PV' % scan) pos3.add_callback(self.PositionerChangedCallback, index=2) pos4 = PV(pvname='%s.P4PV' % scan) pos4.add_callback(self.PositionerChangedCallback, index=3) self._positionersList.append(pos1) self._positionersList.append(pos2) self._positionersList.append(pos3) self._positionersList.append(pos4) return
class PVIntegrator: """PVIntegrator""" def __init__(self,pv = "IBC1H04CRCUR2",name=None,outpv=None): self.output_name = outpv if self.output_name != None : self.output_pv = PV(self.output_name) #else : # self.output_pv = None self.total = 0.0 self.name = name self.total_time = 0.000000001 if name is None: self.name = pv self.pv_name = pv self.process_var = PV(self.pv_name) def Reset(self): self.total = 0.0 self.total_time = 0.000000001 def PVChangeCallback(self,pvname=None, value=None, char_value=None, **kws): value = float(char_value) self.total = self.total + 2.0*value # 2.0 s readout self.total_time = self.total_time + 2.0 def AddCallback(self): self.process_var.add_callback(self.PVChangeCallback) def ClearCallback(self): self.process_var.clear_callbacks() def Dump(self): print str("{:^10} total charge = {} mC").format(self.pv_name, self.total*0.001) print str("{:^10} average current = {} uA").format("", self.total/self.total_time) def Print(self): self.ClearCallback() print str("{:^10} total charge = {} mC").format(self.pv_name, self.total*0.001) print str("{:^10} average current = {} uA").format("", self.total/self.total_time) def GetJSONObject(self): self.ClearCallback() trip_dict = {'total': float(self.total)} trip_dict.update({'PV': self.pv_name}) return {self.name: trip_dict } def PrintJSON(self): print "writing json"
def start_stop(self, stop): data = [] check = util.expect(self.proc, ["C1"]) count, trig_mode, trig_buffer, int_time, low3, init = PV( 'in_counts_3'), PV('trig_mode'), PV('trig_buffer'), PV( 'analog_out_period'), PV('low_limit_3'), PV('initiate') stop_state = PV('stopped_state') running_state = PV('running_state') poll(evt=0.5, iot=0.5) util.put_check(trig_mode, 1) util.put_check(low3, 0.0) util.put_check(trig_buffer, 0) int_time.put(10e-5) poll(evt=1.0, iot=1.01) #print trig_mode.get(), low3.get(), int_time.get(), trig_buffer.get() def getCount(pvname, value, **kw): if len(data) >= stop - 1: init.put(0) poll(evt=0.1, iot=0.1) #poll(evt=0.001, iot=0.001) data.append(value) count.add_callback(getCount) poll(evt=1.0, iot=1.01) init.put(1) poll(evt=0.5, iot=0.5) t0 = time.time() while len(data) < stop: poll(evt=1.e-5, iot=0.01) if time.time() - t0 >= 100: print "didnt reach stop count" break #poll(evt=0.1, iot=0.1) #init.put(0) poll(evt=0.1, iot=0.1) #print trig_buffer.get(), low3.get(), trig_mode.get() pre_sleep = len(data) poll(evt=2.5, iot=0.5) time.sleep(5) post_sleep = len(data) print stop print pre_sleep, post_sleep return [pre_sleep, post_sleep]
def test_get_callback(self): write("Callback test: changing PV must be updated\n") global NEWVALS mypv = PV(pvnames.updating_pv1) NEWVALS = [] def onChanges(pvname=None, value=None, char_value=None, **kw): write( 'PV %s %s, %s Changed!\n' % (pvname, repr(value), char_value)) NEWVALS.append( repr(value)) mypv.add_callback(onChanges) write('Added a callback. Now wait for changes...\n') t0 = time.time() while time.time() - t0 < 3: time.sleep(1.e-4) write(' saw %i changes.\n' % len(NEWVALS)) self.failUnless(len(NEWVALS) > 3) mypv.clear_callbacks()
class MonitorWidget(QtGui.QWidget): def __init__(self, parent=None): super(MonitorWidget, self).__init__(parent) # __init__(parent) for main self.cntName = cntpv # GUI construction self.ui = Ui_monitorWidget() self.ui.setupUi(self) # SR beamcurrent & motor position monitor... self.beamPV = PV(beampv) self.m1PosPV = PV(m1pospv+'.RBV') self.m2PosPV = PV(m2pospv+'.RBV') self.beamPV.add_callback(self.beamCallbackFunc) self.m1PosPV.add_callback(self.m1CallbackFunc) self.m2PosPV.add_callback(self.m2CallbackFunc) # for counter... self.countPV = PV(self.cntName+'_calc2') scalerAttrs = ('calc1','calc2','calc3','calc4', 'calc5','calc6','calc7','calc8') self.scalerDev = epics.Device(prefix=self.cntName+'_', delim='', attrs=scalerAttrs, mutable=False) epics.poll() try: epics.poll(0.001, 1.0) val = self.scalerDev.get_all() self.ui.IoCnt.display(val['calc2']) self.ui.ItCnt.display(val['calc3']) self.ui.IfCnt.display(val['calc4']) self.ui.IrCnt.display(val['calc5']) except: pass self.countPV.add_callback(self.countersCallbackFunc, run_now=True) def beamCallbackFunc(self, pvname=None, value=None, **kw): self.ui.beamCurrent.display(round(value, 2)) def m1CallbackFunc(self, pvname=None, value=None, **kw): self.ui.M1Pos.display(round(value, 2)) def m2CallbackFunc(self, pvname=None, value=None, **kw): self.ui.M2Pos.display(round(value, 2)) def countersCallbackFunc(self, value=None, **kw): epics.poll() val = self.scalerDev.get_all() self.ui.IoCnt.display(value) self.ui.ItCnt.display(val['calc3']) self.ui.IfCnt.display(val['calc4']) self.ui.IrCnt.display(val['calc5'])
def init(): pv_dict = read_pv_config() global dm, view, header_pv, event_pv # init the UI view = init_ui(dm) view.scalar_collection.data_muggler = None # init the header and event pvs header_pv = PV(header_PV_name, auto_monitor=True) event_pv = PV(event_PV_name, auto_monitor=True) # add the proper callbacks to the pvs header_pv.add_callback(header_callback) event_pv.add_callback(event_callback) print('header_pv.get(): {}'.format(header_pv.get())) print('dir(header_pv): {}'.format(dir(header_pv))) create_dm(header_pv.get()) view.show()
def test_waveform_callback_with_count_arg(self): values = [] wf = PV(pvnames.char_arr_pv, count=32) def onChanges(pvname=None, value=None, char_value=None, **kw): write( 'PV %s %s, %s Changed!\n' % (pvname, repr(value), char_value)) values.append( value) wf.add_callback(onChanges) write('Added a callback. Now wait for changes...\n') t0 = time.time() while time.time() - t0 < 3: time.sleep(1.e-4) if len(values)>0: break self.failUnless(len(values) > 0) self.assertEquals(len(values[0]),32) wf.clear_callbacks()
class ToggleShutter(StandardDevice): def __init__(self, mnemonic, shutter, shutterReadback): super().__init__(mnemonic) self.read = PV(shutterReadback) self.toggle = PV(shutter) self._open = self.read.get() self.changed = Event() self.read.add_callback(self.onReadChange) def isOpen(self): return self._open def onReadChange(self, value, **kwargs): self._open = value self.changed.set() def wait(self, timeout=3): ca.flush_io() self.changed.wait(timeout) def change(self, open, wait=False): if self.isOpen() == open: self.changed.set() return self.changed.clear() self.toggle.put(1) ca.flush_io() if wait: self.wait() def open(self, wait=False): self.change(open=True, wait=wait) def close(self, wait=False): self.change(open=False, wait=wait)
class PCO2000(StandardDevice): TYPE_TIFF = "TIFF" TYPE_HDF = "HDF" #CALLBACK FUNCTION FOR THE CCD ACQUIRE STATUS PV def onAcquireChange(self, value, **kw): self._doneRecord = (value == 0) def onAcquireRBVChange(self, value, **kw): self._doneReadOut = (value == 0) def onDataChange(self, value, **kw): if(self.initCamera): self.initCamera = False return self.imageBufferQueue.put(value) self.NData = self.NData + 1 def onNELMChange(self, value, **kw): if(self.initNELM): self.initNELM = False return self.NCount = self.NCount + 1 #CONSTRUCTOR OF CCD CLASS def __init__(self, pvName, mnemonic, imageBufferQueue=None, processName=""): StandardDevice.__init__(self, mnemonic) self.processName = processName self.initCamera = True self.initNELM = True self.NCount = 0 self.NData = 0 self.imageBufferQueue = imageBufferQueue self.pvData = PV(pvName+":Data", auto_monitor=True) self.pvData.add_callback(self.onDataChange) self.pvAcquire = PV(pvName+":Acquire", callback=self.onAcquireChange, auto_monitor=True) self.pvAcquireRBV = PV(pvName+":Acquire_RBV", callback=self.onAcquireRBVChange, auto_monitor=True) self.pvNELM = PV(pvName+":Data.NELM", callback=self.onNELMChange) self._done = self.isDone() self.pvPixelSize = PV(pvName + ":PixelSize") self.pvCheckImage = PV(pvName + ":CheckImage") self.pvMinX = PV(pvName + ":MinX") self.pvMinY = PV(pvName + ":MinY") self.pvSizeX = PV(pvName + ":SizeX") self.pvSizeY = PV(pvName + ":SizeY") self.pvAcquireTime = PV(pvName+":AcquireTime") self.pvAcquireTimeBase = PV(pvName+":AcquireTimeBase") self.pvDelayTime = PV(pvName + ":DelayTime") self.pvDelayTimeBase = PV(pvName + ":DelayTimeBase") self.pvFileFormat = PV(pvName + ":FileFormat") self.pvFileName = PV(pvName + ":FileName") self.pvFileNumber = PV(pvName + ":FileNumber") self.pvFilePath = PV(pvName + ":FilePath") # #### PVS Bellow are used only for information display, no need to be here in the Python Class # #### If needed just uncomment and create the proper methods for GET and SET values. # self.pvADC = PV(pvName+":ADC") # self.pvAutoIncrement = PV(pvName+":AutoIncrement") # self.pvBinHorz = PV(pvName + ":BinHorz") # self.pvBinVert = PV(pvName + ":BinVert") # self.pvBoolTest = PV(pvName + ":BoolTest") # self.pvCamTemp = PV(pvName + ":CamTemp") # self.pvCCDTemp = PV(pvName + ":CCDTemp") # self.pvDoubleImage = PV(pvName + ":DoubleImage") # self.pvHotPixelCorrection = PV(pvName + ":HotPixelCorrection") # self.pvHotPixelX = PV(pvName + ":HotPixelX") # self.pvHotPixelY = PV(pvName + ":HotPixelY") # self.pvNoiseFiltering = PV(pvName + ":NoiseFiltering") # self.pvPixelRate = PV(pvName + ":PixelRate") # self.pvPixelSize = PV(pvName + ":PixelSize") # self.pvPowTemp = PV(pvName + ":PowTemp") # self.pvTimestamp = PV(pvName + ":Timestamp") # self.pvStatus = PV(pvName + ":Status") def getPixelSize(self): return self.pvPixelSize.get() def getCheckImage(self): return self.pvCheckImage.get() def setCheckImage(self, v): self.pvCheckImage.put(v) def getMinX(self): return self.pvMinX.get() def setMinX(self, v): self.pvMinX.put(v) def getMinY(self): return self.pvMinY.get() def setMinY(self, v): self.pvMinY.put(v) def getSizeX(self): return self.pvSizeX.get() def setSizeX(self, v): self.pvSizeX.put(v) def getSizeY(self): return self.pvSizeY.get() def setSizeY(self, v): self.pvSizeY.put(v) def getAcquireTime(self): return self.pvAcquireTime.get() def setAcquireTime(self, v): self.pvAcquireTime.put(v) def getAcquireTimeBase(self): return self.pvAcquireTimeBase.get() def setAcquireTimeBase(self, v): self.pvAcquireTimeBase.put(v) def getDelayTime(self): return self.pvDelayTime.get() def setDelayTime(self, v): self.pvDelayTime.put(v) def getDelayTimeBase(self): return self.pvDelayTimeBase.get() def setDelaytimeBase(self, v): self.pvDelayTimeBase.put(v) def getFileFormat(self): return self.pvFileFormat.get() def setFileFormat(self, v): if(v in [self.TYPE_HDF, self.TYPE_TIFF]): self.pvFileFormat.put(v) else: msg = 'File format "' + v + '" not supported. Only supported are: ' raise Exception('Error: ',msg) def getFileName(self): return self.pvFileName.get() def setFileName(self, v): self.pvFileName.put(v) def getFileNumber(self): return self.pvFileNumber.get() def setFuleNumber(self, v): self.pvFileNumber.put(v) def getFilePath(self): return self.pvFilePath.get() def setFilePath(self, v): self.pvFilePath.put(v) def getCompleteFilePath(self): if(self.getFileFormat() == self.TYPE_TIFF): ext = ".tif" elif(self.getFileFormat() == self.TYPE_HDF): ext = ".h5" else: ext = "" return self.getFilePath()+"/"+self.getFileName()+ext def getNELMChangeCount(self): return self.NCount def getData(self): self._newData = False return self.pvData.get() def isDone(self): return (self.pvAcquireRBV.get() == 0) def isRecordDone(self): return (self.pvAcquire.get() == 0) def isReadOutDone(self): return (self.pvAcquireRBV.get() == 0) def getIntensity(self): return self.scaler.getIntensity() def acquire(self, waitRecord=False, waitReadOut=False): #self.scaler.setCountTime(self.time) #self.scaler.setCountStart() self.pvAcquire.put(1) self._doneRecord = False self._doneReadOut = False self._newData = False if(waitRecord): self.waitRecord() if(waitReadOut): self.waitReadOut() #self.scaler.setCountStop() def waitConfig(self): self._doneConfig = False while(not self._doneConfig): sleep(0.001) def waitRecord(self): while(not self._doneRecord): sleep(0.001) def waitReadOut(self): while(not self._doneReadOut): sleep(0.001) def destroy(self): self.pvData.disconnect() self.pvAcquire.disconnect() self.pvAcquireRBV.disconnect() self.pvNELM.disconnect() self.imageBufferQueue = None
class Feed: """ This class reads frames in a real time using pyepics, and delivers to consuming process. """ def __init__(self): """ Constructor This constructor creates the following queues: process_dataq : a queue used to pass data to the consuming process exitq : a queue used to signal awaiting process the end of processing, so the resources can be closed thread_dataq : this queue delivers counter number on change from call back thread Other fields are initialized. """ self.process_dataq = Queue() self.exitq = tqueue.Queue() self.thread_dataq = tqueue.Queue() self.sizex = 0 self.sizey = 0 self.no_frames = 0 self.ctr = 0 self.sequence = None self.sequence_index = 0 self.cntr_pv = None def deliver_data(self, data_pv, frame_type_pv, logger): """ This function receives data, processes it, and delivers to consuming process. This function is invoked at the beginning of the feed as a distinct thread. It reads data from a thread_dataq inside a loop that delivers current counter value on change. If the counter is not a consecutive number to the previous reading a 'missing' string is enqueued into process_dataq in place of the data to mark the missing frames. For every received frame data, it reads a data type from PV, and the two elements are delivered to a consuming process via process_dataq as Data instance. If a sequence is defined, then the data type for this frame determined from sequence is compared with the data type read from PV. If they are different, a warning log is recorded. On the loop exit an 'all_data' string is enqueud into the inter-process queue, and 'exit' string is enqueued into the inter-thread queue, to notify the main thread of the exit event. Parameters ---------- data_pv : str a PV string for the area detector data frame_type_pv : str a PV string for the area detector data type logger : Logger a Logger instance, typically synchronized with the consuming process logger Returns ------- None """ def build_type_map(): types = {} types[0] = 'data' types[1] = 'data_dark' types[2] = 'data_white' types[3] = 'data' # it'd double correlation, but leave data for now return types def verify_sequence(logger, data_type): while frame_index > self.sequence[self.sequence_index][1]: self.sequence_index += 1 planned_data_type = self.sequence[self.sequence_index][0] if planned_data_type != data_type: logger.warning('The data type for frame number ' + str(frame_index) + ' is ' + data_type + ' but was planned ' + planned_data_type) # def finish(): # self.process_dataq.put(pack_data(None, "end")) # self.exitq.put('exit') types = build_type_map() done = False frame_index = 0 while not done: current_counter = self.thread_dataq.get() if self.no_frames < 0 or current_counter < self.no_frames: try: data = np.array(caget(data_pv)) data_type = types[caget(frame_type_pv)] if data is None: self.finish() done = True logger.error('reading image times out, possibly the detector exposure time is too small') else: delta = current_counter - self.ctr self.ctr = current_counter data.resize(self.sizex, self.sizey) if delta > 1: for i in range (1, delta): self.process_dataq.put(adapter.pack_data(None, "missing")) frame_index += delta packed_data = self.get_packed_data(data, data_type) self.process_dataq.put(packed_data) if self.sequence is not None: verify_sequence(logger, data_type) except: self.finish() done = True logger.error('reading image raises exception, possibly the detector exposure time is too small') else: done = True self.finish() def get_packed_data(self, data, data_type): return adapter.pack_data(data, data_type) def on_change(self, pvname=None, **kws): """ A callback method that activates when a frame counter of area detector changes. This method reads the counter value and enqueues it into inter-thread queue that will be dequeued by the 'deliver_data' function. If it is a first read, the function adjusts counter data in the self object. Parameters ---------- pvname : str a PV string for the area detector frame counter Returns ------- None """ current_ctr = kws['value'] #on first callback adjust the values if self.ctr == 0: self.ctr = current_ctr if self.no_frames >= 0: self.no_frames += current_ctr self.thread_dataq.put(current_ctr) def start_processes(self, counter_pv, data_pv, frame_type_pv, logger, *args): """ This function starts processes and callbacks. This is a main thread that starts thread reacting to the callback, starts the consuming process, and sets a callback on the frame counter PV change. The function then awaits for the data in the exit queue that indicates that all frames have been processed. The functin cancells the callback on exit. Parameters ---------- counter_pv : str a PV string for the area detector frame counter data_pv : str a PV string for the area detector frame data frame_type_pv : str a PV string for the area detector data type logger : Logger a Logger instance, typically synchronized with the consuming process logger *args : list a list of arguments specific to the client process Returns ------- None """ data_thread = CAThread(target = self.deliver_data, args=(data_pv, frame_type_pv, logger,)) data_thread.start() adapter.start_process(self.process_dataq, logger, *args) self.cntr_pv = PV(counter_pv) self.cntr_pv.add_callback(self.on_change, index = 1) # self.exitq.get() # print 'got Exit in exitq stopping callback' # self.cntr.clear_callbacks() def get_pvs(self, detector, detector_basic, detector_image): """ This function takes defined strings from configuration file and constructs PV variables that are accessed during processing. Parameters ---------- detector : str a string defining the first prefix in area detector, it has to match the area detector configuration detector_basic : str a string defining the second prefix in area detector, defining the basic parameters, it has to match the area detector configuration detector_image : str a string defining the second prefix in area detector, defining the image parameters, it has to match the area detector configuration Returns ------- acquire_pv : str a PV string representing acquireing state counter_ pv : str a PV string representing frame counter data_pv : str a PV string representing acquired data sizex_pv : str a PV string representing x size of acquired data sizey_pv : str a PV string representing y size of acquired data frame_type_pv : str a PV string for the area detector data type """ acquire_pv = detector + ':' + detector_basic + ':' + 'Acquire' counter_pv = detector + ':' + detector_basic + ':' + 'NumImagesCounter_RBV' data_pv = detector + ':' + detector_image + ':' + 'ArrayData' sizex_pv = detector + ':' + detector_image + ':' + 'ArraySize0_RBV' sizey_pv = detector + ':' + detector_image + ':' + 'ArraySize1_RBV' frame_type_pv = detector + ':' + detector_basic + ':' + 'FrameType' return acquire_pv, counter_pv, data_pv, sizex_pv, sizey_pv, frame_type_pv def feed_data(self, no_frames, detector, detector_basic, detector_image, logger, sequence=None, *args): """ This function is called by an client to start the process. It parses configuration and gets needed process variables. It stores necessary values in the self object. After all initial settings are completed, the method awaits for the area detector to start acquireing by polling the PV. When the area detective is active it starts processing. Parameters ---------- config : str a configuration file logger : Logger a Logger instance, recommended to use the same logger for feed and consuming process sequence : list or int if int, the number is used to set number of frames to process, if list, take the number of frames from the list, and verify the sequence of data is correct during processing *args : list a list of process specific arguments Returns ------- None """ acquire_pv, counter_pv, data_pv, sizex_pv, sizey_pv, frame_type_pv = self.get_pvs(detector, detector_basic, detector_image) self.no_frames = no_frames # if sequence is None: # self.no_frames = no_frames # elif type(sequence) is int: # self.no_frames = sequence # else: # self.sequence = sequence # self.no_frames = sequence[len(sequence)-1][1] + 1 test = True while test: self.sizex = caget (sizex_pv) self.sizey = caget (sizey_pv) ack = caget(acquire_pv) if ack == 1: test = False self.start_processes(counter_pv, data_pv, frame_type_pv, logger, *args) return caget(acquire_pv) def finish(self): self.process_dataq.put(adapter.pack_data(None, "end")) self.cntr_pv.clear_callbacks()
def setupBlComm(): comm_pv = PV(beamlineName + "_comm:command_s") comm_pv.put("\n",wait=True) # comm_pv.add_callback(comm_cb,{"fish":"bass"}) comm_pv.add_callback(comm_cb,fish="bass")
class PVLine(Frame): def disconnect(self): if self.pv: self.pv.disconnect() self.connected = False def connect(self): if len(self.pvname.get()): self.pv = PV(self.pvname.get(), connection_callback=self.connection_monitor) self.pv.add_callback(self.status_change) #PV value callback def status_change(self, value, **kws): if self.last_value == None: self.last_value = value return if value != self.last_value: self.last_value = value if value == self.target_value: if sys.platform == "linux2": os.system("paplay " + self.LinuxSound) elif sys.platform == "win32" or sys.platform == "cygwin": if self.WindowsSoundType == "ALIAS": winsound.PlaySound(self.WindowsSound, winsound.SND_ALIAS) elif self.WindowsSoundType == "PATH": winsound.PlaySound(self.WindowsSound, winsound.SND_FILENAME) #PV connection callback def connection_monitor(self, **kws): if kws["conn"]: self.connected = True self.last_value = None else: self.connected = False #Switch from one pv to another def switch_pv(self): self.disconnect() self.connect() def change_target(self): self.last_value = None self.target_value = None if len(self.target.get()): self.target_value = int(self.target.get()) #Use tkinter's event queue to update connection status def update_visual(self): if self.connected: self.connection.config(text="Connected", fg="sea green") else: self.connection.config(text="Not Connected", fg="red") self.master.after(250, self.update_visual) def settings_accept(self): self.LinuxSound = self.popup.lentry.get() self.WindowsSound = self.popup.wentry.get() self.WindowsSoundType = self.popup.tentry.get() self.popup.destroy() def popup(self): self.popup = SoundPopup(self.settings_accept) self.popup.focus_force() self.popup.lentry.insert(0, self.LinuxSound) self.popup.wentry.insert(0, self.WindowsSound) self.popup.tentry.insert(0, self.WindowsSoundType) def __init__(self, master, config={}): Frame.__init__(self, master) self.pv = None self.connected = False self.last_value = None self.target_value = int(config.get("target", 1)) self.LinuxSound = config.get("linux_sound", "/usr/share/sounds/freedesktop/stereo/complete.oga") self.WindowsSound = config.get("windows_sound", "SystemExclamation") self.WindowsSoundType = config.get("windows_sound_type", "ALIAS") self.pvname = Entry(self, width=30) self.pvname.insert(0, config.get("name", '')) self.pvname.grid(row=0, column=0, padx=(0,5), pady=(0,5)) self.target = Entry(self, width=10, justify="right") self.target.insert(0, str(self.target_value)) self.target.grid(row=0, column=1, padx=(0,5), pady=(0,5)) self.connection = Label(self, width=12) self.connection.grid(row=0, column=2, padx=(0,5), pady=(0,5)) self.settings_image = PhotoImage(data=sound_icon) self.settings = Button(self, image=self.settings_image, command=self.popup) self.settings.grid(row=0, column=3, padx=(0,5), pady=(0,5)) self.pvname.bind("<Return>", lambda x: self.switch_pv()) self.pvname.bind("<FocusOut>", lambda x: self.switch_pv()) self.target.bind("<Return>", lambda x: self.change_target()) self.target.bind("<FocusOut>", lambda x: self.change_target()) self.connect() self.update_visual()
class Motoman(StandardDevice): def finish(self, value, **kw): if value == "Done": self.motomanfinish = True else: self.motomanfinish = False def __init__ (self,pvPrefix="", mnemonic=""): StandardDevice.__init__(self, mnemonic) self.pvBVAL_RBV = PV(pvPrefix + ":BVAL_RBV") self.pvBVAL = PV(pvPrefix + ":BVAL") self.pvBPOS = PV(pvPrefix+ ":BPOS") self.pvSVON = PV(pvPrefix+":SVON") self.pvRUNNING = PV(pvPrefix+":RUNNING") self.pvRUNNING.add_callback(self.finish) self.pvJOB = PV(pvPrefix+":JOB") self.pvGOJOB = PV(pvPrefix+":GOJOB") self.pvSTA1 = PV(pvPrefix+":STA1") self.pvSTA2 = PV(pvPrefix + ":STA2") self.motomanfinish = False def changeJOB(self,job=""): self.pvJOB.put(job) def goJOB(self): self.pvGOJOB.put(1) self.motomanfinish = False while not self.motomanfinish: sleep(0.1) def waitFinish(self): while not self.motomanfinish: sleep(0.01) def servoON(self,bool): if ((bool != 0) and (bool !=1)): self.pvSVON.put(0) else: self.pvSVON.put(bool) def readBVAL(self): return self.pvBVAL_RBV.get() def setBVAL(self,val): if ((val < 0) or (val > 50)): self.pvBVAL.put(0) self.pvSVON.put(0) else: self.pvBVAL.put(val) def setBPOS(self,pos): if ((pos < 0) or (pos > 2)): self.pvBPOS.put(000) else: self.pvBPOS.put(pos) def readSTA1(self): return self.pvSTA1.get() def readSTA2(self): return self.pvSTA2.get() def setSample(self,val): self.setBPOS(0) self.setBVAL(val) def removeSample(self): self.setBPOS(2) self.setBVAL(1) def run (self): self.changeJOB("CICLO") self.goJOB()
class Mythen(StandardDevice, ICountable): def finish(self, value, **kw): if value == 0: self.mythenfinish = True else: self.mythenfinish = False def __init__ (self,pvPrefix, mnemonic): StandardDevice.__init__(self, mnemonic) self.pvAcquire = PV(pvPrefix + ":Acquire") self.pvTime = PV(pvPrefix + ":Time") self.pvDataRBV = PV(pvPrefix+ ":Data_RBV") self.pvAcquireRBV = PV(pvPrefix+":Acquire_RBV") self.pvAcquireRBV.add_callback(self.finish) self.pvSettings = PV(pvPrefix+":Settings") self.pvFlatfield = PV(pvPrefix+":FlatfieldCorrection") self.pvFlatfieldRBV = PV(pvPrefix+":FlatfieldCorrection_RBV") self.pvFlip = PV(pvPrefix + ":FlipChannels") self.pvFlipRBV = PV(pvPrefix + ":FlipChannels_RBV") self.mythenfinish = (self.pvAcquireRBV.get() == 0) def changeTime(self,tempo): self.pvTime.put(tempo*10000000) def acquire(self): self.pvAcquire.put(1) self.mythenfinish = False #sleep(0.1) def readout(self): return self.pvDataRBV.get() def waitFinish(self): while not self.mythenfinish: sleep(0.001) def settings(self,settings=""): self.pvSettings.put(settings) def setFlatfield(self,bool): if ((bool != 0) and (bool != 1)): self.pvFlatfield.put(0) else: self.pvFlatfield.put(bool) def readFlatfield(self): return self.pvFlatfieldRBV.get() def setFlip(self,bool): if ((bool != 0) and (bool != 1)): self.pvFlip.put(1) else: self.pvFlip.put(bool) def readFlip(self): return self.pvFlipRBV.get() def getValue(self, **kwargs): """ Abstract method to get the current value of a countable device. Parameters ---------- kwargs : value Where needed informations can be passed, e.g. select which channel must be read. Returns ------- out : value Returns the current value of the device. Type of the value depends on device settings. """ return self.readout() def setCountTime(self, t): """ Abstract method to set the count time of a countable target device. Parameters ---------- t : value The target count time to be set. Returns ------- out : None """ self.changeTime(abs(t)) def setPresetValue(self, channel, val): """ Abstract method to set the preset count of a countable target device. Parameters ---------- channel : `int` The monitor channel number val : `int` The preset value Returns ------- out : None """ self.changeTime(abs(val)) def startCount(self): """ Abstract method trigger a count in a counter """ self.acquire() def stopCount(self): """ Abstract method stop a count in a counter """ pass def canMonitor(self): """ Abstract method to check if the device can or cannot be used as monitor. Returns ------- out : `bool` """ return True def canStopCount(self): """ Abstract method to check if the device can or cannot stop the count and return values. Returns ------- out : `bool` """ return True def isCounting(self): """ Abstract method to check if the device is counting or not. Returns ------- out : `bool` """ return (not self.mythenfinish) def wait(self): """ Abstract method to wait for a count to finish. Returns ------- out : `bool` """ self.waitFinish()
class Magnet(object): STATUS_CYCLE_REQUIRED = 'Required' STATUS_TIMEOUT = 'Failed: Timeout' STATUS_CA_ERROR = 'Failed: Channel Access' STATUS_GOING_TO_MIN = 'Going to Min' STATUS_GOING_TO_MAX = 'Going to Max' STATUS_GOING_TO_INIT = 'Going to Init' STATUS_PAUSING = 'Pausing' TIMEOUT = 60 def __init__(self, prefix, name, min_sp=None, max_sp=None, **kws): super(Magnet, self).__init__() self.setpoint_pv = PV(prefix + ':CURRENT_SP') self.readback_pv = PV(prefix + ':CURRENT_MONITOR') self.name = name self.prefix = prefix self.tag = re.sub('[:-]', '_', prefix) self._cycle_status = self.STATUS_CYCLE_REQUIRED self.min_sp = min_sp self.max_sp = max_sp self.tolerance = 0.05 self.cycling = False self.cycle_iterations = 3 self.cycle_pause_time = 3. self.cycle_status_callbacks = [] self.setpoint_pv.add_callback(self.setpoint_changed) def setpoint_changed(self, **kws): if not self.cycling: self.cycle_status = self.STATUS_CYCLE_REQUIRED def add_callback(self, attr, callback, **kws): if attr == 'cycle_status': self.cycle_status_callbacks.append(callback) elif attr == 'setpoint': self.setpoint_pv.add_callback(callback, **kws) elif attr == 'readback': self.readback_pv.add_callback(callback, **kws) else: raise KeyError('Unknown attribute.') @property def setpoint(self): return self.setpoint_pv.get() @setpoint.setter def setpoint(self, value): self.setpoint_pv.put(value) @property def readback(self): return self.readback_pv.get() @property def cycle_status(self): return self._cycle_status @cycle_status.setter def cycle_status(self, value): changed = self._cycle_status != value self._cycle_status = value if changed and self.cycle_status_callbacks: kws = {'pvname': self.prefix + ':CYCLE_STATUS', 'value': value} for cb in self.cycle_status_callbacks: Thread(target=cb, kwargs=kws).start() def go_to_setpoint(self, value): self.setpoint = value start_time = time.time() while abs(self.readback - value) > self.tolerance: if time.time() - start_time > self.TIMEOUT: raise SetpointTimeoutException() time.sleep(1.) def cycle_iteration(self): self.cycle_status = self.STATUS_GOING_TO_MIN self.go_to_setpoint(self.min_sp) self.cycle_status = self.STATUS_PAUSING time.sleep(self.cycle_pause_time) self.cycle_status = self.STATUS_GOING_TO_MAX self.go_to_setpoint(self.max_sp) self.cycle_status = self.STATUS_PAUSING time.sleep(self.cycle_pause_time) def cycle(self): if self.cycling: return self.cycling = True init_sp = self.setpoint err = None for i in range(self.cycle_iterations): try: self.cycle_iteration() except SetpointTimeoutException: err = self.STATUS_TIMEOUT break except CASeverityException: err = self.STATUS_CA_ERROR break self.cycle_status = self.STATUS_GOING_TO_INIT try: self.go_to_setpoint(init_sp) except SetpointTimeoutException: err = self.STATUS_TIMEOUT except CASeverityException: err = self.STATUS_CA_ERROR if err: self.cycle_status = err else: self.cycle_status = u'✓ {0:%H:%M %d/%m}'.format(datetime.now()) self.cycling = False
class QtEpicsMotorWidget(QtGui.QWidget): """ This module provides a class library for a GUI label field widget bound to an Epics PV. The PV is monitored and the field is updated when the PV changes """ changeColor = QtCore.pyqtSignal() def __init__(self, pvname, parent, input_width, precision = 2, editable=False): """ Inputs: pvname: The name of the epics process variable. parent: The container to place the entry widget. input_width: precision: highlight_on_change: Example: detstat_file = epicsPVLabel("x12c_comm:datafilename",filestat_frame,70) detstat_file.getEntry().pack(side=LEFT,fill=X,expand=YES) """ super(QtEpicsMotorWidget, self).__init__() self.precision = precision self.editable = editable #self.applyOnEnter = applyOnEnter self.entry_var = "" # Creates the PV self.entry_pv = PV(pvname+".RBV", connection_callback=self._conCB) self.base_pv = PV(pvname) if(self.editable): self.entry = QtGui.QLineEdit(parent) else: self.entry = QtGui.QLabel(parent) if (input_width != 0): self.entry.setFixedWidth(input_width) time.sleep(0.05) try: #because the connection CB handles the timeout for PVs that don't exist self._set_entry_var_with_precision(self.entry_pv.get()) self.entry.setText(self.entry_var) except: self.entry_var = "-----" self.entry.setText(self.entry_var) self.emit(QtCore.SIGNAL("changeColor"),"white") return self.connect(self, QtCore.SIGNAL("changeColor"),self.setColor) self.entry_pv.add_callback(self._entry_pv_movingCb) self.entry_dmov_pv = PV(pvname+".DMOV") self.entry_dmov_pv.add_callback(self._entry_pv_dmovCb) def _conCB(self,conn,**kwargs): # print "in Con callback %d" % epics_args[1] if (conn): self.emit(QtCore.SIGNAL("changeColor"),"blue") # self.entry.configure(background="#729fff") else: self.entry_var = "-----" self.entry.setText(self.entry_var) self.emit(QtCore.SIGNAL("changeColor"),"white") def _entry_pv_movingCb(self,value,**kwargs): # print "in callback " + str(epics_args['pv_value']) + " " + ca.dbf_text(epics_args['type']) self._set_entry_var_with_precision(value) self.entry.setText(self.entry_var) # self.emit(QtCore.SIGNAL("changeColor"),"green") def _entry_pv_dmovCb(self,value,**kwargs): # print "in callback " + str(epics_args['pv_value']) if (value == 1): self.emit(QtCore.SIGNAL("changeColor"),"None") else: # self.emit(QtCore.SIGNAL("changeColor"),"#99FF66") self.emit(QtCore.SIGNAL("changeColor"),"yellow") def _set_entry_var_with_precision(self,inval): try: val = float(inval) if (self.precision == 0): self.entry_var = "%.0f" % val elif (self.precision == 1): self.entry_var = "%.1f" % val elif (self.precision == 2): self.entry_var = "%.2f" % val elif (self.precision == 3): self.entry_var ="%.3f" % val elif (self.precision == 4): self.entry_var = "%.4f" % val else: self.entry_var ="%.5f" % val except TypeError: #TODO: check this waveform_to_string function self.entry_var = "Type Error" # waveform_to_string(inval) pass except ValueError: #TODO: check this waveform_to_string function self.entry_var = "Value Error" # waveform_to_string(inval) pass # def pack(self,side=LEFT,padx=0,pady=0): #pass the params in # self.entry.pack(side=side,padx=padx,pady=pady) def getEntry(self): return self.entry def getBasePV(self): return self.base_pv def getField(self): return self.entry_var def setField(self,value): self.entry_var = value def setColor(self,color_s="pink"): self.entry.setStyleSheet("background-color: %s;" % color_s)