import socket

from eventlet.event import Event
from eventlet.greenpool import GreenPool
import eventlet
import pytest

from kombu import Connection

from nameko import exceptions
from nameko import service
from nameko.testing import TestProxy
from nameko.timer import timer

def test_service(get_connection):
    class Controller(object):
        def test_method(self, context, foo):
            return foo + 'spam'

    srv = service.Service(
        Controller, connection_factory=get_connection,
        exchange='testrpc', topic='test', )
    srv.start()
    eventlet.sleep()

    try:
        test = TestProxy(get_connection, timeout=3).test
        ret = test.test_method(foo='bar')

        assert ret == 'barspam'
    finally:
        srv.kill()

def test_service_socket_error():

    class FailConnection(Connection):
        # a connection that will give a socket.error
        # when the service starts
        def drain_events(self, *args, **kwargs):
            raise socket.error

    def get_connection():
        return FailConnection(transport='memory')

    class Controller(object):
        def test_method(self, context, foo):
            return foo + 'spam'

    srv = service.Service(
        Controller, connection_factory=get_connection,
        exchange='testrpc', topic='test', )

    try:
        srv.start()
        eventlet.sleep()
        with pytest.raises(socket.error):
            # we expect that a socket.error has been raised
            # within the startup greenthread
            # calling .wait() should raise this returned error
            srv.greenlet.wait()

    finally:
        srv.kill()

def test_service_doesnt_exhaust_pool(get_connection):
    POOLSIZE = 10

    class Controller(object):
        def test_method(self, context, foo):
            return foo + 'spam'

    srv = service.Service(
        Controller, connection_factory=get_connection,
        exchange='testrpc', topic='test', poolsize=POOLSIZE)
    srv.start()
    eventlet.sleep()

    try:
        with eventlet.Timeout(10):
            for i in range(POOLSIZE * 2):
                test = TestProxy(get_connection, timeout=3).test
                test.test_method(foo='bar')

    finally:
        srv.kill()

def test_exceptions(get_connection):
    class Controller(object):
        def test_method(self, context, **kwargs):
            raise KeyError('foo')

    srv = service.Service(
        Controller, connection_factory=get_connection,
        exchange='testrpc', topic='test', )
    srv.start()
    eventlet.sleep()

    try:
        test = TestProxy(get_connection, timeout=3).test
        with pytest.raises(exceptions.RemoteError):
            test.test_method()

        with pytest.raises(exceptions.RemoteError):
            test.test_method_does_not_exist()
    finally:
        srv.kill()

def test_service_wait(get_connection):
    # TODO: this is a coverage test,
    #       I am not sure the behavior we test is actually what we want.

    spam_continue = Event()
    spam_called = Event()

    class Foobar(object):
        def spam(self, context, **kwargs):
            spam_called.send(1)
            # lets wait until we are told to stop,
            # pretending we are working really hard
            spam_continue.wait()

    srv = service.Service(
        Foobar, connection_factory=get_connection,
        exchange='testrpc', topic='test', )

    srv.start()
    eventlet.sleep()

    try:
        with eventlet.timeout.Timeout(5):
            foobar = TestProxy(get_connection, timeout=3).test
            # lets make sure we actually have a worker currently
            # processing an RPC call
            rpc_call = eventlet.spawn(foobar.spam)
            spam_called.wait()

            # we are in the middle of an RPC call, this will make sure
            # that wait() will have to wait for the worker and the queue
            kill_thread = eventlet.spawn(srv.kill)
            # Let the worker finish it's job
            spam_continue.send(1)
            rpc_call.wait()
            kill_thread.wait()

    except eventlet.timeout.Timeout as t:
        pytest.fail('waiting for death of service timed out: {}'.format(t))
    finally:
        srv.kill()

def test_service_wait_consumer_dies(get_connection):
    srv = service.Service(
        object, connection_factory=get_connection,
        exchange='testrpc', topic='test', )

    srv.start()
    eventlet.sleep()
    srv.greenlet.kill()
    # we don't expect any errors while waiting
    srv.kill()

def test_service_cancells_timers(get_connection):
    timer_evt = Event()

    class Foobar(object):
        @timer(0)
        def shrub(self):
            try:
                timer_evt.send(True)
            except:
                pass

    srv = service.Service(
        Foobar, connection_factory=get_connection,
        exchange='testrpc', topic='test', )

    srv.start()
    # wait for the timer to be called once
    timer_evt.wait()
    # this should stop the timers and we should not get any errors
    srv.kill()
    assert len(srv._timers) == 0

def test_service_link(get_connection):
    srv = service.Service(
        object, connection_factory=get_connection,
        exchange='testrpc', topic='test', )

    srv.start()

    complete_called = []

    def complete(gt, spam, foo):
        assert spam == 'spam'
        assert foo == 'bar'
        assert gt == srv.greenlet
        complete_called.append(True)

    srv.link(complete, 'spam', foo='bar')

    srv.kill()

    assert complete_called == [True]

def test_service_cannot_be_started_twice(get_connection):
    srv = service.Service(
        object, connection_factory=get_connection,
        exchange='testrpc', topic='test')

    srv.start()
    with pytest.raises(RuntimeError):
        srv.start()

    srv.kill()

def test_service_requeues_if_out_of_workers(get_connection):
    foobar_continue = Event()
    foobar_called = Event()

    class Foobar(object):
        def spam(self, context):
            foobar_called.send(True)
            with eventlet.Timeout(2):
                foobar_continue.wait()

    s1 = service.Service(
        Foobar, connection_factory=get_connection,
        exchange='testrpc', topic='test', poolsize=1)

    s1.start()
    eventlet.sleep()

    foobar = TestProxy(get_connection, timeout=3).test

    w1 = eventlet.spawn(foobar.spam)
    foobar_called.wait()
    # the servcie should now be busy and requeue the next request
    w2 = eventlet.spawn(foobar.spam)
    eventlet.sleep()

    # we create a second service to pick up the message
    spam_received = Event()

    class Spam(object):
        def spam(self, context):
            spam_received.send(True)

    s2 = service.Service(
        Spam, connection_factory=get_connection,
        exchange='testrpc', topic='test', poolsize=1)

    s2.start()
    eventlet.sleep()
    # wait for the 2nd service to pick up the message
    with eventlet.Timeout(2):
        assert spam_received.wait()

    # be nice to the first service and tell it to stop being busy
    foobar_continue.send(True)

    w1.wait()
    w2.wait()
    s1.kill()
    s2.kill()

def test_service_custom_pool(get_connection):
    class Foobar(object):
        def spam(self, context, **kwargs):
            pass

    class MyPool(object):
        _pool = GreenPool(size=10)
        count = 0

        def spawn(self, *args, **kwargs):
            self.count += 1
            return self._pool.spawn(*args, **kwargs)

        def waitall(self):
            return self._pool.waitall()

        @property
        def size(self):
            return self._pool.size

        def free(self):
            return self._pool.free()

        def running(self):
            return self._pool.running()

    pool = MyPool()
    srv = service.Service(
        Foobar, connection_factory=get_connection,
        exchange='testrpc', topic='test', pool=pool)

    srv.start()
    srv.consume_ready.wait()

    foobar = TestProxy(get_connection, timeout=3).test
    foobar.spam()

    srv.kill()
    assert pool.count == 1

def test_force_kill(get_connection):
    spam_continue = Event()
    spam_called = Event()

    class Foobar(object):
        def spam(self, context):
            spam_called.send(1)
            spam_continue.wait()

    srv = service.Service(
        Foobar, connection_factory=get_connection,
        exchange='testrpc', topic='test', poolsize=1)
    srv.start()
    eventlet.sleep()

    foobar = TestProxy(get_connection, timeout=3).test
    eventlet.spawn(foobar.spam)

    spam_called.wait()
    # spam will not complete, so we force it
    srv.kill(force=True)

    assert srv.greenlet.dead

def test_force_kill_no_workers(get_connection):
    spam_continue = Event()
    spam_called = Event()

    class Foobar(object):
        def spam(self, context):
            spam_called.send(1)
            spam_continue.wait()

    srv = service.Service(
        Foobar, connection_factory=get_connection,
        exchange='testrpc', topic='test', poolsize=1)
    srv.start()
    eventlet.sleep()

    foobar = TestProxy(get_connection, timeout=3).test
    eventlet.spawn(foobar.spam)

    spam_called.wait()
    spam_continue.send(2)
    # spam has completed - but force anyway
    srv.kill(force=True)

    assert srv.greenlet.dead

def test_service_dos(get_connection):
    spam_continue = Event()
    spam_called = Event()

    class Foobar(object):
        def spam(self, context, do_wait=True):
            if do_wait:
                spam_called.send(1)
                spam_continue.wait()

    s1 = service.Service(
        Foobar, connection_factory=get_connection,
        exchange='testrpc', topic='test', poolsize=1)
    s1.start()
    eventlet.sleep()

    foobar = TestProxy(get_connection, timeout=10).test
    # lets call spam such that it will block until we tell it to continue
    spam_call_1 = eventlet.spawn(foobar.spam, do_wait=True)
    eventlet.sleep()
    spam_called.wait()

    # At this point we will have exhausted it's prefetch count and worker-pool
    # s1 should not accept any more RPCs as it is busy processing spam().
    # Lets kick off two more RPC anyways, which should just wait in the queue
    spam_call_2 = eventlet.spawn(foobar.spam, do_wait=False)
    spam_call_3 = eventlet.spawn(foobar.spam, do_wait=False)
    eventlet.sleep()

    # lets fire up another service, which should take care of the 2 extra calls
    s2 = service.Service(
        Foobar, connection_factory=get_connection,
        exchange='testrpc', topic='test')

    s2.start()
    s2.consume_ready.wait()
    eventlet.sleep()

    try:
        with eventlet.timeout.Timeout(5):
            # as soon as s2 is up and running, the 2 extra calls should
            # get a reply
            spam_call_2.wait()
            spam_call_3.wait()

            # we can let the first call continue now
            spam_continue.send(1)
            spam_call_1.wait()
    except eventlet.timeout.Timeout as t:
        pytest.fail('waiting for 2nd server timed out: {}'.format(t))
    finally:
        s1.kill()
        s2.kill()


from bson.objectid import ObjectId
from datetime import timedelta
from datetime import datetime

