示例#1
0
 def __init__(self, *args, **kwargs):
     Visualiser.__init__(self, *args, **kwargs)
     fin = NetCDFFile(self.vis_source, 'r')
     self.xPoints = array(fin.variables['x'], Float)
     self.yPoints = array(fin.variables['y'], Float)
     self.quantityCache = {}
     fin.close()
示例#2
0
    def __init__(self, source, frameDelay=100, frameStep=1):
        """The source parameter is assumed to be a NetCDF sww file.
        The frameDelay parameter is the number of milliseconds waited between frames.
        """
        Visualiser.__init__(self, source)

        self.frameNumber = 0
        fin = NetCDFFile(self.source, 'r')
        self.maxFrameNumber = fin.variables['time'].shape[0] - 1
        fin.close()

        #self.frameNumberTkVariable = StringVar()
        #self.frameNumberTkVariable.set('Frame - %05g'%self.framNumber)

        self.frameDelay = frameDelay

        self.xmin = None
        self.xmax = None
        self.ymin = None
        self.ymax = None
        self.zmin = None
        self.zmax = None

        self.frameStep = frameStep

        self.vtk_heightQuantityCache = []
        for i in range(self.maxFrameNumber +
                       1):  # maxFrameNumber is zero indexed.
            self.vtk_heightQuantityCache.append({})

        self.paused = False
        self.movie = False
示例#3
0
    def __init__(self, source, frameDelay=100, frameStep=1):
        """The source parameter is assumed to be a NetCDF sww file.
        The frameDelay parameter is the number of milliseconds waited between frames.
        """
        Visualiser.__init__(self, source)

        self.frameNumber = 0
        fin = NetCDFFile(self.source, 'r')
        self.maxFrameNumber = fin.variables['time'].shape[0] - 1
        fin.close()
        
        #self.frameNumberTkVariable = StringVar()
        #self.frameNumberTkVariable.set('Frame - %05g'%self.framNumber)

        self.frameDelay = frameDelay

        self.xmin = None
        self.xmax = None
        self.ymin = None
        self.ymax = None
        self.zmin = None
        self.zmax = None

        self.frameStep= frameStep 

        self.vtk_heightQuantityCache = []
        for i in range(self.maxFrameNumber + 1): # maxFrameNumber is zero indexed.
            self.vtk_heightQuantityCache.append({})

        self.paused = False
        self.movie = False
示例#4
0
    def setup_gui(self):
        Visualiser.setup_gui(self)
        self.tk_quit.grid(row=0, column=0, sticky=W+E)
        self.tk_movie_toggle = Button(self.tk_controlFrame, text="Movie off", command=self.movie_toggle)
        self.tk_movie_toggle.grid(row=0, column=6,  sticky=W+E)
        
                
        self.tk_restart = Button(self.tk_controlFrame, text="<<<", command=self.restart, width=5)
        self.tk_restart.grid(row=1, column=0, sticky=W+E)
        self.tk_back10 = Button(self.tk_controlFrame, text="<<", command=self.back10, width=5)
        self.tk_back10.grid(row=1, column=1, sticky=W+E)
        self.tk_back = Button(self.tk_controlFrame, text="<", command=self.back, width=5)
        self.tk_back.grid(row=1, column=2, sticky=W+E)
        self.tk_pauseResume = Button(self.tk_controlFrame, text="Pause", command=self.pauseResume, width=15)
        self.tk_pauseResume.grid(row=1, column=3, sticky=W+E)
        self.tk_forward = Button(self.tk_controlFrame, text=">", command=self.forward, width=5)
        self.tk_forward.grid(row=1, column=4, sticky=W+E)
        self.tk_forward10 = Button(self.tk_controlFrame, text=">>", command=self.forward10, width=5)
        self.tk_forward10.grid(row=1, column=5, sticky=W+E)
        self.tk_forwardEnd = Button(self.tk_controlFrame, text=">>>", command=self.forwardEnd, width=5)
        self.tk_forwardEnd.grid(row=1, column=6, sticky=W+E)
        

        self.tk_frameNumber = Label(self.tk_controlFrame, text='Frame')
        self.tk_frameNumber.grid(row=2, column=0, sticky=W+E)
        self.tk_gotoFrame = Scale(self.tk_controlFrame, from_=0, to=self.maxFrameNumber, orient=HORIZONTAL)
        self.tk_gotoFrame.grid(row=2, column=1, columnspan=2, sticky=W+E)
        self.tk_stepLabel = Label(self.tk_controlFrame, text='Step')
        self.tk_stepLabel.grid(row=2, column=4, sticky=W+E)        
        self.tk_frameStep = Scale(self.tk_controlFrame, from_=0, to=self.maxFrameNumber, orient=HORIZONTAL)
        self.tk_frameStep.grid(row=2, column=5, columnspan=2, sticky=W+E)
        
        # Make the buttons stretch to fill all available space
        for i in range(7):
            self.tk_controlFrame.grid_columnconfigure(i, weight=1)
