diff --git a/camera.py b/camera.py index 7b7cf91..a828c72 100755 --- a/camera.py +++ b/camera.py @@ -107,6 +107,7 @@ class epics_cam(object): print('camera.new_frame_pv_cb') def get_image(self): + _log.warning('this can be very slow. Use callbacks if possible.') try: pv_pic=self.getPv('FPICTURE') except AttributeError: @@ -120,13 +121,7 @@ class epics_cam(object): pv_pic=self.getPv('FPICTURE') sz=self._sz pic = pv_pic.get(count=sz[0]*sz[1], as_numpy=True).reshape(sz[::-1]) - f=np.array(((0, 0, 0, 0, 0), - (0, 1, 1, 1, 0), - (0, 1, 0, 0, 0), - (0, 1, 1, 0, 0), - (0, 1, 0, 0, 0), - (0, 0, 0, 0, 0),), pic.dtype) - pic[0:6, 0:5]=f*255 + epics_cam.set_fiducial(pic,255) except AttributeError as e: _log.warning("failed to fetch image") @@ -219,6 +214,16 @@ class epics_cam(object): pv_cam.put(CameraStatus.RUNNING, wait=True) self.update_size() + @staticmethod + def set_fiducial(pic,val): + # fiducial test + f=np.array(((0, 0, 0, 0, 0), + (0, 1, 1, 1, 0), + (0, 1, 0, 0, 0), + (0, 1, 1, 0, 0), + (0, 1, 0, 0, 0), + (0, 0, 0, 0, 0),), pic.dtype) + pic[0:6, 0:5]=f*pic.max() def sim_gen(self,sz=(1500,1000),t=100,mode=0): 'generate simulation data' @@ -257,15 +262,8 @@ class epics_cam(object): assert(img.mode=='L') # 8 bit grayscale assert(sz==img.size) imgSeq[i,:,:]=np.array(img.getdata()).reshape(sz[::-1]) - f=np.array(((0,0,0,0,0), - (0,1,1,1,0), - (0,1,0,0,0), - (0,1,1,0,0), - (0,1,0,0,0), - (0,0,0,0,0),),imgSeq.dtype) - imgSeq[i,0:6,0:5]=f*255 - - + pic=imgSeq[i] + epics_cam.set_fiducial(pic, 255) self._sim['imgSeq']=imgSeq self._sim['imgIdx']=0 diff --git a/swissmx.py b/swissmx.py index a88ed3f..57c27cf 100755 --- a/swissmx.py +++ b/swissmx.py @@ -395,12 +395,32 @@ class Main(QMainWindow, Ui_MainWindow): app=QApplication.instance() app._camera.pause() - def updateImage(self, pause=False): - #if not sample_camera.is_paused(): #ZAC: orig. code + def new_frame_sim_cb(self, **kwargs): app=QApplication.instance() - img = app._camera.get_image() - if img is not None: - self.img.setImage(img) + sim=app._camera._sim + imgSeq=sim['imgSeq'] + idx=sim['imgIdx'] + sim['imgIdx']=(idx+1)%imgSeq.shape[0] + # _log.info('simulated idx:{}'.format(idx)) + pic=imgSeq[idx] + self.img.setImage(pic) + + delay=500 # ms -> 2fps + QtCore.QTimer.singleShot(delay, self.new_frame_sim_cb) + + def new_frame_pv_cb(self, **kwargs): + app=QApplication.instance() + sz=app._camera._sz + if kwargs['count']==sz[0]*sz[1]: + pic=kwargs['value'].reshape(sz[::-1]) + else: + sz=self.update_size() + pic=kwargs['value'].reshape(sz[::-1]) + _log.debug('new_frame_pv_cb count {}'.format(kwargs['count'])) + if pic.dtype==np.int16: + pic.dtype=np.uint16 + camera.epics_cam.set_fiducial(pic, 255) + self.img.setImage(pic) def init_settings_tracker(self): _log.info("configuring widget persistence") @@ -527,15 +547,13 @@ class Main(QMainWindow, Ui_MainWindow): self.timer.timeout.connect(self.check_zescape) self.timer.start(20) else: - #zescape.stop_listening() #ZAC: orig. code - _log.warning("re-starting timer on camera update") + app=QApplication.instance() try: - self.timer.stop() - except: - pass - self.timer = QtCore.QTimer(self) - self.timer.timeout.connect(self.updateImage) - self.timer.start(10) + self.new_frame_sim_cb() + except AttributeError: + app._camera.run(self.new_frame_pv_cb) + + def check_zescape(self): msg = zescape.check() @@ -3156,28 +3174,31 @@ class Main(QMainWindow, Ui_MainWindow): def really_quit(self): """called when user Ctrl-Q the app""" - global user, just_quit - if (just_quit - or QMessageBox.question(self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes - ): + if QMessageBox.question(self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes: self._do_quit = True self.close() def closeEvent(self, event): """this is called when the user clicks the window's cross icon""" - global user, just_quit if ( - just_quit - or self._do_quit + self._do_quit or QMessageBox.question( self, "", "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No,) == QMessageBox.Yes ): - sample_camera.disconnect() + app=QApplication.instance() + try: + pv=app._camera._pv['pic'] + pv.clear_auto_monitor() # disconnect PV monitor callback -> program exit faster. + except AttributeError: + _log.warning('disconnect PV callback failed.') + + _log.info('disconnect PV callback') settings.setValue("window/geometry", self.saveGeometry()) settings.setValue("window/windowState", self.saveState()) settings.setValue("window/main_splitter", self._main_splitter.sizes()) settings.setValue("last_active", time.time()) - - QMainWindow.closeEvent(self, event) + _log.info('save settings') + #QMainWindow.closeEvent(self, event) + _log.info('closeEvent done') else: event.ignore() @@ -3220,7 +3241,10 @@ def sigint_handler(*args): def main(): import argparse - parser = argparse.ArgumentParser() + #(h, t)=os.path.split(sys.argv[0]);cmd='\n '+(t if len(h)>20 else sys.argv[0])+' ' + #exampleCmd=('', '-m0xf -v0') + epilog=__doc__ #+'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n' + parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("--sim", "-s", type=lambda x: int(x,0), help="simulate devices (see bitmasks) default=0x%(default)x", default=0) args = parser.parse_args() _log.info('Arguments:{}'.format(args.__dict__)) @@ -3250,10 +3274,9 @@ def main(): if args.sim&0x08: app._camera = camera.epics_cam(None) app._camera.sim_gen(mode=1) - app._camera.run() else: app._camera = camera.epics_cam() - app._camera.run() + #app._camera.run() is called in center_piece_update app_icon = QtGui.QIcon() app_icon.addFile("artwork/logo/16x16.png", QtCore.QSize(16, 16))