Ejemplo n.º 1
0
 def generate_heatmap_layer(self):
     hm = Heatmap()
     foreground = hm.heatmap(self.l,
                             area=((self.calculate.upper_left[0],
                                    self.calculate.lower_left[1]),
                                   (self.calculate.upper_right[0],
                                    self.calculate.upper_left[1])),
                             scheme='green-red')
     foreground.save("foreground.png")
Ejemplo n.º 2
0
	def start(self):
		"""Default command of self.startbutton. Starts simulation.
		If no object has been added by user, raises NoObjectError.
		Otherwise, creates the data array and the initial heatmap.
		"""
		
		if Object.objects == [] and Window.windows == []:
			try:
				raise UniformFieldError("At least one object or window must be added to start simulation.")
			except UniformFieldError as error:
				self._showerror(error)
		
		elif self.temp is None:
			try:
				raise AttributeError("Value not found for the field temperature.")
			except AttributeError as error:
				self._showerror(error)
		
		elif self.tout is None and Window.windows != []:
			try:
				raise AttributeError("Value not found for the outside temperature.")
			except AttributeError as error:
				self._showerror(error)
		
		else:
			self.objectmenu.entryconfig(1, state=DISABLED)
			self.objectmenu.entryconfig(2, state=DISABLED)
			self.objectmenu.entryconfig(3, state=DISABLED)
			self.windowmenu.entryconfig(1, state=DISABLED)
			self.windowmenu.entryconfig(2, state=DISABLED)
			self.windowmenu.entryconfig(3, state=DISABLED)
			self.temp_entry["state"] = "readonly"
			self.tout_entry["state"] = "readonly"
			
			if self.tout is None:
				self.tout = self.temp
			self.data = Data(self.temp, self.tout, Object.objects, Window.windows)
			Object.objects = []
			Window.windows = []
			self.heatmap = Heatmap(self.data.range, self.data.haswindow)
			self.simulation["image"] = self.heatmap.get(self.data.field)			
			
			self.red["text"] = " = {} K".format(str(round(self.heatmap.red))[:5])
			self.green["text"] = " = {} K".format(str(round(self.heatmap.green))[:5])
			self.blue["text"] = " = {} K".format(str(round(self.heatmap.blue))[:5])
			self.startbutton.config(text="Pause Simulation", command=self.pause, fg="red")
			self.endbutton.config(fg="red", state=NORMAL)
			
			self.ws.write(0,0, "t")
			self.isrunning = True
			self.update_idletasks()
			self.run()
Ejemplo n.º 3
0
 def __init__(self):
     Tk.__init__(self)
     container = self.create_main_container()
     self.set_window_properties()
     self.data = Data(pd.DataFrame())
     self.coordinates = Coordinates()
     self.heatmap = Heatmap()
     self.initialize_pages(container)
     self.show_frame(FirstPage)
     self.protocol("WM_DELETE_WINDOW", self.on_closing)
Ejemplo n.º 4
0
def main():
    os.system('rm -rf graph/ && mkdir graph/')
    models = [
        Model('node2vec', '%s/../../../../node2vec/emb' % c),
        Model('gcn', get_latest_gcn_exp())
    ]
    for dataset in datasets:
        for dim in DIMENSIONS:
            truth = np.load('%s_adj_norm.npy' % dataset)
            Heatmap(truth[0:dim, 0:dim]).getHeatmap('truth_sims_dim_%s' % dim,
                                                    'Adjacency Normalized')
        for model in models:
            model.eval(dataset, truth)
Ejemplo n.º 5
0
def build_heatmap_on_image(image_path, data_file_path, outfile_path, heatmap_settings=None, save_only_heatmap=False):
    if heatmap_settings is None:
        heatmap_settings = {}
    img = Image.open(image_path)
    img.load()
    if heatmap_settings.get('monochrome_image'):
        img = img.convert('L')
    img = img.convert('RGBA')

    coordinates = convert_y_coordinate(read_coordinates(data_file_path), img.size[1])
    if 'single_point_exclude_radius' in heatmap_settings:
        coordinates = filter_single_dots_with_radius(coordinates, heatmap_settings['single_point_exclude_radius'],
                                                     heatmap_settings['required_near_points_in_radius'])

    dotsize = heatmap_settings.get('dotsize', 70)
    hm = Heatmap(libpath=join(dirname(sys.argv[0]), 'cHeatmap-x86.dll'))
    img_heatmap = hm.heatmap(coordinates, size=img.size, area=((0, 0), img.size), dotsize=dotsize, opacity=150)
    img_heatmap = img_heatmap.filter(ImageFilter.GaussianBlur(3))
    if save_only_heatmap:
        img_heatmap.save(outfile_path)
    else:
        out_file = Image.alpha_composite(img, img_heatmap)
        out_file.save(outfile_path)
Ejemplo n.º 6
0
 def _eval(self, file, dataset, truth):
     epoch_str = self._get_epoch_str(file)
     emb = np.load(file)
     sims = self._get_sims(emb, truth)
     sims_, truth_, probs, loss = self._loss(sims, truth)
     loss, probs = sess.run([loss, probs],
                            feed_dict={
                                sims_: sims,
                                truth_: truth
                            })
     print('%s%s loss %s' % (self.name, epoch_str, loss))
     for dim in DIMENSIONS:
         Heatmap(probs[0:dim, 0:dim]).getHeatmap(
             '%s_%s_probs_dim_%s%s' % (self.name, dataset, dim, epoch_str),
             '%s %s embeddings' % (self.name, dataset))
