Exemplo n.º 1
0
 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())
Exemplo n.º 2
0
 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()
Exemplo n.º 3
0
 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
Exemplo n.º 4
0
 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])
Exemplo n.º 5
0
 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)
Exemplo n.º 6
0
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
Exemplo n.º 7
0
# 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')
Exemplo n.º 8
0
    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__)
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
 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