示例#5
0
 def redraw(self):
     if self.running and self.sync_unpaused.isSet():
         self.sync_redrawReady.wait()
         self.sync_redrawReady.clear()
         self.redraw_quantities()
         self.sync_idle.set()
     Visualiser.redraw(self)
 def __init__(self, *args, **kwargs):
     Visualiser.__init__(self, *args, **kwargs)
     fin = NetCDFFile(self.vis_source, 'r')
     self.xPoints = array(fin.variables['x'], Float)
     self.yPoints = array(fin.variables['y'], Float)
     self.quantityCache = {}
     fin.close()
示例#7
0
def main():
    # def main(arglist):
    file = './testcases/4g1_m1.txt'
    outfile = 'out/4g1_m1_output.txt'
    # file = arglist[0]
    # outfile = arglist[1]

    prm = EST(file)
    # config = prm.sampling(1000)
    # robot = prm.get_init_state();
    f = open("tmp_output.txt", "w")
    f.write("")
    f.close()
    prm.run_EST(outfile)
    # D = [1e-3,1e-3]
    # sampleRobot = prm.sampling_withinD(robot,D,100)
    # robot = prm.assign_config(config.tolist(),0)
    # print(sampleRobot)
    # print(config.tolist())
    # config = config[:,:-1]
    # prm.write_config('test.txt',config.tolist())

    aa = test_robot(prm)
    qq = aa.load_output('output.txt')
    vis = Visualiser(prm, qq)
    def create_widgets(self):

        self.code_text = CodeText(self)
        self.visualiser = Visualiser(self)
        self.code_runner = wx.Panel(self)

        # self.aui_manager = wx.aui.AuiManager(self, wx.aui.AUI_MGR_DEFAULT | wx.aui.AUI_MGR_LIVE_RESIZE)
        self.aui_manager = wx.aui.AuiManager(
            self,
            wx.aui.AUI_MGR_ALLOW_FLOATING | wx.aui.AUI_MGR_TRANSPARENT_HINT
            | wx.aui.AUI_MGR_LIVE_RESIZE)
        # self.aui_manager = wx.lib.agw.aui.AuiManager(self, wx.aui.AUI_MGR_ALLOW_FLOATING | wx.aui.AUI_MGR_TRANSPARENT_HINT
        #                                              | wx.aui.AUI_MGR_LIVE_RESIZE)
        self.aui_manager.AddPane(self.code_text, wx.CENTRE, 'Code Text')
        self.aui_manager.AddPane(self.visualiser, wx.TOP, 'Visualiser')
        self.aui_manager.AddPane(self.code_runner, wx.BOTTOM, 'Code Runner')
        self.aui_manager.Update()
示例#9
0
    def __init__(self, current_season: int):
        self.current_season = current_season
        self.data = Data(current_season)
        self.visualiser = Visualiser()

        # Import environment variables
        __file__ = 'data.py'
        dotenv_path = join(dirname(__file__), '.env')
        load_dotenv(dotenv_path)
        self.url = os.getenv('URL')
        self.headers = {'X-Auth-Token': os.getenv('X_AUTH_TOKEN')}

        # Number of games played in a season for season data to be used
        self.games_threshold = 4
        self.home_games_threshold = 6
        self.star_team_threshold = 0.75  # Rating over 75% to be a star team

        # Store for new requested API data or old data from memory
        self.json_data = {'fixtures': {}, 'standings': {}}
        self.last_updated = None  # type: str