Ejemplo n.º 7
0
def main(args):
    svc = pickle.load(open(args.svc, "rb"))
    scaler = pickle.load(open(args.scaler, "rb"))
    heatmap_history = Heatmap()
    pipeline_partial = partial(pipeline,
                               svc=svc,
                               X_scaler=scaler,
                               orient=orient,
                               pix_per_cell=pix_per_cell,
                               cell_per_block=cell_per_block,
                               spatial_size=spatial_size,
                               hist_bins=hist_bins,
                               heatmap_history=heatmap_history)
    clip1 = VideoFileClip(args.input)
    white_clip = clip1.fl_image(pipeline_partial)
    white_clip.write_videofile(args.output, audio=False)
Ejemplo n.º 8
0
 def __init__(self, sensor_list_filepath, config):
     Heatmap.__init__(self, sensor_list_filepath, config)
     self.heatmap = self.get_heatmap_array()
     self.landing_zone = (0, 0)  # Eventually will look at historical data
     self.previous_point = (0, 0)
Ejemplo n.º 9
0
def detect_vehicles(img, model, scaler):

    import params as p
    import helpers as h
    import cv2 as cv
    import numpy as np
    from heatmap import Heatmap

    # Perform HOG extraction
    print("Extracting HOG features...")
    hog_image = h.hog_extraction(img, p.hog_params)

    window_dims = []
    windows = []

    print("Generating sliding window features...")

    for i in range(len(p.slider_params['sizes'])):
        x = 0
        y = p.slider_params['positions'][i]
        size = p.slider_params['sizes'][i]

        while x + size < img.shape[1]:
            window_dims.append([y, x, size])
            window = hog_image[y:y + size, x:x + size]
            window = cv.resize(window, (80, 80))
            window = window.flatten()

            windows.append(window)
            x += p.slider_params['step']
    window_dims = np.asarray(window_dims)

    # Normalize windows into features
    windows = np.asarray(windows)
    features = scaler.transform(windows)

    # Feed into SVM model and store positive labels
    print("Identifying positive features...")
    results = model.predict(features)

    labels = []
    for i in range(len(results)):
        if int(results[i]) == 1:
            labels.append(i)

    labels = np.asarray(labels)

    # Windows that were all labelled as positive from SVM
    pw = window_dims[labels]

    # Get heatmap using the labels
    hm = Heatmap(img.shape[0], img.shape[1])
    hm.generate(pw)
    heatmap = hm.get().astype('uint8')

    # Perform thresholding on heatmap
    ret, detected = cv.threshold(heatmap, 0, 255,
                                 cv.THRESH_BINARY + cv.THRESH_OTSU)

    # Extract rectangles from threshold
    print('Extracting detected vehicles...')
    contours = cv.findContours(detected, cv.RETR_EXTERNAL,
                               cv.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]

    bboxes = []
    minSize = 80 * 80
    maxSize = 200 * 200

    # Format the rectangles into the bbox label format
    for item in contours:
        x, y, w, h = cv.boundingRect(item)
        if w * h > minSize and w * h < maxSize:
            bbox = {
                'bbox': {
                    'top': y,
                    'left': x,
                    'bottom': y + h,
                    'right': x + w
                }
            }
            bboxes.append(bbox)

    print('Detection completed')
    return bboxes