# def map_dict_by_class(clazz, dictionary):
#     """ function to map dictionary values into class member variables
#         clazz: a class instance
#         dictionary: a dict containing the variables to be assigned
#         return: a dict with mapped key and values based on the clazz
#     """
#
#     if not (isinstance(clazz, object) and isinstance(dictionary, dict)):
#         return
#     # obtain a list of class members for table fields
#     members = [attr for attr in dir(clazz) if not callable(attr) and not attr.startswith("__") and not attr.startswith("_") and attr != "metadata" or attr == '_id']
#     # print 'member length: {}'.format(len(members))
#     # print members
#     new_dict = {}
#     for m in members:
#         if m in dictionary.keys():
#             if isinstance(dictionary[m], list):
#                 new_dict[m] = '
'.join(map(str, dictionary[m]))
#             elif isinstance(dictionary[m], dict):
#                 new_dict[m] = '
'.join(['%s:: %s' % (str(key), str(value)) for (key, value) in dictionary[m].items()])
#             else:
#                 new_dict[m] = dictionary[m]
#
#     # print 'new dictionary length: {}'.format(len(new_dict))
#
#     return new_dict

def clean_data(dictionary, keys):
    """ function to clean and transform data
        doc_list: a list containing all the documents from mongodb
        doc_keys: a list of keys to be transformed
        return: a dict after cleaning
    """
    if dictionary is None or len(dictionary) == 0:
        return

    if keys is None or len(keys) == 0:
        return

    for key in keys:
        if key == '_id': # Transform Object_id
            dictionary[key] = str(dictionary[key])
        else: # timestamp(2016-07-21T13:55:46-05:00)
            dictionary[key] = dictionary[key].split('T')[0] if dictionary.get(key, None) is not None else None

    return dictionary

def get_objectid_1st_weekday():
    """ function to generate the ObjectId of the first day of the current week.
        return: a string ObjectId like '5774edbd0000000000000000'.
    """
    today = datetime.now()
    # isocalendar outputs year, week of year, and day of week. dow is Mon = 1, Sat = 6, Sun = 7
    year, week, dow = today.isocalendar()
    # get the start day of the week
    start_date = today - timedelta(dow)

    return ObjectId.from_datetime(start_date)

def map_dict_by_class(clazz, map_obj, date_list):
    """ function to clean and map a dict by target class
        clazz: a class for mapping
        map_obj: a json or dict object from mongodb
        date_list: date key to be transformed
        return: a cleaned dict for one specific clazz
    """
    if clazz is None or  map_obj is None:
        return

    # clean date format
    if isinstance(date_list, list) and len(date_list) > 0:
        map_obj = clean_data(dict(map_obj), date_list)

    # obtain a list of class members for table fields
    members = [attr for attr in dir(clazz) if not callable(attr) and not attr.startswith("__") and not attr.startswith("_") and attr != "metadata" or attr == '_id']

    # map a new dict by class
    new_dict = {}
    for m in members: # loop the attributes in the clazz
        if m in map_obj.keys():
            if isinstance(map_obj[m], list): # handle list value
                new_dict[m] = '
'.join(map(str, map_obj[m]))
            elif isinstance(map_obj[m], dict): # handle dict value
                new_dict[m] = '
'.join(['%s:: %s' % (str(key), str(value)) for (key, value) in map_obj[m].items()])
            else:
                new_dict[m] = map_obj[m]
    return new_dict

def sub_dict_list(map_obj, one2many, group_key):
    """ function to sub-select dictionary list
        map_obj: a json or dict object
        one2many: foreign key mapping, one to many
        group_key: the key to access the main data
        return: a dictionary
    """
    if map_obj is None:
        return

    fk = {one2many.values()[0]:map_obj.get(one2many.keys()[0], None)} if one2many is not None else None
    timestamp = ({'_id':map_obj.get('_id', None)})

    if group_key:
        nested_data = map_obj.get(group_key, None)
        if isinstance(nested_data, dict):
            if fk is not None:
                nested_data.update(fk)
            nested_data.update(timestamp)
            return nested_data
        elif isinstance(nested_data, list):
            nested_list = []
            for i in nested_data:
                if fk is not None:
                    i.update(fk)
                i.update(timestamp)
                nested_list.append(i)
            return nested_list
        else:
            return
    else:
        if fk is not None:
            map_obj.update(fk)
        return map_obj


# -*- coding:utf-8 -*-

from api.api import API
from pages.ios.common.superPage import SuperPage
from pages.ios.ffan.hui_life_page_configs import HuiLifePageConfigs

HLPC = HuiLifePageConfigs()

class HuiLifePage(SuperPage):
    '''
    作者 宋波
    首页=>惠生活页面
    '''

    def __init__(self, testcase, driver, logger):
        super(HuiLifePage, self).__init__(testcase,
                                          driver,
                                          logger)

    def validSelf(self):
        '''
        usage: 验证惠生活界面
        '''

        API().assertElementByName(self.testcase, self.driver, self.logger,
                                  HuiLifePageConfigs.resource_id_taking_taxi_st,
                                  HuiLifePageConfigs.assert_view_timeout)

    def clickOnAndValidByXpathAndName(self, viewXpath, validValue):
        '''
        usage: 点击一个控件，并验证是否点击正确。
        '''

        print("KEYWORDS: %s" % validValue)
        API().clickElementByXpath(self.testcase, self.driver, self.logger, viewXpath,
                                  HuiLifePageConfigs.click_on_button_timeout)
        API().waitBySeconds(10)
        if u"加油" == validValue:
            # API.assertElementByXpath(self.testcase,self.driver,self.logger,
            #                          "//UIAApplication[1]/UIAWindow[1]/UIAScrollView[1]/UIAWebView[1]/UIAStaticText[1]")
            API().assertElementByXpath(self.testcase, self.driver, self.logger,
                                       HuiLifePageConfigs.xpath_jiayou,
                                       HuiLifePageConfigs.assert_view_timeout)
        else:
            API().assertElementByName(self.testcase, self.driver, self.logger, validValue,
                                              HuiLifePageConfigs.assert_view_timeout)
        if u"滴滴出行" == validValue:
            tempXpath = "//UIAApplication[1]/UIAWindow[1]/UIAButton[1]"
        else:
            tempXpath = "//UIAApplication[1]/UIAWindow[1]/UIANavigationBar[1]/UIAButton[2]"

        API().clickBackKeyForIos(self.testcase, self.driver, self.logger, tempXpath,
                                 HuiLifePageConfigs.click_on_button_timeout)

    def clickOnActivity(self):
        '''
        usage: 点击活动
        '''
        API().clickElementByText(self.testcase,
                                 self.driver,
                                 self.logger,
                                 HLPC.text_activity_button,
                                 HLPC.click_on_button_timeout);

    def clickOnPrivilege(self):
        '''
        usage: 点击优惠
        '''
        API().clickElementByText(self.testcase,
                                 self.driver,
                                 self.logger,
                                 HLPC.text_privilege_button,
                                 HLPC.click_on_button_timeout);

    def clickOnSpecificActivity(self):
        '''
        usage: 点击特别活动按钮
        '''
        API().clickElementByName(self.testcase,
                                 self.driver,
                                 self.logger,
                                 HLPC.resource_id_specific_activity_button,
                                 HLPC.click_on_button_timeout);

    def clickOnSpecificPrivilege(self):
        '''
        usage: 点击特权
        '''
        API().clickElementByName(self.testcase,
                                 self.driver,
                                 self.logger,
                                 HLPC.resource_id_specific_privilege_button,
                                 HLPC.click_on_button_timeout);

    def clickOnResourceNiche(self):
        '''
        usage: 点击资源位
        '''
        API().clickElementByName(self.testcase,
                                 self.driver,
                                 self.logger,
                                 HLPC.resource_id_resource_niche_button,
                                 HLPC.click_on_button_timeout)

    def clickOnTaxi(self):
        '''
        usage: 点击打车
        '''
        API().clickElementByText(self.testcase,
                                         self.driver,
                                         self.logger,
                                         HLPC.text_taxi,
                                         HLPC.click_on_button_timeout)

    def clickOnJingxuan(self):
        '''
        usage: 点击精选,验证精选页面加载
        '''
        API().clickElementByName(self.testcase,
                                 self.driver,
                                 self.logger,
                                 HLPC.name_jingxuan,
                                 HLPC.click_on_button_timeout)

        API().assertElementByXpath(self.testcase, self.driver, self.logger,
                                   HuiLifePageConfigs.xpath_jingxuan_title,
                                   HuiLifePageConfigs.assert_view_timeout)

    def clickOnJiandian(self):
        '''
        usage: 点击推荐店,验证精选页面加载
        '''
        API().clickElementByName(self.testcase,
                                 self.driver,
                                 self.logger,
                                 HLPC.name_jiandian,
                                 HLPC.click_on_button_timeout)

        API().assertElementByXpath(self.testcase, self.driver, self.logger,
                                   HuiLifePageConfigs.xpath_jiandian_title,
                                   HuiLifePageConfigs.assert_view_timeout)

if __name__ == '__main__':
    pass


# a host we can connect into to debug code
import struct
import threading
from queue import Queue
from socket import socket, AF_INET, SOCK_STREAM, gethostname, timeout
from SocketServer.MessagePack import MessagePack, MsgType, get_bytes, Header, build_from_bytes
from SocketServer.QueueMessage import QueueMessage

class DebuggerHost(threading.Thread):

    def __init__(self, socket_server):

        # Call the supers init function
        threading.Thread.__init__(self)
        self.running = False
        self.socket_server= socket_server

    def run(self):
        self.running = True
        # Setup socket
        sock = socket(AF_INET, SOCK_STREAM)
        sock.settimeout(2)
        sock.bind((gethostname(), 555))
        sock.listen(5)
        client_socket, address = None, None
        while True:
            try:
                client_socket, address = sock.accept()
            except timeout:
                continue
            print("Debugger connected!")
            break

        while self.running:
            # receive the message bytes
            msg_bytes = client_socket.recv(1024)
            # Decode the message
            msg = msg_bytes.decode("utf-8")

            # Do reply stuff here
            if msg == 'getNodeList':
                print(self.socket_server.node_list)

        self.break_down()

    def set_running(self, option: bool):
        self.running = option

    def break_down(self):
        print("Breaking down thread: " + self.name)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 13 19:34:06 2021

@author: leichen
"""
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Feb  5 13:48:23 2021

@author: leichen
"""
import copy
import pickle
from pathlib import Path
import numpy as np
from tqdm import tqdm
from nuscenes.utils.data_classes import LidarPointCloud, RadarPointCloud, Box
from nuscenes.nuscenes import NuScenes
from pyquaternion import Quaternion
from nuscenes.utils.geometry_utils import view_points, box_in_image, BoxVisibility, transform_matrix
from nuscenes.nuscenes import NuScenesExplorer
import matplotlib.pyplot as plt
import os.path as osp
from PIL import Image
from nuscenes.utils.geometry_utils import points_in_box
from nuscenes.utils.data_classes import Box
import random

