示例#1
0
class HDInspector(Frame):
    def __init__(self, parent, cmdr, is_beta, client, gridrow):
        "Initialise the ``Patrol``."
        Frame.__init__(self, parent)
        self.client = client
        self.commander = cmdr
        self.is_beta = is_beta
        self.grid(row=gridrow, column=0)
        self.button = Button(
            self,
            text="Click here to scan all your journals for Hyperdictions")
        self.button.bind('<Button-1>', self.run)
        self.button.grid(row=0, column=0)
        Emitter.setRoute(is_beta, client)

    def getUrl(self):
        if self.is_beta:
            url = Emitter.urls.get("staging")
        else:
            url = Emitter.route
        return url

    def excludesystems(self):
        url = self.getUrl()
        if not HDReport.hdsystems:
            debug("getting old hdsystems")
            r = requests.get(
                "{}/{}?cmdrName={}&_sort=created_at:DESC&_limit=100".format(
                    url, "hdreports", self.commander))
            for hd in r.json():
                debug("excluding: {}".format(hd.get("fromSystemName")))
                HDReport.hdsystems[hd.get("fromSystemName")] = hd.get(
                    "fromSystemName")

    def run(self, event):
        self.button.grid_remove()
        HDScanner(self.scan_journals).start()

    def set_beta(self, entry):
        if entry.get("event") == "Fileheader":
            if "beta" in entry.get("gameversion").lower():
                self.is_beta = True
            else:
                self.is_beta = False

    def set_commander(self, entry):
        if entry.get("event") == "Commander":
            self.commander = entry.get("Name")

    def detect_hyperdiction(self, entry):
        if entry.get("event") == "Statistics":
            debug("detected")
            submit(self.commander, self.is_beta, None, None, entry,
                   self.client)
            time.sleep(0.1)
        # else:
        # debug(entry.get("event"))

    def scan_file(self, filename):
        with open(filename) as f:
            for line in f:
                entry = json.loads(line)
                self.set_beta(entry)
                self.set_commander(entry)
                self.detect_hyperdiction(entry)

    def scan_journals(self):
        self.excludesystems()
        config.default_journal_dir
        for filename in glob.glob(
                os.path.join(config.default_journal_dir, 'journal*.log')):
            self.scan_file(filename)
示例#2
0
class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.padx = 3
        self.pady = 3
        self.grid()
        self.results = []
        self.playlists = []
        self.vids = []
        self.__createWidgets()

    def __createWidgets(self):
        self.__searchFields()
        self.__resultArea()
        self.__buttons()
        self.__markdownArea()
        self.bind('<Return>', self.search_button)

    def __buttons(self):
        self.resultSelect = Button(text='OK', state=DISABLED)
        self.resultSelect.grid(row=5, column=4, sticky=E,
                               padx=self.padx, pady=self.pady)
        self.status = Label(text="", bd=1, relief=SUNKEN, anchor=W)
        self.status.grid(row=9, column=0, columnspan=10, sticky=N + E + S + W)
        self.__vidButtons()
        self.__rmVidButtons()
        self.resultSelect.grid_forget()

    def __searchFields(self):
        Label(text="User", anchor=E).grid(row=0, column=0,
                                          padx=self.padx, pady=self.pady,
                                          sticky=W)
        self.user_entry = Entry()
        self.user_entry.grid(row=0, column=1, padx=self.padx, pady=self.pady,
                             sticky=W)
        Label(text="Search terms").grid(row=0, column=3,
                                        padx=self.padx, pady=self.pady,
                                        sticky=W)
        self.search_terms = Entry()
        self.search_terms.grid(row=0, column=4,
                               padx=self.padx, pady=self.pady,
                               sticky=W)
        Label(text="playlist id").grid(row=1, column=3,
                                       padx=self.padx, pady=self.pady,
                                       sticky=W)
        self.playlist_id = Entry()
        self.playlist_id.grid(row=1, column=4, padx=self.padx, pady=self.pady,
                              sticky=W)
        self.search_button = Button(text="Search", command=self.__search)
        self.search_button.grid(row=2, column=4,
                                padx=self.padx, pady=self.pady, sticky=E)

    def __resultArea(self):
        self.result_label = Label(text="Results")
        self.result_label.grid(row=2, column=0,
                               padx=self.padx, pady=self.pady,
                               sticky=W)
        self.resultshowbut = Button(text="View", command=self.__showResults)
        self.resultshowbut.grid(row=2, column=1, sticky=W)
        self.yScroll = Scrollbar(orient=VERTICAL)
        self.xScroll = Scrollbar(orient=HORIZONTAL)
        self.listbox = Listbox(xscrollcommand=self.xScroll.set,
                                yscrollcommand=self.yScroll.set,
                                selectmode=SINGLE)
        self.xScroll.config(command=self.listbox.xview)
        self.yScroll.config(command=self.listbox.yview)

    def __showResults(self):
        self.resultshowbut.config(text="Hide", command=self.__hideResults)
        self.yScroll.grid(row=3, column=5, sticky=N + S)
        self.xScroll.grid(row=4, column=0, sticky=E + W, columnspan=5)
        self.listbox.grid(row=3, column=0, sticky=N + S + E + W, columnspan=5)
        self.markdownarea.config(height=10)

    def __hideResults(self):
        self.resultshowbut.config(text="View", command=self.__showResults)
        self.yScroll.grid_forget()
        self.xScroll.grid_forget()
        self.listbox.grid_forget()
        self.markdownarea.config(height=30)

    def __markdownArea(self):
        self.markdownlabel = Label(text="Markdown")
        self.mdyScroll = Scrollbar(orient=VERTICAL)
        self.mdxScroll = Scrollbar(orient=HORIZONTAL)
        self.markdownarea = Text(wrap=WORD, height=10,
                                 yscrollcommand=self.mdyScroll.set,
                                 xscrollcommand=self.mdxScroll.set)
        self.copymarkdown = Button(text="Copy To Clipboard",
                                  command=self.__copyMarkdown)
        self.mdxScroll.config(command=self.markdownarea.xview)
        self.mdyScroll.config(command=self.markdownarea.yview)

    def __vidButtons(self):
        self.modtitle = Button(text='Modify titles', command=self.__modTitles)
        #self.modtitle.grid(row=5, column=0, sticky=W, columnspan=2,
        #                   padx=self.padx, pady=self.pady)
        self.getcaps = Button(text="Get captions", command=self.__getCaptions)
        self.getcaps.grid(row=5, column=2, columnspan=3, sticky=E,
                          padx=self.padx, pady=self.pady)

    def __rmVidButtons(self):
        self.modtitle.grid_remove()
        self.getcaps.grid_remove()
        self.bind('<Return>', self.search_button)

    def __search(self):
        user = self.user_entry.get()
        playlist = self.playlist_id.get()
        searchterms = self.search_terms.get()
        self.__showResults()
        self.resultSelect.config(state=DISABLED)
        self.__rmVidButtons()
        self.__rmMarkdown()
        if not self.__validparams(user, searchterms, playlist):
            return False

        if len(playlist) > 0:
            self.__searchPlaylist(playlist)
            return

        self.__searchUser(user, searchterms)

    def __showMarkdown(self):
        self.markdownlabel.grid(row=5, column=0,
                                    padx=self.padx, pady=self.pady,
                                    sticky=W)
        self.markdownarea.grid(row=6, column=0, columnspan=5,
                               padx=self.padx, pady=self.pady,
                               sticky=N + S + E + W)
        self.mdyScroll.grid(row=6, column=5, sticky=N + S)
        self.mdxScroll.grid(row=7, column=0, sticky=E + W, columnspan=5)
        self.copymarkdown.grid(row=8, column=2, columnspan=3, sticky=E,
                          padx=self.padx, pady=self.pady)

    def __rmMarkdown(self):
        self.markdownarea.grid_forget()
        self.markdownlabel.grid_forget()
        self.copymarkdown.grid_forget()
        self.mdyScroll.grid_forget()
        self.mdxScroll.grid_forget()

    def __searchPlaylist(self, playlistid):
        self.__getvids(playlistid)

    def __searchUser(self, user, searchterms):
        self.listbox.delete(0, END)
        self.__status("Searching for%splaylists by user \"%s\"" % (
                      " \"%s\" " % searchterms if len(searchterms) else " ",
                      user))
        self.playlists = []
        try:
            self.playlists = lib.yt.search.PlaylistSearch(user=user,
                                                 search=searchterms).query()
        except HTTPError:
            self.__status("User %s does not exist at youtube" % user)
            return
        if self.playlists is None or len(self.playlists) == 0:
            self.__status("Search returned no results")
            return
        self.__populateResults([v['title'] for v in self.playlists])
        self.resultSelect.config(command=self.__getVidsFromSelected,
                                 state=NORMAL)
        self.__status("")
        self.resultSelect.grid(row=5, column=4, sticky=E,
                               padx=self.padx, pady=self.pady)

    def __populateResults(self, values):
        self.listbox.delete(0, END)
        for i, val in enumerate(values):
            self.listbox.insert(i, val)
        self.listbox.activate(0)
        self.listbox.selection_set(0)

    def __getVidsFromSelected(self):
        selected = int(self.listbox.curselection()[0])
        self.__getvids(self.playlists[selected]['id'])

    def __getvids(self, playlistid):
        self.playlist_id.delete(0, END)
        self.playlist_id.insert(0, playlistid)
        self.resultSelect.grid_forget()
        title = playlistid
        if len(self.playlists) > 0:
            for playlist in self.playlists:
                if playlist['id'] == playlistid:
                    title = playlist['title']
                    break

        self.__status("Getting videos for %s" % title)
        self.listbox.delete(0, END)
        try:
            self.vids = lib.yt.search.PlaylistVideoSearch(
                                                    id=playlistid).query()
            self.__populateResults([v['title'] for v in self.vids])
            self.__status("%d Videos found" % len(self.vids))
            self.__vidButtons()
            self.bind('<Return>', self.getcaps)
        except HTTPError:
            self.__status("No videos found! is %s a valid playlist?" %
                          playlistid)

    def __status(self, msg):
        if len(msg) > 75:
            msg = msg[:70] + '...'
        self.status.config(text=msg)
        self.status.update_idletasks()

    def __trackSelect(self, vid, tracks, preftrack=None):
        pref = self.__prefAvailable(preftrack, tracks)
        if pref is None:
            sel = lib.trackSelect.TrackSelect(self, vid=vid,
                                              tracks=tracks)
            if sel.result is None:
                self.__status("skipped")
                tracks = None
            else:
                tracks = [sel.result[0]]
                if sel.preflang is not None:
                    preftrack['lang'] = sel.preflang
                if sel.prefname is not None:
                    preftrack['name'] = sel.prefname
        else:
            tracks = pref
        return tracks, preftrack

    def __getCaptions(self):
        preftrack = {'name': None, 'lang': None}
        self.listbox.delete(0, END)
        self.markdownarea.delete(1.0, END)
        self.__showMarkdown()
        for i, vid in enumerate(self.vids):
            nocapmsg = '[%02d] --NO CAPTIONS-- %s' % (i + 1, vid['title'])
            tracks = lib.yt.search.CaptionSearch(id=vid['id']).query()
            self.vids[i]['text'] = ''
            if len(tracks) == 0:
                self.__status('No captions available for %s' %
                              self.vids[i]['title'])
                self.listbox.insert(END, nocapmsg)

            elif len(tracks) > 1:
                sel = self.__trackSelect(vid, tracks, preftrack)
                if sel[0] is None:
                    msg = '[%02d] --SKIPPED-- %s' % (i + 1, vid['title'])
                    self.listbox.insert(END, msg)
                    self.listbox.see(END)
                    continue
                tracks = sel[0]

            if len(tracks) == 1:
                self.__trackCaps(i, tracks, nocapmsg)
        self.__status('')
        self.__hideResults()

    def __trackCaps(self, vidIndex, tracks, nocapmsg):
        i = vidIndex
        vid = self.vids[i]
        msg = '%02d of %02d Getting captions for %s' % (
                        i + 1, len(self.vids), self.vids[i]['title'])
        self.__status(msg)
        self.listbox.insert(END, msg)
        self.vids[i]['text'] = lib.markdown.heading(vid['title'])
        captions = lib.yt.search.GetCaptions(id=vid['id'],
                                lang=tracks[0]['lang'],
                                name=tracks[0]['name'])
        captions.query()
        captiontext = captions.textOnly()
        sleep(0.2)
        msg = nocapmsg
        if captiontext is not None and len(captiontext) > 0:
            self.vids[i]['text'] += (lib.markdown.to_utf8(captiontext)
                                     + '\n\n')
            msg = '[%02d] --DONE-- %s' % (i + 1, vid['title'])
        self.listbox.delete(END, END)
        self.listbox.insert(END, msg)
        self.listbox.see(END)
        self.markdownarea.insert(END, self.vids[i]['text'])
        self.markdownarea.see(END)

    def __prefAvailable(self, preftrack, tracks):
        if preftrack['lang'] is None:
            return None

        pref = None
        for track in tracks:
            if (track['lang'] == preftrack['lang'] and
                track['name'] == preftrack['name']):
                return [track]
            if track['lang'] == preftrack['lang'] and pref is None:
                pref = [track]

        return pref

    def __modTitles(self):
        pass

    def __validparams(self, user, searchterms, playlist):
        if len(user) == 0 and len(playlist) == 0:
            msg = "Either a valid youtube user or playlist id must be given."
            tkMessageBox.showwarning("missing information", msg)
            return False

        if len(user) > 0 and not self.__validstring(user):
            msg = "The user given contains invalid characters"
            tkMessageBox.showwarning('Bad user', msg)
            return False

        if len(playlist) > 0 and not self.__validstring(playlist):
            msg = "The playlist given contains invalid characters"
            tkMessageBox.showwarning('Bad playlist', msg)
            return False

        if len(searchterms) > 0 and not self.__validstring(searchterms, True):
            msg = "The search terms given contain invalid characters"
            tkMessageBox.showwarning('Bad search', msg)
            return False

        return True

    def __validstring(self, s, spacechar=False):
        validchars = string.letters + string.digits + string.punctuation
        if spacechar:
            validchars += ' '
        for c in s:
            if c not in validchars:
                return False
        return True

    def __copyMarkdown(self):
        self.markdownarea.clipboard_clear()
        self.markdownarea.clipboard_append(self.markdownarea.get(1.0, END))