Ejemplo n.º 10
0
def main():
    parser = argparse.ArgumentParser(description=("Generates a heatmap from "
                                                  "data and displays it"))
    parser.add_argument("-v", "--verbose", action="store_true")
    parser.add_argument("-d", "--dataset")
    parser.add_argument("-m", "--mode")
    parser.add_argument("-nc", "--name_col")
    parser.add_argument("-latc", "--lat_col")
    parser.add_argument("-lonc", "--lon_col")
    parser.add_argument("-vc", "--value_col")
    parser.add_argument("-s", "--scale")
    parser.add_argument("-r", "--radius")
    parser.add_argument("-border", "--border_offset")
    parser.add_argument("-north", "--north_offset")
    parser.add_argument("-south", "--south_offset")
    parser.add_argument("-east", "--east_offset")
    parser.add_argument("-west", "--west_offset")
    parser.add_argument("-cmap", "--colourmap")
    parser.add_argument("-lloc", "--legend_location")
    parser.add_argument("-lfs", "--legend_fontsize")

    args = parser.parse_args()

    dataset = args.dataset
    mode = args.mode.lower() if args.mode else None
    mode = None if mode not in MODES else mode
    name_col = int(args.name_col) if args.name_col else None
    lat_col = int(args.lat_col) if args.lat_col else None
    lon_col = int(args.lon_col) if args.lon_col else None
    value_col = int(args.value_col) if args.value_col else None
    scale = float(args.scale) if args.scale else None
    radius = float(args.radius) if args.radius else None
    border_offset = float(args.border_offset) if args.border_offset else None
    north_offset = float(args.north_offset) if args.north_offset else None
    south_offset = float(args.south_offset) if args.south_offset else None
    east_offset = float(args.east_offset) if args.east_offset else None
    west_offset = float(args.west_offset) if args.west_offset else None
    colourmap = args.colourmap if args.colourmap else None
    legend_location = args.legend_location if args.legend_location else None
    legend_location = None if legend_location not in LEGEND_LOCATIONS else legend_location
    legend_fontsize = int(
        args.legend_fontsize) if args.legend_fontsize else None

    while dataset == None:
        try:
            dataset = input(
                "Which dataset csv file to use? (enter filepath): ")
            verify_dataset(dataset)
        except Exception as err:
            dataset = None
            print("Error: {}. Please try again.".format(err))

    while mode == None:
        try:
            mode = input(("What mode is the map in? Leave blank for default. "
                          "Type 'list' to get a list of the modes: ")).lower()
            if mode == "list":
                mode = None
                print("Available modes: {}\n".format(", ".join(MODES)))
                print("Please refer to the documentation for more details.")
                continue
            if not mode:
                mode = MODES[0]
            elif mode not in MODES:
                raise ValueError("invalid mode")
        except Exception as err:
            mode = None
            print("Error: {}. Please try again.".format(err))

    while name_col == None:
        try:
            name_col = input(
                ("What column are the point names in? "
                 "Leave blank for column {}: ".format(DEFAULT_NAME_COL + 1)))
            name_col = DEFAULT_NAME_COL + 1 if name_col == "" else int(
                name_col)
        except Exception as err:
            name_col = None
            print("Error: {}. Please try again.".format(err))

    while lat_col == None:
        try:
            lat_col = input(
                ("What column are the latitudes in? "
                 "Leave blank for column {}: ".format(DEFAULT_LAT_COL + 1)))
            lat_col = DEFAULT_LAT_COL + 1 if lat_col == "" else int(lat_col)
        except Exception as err:
            lat_col = None
            print("Error: {}. Please try again.".format(err))

    while lon_col == None:
        try:
            lon_col = input(
                ("What column are the longitudes in? "
                 "Leave blank for column {}: ".format(DEFAULT_LON_COL + 1)))
            lon_col = DEFAULT_LON_COL + 1 if lon_col == "" else int(lon_col)
        except Exception as err:
            lon_col = None
            print("Error: {}. Please try again.".format(err))

    while value_col == None:
        try:
            value_col = input(
                ("What column are the values in? "
                 "Leave blank for column {}: ".format(DEFAULT_VALUE_COL + 1)))
            value_col = DEFAULT_VALUE_COL + 1 if value_col == "" else int(
                value_col)
        except Exception as err:
            value_col = None
            print("Error: {}. Please try again.".format(err))

    while scale == None:
        try:
            scale = input(("What is the scale of the map? "
                           "Leave blank for the default value of 0.007 "
                           "(smaller = more fidelity but slower, "
                           "larger = less accurate but faster): "))
            scale = DEFAULT_SCALE if scale == "" else float(scale)
        except Exception:
            scale = None
            print("Please input a valid number.")

    while radius == None:
        try:
            radius = input(("What is the checking radius for the data? "
                            "Leave blank for the default of 0.3 "
                            "(This is based on latitude/longitude degrees "
                            "and determines how far the program will look "
                            "for another point in the area): "))
            radius = DEFAULT_RADIUS if radius == "" else float(radius)
        except Exception:
            radius = None
            print("Please input a valid number.")

    border_mode = None
    if (border_offset == None and north_offset == None and south_offset == None
            and east_offset == None and west_offset == None):
        while border_mode == None:
            try:
                border_mode = input(
                    ("Would you like to specify an offset "
                     "for the entire border, or assign "
                     "specific offset to each side? (type "
                     "'entire', 'specific', 'both', or "
                     "leave blank to pick 'entire'): ")).lower()
                if border_mode and border_mode not in BORDER_MODES:
                    raise ValueError("invalid border mode provided")
                border_mode = BORDER_MODES[
                    0] if border_mode == "" else border_mode
            except Exception as err:
                border_mode = None
                print("Error: {}. Please try again.")

        if border_mode == BORDER_MODES[0] or border_mode == BORDER_MODES[2]:
            while border_offset == None:
                try:
                    border_offset = input(
                        ("What is the border offset of the map? "
                         "Leave blank for default of 0.03: "))
                    border_offset = 0.03 if border_offset == "" else float(
                        border_offset)
                except Exception:
                    border_offset = None
                    print("Please input a valid number.")

        if border_mode == BORDER_MODES[1] or border_mode == BORDER_MODES[2]:
            while north_offset == None:
                try:
                    north_offset = input(("What is the north side offset? "
                                          "Leave blank for 0: "))
                    north_offset = 0 if north_offset == "" else float(
                        north_offset)
                except Exception:
                    north_offset = None
                    print("Please input a valid number.")

            while south_offset == None:
                try:
                    south_offset = input(("What is the south side offset? "
                                          "Leave blank for 0: "))
                    south_offset = 0 if south_offset == "" else float(
                        south_offset)
                except Exception:
                    south_offset = None
                    print("Please input a valid number.")

            while east_offset == None:
                try:
                    east_offset = input(("What is the east side offset? "
                                         "Leave blank for 0: "))
                    east_offset = 0 if east_offset == "" else float(
                        east_offset)
                except Exception:
                    east_offset = None
                    print("Please input a valid number.")

            while west_offset == None:
                try:
                    west_offset = input(("What is the west side offset? "
                                         "Leave blank for 0: "))
                    west_offset = 0 if west_offset == "" else float(
                        west_offset)
                except Exception:
                    west_offset = None
                    print("Please input a valid number.")

    border_offset = 0 if border_offset == None else border_offset
    north_offset = 0 if north_offset == None else north_offset
    south_offset = 0 if south_offset == None else south_offset
    east_offset = 0 if east_offset == None else east_offset
    west_offset = 0 if west_offset == None else west_offset

    heatmap = Heatmap(dataset, mode, name_col - 1, lat_col - 1, lon_col - 1,
                      value_col - 1, scale, radius, border_offset,
                      north_offset, south_offset, east_offset, west_offset,
                      args.verbose)

    heatmap.calculate_grid()

    if mode == MODES[0]:
        while legend_location == None:
            try:
                legend_location = input(("Where should the legend be? "
                                         "Type 'list' to get possible values. "
                                         "Leave blank for default: "))
                if legend_location == "list":
                    legend_location = None
                    print("Possible values are:")
                    print(", ".join(LEGEND_LOCATIONS))
                    continue
                if not legend_location:
                    legend_location = LEGEND_LOCATIONS[0]
                elif legend_location not in LEGEND_LOCATIONS:
                    raise ValueError("invalid location")
            except Exception as err:
                legend_location = None
                print("Error: {}. Please try again.".format(err))

        while legend_fontsize == None:
            try:
                legend_fontsize = input(
                    ("What is the fontsize for the legend? "
                     "Leave blank for 14: "))
                legend_fontsize = 14 if legend_fontsize == "" else int(
                    legend_fontsize)
            except Exception as err:
                legend_fontsize = None
                print("Error: {}. Please try again.")

    elif mode == MODES[1]:
        while colourmap == None:
            try:
                colourmap = input(("Please specify a colourmap. "
                                   "Leave blank for default of viridis: "))
                colourmap = "viridis" if colourmap == "" else colourmap
                get_cmap(colourmap)
            except Exception as err:
                colourmap = None
                print("Error: {}. Please try again.".format(err))

    heatmap.display_map(colourmap, legend_location, legend_fontsize)