###########################
from typing import Tuple, List, Iterable

FLAG_FIGURE=True

def find_ghost_target( points_radar, points_lidar,mask_GT
        ) -> Tuple:
    points_ghost_radar= np.zeros_like(points_radar)

    for i in range (points_radar.shape[1]):
        np_min_dis= np.zeros((2,points_lidar.shape[1]))
        np_min_dis_x= np.zeros((2,points_lidar.shape[1]))
        np_min_dis_y= np.zeros((2,points_lidar.shape[1]))
        np_min_dis_x[0,:]= points_lidar[0,:]-points_radar[0,i]
        np_min_dis_y[1,:]= points_lidar[1,:]-points_radar[1,i]
        np_min_dis= np.sqrt(np_min_dis_x[0,:]*np_min_dis_x[0,:]+np_min_dis_y[1,:]*np_min_dis_y[1,:])
        # dist = np.linalg.norm(points_lidar[:2,:]-points_radar[:2,i])
        min_dis= np.amin(np_min_dis)
        if min_dis>1.5:
            points_ghost_radar[:,i]=points_radar[:,i]

    mask_lidar = np.ones(points_radar.shape[1], dtype=bool)
    mask_lidar = np.logical_and(mask_lidar, points_ghost_radar[0, :] !=0)
    mask_No_GT=np.logical_not(mask_GT)
    mask = np.logical_and(mask_lidar, mask_No_GT)
    if FLAG_FIGURE:

        n_wrong_point = random.randint(1,15)
        for i in range(n_wrong_point):
            wrong_pos=random.randint(1,len(mask)-1)
            if mask[wrong_pos]==True:
                mask[wrong_pos]=False
            else:
                mask[wrong_pos]=True

    points_ghost_radar = points_radar[:, mask]
    return points_ghost_radar,mask

def map_pointcloud_to_image(pointsensor_token: str,
                                camera_token: str,
                                min_dist: float = 1.0,
                                render_intensity: bool = False,
                                show_lidarseg: bool = False,
                                filter_lidarseg_labels: List = None,
                                lidarseg_preds_bin_path: str = None) -> Tuple:
    cam = nusc.get('sample_data', camera_token)
    pointsensor = nusc.get('sample_data', pointsensor_token)
    pcl_path = osp.join(nusc.dataroot, pointsensor['filename'])
    if pointsensor['sensor_modality'] == 'lidar':
        print("wrong")
    else:
        pc_0 = RadarPointCloud.from_file(pcl_path)
        #######leichen changed
        pointsensor_next_token = pointsensor["next"]
        pointsensor_next = nusc.get('sample_data', pointsensor_next_token)
        pcl_path = osp.join(nusc.dataroot, pointsensor_next['filename'])
        pc_1 = RadarPointCloud.from_file(pcl_path)

        pointsensor_next_next_token = pointsensor_next["next"]
        pointsensor_next_next = nusc.get('sample_data', pointsensor_next_next_token)
        pcl_path = osp.join(nusc.dataroot, pointsensor_next_next['filename'])
        pc_2 = RadarPointCloud.from_file(pcl_path)

    im = Image.open(osp.join(nusc.dataroot, cam['filename']))

    # Points live in the point sensor frame. So they need to be transformed via global to the image plane.
    # First step: transform the pointcloud to the ego vehicle frame for the timestamp of the sweep.
    cs_record = nusc.get('calibrated_sensor', pointsensor['calibrated_sensor_token'])
    pc_0.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_0.translate(np.array(cs_record['translation']))
    ##### leichen changed!
    pc_1.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_1.translate(np.array(cs_record['translation']))
    pc_2.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_2.translate(np.array(cs_record['translation']))
    #####
    # Second step: transform from ego to the global frame.
    poserecord = nusc.get('ego_pose', pointsensor['ego_pose_token'])
    pc_0.rotate(Quaternion(poserecord['rotation']).rotation_matrix)
    pc_0.translate(np.array(poserecord['translation']))
    ##### leichen changed!
    pc_1.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_1.translate(np.array(cs_record['translation']))
    pc_2.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_2.translate(np.array(cs_record['translation']))
    #####
    # Third step: transform from global into the ego vehicle frame for the timestamp of the image.
    poserecord = nusc.get('ego_pose', cam['ego_pose_token'])
    pc_0.translate(-np.array(poserecord['translation']))
    pc_0.rotate(Quaternion(poserecord['rotation']).rotation_matrix.T)
    ##### leichen changed!
    pc_1.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_1.translate(np.array(cs_record['translation']))
    pc_2.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_2.translate(np.array(cs_record['translation']))
    #####
    # Fourth step: transform from ego into the camera.
    cs_record = nusc.get('calibrated_sensor', cam['calibrated_sensor_token'])
    pc_0.translate(-np.array(cs_record['translation']))
    pc_0.rotate(Quaternion(cs_record['rotation']).rotation_matrix.T)
    ##### leichen changed!
    pc_1.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_1.translate(np.array(cs_record['translation']))
    pc_2.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
    pc_2.translate(np.array(cs_record['translation']))
    #####
    # Fifth step: actually take a "picture" of the point cloud.
    # Grab the depths (camera frame z axis points away from the camera).
    radar_points = np.concatenate((pc_0.points, pc_1.points,pc_2.points),axis=1)

    depths = radar_points[2, :]
    coloring = depths

    # Take the actual picture (matrix multiplication with camera-matrix + renormalization).
    points = view_points(radar_points[:3, :], np.array(cs_record['camera_intrinsic']), normalize=True)

    # Remove points that are either outside or behind the camera. Leave a margin of 1 pixel for aesthetic reasons.
    # Also make sure points are at least 1m in front of the camera to avoid seeing the lidar points on the camera
    # casing for non-keyframes which are slightly out of sync.
    mask = np.ones(depths.shape[0], dtype=bool)
    mask = np.logical_and(mask, depths > min_dist)
    mask = np.logical_and(mask, points[0, :] > 1)
    mask = np.logical_and(mask, points[0, :] < im.size[0] - 1)
    mask = np.logical_and(mask, points[1, :] > 1)
    mask = np.logical_and(mask, points[1, :] < im.size[1] - 1)
    points = points[:, mask]

    coloring = coloring[mask]

    return points, coloring, im

def get_color(category_name: str) -> Tuple[int, int, int]:
    """
    Provides the default colors based on the category names.
    This method works for the general nuScenes categories, as well as the nuScenes detection categories.
    """

    return nusc.colormap[category_name]

#nusc = NuScenes(version='v1.0-mini', dataroot='/media/leichen/SeagateBackupPlusDrive/NUSCNES/nuscenes_train', verbose=True)
nusc = NuScenes(version='v1.0-mini', dataroot='/home/leichen/OpenPCDet/data/nuscenes/v1.0-mini', verbose=True)