示例#10
0
 def setUp(self):
     self.parser = DataParser()
     self.cmd_view = CmdView()
     self.file_view = FileView()
     self.validator = Validator()
     self.db = DatabaseView("test.db")
     self.vis = Visualiser()
     # self.val = Validator()
     self.controller = Controller(self.cmd_view, self.file_view,
                                  self.parser, self.validator, self.db,
                                  self.vis)
示例#11
0
def run_optimal():
	vis = Visualiser(env, 80)
	numActions = env.n_actions
	playerA = QLearn(actions=list(range(numActions)))
	playerA.load_Qtable("saved_players/QR")
	playerB = QLearn(actions=list(range(numActions)))
	playerB.load_Qtable("saved_players/QR_base")
	for episode in range(500):
		observation = env.reset()
		vis.update_canvas(env)
		while(True):
			actionA = playerA.choose_action(str(observation))
			actionB = playerB.choose_action(str(observation))
			observation_, reward, done = env.step(actionA, actionB)
			observation = observation_
			vis.update_canvas(env)
			if done:
				vis.reset()
				break
	print("Games won: " + str(env.win_count))
	vis.destroy()
示例#12
0
    def __init__(self, source):
        """The source parameter is assumed to be a Domain.
        """
        Visualiser.__init__(self, source)

        self.running = True

        self.xmin = None
        self.xmax = None
        self.ymin = None
        self.ymax = None
        self.zmin = None
        self.zmax = None

        # Synchronisation Constructs
        self.sync_idle = Event()
        self.sync_idle.clear()
        self.sync_unpaused = Event()
        self.sync_unpaused.set()
        self.sync_redrawReady = Event()
        self.sync_redrawReady.clear()
示例#13
0
 def setUp(self):
     self.parser = DataParser()
     self.cmd_view = CmdView()
     self.file_reader = FileReader()
     self.validator = Validator()
     self.db = Database("test.db")
     self.vis = Visualiser()
     self.val = Validator()
     self.serial = Serializer()
     self.controller = Controller(self.cmd_view, self.file_reader,
                                  self.parser, self.validator, self.db,
                                  self.vis, self.serial)
     self.init()
示例#14
0
    def print_top(self, sentiments=[], n=10):
        '''

        :param sentiments:
        :param n:
        :return:
        '''

        if not self._scored : self.score_tweets()

        if len(set(sentiments).difference(self._data.columns)) != 0 or not isinstance(sentiments, list) or len(
                sentiments) == 0:
            raise Exception("Use a valid sentiment list {}".format([sentiment for sentiment in self.models_ar]))
        Visualiser(self._data).print_top(sentiments=sentiments, n=n)
示例#15
0
def run_optimalB():
	numActions = env.n_actions
	drawProbability = 0.1
	decay = 10**(-2. / N_EPISODES * 0.05)
	vis = Visualiser(env, 80)
	numActions = env.n_actions
	playerB = MinimaxQPlayer(numActions, numActions, decay=decay, expl=0.00, gamma=1-drawProbability)
	playerB.load_Qtable("MR")
	playerA = QLearn(actions=list(range(numActions)))
	playerA.load_Qtable("saved_players/MR_base")
	for episode in range(20):
		observation = env.reset()
		vis.update_canvas(env)
		while(True):
			actionA = playerA.choose_action(str(observation))
			actionB = playerB.choose_action(str(observation))
			observation_, reward, done = env.step(actionA, actionB)
			observation = observation_
			vis.update_canvas(env)
			if done:
				vis.reset()
				break
	print("Games won: " + str(env.win_count))
	vis.destroy()
示例#16
0
    def bubble_chart(self,
                     rounding=2,
                     positive_sentiments=['joy', 'love'],
                     negative_sentiments=['anger', 'sadness']):
        '''

        :param rounding:
        :param positive_sentiments:
        :param negative_sentiments:
        :return:
        '''

        if not self._scored : self.score_tweets()

        Visualiser(self._data).bubble_chart(
            rounding=rounding,
            positive_sentiments=positive_sentiments,
            negative_sentiments=negative_sentiments)