Ejemplo n.º 11
0
def create_retail(heatmap_filepath, new_filepath, hotdog_limit):
    hm = Heatmap.load(heatmap_filepath)
    output_json = heatmap_filepath.replace('.heatmap', 'retail.json')
    retail = RetailSuggestion(hm, output_json, hotdog_limit)
    retail.suggestions()
    retail.write_json(new_filepath)
Ejemplo n.º 12
0
#     img[img==grey_val] = 0 # Remove the grey background
#     img[img>0] = 1
#     img = img[::-1,].reshape(img.shape + (1,))

#     global historical_img
#     historical_img = np.concatenate((historical_img, img), axis=2)

# fig, ax = plt.subplots()
# def draw_heatmap(frame_number):
#     heatmap = gaussian_filter(np.sum(historical_img, 2), 1)
#     ax.pcolormesh(heatmap, cmap='seismic', vmin=-historical_img.max(), vmax=historical_img.max(), alpha=0.5)
#     fig.savefig(f"./{output_folder}/colormap_frame_{frame_number}.jpg")
#     ax.clear()

detection_heatmap = Heatmap(floor_depth, floor_width)


def scale_box(box):
    box = list(box)
    box[0] = int(box[0] * scale_w)
    box[2] = int(box[2] * scale_w)
    box[1] = int(box[1] * scale_h)
    box[3] = int(box[3] * scale_h)
    return box


def scale_coords(coords):
    return (int(coords[0] * scale_w), int(coords[1] * scale_h))

Ejemplo n.º 13
0
def estimate_total(heatmap_filepath):
    hm = Heatmap.load(heatmap_filepath)
    return estimate_total_hm(hm)
Ejemplo n.º 14
0
sw = Swarm()
def program_direction(directionimg, center, scale):
	theta = get_direction(directionimg,center,50*scale)
	if theta:
		external_point = (int(center[0]+ math.cos(theta)*100*scale), int(center[1]+scale*100*math.sin(theta)))
		directionimg.drawLine(center,external_point,SimpleCV.Color.YELLOW,2)

while not display.isDone():
	before = time.time()
	if display.mouseRight:
		normaldisplay = not(normaldisplay)
	img = vc.getImage().scale(scale) #.bilateralFilter() #.flipHorizontal()
	directionimg = img.convolve([[-1,4],[-1,1]]).stretch(70,220)

	if not hm:
		hm = Heatmap(img.width, img.height)

	wasps = list(sw.find_wasps(img))
	sw.relation_wasps(wasps)

	procs = []
	for color, circle in wasps:
		center = (circle.x, circle.y)
		#procs.append(Process(target=program_direction, args=(directionimg, center, scale)))
		program_direction(directionimg, center, scale)
		radius = circle.radius()
		img.drawCircle(center, radius,color,min(radius,2))
		hm.addPoint(Point(circle.x,circle.y), 10)

	for p in procs: p.start()
	for p in procs: p.join()
Ejemplo n.º 15
0
 def __init__(self, sensor_list_filepath, smarthome_data_filepath, config):
     Heatmap.__init__(self, sensor_list_filepath, config)
     self._load_from_file(smarthome_data_filepath)
Ejemplo n.º 16
0
def test_include_in_period(manifest, filtered_images):
    hm = Heatmap.new(manifest)
    hm.include_in_period(filtered_images)
    assert hm.period.start == datetime(2018, 3, 23, 21, 15, 26)
    assert hm.period.end == datetime(2018, 3, 23, 21, 15, 40)