##### define
nusc.list_scenes()
my_scene = nusc.scene[7]
first_sample_token = my_scene['first_sample_token']
my_sample = nusc.get('sample', first_sample_token)
verbose=True
while my_sample["next"] !=None:
    sample_token = my_sample["next"]
    my_sample = nusc.get('sample', sample_token)
    print("sample_token",sample_token)
    max_sweeps=3
    sensor="radarlidar"
    # nusc.render_pointcloud_in_image(sample_token, pointsensor_channel='RADAR_FRONT',out_path="/home/leichen/Point Transformer/"+sample_token)

    ########## show the image

    # Here we just grab the front camera and the point sensor.
    pointsensor_token = my_sample['data']["RADAR_FRONT"]
    camera_token = my_sample['data']["CAM_FRONT"]

    points, coloring, im = map_pointcloud_to_image(pointsensor_token, camera_token)
    ax=None
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(9, 16))

        fig.canvas.set_window_title(sample_token)
    else:  # Set title on if rendering as part of render_sample.
        ax.set_title("CAM_FRONT")
    ax.imshow(im)
    dot_size=15.0
    #ax.scatter(points[0, :], points[1, :], c=coloring, s=dot_size)
    ax.axis('off')
    out_path="/home/leichen/Point Transformer/"+sample_token
    if out_path is not None:
        plt.savefig(out_path, bbox_inches='tight', pad_inches=0, dpi=200)
    if verbose:
        plt.show()
    ########## show the image end

    #####get the radar points
    if sensor=="radar":
        sample_rec = nusc.get('sample', sample_token)
        ref_chan ="LIDAR_TOP"
        Point_F, times_F = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_FRONT", ref_chan, nsweeps=max_sweeps)
        pc_F_times = np.concatenate((Point_F.points, times_F))

        Point_F_L, times_F_L = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_FRONT_LEFT", ref_chan, nsweeps=max_sweeps)
        pc_F_L_times = np.concatenate((Point_F_L.points, times_F_L))

        Point_F_R, times_F_R = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_FRONT_RIGHT", ref_chan, nsweeps=max_sweeps)
        pc_F_R_times = np.concatenate((Point_F_R.points, times_F_R))

        Point_B_L, times_B_L = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_BACK_LEFT", ref_chan, nsweeps=max_sweeps)
        pc_B_L_times = np.concatenate((Point_B_L.points, times_B_L))
        Point_B_R, times_B_R = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_BACK_RIGHT", ref_chan, nsweeps=max_sweeps)
        pc_B_R_times = np.concatenate((Point_B_R.points, times_B_R))
        pc_times = np.concatenate((pc_F_times, pc_F_L_times, pc_F_R_times, pc_B_L_times, pc_B_R_times), axis=1)

    elif sensor== "lidar":
        sample_rec = nusc.get('sample', sample_token)
        ref_chan ="LIDAR_TOP"
        Point_LiDAR, times_LiDAR = LidarPointCloud.from_file_multisweep(nusc, sample_rec, "LIDAR_TOP", ref_chan, nsweeps=max_sweeps)
        pc_times = np.concatenate((Point_LiDAR.points, times_LiDAR))

    else:
        sample_rec = nusc.get('sample', sample_token)
        ref_chan ="LIDAR_TOP"
        Point_F, times_F = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_FRONT", ref_chan, nsweeps=max_sweeps)
        pc_F_times = np.concatenate((Point_F.points, times_F))

        Point_F_L, times_F_L = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_FRONT_LEFT", ref_chan, nsweeps=max_sweeps)
        pc_F_L_times = np.concatenate((Point_F_L.points, times_F_L))

        Point_F_R, times_F_R = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_FRONT_RIGHT", ref_chan, nsweeps=max_sweeps)
        pc_F_R_times = np.concatenate((Point_F_R.points, times_F_R))

        Point_B_L, times_B_L = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_BACK_LEFT", ref_chan, nsweeps=max_sweeps)
        pc_B_L_times = np.concatenate((Point_B_L.points, times_B_L))
        Point_B_R, times_B_R = RadarPointCloud.from_file_multisweep(nusc, sample_rec, "RADAR_BACK_RIGHT", ref_chan, nsweeps=max_sweeps)
        pc_B_R_times = np.concatenate((Point_B_R.points, times_B_R))
        pc_times_radar = np.concatenate((pc_F_times, pc_F_L_times, pc_F_R_times, pc_B_L_times, pc_B_R_times), axis=1)
        ref_chan ="LIDAR_TOP"
        Point_LiDAR, times_LiDAR = LidarPointCloud.from_file_multisweep(nusc, sample_rec, "LIDAR_TOP", ref_chan, nsweeps=max_sweeps)
        pc_times_lidar = np.concatenate((Point_LiDAR.points, times_LiDAR))
        #####################################################
        #####################################################transform block
        ####F
        LIDAR_TOKEN=my_sample["data"]["LIDAR_TOP"]

        RADAR_FRONT_TOKEN=my_sample["data"]["RADAR_FRONT"]

        pointsensor = nusc.get('sample_data', LIDAR_TOKEN)
        cs_record = nusc.get('calibrated_sensor', pointsensor['calibrated_sensor_token'])
        Point_F.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
        Point_F.translate(np.array(cs_record['translation']))
        # Second step: transform from ego to the global frame.
        poserecord = nusc.get('ego_pose', pointsensor['ego_pose_token'])
        Point_F.rotate(Quaternion(poserecord['rotation']).rotation_matrix)
        Point_F.translate(np.array(poserecord['translation']))

        #### FL
        RADAR_FRONT_LEFT_TOKEN=my_sample["data"]["RADAR_FRONT_LEFT"]
        # pointsensor = nusc.get('sample_data', RADAR_FRONT_LEFT_TOKEN)
        # cs_record = nusc.get('calibrated_sensor', pointsensor['calibrated_sensor_token'])
        Point_F_L.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
        Point_F_L.translate(np.array(cs_record['translation']))
        # Second step: transform from ego to the global frame.
        poserecord = nusc.get('ego_pose', pointsensor['ego_pose_token'])
        Point_F_L.rotate(Quaternion(poserecord['rotation']).rotation_matrix)
        Point_F_L.translate(np.array(poserecord['translation']))

        ###FR
        RADAR_FRONT_RIGHT_TOKEN=my_sample["data"]["RADAR_FRONT_RIGHT"]
        # pointsensor = nusc.get('sample_data', RADAR_FRONT_RIGHT_TOKEN)
        cs_record = nusc.get('calibrated_sensor', pointsensor['calibrated_sensor_token'])
        Point_F_R.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
        Point_F_R.translate(np.array(cs_record['translation']))
        # Second step: transform from ego to the global frame.
        poserecord = nusc.get('ego_pose', pointsensor['ego_pose_token'])
        Point_F_R.rotate(Quaternion(poserecord['rotation']).rotation_matrix)
        Point_F_R.translate(np.array(poserecord['translation']))

        ###BL
        RADAR_BACK_LEFT_TOKEN=my_sample["data"]["RADAR_BACK_LEFT"]
        # pointsensor = nusc.get('sample_data', RADAR_BACK_LEFT_TOKEN)
        cs_record = nusc.get('calibrated_sensor', pointsensor['calibrated_sensor_token'])
        Point_B_L.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
        Point_B_L.translate(np.array(cs_record['translation']))
        # Second step: transform from ego to the global frame.
        poserecord = nusc.get('ego_pose', pointsensor['ego_pose_token'])
        Point_B_L.rotate(Quaternion(poserecord['rotation']).rotation_matrix)
        Point_B_L.translate(np.array(poserecord['translation']))

        ###BR
        RADAR_BACK_RIGHT_TOKEN=my_sample["data"]["RADAR_BACK_RIGHT"]
        # pointsensor = nusc.get('sample_data', RADAR_BACK_RIGHT_TOKEN)
        cs_record = nusc.get('calibrated_sensor', pointsensor['calibrated_sensor_token'])
        Point_B_R.rotate(Quaternion(cs_record['rotation']).rotation_matrix)
        Point_B_R.translate(np.array(cs_record['translation']))
        # Second step: transform from ego to the global frame.
        poserecord = nusc.get('ego_pose', pointsensor['ego_pose_token'])
        Point_B_R.rotate(Quaternion(poserecord['rotation']).rotation_matrix)
        Point_B_R.translate(np.array(poserecord['translation']))

        pc_radar_global = np.concatenate((Point_F.points, Point_F_L.points, Point_F_R.points, Point_B_L.points, Point_B_R.points), axis=1)

    #####find the points in GT boxes!!
    if sensor =="radar":
        radar_front_data = nusc.get('sample_data', sample_rec['data']["RADAR_FRONT"])
        sample_data_token = radar_front_data['token']
    elif sensor =="lidar":
        lidar_front_data = nusc.get('sample_data', sample_rec['data']["LIDAR_TOP"])
        sample_data_token = lidar_front_data['token']
    else:
        lidar_front_data = nusc.get('sample_data', sample_rec['data']["LIDAR_TOP"])
        sample_data_token = lidar_front_data['token']

        boxes = nusc.get_boxes(sample_data_token)
        mask_GT = np.zeros(pc_radar_global.shape[1], dtype=bool)
        pc_radar_global[2,:]=1.0
        for box in boxes:
            mask_GT_box = points_in_box(box, pc_radar_global[:3,:], wlh_factor=1.5)
            mask_GT=np.logical_or(mask_GT_box, mask_GT)

    use_flat_vehicle_coordinates=True
    ax=None
    underlay_map=True
    with_anns=True

    sd_record = nusc.get('sample_data', sample_data_token)

    sensor_modality = sd_record['sensor_modality']
    if sensor_modality in ['lidar', 'radar']:
        chan = sd_record['channel']
        ref_chan = 'LIDAR_TOP'
        ref_sd_token = sample_rec['data'][ref_chan]
        ref_sd_record = nusc.get('sample_data', ref_sd_token)

        if sensor == 'lidar':

            pc, times = LidarPointCloud.from_file_multisweep(nusc, sample_rec, chan, ref_chan,
                                                                 nsweeps=5)
            velocities = None
        elif sensor == "radar":

        # Get aggregated radar point cloud in reference frame.
        # The point cloud is transformed to the reference frame for visualization purposes.

        # Transform radar velocities (x is front, y is left), as these are not transformed when loading the
        # point cloud.
            radar_cs_record = nusc.get('calibrated_sensor', sd_record['calibrated_sensor_token'])
            ref_cs_record = nusc.get('calibrated_sensor', ref_sd_record['calibrated_sensor_token'])
            velocities = pc_times[8:10, :]  # Compensated velocity
            velocities = np.vstack((velocities, np.zeros(pc_times.shape[1])))
            velocities = np.dot(Quaternion(radar_cs_record['rotation']).rotation_matrix, velocities)
            velocities = np.dot(Quaternion(ref_cs_record['rotation']).rotation_matrix.T, velocities)
            velocities[2, :] = np.zeros(pc_times.shape[1])

        else:
            pc, times = LidarPointCloud.from_file_multisweep(nusc, sample_rec, chan, ref_chan,
                                                                 nsweeps=5)

            radar_cs_record = nusc.get('calibrated_sensor', sd_record['calibrated_sensor_token'])
            ref_cs_record = nusc.get('calibrated_sensor', ref_sd_record['calibrated_sensor_token'])
            velocities = pc_times_radar[8:10, :]  # Compensated velocity
            velocities = np.vstack((velocities, np.zeros(pc_times_radar.shape[1])))
            velocities = np.dot(Quaternion(radar_cs_record['rotation']).rotation_matrix, velocities)
            velocities = np.dot(Quaternion(ref_cs_record['rotation']).rotation_matrix.T, velocities)
            velocities[2, :] = np.zeros(pc_times_radar.shape[1])    # By default we render the sample_data top down in the sensor frame.
        # This is slightly inaccurate when rendering the map as the sensor frame may not be perfectly upright.
        # Using use_flat_vehicle_coordinates we can render the map in the ego frame instead.
        if use_flat_vehicle_coordinates:
            # Retrieve transformation matrices for reference point cloud.
            cs_record = nusc.get('calibrated_sensor', ref_sd_record['calibrated_sensor_token'])
            pose_record = nusc.get('ego_pose', ref_sd_record['ego_pose_token'])
            ref_to_ego = transform_matrix(translation=cs_record['translation'],
                                          rotation=Quaternion(cs_record["rotation"]))

            # Compute rotation between 3D vehicle pose and "flat" vehicle pose (parallel to global z plane).
            ego_yaw = Quaternion(pose_record['rotation']).yaw_pitch_roll[0]
            rotation_vehicle_flat_from_vehicle = np.dot(
                Quaternion(scalar=np.cos(ego_yaw / 2), vector=[0, 0, np.sin(ego_yaw / 2)]).rotation_matrix,
                Quaternion(pose_record['rotation']).inverse.rotation_matrix)
            vehicle_flat_from_vehicle = np.eye(4)
            vehicle_flat_from_vehicle[:3, :3] = rotation_vehicle_flat_from_vehicle
            viewpoint = np.dot(vehicle_flat_from_vehicle, ref_to_ego)
        else:
            viewpoint = np.eye(4)

        # Init axes.
        if ax is None:
            _, ax = plt.subplots(1, 1, figsize=(9, 9))

        # Render map if requested.
        if underlay_map:
            assert use_flat_vehicle_coordinates, 'Error: underlay_map requires use_flat_vehicle_coordinates, as ' \
                                                 'otherwise the location does not correspond to the map!'
            axes_limit=100
            #NuScenesExplorer.render_ego_centric_map(sample_data_token=sample_data_token, axes_limit=axes_limit, ax=ax)

        # Show point cloud.

        if sensor== "radarlidar":

            points_lidar= view_points(pc_times_lidar[:3, :], viewpoint, normalize=False)
            dists_lidar = np.sqrt(np.sum(pc_times_lidar[:2, :] ** 2, axis=0))

            point_scale = 0.0005
            ax.scatter(points_lidar[0, :], points_lidar[1, :], c="gray", s=point_scale)

            points_radar= view_points(pc_times_radar[:3, :], viewpoint, normalize=False)
            dists_radar = np.sqrt(np.sum(pc_times_radar[:2, :] ** 2, axis=0))
            colors = np.minimum(1, dists_radar / axes_limit / np.sqrt(2))
            point_scale = 0.3

            ###### compare points_lidar & points_radar:
            points_radar_ghost,ghost_mask=find_ghost_target(points_radar, points_lidar,mask_GT)
            # scatter = ax.scatter(points_radar_ghost[0, :], points_radar_ghost[1, :], c="red", s=point_scale)
            dists_radar_ghost = np.sqrt(np.sum(points_radar_ghost[:2, :] ** 2, axis=0))
            colors=dists_radar_ghost
            scatter=ax.scatter(points_radar[0, :], points_radar[1, :], c="blue",s=point_scale)

        else :
            points= view_points(pc_times[:3, :], viewpoint, normalize=False)
            dists = np.sqrt(np.sum(pc_times[:2, :] ** 2, axis=0))

            colors = np.minimum(1, dists / axes_limit / np.sqrt(2))
            point_scale = 0.2 if sensor_modality == 'lidar' else 3.0

            scatter = ax.scatter(points[0, :], points[1, :], c=colors, s=point_scale)

        if sensor == 'radar':
            points_vel = view_points(points[:3, :] + velocities, viewpoint, normalize=False)
            deltas_vel = points_vel - points
            deltas_vel = 6 * deltas_vel  # Arbitrary scaling
            max_delta = 20
            deltas_vel = np.clip(deltas_vel, -max_delta, max_delta)  # Arbitrary clipping
            colors_rgba = scatter.to_rgba(colors)
            for i in range(points.shape[1]):
                ax.arrow(points[0, i], points[1, i], deltas_vel[0, i], deltas_vel[1, i], color=colors_rgba[i])

        # Show ego vehicle.
        ax.plot(0, 0, 'x', color='red')
        box_vis_level= BoxVisibility.ANY
        # Get boxes in lidar frame.
        _, boxes, _ = nusc.get_sample_data(ref_sd_token, box_vis_level=box_vis_level,
                                                use_flat_vehicle_coordinates=use_flat_vehicle_coordinates)

        # Show boxes.
        if with_anns:
            for box in boxes:
                if "vehicle.car" in box.name:
                    print
                    c = np.array(get_color("vehicle.car")) / 255.0
                    box.render(ax, view=np.eye(4), colors=(c,c,c),linewidth=1)

        # Limit visible range.
        ax.set_xlim(-axes_limit, axes_limit)
        ax.set_ylim(-axes_limit, axes_limit)

    else:
        raise ValueError("Error: Unknown sensor modality!")

    ax.axis('off')

    ax.set_aspect('equal')
    out_path=None
    if out_path is not None:
        plt.savefig(out_path, bbox_inches='tight', pad_inches=0, dpi=200)
    verbose=True
    if verbose:
        plt.show()