示例#17
0
def sample(spec):
    samples = []
    samples += sample_double_grappled(spec)
    samples += uniform_sample(spec)
    double_samples = []
    for s in samples:
        angles = s.ee1_angles.copy()
        lengths = s.lengths.copy()
        lengths.reverse()
        double_samples.append(
            make_robot_config_from_ee2(s.points[0][0],
                                       s.points[0][1],
                                       angles,
                                       lengths,
                                       ee1_grappled=s.ee2_grappled,
                                       ee2_grappled=s.ee1_grappled))
    samples += double_samples
    Visualiser(spec, samples)
    return samples
示例#18
0
    def pie_chart(self,
                  treshold_pos=0.7,
                  treshold_neg=0.3,
                  positive_sentiments=['joy', 'love'],
                  negative_sentiments=['anger', 'sadness']):
        '''

        :param treshold_pos:
        :param treshold_neg:
        :param positive_sentiments:
        :param negative_sentiments:
        :return:
        '''

        if not self._scored : self.score_tweets()

        Visualiser(self._data).pie_chart(
            treshold_pos=treshold_pos,
            treshold_neg=treshold_neg,
            positive_sentiments=positive_sentiments,
            negative_sentiments=negative_sentiments)
示例#19
0
def ql_vs_minmax(visualise):
	print("ql vs minmax ql")
	numActions = env.n_actions
	drawProbability = 0.1
	decay = 10**(-2. / N_EPISODES * 0.05)
	if(visualise):
		vis = Visualiser(env, 80)
	numActions = env.n_actions
	start_time = time.time()
	ql_wins = 0
	minmax_wins = 0
	playerA = QLearn(actions=list(range(numActions)), reward_decay=0.7)
	playerB = MinimaxQPlayer(numActions, numActions, decay=decay, expl=0.01, gamma=1-drawProbability)
	playerA.load_Qtable('saved_players/QR')
	playerB.load_Qtable("MR")
	# no explore
	iterations = 5000
	for episode in range(iterations):
		# initial observation
		observation = env.reset()
		# print(str(episode))
		if(episode % 100 == 0):
			print(str(float(episode) / iterations * 100) + "%")
		# if(episode > iterations - 100):
		# 	vis.update_canvas(env)
		while True:
			# RL choose action based on observation
			actionA = playerA.choose_action(str(observation))
			actionB = playerB.choose_action(str(observation))

			# RL take action and get next observation and reward
			observation_, reward, done = env.step(actionA, actionB)
			if reward == 1:
				ql_wins += 1
			elif reward == -1:
				minmax_wins += 1
			
			observation = observation_
			if(visualise):
				vis.update_canvas(env)
			if done:
				if(visualise):
					vis.reset()
				break
	return (ql_wins, minmax_wins)
示例#20
0
def main():
    # input data
    inputDataFileName = '/home/dane/repos/oops/datasets/small.in'
    print("Input Dataset: ", inputDataFileName)
    smallData = InputData(inputDataFileName)

    # assume the slices piece is valid
    # magic code goes here
    slicedSmallPizza = [
        7,
        [[0, 0, 1, 1], [0, 3, 1, 4], [0, 5, 1, 6], [2, 0, 3, 1], [2, 2, 3, 3],
         [2, 4, 3, 5], [4, 5, 5, 6]]
    ]
    # visualise slices
    Visualiser(smallData, slicedSmallPizza[1])

    # calculate the score
    print('Score: ', ScoreCalc(slicedSmallPizza[1]).score)

    # output the the file
    outputDataFileName = '/home/dane/repos/oops/output/small.out'
    print("Output file: ", outputDataFileName)
    GenerateOutput(slicedSmallPizza, outputDataFileName)