Ejemplo n.º 17
0
class MainInterface(Frame):
	"""Main interface in the heat transfer simulation window.
	Inherits from the Tkinter Frame widget.
	
	Widgets in the interface:
		
	self.root
		Class Tk. Root interface of the simulation. Contains the Menu.
		
	self.objectmenu
		Class Menu. Contains the commands to add of modify an object.
		
	self.settemp
		Classe DoubleVar. Variable of the field temperature entry.
		
	self.temp_label
		Class Label. Text indicating to write the field temperature.
	
	self.temp_entry
		Class Entry. Contains the variable representing the initial
		field temperature.
		
	self.settout
		Classe DoubleVar. Variable of the outside temperature entry.
		
	self.tout_label
		Class Label. Text indicating to write the outside temperature.
	
	self.tout_entry
		Class Entry. Contains the variable representing the outside
		temperature.
	
	self.startbutton
		Class Button. Command to start numerical simulation.
		When pressed, changes text and command to pause simulation.
		When paused, changes text and command to resume simulation.
		When simulation is ended, returns to its original function.
		
	self.endbutton
		Class Button. Command to end numerical simulation.
		Disabled until simulation is started.
		
	self.map
		Class PhotoImage. Contains the actual image for the heatmap
		when simulation is not running Used to initialize the map
		and to show objects before simulation starts.
	
	self.simulation
		Class Label. Contains the heatmap as an image.
		Is modified with the appropriate heatmap at each iteration.
		
	self.dimensions
		Label indicating the dimensions of heatmap.
	
	self.temperature
		Label indicating temperature scaling in heatmap, with the
		widgets self.red_image, seld.red, self.green_image,
		self.green, self.blue_image and self.blue.
		
	
	Other attributes:
	
	self.data
		Data instance which contains the temperature field.
		Initialized when simulation starts, deleted when it ends.
	
	self.heatmap
		Heatmap instance which contains the image where a color is
		calculated for each temperature value in the field.
		Initialized when simulation starts, deleted when it ends.
	
	self.isrunning
		Is True if simulation is running, is False otherwise.
		
	self.temp
		Initial temperature of the field. Is None until a suitable
		temperature is set.
		
	self.tout
		Outside temperature. Is None until a suitable temperature is set.
		
	self.wb
		Workbook object used to export data to an Excel file.
	
	self.ws
		Work sheet used to write data in an Excel file.
	
	self.points
		List of followed points. The temperature at each time incrementation
		will be kept in an Excel file if user used the "Export" command.
	

	Methods defined here:
	
	__init__(self, root):
		MainInterface class builder.
		
	_initmenu(self):
		Method to initialize the menu bar of the interface.
	
	_showerror(self, error):
		Used to show any error that the user may encounter.
	
	addobject(self):
		Command of the "Add Object" option in "Object" menu.
		Creates an Object object to support object creation.
		If created, object is shown on the heatmap.
		
	addpoint(self):	
		Asks user to choose a point that will be followed by
		an Excel worksheet.
		
	addwindow(self):
		Command of the "Add Window" option in "Window" menu.
		Creates a Window object to support window creation.
		
	delobject(self, name):
		Deletes an object and erases it from the heatmap.
	
	delwindow(self, name):
		Deletes a window and erases it from the heatmap.
	
	end(self):
		Command of self.endbutton. Used to end simulation.
		Heatmap will be reinitialized and cannot be recovered.
	
	export(self):
		Export the work sheet to an Excel file for further
		data manipulation.
		
	fieldtemp(self, *args):
		Callback method of the field temperature entry.
		Verifies if the entry can be treated as a number.
		
	fill(self, color):
		Fill image with a color = (r, b, g). Used at
		initialization of interface and at end of simulation.
		
	help(self):	
		Command of "Help" in the main menu. Opens a html 
		page with some guidelines on how to use this program.
		
	newpoint(self):
		Adds a new point to ths list of points for which the
		temperature values will be kept in an Excel work sheet.
		
	outsidetemp(self. *args):	
		Callback method of the outside temperature entry.
		Verifies if the entry can be treated as a number.
	
	pause(self):
		Command to pause simulation.
		
	quit(self):
		Method called when the user interface is closed.
	
	resume(self):
		Command to resume simulation.
		
	run(self):
		Iterate numerical data and update heatmap.
		
	showobject(self, object):	
		Show the object on the heatmap.
		
	showwindow(self, window):
		Show the window on the heatmap.
	
	start(self):	
		Default command of self.startbutton. Starts simulation.
		If no object or window is added, raises UniformFieldError.
		Otherwise, creates the data array and the initial heatmap.
		
	todelete_object(self):
		Allows user to choose the object he wants to delete.
		
	todelete_window(self):
		Allows user to choose the window he wants to delete.
	
	tomodify_object(self):
		Allows user to choose the object he wants to modify.
	
	tomodify_window(self):
		Allows user to choose the window he wants to modify.
		
	
	Exceptions handled:
	
	AttributeError
		When user attempts to start simulation without any value
		for the field temperature or the outside temperature.
		
	ValueError
		When the field temperature entry is either physically
		impossible or unsuitable for the simulation.
		
	UniformFieldError
		When user tries to start simulation with no object or window.
	"""
	
	def __init__(self, root):
		"""MainInterface class builder."""
		
		Frame.__init__(self, root)
		
		self.root = root
		self.root.title("Heat Transfer Simulation")
		
		self._initmenu()
		
		self.settemp = StringVar()
		self.temp_label = Label(self, text="Set Temperature in Field : ")
		self.temp_label.grid(row=0, column=1, columnspan=2, sticky=E)
		self.temp_entry = Entry(self, textvariable=self.settemp, width=10)
		self.temp_entry.grid(row=0, column=3, sticky=W)
		self.settemp.trace("w", self.fieldtemp)
		
		self.settout = StringVar()
		self.tout_label = Label(self, text="Set Temperature Outside : ")
		self.tout_label.grid(row=1, column=1, columnspan=2, sticky=E)
		self.tout_entry = Entry(self, textvariable=self.settout, width=10, state=DISABLED)
		self.tout_entry.grid(row=1, column=3, sticky=W)
		self.settout.trace("w", self.outsidetemp)
		
		self.startbutton = Button(self, text="Start Simulation", command=self.start, fg="green", width=13)
		self.startbutton.grid(row=2, column=1)
		self.endbutton = Button(self, text="End Simulation", command=self.end, fg="grey", width=13, state=DISABLED)
		self.endbutton.grid(row=2, column=2, columnspan=2)
		
		self.map = PhotoImage(width=Data.nb_x, height=Data.nb_y)
		self.fill(self.map, (255, 255, 255))
		self.simulation = Label(self, image=self.map)
		self.simulation.grid(row=3, rowspan=4, column=1, columnspan=3)
		
		self.dimensions = Label(self, text="""Dimensions:
		\nx-axis: {} m
		\ny-axis: {} m""".format(Data.dx * Data.nb_x, Data.dy * Data.nb_y))
		self.dimensions.grid(row=0, rowspan=3, column=4)
		
		self.temperature = Label(self, text="Temperature:")
		self.temperature.grid(row=3, column=4)
		self.red_image = PhotoImage(file="/Users/Guy/Desktop/Projets/Python/Heat Transfer Simulations/image/red.gif")
		self.red = Label(self, image=self.red_image, text=" = 0.0 K  ", compound=LEFT)
		self.red.grid(row=4, column=4)
		self.green_image = PhotoImage(file="/Users/Guy/Desktop/Projets/Python/Heat Transfer Simulations/image/green.gif")
		self.green = Label(self, image=self.green_image, text=" = 0.0 K  ", compound=LEFT)
		self.green.grid(row=5, column=4)
		self.blue_image = PhotoImage(file="/Users/Guy/Desktop/Projets/Python/Heat Transfer Simulations/image/blue.gif")
		self.blue = Label(self, image=self.blue_image, text=" = 0.0 K  ", compound=LEFT)
		self.blue.grid(row=6, column=4)
		
		self.grid(sticky=W+E+N+S)
		
		self.isrunnung = False
		self.temp = None
		self.tout = None
		
		self.wb = Workbook()
		self.ws = self.wb.add_sheet("Simulation1")
		self.nb_simulation = 1
		self.points = []
		
	def _initmenu(self):
		"""Method to initialize the menu bar of the interface."""
		
		menubar = Menu(self.root)
		self.root.config(menu=menubar)
		
		self.filemenu = Menu(menubar)
		self.filemenu.add_command(label="Follow Point", underline=7, command=self.addpoint)
		self.filemenu.add_command(label="Export Data", underline=0, command=self.export)
		
		self.objectmenu = Menu(menubar)
		self.objectmenu.add_command(label="Add Object", underline=0, command=self.addobject)
		
		self.windowmenu = Menu(menubar)
		self.windowmenu.add_command(label="Add Window", command=self.addwindow)
		
		menubar.add_cascade(label="File", underline=0, menu=self.filemenu)
		menubar.add_cascade(label="Object", underline=0, menu=self.objectmenu)
		menubar.add_cascade(label="Window", underline=0, menu=self.windowmenu)
		menubar.add_command(label="Help", underline=0, command=self.help)
		
	def _showerror(self, error):
		"""Used to show any error that the user may encounter."""
	
		top = Toplevel()
		top.title("Error")
		
		msg = Message(top, text=error, aspect=500, justify=CENTER)
		msg.grid()
		
		button = Button(top, text="OK", command=top.destroy)
		button.grid()
		
	def addobject(self):
		"""Command of the "Add Object" option in "Object" menu.
		Creates an Object object to support object creation.
		"""
		
		newobj = Object(self)
		newobj.config()
		
	def addpoint(self):
		"""Asks user to choose a point that will be followed.
		Each temperature value of this point will be written in
		an Excel worksheet that can be saved with the "Export"
		command.
		"""
		
		self.top = Toplevel()
		self.top.title("Follow Point")
		
		self.name = StringVar(value="Point{}".format(len(self.points) + 1))
		name_label = Label(self.top, text="Point name:", width=15)
		name_entry = Entry(self.top, textvariable=self.name, width=15)
		name_label.grid(row=0, column=0)
		name_entry.grid(row=0, column=1, columnspan=2)
		
		self.xpos = DoubleVar()
		xpos_label = Label(self.top, text="x-position:", width=20)
		xpos_entry = Entry(self.top, textvariable=self.xpos, width=10)
		xpos_label.grid(row=1, column=0, columnspan=2)
		xpos_entry.grid(row=1, column=2)

		self.ypos = DoubleVar()
		ypos_label = Label(self.top, text="y-position:", width=20)
		ypos_entry = Entry(self.top, textvariable=self.ypos, width=10)
		ypos_label.grid(row=2, column=0, columnspan=2)
		ypos_entry.grid(row=2, column=2)
		
		follow = Button(self.top, text="Follow Point", command=self.newpoint)
		follow.grid(row=3, column=2)
		
	def addwindow(self):
		"""Command of the "Add Window" option in "Window" menu.
		Creates a Window object to support window creation.
		"""
		
		newwindow = Window(self)
		newwindow.config()
		
	def delobject(self, name):
		"""Deletes an object and erases it from the heatmap."""
		
		for object in Object.objects:
			if object["name"] == name:
				i = object["left"]
				while i <= object["right"]:
					self.map.put("white", (i, object["bottom"]))
					self.map.put("white", (i, object["top"]))
					i += 1
				
				j = object["top"]
				while j <= object["bottom"]:
					self.map.put("white", (object["left"], j))
					self.map.put("white", (object["right"], j))
					j += 1
				
				self.simulation["image"] = self.map
				
		Object.objects = [object for object in Object.objects if object["name"] != name]
		
		if Object.objects == []:
			self.objectmenu.delete("Modify Object")
			self.objectmenu.delete("Delete Object")
			
	def delwindow(self, name):
		"""Deletes a window and erases it from the heatmap."""
		
		for window in Window.windows:
			if window["name"] == name:
				if window["side"].lower() == "left" or window["side"].lower() == "right":
					if window["side"].lower() == "left":
						i = 0
					elif window["side"].lower() == "right":
						i = Data.nb_x - 1
					j = window["min"]
					while j <= window["max"]:
						self.map.put("white", (i, j))
						self.map.put("white", (i, j))
						j += 1
			
				elif window["side"].lower() == "top" or window["side"].lower() == "bottom":
					if window["side"].lower() == "top":
						j = 0
					elif window["side"].lower() == "bottom":
						j = Data.nb_y - 1
					i = window["min"]
					while i <= window["max"]:
						self.map.put("blue", (i, j))
						self.map.put("blue", (i, j))
						i += 1
		
		Window.windows = [window for window in Window.windows if window["name"] != name]
		
		if Window.windows == []:
			self.windowmenu.delete("Modify Window")
			self.windowmenu.delete("Delete Window")
	
	def end(self):
		"""Command of self.endbutton. Used to end simulation.
		Heatmap will be reinitialized and cannot be recovered.
		"""
	
		self.isrunning = False
		self.points = []
		del self.data
		del self.heatmap

		self.nb_simulation += 1
		self.ws = self.wb.add_sheet("Simulation{}".format(self.nb_simulation))
		
		self.temp = None
		self.tout = None
		self.settemp.set("")
		self.settout.set("")
		self.temp_entry["state"] = NORMAL
		self.tout_entry["state"] = DISABLED
		self.endbutton.config(fg="grey", state=DISABLED)
		self.startbutton.config(text="Start Simulation", command=self.start, fg="green")
		self.objectmenu.entryconfig(1, state=NORMAL)
		self.windowmenu.entryconfig(1, state=NORMAL)
		
		try:
			self.objectmenu.delete("Modify Object")
			self.objectmenu.delete("Delete Object")
			self.windowmenu.delete("Modify Window")
			self.windowmenu.delete("Delete Window")
		except TclError:
			pass
		
		self.map = PhotoImage(width=Data.nb_x, height=Data.nb_y)
		self.fill(self.map, (255, 255, 255))
		self.simulation["image"] = self.map
		
	def export(self):
		"""Export the work sheet to an Excel file for further
		data manipulation."""
		
		filename = str(randint(1, 9999999999))
		self.wb.save(filename + ".xls")
		
	def fieldtemp(self, *args):
		"""Callback method of the field temperature entry.
		Verifies if the entry can be treated as a number.
		"""
		
		try:
			temp = float(self.settemp.get())
			assert temp >= 0
			
		except ValueError:
			if self.settemp.get() is "" or self.settemp.get() is "-":
				pass
			else:
				try:
					raise ValueError("Field temperature must be an integer or decimal number.")
				except ValueError as error:
					self._showerror(error)
		
		except AssertionError:
			try:
				raise ValueError("Field temperature must be in Kelvin and no less than absolute zero.")
			except ValueError as error:
				self._showerror(error)
		
		else:
			self.temp = temp
		
	def fill(self, image, color):
		"""Fill image with a color in (r, g, b) format. Used at
		initialization of interface and at end of simulation.
		"""
	
		r, g, b = color
		width = image.width()
		height = image.height()
		hexcode = "#%02x%02x%02x" % (r, g, b)
		horizontal_line = "{" + " ".join([hexcode] * width) + "}"
		image.put(" ".join([horizontal_line] * height))
		
	def help(self):
		"""Command of "Help" in the main menu. Opens a html 
		page with some guidelines on how to use this program.
		"""
		
		webbrowser.open("file://" + os.path.realpath("help.html"))
		
	def newpoint(self):
		"""Adds a new point to ths list of points for which the
		temperature values will be kept in an Excel work sheet.
		"""
		
		name = self.name.get()
		
		try:
			xpos = self.xpos.get()
			ypos = self.ypos.get()
			ipos = round(xpos/Data.dx)
			jpos = Data.nb_y - round(ypos/Data.dy)
			
			if not 0 <= ipos < Data.nb_x or not 0 <= jpos < Data.nb_y:
				raise HeatmapError("The point {} must be in the visible heatmap.".format(name))
					
		except TclError:
			try:
				raise ValueError("The x- and y- positions of point {} need to be integers or decimal numbers.".format(name))
			except ValueError as error:
				self._showerror(error)
				
		except HeatmapError as error:
			self._showerror(error)
			
		else:
			self.ws.write(0, len(self.points) + 1, name)
			self.points.append((ipos, jpos))
			self.top.destroy()
		
	def outsidetemp(self, *args):
		"""Callback method of the outside temperature entry.
		Verifies if the entry can be treated as a number.
		"""
		
		try:
			tout = float(self.settout.get())
			assert tout >= 0
			
		except ValueError:
			if self.settout.get() is "" or self.settout.get() is "-":
				pass
			else:
				try:
					raise ValueError("Outside temperature must be an integer or decimal number.")
				except ValueError as error:
					self._showerror(error)
		
		except AssertionError:
			try:
				raise ValueError("Outside temperature must be in Kelvin and no less than absolute zero.")
			except ValueError as error:
				self._showerror(error)
		
		else:
			self.tout = tout
	
	def pause(self):
		"""Command to pause simulation."""
		
		self.isrunning = False
		self.startbutton.config(text="Resume Simulation", command=self.resume, fg="green")
		
	def quit(self):
		"""Method called when the user interface is closed."""
		
		self.wb.close()
		Misc.quit(self)
		
	def resume(self):
		"""Command to resume simulation."""
	
		self.isrunning = True
		self.startbutton.config(text="Pause Simulation", command=self.pause, fg="red")
		self.run()
		
	def run(self):
		"""Iterate numerical data and update heatmap."""
		
		n = 1
		while self.isrunning:
			self.ws.write(n, 0, n * Data.dt)
			for i, p in enumerate(self.points):
				self.ws.write(n, i + 1, self.data.field[p[1]][p[0]])
			self.data.iterate()
			self.simulation["image"] = self.heatmap.get(self.data.field)
			self.update()
			n += 1
			
	def showobject(self, object):
		"""Show the object on the heatmap."""
		
		if Object.objects == []:
				self.objectmenu.add_command(label="Modify Object", underline=0, command=self.tomodify_object)
				self.objectmenu.add_command(label="Delete Object", underline=0, command=self.todelete_object)
			
		i = object["left"]
		while i <= object["right"]:
			self.map.put("red", (i, object["bottom"]))
			self.map.put("red", (i, object["top"]))
			i += 1
				
		j = object["top"]
		while j <= object["bottom"]:
			self.map.put("red", (object["left"], j))
			self.map.put("red", (object["right"], j))
			j += 1
				
		self.simulation["image"] = self.map
		
	def showwindow(self, window):
		"""Show the window on the heatmap."""
		
		if Window.windows == []:
				self.windowmenu.add_command(label="Modify Window", command=self.tomodify_window)
				self.windowmenu.add_command(label="Delete Window", command=self.todelete_window)
				self.tout_entry["state"] = NORMAL
			
		if window["side"].lower() == "left" or window["side"].lower() == "right":
			if window["side"].lower() == "left":
				i = 0
			elif window["side"].lower() == "right":
				i = Data.nb_x - 1
			j = window["min"]
			while j <= window["max"]:
				self.map.put("blue", (i, j))
				self.map.put("blue", (i, j))
				j += 1
			
		elif window["side"].lower() == "top" or window["side"].lower() == "bottom":
			if window["side"].lower() == "top":
				j = 0
			elif window["side"].lower() == "bottom":
				j = Data.nb_y - 1
			i = window["min"]
			while i <= window["max"]:
				self.map.put("blue", (i, j))
				self.map.put("blue", (i, j))
				i += 1
				
		self.simulation["image"] = self.map
	
	def start(self):
		"""Default command of self.startbutton. Starts simulation.
		If no object has been added by user, raises NoObjectError.
		Otherwise, creates the data array and the initial heatmap.
		"""
		
		if Object.objects == [] and Window.windows == []:
			try:
				raise UniformFieldError("At least one object or window must be added to start simulation.")
			except UniformFieldError as error:
				self._showerror(error)
		
		elif self.temp is None:
			try:
				raise AttributeError("Value not found for the field temperature.")
			except AttributeError as error:
				self._showerror(error)
		
		elif self.tout is None and Window.windows != []:
			try:
				raise AttributeError("Value not found for the outside temperature.")
			except AttributeError as error:
				self._showerror(error)
		
		else:
			self.objectmenu.entryconfig(1, state=DISABLED)
			self.objectmenu.entryconfig(2, state=DISABLED)
			self.objectmenu.entryconfig(3, state=DISABLED)
			self.windowmenu.entryconfig(1, state=DISABLED)
			self.windowmenu.entryconfig(2, state=DISABLED)
			self.windowmenu.entryconfig(3, state=DISABLED)
			self.temp_entry["state"] = "readonly"
			self.tout_entry["state"] = "readonly"
			
			if self.tout is None:
				self.tout = self.temp
			self.data = Data(self.temp, self.tout, Object.objects, Window.windows)
			Object.objects = []
			Window.windows = []
			self.heatmap = Heatmap(self.data.range, self.data.haswindow)
			self.simulation["image"] = self.heatmap.get(self.data.field)			
			
			self.red["text"] = " = {} K".format(str(round(self.heatmap.red))[:5])
			self.green["text"] = " = {} K".format(str(round(self.heatmap.green))[:5])
			self.blue["text"] = " = {} K".format(str(round(self.heatmap.blue))[:5])
			self.startbutton.config(text="Pause Simulation", command=self.pause, fg="red")
			self.endbutton.config(fg="red", state=NORMAL)
			
			self.ws.write(0,0, "t")
			self.isrunning = True
			self.update_idletasks()
			self.run()
			
	def todelete_object(self):
		"""Allows user to choose the object he wants to delete."""
		
		newobj = Object(self)
		
		newobj.top = Toplevel()
		newobj.top.title("Delete Object")
		
		text = Label(newobj.top, text="Which object do you want to delete?")
		text.pack()
		
		def choose():
			delete_button["state"] = NORMAL
		
		newobj.name = StringVar()
		for object in Object.objects:
			radio = Radiobutton(newobj.top, text=object["name"], variable=newobj.name, value=object["name"], command=choose)
			radio.pack()
		
		delete_button = Button(newobj.top, text="Delete Object", command=newobj.delete, state=DISABLED)
		delete_button.pack()
		
	def todelete_window(self):
		"""Allows user to choose the window he wants to delete."""
		
		newwindow = Window(self)
		
		newwindow.top = Toplevel()
		newwindow.top.title("Delete Window")
		
		text = Label(newwindow.top, text="Which window do you want to delete?")
		text.pack()
		
		def choose():
			modify_button["state"] = NORMAL
		
		newwindow.name = StringVar()
		for window in Window.windows:
			radio = Radiobutton(newwindow.top, text=window["name"], variable=newwindow.name, value=window["name"], command=choose)
			radio.pack()
		
		modify_button = Button(newwindow.top, text="Delete Window", command=newwindow.delete, state=DISABLED)
		modify_button.pack()
	
	def tomodify_object(self):
		"""Allows user to choose the object he wants to modify."""
		
		newobj = Object(self)
		
		newobj.top = Toplevel()
		newobj.top.title("Modify Object")
		
		text = Label(newobj.top, text="Which object do you want to modify?")
		text.pack()
		
		def choose():
			modify_button["state"] = NORMAL
		
		newobj.name = StringVar()
		for object in Object.objects:
			radio = Radiobutton(newobj.top, text=object["name"], variable=newobj.name, value=object["name"], command=choose)
			radio.pack()
		
		modify_button = Button(newobj.top, text="Modify Object", command=newobj.modify, state=DISABLED)
		modify_button.pack()
		
	def tomodify_window(self):
		"""Allows user to choose the window he wants to modify."""
		
		newwindow = Window(self)
		
		newwindow.top = Toplevel()
		newwindow.top.title("Modify Window")
		
		text = Label(newwindow.top, text="Which window do you want to modify?")
		text.pack()
		
		def choose():
			modify_button["state"] = NORMAL
		
		newwindow.name = StringVar()
		for window in Window.windows:
			radio = Radiobutton(newwindow.top, text=window["name"], variable=newwindow.name, value=window["name"], command=choose)
			radio.pack()
		
		modify_button = Button(newwindow.top, text="Modify Window", command=newwindow.modify, state=DISABLED)
		modify_button.pack()