from tkinter import *
from functools import partial
import random

class Game:
    def __init__(self):
        self.game_stats_list = [50, 6]
        self.round_stats_list = ['lead\n($0) | copper\n($1) | lead\n($0) - Cost: $5 | Payback: $1 | Current Balance: $46',
                                 'copper\n($1) | copper\n($1) | silver\n($2) - Cost: $5 | Payback: $4 | Current Balance: $45',
                                 'silver\n($2) | copper\n($1) | copper\n($1) - Cost: $5 | Payback: $4 | Current Balance: $44',
                                 'silver\n($2) | lead\n($0) | lead\n($0) - Cost: $5 | Payback: $2 | Current Balance: $41',
                                 'copper\n($1) | copper\n($1) | silver\n($2) - Cost: $5 | Payback: $4 | Current Balance: $40']
        self.game_frame = Frame()
        self.game_frame.grid()

            # heading row
        self.heading_label = Label(self.game_frame, text="Play",
                                   font="Verdana 24 bold", padx=10,pady=10)
        self.heading_label.grid(row=0)

            # history button
        self.stats_button = Button(self.game_frame, text="Game Stats",
                                   font="Verdana 14", padx=10, pady=10,
                                   command=lambda: self.to_stats(self.round_stats_list))
        self.stats_button(row=1)

    def to_stats(self, game_history, game_stats):
        GameStats(self, game_history, game_stats)

class GameStats:
    def __init__(self, partner, game_history, game_stats):
        print(game_history)

            # disable help button
        partner.stats_button.config(state=DISABLED)

            # initalise vars
        heading = "Verdana 12 bold"
        content = "Verdana 12"

            # sets up child window
        self.stats_box = Toplevel()

            # if users press cross at top, closes help and releases button.
        self.stats_box.protocol('WM_DELETE_WINDOW', partial(self.close_stats, partner))

            # set up GUI frame.
        self.stats_frame = Frame(self.stats_box)
        self.stats_frame.grid()

            # set up help heading
        self.stats_heading_label = Label(self.stats_frame, text="Game Statistics", font="Verdana 19 bold")
        self.stats_heading_label.grid(row=0)

            # to export instructions
        self.export_instructions = Label(self.stats_frame, text="Here are your Game Statistics. Please use the Export button to access the results"
                                         "of each round that you played.", wrap=250,font="Verdana 10 italic", justify=LEFT, fg="green", padx=10, pady=10)
        self.export_instructions.grid(row=1)

            # starting balance
        self.details_frame = Frame(self.stats_frame)
        self.details_frame.grid(row=2)

        self.start_balance_label = Label(self.details_frame, text="Starting Balance:", font=heading, anchor="e")
        self.start_balance_label.grid(row=0, column=0, padx=0)

        self.start_balance_value_label = Label(self.details_frame, font=content, text="${}".format(game_stats[0]), anchor="w")
        self.start_balance_value_label.grid(row=0, column=1, padx=0)

            # current balance
        self.current_balance_label = Label(self.details_frame, text="Current Balance:", font=heading, anchor="e")
        self.current_balance_label.grid(row=1,column=0,padx=10)

        self.current_balance_value_label = Label(self.details_frame, font=content, text="${}".format(game_stats[1]))
        self.current_balance_value_label.grid(row=1,column=1,padx=0)

        if game_stats[1] > game_stats[0]:
            win_loss = "Amount Won:"
            amount = game_stats[1] - game_stats[0]
            win_loss_fg = "green"
        else:
            win_loss = "Amount Lost:"
            amount = game_stats[0] - game_stats[1]
            win_loss_fg = "#660000"

            # amount won or lost
        self.wind_loss_label = Label(self.details_frame, text=win_loss, font=heading, anchor="e")
        self.wind_loss_label.grid(row=2,column=0,padx=0)

        self.wind_loss_value_label = Label(self.details_frame, font=content, text="${}".format(amount), fg=win_loss_fg, anchor="w")
        self.wind_loss_value_label.grid(row=2, column=1, padx=0)

            # rounds played
        self.games_played_label = Label(self.details_frame,text="Rounds Played:", font=heading, anchor="e")
        self.games_played_label.grid(row=4, column=0, padx=0)

        self.games_played_value_label = Label(self.details_frame, font=content, text=len(game_history), anchor="w")
        self.games_played_value_label.grid(row=4, column=1, padx=0)

            # dismiss button

if __name__ == "__main__":
    root = Tk()
    root.title("Mystery Box Game")
    something = Game(root)
    root.mainloop()


import json
from flask import Flask, render_template, redirect, request, jsonify, session, url_for, make_response, escape

app = Flask(__name__)

init_contact = { 'id': None,
			'firstname': None,
			'lastname': None,
			'phonenumber': None,
			'emailaddress': None,
			'birthdate': None,
			'note': None }

def initialise_contacts():
	with open('appdata.md', 'r') as data_file:
		if data_file.read(1) == '':
			data = []
			initContact = dict(init_contact)
			initContact['id'] = 0
			data.append(initContact)
			app.logger.info('Initial contact created.')

			with open('appdata.md', 'w+') as data_file:
				data_file.write(json.dumps(data))
			app.logger.info('Data file written.')
	with open('appdata.md', 'r') as data_file:
		return json.loads(data_file.read())

@app.route('/')
def _view_index():
	data = initialise_contacts()
	if len(data) <= 0:
		data = []
	return render_template('index.html', data=data)

@app.route('/contact', methods=['POST'])
def new_contact():
	data = initialise_contacts()
	if 'id' in request.form:
		if request.form['id'] is '':
			contact = dict(init_contact)
			if 'firstname' in request.form:
				contact['firstname'] = escape(request.form['firstname'])
			if 'lastname' in request.form:
				contact['lastname'] = escape(request.form['lastname'])
			if 'phonenumber' in request.form:
				contact['phonenumber'] = escape(request.form['phonenumber'])
			if 'emailaddress' in request.form:
				contact['emailaddress'] = escape(request.form['emailaddress'])
			if 'birthdate' in request.form:
				contact['birthdate'] = escape(request.form['birthdate'])
			if 'note' in request.form:
				contact['note'] = escape(request.form['note'])
			if contact == init_contact:
				app.logger.error('All fields are empty.')
				return 'Error'
			contact['id'] = data[0]['id']
			data.append(contact)
			data[0]['id'] = data[0]['id'] + 1
			app.logger.info('New contact added locally.')
		else:
			for contact in data:
				if contact['id'] is int(request.form['id']):
					if 'firstname' in request.form:
						contact['firstname'] = escape(request.form['firstname'])
					if 'lastname' in request.form:
						contact['lastname'] = escape(request.form['lastname'])
					if 'emailaddress' in request.form:
						contact['emailaddress'] = escape(request.form['emailaddress'])
					if 'phonenumber' in request.form:
						contact['phonenumber'] = escape(request.form['phonenumber'])
					if 'birthdate' in request.form:
						contact['birthdate'] = escape(request.form['birthdate'])
					if 'note' in request.form:
						contact['note'] = escape(request.form['note'])
					app.logger.info('Contact edited locally.')
					break
	with open('appdata.md', 'w') as data_file:
		data_file.write(json.dumps(data))
	app.logger.info('Data file written.')
	return 'OK'

@app.route('/delete', methods=['POST'])
def delete_contact():
	if 'id' not in request.form:
		return False
	inputId = int(request.form['id'])
	with open('appdata.md', 'r') as data_file:
		data = json.loads(data_file.read())
	data = [t for t in data if not (t['id'] is inputId)]
	with open('appdata.md', 'w') as data_file:
		data_file.write(json.dumps(data))
	return 'OK'

if __name__ == "__main__":
	app.run(host="0.0.0.0", debug=True)


