class Ctrl(jk.Joystick): # initialize the infinite loop decorator _infinite_loop = jk.deco_infinite_loop() def _init(self, **kwargs): first_seg = kwargs.get('first_seg', []) # create a graph frame self.mygraph = self.add_frame( jk.Graph(name="tip-tilt", size=(500, 500), pos=(50, 50), fmt="ko", xnpts=len(first_seg), xnptsmax=len(first_seg), freq_up=3, bgcol="w", xylim=(-core.TIPTILTMAX, core.TIPTILTMAX, -core.TIPTILTMAX, core.TIPTILTMAX))) self.mems = Mems(first_segs) @_infinite_loop(wait_time=0.2) def _generate_fake_data(self): # function looped every 0.2 second """ Loop starting with simulation start, getting data and pushing it to the graph every 0.2 seconds """ # If the connection to the mems got killed self.running = self.mems.connected if self.mems.connected: # get pos of mems self.mems.get_pos('all') # push new data to the graph self.mygraph.set_xydata(self.mems._pos[:, 0], self.mems._pos[:, 1])
class test(jk.Joystick): # initialize the infinite loop decorator _infinite_loop = jk.deco_infinite_loop() def _init(self, *args, **kwargs): """ Function called at initialization, see the doc """ self._t0 = time.time() # initialize time self.xdata = np.array([self._t0]) # time x-axis self.ydata = np.array([0.0]) # fake data y-axis # create a graph frame self.mygraph = self.add_frame(jk.Graph(name="test", size=(500, 500), pos=(50, 50), fmt="go-", xnpts=10000, xnptsmax=10000, xylim=(None, None, 0, 1))) @_infinite_loop(wait_time=0.2) def _generate_data(self): # function looped every 0.2 second to read or produce data """ Loop starting with the simulation start, getting data and pushing it to the graph every 0.2 seconds """ # concatenate data on the time x-axis self.xdata = jk.core.add_datapoint(self.xdata, time.time(), xnptsmax=self.mygraph.xnptsmax) # concatenate data on the fake data y-axis self.ydata = jk.core.add_datapoint(self.ydata, np.random.random(), xnptsmax=self.mygraph.xnptsmax) self.mygraph.set_xydata(t, self.ydata)
class test(jk.Joystick, y_data): # initialize the infinite loop and callit decorators so they can auto- # register methods they decorate _infinite_loop = jk.deco_infinite_loop() _callit = jk.deco_callit() @_callit('before', 'init') def _init_data(self, *args, **kwargs): # Function automatically called at initialization, thanks to the # decorator self.xdata = np.array([]) # time x-axis self.ydata = np.array([y_data]) # fake data y-axis @_callit('after', 'init') def _build_frames(self, *args, **kwargs): # Function automatically called at initialization, thanks to the # decorator. It will be called after "_init_data" given that it is # declared after # create a graph frame self.mygraph = self.add_frame( jk.Graph(name="test", size=(500, 500), pos=(50, 50), fmt="go-", xnpts=15, freq_up=7, bgcol="y", xylim=(0, 10, 0, 1), xlabel='t', ylabel='random')) # create a text frame self.mytext = self.add_frame( jk.Text(name="Y-overflow", size=(500, 250), pos=(600, 50), freq_up=1)) @_callit('before', 'start') def _set_t0(self): # initialize t0 at start-up self._t0 = time.time() @_infinite_loop(wait_time=0.2) def _get_data(self): # This method will automatically be called with simulation start # (t.start()), and looped every 0.2 in a separate thread as long as # the simulation runs (running == True) # It gets new data (fake random data) and pushes it to the frames. # concatenate data on the time x-axis new_x_data = time.time() self.xdata = jk.core.add_datapoint(self.xdata, new_x_data, xnptsmax=self.mygraph.xnptsmax) # concatenate data on the fake data y-axis ''' new_y_data = np.random.random()*1.05 # check overflow for the new data point if new_y_data > 1: # send warning to the text-frame self.mytext.add_text('Some data bumped into the ceiling: ' '{:.3f}'.format(new_y_data)) self.ydata = jk.core.add_datapoint(self.ydata, new_y_data, xnptsmax=self.mygraph.xnptsmax) ''' # prepare the time axis t = np.round(self.xdata - self._t0, 1) # push new data to the graph self.mygraph.set_xydata(t, self.ydata) @_callit('before', 'exit') def exit_warning(self): # Just a warning, automatically called with the exit method, and # before the exiting actually takes place (closing frames, etc) print("You're about to exit, frames will disappear in 1 second") time.sleep(1)
class test(jk.Joystick): # initialize the infinite loop decorator _infinite_loop = jk.deco_infinite_loop() def _init(self, *args, **kwargs): """ Function called at initialization, don't bother why for now """ self._t0 = time.time() # initialize time self.xdata = np.array([self._t0]) # time x-axis self.ydata = np.array([0.0]) # fake data y-axis # create a graph frame self.mygraph = self.add_frame( jk.Graph(name="test", size=(500, 500), pos=(50, 50), fmt="go-", xnpts=15, freq_up=7, bgcol="y", xylim=(0, 10, 0, 1))) # create a text frame self.mytext = self.add_frame( jk.Text(name="Y-overflow", size=(500, 250), pos=(600, 50), freq_up=2)) self.myimg = self.add_frame( jk.Image(name="IMG", size=(0.5, 0.5), pos=(0.2, 0.2), screen_relative=True, axrect=(0, 0, 1, 1), freq_up=3, cm_bounds=(0, 1))) @_infinite_loop(wait_time=0.2) def _generate_fake_data(self): # function looped every 0.2 second """ Loop starting with simulation start, getting data and pushing it to the graph every 0.2 seconds """ # concatenate data on the time x-axis self.xdata = jk.core.add_datapoint(self.xdata, time.time(), xnptsmax=self.mygraph.xnptsmax) # concatenate data on the fake data y-axis self.ydata = jk.core.add_datapoint(self.ydata, np.random.random() * 1.05, xnptsmax=self.mygraph.xnptsmax) # check overflow for the last data point added if self.ydata[-1] > 1: # send warning to the text-frame self.mytext.add_text('Some data bumped into the ceiling: ' '{:.3f}'.format(self.ydata[-1])) # prepare the time axis t = np.round(self.xdata - self._t0, 1) # push new data to the graph self.mygraph.set_xydata(t, self.ydata) @_infinite_loop(wait_time=5) def _generate_fake_image(self): # function looped every 5 second data = np.random.random((10, 10))**3 self.myimg.set_data(data) self.mytext.add_text('Updated graph, mean: {:.3f}'.format(data.mean()))
class AndorCtrl(jk.Joystick): _infinite_loop = jk.deco_infinite_loop() _callit = jk.deco_callit() _boxcal = BoxCal(nfib=len(core.FIRSTSEGS), with_cam=False) @_callit('before', 'init') def _init_data(self, *args, **kwargs): print("Initializing Andor Camera .... ") #self.cam = andorsdk.Andor() self.cam = andor.Andor() print("Cooling down the detector...") self.cam.SetTemperature(core.CAMERATEMP) self.cam.CoolerON() #self.cam.GetStatus() self._txtlog = {} self.auto_cmap_adjust = True self.log = False self.camsize = (self.cam.width, self.cam.height) self.lastimg = np.zeros(self.camsize).astype(np.int16) self._dark = np.zeros(self.camsize).astype(np.int16) #self.cam.exposure = core.DEFAULTEXPOSURETIME # ms self.cam.exposure = 100 # ms self.cam.SetVideoScan() self.cam.StartAcquisition() # needed for boxcal show_boxes self._boxcal._szratio = self.camsize[0]*1./self.camsize[1] # init the sub img self._nsub = [int(np.ceil(np.sqrt(len(core.FIRSTSEGS)))), 0] self._nsub[1] = int(np.ceil(len(core.FIRSTSEGS)/self._nsub[0])) self._do_boxes() l = self.boxes_list(ret=True) if len(l) > 0: self.boxes_load(l[-1]) self._txtlog = {'dark': False, 'log': self._log, 'auto': self.auto_cmap_adjust} def _do_boxes(self): box_pxsize = self._boxcal.box_pxsize self._subsize = [self._nsub[0] * (box_pxsize[0] + core.MARGIN)\ + core.MARGIN, self._nsub[1] * (box_pxsize[1] + core.MARGIN)\ + core.MARGIN] self.lastsubimg = np.zeros(self._subsize).astype(np.int16) * np.nan self._subimgboxes = [] for idx, seg in enumerate(core.FIRSTSEGS): ystart = (idx % self._nsub[0]) * (box_pxsize[0] + core.MARGIN)\ + core.MARGIN xstart = (idx // self._nsub[1]) * (box_pxsize[1] + core.MARGIN)\ + core.MARGIN ystop = ystart + box_pxsize[0] xstop = xstart + box_pxsize[1] self._subimgboxes.append([slice(ystart, ystop), slice(xstart, xstop)]) @_callit('after', 'init') def _build_frames(self, *args, **kwargs): if core.SHOWANDORBIGIMAGE: self.img = self.add_frame( jk.Image(name="Andor", pos=(50, 100), size=[self.camsize[1], self.camsize[0]], #size=[self.camsize[0], self.camsize[1]], freq_up=7, cmap='gist_earth')) self.subimg = self.add_frame( jk.Image(name="Segments", pos=(650, 50), size=[self._subsize[1]*core.ZOONFACTORSUBIMG, self._subsize[0]*core.ZOONFACTORSUBIMG], freq_up=7, cmap='gist_earth', axrect=[0,0,1,1], centerorig=False)) self.cts = self.add_frame( jk.Text(name="Counts", size=(350, 230), pos=(10, 10), freq_up=10, rev=True, mark_line=False, scrollbar=False)) for idx, seg in enumerate(core.FIRSTSEGS): sby, sbx = self._subimgboxes[idx] self.subimg.ax.text(sbx.start + core.MARGIN, sby.stop, "#"+str(seg)) @_infinite_loop(wait_time=0.12) def _get_data(self): #error = self.cam.dll.SetCurrentCamera(self.cam.camera_handle) #self.lastimg = self.cam.Acquire.Newest(1).astype(np.int16).reshape((496,658)).T self.rawdata = [] #print(self.cam.GetStatus()) self.cam.GetMostRecentImage(self.rawdata) #self.lastimg = np.reshape(self.rawdata,(496, 658)).T self.lastimg = np.reshape(self.cam.imageArray,(496, 658)).T #try: #self.lastimg = self.cam.Acquire.Newest(1).astype(np.int16) # self.lastimg = self.cam.Acquire.Newest(1).astype(np.int16).reshape((496,658)).T #except andorsdk.AndorError:#################################################################### #except andor.AndorError: # return data = self.lastimg-self.dark if self._log: data = np.log(np.clip(data, a_min=data[data>0].min(), a_max=1e99)) if core.SHOWANDORBIGIMAGE: self.img.set_data(data) for idx, seg in enumerate(core.FIRSTSEGS): by, bx = self._boxcal.boxes[idx] cut = data[by.start:by.stop,bx.start:bx.stop] sby, sbx = self._subimgboxes[idx] self._txtlog['sum'+str(seg)] = cut.sum() self._txtlog['max'+str(seg)] = cut.max() self.lastsubimg[sby.start:sby.stop,sbx.start:sbx.stop] = cut self.subimg.set_data(self.lastsubimg) self.cts.clear() # auto-adjust cmap if self._auto_cmap_adjust: bds = data.min(), data.max() if core.SHOWANDORBIGIMAGE: self.img.cm_bounds = bds self.subimg.cm_bounds = bds self._txtlog['min'], self._txtlog['max'] = self.subimg.cm_bounds self.cts.add_text(core.DISPLAYLOG.format(**self._txtlog)) def save_latest(self, name, override=False): """ Saves the latest image to file Args: * name (str): the name of the file * override (bool): whether to override an existing file """ name = os.path.join(core.PATHIMG, datetime.utcnow().strftime(core.IMGFILENAME)\ .format(name=core.clean_txt(str(name)))) if os.path.isfile(name) and not bool(override): print("File '{}' already exists".format(name)) return hdulist = pf.HDUList() self.cam.CoolerON() hd = pf.Header([ ('TYPE', 'img-dark', 'See other hdus for img or dark data'), ('ITIME', self.cam.exposure, 'in ms'), ('TIME', datetime.utcnow().strftime('%H%M%S'), 'Time HHMMSS'), ('MSTIME', datetime.utcnow().strftime('%f'), 'Time microseconds'), ('DATE', datetime.utcnow().strftime('%Y%m%d'), 'Date YYYYMMDD'), ('COOLER', core.CAMERACOOLING, 'Cooler on/off'), ('TEMP', self.cam.temperature, 'Current temperature (C)'), ('SETTEMP', core.CAMERATEMP, 'Target temperature (C)') ]) hd.add_comment('Written by Guillaume SCHWORER') last = self.lastimg dark = self.dark hdulist.append(pf.ImageHDU(data=last-dark, header=hd)) hdulist.append(pf.ImageHDU(data=last, header=pf.Header([('TYPE', 'img')]))) hdulist.append(pf.ImageHDU(data=dark, header=pf.Header([('TYPE', 'dark')]))) hdulist.writeto(name, clobber=override) print("Saved in '{}'".format(name)) def save_dark(self, name, override=False): """ Saves the current dark to file Args: * name (str): the name of the file * override (bool): whether to override an existing file """ name = os.path.join(core.PATHIMG, datetime.utcnow().strftime(core.IMGFILENAME)\ .format(name=core.clean_txt(str(name)))) if os.path.isfile(name) and not bool(override): print("File '{}' already exists".format(name)) return hdulist = pf.HDUList() hd = pf.Header([ ('TYPE', 'dark', ''), ('ITIME', self.cam.exposure, 'in ms'), ('TIME', datetime.utcnow().strftime('%H%M%S'), 'Time HHMMSS'), ('MSTIME', datetime.utcnow().strftime('%f'), 'Time microseconds'), ('DATE', datetime.utcnow().strftime('%Y%m%d'), 'Date YYYYMMDD'), ('COOLER', self.cam.Temperature.cooler, 'Cooler on/off'), ('TEMP', self.cam.Temperature.read['temperature'], 'Current temperature (C)'), ('SETTEMP', self.cam.Temperature.setpoint, 'Target temperature (C)') ]) hd.add_comment('Written by Guillaume SCHWORER') hdulist.append(pf.ImageHDU(data=self.dark, header=hd)) hdulist.writeto(name, clobber=override) print("Saved in '{}'".format(name)) def boxes_load(self, name): """ Loads a boxes file previously saved Args: * name (str): the name of the file to load """ self._boxcal.boxes_load(name) self._do_boxes() boxes_list = _boxcal.boxes_list def show_boxes(self, cmap_minmax=None, cmap='gist_earth'): """ Shows the boxes Args: * cmap_minmax ([float, float] or None): min-max for the color- scale, or None for auto-determination * cmap (color map object or str): the color map used for displaying the image """ self._boxcal.show_boxes(img=self.lastimg, cmap_minmax=cmap_minmax, cmap=cmap) @property def clims(self): """ The [min, max] of the view """ return self.subimg.cm_bounds @clims.setter def clims(self, value): if core.SHOWANDORBIGIMAGE: self.img.cm_bounds = value self.subimg.cm_bounds = value @_callit('after', 'exit') def _exit_warning(self): print("Exiting") self.cam.ShutDown() time.sleep(1) @property def dark(self): return self._dark @dark.setter def dark(self, value): print('Use acq_dark or rm_dark instead') def acq_dark(self): """ Acquires a dark frame that will be subtracted to the current video stream """ self.rawdata = [] #self._dark = self.cam.Acquire.Newest(1).astype(np.int16) self.cam.GetMostRecentImage(self.rawdata) #self.lastimg = np.reshape(self.rawdata,(496, 658)).T self._dark = np.reshape(self.cam.imageArray,(496, 658)).T self._txtlog['dark'] = True def rm_dark(self): """ Deletes the current dark frame """ self._dark = np.zeros(self.camsize).astype(np.int16) self._txtlog['dark'] = False @property def auto_cmap_adjust(self): """ Set to True to activate automated color-map min-max adjustment, or False to deactivate it """ return self._auto_cmap_adjust @auto_cmap_adjust.setter def auto_cmap_adjust(self, value): self._auto_cmap_adjust = bool(value) self._txtlog['auto'] = self._auto_cmap_adjust @property def log(self): """ Set to True to activate log view, or False to deactivate it """ return self._log @log.setter def log(self, value): self._log = bool(value) self._txtlog['log'] = self._log
class MemsCtrl(jk.Joystick): # initialize the infinite loop decorator _infinite_loop = jk.deco_infinite_loop() _callit = jk.deco_callit() @_callit('before', 'init') def _init_data(self, **kwargs): # some variable init pass @_callit('after', 'init') def _build_frames(self, *args, **kwargs): self.tiptilt = self.add_frame( jk.GraphMulti(name="tip-tilt", size=(500, 500), pos=(50, 50), fmt="ko", xnpts=len(core.FIRSTSEGS), nlines=len(core.FIRSTSEGS), freq_up=5, bgcol="w", numbering=True, lbls=core.FIRSTSEGS, legend=False, xylim=(core.TIPTILTMIN, core.TIPTILTMAX, core.TIPTILTMIN, core.TIPTILTMAX), xlabel='tip', ylabel='tilt')) self.piston = self.add_frame( jk.Graph(name="Piston", size=(500, 500), pos=(650, 50), fmt="rs", xnpts=len(core.FIRSTSEGS), freq_up=5, bgcol="w", xylim=(-1, np.max(core.FIRSTSEGS) + 1, core.PISTONMIN, core.PISTONMAX), xlabel='segment', ylabel='piston')) self.mems = Mems() @_callit('before', 'exit') def _exit_warning(self): print('Exiting') self.mems.disconnect() @_infinite_loop(wait_time=0.2) def _get_pos(self): """ Loop starting with simulation start, getting data and pushing it to the graph every 0.2 seconds """ # If the connection to the mems got killed if self.mems.connected: # get pos of mems tip, tilt, piston = self.mems.get_pos('first') # push new data to the graph self.tiptilt.set_xydata(x=tip.reshape((tip.size, 1)), y=tilt.reshape((tilt.size, 1))) self.piston.set_xydata(core.FIRSTSEGS, piston) else: self.running = False