示例#21
0
def main(arglist):
    # input_file = arglist[0]
    # output_file = arglist[1]
    input_file = "testcases/3g1_m2.txt"
    output_file = "testcases/output.txt"
    spec = ProblemSpec(input_file)

    init_node = GraphNode(spec, spec.initial)
    goal_node = GraphNode(spec, spec.goal)

    g = GraphNode(spec, spec.goal)
    # path_plan = []
    #
    # for i in range(200):
    #     c = g.generate_sample()
    #     path_plan.append(c)

    steps = []

    path_plan = g.PRM(init_node, goal_node)
    # write_robot_config_list_to_file(output_file, path_plan)

    # Code for your main method can go here.
    #
    # Your code should find a sequence of RobotConfig objects such that all configurations are collision free, the
    # distance between 2 successive configurations is less than 1 primitive step, the first configuration is the initial
    # state and the last configuration is the goal state.
    #
    #

    # if len(arglist) > 1:

    #
    # You may uncomment this line to launch visualiser once a solution has been found. This may be useful for debugging.
    # *** Make sure this line is commented out when you submit to Gradescope ***
    #
    v = Visualiser(spec, path_plan)
示例#22
0
def main(arglist):
    input_file = arglist[0]
    output_file = arglist[1]

    spec = ProblemSpec(input_file)

    init_node = GraphNode(spec, spec.initial)
    goal_node = GraphNode(spec, spec.goal)

    num_grapple_points = spec.num_grapple_points
    if num_grapple_points == 1:
        graph_nodes = [[init_node, goal_node]]
    else:
        graph_nodes = [[] for i in range(num_grapple_points)]
        graph_nodes[0].append(init_node)
        graph_nodes[-1].append(goal_node)

    steps = []

    # Solution

    # Note on solution: if there are multiple grapple points, samples are collected separately for each grapple point
    # Then, the closest node to a grapple point in the sample for an ADJACENT grapple point is taken as the goal node.
    #

    steps = generate_steps(spec, 5000 * spec.num_grapple_points, graph_nodes,
                           init_node, goal_node, spec.num_grapple_points)

    if len(arglist) > 1:
        write_robot_config_list_to_file(output_file, steps)

    #
    # You may uncomment this line to launch visualiser once a solution has been found. This may be useful for debugging.
    # *** Make sure this line is commented out when you submit to Gradescope ***
    #
    v = Visualiser(spec, steps)
示例#23
0
import pygame
import sys
import random

from map import Map
from visualiser import Visualiser
from pathfinder import Pathfinder

map = Map()
map.loadData()

visualiser = Visualiser("Inlupp 2 - Visualiser", map.getWidth(),
                        map.getHeight())
visualiser.setMap(map)

pathfinder = Pathfinder(visualiser, map)
pathfinder.findCheapestPath()

visualiser.runLoop()
示例#24
0
            vis.update_canvas(env.actor, env.enemy)
            if done:
                break
    print("Games won: " + str(env.win_count))
    vis.destroy()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='QMaze options')
    parser.add_argument('--test',
                        dest='test',
                        action='store_true',
                        help='if you wish to re-train')
    parser.add_argument('--vis',
                        dest='vis',
                        action='store_true',
                        help='if you wish to see the GUI')
    args = parser.parse_args()
    print(args)
    if (args.test):
        env = Maze()
        RL = QLearn(actions=list(range(env.n_actions)))
        if (args.vis):
            vis = Visualiser(4, 4, 80, env.hell_blocks, env.goal, env.enemy)
        test(args.vis)
    else:
        env = Maze()
        vis = Visualiser(4, 4, 80, env.hell_blocks, env.goal, env.enemy)
        RL = QLearn(actions=list(range(env.n_actions)), e_greedy=1.0)
        run_optimal()
示例#25
0
from controller import Controller
from cmdview import CmdView
from file_reader import FileReader
from data_parser import DataParser
from validator import Validator
from database import Database
from visualiser import Visualiser
from serializer import Serializer

if __name__ == "__main__":
    parser = DataParser()
    cmd_view = CmdView()
    file_reader = FileReader()
    validator = Validator()
    db = Database("test.db")
    vis = Visualiser()
    serial = Serializer()

    con = Controller(cmd_view, file_reader, parser, validator, db, vis, serial)
    cmd_view.set_controller(con)

    # run program
    cmd_view.cmdloop()