import pdfplumber
import os
import concurrent.futures
from functools import wraps
import time
import pandas as pd
import pickle
from datetime import date

def timeit(method):
    @wraps(method)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = method(*args, **kwargs)
        end_time = time.time()
        print(f"{method.__name__} => {(end_time-start_time)*1000} ms")

        return result

    return wrapper

@timeit
def extract_pdf(filename, directory):
    filename = os.fsdecode(filename)
    allpages_text = []
    data = []
    if filename.endswith('.pdf'):
        with pdfplumber.open(directory + filename) as pdf:
            for page in pdf.pages:
                text = page.extract_text()
                allpages_text.append(text)
            allpages_text = '-'.join(allpages_text)
            data.append(allpages_text)
            data.append(filename)

            return data

@timeit
def extract_all(directory):

    '''
    Uses extract_pdf to extract multiple PDFs within a directory.
    '''

    data = []

    with concurrent.futures.ProcessPoolExecutor(max_workers=8) as executor:

        futures = {executor.submit(extract_pdf, filename, directory): filename for filename in os.listdir(directory)}

        for future in concurrent.futures.as_completed(futures):
            try:
                result = future.result()
                data.append(result)
            except Exception as exc:
                print("There was an error. It is defined as {}".format(exc))
    return data

@timeit
def extract_all_singleprocess(directory):
    return [extract_pdf(filename, directory) for filename in os.listdir(directory)]

if __name__ == '__main__':
    # filename = '224.pdf'
    directory = r'../files/' # r'C:/Users/peter/research_files/supreme_court/'

    results = extract_all(directory)
    with open(r'../data/pdfextracts_{}.pkl'.format(date.today()), 'wb') as file:
        pickle.dump(results, file)


import os
import time
from datetime import datetime

from cnaas_nac.db.accounting import Accounting
from cnaas_nac.db.nas import NasPort
from cnaas_nac.db.user import Reply, User, UserInfo
from cnaas_nac.tools.log import get_logger

logger = get_logger()
ONE_MONTH = 2629800

def users_cleanup():
    if "NO_CLEANUP" in os.environ:
        logger.info("Aborting cleanup.")
        return ""

    users = User.get()

    logger.info("Cleaning up users...")

    for user in users:
        username = user["username"]

        # Skip enabled users
        if user["op"] != "":
            logger.info("User {} active, skipping".format(username))
            continue

        userinfo = UserInfo.get([username])
        authdate = userinfo[username]["authdate"]

        if authdate is None or authdate == "":
            logger.info("No timestamp for user {}, skipping".format(username))
            continue

        authdate_epoch = int(authdate.timestamp())
        current_epoch = int(time.time())

        if current_epoch - authdate_epoch >= ONE_MONTH:
            logger.info("Removing user {}".format(user["username"]))
            User.delete(user["username"])
            Reply.delete(user["username"])
            NasPort.delete(user["username"])
        else:
            logger.info("Keeping user {}".format(user["username"]))

    return ""

def accounting_cleanup():
    removed_items = 0

    logger.info("Cleaning up accounting...")

    if "NO_CLEANUP" in os.environ:
        logger.info("Aborting cleanup.")
        return ""

    for account in Accounting.get():
        if "acctstoptime" in account:
            acctstoptime = account["acctstoptime"]
        else:
            continue

        if not acctstoptime:
            continue

        epoch_stop = round(datetime.strptime(
            acctstoptime, "%Y-%m-%d %H:%M:%S+00:00").timestamp())
        current_epoch = int(time.time())

        if current_epoch - epoch_stop >= ONE_MONTH:
            try:
                Accounting.delete(account["username"], account["acctstoptime"])
            except Exception:
                logger.info("Failed to remove account: {} {}".format(
                    account["username"], account["acctstoptime"]))
                continue
            removed_items += 1

    logger.info(f"Cleaned up {removed_items} items from radacct")

if __name__ == "__main__":
    users_cleanup()
    accounting_cleanup()


#!/usr/bin/env python

import argparse
import os
import time
from pprint import pprint

import googleapiclient.discovery
import google.auth
import google.oauth2.service_account as service_account

#
# Use Google Service Account - See https://google-auth.readthedocs.io/en/latest/reference/google.oauth2.service_account.html#module-google.oauth2.service_account
#
credentials = service_account.Credentials.from_service_account_file(filename='service-credentials.json')
project = os.getenv('GOOGLE_CLOUD_PROJECT') or 'datacenter5'
service = googleapiclient.discovery.build('compute', 'v1', credentials=credentials)

bucket = 'lab-5bucket'
zone = 'us-central1-f'
disk = 'demo-2'

def list_instances(compute, project, zone):
    result = compute.instances().list(project=project, zone=zone).execute()
    return result['items'] if 'items' in result else None

def create_instance(compute, project, zone, name, bucket):
    # Get the latest Debian Jessie image.
    image_response = compute.images().getFromFamily(
        project='ubuntu-os-cloud', family='ubuntu-1804-lts').execute()
    source_disk_image = image_response['selfLink']

    # Configure the machine
    machine_type = "zones/%s/machineTypes/f1-micro" % zone
    startup_script = open(
        os.path.join(
            os.path.dirname(__file__), 'startup-script.sh'), 'r').read()
    image_url = "http://storage.googleapis.com/gce-demo-input/photo.jpg"
    image_caption = "Ready for dessert?"

    config = {
        'name': name,
        'machineType': machine_type,

        # Specify the boot disk and the image to use as a source.
        'disks': [
            {
                'boot': True,
                'autoDelete': True,
                'initializeParams': {
                    'sourceImage': source_disk_image,
                }
            }
        ],

        # Specify a network interface with NAT to access the public
        # internet.
        'networkInterfaces': [{
            'network': 'global/networks/default',
            'accessConfigs': [
                {'type': 'ONE_TO_ONE_NAT', 'name': 'External NAT'}
            ]
        }],

        # Allow the instance to access cloud storage and logging.
        'serviceAccounts': [{
            'email': 'default',
            'scopes': [
                'https://www.googleapis.com/auth/devstorage.read_write',
                'https://www.googleapis.com/auth/logging.write'
            ]
        }],

        # Metadata is readable from the instance and allows you to
        # pass configuration from deployment scripts to instances.
        'metadata': {
            'items': [{
                # Startup script is automatically executed by the
                # instance upon startup.
                'key': 'startup-script',
                'value': startup_script
            }, {
                'key': 'url',
                'value': image_url
            }, {
                'key': 'text',
                'value': image_caption
            }, {
                'key': 'bucket',
                'value': bucket
            }]
        }
    }

    return compute.instances().insert(
        project=project,
        zone=zone,
        body=config).execute()
# [END create_instance]

# [START delete_instance]
def delete_instance(compute, project, zone, name):
    return compute.instances().delete(
        project=project,
        zone=zone,
        instance=name).execute()
# [END delete_instance]

# [START wait_for_operation]
def wait_for_operation(compute, project, zone, operation):
    print('Waiting for operation to finish...')
    while True:
        result = compute.zoneOperations().get(
            project=project,
            zone=zone,
            operation=operation).execute()

        if result['status'] == 'DONE':
            print("done.")
            if 'error' in result:
                raise Exception(result['error'])
            return result

        time.sleep(1)
# [END wait_for_operation]

# [START run]
def main(project, bucket, zone, instance_name, wait=True):
    compute = googleapiclient.discovery.build('compute', 'v1')

    print('Creating instance.')

    operation = create_instance(compute, project, zone, instance_name, bucket)
    wait_for_operation(compute, project, zone, operation['name'])

    instances = list_instances(compute, project, zone)

    print('Instances in project %s and zone %s:' % (project, zone))
    for instance in instances:
        print(' - ' + instance['name'])

main(project, bucket, zone, 'via-service-2')

# snapshot_body = {
# 	"name": "base-snapshot-demo-2"
#     # TODO: Add desired entries to the request body.
# }

# request = service.disks().createSnapshot(project=project, zone=zone, disk=disk, body=snapshot_body)
# response = request.execute()

print("Your running instances are:")
for instance in list_instances(service, project, 'us-west1-b'):
    print(instance['name'])


import logging

class Test:
    def __init__(self, documents):
        self.documents = documents
        self.correct_states = 0
        self.total_states = sum([len(document) for document in documents])
        self.correct_documents = 0
        self.total_documents = len(documents)

    def test_decoder(self, decoder, lowercase=False):
        self.correct_states = 0
        self.correct_documents = 0
        for i, document in enumerate(self.documents):
            logging.info("Decoder test for document %s", i)
            observations = []
            true_states = []
            for observation, state in document:
                observations.append(observation)
                true_states.append(state)
            if lowercase:
                observations = [observation.lower() for observation in observations]
            decoded_sequence = decoder.decode(observations)
            if decoded_sequence == true_states:
                self.correct_documents += 1
            for i, decoded_state in enumerate(decoded_sequence):
                if decoded_state == true_states[i]:
                    self.correct_states += 1
        return self.correct_states/self.total_states, self.correct_documents/self.total_documents


# -*- coding: utf-8 -*-
"""

Credit
------
Modified from Erik Linder-Norén's MIT licensed kerasGAN library,
https://github.com/eriklindernoren/Keras-GAN

"""

import scipy
import numpy as np
import os
from fnmatch import fnmatch
import cv2 as cv
import keras

from util import resize_preserving_aspect_ratio, gaussian2d
from augmentations import get_augmentation_fcn2

def points2mask(points, image_shape, use_gaussian=False, fill=False):
    """Returns n-channel mask given n x 2 array of xy-points."""

    if fill:
        assert not use_gaussian
        return cv.drawContours(image=np.zeros(image_shape[:2]),
                               contours=[cv.convexHull(np.array(points))],
                               contourIdx=-1,
                               color=1,
                               thickness=-1)

    mask = np.zeros(image_shape[:2] + (len(points),), dtype=bool)
    if use_gaussian:
        for k, (j, i) in enumerate(points):
            mask[:, :, k] = mask[:, :, k] + \
                            gaussian2d(image_shape, (j, i), variance=1)
    else:
        for k, (j, i) in enumerate(points):
            mask[i, j, k] = 1
    return mask

def pmask2points(mask):
    pts = [np.unravel_index(mask[:, :, k].argmax(), mask.shape[:2])
           for k in range(mask.shape[-1])]
    return np.array(pts)[:, ::-1]

def mask2points(mask):
    pts = []
    for k in range(mask.shape[-1]):
        pts += list(zip(*np.where(mask[:, :, k] != 0)))
    return np.array(pts)[:, ::-1]