示例#3
0
文件: gui.py 项目: akiress/idt4243
class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.parent = master

        self.dict = scrapeStart()
        self.initUI()


    def initUI(self):
        """ Build the grid """
        self.grid()
        for r in range(66):
            self.parent.rowconfigure (r, weight = 1)
        for c in range(8):
            self.parent.columnconfigure (c, weight = 1)
        """ Center the window on the display """
        width = 768
        height = 1024

        screenWidth = self.parent.winfo_screenwidth()
        screenHeight = self.parent.winfo_screenheight()

        x = (screenWidth - width) / 2
        y = (screenHeight - height) / 2

        self.parent.geometry('%dx%d+%d+%d' % (width, height, x, y))
        self.parent.configure(bg = "grey10")

        status = "home"
        self.drawScreen(status)


    def drawScreen(self, status):
        print ("%s is the status" % status)

        if (status == "home"):
            self.drawHome()
        elif (status == "film"):
            self.drawFilm()
        elif (status == "recipes"):

            self.drawRecipes()
        else:
            print('Bad mojo')


    def drawHome(self):
        infoText = ("Some Louisiana urban environments have a multicultural, multilingual heritage, being so strongly "
            "by an admixture of 18th century French, Spanish, Native American (Indian), and African cultures that they "
            "are considered to be somewhat exceptional in the U.S. Before the American influx and statehood at the "
            "beginning of the 19th century, the territory of current Louisiana State had been both a Spanish and "
            "French colony. In addition, the pattern of development included importing numerous African slaves in "
            "the 18th century, with many from the same region of West Africa, thus concentrating their culture.")

        self.img = ImageTk.PhotoImage(Image.open("louisiana.png"))

        self.title = Label(self.parent, width = 1, height = 1, text = "Louisiana", fg = "white", bg = "grey30",
                        font = ("Times 48 italic"), bd = 5, relief = RAISED)
        self.title.grid(row = 1, column = 2, rowspan = 10, columnspan = 4, sticky = W+E+N+S)

        self.info = Label(self.parent, width = 1, height = 1, text = infoText, fg = "white", bg = "grey30",
                        font = ("Times 14"), bd = 5, relief = RAISED, wraplength = 350, justify = LEFT)
        self.info.grid(row = 23, column = 4, rowspan = 24, columnspan = 4, sticky = W+E+N+S)

        self.image1 = Label(self.parent, width = 1, height = 1, image = self.img, bg = "grey10")
        self.image1.grid(row = 23, column = 0, rowspan = 24, columnspan = 4, sticky = W+E+N+S)

        self.Button1 = Button(self.parent, text = "Film", command = lambda: self.drawScreen("film"))
        self.Button1.grid(row = 61, column = 1, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button2 = Button(self.parent, text = "Recipes", command = lambda: self.drawScreen("recipes"))
        self.Button2.grid(row = 61, column = 5, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button3 = Button()
        self.Button3.grid_remove()
        self.Button4 = Button()
        self.Button4.grid_remove()
        self.Button5 = Button()
        self.Button5.grid_remove()
        self.listbox = Listbox()
        self.listbox.grid_remove()
        self.image2 = Label()
        self.image2.grid_remove()


    def drawFilm(self):
        self.title = Label(self.parent, text = "Film", fg="white", bg="grey30", font=("Times 48 italic"),
                        bd = 5, relief = RAISED)
        self.title.grid(row = 1, column = 2, rowspan = 10, columnspan = 4, sticky = W+E+N+S)

        self.Button1 = Button(self.parent, text = "Recipes", command = lambda: self.drawScreen("recipes"))
        self.Button1.grid(row = 61, column = 1, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button2 = Button(self.parent, text = "Home", command = lambda: self.drawScreen("home"))
        self.Button2.grid(row = 61, column = 5, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.info.grid_remove()
        self.image1.grid_remove()
        self.image2.grid_remove()
        self.Button3.grid_remove()
        self.Button4.grid_remove()
        self.Button5.grid_remove()
        self.listbox.grid_remove()


    def drawRecipes(self):
        self.title = Label(self.parent, text = "Recipes", fg="white", bg="grey30", font=("Times 48 italic"),
                        bd = 5, relief = RAISED)
        self.title.grid(row = 1, column = 2, rowspan = 10, columnspan = 4, sticky = W+E+N+S)

        self.Button1 = Button(self.parent, text = "Film", command = lambda: self.drawScreen("film"))
        self.Button1.grid(row = 61, column = 1, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button2 = Button(self.parent, text = "Home", command = lambda: self.drawScreen("home"))
        self.Button2.grid(row = 61, column = 5, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button3 = Button(self.parent, text = "Gumbo", command = self.drawRecipeList)
        self.Button3.grid(row = 24, column = 3, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button4 = Button(self.parent, text = "Jambalaya", command = self.quit)
        self.Button4.grid(row = 29, column = 3, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button5= Button(self.parent, text = "Seafood", command = self.quit)
        self.Button5.grid(row = 34, column = 3, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.info.grid_remove()
        self.image1.grid_remove()
        self.listbox.grid_remove()
        self.image2.grid_remove()


    def drawRecipeList(self):
        self.Button3.grid_remove()
        self.Button4.grid_remove()
        self.Button5.grid_remove()
        self.image2.grid_remove()

        self.Button1 = Button(self.parent, text = "Film", command = lambda: self.drawScreen("film"))
        self.Button1.grid(row = 61, column = 1, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button2 = Button(self.parent, text = "Home", command = lambda: self.drawScreen("home"))
        self.Button2.grid(row = 61, column = 5, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.listbox = Listbox(self.parent)
        for key in self.dict:
            index = 1
            self.listbox.insert(index, key)
            index += 1
        self.listbox.grid(row = 29, column = 1, rowspan = 12, columnspan = 6, sticky = W+E+N+S)
        self.listbox.bind("<<ListboxSelect>>", self.get_List)


    def get_List(self, *args):
        self.info.grid_remove()
        self.image1.grid_remove()
        self.image2.grid_remove()
        self.Button3.grid_remove()
        self.Button4.grid_remove()
        self.Button5.grid_remove()
        self.listbox.grid_remove()

        self.index = self.listbox.curselection()

        self.Button1 = Button(self.parent, text = "Film", command = lambda: self.drawScreen("film"))
        self.Button1.grid(row = 61, column = 1, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.Button2 = Button(self.parent, text = "Home", command = lambda: self.drawScreen("home"))
        self.Button2.grid(row = 61, column = 5, rowspan = 3, columnspan = 2, sticky = W+E+N+S)

        self.img2 = ImageTk.PhotoImage(Image.open("creole_gumbo.png"))
        self.image2 = Label(self.parent, width = 1, height = 1, image = self.img2, bg = "grey10")
        self.image2.grid(row = 21, column = 1, rowspan = 34, columnspan = 6, sticky = W+E+N+S)
示例#4
0
class CoreGUI(object):
    def __init__(self, parent, doc_dir):
        self.doc_dir = doc_dir
        self.parent = parent
        self.InitUI()
        self.show_poss_vals = False
        self.show_forced_vals = False
        self.use_SD = False
        self.out = StdoutRedirector(self.text_box)
        sys.stdout = self.out

    def main(self):
        '''
        The body of the execution.  It is split up so that the GUI freezes as little as possible, but it will still
        freeze during several portions (some potentially quite long)
        :return:
        '''
        self.start_button.config(text='Running...')
        self.start_button.config(command=None)
        self.graph_button.grid_remove()
        self.start_button.grid_remove()
        self.start_button.grid(row=15, columnspan=3, column=0)
        debug = bool(self.debug.get())
        if debug:
            print "Starting Data Recreation..."
        var = eval(
            compile(self.variance.get(), '<string>', 'eval',
                    __future__.division.compiler_flag))
        var_precision = abs(
            eval(
                compile(self.variance_precision.get(), '<string>', 'eval',
                        __future__.division.compiler_flag)))
        if self.use_SD:
            min_var = max(0, (var - var_precision))**2
            max_var = (var + var_precision)**2
            var = (min_var + max_var) / 2
            var_precision = (max_var - min_var) / 2

        self.rd = RecreateData(self.min_score.get(),
                               self.max_score.get(),
                               self.num_subjects.get(),
                               eval(
                                   compile(self.mean.get(), '<string>', 'eval',
                                           __future__.division.compiler_flag)),
                               var,
                               debug=debug,
                               mean_precision=eval(
                                   compile(self.mean_precision.get(),
                                           '<string>', 'eval',
                                           __future__.division.compiler_flag)),
                               variance_precision=var_precision)
        # self.rd.recreateData(check_val=self.getForcedVals(), poss_vals=self.poss_vals.getPossVals(),
        #                             multiprocess=True, find_first=(not bool(self.find_all.get())))
        self.parent.after(5, self.main_2)

    def main_2(self):
        debug = bool(self.debug.get())
        mean_var_pairs = self.rd._recreateData_piece_1(
            check_val=self.getForcedVals(),
            poss_vals=self.poss_vals.getPossVals(),
            multiprocess=True,
            find_first=(bool(self.find_first.get())))
        partial_3 = wrapped_partial(self.main_3, mean_var_pairs)
        self.parent.after(5, partial_3)

    def main_3(self, mean_var_pairs):
        debug = bool(self.debug.get())
        solution_spaces = self.rd._recreateData_piece_2(
            mean_var_pairs,
            check_val=self.getForcedVals(),
            poss_vals=self.poss_vals.getPossVals(),
            multiprocess=True,
            find_first=(bool(self.find_first.get())))
        partial_4 = wrapped_partial(self.main_4, solution_spaces)
        self.parent.after(5, partial_4)

    def main_4(self, solution_spaces):
        debug = bool(self.debug.get())
        if (bool(self.find_first.get())):
            self.rd._findFirst_piece_1(solution_spaces,
                                       check_val=self.getForcedVals(),
                                       poss_vals=self.poss_vals.getPossVals(),
                                       multiprocess=True,
                                       find_first=(bool(
                                           self.find_first.get())))
            self.parent.after(5, self.main_6)
        else:
            init_bases, init_base_vecs, param_tuples = self.rd._findAll_piece_1_multi_proc(
                solution_spaces,
                check_val=self.getForcedVals(),
                poss_vals=self.poss_vals.getPossVals(),
                multiprocess=True,
                find_first=(bool(self.find_first.get())))
            partial_5 = wrapped_partial(self.main_5, init_bases,
                                        init_base_vecs, param_tuples)
            self.parent.after(5, partial_5)

    def main_5(self, init_bases, init_base_vecs, param_tuples):
        debug = bool(self.debug.get())
        self.rd._findAll_piece_2_multi_proc(
            init_bases,
            init_base_vecs,
            param_tuples,
            check_val=self.getForcedVals(),
            poss_vals=self.poss_vals.getPossVals(),
            multiprocess=True,
            find_first=(bool(self.find_first.get())))
        self.parent.after(5, self.main_6)

    def main_6(self):
        debug = bool(self.debug.get())
        self.start_button.config(text='Start')
        self.start_button.config(command=self.main)
        self.graph_button.grid()
        self.start_button.grid_remove()
        self.start_button.grid(row=15, columnspan=1, column=0)
        if len(self.rd.sols) > 0:
            self.rd.getDataSimple()
            if debug:
                print str(
                    sum([len(x) for x in self.rd.simpleData.itervalues()
                         ])) + " unique solutions found."
                index = 0
                for params in self.rd.simpleData:
                    if index > 100:
                        break
                    print "At mean, variance", params, ":"
                    for simpleSol in self.rd.simpleData[params]:
                        if index > 100:
                            break
                        index += 1
                        print simpleSol
        else:
            if debug:
                print str(len(
                    self.rd.getDataSimple())) + " unique solutions found."

    def graph(self):
        self.rd.graphData()

    def _showOrHidePossVals(self):
        self.show_poss_vals = not self.show_poss_vals
        if self.show_poss_vals:
            self.poss_vals.grid()
        else:
            self.poss_vals.grid_remove()

    def _showOrHideForcedVals(self):
        self.show_forced_vals = not self.show_forced_vals
        if self.show_forced_vals:
            self.forced_vals.grid()
        else:
            self.forced_vals.grid_remove()

    def _switch_SD_Var(self):
        self.use_SD = not self.use_SD
        if self.use_SD:
            self.SD_Button.config(text='Switch to Variance Instead of SD')
            self.variance_label.config(text='Standard Deviation')
            self.variance.set(0.0)
            self.variance_precision_label.config(text='SD Precision')
            self.variance_precision.set(0.0)
        else:
            self.SD_Button.config(text='Switch to SD Instead of Variance')
            self.variance_label.config(text='Variance')
            self.variance.set(0.0)
            self.variance_precision_label.config(text='Variance Precision')
            self.variance_precision.set(0.0)

    def getForcedVals(self):
        current_forced = re.split('[,\s]+',
                                  self.forced_vals.get("1.0", "end-1c"))
        forced_vals = [
            int(math.floor(eval(forced))) for forced in current_forced
            if len(forced) and
            (forced == '0' or (forced if forced.find('..') > -1 else forced.
                               lstrip('-+').rstrip('0').rstrip('.')).isdigit())
            and math.floor(eval(forced)) == eval(forced)
        ]
        forced_vals.sort()
        return forced_vals

    def clearInputFields(self):
        self.variance.set(0.0)
        self.mean.set(0.0)
        self.min_score.set(0)
        self.max_score.set(0)
        self.variance_precision.set(0.0)
        self.mean_precision.set(0.0)
        self.num_subjects.set(0)

    def clearOutputField(self):
        self.text_box.delete('1.0', END)

    def clearAll(self):
        self.clearInputFields()
        self.clearOutputField()

    def InitUI(self):

        from PIL import Image
        from PIL import ImageTk

        self.parent.lift()
        # image = Image.open("Corvid.png")
        # help_image = Image.open("Question.png")
        # photo = ImageTk.PhotoImage(image)
        # help_photo = ImageTk.PhotoImage(help_image)
        # img = PhotoImage(file="Corvid.png")
        # self.parent.tk.call('wm', 'iconphoto', self.parent._w, photo)
        self.parent.wm_title(string="CORVIDS")

        self.window = MenuItems(self.parent)
        self.window.addMenu("clearMenu", "Clear")
        self.window.addTopLevelMenuItem(self.window.fileMenu,
                                        "Load Settings",
                                        self.myLoadFunc(self.window),
                                        hotKey="<Control-o>")
        self.window.addTopLevelMenuItem(self.window.fileMenu,
                                        "Save Settings",
                                        self.mySaveFunc(self.window),
                                        hotKey="<Control-s>")
        self.window.addTopLevelMenuItem(self.window.fileMenu,
                                        "Load Model",
                                        self.myLoadModelFunc(self.window),
                                        hotKey="<Control-m>")
        self.window.addTopLevelMenuItem(self.window.fileMenu,
                                        "Save Model",
                                        self.mySaveModelFunc(self.window),
                                        hotKey="<Control-M>")
        self.window.addTopLevelMenuItem(self.window.fileMenu,
                                        "Save Data",
                                        self.mySaveDataFunc(self.window),
                                        hotKey="<Control-d>")
        self.window.addTopLevelMenuItem(self.window.clearMenu,
                                        "Clear Input Fields",
                                        self.clearInputFields)
        self.window.addTopLevelMenuItem(self.window.clearMenu,
                                        "Clear Output Field",
                                        self.clearOutputField)
        self.window.addTopLevelMenuItem(self.window.clearMenu, "Clear All",
                                        self.clearAll)

        self.window.addQuit()

        description_col = 0
        field_col = 2
        help_col = 1

        self.debug = IntVar()
        self.debug.set(1)
        Checkbutton(self.parent, text="Show Progress",
                    variable=self.debug).grid(column=description_col,
                                              row=0,
                                              sticky=W)
        self.find_first = IntVar()
        self.find_first.set(0)
        Checkbutton(self.parent,
                    text="Stop After First Solution",
                    variable=self.find_first).grid(column=field_col,
                                                   row=0,
                                                   sticky=E)

        Label(self.parent, text="Minimum Value",
              anchor='e').grid(row=1,
                               column=description_col,
                               sticky=N + S + E + W)
        self.min_score = IntVar()
        self.min_entry = Entry(self.parent, textvariable=self.min_score)
        self.min_entry.grid(row=1, column=field_col, sticky=E + W, padx=15)
        min_value_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "minimum-value",
                self.doc_dir))  #width=14, height=14)#, text="?")
        # min_value_help.config(image=help_photo)
        # min_value_help.image = help_photo
        min_value_help.grid(row=1, column=help_col, sticky=E + W)

        Label(self.parent, text="Maximum Value",
              anchor='e').grid(row=2,
                               column=description_col,
                               sticky=N + S + E + W)
        self.max_score = IntVar()
        self.max_entry = Entry(self.parent, textvariable=self.max_score)
        self.max_entry.grid(row=2, column=field_col, sticky=E + W, padx=15)
        max_value_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "maximum-value",
                self.doc_dir))  #width=14, height=14)#, text="?")
        # max_value_help.config(image=help_photo)
        # max_value_help.image = help_photo
        max_value_help.grid(row=2, column=help_col, sticky=E + W)

        Label(self.parent, text="Mean",
              anchor='e').grid(row=3,
                               column=description_col,
                               sticky=N + S + E + W)
        self.mean = StringVar()
        self.mean.set(0.0)
        self.mean_entry = Entry(self.parent, textvariable=self.mean)
        self.mean_entry.grid(row=3, column=field_col, sticky=E + W, padx=15)
        mean_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "mean", self.doc_dir))  #width=14, height=14)#, text="?")
        # mean_help.config(image=help_photo)
        # mean_help.image = help_photo
        mean_help.grid(row=3, column=help_col, sticky=E + W)

        Label(self.parent, text="Mean Precision",
              anchor='e').grid(row=4,
                               column=description_col,
                               sticky=N + S + E + W)
        self.mean_precision = StringVar()
        self.mean_precision.set(0.0)
        self.mean_precision_entry = Entry(self.parent,
                                          textvariable=self.mean_precision)
        self.mean_precision_entry.grid(row=4,
                                       column=field_col,
                                       sticky=E + W,
                                       padx=15)
        mean_precision_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "mean-precision",
                self.doc_dir))  #width=14, height=14)#, text="?")
        # mean_precision_help.config(image=help_photo)
        # mean_precision_help.image = help_photo
        mean_precision_help.grid(row=4, column=help_col, sticky=E + W)

        self.SD_Button = Button(self.parent,
                                text="Switch to SD Instead of Variance",
                                command=self._switch_SD_Var)
        self.SD_Button.grid(row=5,
                            columnspan=3,
                            column=description_col,
                            sticky=E + W)

        self.variance_label = Label(self.parent, text="Variance", anchor='e')
        self.variance_label.grid(row=6,
                                 column=description_col,
                                 sticky=N + S + E + W)
        self.variance = StringVar()
        self.variance.set(0.0)
        self.variance_entry = Entry(self.parent, textvariable=self.variance)
        self.variance_entry.grid(row=6,
                                 column=field_col,
                                 sticky=E + W,
                                 padx=15)
        variance_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "variance", self.doc_dir))  #width=14, height=14)#, text="?")
        # variance_help.config(image=help_photo)
        # variance_help.image = help_photo
        variance_help.grid(row=6, column=help_col, sticky=E + W)

        self.variance_precision_label = Label(self.parent,
                                              text="Variance Precision",
                                              anchor='e')
        self.variance_precision_label.grid(row=7,
                                           column=description_col,
                                           sticky=N + S + E + W)
        self.variance_precision = StringVar()
        self.variance_precision.set(0.0)
        self.variance_precision_entry = Entry(
            self.parent, textvariable=self.variance_precision)
        self.variance_precision_entry.grid(row=7,
                                           column=field_col,
                                           sticky=E + W,
                                           padx=15)
        variance_precision_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "variance-precision",
                self.doc_dir))  #width=14, height=14)#, text="?")
        # variance_precision_help.config(image=help_photo)
        # variance_precision_help.image = help_photo
        variance_precision_help.grid(row=7, column=help_col, sticky=E + W)

        Label(self.parent, text="Number of Subjects",
              anchor='e').grid(row=8,
                               column=description_col,
                               sticky=N + S + E + W)
        self.num_subjects = IntVar()
        self.num_subjects_entry = Entry(self.parent,
                                        textvariable=self.num_subjects)
        self.num_subjects_entry.grid(row=8,
                                     column=field_col,
                                     sticky=E + W,
                                     padx=15)
        num_subjects_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "number-of-subjects",
                self.doc_dir))  #width=14, height=14)#, text="?")
        # num_subjects_help.config(image=help_photo)
        # num_subjects_help.image = help_photo
        num_subjects_help.grid(row=8, column=help_col, sticky=E + W)

        Label(self.parent, text="Possible Values",
              anchor='e').grid(row=9,
                               column=description_col,
                               sticky=N + S + E + W)
        # Button(self.parent, text="Possible Values", command=self._showOrHidePossVals).grid(row=8, columnspan=2, column=description_col, sticky=E+W)
        Button(self.parent, text="Show/Hide",
               command=self._showOrHidePossVals).grid(row=9,
                                                      column=field_col,
                                                      sticky=E + W,
                                                      padx=15)
        self.poss_vals = PossValsText(self.parent,
                                      min_value=self.min_score,
                                      max_value=self.max_score,
                                      wrap='word',
                                      height=11,
                                      width=50)
        self.poss_vals.grid(row=10,
                            columnspan=3,
                            column=description_col,
                            sticky=N + S + E + W)
        self.poss_vals.grid_remove()
        # poss_vals_frame = Frame(self.parent, height=10, width=10)
        # poss_vals_frame.grid(row=10, column=help_col, sticky=E+W)
        # poss_vals_help = Button(poss_vals_frame, text="?", font=('TkDefaultFont', 8)) #width=14, height=16)#, text="?")
        # poss_vals_help.pack()
        poss_vals_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "possible-values",
                self.doc_dir))  #width=14, height=16)#, text="?")
        # poss_vals_help.config(image=help_photo)
        # poss_vals_help.image = help_photo
        poss_vals_help.grid(row=9, column=help_col, sticky=E + W)

        Label(self.parent, text="Forced Values",
              anchor='e').grid(row=11,
                               column=description_col,
                               sticky=N + S + E + W)
        Button(self.parent,
               text="Show/Hide",
               command=self._showOrHideForcedVals).grid(row=11,
                                                        column=field_col,
                                                        sticky=E + W,
                                                        padx=15)
        # Button(self.parent, text="Forced Values", command=self._showOrHideForcedVals).grid(row=10, columnspan=2, column=description_col, sticky=E+W)
        self.forced_vals = Text(self.parent, wrap='word', height=12, width=50)
        self.forced_vals.grid(row=12,
                              columnspan=3,
                              column=description_col,
                              sticky=N + S + E + W)
        self.forced_vals.grid_remove()
        # forced_vals_frame = Frame(self.parent, height=10, width=10)
        # forced_vals_frame.grid(row=10, column=help_col, sticky=E+W)
        forced_vals_help = Button(
            self.parent,
            text="?",
            font=('TkDefaultFont', 8),
            command=doc_call_wrapper(
                "forced-values",
                self.doc_dir))  #width=14, height=16)#, text="?")
        # forced_vals_help.config(image=help_photo)
        # forced_vals_help.image = help_photo
        forced_vals_help.grid(row=11, column=help_col, sticky=E + W)

        Label(self.parent, text="Output:").grid(row=13,
                                                columnspan=3,
                                                column=description_col,
                                                sticky=E + W)
        # self.outputFrame = tk.Frame(self.parent)
        self.parent.columnconfigure(0, weight=1)
        self.parent.rowconfigure(14, weight=1)
        self.text_box = Text(self.parent, wrap='word', height=11, width=50)
        self.text_box.grid(row=14,
                           columnspan=3,
                           column=0,
                           sticky=N + S + E + W)

        self.start_button = Button(self.parent,
                                   text="Start",
                                   command=self.main)
        self.start_button.grid(row=15, columnspan=3, column=0)

        self.graph_button = Button(self.parent,
                                   text="Graph",
                                   command=self.graph)
        self.graph_button.grid(row=15, column=field_col)
        self.graph_button.grid_remove()

    def setSettings(self, settings_file_full_path):
        '''
        Takes a path and a filename and sets the simulation to that, informing the user that it has been loaded.
        :param settings_file_full_path: from root directory to filename and extension
        :return:
        '''
        if self.debug.get():
            print "Loading settings from " + settings_file_full_path
        self.settings_file = settings_file_full_path
        input_file = open(self.settings_file, 'rb')
        settings = cPickle.load(input_file)
        assert isinstance(settings, RecreateDataGUISettings)
        input_file.close()
        self.debug.set(settings.debug)
        self.min_score.set(settings.min_score)
        self.max_score.set(settings.max_score)
        self.poss_vals.delete("1.0", "end")
        self.poss_vals.insert("1.0", settings.poss_vals)
        self.mean.set(settings.mean)
        self.mean_precision.set(settings.mean_precision)
        if self.use_SD != settings.use_SD:
            self._switch_SD_Var()
        self.variance.set(settings.variance)
        self.variance_precision.set(settings.variance_precision)
        self.num_subjects.set(settings.num_samples)
        self.forced_vals.delete("1.0", "end")
        self.forced_vals.insert("1.0", settings.check_vals)

    def saveSettings(self, settings_file_full_path):
        if self.debug.get():
            print "Saving settings to " + settings_file_full_path
        self.settings_file = settings_file_full_path
        settings_save_file = open(self.settings_file, 'wb')
        settings = RecreateDataGUISettings(
            self.debug.get(), self.min_score.get(), self.max_score.get(),
            self.poss_vals.get("1.0", "end-1c"), self.mean.get(),
            self.mean_precision.get(), self.variance.get(),
            self.variance_precision.get(), self.num_subjects.get(),
            self.forced_vals.get("1.0", "end-1c"), self.use_SD)
        cPickle.dump(settings, settings_save_file)
        settings_save_file.close()

    def saveModel(self, model_file_full_path):
        if self.debug.get():
            print "Saving model to " + model_file_full_path
        self.model_file = model_file_full_path
        model_save_file = open(self.model_file, 'wb')
        cPickle.dump(self.rd, model_save_file)
        model_save_file.close()

    def loadModel(self, model_file_full_path):
        if self.debug.get():
            print "Loading model from " + model_file_full_path

        self.model_file = model_file_full_path
        model_read_file = open(self.model_file, 'rb')
        self.rd = cPickle.load(model_read_file)
        assert isinstance(self.rd, RecreateData)
        model_read_file.close()
        self.graph_button.grid()
        self.start_button.grid_remove()
        self.start_button.grid(row=14, columnspan=1, column=0)

    def saveData(self, data_file_full_path):
        if self.debug.get():
            print "Saving data to " + data_file_full_path
        self.data_file = data_file_full_path
        data_save_file = open(self.data_file, 'wb')
        if len(self.rd.sols) == 0:
            data_save_file.close()
            return
        dataStr = ""
        for param, solutions in self.rd.simpleData.iteritems():
            dataStr += str(param) + ":\n"
            for sol in solutions:
                dataStr += "\t" + str(sol) + "\n"
        data_save_file.write(dataStr.strip())
        data_save_file.close()

    def myLoadFunc_lambda(self, environment):
        lambda_new_window("openerWindow", environment, "Load Settings")
        lambda_make_file_loader(environment, "openerWindow", "opener",
                                self.setSettings)

    def myLoadFunc(self, environment):
        return lambda environment=environment: self.myLoadFunc_lambda(
            environment)

    def mySaveFunc_lambda(self, environment):
        lambda_new_window("openerWindow", environment, "Save Settings")
        lambda_make_file_saver(environment, "openerWindow", "opener",
                               self.saveSettings)

    def mySaveFunc(self, environment):
        return lambda environment=environment: self.mySaveFunc_lambda(
            environment)

    def mySaveDataFunc_lambda(self, environment):
        lambda_new_window("openerWindow", environment, "Save Data")
        lambda_make_file_saver(environment, "openerWindow", "opener",
                               self.saveData)

    def mySaveDataFunc(self, environment):
        return lambda environment=environment: self.mySaveDataFunc_lambda(
            environment)

    def mySaveModelFunc_lambda(self, environment):
        lambda_new_window("openerWindow", environment, "Save Model")
        lambda_make_file_saver(environment, "openerWindow", "opener",
                               self.saveModel)

    def mySaveModelFunc(self, environment):
        return lambda environment=environment: self.mySaveModelFunc_lambda(
            environment)

    def myLoadModelFunc_lambda(self, environment):
        lambda_new_window("openerWindow", environment, "Load Model")
        lambda_make_file_loader(environment, "openerWindow", "opener",
                                self.loadModel)

    def myLoadModelFunc(self, environment):
        return lambda environment=environment: self.myLoadModelFunc_lambda(
            environment)
