def setUp(self): # arguments and keywords self.test_fits = os.path.abspath(os.path.dirname(__file__)) # __init__ test self.ml = MultiLens(self.test_fits) # verbosity self.v = {'verbose': 1} print("") print(self.separator) print(self.shortDescription())
def _on_open(self, event=None): """ Execute when 'open' event is triggered """ fin = filedialog.askopenfilenames(parent=self.master, defaultextension=".fits", multiple=True) if fin: if len(fin) > 0 and all([f.endswith(".fits") for f in fin]): self.lens_patch = MultiLens(fin, auto=False) elif len(fin) == 1 and fin[0].endswith(".json"): with open(fin[0], 'r') as jsonf: self.lens_patch = MultiLens.from_json(jsonf) self.window.canvas.N = self.lens_patch.N self.project_patch()
def test_from_json(self): """ # from_json """ filename = 'test.json' self.ml.lens_objects[5].photzp = 25.67 filename = self.ml.jsonify(name='test.json') print(">>> {}".format(filename)) with open(filename, 'r') as j: jcopy = MultiLens.from_json(j, **self.v) self.assertEqual(jcopy, self.ml) self.assertFalse(jcopy is self.ml) self.assertEqual(jcopy.lens_objects[0], self.ml.lens_objects[0]) self.assertEqual(jcopy.lens_objects[5].photzp, self.ml.lens_objects[5].photzp) try: os.remove(filename) except OSError: pass
def test_find_files(self): """ # find_files """ print(">>> {}".format(self.test_fits)) fpaths = MultiLens.find_files(self.test_fits, **self.v) self.assertTrue([self.test_fits in fpaths])
def test_MultiLens(self): """ # MultiLens """ print(">>> {}".format(self.test_fits)) ml = MultiLens(self.test_fits, **self.v) self.assertIsInstance(ml, MultiLens) self.assertEqual(ml, self.ml)
class TestMultiLens(UnitTestPrototype): def setUp(self): # arguments and keywords self.test_fits = os.path.abspath(os.path.dirname(__file__)) # __init__ test self.ml = MultiLens(self.test_fits) # verbosity self.v = {'verbose': 1} print("") print(self.separator) print(self.shortDescription()) def tearDown(self): print("") def test_MultiLens(self): """ # MultiLens """ print(">>> {}".format(self.test_fits)) ml = MultiLens(self.test_fits, **self.v) self.assertIsInstance(ml, MultiLens) self.assertEqual(ml, self.ml) def test_copy(self): """ # copy """ print(">>> {}".format(self.ml)) copy = self.ml.copy(**self.v) self.assertEqual(copy, self.ml) self.assertFalse(copy is self.ml) def test_deepcopy(self): """ # deepcopy """ print(">>> {}".format(self.ml)) copy = self.ml.deepcopy(**self.v) self.assertEqual(copy, self.ml) self.assertFalse(copy is self.ml) def test_from_json(self): """ # from_json """ filename = 'test.json' self.ml.lens_objects[5].photzp = 25.67 filename = self.ml.jsonify(name='test.json') print(">>> {}".format(filename)) with open(filename, 'r') as j: jcopy = MultiLens.from_json(j, **self.v) self.assertEqual(jcopy, self.ml) self.assertFalse(jcopy is self.ml) self.assertEqual(jcopy.lens_objects[0], self.ml.lens_objects[0]) self.assertEqual(jcopy.lens_objects[5].photzp, self.ml.lens_objects[5].photzp) try: os.remove(filename) except OSError: pass def test_jsonify(self): """ # jsonify """ self.ml.lens_objects[5].photzp = 25.67 print(">>> {}".format(self.ml)) jsnstr = self.ml.jsonify(**self.v) self.assertIsInstance(jsnstr, str) def test_find_files(self): """ # find_files """ print(">>> {}".format(self.test_fits)) fpaths = MultiLens.find_files(self.test_fits, **self.v) self.assertTrue([self.test_fits in fpaths]) def test_add_srcimg(self): """ # add_srcimg """ print(">>> {}".format((-1.234, 0.567))) before = self.ml.srcimgs[:] self.ml.add_srcimg((-1.234, 0.567), unit='arcsec', relative=True, **self.v) after = self.ml.srcimgs self.assertEqual([len(b) + 1 for b in before], [len(a) for a in after]) def test_add_to_patch(self): """ # add_to_patch""" print(">>> {}".format(self.ml.filepaths[0])) before = self.ml.copy() self.ml.add_to_patch(self.ml.filepaths[0]) after = self.ml self.assertEqual(before.N + 1, after.N) self.assertEqual(before.filepaths, after.filepaths[:-1]) self.assertEqual(before.bands, after.bands[:-1]) self.assertEqual(self.ml.filepaths[0], after.filepaths[-1]) def test_remove_from_patch(self): """ # remove_from_patch """ print(">>> {}".format(-1)) before = self.ml.copy() self.ml.remove_from_patch(-1, **self.v) after = self.ml self.assertEqual(before.N - 1, after.N) self.assertEqual(before.filepaths[:-1], after.filepaths) def test_reorder_patch(self): """ # reorder_patch """ print(">>> {}".format(list(range(self.ml.N))[::-1])) before = self.ml.copy() self.ml.reorder_patch(list(range(self.ml.N))[::-1], **self.v) after = self.ml self.assertEqual(before.N, after.N) self.assertEqual(before.filepaths[::-1], after.filepaths) self.assertEqual(before.bands[::-1], after.bands) def test_plot_composite(self): """ # plot_composite """ print(">>> {}".format(self.ml)) fig, ax = self.ml.show_composite(savefig='test.pdf', **self.v) self.assertIsNotNone(fig, ax) try: os.remove('test.pdf') except OSError: pass
# jsonfile = "data/Caba22.multilens#a061574e76f9a7d1a7bbbd7a0a61e.json" # jsonfile = "data/Caba39.multilens#7c20b67b2e57c890d283ab7ba35e4.json" # jsonfile = "data/MoreSA28.multilens#45d308e03681414d48a2e8c6504cf.json" # jsonfile = "data/MoreSA59.multilens#e27bed3796282edbb2f4add2b0928.json" # jsonfile = "data/MoreSA121.multilens#f8401b8d6046f4bb22b714032be1e.json" # jsonfile = "data/Para1024.multilens#7d27cc987b89ad1b9d03828a8bc2d.json" # jsonfile = "data/Para1037.multilens#0d34f904ecd3e5c38035b43483295.json" # jsonfile = "data/Para1079.multilens#81a0a92146af752f4404c0380fdf6.json" # jsonfile = "data/Para1106.multilens#843e6153eea1cdb0c8d6c6c89eba2.json" # jsonfile = "data/Para2109.multilens#586f69cabe4f43ef74751c4820fa3.json" # jsonfile = "data/Para2169.multilens#1cf88bd132faf8931a02f3076b591.json" jsonfile = "data/SW05.multilens#4ebca5f7da0763d2a8aae675763a8.json" # jsonfile = "data/SW06.multilens#dbfc84ca1d42c30410d812fc1dab2.json" with open(jsonfile, 'r') as f: ml = MultiLens.from_json(f, verbose=1) print("\n") sampler = StarSampler.from_gleamobj(ml, verbose=1) m_stel = sampler.chabrier_estimate(band_data=[l.data for l in ml]) print("Mstel (model): {}".format(m_stel)) m_stel = m_stel[1] ml['i'].stel_mass = m_stel # ml.jsonify(name=jsonfile, with_hash=True) # # Test for constructing the stellar mass map from total mass estimate # print(ml['i'].stel_map) mstel_map = ml['i'].stel_map # print(dir(ml['i'])) mstel_map = StarSampler.resample_map(mstel_map, ml['i'].extent, (32, 32), [-7.5, -7.5, 7.5, 7.5]) plt.imshow(mstel_map, origin='lower')
def __init__(self, master, filepath, cell_size=None, display_off=False, verbose=False, *args, **kwargs): """ Initialize all components of the app Args: master <Tk object> - master root of the frame filepath <str> - file path to the directory where all .fits files reside Kwargs: cell_size <> verbose <bool> - verbose mode; print command line statements Return: <App object> - standard initializer """ FramePrototype.__init__(self, master, root=master, *args, **kwargs) self.master.title('App') self.master.protocol('WM_DELETE_WINDOW', self._on_close) # self.master.wm_iconbitmap() # add lens framework if filepath.endswith(".json"): with open(filepath, 'r') as f: self.lens_patch = MultiLens.from_json(f) else: self.lens_patch = MultiLens(filepath, auto=False) self.env.add(self.env, self.lens_patch, self, itemname='lens_patch') # initialize app components self.menubar = Menubar(self) self.navbar = Navbar(self) self.toolbar = Toolbar(self) self.statusbar = Statusbar(self) self.window = Window(self) # state attributes self.selection_mode = None self.colormap = 'Spectral_r' # menubar self.menubar.main_labels = ['file', 'edit', 'view', 'help'] self.menubar.labels = [[ 'open...', 'save as...', 'export .gls', 'exit' ], ['colormap', 'toggle scalebar'], ['navbar', 'toolbar', 'statusbar'], ['help', 'about']] self.menubar.mk_checklist('colormap', sub_labels=list(plt.colormaps()), variable=self._colormap, command=self._on_colormap) self.menubar.shortcuts = [[u'\u2303F', u'\u2303S', u'', u'\u2303Q'], ['', ''], [ u'\u2303\u2325N', u'\u2303\u2325T', u'\u2303\u2325S' ], [u'\u2303H', '']] self.menubar.bindings = [ [ self._on_open, self._on_save_as, self._on_export_glsc, self._on_close ], [self.menubar.dummy_func, self.menubar.dummy_func], [ self.menubar.dummy_func, self.menubar.dummy_func, self.menubar.dummy_func ], [self._on_help, self._on_about], ] self.menubar.rebuild() # navbar # toolbar self.toolbar.sections = ['data', 'selection', ' '] self.toolbar.add_labels('data', [ ['XY', self.window.canvas._cursor_position], ['ADU', self.window.canvas._cursor_value], [ 'Mag', self.window.canvas.cursor_value_transf( self.lens_patch[0].mag_formula) ], ]) self.toolbar.add_buttons('selection', [ ['Lens', 'Clear lens'], ['Src imgs', 'Clear srcimgs'], ['/assets/circle.png', 'Revert'], ['/assets/rect.png', 'Delete'], ['/assets/polygon.png'], ]) self.toolbar.add_buttons(' ', [ ['Save JSON', 'Save PNG'], ]) self.toolbar.bindings = [ [], [ self._on_lens, self._on_clear_lens, self._on_srcimgs, self._on_clear_srcimgs, self._on_circle, self._on_revert, self._on_rect, self._on_delete, self._on_polygon ], [self._on_save_as_json, self._on_save_as_png], ] self.toolbar.rebuild() # statusbar self.statusbar.log('In development...') # window and canvas if cell_size is None: # default configuration cols = 3 rows = max(self.lens_patch.N // 3, 1) # 67% of the screen width and 89% of the screen height cw = int(0.6666 * self.master.winfo_screenwidth() // cols // 100 * 100) ch = int(0.8888 * self.master.winfo_screenheight() // rows // 100 * 100) cell_size = (min(cw, ch), min(cw, ch)) self.window.canvas.cell_size = cell_size self.window.canvas.scroll_event_offset_widget = self.toolbar # pack all frames with the grid geometry manager self.menubar.grid(columnspan=2, row=0, sticky=tk.NE) self.navbar.grid(columnspan=2, row=1, sticky=tk.NE) self.toolbar.grid(column=0, row=2, columnspan=1, sticky=tk.N + tk.W + tk.S) self.window.grid(column=1, row=2, columnspan=1, sticky=tk.N + tk.S + tk.E + tk.W) self.statusbar.grid(columnspan=2, row=3, sticky=tk.E + tk.S + tk.W) # adding resize configs for window at (1, 2) self.grid(sticky=tk.N + tk.S + tk.E + tk.W) self.columnconfigure(1, weight=1) self.rowconfigure(2, weight=1) self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=1) # test projecting entire image patch if not display_off: self.project_patch() # test reducing image number and column number # self.window.canvas.N = 1 # self.window.canvas.ncols = 1 # self.window.canvas.matrix_size = 500, 500 # self.project([self.lens_patch.composite_image]) if verbose: print(self.__v__)
class App(FramePrototype): """ Main frame for the app """ def __init__(self, master, filepath, cell_size=None, display_off=False, verbose=False, *args, **kwargs): """ Initialize all components of the app Args: master <Tk object> - master root of the frame filepath <str> - file path to the directory where all .fits files reside Kwargs: cell_size <> verbose <bool> - verbose mode; print command line statements Return: <App object> - standard initializer """ FramePrototype.__init__(self, master, root=master, *args, **kwargs) self.master.title('App') self.master.protocol('WM_DELETE_WINDOW', self._on_close) # self.master.wm_iconbitmap() # add lens framework if filepath.endswith(".json"): with open(filepath, 'r') as f: self.lens_patch = MultiLens.from_json(f) else: self.lens_patch = MultiLens(filepath, auto=False) self.env.add(self.env, self.lens_patch, self, itemname='lens_patch') # initialize app components self.menubar = Menubar(self) self.navbar = Navbar(self) self.toolbar = Toolbar(self) self.statusbar = Statusbar(self) self.window = Window(self) # state attributes self.selection_mode = None self.colormap = 'Spectral_r' # menubar self.menubar.main_labels = ['file', 'edit', 'view', 'help'] self.menubar.labels = [[ 'open...', 'save as...', 'export .gls', 'exit' ], ['colormap', 'toggle scalebar'], ['navbar', 'toolbar', 'statusbar'], ['help', 'about']] self.menubar.mk_checklist('colormap', sub_labels=list(plt.colormaps()), variable=self._colormap, command=self._on_colormap) self.menubar.shortcuts = [[u'\u2303F', u'\u2303S', u'', u'\u2303Q'], ['', ''], [ u'\u2303\u2325N', u'\u2303\u2325T', u'\u2303\u2325S' ], [u'\u2303H', '']] self.menubar.bindings = [ [ self._on_open, self._on_save_as, self._on_export_glsc, self._on_close ], [self.menubar.dummy_func, self.menubar.dummy_func], [ self.menubar.dummy_func, self.menubar.dummy_func, self.menubar.dummy_func ], [self._on_help, self._on_about], ] self.menubar.rebuild() # navbar # toolbar self.toolbar.sections = ['data', 'selection', ' '] self.toolbar.add_labels('data', [ ['XY', self.window.canvas._cursor_position], ['ADU', self.window.canvas._cursor_value], [ 'Mag', self.window.canvas.cursor_value_transf( self.lens_patch[0].mag_formula) ], ]) self.toolbar.add_buttons('selection', [ ['Lens', 'Clear lens'], ['Src imgs', 'Clear srcimgs'], ['/assets/circle.png', 'Revert'], ['/assets/rect.png', 'Delete'], ['/assets/polygon.png'], ]) self.toolbar.add_buttons(' ', [ ['Save JSON', 'Save PNG'], ]) self.toolbar.bindings = [ [], [ self._on_lens, self._on_clear_lens, self._on_srcimgs, self._on_clear_srcimgs, self._on_circle, self._on_revert, self._on_rect, self._on_delete, self._on_polygon ], [self._on_save_as_json, self._on_save_as_png], ] self.toolbar.rebuild() # statusbar self.statusbar.log('In development...') # window and canvas if cell_size is None: # default configuration cols = 3 rows = max(self.lens_patch.N // 3, 1) # 67% of the screen width and 89% of the screen height cw = int(0.6666 * self.master.winfo_screenwidth() // cols // 100 * 100) ch = int(0.8888 * self.master.winfo_screenheight() // rows // 100 * 100) cell_size = (min(cw, ch), min(cw, ch)) self.window.canvas.cell_size = cell_size self.window.canvas.scroll_event_offset_widget = self.toolbar # pack all frames with the grid geometry manager self.menubar.grid(columnspan=2, row=0, sticky=tk.NE) self.navbar.grid(columnspan=2, row=1, sticky=tk.NE) self.toolbar.grid(column=0, row=2, columnspan=1, sticky=tk.N + tk.W + tk.S) self.window.grid(column=1, row=2, columnspan=1, sticky=tk.N + tk.S + tk.E + tk.W) self.statusbar.grid(columnspan=2, row=3, sticky=tk.E + tk.S + tk.W) # adding resize configs for window at (1, 2) self.grid(sticky=tk.N + tk.S + tk.E + tk.W) self.columnconfigure(1, weight=1) self.rowconfigure(2, weight=1) self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=1) # test projecting entire image patch if not display_off: self.project_patch() # test reducing image number and column number # self.window.canvas.N = 1 # self.window.canvas.ncols = 1 # self.window.canvas.matrix_size = 500, 500 # self.project([self.lens_patch.composite_image]) if verbose: print(self.__v__) @classmethod def init(cls, files=[], verbose=False, **kwargs): """ From files initialize an App instance together with it's tk root Args: None Kwargs: files <list(str)> - .fits files for the app to read verbose <bool> - verbose mode; print command line statements Return: root <Tk object> - the master Tk object app <App object> - the app frame instance packed with GLEAM features """ root = tk.Tk() # init master root app = App(root, files, verbose=False, **kwargs) return root, app @property def tests(self): """ A list of attributes being tested when calling __v__ Args/Kwargs: None Return: tests <list(str)> - a list of test variable strings """ return [ 'master', 'lens_patch', 'navbar', 'statusbar', 'menubar', 'toolbar', 'window' ] def project(self, images, image_data=None, verbose=False): """ Project images directly onto the canvas Args: images <list(PIL.Image object)> - images to be added to the buffer Kwargs: image_data <list(np.ndarray)> - the raw data represented in the images verbose <bool> - verbose mode; print command line statements Return: None """ for i, img in enumerate(images): if hasattr(image_data, '__len__'): self.window.canvas.add_image(img, i, image_data=image_data[i]) else: self.window.canvas.add_image(img, i) def project_patch(self, draw_lens=True, draw_srcimgs=True, draw_roi=True): """ Project the lens patch onto the canvas Args: None Kwargs: draw_lens <bool> - draw the lens position on top of data draw_srcimgs <bool> - draw the source image positions on top of data draw_roi <bool> - draw the ROI objects on top of data Return: None """ kwargs = { 'cmap': self.colormap, 'draw_lens': draw_lens, 'draw_srcimgs': draw_srcimgs, 'draw_roi': draw_roi } self.project(self.lens_patch.image_patch(**kwargs), image_data=[f.data for f in self.lens_patch]) def display(self, term_mode=False, verbose=False): """ Wrapper for mainloop Args: None Kwargs: term_mode <bool> - display the app in terminal mode verbose <bool> - verbose mode; print command line statements Return: None """ if term_mode: self.after(100, self.term_shell) if verbose: print(self.__v__) self.mainloop() # Properties ################################################################## @property def selection_mode(self): """ Variable to indicate whether selection mode is on or off Args/Kwargs: None Return: mode <str> - mode string ('circle'/'rect'/'polygon' or None) """ if not hasattr(self, '_selection_mode'): self._selection_mode = None return self._selection_mode @selection_mode.setter def selection_mode(self, mode): """ Set the selection mode. While selection mode is off, all widgets are enabled. Args: mode <str> - mode string ('lens'/'srcimg'/'circle'/'rect'/'polygon' or None) Kwargs/Return: None """ self._selection_mode = mode if self._selection_mode is None: self.enable(self.toolbar) else: button_name = "_on_{}".format(self._selection_mode) self.disable(self.toolbar, exceptions=[button_name]) @property def selection(self): """ The current selection Args/Kwargs: None Return: selection <ROISelector.[] object> - current ROI object """ if not hasattr(self, '_selection'): self._selection = None return self._selection @selection.setter def selection(self, roi): """ Setter for the current selection Args: roi <ROISelector.[] object> - current ROI object Kwargs/Return: None """ self._selection = roi @property def colormap(self): """ The colormap used for data representation Args/Kwargs: None Return: cmap <str> - matplotlib.cm strings """ if not hasattr(self, '_colormap'): self._colormap = tk.StringVar() self._colormap.set("viridis") return self._colormap.get() @colormap.setter def colormap(self, cmap): """ Setter for the colormap used for data representation Args: cmap <str> - new matplotlib.cm string Kwargs/Return: None """ if not hasattr(self, '_colormap'): self._colormap = tk.StringVar() self._colormap.set(cmap) # Menu bindings ############################################################### def _on_open(self, event=None): """ Execute when 'open' event is triggered """ fin = filedialog.askopenfilenames(parent=self.master, defaultextension=".fits", multiple=True) if fin: if len(fin) > 0 and all([f.endswith(".fits") for f in fin]): self.lens_patch = MultiLens(fin, auto=False) elif len(fin) == 1 and fin[0].endswith(".json"): with open(fin[0], 'r') as jsonf: self.lens_patch = MultiLens.from_json(jsonf) self.window.canvas.N = self.lens_patch.N self.project_patch() def _on_save_as(self, event=None): """ Execute when 'save as' event is triggered """ fout = filedialog.asksaveasfilename( parent=self.master, defaultextension=".json", initialfile=self.lens_patch.json_filename(), # filetypes=[ # ('All files', '*.*'), ('JSON files', '*.json'), # ('Image files', '*.jpg'), ('Image files', '*.png'), ('Image files', '*.gif'), # ('Image files', '*.tiff'), ('Image files', '*.ppm'), ('Image files', '*.bmp'), # ('Image files', '*.eps'), ('Image files', '*.pdf')] ) if not fout: return # save as json if fout.endswith('.json'): self.lens_patch.jsonify(name=fout, with_hash=False) # save as image if True in [ fout.endswith(ext) for ext in [ '.png', '.PNG', '.sgi', '.tiff', ] ]: kwargs = { 'cmap': self.colormap, 'draw_lens': True, 'draw_srcimgs': True, 'draw_roi': True } for i, img in enumerate(self.lens_patch.image_patch(**kwargs)): fout = ".".join( fout.split('.')[:-1] + ['{:04d}'.format(i)] + fout.split('.')[-1:]) img.save(fout) if True in [ fout.endswith(ext) for ext in [ '.jpg', '.JPG', '.JPEG', '.bmp', '.eps', '.gif', '.ppm', '.pdf', ] ]: kwargs = { 'cmap': self.colormap, 'draw_lens': True, 'draw_srcimgs': True, 'draw_roi': True } for i, img in enumerate(self.lens_patch.image_patch(**kwargs)): fout = ".".join( fout.split('.')[:-1] + ['{:04d}'.format(i)] + fout.split('.')[-1:]) # img.load() bg = Image.new("RGB", img.size, (255, 255, 255)) bg.paste(img, mask=img.split()[3]) bg.save(fout, quality=100) def _on_export_glsc(self, event=None): """ Execute when 'export glsc' event is triggered """ dfltname = self.lens_patch.json_filename() dfltname = ".".join(dfltname.split('.')[:-1] + ['config', 'gls']) fout = filedialog.asksaveasfilename(parent=self.master, defaultextension=".gls", initialfile=dfltname) if not fout: return self.lens_patch[0].glscfactory.write(fout) def _on_close(self, event=None): """ Execute when window is closed """ self.master.quit() sys.exit(1) def _on_colormap(self): """ Change the colormap and reproject """ self.project_patch() def _on_help(self, event=None): """ Execute when 'help' event is triggered """ import webbrowser helpurl = "https://github.com/phdenzel/gleam/blob/master/README.org" webbrowser.open(helpurl, new=0) def _on_about(self, event=None): """ Execute when 'about' event is triggered """ pass # Button bindings ############################################################# def _on_lens(self, event=None): """ Execute when 'lens selection' event is triggered """ # if 'lens selection' event already has been triggered if self.selection_mode == 'lens': self.selection_mode = None self.window.canvas._cursor_click.trace_vdelete( 'w', self.selection_trace[0]) else: self.selection_mode = 'lens' self.selection_trace = [] self.selection_trace.append( self.window.canvas._cursor_click.trace('w', self._lens_click)) def _on_clear_lens(self, event=None): """ Execute when 'lens undo' event is triggered """ for l in self.lens_patch: l._lens = None self.project_patch() def _on_srcimgs(self, event=None): """ Execute when 'srcimgs selection' event is triggered """ # if 'srcimg selection' event already has been triggered if self.selection_mode == 'srcimgs': self.selection_mode = None self.window.canvas._cursor_click.trace_vdelete( 'w', self.selection_trace[0]) else: self.selection_mode = 'srcimgs' self.selection_trace = [] self.selection_trace.append( self.window.canvas._cursor_click.trace('w', self._srcimgs_click)) def _on_clear_srcimgs(self, event=None): """ Execute when 'srcimgs undo' event is triggered """ for l in self.lens_patch: l.srcimgs = [] self.project_patch() def _on_circle(self, event=None): """ Execute when 'circle selection' event is triggered """ # if 'circle selection' event already has been triggered if self.selection_mode == 'circle': self.selection_mode = None self.window.canvas._cursor_click.trace_vdelete( 'w', self.selection_trace[0]) self.window.canvas._cursor_position.trace_vdelete( 'w', self.selection_trace[1]) self.window.canvas._cursor_release.trace_vdelete( 'w', self.selection_trace[2]) else: self.selection_mode = 'circle' # bind key press to create circle, move changes the radius, release saves it self.selection_trace = [] self.selection_trace.append( self.window.canvas._cursor_click.trace('w', self._circle_click)) self.selection_trace.append( self.window.canvas._cursor_position.trace( 'w', self._circle_move)) self.selection_trace.append( self.window.canvas._cursor_release.trace( 'w', self._circle_release)) def _on_rect(self, event=None): """ Execute when 'rectangle selection' event is triggered """ # if 'rect selection' event already has been triggered if self.selection_mode == 'rect': self.selection_mode = None self.window.canvas._cursor_click.trace_vdelete( 'w', self.selection_trace[0]) self.window.canvas._cursor_position.trace_vdelete( 'w', self.selection_trace[1]) self.window.canvas._cursor_release.trace_vdelete( 'w', self.selection_trace[2]) else: self.selection_mode = 'rect' # bind key press to create rectangle, every following click adds to it self.selection_trace = [] self.selection_trace.append( self.window.canvas._cursor_click.trace('w', self._rect_click)) self.selection_trace.append( self.window.canvas._cursor_position.trace( 'w', self._rect_move)) self.selection_trace.append( self.window.canvas._cursor_release.trace( 'w', self._rect_release)) def _on_polygon(self, event=None): """ Execute when 'polygon selection' event is triggered """ # if 'polygon selection' event already has been triggered if self.selection_mode == 'polygon': self.selection_mode = None self.window.canvas._cursor_click.trace_vdelete( 'w', self.selection_trace[0]) else: self.selection_mode = 'polygon' # bind key press to create polygon, every following click adds to it self.selection_trace = [] self.selection_trace.append( self.window.canvas._cursor_click.trace('w', self._polygon_click)) def _on_revert(self): """ Execute when 'revert' event is triggered """ if hasattr(self, '_selection'): del self._selection for l in self.lens_patch: l.roi._buffer[l.roi._selection] = l.roi._buffer[ l.roi._selection][:-1] self.project_patch() def _on_delete(self): """ Execute when 'delete' event is triggered """ if hasattr(self, '_selection'): del self._selection for l in self.lens_patch: for k in l.roi.selection_modes: l.roi._buffer[k] = [] self.project_patch() def _on_save_as_json(self, event=None): """ Execute when 'save as json' event is triggered """ fout = self.lens_patch.json_filename() if fout.endswith('.json'): self.lens_patch.jsonify(name=fout, with_hash=False) def _on_save_as_png(self, event=None): """ Execute when 'save as png' event is triggered """ fout = self.lens_patch.json_filename() kwargs = { 'cmap': self.colormap, 'draw_lens': True, 'draw_srcimgs': True, 'draw_roi': True } for i, img in enumerate(self.lens_patch.image_patch(**kwargs)): fout = ".".join( fout.split('.')[:-1] + ['{:04d}'.format(i)] + ['png']) if fout.endswith('.png'): img.save(fout) # Traces ###################################################################### def _lens_click(self, *args): """ Place the lens position during 'click' event Args/Kwargs/Return: None """ pos = self.window.canvas.cursor_click for l in self.lens_patch: l.lens = pos self.project_patch() self.selection_mode = None self.window.canvas._cursor_click.trace_vdelete('w', self.selection_trace[0]) def _srcimgs_click(self, *args): """ Place source image positions during 'click' event Args/Kwargs/Return: None """ pos = self.window.canvas.cursor_click for l in self.lens_patch: xy = l.srcimgs_xy l.srcimgs_xy = xy + [pos] self.project_patch() def _circle_click(self, *args): """ Start a circle during 'click' event Args/Kwargs/Return: None """ idx = self.window.canvas.cursor_index pos = self.window.canvas.cursor_click if not hasattr(self, '_selection'): self.selection = self.lens_patch[idx].roi.Circle(pos) for l in self.lens_patch: l.roi._buffer['circle'].append(self.selection) l.roi._selection = 'circle' l.roi._focus = -1 self.project_patch() for l in self.lens_patch: l.roi._buffer['circle'] = l.roi._buffer['circle'][:-1] def _circle_move(self, *args): """ Move circle radius during 'motion' event Args/Kwargs/Return: None """ if not hasattr(self, '_selection'): # first there has to be a click, # so if _selection doesn't exist don't do anything return pos = self.window.canvas.cursor_position self.selection.mv_r(pos) for l in self.lens_patch: l.roi._buffer['circle'].append(self.selection) l.roi._selection = 'circle' l.roi._focus = -1 self.project_patch() for l in self.lens_patch: l.roi._buffer['circle'] = l.roi._buffer['circle'][:-1] def _circle_release(self, *args): """ Put the circle into the ROISelector buffers during the 'release' event Args/Kwargs/Return: None """ if not hasattr(self, '_selection'): # first there has to be a click, # so if _selection doesn't exist don't do anything return pos = self.window.canvas.cursor_release self.selection.mv_r(pos) for l in self.lens_patch: l.roi._buffer['circle'].append(self.selection) l.roi._selection = 'circle' l.roi._focus = -1 self.project_patch() self.selection_mode = None del self._selection self.window.canvas._cursor_click.trace_vdelete('w', self.selection_trace[0]) self.window.canvas._cursor_position.trace_vdelete( 'w', self.selection_trace[1]) self.window.canvas._cursor_release.trace_vdelete( 'w', self.selection_trace[2]) def _rect_click(self, *args): """ Start a rectangle during 'click' event Args/Kwargs/Return: None """ idx = self.window.canvas.cursor_index pos = self.window.canvas.cursor_click if not hasattr(self, '_selection'): self.selection = self.lens_patch[idx].roi.Rectangle(pos) for l in self.lens_patch: l.roi._buffer['rect'].append(self.selection) l.roi._selection = 'rect' l.roi._focus = -1 self.project_patch() for l in self.lens_patch: l.roi._buffer['rect'] = l.roi._buffer['rect'][:-1] def _rect_move(self, *args): """ Move rectangle corner (opposite of anchor) during 'motion' event Args/Kwargs/Return: None """ if not hasattr(self, '_selection'): # first there has to be a click, # so if _selection doesn't exist don't do anything return pos = self.window.canvas.cursor_position self.selection.dcorner = pos for l in self.lens_patch: l.roi._buffer['rect'].append(self.selection.close()) l.roi._selection = 'rect' l.roi._focus = -1 self.project_patch() for l in self.lens_patch: l.roi._buffer['rect'] = l.roi._buffer['rect'][:-1] def _rect_release(self, *args): """ Put the rectangle into the ROISelector buffers during the 'release' event Args/Kwargs/Return: None """ if not hasattr(self, '_selection'): # first there has to be a click, # so if _selection doesn't exist don't do anything return pos = self.window.canvas.cursor_release self.selection.dcorner = pos self.selection = self.selection.close() for l in self.lens_patch: l.roi._buffer['rect'].append(self.selection) l.roi._selection = 'rect' l.roi._focus = -1 self.project_patch() self.selection_mode = None del self._selection self.window.canvas._cursor_click.trace_vdelete('w', self.selection_trace[0]) self.window.canvas._cursor_position.trace_vdelete( 'w', self.selection_trace[1]) self.window.canvas._cursor_release.trace_vdelete( 'w', self.selection_trace[2]) def _polygon_click(self, *args): """ Start or add to polygon during 'click' event Args/Kwargs/Return: None """ idx = self.window.canvas.cursor_index pos = self.window.canvas.cursor_click if not hasattr(self, '_selection'): self.selection = self.lens_patch[idx].roi.Polygon() self.selection.add_point(pos) for l in self.lens_patch: l.roi._buffer['polygon'].append(self._selection) l.roi._selection = 'polygon' l.roi._focus = -1 self.project_patch() if not self.selection.is_closed: for l in self.lens_patch: l.roi._buffer['polygon'] = l.roi._buffer['polygon'][:-1] else: self.selection_mode = None del self._selection self.window.canvas._cursor_click.trace_vdelete( 'w', self.selection_trace[0]) def term_shell(self, verbose=False): """ Use as callback during mainloop to exit via command line Args: None Kwargs: verbose <bool> - verbose mode; print command line statements Return: None """ if sys.version_info.major < 3: user_input = raw_input(">> ") else: user_input = input(">>> ") if user_input in ["exit", "exit()", "q", "quit", "quit()"]: if verbose: print("Quitting the app") self.master.quit() else: print("\n APP") print(self.__v__) print("\n MENUBAR") print(self.menubar.__v__) print("\n TOOLBAR") print(self.toolbar.__v__) print("\n STATUSBAR") print(self.statusbar.__v__) print("\n WINDOW") print(self.window.__v__) print("\n CANVAS") print(self.window.canvas.__v__) print("\n LENSPATCH") print(self.lens_patch.__v__) self.after(100, self.term_shell)
if args.config_single: params = {'zl': args.redshifts[0], 'zs': args.redshifts[1]} kwargs = dict(parameter=params, text_file=args.text_file, filter_=args.filter_, reorder=args.reorder, name=args.name, output=args.config_single, verbose=args.verbose) verbose = kwargs.pop('verbose', False) if len(case) > 1: from gleam.multilens import MultiLens fopt = [dict(n=5, sigma=4.5, centroid=2, min_q=0.05)] * len(case) if case.endswith('json'): with open(case) as f: ml = MultiLens.from_json(f) else: ml = MultiLens(case, auto=True, finder_options=fopt) for l in ml: factory = GLSCFactory(lensobject=l, **kwargs) print("".join(factory.config['single'])) # TODO: decide which band to save else: fopt = dict(n=4, sigma=2.0, centroid=2, min_q=0.1, separate_lens=False) kwargs.update({'finder_options': fopt}) factory = GLSCFactory(fits_file=case[0], **kwargs) # For a visual response