示例#26
0
 def shutdown(self):
     Visualiser.shutdown(self)
     self.running = False
     self.sync_idle.set()
     self.sync_unpaused.set()
示例#27
0
    def setup_gui(self):
        Visualiser.setup_gui(self)
        self.tk_quit.grid(row=0, column=0, sticky=W + E)
        self.tk_movie_toggle = Button(self.tk_controlFrame,
                                      text="Movie off",
                                      command=self.movie_toggle)
        self.tk_movie_toggle.grid(row=0, column=6, sticky=W + E)

        self.tk_restart = Button(self.tk_controlFrame,
                                 text="<<<",
                                 command=self.restart,
                                 width=5)
        self.tk_restart.grid(row=1, column=0, sticky=W + E)
        self.tk_back10 = Button(self.tk_controlFrame,
                                text="<<",
                                command=self.back10,
                                width=5)
        self.tk_back10.grid(row=1, column=1, sticky=W + E)
        self.tk_back = Button(self.tk_controlFrame,
                              text="<",
                              command=self.back,
                              width=5)
        self.tk_back.grid(row=1, column=2, sticky=W + E)
        self.tk_pauseResume = Button(self.tk_controlFrame,
                                     text="Pause",
                                     command=self.pauseResume,
                                     width=15)
        self.tk_pauseResume.grid(row=1, column=3, sticky=W + E)
        self.tk_forward = Button(self.tk_controlFrame,
                                 text=">",
                                 command=self.forward,
                                 width=5)
        self.tk_forward.grid(row=1, column=4, sticky=W + E)
        self.tk_forward10 = Button(self.tk_controlFrame,
                                   text=">>",
                                   command=self.forward10,
                                   width=5)
        self.tk_forward10.grid(row=1, column=5, sticky=W + E)
        self.tk_forwardEnd = Button(self.tk_controlFrame,
                                    text=">>>",
                                    command=self.forwardEnd,
                                    width=5)
        self.tk_forwardEnd.grid(row=1, column=6, sticky=W + E)

        self.tk_frameNumber = Label(self.tk_controlFrame, text='Frame')
        self.tk_frameNumber.grid(row=2, column=0, sticky=W + E)
        self.tk_gotoFrame = Scale(self.tk_controlFrame,
                                  from_=0,
                                  to=self.maxFrameNumber,
                                  orient=HORIZONTAL)
        self.tk_gotoFrame.grid(row=2, column=1, columnspan=2, sticky=W + E)
        self.tk_stepLabel = Label(self.tk_controlFrame, text='Step')
        self.tk_stepLabel.grid(row=2, column=4, sticky=W + E)
        self.tk_frameStep = Scale(self.tk_controlFrame,
                                  from_=0,
                                  to=self.maxFrameNumber,
                                  orient=HORIZONTAL)
        self.tk_frameStep.grid(row=2, column=5, columnspan=2, sticky=W + E)

        # Make the buttons stretch to fill all available space
        for i in range(7):
            self.tk_controlFrame.grid_columnconfigure(i, weight=1)
示例#28
0
 def run(self):
     self.alter_tkroot(Tk.after, (self.frameDelay, self.animateForward))
     Visualiser.run(self)
示例#29
0
 def setup_gui(self):
     Visualiser.setup_gui(self)
     self.tk_pauseResume = Button(self.tk_controlFrame, text="Pause", command=self.pauseResume)
     self.tk_pauseResume.grid(row=1, column=0, sticky=E+W)
示例#30
0
            sky_type += "-rgb"
        step = .1  # 10 cm
        tau_phi = np.pi  # 60 deg
        condition = Hybrid(tau_x=step, tau_phi=tau_phi)
        agent_name = create_agent_name(date, sky_type, step, fov[0], fov[1])
        print agent_name

        world = load_world()
        world.enable_pol_filters(enable_pol)
        world.uniform_sky = uniform_sky
        routes = load_routes()
        world.add_route(routes[0])

        agent = MBAgent(condition=condition,
                        live_sky=update_sky,
                        visualiser=Visualiser(),
                        rgb=rgb,
                        fov=fov,
                        name=agent_name)
        agent.set_world(world)
        print agent.homing_routes[0]

        agent.visualiser.set_mode("panorama")
        for route in agent.start_learning_walk():
            print "Learned route:", route

        agent.visualiser.set_mode("top")
        route = agent.start_homing()
        print route
        if route is not None:
            save_route(route, agent_name)