def mark_image(image, points):
    assert 0 <= np.max(np.array(points)[:, 0]) < image.shape[1]
    assert 0 <= np.max(np.array(points)[:, 1]) < image.shape[0]
    # from copy import copy
    # img0 = copy(image)
    for k, pt in enumerate(points):

        image = cv.putText(img=image,
                           text=str(k + 1),
                           org=tuple(pt),
                           fontFace=cv.FONT_HERSHEY_SIMPLEX,
                           fontScale=.5,
                           color=(0, 0, 255),
                           thickness=2,
                           lineType=2)
    return image

def scary_shuffle_in_unison(a, b):
    # https://stackoverflow.com/questions/4601373
    rng_state = np.random.get_state()
    np.random.shuffle(a)
    np.random.set_state(rng_state)
    np.random.shuffle(b)

def find(pattern, path):
    # https://stackoverflow.com/questions/1724693
    result = []
    for root, dirs, files in os.walk(path):
        for name in files:
            if fnmatch(name, pattern):
                result.append(os.path.join(root, name))
    return result

def read_csv(csv_path, has_headers=True):
    sample_points = dict()
    headers = None
    with open(csv_path) as f:
        for k, line in enumerate(f):

            if k == 0 and has_headers:
                headers = line.strip().split(',')
                continue

            row = line.strip().split(',')
            name = row[0]
            points = [(int(row[i]), int(row[i+1]))
                      for i in range(1, len(row)-1, 2)]
            sample_points[name] = points
    return sample_points, headers

def show_generated_pairs(generator, fx=.5, fy=.5, use_system_viewer=True):
    for image_batch, mask_batch in generator:
        for image, mask in zip(image_batch, mask_batch):
            print(image.shape)
            print(mask.shape)
            bgr = (np.flip(image, axis=2)*255).astype('uint8')
            if generator.fill:
                contours, _ = cv.findContours(image=mask.astype('uint8'),
                                              mode=cv.RETR_TREE,
                                              method=cv.CHAIN_APPROX_SIMPLE)
                visual = bgr.copy()
                cv.drawContours(visual, contours, -1, (0, 255, 0))
            else:
                assert mask.sum() == mask.shape[-1]
                pts = pmask2points(mask)
                visual = mark_image(bgr, pts)
            visual = cv.resize(visual, None, fx=fx, fy=fy)
            # visual = (visual*255).astype('uint8')
            print(visual.shape)

            if use_system_viewer:
                debug_out = '/tmp/debug_visual.jpg'
                cv.imwrite(debug_out, visual)
                os.system('open ' + debug_out)
                res = input()
                if res == 'q':
                    return
            else:
                cv.imshow('', visual)
                print(image.shape, mask.shape)

                cv.waitKey(10)
                keypress = input()
                if keypress == 'q':
                    cv.destroyAllWindows()
                    return

class PointsDataGenerator(keras.utils.Sequence):
    def __init__(self, images_dir, points_csv, subset, img_res=(128, 128),
                 image_channels=3, augment=False,
                 batch_size=2, shuffle=True, fill=False,
                 raster_then_augment=False):
        self.image_dir = images_dir
        self.points_path = points_csv
        self.img_res = img_res
        self.images = None
        self.masks = None
        self.points = None
        self.image_shape = img_res[::-1] + (image_channels,)
        self.mask_shape = None  # will be set automatically
        self.augmented = augment
        self.batch_size = batch_size
        self.subset = subset
        # self.dim = img_res
        self.batch_size = batch_size
        self.shuffle = shuffle
        self.augmentation_fcn = get_augmentation_fcn2('truss_points')
        self.fill = fill
        self.raster_then_augment = raster_then_augment
        print('WARNING: using "scary" shuffling.  You may want to check '
              'this still works, i.e. whether masks match images.')
        self.on_epoch_end()

    def __len__(self):
        """Denotes the number of batches per epoch"""
        return int(np.floor(len(self.images) / self.batch_size))

    def __getitem__(self, index):
        """Generate one batch of data"""

        bs = self.batch_size
        image_batch = self.images[index*bs: (index+1)*bs]
        # mask_batch  =  self.masks[index*bs: (index+1)*bs]
        points_batch = self.points[index * bs: (index + 1) * bs]

        if self.augmented:
            augmented_mask_batch = np.empty((bs,) + self.mask_shape, dtype='float32')
            augmented_image_batch = np.empty(image_batch.shape, dtype='float32')

            for k, image, pts in zip(range(bs), image_batch, points_batch):
                keypoints = [(x, y, 0, 0) for x, y in pts]
                if self.raster_then_augment:
                    mask = points2mask(pts, image.shape, fill=self.fill)
                    augmented_data = self.augmentation_fcn(image=image,
                                                           mask=mask)
                    augmented_image = augmented_data['image']
                    augmented_mask = augmented_data['mask']
                else:
                    augmented_data = self.augmentation_fcn(image=image,
                                                           keypoints=keypoints)
                    augmented_image = augmented_data['image']
                    pts = [(x, y) for (x, y, a, s) in augmented_data['keypoints']]
                    augmented_mask = \
                        points2mask(pts, augmented_image.shape, fill=self.fill)
                augmented_mask_batch[k] = augmented_mask
                augmented_image_batch[k] = augmented_image
            image_batch = augmented_image_batch
            mask_batch = np.array(augmented_mask_batch, dtype='float32')
        else:
            mask_batch = np.empty((bs,) + self.mask_shape, dtype='float32')
            for k, pts in enumerate(points_batch):
                mask_batch[k] = \
                    points2mask(pts, self.image_shape, fill=self.fill)

        return image_batch.astype('float32') / 255, mask_batch

    def preload(self):

        unformatted_points, headers = read_csv(self.points_path)
        images = []
        # masks = []
        points = []
        subset_dir = os.path.join(self.image_dir, self.subset)
        for fn in os.listdir(subset_dir):
            fn_full = os.path.join(subset_dir, fn)
            if fn.lower().endswith('jpg') or fn.lower().endswith('.jpeg'):

                try:
                    pts = unformatted_points[fn]
                except KeyError:
                    print('Data not found for "%s" in "%s"; skipping '
                          'this sample.' % (fn, self.points_path))
                    continue

                image = self.imread(fn_full)

                # resize image and transform points along with it
                image, transform = resize_preserving_aspect_ratio(
                    image, dsize=self.img_res, border_type='constant',
                    return_coordinate_transform=True)
                pts = [np.dot(transform, [[x], [y], [1]]) for x, y in pts]
                pts = [(int(np.round(x)), int(np.round(y))) for x, y in pts]

                images.append(image)
                # masks.append(points2mask(pts, image.shape))
                points.append(pts)

        if self.fill:
            self.mask_shape = self.img_res[::-1]
        else:
            self.mask_shape = self.img_res[::-1] + (len(points[0]),)

        print('preloaded %s %s images and %s %s points'
              '' % (len(images), self.subset, len(points), self.subset))
        self.images, self.points = np.array(images), np.array(points)
        # self.masks = np.array(masks)

    def imread(self, path):
        return scipy.misc.imread(path, mode='RGB')

    def on_epoch_end(self):
        """Updates indexes after each epoch"""
        # fetch all data in subset
        if self.images is None:
            self.preload()

        # shuffle (once each epoch)
        if self.shuffle:
            rng_state = np.random.get_state()
            np.random.shuffle(self.images)
            np.random.set_state(rng_state)
            # np.random.shuffle(self.masks)
            np.random.shuffle(self.points)

if __name__ == '__main__':

    # for testing that the data is being input as expected
    import argparse
    args = argparse.ArgumentParser()
    args.add_argument('images_dir', help="Directory of images.")
    args.add_argument('points_csv', help="Path to csv w/ feature locations.")
    args.add_argument('-s', '--image_dimensions', nargs=2, type=int,
                      default=(1024, 512),
                      help="Path to csv w/ feature locations.")
    args.add_argument('--subset', default='train',
                      help="Which data set to show 'train', 'val',  or 'test'.")
    args.add_argument('-a', '--augment', default=False, action='store_true',
                      help="Use augmentation.")
    args.add_argument('-f', '--fill', default=False, action='store_true',
                      help="Masks are to be (2-D) filled convex hulls, as "
                           "opposed to 3-tensors with one channel per point.")
    args.add_argument('-r', '--raster_then_augment',
                      default=False, action='store_true',
                      help="Rasterize points to mask before, as opposed "
                           "to after, augmentation step.  This is meant for"
                           "cases where `--fill` is invoked and augmentations "
                           "do not commute with convex hull operation.")
    args = args.parse_args()

    dataset = PointsDataGenerator(images_dir=args.images_dir,
                                  points_csv=args.points_csv,
                                  img_res=args.image_dimensions,
                                  image_channels=3,
                                  subset=args.subset,
                                  batch_size=2,
                                  augment=True,
                                  fill=args.fill,
                                  raster_then_augment=args.raster_then_augment)

    show_generated_pairs(dataset, fx=1, fy=1)


from __future__ import print_function
import os
from py2gcode import gcode_cmd
from py2gcode import cnc_drill
from params import params

safeZ = 0.15
startZ = 0.0
stepZ = 0.02
stopZ = -0.09
feedrate = 15
startDwell = 2.0

prog = gcode_cmd.GCodeProg()
prog.add(gcode_cmd.GenericStart())
prog.add(gcode_cmd.Space())
prog.add(gcode_cmd.FeedRate(feedrate))

for cx, cy in params['partPosList']:
    for i in (-1,1):
        for j in (-1,1):
            xPos = 0.5*i*params['mountHole']['spacing'] + cx
            yPos = 0.5*j*params['mountHole']['spacing'] + cy
            drillDict =  {
                    'centerX'    : xPos,
                    'centerY'    : yPos,
                    'startZ'     : startZ,
                    'stopZ'      : stopZ,
                    'safeZ'      : safeZ,
                    'stepZ'      : stepZ,
                    'startDwell' : startDwell,
                    }
            drill = cnc_drill.PeckDrill(drillDict)
            prog.add(drill)
            prog.add(gcode_cmd.Space())

prog.add(gcode_cmd.Space())
prog.add(gcode_cmd.End(),comment=True)
print(prog)
baseName, dummy = os.path.splitext(__file__)
fileName = '{0}.ngc'.format(baseName)
prog.write(fileName)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# --------------------------------------------------------------------------- #
__author__ = "Juan Luis Padilla Salomé"
__copyright__ = "Copyright 2021"
__credits__ = ["University of Cantabria", "Pablo Abad", "Pablo Prieto"]
__license__ = "GPL"
__version__ = "1.0.0"
__maintainer__ = "Juan Luis Padilla Salomé"
__email__ = "juan-luis.padilla@alumnos.unican.es"
__status__ = "Production"
# --------------------------------------------------------------------------- #