示例#5
0
class SkyglowEstimationToolbox:
    """Main class that establishes GUI."""
    def __init__(self, root):
        self.root = root

        # Radio action buttons
        self.action = None
        self.sgmap_single_btn, self.krn_lib_btn, self.multi_map_btn = None, None, None

        self.file_log_var = StringVar()
        self.csv_file_var = StringVar()
        self.krn_folder_var = StringVar()
        self.output_folder_var = StringVar()
        self.sgmap_folder_var = StringVar()

        self.krn_ent_var = StringVar()
        self.krn_var, self.hem_var = IntVar(), IntVar()
        self.img, self.cdiag = None, None
        self.lat_lbl, self.lat_entry = None, None
        self.k_lbl, self.k_entry = None, None
        self.zen_lbl, self.zen_entry = None, None
        self.azi_lbl, self.azi_entry = None, None
        self.krn_lvl, self.krn_entry, self.krn_btn = None, None, None
        self.txt_redir, self.prg_log = None, None
        self.map_btn, self.gen_krn_btn = None, None

        # Sets window title, size, and icon on screen.
        self.root.title("Skyglow Estimation Toolbox (SET)")
        self.root.geometry('%dx%d+%d+%d' %
                           (constants.SW * 0.75, constants.SH * 0.75, 25, 25))
        self.root.iconbitmap(os.path.join(os.getcwd(), constants.ICO))
        self.root.resizable(False, False)
        self.root.update_idletasks()

        # Creates three paned windows for the main screen.
        base = PanedWindow()
        base.pack(fill=BOTH, expand=1)
        sub1 = PanedWindow(base,
                           orient=VERTICAL,
                           height=self.root.winfo_height() * 3 / 4)
        base.add(sub1)
        sub2 = PanedWindow(sub1,
                           orient=HORIZONTAL,
                           height=self.root.winfo_height() / 5)
        sub1.add(sub2)

        # Creates frame for holding inputs.
        self.input_frame = Frame(sub2)
        sub2.add(self.input_frame)

        # Creates frame for bottom half of main screen.
        self.img_frame = Frame(sub1, bd=2, bg='white', relief="sunken")
        sub1.add(self.img_frame)

        # Creates canvas for displaying images.
        self.img_canvas = Canvas(self.img_frame,
                                 bd=2,
                                 relief="groove",
                                 width=constants.SW * 0.6,
                                 height=self.root.winfo_height() * 3 / 4 * 0.9)
        self.img_canvas.place(relx=.5, rely=.5, anchor=CENTER)

        # Creates help button for link to documentation, instructions, and about.
        self.help_btn = Menubutton(self.input_frame,
                                   text="Help",
                                   relief="raised",
                                   bd=2,
                                   width=8,
                                   pady=1)
        #self.help_btn.place(relx=1, rely=0, anchor=NE)
        self.help_btn.grid(column=4, columnspan=1, row=0)
        self.help_btn_menu = Menu(self.help_btn, tearoff=0)
        doc = 'https://github.com/NASA-DEVELOP'
        self.help_btn_menu.add_command(label="Documentation",
                                       command=lambda: self.open_url(doc))
        self.help_btn_menu.add_command(label="Instructions",
                                       command=self.instructions)
        self.help_btn_menu.add_separator()
        self.help_btn_menu.add_command(label="About", command=self.about)
        self.help_btn["menu"] = self.help_btn_menu

    def main_screen(self):
        """Set up input GUI and image display screen."""
        self.action = IntVar()

        btn_width = int(constants.SW / 60)
        file_width = int(constants.SW / 18)
        lbl_width = int(constants.SW / 60)
        gen_width = int(constants.SW / 42)
        radio_font = Font(family='TkDefaultFont', size=12)
        self.sgmap_single_btn = Radiobutton(
            self.input_frame,
            text="Generate Artificial Skyglow Map",
            font=radio_font,
            width=btn_width,
            variable=self.action,
            value='sng',
            command=self.sng_popup)
        self.krn_lib_btn = Radiobutton(self.input_frame,
                                       text="Generate Kernel Library",
                                       font=radio_font,
                                       width=btn_width,
                                       variable=self.action,
                                       value='krn',
                                       command=self.krn_popup)
        self.multi_map_btn = Radiobutton(
            self.input_frame,
            text="Generate Maps from Multiple Kernels",
            font=radio_font,
            width=btn_width,
            variable=self.action,
            value='mul',
            command=self.mul_popup)
        self.hem_map_btn = Radiobutton(
            self.input_frame,
            text="Generate Hemispherical Visualization",
            font=radio_font,
            width=btn_width,
            variable=self.action,
            value='hem',
            command=self.hem_popup)
        #Place widget
        self.sgmap_single_btn.grid(column=0, columnspan=1, row=0)
        self.krn_lib_btn.grid(column=1, columnspan=1, row=0)
        self.multi_map_btn.grid(column=2, columnspan=1, row=0)
        self.hem_map_btn.grid(column=3, columnspan=1, row=0)

        # VIIRS Image Reference File
        self.file_lbl = Label(self.input_frame,
                              text="Image File:",
                              width=lbl_width,
                              anchor=E)
        self.file_log = Entry(self.input_frame,
                              width=file_width,
                              bd=2,
                              relief="sunken",
                              textvariable=self.file_log_var)
        self.browse_btn = Button(self.input_frame,
                                 text="Browse",
                                 command=self.import_viirs)

        # Angles CSV File
        self.csv_file_lbl = Label(self.input_frame,
                                  text="Angles CSV File:",
                                  width=lbl_width,
                                  anchor=E)
        self.csv_file_log = Entry(self.input_frame,
                                  width=file_width,
                                  bd=2,
                                  relief="sunken",
                                  textvariable=self.csv_file_var)
        self.csv_browse_btn = Button(self.input_frame,
                                     text="Browse",
                                     command=self.import_csv)

        # Multiple Maps form Kernel library
        self.mul_file_lbl = Label(self.input_frame,
                                  text="Kernel Folder:",
                                  width=lbl_width,
                                  anchor=E)
        self.mul_file_log = Entry(self.input_frame,
                                  width=file_width,
                                  bd=2,
                                  relief="sunken",
                                  textvariable=self.krn_folder_var)
        self.mul_browse_btn = Button(self.input_frame,
                                     text="Browse",
                                     command=self.import_krn_folder)

        # MultiKrn Map Output Location
        self.output_lbl = Label(self.input_frame,
                                text="Output Location:",
                                width=lbl_width,
                                anchor=E)
        self.output_log = Entry(self.input_frame,
                                width=file_width,
                                bd=2,
                                relief="sunken",
                                textvariable=self.output_folder_var)
        self.output_btn = Button(self.input_frame,
                                 text="Browse",
                                 command=self.import_out_folder)

        # Hemisphere Output Location
        self.sgmap_folder_lbl = Label(self.input_frame,
                                      text="Skyglow Map Location:",
                                      width=lbl_width,
                                      anchor=E)
        self.sgmap_folder_log = Entry(self.input_frame,
                                      width=file_width,
                                      bd=2,
                                      relief="sunken",
                                      textvariable=self.sgmap_folder_var)
        self.sgmap_folder_btn = Button(self.input_frame,
                                       text="Browse",
                                       command=self.import_sgmap_folder)

        # Import Kernel Checkbutton
        self.check_lbl = Label(self.input_frame,
                               text="Import Kernel:",
                               width=lbl_width,
                               anchor=E)

        self.krn_chk = Checkbutton(self.input_frame,
                                   anchor=W,
                                   variable=self.krn_var,
                                   command=self.checkbtn_val)

        self.hem_chk_lbl = Label(self.input_frame,
                                 text="Generate kernels for hemisphere:",
                                 width=lbl_width,
                                 anchor=E)

        self.hem_chk = Checkbutton(self.input_frame,
                                   anchor=W,
                                   variable=self.hem_var)

        # Region Latitude (deg), Grand Teton National park = 43.7904 degrees N
        self.lat_lbl = Label(self.input_frame,
                             text="Latitude (deg):",
                             width=lbl_width,
                             anchor=E)
        self.lat_entry = Entry(self.input_frame,
                               width=btn_width,
                               bd=2,
                               relief="sunken")
        self.lon_lbl = Label(self.input_frame,
                             text="Longitude (deg):",
                             width=lbl_width,
                             anchor=E)
        self.lon_entry = Entry(self.input_frame,
                               width=btn_width,
                               bd=2,
                               relief="sunken")

        # Atmospheric Clarity Parameter, REF 2, Eq. 12, p. 645
        self.k_lbl = Label(self.input_frame,
                           text="Atmospheric Clarity Parameter:",
                           width=btn_width,
                           anchor=E)
        self.k_entry = Entry(self.input_frame,
                             width=btn_width,
                             bd=2,
                             relief="sunken")

        # Zenith angle (deg), z, REF 2, Fig. 6, p.648
        self.zen_lbl = Label(self.input_frame,
                             text="Zenith Angle (deg):",
                             width=lbl_width,
                             anchor=E)
        self.zen_entry = Entry(self.input_frame,
                               width=btn_width,
                               bd=2,
                               relief="sunken")

        # Azimuth angle (deg)
        self.azi_lbl = Label(self.input_frame,
                             text="Azimuth Angle (deg):",
                             width=lbl_width,
                             anchor=E)
        self.azi_entry = Entry(self.input_frame,
                               width=btn_width,
                               bd=2,
                               relief="sunken")

        self.krn_lbl = Label(self.input_frame,
                             text="Kernel File:",
                             width=lbl_width,
                             anchor=E)
        self.krn_ent = Entry(self.input_frame,
                             width=file_width,
                             bd=2,
                             relief="sunken",
                             textvariable=self.krn_ent_var)
        self.krn_btn = Button(self.input_frame,
                              text="Browse",
                              command=self.import_krn)

        # Generate Artificial Skyglow Map Button
        self.map_btn = Button(self.input_frame,
                              text="Generate Artificial Skyglow Map",
                              width=gen_width,
                              command=self.generate_map)
        # Generate Kernal library button for SET
        self.gen_krn_btn = Button(self.input_frame,
                                  text="Generate Kernel Library",
                                  width=gen_width,
                                  command=self.generate_krn)
        # Generate Map of Multiple Kernals(word better later on)
        self.mul_map_btn = Button(self.input_frame,
                                  text="Generate Maps from Multiple Kernels",
                                  width=gen_width,
                                  command=self.generate_mmap)
        # Generate Hemispherical Visualization Display of Skyglow
        self.hem_gen_btn = Button(self.input_frame,
                                  text="Generate Hemisphere",
                                  width=gen_width,
                                  command=self.generate_hem)

    def import_viirs(self):
        """Import a VIIRS DNB file."""
        # Allows user to search through his directory for VIIRS Image file.
        file_types = [('TIFF Files', '*.tif'), ('All files', '*')]
        file_name = filedialog.askopenfilename(initialdir='/',
                                               title="Select file",
                                               filetypes=file_types)
        self.file_log_var.set(file_name)

        # Checks to see if file is empty. If not, displays image on canvas.
        if file_name != '':
            pilimg = Image.open(file_name)
            pilimg_width, pilimg_height = pilimg.size
            pilimg.tile = [
                t for t in pilimg.tile
                if t[1][2] < pilimg_width and t[1][3] < pilimg_height
            ]
            canvas_size = (self.img_canvas.winfo_width(),
                           self.img_canvas.winfo_height())
            pilimg_r = pilimg.resize(canvas_size, Image.ANTIALIAS)
            pilimg_col = ImageOps.colorize(ImageOps.grayscale(pilimg_r),
                                           (0, 0, 0), (255, 255, 255))
            pilimg_cont = ImageOps.autocontrast(pilimg_col,
                                                cutoff=.4,
                                                ignore=None)
            self.img = ImageTk.PhotoImage(pilimg_cont)
            self.img_canvas.create_image(canvas_size[0] / 2,
                                         canvas_size[1] / 2,
                                         image=self.img)
        else:
            print('File is empty.')

    def import_csv(self):
        """Import CSV file."""
        file_types = [('CSV Files', '*.csv'), ('All files', '*')]
        file_name = filedialog.askopenfilename(initialdir='/',
                                               title="Select file",
                                               filetypes=file_types)
        self.csv_file_var.set(file_name)

        if file_name is '':
            print('File is empty.')

    def import_krn_folder(self):
        """Import kernel folder."""
        krn_dir = filedialog.askdirectory(initialdir='/',
                                          title="Select kernel folder")
        self.krn_folder_var.set(krn_dir)

        if krn_dir is '':
            print('Directory is empty.')

    def import_out_folder(self):
        """Import skyglow output folder."""
        output_dir = filedialog.askdirectory(initialdir='/',
                                             title="Select output folder")
        self.output_folder_var.set(output_dir)

        if output_dir is '':
            print('Directory is empty.')

    def import_krn(self):
        """Import existing kernel tif."""
        file_types = [('TIFF Files', '*.tif'), ('All files', '*')]
        file_name = filedialog.askopenfilename(initialdir='/',
                                               title="Select file",
                                               filetypes=file_types)
        self.krn_ent_var.set(file_name)

    def import_sgmap_folder(self):
        """Import skyglow map folder for hemisphere building."""
        sgmap_dir = filedialog.askdirectory(initialdir='/',
                                            title="Select skyglow map folder")
        self.sgmap_folder_var.set(sgmap_dir)

        if sgmap_dir is '':
            print('Directory is empty.')

    def sng_popup(self):
        """Single map tab."""
        self.remove_all()

        self.check_lbl.grid(column=0, row=2)
        self.krn_chk.place(relx=.22, rely=.41, anchor=CENTER)

        self.file_lbl.grid(column=0, row=1)
        self.file_log.grid(column=1, columnspan=3, row=1)
        self.browse_btn.grid(column=4, row=1, sticky=W, padx=3)

        self.lat_lbl.grid(column=0, row=3)
        self.lat_entry.grid(column=1, row=3)

        self.k_lbl.grid(column=2, row=3)
        self.k_entry.grid(column=3, row=3)

        self.zen_lbl.grid(column=0, row=4)
        self.zen_entry.grid(column=1, row=4)

        self.azi_lbl.grid(column=2, row=4)
        self.azi_entry.grid(column=3, row=4)

        self.map_btn.grid(column=1, columnspan=3, row=5, sticky=N + S + E + W)

    def krn_popup(self):
        """Kernel lib tab."""
        self.remove_all()

        # latitude
        self.lat_lbl.grid(column=0, row=3)
        self.lat_entry.grid(column=1, row=3)

        # atmospheric clarity
        self.k_lbl.grid(column=2, row=3)
        self.k_entry.grid(column=3, row=3)

        # angles file
        self.csv_file_lbl.grid(column=0, row=1)
        self.csv_file_log.grid(column=1, columnspan=3, row=1)
        self.csv_browse_btn.grid(column=4, row=1, sticky=W, padx=3)

        # input VIIRS image
        self.file_lbl.grid(column=0, row=2)
        self.file_log.grid(column=1, columnspan=3, row=2)
        self.browse_btn.grid(column=4, row=2, sticky=W, padx=3)

        self.hem_chk_lbl.grid(column=0, row=4)
        self.hem_chk.place(relx=.21, rely=.69)

        self.gen_krn_btn.grid(column=1,
                              columnspan=3,
                              row=5,
                              sticky=N + S + E + W)

    def mul_popup(self):
        """Multiple maps tab."""
        self.remove_all()

        # Kernel folder location
        self.mul_file_lbl.grid(column=0, row=1)
        self.mul_file_log.grid(column=1, columnspan=3, row=1)
        self.mul_browse_btn.grid(column=4, row=1, sticky=W, padx=3)

        # input VIIRS image
        self.file_lbl.grid(column=0, row=2)
        self.file_log.grid(column=1, columnspan=3, row=2)
        self.browse_btn.grid(column=4, row=2, sticky=W, padx=3)

        # Choose output location
        self.output_lbl.grid(column=0, row=3)
        self.output_log.grid(column=1, columnspan=3, row=3)
        self.output_btn.grid(column=4, row=3, sticky=W, padx=3)

        # Generate map from kernel folder
        self.mul_map_btn.grid(column=1,
                              columnspan=3,
                              row=4,
                              sticky=N + S + E + W)

    def hem_popup(self):
        """Hemisphere tab."""
        self.remove_all()

        # Skyglow Map Folder
        self.sgmap_folder_lbl.grid(column=0, row=1)
        self.sgmap_folder_log.grid(column=1, columnspan=3, row=1)
        self.sgmap_folder_btn.grid(column=4, row=1, sticky=W, padx=3)

        # Latitude entry
        self.lat_lbl.grid(column=0, row=3)
        self.lat_entry.grid(column=1, row=3)

        # Longitude entry
        self.lon_lbl.grid(column=2, row=3)
        self.lon_entry.grid(column=3, row=3)

        # Generate Hemispherical Visualization button
        self.hem_gen_btn.grid(column=1,
                              columnspan=3,
                              row=4,
                              sticky=N + S + E + W)

    def remove_all(self):
        """Remove all existing GUI elements before opening new tab."""
        self.check_lbl.grid_remove()
        self.krn_chk.place_forget()
        self.hem_chk.place_forget()
        self.hem_chk_lbl.grid_remove()
        self.file_lbl.grid_remove()
        self.file_log.grid_remove()
        self.browse_btn.grid_remove()
        self.krn_lbl.grid_remove()
        self.krn_ent.grid_remove()
        self.krn_btn.grid_remove()
        self.lat_lbl.grid_remove()
        self.lat_entry.grid_remove()
        self.k_lbl.grid_remove()
        self.k_entry.grid_remove()
        self.zen_lbl.grid_remove()
        self.zen_entry.grid_remove()
        self.azi_lbl.grid_remove()
        self.azi_entry.grid_remove()
        self.map_btn.grid_remove()
        self.gen_krn_btn.grid_remove()
        self.mul_map_btn.grid_remove()
        self.csv_file_lbl.grid_remove()
        self.csv_file_log.grid_remove()
        self.csv_browse_btn.grid_remove()
        self.mul_file_lbl.grid_remove()
        self.mul_file_log.grid_remove()
        self.mul_browse_btn.grid_remove()
        self.output_lbl.grid_remove()
        self.output_log.grid_remove()
        self.output_btn.grid_remove()
        self.hem_gen_btn.grid_remove()
        self.lat_lbl.grid_remove()
        self.lat_entry.grid_remove()
        self.lon_lbl.grid_remove()
        self.lon_entry.grid_remove()
        self.sgmap_folder_lbl.grid_remove()
        self.sgmap_folder_log.grid_remove()
        self.sgmap_folder_btn.grid_remove()

    def checkbtn_val(self):
        """Change interface based on if Import Kernel button is checked."""
        # Import Kernel File widgets when Kernel Checkbutton is marked.
        if self.krn_var.get():
            self.lat_lbl.grid_remove()
            self.lat_entry.grid_remove()
            self.k_lbl.grid_remove()
            self.k_entry.grid_remove()
            self.zen_lbl.grid_remove()
            self.zen_entry.grid_remove()
            self.azi_lbl.grid_remove()
            self.azi_entry.grid_remove()
            self.krn_lbl.grid(column=0, row=2)
            self.krn_ent.grid(column=1, columnspan=3, row=2)
            self.krn_btn.grid(column=4, row=2, sticky=W, padx=3)
            self.krn_chk.place_forget()
            self.krn_chk.place(relx=0.19, rely=.5)
        # Input parameter widgets when Kernel Checkbuttton is unmarked
        else:
            self.krn_lbl.grid_remove()
            self.krn_ent.grid_remove()
            self.krn_btn.grid_remove()
            self.lat_lbl.grid(column=0, row=3)
            self.lat_entry.grid(column=1, row=3)
            self.k_lbl.grid(column=2, row=3)
            self.k_entry.grid(column=3, row=3)
            self.zen_lbl.grid(column=0, row=4)
            self.zen_entry.grid(column=1, row=4)
            self.azi_lbl.grid(column=2, row=4)
            self.azi_entry.grid(column=3, row=4)
            self.krn_chk.place_forget()
            self.krn_chk.place(relx=0.22, rely=.41, anchor=CENTER)

    @staticmethod
    def open_url(url):
        """"Open a url"""
        webbrowser.open_new(url)

    def instructions(self):
        """Open instructions window."""
        # Instantiates separate Toplevel instruction window.
        instr_window = Toplevel(self.root)
        instr_window.geometry('550x575+25+25')
        instr_window.title('Instructions')
        instr_window.wm_iconbitmap(constants.ICO)
        instr_window.resizable(False, False)

        # Creatse Scrollbar and Frame for containing other widgets.
        instr_scroll = Scrollbar(instr_window)
        instr_scroll.pack(fill=Y, side="right")
        instr_frame = Frame(instr_window, bg='white')
        instr_frame.pack(fill=BOTH, side="left")

        # Adds instruction text from constants and adds image of Cinzano's diagram.
        instr = Text(instr_frame,
                     width=65,
                     height=40,
                     padx=10,
                     pady=5,
                     bd=0,
                     wrap="word")
        instr.insert("end", constants.INSTR)
        cdiagram_file = Image.open("./static/cinzano_diagram.PNG")
        cdiagram_file = cdiagram_file.resize((500, 450), Image.ANTIALIAS)
        self.cdiag = ImageTk.PhotoImage(cdiagram_file)
        instr.image_create("end", image=self.cdiag)
        instr.tag_add("top", "1.0", "4.10")
        instr.tag_config("top", font='Times 12 bold')
        instr.tag_add("body", "5.0", "19.20")
        instr.tag_config("body", font='Times 12')
        instr.insert("end", constants.CDIAG)
        instr.pack()
        instr_scroll.config(command=instr.yview)

    def about(self):
        """Open an about window.

        Window gives authors, SET version number, and icon credit.
        """
        # Instantiates a new Toplevel about window.
        about_window = Toplevel(self.root)
        about_window.geometry('350x335+25+25')
        about_window.title('About')
        about_window.wm_iconbitmap(constants.ICO)
        about_window.resizable(False, False)

        # Adds text to about window.
        about = Text(about_window, width=50, height=30, padx=10, pady=3)
        about.insert("end", constants.ABOUT)
        about.tag_add("abt", "1.0", "21.30")
        about.tag_config("abt", font='Times 10 bold', justify=CENTER)
        about.pack()

    def progress(self):
        """Construct a progress window to monitor darksky."""
        # Instantiates a new Toplevel window and frame for progress bar and loading log.
        self.prg_window = Toplevel(self.root)
        self.prg_window.geometry('650x325+250+250')
        self.prg_window.title('Generating Artificial Skyglow Map...')
        self.prg_window.iconbitmap(constants.ICO)
        self.prg_window.resizable(False, False)
        prg_frame = Frame(self.prg_window)
        prg_frame.pack(fill=BOTH)

        # Creates Scrollbar, Progressbar, and Label for checking progress..
        prg_scroll = Scrollbar(prg_frame)
        prg_scroll.pack(fill=Y, side="right")
        self.prg_bar = ttk.Progressbar(prg_frame,
                                       orient=HORIZONTAL,
                                       length=750,
                                       mode='indeterminate')
        self.prg_bar.pack()
        self.prg_bar.start()
        prg_lbl_txt = StringVar()
        prg_lbl = Label(prg_frame, textvariable=prg_lbl_txt)
        prg_lbl.pack()

        # Displays message log that prints from log file and starts darkskypy.
        self.prg_log = Text(prg_frame,
                            width=90,
                            padx=5,
                            pady=5,
                            relief="sunken")
        self.prg_log.pack()
        self.prg_log.insert(
            "end", "*****Progress Log*****\n=======================\n")
        self.prg_log.tag_add("abt", "1.0", "3.0")
        self.prg_log.tag_config("abt", font='Courier 12 bold', justify=CENTER)
        self.txt_redir = LogRedirector(self.prg_log)
        logger.addHandler(self.txt_redir)
        sys.stderr = StderrRedirector(self.prg_log)
        prg_lbl_txt.set("Start time: " + str(time.asctime()))

        self.no_progress = 0

    def update_progress(self):
        """Update progress window to prevent it from freezing."""
        self.prg_log.update()
        # if only one thread exists, stop progress bar and close window
        if len(threading.enumerate()) == 1:
            self.prg_bar.stop()
            self.no_progress += 1
            if self.no_progress == 3:
                self.prg_window.withdraw()
        else:
            self.prg_bar.start()
        self.root.after(1000, self.update_progress)

    def generate_map(self):
        """Call darksky.sgmapper in background thread."""
        # Acquires input arguments.
        lat_in, k_in, zen_in, azi_in, file_in, krn_file_in = 0, 0, 0, 0, '', ''
        if self.krn_var.get():
            krn_file_in = self.krn_ent_var.get()
        else:
            lat_in = float(self.lat_entry.get())
            k_in = float(self.k_entry.get())
            zen_in = float(self.zen_entry.get())
            azi_in = float(self.azi_entry.get())
        file_in = self.file_log_var.get()

        self.progress()

        # Create new threads to run light propagation model simultaneously.
        p_thread = threading.Thread(target=self.update_progress())
        t_thread = threading.Thread(target=darksky.sgmapper,
                                    args=(lat_in, k_in, zen_in, azi_in,
                                          file_in, krn_file_in))
        t_thread.setDaemon(True)
        p_thread.start()
        t_thread.start()

    def generate_krn(self):
        """Start kernel generation in background threads."""
        # Acquires input arguments
        csv_in, file_in, lat_in, k_in, hem = '', '', 0, 0, False
        csv_in = self.csv_file_var.get()
        file_in = self.file_log_var.get()
        lat_in = float(self.lat_entry.get())
        k_in = float(self.k_entry.get())
        hem = self.hem_var.get()

        self.progress()

        # Create new threads to run light propagation model simultaneously.
        p_thread = threading.Thread(target=self.update_progress())
        with open(csv_in, "rb") as f:
            angle_list = loadtxt(f, delimiter=",", skiprows=1)
        p_thread.start()
        for angle_set in angle_list:
            t_thread = threading.Thread(target=darksky.generate_krn,
                                        args=(lat_in, k_in, angle_set[0],
                                              angle_set[1], file_in, hem))
            t_thread.setDaemon(True)

            t_thread.start()

    def generate_mmap(self):
        """Start brightness map creation from kernels."""
        # Acquires input arguments
        krn_folder_in, file_in, output_in, = '', '', ''
        krn_folder_in = self.krn_folder_var.get()
        file_in = self.file_log_var.get()
        output_in = self.output_folder_var.get()

        self.progress()

        # Create new threads to run light propagation model simultaneously.
        p_thread = threading.Thread(target=self.update_progress())
        t_thread = threading.Thread(target=darksky.multisgmapper,
                                    args=(file_in, krn_folder_in, output_in))
        t_thread.setDaemon(True)
        p_thread.start()
        t_thread.start()

    def generate_hem(self):
        """Generate hemisphere."""
        sgmap_folder_in, lat_in, lon_in, = '', 0, 0
        sgmap_folder_in = self.sgmap_folder_var.get()
        lat_in = float(self.lat_entry.get())
        lon_in = float(self.lon_entry.get())
        darksky.generate_hem(lat_in, lon_in, sgmap_folder_in)