示例#31
0
 def overview_chart(self):
     if not self._scored : self.score_tweets()
     sentiments = [sentiment for sentiment in self.models_ar]
     Visualiser(self._data).overview(sentiments=sentiments)
示例#32
0
 def run(self):
     self.alter_tkroot(Tk.after, (self.frameDelay, self.animateForward))
     Visualiser.run(self)
示例#33
0
class Updater:
    def __init__(self, current_season: int):
        self.current_season = current_season
        self.data = Data(current_season)
        self.visualiser = Visualiser()

        # Import environment variables
        __file__ = 'data.py'
        dotenv_path = join(dirname(__file__), '.env')
        load_dotenv(dotenv_path)
        self.url = os.getenv('URL')
        self.headers = {'X-Auth-Token': os.getenv('X_AUTH_TOKEN')}

        # Number of games played in a season for season data to be used
        self.games_threshold = 4
        self.home_games_threshold = 6
        self.star_team_threshold = 0.75  # Rating over 75% to be a star team

        # Store for new requested API data or old data from memory
        self.json_data = {'fixtures': {}, 'standings': {}}
        self.last_updated = None  # type: str

    # ----------------------------- DATA API -----------------------------------

    def fixtures_data(self, season: int, request_new: bool = True) -> dict:
        if request_new and self.url is not None:
            response = requests.get(
                self.url + 'competitions/PL/matches/?season={}'.format(season),
                headers=self.headers)

            code = response.status_code
            if code == 429 or code == 403:
                print('❌  Status:', code)
                raise ValueError('❌ ERROR: Data request failed')
            else:
                print('✔️  Status:', code)

            return response.json()['matches']
        else:
            # Read saved fixtures data
            with open(f'data/fixtures_{season}.json', 'r') as json_file:
                return json.load(json_file)

    def standings_data(self, season: int, request_new: bool = True) -> dict:
        if request_new and self.url is not None:
            response = requests.get(
                self.url +
                'competitions/PL/standings/?season={}'.format(season),
                headers=self.headers)

            code = response.status_code
            if code == 429 or code == 403:
                print('❌  Status:', code)
                raise ValueError('❌ ERROR: Data request failed')
            else:
                print('✔️  Status:', code)

            return response.json()['standings'][0]['table']
        else:
            # Read standings data
            with open(f'data/standings_{season}.json', 'r') as json_file:
                return json.load(json_file)

    def fetch_current_season(self, request_new: bool):
        # Fetch data from API (max this season and last season)
        self.json_data['fixtures'][self.current_season] = self.fixtures_data(
            self.current_season, request_new)
        self.json_data['standings'][self.current_season] = self.standings_data(
            self.current_season, request_new)

    def load_previous_fixtures(self, n_seasons: int):
        for i in range(1, n_seasons):
            season = self.current_season - i
            self.json_data['fixtures'][season] = self.fixtures_data(
                season, request_new=False)
            self.json_data['standings'][season] = self.standings_data(
                season, request_new=False)

    def fetch_json_data(self, n_seasons: int, request_new: bool = True):
        self.fetch_current_season(request_new)
        self.load_previous_fixtures(n_seasons)

        if request_new:
            self.last_updated = datetime.now().strftime(
                'Last updated: %Y-%m-%d %H:%M:%S')

    def save_data(self):
        """ Save current season fixtures and standings data in self.json_data to 
            json files. """
        for type in ('fixtures', 'standings'):
            with open(f'data/{type}_{self.current_season}.json', 'w') as f:
                json.dump(self.json_data[type][self.current_season], f)

    def get_logo_urls(self) -> dict[str, str]:
        data = self.json_data['standings'][self.current_season]

        logo_urls = {}
        for standings_row in data:
            team_name = standings_row['team']['name'].replace('&', 'and')
            crest_url = standings_row['team']['crestUrl']
            logo_urls[team_name] = crest_url

        return logo_urls

    def update_dataframes(self, n_seasons: int, display_tables: bool = False):
        # Standings for the last [n_seasons] seasons
        self.data.standings.update(self.json_data,
                                   self.data.team_names,
                                   self.current_season,
                                   n_seasons,
                                   display=display_tables)
        # Fixtures for the whole season for each team
        self.data.fixtures.update(self.json_data,
                                  self.current_season,
                                  display=display_tables)
        # Ratings for each team, based on last <no_seasons> seasons standings table
        self.data.team_ratings.update(self.data.standings,
                                      self.current_season,
                                      self.games_threshold,
                                      n_seasons,
                                      display=display_tables)
        # Calculated values to represent the personalised advantage each team has at home
        self.data.home_advantages.update(self.json_data,
                                         self.current_season,
                                         self.home_games_threshold,
                                         n_seasons,
                                         display=display_tables)
        # Calculated form values for each team for each matchday played so far
        self.data.form.update(self.data.fixtures,
                              self.data.standings,
                              self.data.team_ratings,
                              self.star_team_threshold,
                              display=display_tables)
        # Season metrics
        self.data.season_stats.update(self.data.form, display=display_tables)
        # Data about the opponent in each team's next game
        self.data.upcoming.update(self.json_data,
                                  self.data.fixtures,
                                  self.data.form,
                                  self.data.home_advantages,
                                  self.data.team_names,
                                  self.current_season,
                                  n_seasons,
                                  display=display_tables)

    def save_tables(self):
        self.data.standings._save_to_html()
        self.data.fixtures._save_to_html()
        self.data.team_ratings._save_to_html()
        self.data.home_advantages._save_to_html()
        self.data.form._save_to_html()
        self.data.upcoming._save_to_html()
        self.data.season_stats._save_to_html()

    def update_data(self, n_seasons, display_tables):
        self.data.logo_urls = self.get_logo_urls()
        self.data.team_names = self.data.logo_urls.keys()
        # Using stored data in self.json_data
        self.update_dataframes(n_seasons, display_tables)

    @timebudget
    def update_all(self,
                   n_seasons: int = 4,
                   team_name: str = None,
                   display_tables: bool = False,
                   display_graphs: bool = False,
                   request_new: bool = True):
        try:
            self.fetch_json_data(n_seasons, request_new)
        except ValueError as e:
            print(e)
            print('🔁 Retrying with saved data...')
            request_new = False
            self.fetch_json_data(n_seasons, request_new)

        self.update_data(n_seasons, display_tables)

        if request_new:
            print('💾 Saving new data as JSON files...')
            self.save_data()
            print('💾 Saving tables as HTML files...')
            self.save_tables()
            # Use dataframes to update all graph HTML files
            self.visualiser.update(self.data.fixtures,
                                   self.data.team_ratings,
                                   self.data.home_advantages,
                                   self.data.form,
                                   display_graphs=display_graphs,
                                   team=team_name)
                                       body_luminosity=7,
                                       body_object_area=5000,
                                       body_hole_area=5000,
                                       edge_luminosity=7,
                                       edge_object_area=6,
                                       edge_hole_area=5000)
segmentor_nuc = ConfocalNucleusSegmentor(img_retriever=skimage_img_retriever)

masker_cell = ConfocalCellAreaMasker(img_retriever=skimage_img_retriever,
                                     body_luminosity=7,
                                     body_object_area=100,
                                     body_hole_area=100)
segmentor_cell = ConfocalCellSegmentor(img_retriever=skimage_img_retriever)

shaper_cell = ImageShapeMaker(img_retriever=skimage_img_retriever)
viz = Visualiser(cmap='gray', cmap_set_under='green')

df_labels = parse_labels('./data_tmp/train.csv')

for cell_id, data_path_collection in local_imgs.items():

    if not '0020ad' in cell_id:
        continue

    img_nuc = data_path_collection['nuclei']
    img_er = data_path_collection['ER']
    img_tube = data_path_collection['microtubule']
    img_prot = data_path_collection['green']

    masker_nuc.make_mask_(img_nuc)
    segmentor_nuc.make_segments_(img_nuc, masker_nuc.mask)