# --------------------------------------------------------------------------- #
if __name__ == "__main__":
    """
    TODO
    """

    # standard library
    import numpy as np
    import os

    # Forces the program to execute on CPU
    os.environ['CUDA_VISIBLE_DEVICES'] = '0'

    # Just disables the warning, doesn't take advantage of AVX/FMA to run faster
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

    # 3rd party packages
#    import tensorflow as tf
    from tensorflow import keras

    # ---------------- Setting up the inter and intra threads --------------- #
    # inter = tf.config.threading.get_inter_op_parallelism_threads()
    # intra = tf.config.threading.get_intra_op_parallelism_threads()

#    inter = 1
#    intra = 1

#    tf.config.threading.set_inter_op_parallelism_threads(inter)
#    tf.config.threading.set_intra_op_parallelism_threads(intra)

#    print("inter_op_parallelism_threads = {}\nintra_op_parallelism_threads = "
#          "{}".format(tf.config.threading.get_inter_op_parallelism_threads(),
#                      tf.config.threading.get_intra_op_parallelism_threads()))
    # ----------------------------------------------------------------------- #

    # ----------------------------------------------------------------------- #
    # Loads the my_callbacks library
    # ----------------------------------------------------------------------- #
    import sys
    import pathlib

    # Absolute path to this script
    MY_PAPI_DIR = pathlib.Path(__file__).absolute()
    # Now, we have to move to the root of this workspace ([prev. path]/TFG)
    MY_PAPI_DIR = MY_PAPI_DIR.parent.parent.parent.parent.parent.absolute()
    # From the root (TFG/) access to my_papi dir. and its content
    MY_PAPI_DIR = MY_PAPI_DIR / "my_papi"
    # Folder where the configuration files are located
    CFG_DIR = MY_PAPI_DIR / "conf"
    # Folder where the library is located
    LIB_DIR = MY_PAPI_DIR / "lib"
    # Folder where the source codes are located
    SRC_DIR = MY_PAPI_DIR / "src"

    # Add the source path and import the script
    sys.path.insert(0, str(SRC_DIR))
    from MyPapi import *

    # ----------------------------------------------------------------------- #
    # Params for the measure
    # ----------------------------------------------------------------------- #
    # Path to the library, needed to create an object of class my_papi
    libname = LIB_DIR / "libmy_papi.so"

    # Load a file with the events
    events_file = CFG_DIR / "events_node_mnist_test.cfg"

    # Output file with the measures
    train_output_file = "out/mnist_train_each_batch.csv"
    test_output_file = "out/mnist_test_each_batch.csv"
    predict_output_file = "out/mnist_predict_each_batch.csv"
    # train_output_file = test_output_file = predict_output_file = None
    # ----------------------------------------------------------------------- #

    # ------------------- Load the dataset and define it -------------------- #
    # Fetch and load common datasets, including Fashion MNIST
    # It has the exact same format as MNIST (70.000 grayscale image of 28 x
    # 28 pixels each, with 10 classes).
    fashion_mnist = keras.datasets.fashion_mnist

    # Images represented as a 28 x 28 array
    # Pixel intensities are represented as integers (from 0 to 255)

    # The dataset is already split inot a training set and a test set
    (X_train_full, Y_train_full), (X_test, Y_test) = fashion_mnist.load_data()

    # We'll create a validation set which will contain 5,000 images, and
    # the test set will contain 10,000 images. So, the others 55.000 images
    # will be used as trainning set
    X_valid, X_train = X_train_full[:5000] / 255., X_train_full[5000:] / 255.
    Y_valid, Y_train = Y_train_full[:5000], Y_train_full[5000:]
    X_test = X_test / 255.

    # List of class names
    class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat",
                   "Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]
    # ----------------------------------------------------------------------- #

    # ------------- Creating the model using the Sequential API ------------- #
    # 1. Creates a Sequential model. Layers connected sequentially
    model = keras.models.Sequential()

    # 2. Adds a flatten layer whose role is to convert each input image
    # into a 1D array.
    model.add(keras.layers.Flatten(input_shape=[28, 28]))

    # 3. Adds a dense hidden layer with 300 neurons using the ReLU
    # activation function. Each one manages its own weight matrix.
    model.add(keras.layers.Dense(300, activation="relu"))

    # 4. Adds a second dense hidden layer with 100 neurons using the ReLU
    # activation function.
    model.add(keras.layers.Dense(100, activation="relu"))

    # 5. Finaly, add a dense output layer with 10 neurons (one per class),
    # using the softmax activation function (beacuse the classes are
    # exclusive).
    model.add(keras.layers.Dense(10, activation="softmax"))

    # Compiling
    model.compile(loss="sparse_categorical_crossentropy",
                  optimizer="sgd",
                  metrics=["accuracy"])
    # ----------------------------------------------------------------------- #

    # Creates a callback from my_papi library
    my_callbacks = MeasureOnEachBatch(lib_path=str(libname),
                                      events_file=str(events_file),
                                      output_file=str(train_output_file))

    # ----------------------------------------------------------------------- #
    # ! TRAIN
    # ----------------------------------------------------------------------- #
    history = model.fit(x=X_train,
                        y=Y_train,
                        batch_size=110,
                        epochs=30,
                        verbose=1,
                        callbacks=my_callbacks,
                        validation_split=0.,
                        validation_data=None,
                        shuffle=True,
                        class_weight=None,
                        sample_weight=None,
                        initial_epoch=0,
                        steps_per_epoch=None,
                        validation_steps=None,
                        validation_batch_size=None,
                        validation_freq=1,
                        max_queue_size=10,
                        workers=1,
                        use_multiprocessing=False)
    # ----------------------------------------------------------------------- #
    # ! END TRAIN
    # ----------------------------------------------------------------------- #

    # # ----------------------------------------------------------------------- #
    # # ! TEST
    # # ----------------------------------------------------------------------- #
    # model.evaluate(x=X_test,
    #                y=Y_test,
    #                batch_size=None,
    #                verbose=1,
    #                sample_weight=None,
    #                steps=None,
    #                callbacks=my_callbacks,
    #                max_queue_size=10,
    #                workers=1,
    #                use_multiprocessing=False,
    #                return_dict=False)
    # # ----------------------------------------------------------------------- #
    # # ! END TEST
    # # ----------------------------------------------------------------------- #

    # # Get the last n items of the test dataset
    # n_items = 15
    # X_new = X_test[:n_items]

    # # ----------------------------------------------------------------------- #
    # # ! PREDICT
    # # ----------------------------------------------------------------------- #
    # y_proba = model.predict(x=X_new,
    #                         batch_size=None,
    #                         verbose=0,
    #                         steps=None,
    #                         callbacks=my_callbacks,
    #                         max_queue_size=10,
    #                         workers=1,
    #                         use_multiprocessing=False)
    # # ----------------------------------------------------------------------- #
    # # ! END PREDICT
    # # ----------------------------------------------------------------------- #

    # # Check if the prediction is correct:
    # # From the list, get the option which has most probab.
    # y_pred = np.argmax(y_proba, axis=-1)
    # # We can get the correspondences between class name and num
    # pred = np.array(class_names)[y_pred]

    # # And check if it its correct
    # y_new = Y_test[:n_items]
    # sol = np.array(class_names)[y_new]

    # print("Clothes predicted: {}\nClothes tested: {}".format(pred, sol))

    my_callbacks.finalize_measure()

    # MyPapi.dash_table_by_cpus_static(str(output_file))


import numpy as np
import cv2
import time
from grabscreen.grabscreen import grab_screen

def capture_full_screen():

    captured_screen = grab_screen(region=(0,27,640,425))
    rgb_full_screen = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_full_screen

#drivingwindow
def capture_drivingwindow():

    captured_screen = grab_screen(region=(0,140,640,245))
    rgb_drivingwindow = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_drivingwindow

#race map
def capture_map():

    captured_screen = grab_screen(region=(0,27,170,100))
    rgb_map = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_map

#scoreboard
def capture_scoreboard():

    captured_screen = grab_screen(region=(490,31,630,88))
    rgb_scoreboard = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_scoreboard

#speedometer
def capture_speedometer():

    captured_screen = grab_screen(region=(205,250,255,275))
    rgb_speedometer = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_speedometer

#health meter
def capture_healthmeter():

    captured_screen = grab_screen(region=(268,250,435,270))
    rgb_healthmeter = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_healthmeter

#RPM gauge
def capture_RPMgauge():

    captured_screen = grab_screen(region=(255,295,385,395))
    rgb_RPMgauge = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_RPMgauge

#Steering wheel
def capture_steeringwheel():

    captured_screen = grab_screen(region=(180,270,460,420))
    rgb_steeringwheel = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_steeringwheel

#Gear box to shift gears
def capture_gears():

    captured_screen = grab_screen(region=(525,325,610,410))
    rgb_gears = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_gears

#Left rearview mirror
def capture_leftRvm():

    captured_screen = grab_screen(region=(0,250,130,300))
    rgb_leftRvm = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_leftRvm

#Right rearview mirror
def capture_rightRvm():

    captured_screen = grab_screen(region=(510,250,(510+130),300))
    rgb_rightRvm = cv2.cvtColor(captured_screen, cv2.COLOR_BGR2RGB)
    return rgb_rightRvm

if __name__ == "__main__":

    while True:

        #Capture game window and convert from BGR to RGB
        full_screen = capture_full_screen()
        drivingwindow = capture_drivingwindow()
        map_image = capture_map()
        scoreboard = capture_scoreboard()
        speedometer = capture_speedometer()
        healthmeter = capture_healthmeter()
        RPMgauge = capture_RPMgauge()
        steeringwheel = capture_steeringwheel()
        gears = capture_gears()
        leftRvm = capture_leftRvm()
        rightRvm = capture_rightRvm()

        #cv2.imshow('full screen',full_screen)
        cv2.imshow('driving window',drivingwindow)
        #cv2.imshow('map',map_image)
        #cv2.imshow('scoreboard',scoreboard)
        #cv2.imshow('speedometer',speedometer)
        #cv2.imshow('healthmeter',healthmeter)
        #cv2.imshow('RPMgauge',RPMgauge)
        cv2.imshow('steering wheel',steeringwheel)
        #cv2.imshow('gears',gears)
        #cv2.imshow('leftRvm',leftRvm)
        #cv2.imshow('rightRvm',rightRvm)

        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break