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

import logging
import os
import torch

from TransXL.metrics import classification_report
from TransXL.metrics import f1_score

class InputFeatures(object):
  """
  Input feature for BERT.
  """
  def __init__(self, input_id, label_id, input_mask):
    """
    Args:
      input_id(int): Id of character.
      label_id(str): Id of label for classify.
      input_mask(int): Mask flag, 0 or 1.
    """
    self.input_id = input_id
    self.label_id = label_id
    self.input_mask = input_mask

def load_vocab(vocab_file):
  """
  Loads a vocabulary file into a dictionary.

  Args:
    vocab_file(str): file path.

  Returns:
    vocab(dict): Character and index map.
  """
  vocab = {}
  index = 0
  with open(vocab_file, "r", encoding="utf-8") as reader:
    while True:
      token = reader.readline()
      if not token:
          break
      token = token.strip()
      vocab[token] = index
      index += 1
  return vocab

def get_text_line_feature(sentense, vocab, max_length=512):
  """
  Gets text feature.

  Args:
    sentense(str): Input string.
    vocab(dict): Character and index map.
    max_length(int): Input content max length.

  Returns:
    feature(InputFeatures): Feature of sentense.
  """
  tokens = list(sentense.replace(" ", ""))
  tokens_f = ['[CLS]'] + tokens + ['[SEP]']
  input_ids = [
    int(vocab[i]) if i in vocab else int(vocab['[UNK]']) for i in tokens_f]
  input_mask = [1] * len(input_ids)
  while len(input_ids) < max_length:
    input_ids.append(0)
    input_mask.append(0)
  feature = InputFeatures(
    input_id=input_ids, input_mask=input_mask, label_id=None)
  return feature

def id2tag(tag_id, ids):
  """
  Index to tag.

  Args:
    tag_id(dict): Label and index map.
    ids(list): List of tag.

  Returns:
    tags(list): Tags of ids.
  """
  id_tag = dict([val, key] for key, val in tag_id.items())
  tags = [id_tag.get(id) for id in ids]
  return tags

def decode_tags_biose(text, tags):
  """
  Decodes BIOSE to string with tag.

  Args:
    text(str): Origin string.
    tags(list): Tag of string.

  Returns:
    item(dict): Decoded result of current string.
  """
  item = {"string": text, "entities": []}
  entity_name = ""
  entity_start = 0
  idx = 0
  for char, tag in zip(text, tags):
    if tag[0] == "S":
      item["entities"].append(
        {"word": char, "start": idx, "end": idx+1, "type": tag[2:]})
    elif tag[0] == "B":
      entity_name += char
      entity_start = idx
    elif tag[0] == "I":
      if idx - 1 >= 0:
        if tags[idx-1] == "O":
          entity_start = idx
      entity_name += char
    elif tag[0] == "E":
      if entity_name:
        entity_name += char
        if len(set([t[2:] for t in tags[entity_start:idx +1]])) == 1:
          item["entities"].append(
            {"word": entity_name, "start": entity_start, "end": idx + 1, "type": tag[2:]})
        entity_name = ""
    else:
      entity_name = ""
      entity_start = idx
    idx += 1
  return item

def decode_tags_io(text, tags):
  """
  Decodes IO to string with tag.

  Args:
    text(str): Origin string.
    tags(list): Tag of string.

  Returns:
    item(dict): Decoded result of current string.
  """
  item = {"string": text, "entities": []}
  entity_name = ""
  entity_start = 0
  last_tag = ""
  for idx, (char, tag) in enumerate(zip(text, tags)):
    if tag not in ["O", "<pad>", "<start>", "<eos>"]:
      entity_tag = tag[2:]
    else:
      entity_tag = "O"
    if entity_tag != "O":
      # entity_tag = tag[2:]
      if last_tag != entity_tag:
        entity_name = char
        entity_start = idx
      else:
        entity_name += char
      if idx == len(tags)-1 or tags[idx+1][2:] != entity_tag:
        if len(set([t[2:] for t in tags[entity_start:idx + 1]])) == 1:
          if text[entity_start:idx + 1] != entity_name:
            print("tttttttttttt")
          item["entities"].append(
            {"word": entity_name, "start": entity_start, "end": idx + 1, "type": tag[2:]})
        entity_name = ""
    else:
      entity_name = ""
      entity_start = idx
    last_tag = entity_tag
  return item

def compute(pre, groud_true):
  """
  Computes correct.

  Args:
    pre(list): Predicted tags.
    groud_true(list): Tags of groud true.

  Returns:
    correct_num(int): Num of correct.
  """
  correct_num = 0
  use_num = 0
  for p, t in zip(pre, groud_true):
    if p == "o":
      continue
    use_num += 1
    if p == t:
      correct_num += 1
  return correct_num

def evaluate(true_tags, pred_tags, verbose=False):
  """
  Evaluate method.

  Args:
    true_tags(list): Tags of groud true.
    pred_tags(list): Tags of predict.
    verbose(bool): Whether need verbose f1 report.

  Returns:
    metrics(dict): Metrics of evaluation.
  """
  metrics_all = f1_score(true_tags, pred_tags)
  # logger.debug("Metrics: {}".format(metrics_all))
  metrics = metrics_all.get("avg")

  metrics_str = "; ".join("{}: {:05.2f}".format(k, v)
    for k, v in metrics.items())
  logger.debug("- {} metrics: ".format(metrics_str))
  print("- {} metrics: ".format(metrics_str))
  if verbose:
    report = classification_report(true_tags, pred_tags)
    logger.debug(report)
  return metrics

def decode_tags_bio(text, tags):
  """
  Decodes BIO to string with tag.

  Args:
    string(str): Origin string.
    tags(list): Tag of string.

  Returns:
    item(dict): Decoded result of current string.
  """
  item = {"text": text, "entities": []}
  entity_name = ""
  entity_start = 0
  count = 0
  entity_tag = ""
  for c_idx in range(len(text)):
    c, tag = text[c_idx], tags[c_idx]
    if c_idx < len(tags)-1:
      tag_next = tags[c_idx+1]
    else:
      tag_next = ''
    if tag[0] == 'B':
      entity_tag = tag[2:]
      entity_name = c
      entity_start = count
      if tag_next[2:] != entity_tag:
        item["entities"].append({"word": c, "start": count, "end": count + 1, "type": tag[2:]})
    elif tag[0] == "I":
      if tag[2:] != tags[c_idx-1][2:] or tags[c_idx-1][2:] == 'O':
        tags[c_idx] = 'O'
        pass
      else:
        entity_name = entity_name + c
        if tag_next[2:] != entity_tag:
          item["entities"].append(
            {"word": entity_name, "start": entity_start, "end": iCount + 1, "type": entity_tag})
          entity_name = ''
    count += 1
  return item

def save_model(model, epoch, path='result', **kwargs):
  """
  Saves model.

  Args:
    model(BERT_LSTM_CRF): Model of BERT_LSTM_CRF.
    epoch(int): Number of epoch.
    path(str): Model saved path.
  """
  if not os.path.exists(path):
    os.mkdir(path)
  if kwargs.get('name', None) is None:
    f1 = 0.0
    if kwargs.get("f1"):
      f1 = kwargs.get("f1")
    name = ('epoch_' + str(epoch) +
      "_loss_" + str('%.3f' % kwargs.get("loss")) + "f1_" + str(f1) + ".pkl")
    full_name = os.path.join(path, name)
    if isinstance(model, torch.nn.DataParallel):
      model = model.module
    torch.save(model, full_name)
    print('Saved model at epoch {} successfully'.format(epoch))
    with open('{}/checkpoint'.format(path), 'w') as file:
      file.write(name)
      print('Write to checkpoint')
    file_list = os.listdir(path)
    file_list = sorted(
      file_list, key=lambda x: os.path.getmtime(os.path.join(path, x)))
    surplus = file_list[:-6]
    for file_name in surplus:
      os.remove(os.path.join(path, file_name))

def save_train_model(model, epoch, path='result', **kwargs):
  """
  Saves model.

  Args:
    model(BERT_LSTM_CRF): Model of BERT_LSTM_CRF.
    epoch(int): Number of epoch.
    path(str): Model saved path.
  """
  if not os.path.exists(path):
    os.mkdir(path)
  if kwargs.get('name', None) is None:
    f1 = 0.0
    if kwargs.get("f1"):
      f1 = kwargs.get("f1")
    name = ('epoch_' + str(epoch) +
      "_loss_" + str('%.3f' % kwargs.get("loss")) + "f1_" + str(f1) + ".pth")
    full_name = os.path.join(path, name)
    if isinstance(model, torch.nn.DataParallel):
      model = model.module

    print('Saved model at epoch {} successfully'.format(epoch))
    with open('{}/checkpoint'.format(path), 'w') as file:
      file.write(name)
      print('Write to checkpoint')
    file_list = os.listdir(path)
    file_list = sorted(
      file_list, key=lambda x: os.path.getmtime(os.path.join(path, x)))
    surplus = file_list[:-1]
    for file_name in surplus:
      os.remove(os.path.join(path, file_name))
    torch.save(model.state_dict(), full_name)

def load_model(path='result', **kwargs):
  """
  Loads model.

  Args:
    model(BERT_LSTM_CRF): Model of BERT_LSTM_CRF.
    path(str): Model saved path.

  Returns:
    model(BERT_LSTM_CRF): Model of BERT_LSTM_CRF after added weights.
  """
  if kwargs.get('name', None) is None:
    with open('{}/checkpoint'.format(path)) as file:
      content = file.read().strip()
      name = os.path.join(path, content)
  else:
    name = kwargs['name']
    name = os.path.join(path, name)
  model = torch.load(name, map_location=lambda storage, loc: storage)
  print('load model {} successfully'.format(name))
  return model

def load_train_model(model, path='result', **kwargs):
  if kwargs.get('name', None) is None:
    with open('{}/checkpoint'.format(path)) as file:
      content = file.read().strip()
      name = os.path.join(path, content)
  else:
    name = kwargs['name']
    name = os.path.join(path, name)
  model.load_state_dict(torch.load(name, map_location=lambda storage, loc: storage))
  print('load model {} successfully'.format(name))
  return model

def iob_iobes(tags):
  """
  BIO mode to BIOSE.

  Args:
    tags(list): BIO tags.

  Returns:
    new_tags(list): BIOSE tags.
  """
  new_tags = []
  for i, tag in enumerate(tags):
    if tag == 'O':
      new_tags.append(tag)
    elif tag.split('-')[0] == 'B':
      if i + 1 != len(tags) and tags[i + 1].split('-')[0] == 'I':
        new_tags.append(tag)
      else:
        new_tags.append(tag.replace('B-', 'S-'))
    elif tag.split('-')[0] == 'I':
      if i + 1 < len(tags) and tags[i + 1].split('-')[0] == 'I':
        new_tags.append(tag)
      else:
        new_tags.append(tag.replace('I-', 'E-'))
    else:
      raise Exception('Invalid IOB format!')
  return new_tags

def iobes_iob(tags):
  """
  BIOSE mode to BIO.

  Args:
    tags(list): BIOSE tags.

  Returns:
    new_tags(list): BIO tags.
  """
  new_tags = []
  for i, tag in enumerate(tags):
    if tag.split('-')[0] == 'B':
      new_tags.append(tag)
    elif tag.split('-')[0] == 'I':
      new_tags.append(tag)
    elif tag.split('-')[0] == 'S':
      new_tags.append(tag.replace('S-', 'B-'))
    elif tag.split('-')[0] == 'E':
      new_tags.append(tag.replace('E-', 'I-'))
    elif tag.split('-')[0] == 'O':
      new_tags.append(tag)
    else:
      raise Exception('Invalid format!')
  return new_tags

def get_logger():
  """
  Gets logger obj.

  Returns:
    logger(loggerClass): Logger util.
  """
  logger = logging.getLogger("train")
  logger.setLevel(logging.DEBUG)
  # Builds filehandler write log, above debug level.
  fh = logging.FileHandler("train.log")
  fh.setLevel(logging.DEBUG)
  # Builds streamhandler CMD window，above error.
  ch = logging.StreamHandler()
  ch.setLevel(logging.ERROR)
  # Sets log format.
  formatter = logging.Formatter(
    "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
  ch.setFormatter(formatter)
  fh.setFormatter(formatter)
  # Adds handler to logger obj.
  logger.addHandler(ch)
  logger.addHandler(fh)
  return logger

logger = get_logger()


import egraph as eg
import networkx as nx
import unittest

def create_graph(nx_graph):
    graph = eg.DiGraph() if nx.is_directed(nx_graph) else eg.Graph()
    indices = {}
    for u in nx_graph.nodes:
        indices[u] = graph.add_node(u)
    for u, v in nx_graph.edges:
        graph.add_edge(indices[u], indices[v], (u, v))
    return (nx_graph, graph)

class TestShortestPath(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._graphs = [
            create_graph(nx.les_miserables_graph().to_undirected()),
        ]
        cls._digraphs = [
            create_graph(nx.les_miserables_graph().to_directed()),
            create_graph(nx.gn_graph(100, seed=0))
        ]

    def check(self, nx_graph, d_actual):
        d_expected = nx.floyd_warshall_numpy(nx_graph, weight='dummy')
        n = nx_graph.number_of_nodes()
        for i in range(n):
            for j in range(n):
                self.assertEqual(
                    d_actual.get(i, j),
                    d_expected[j, i],
                    f'({i},{j})'
                )

    def test_all_sources_bfs(self):
        for nx_graph, graph in self._graphs:
            self.check(nx_graph, eg.all_sources_bfs(graph, 1))

    def test_all_sources_bfs_directed(self):
        for nx_graph, graph in self._digraphs:
            self.check(nx_graph, eg.all_sources_bfs(graph, 1))

    def test_all_sources_dijkstra(self):
        for nx_graph, graph in self._graphs:
            self.check(nx_graph, eg.all_sources_dijkstra(graph, lambda _: 1))

    def test_all_sources_dijkstra_directed(self):
        for nx_graph, graph in self._digraphs:
            self.check(nx_graph, eg.all_sources_dijkstra(graph, lambda _: 1))

    def test_warshall_floyd(self):
        for nx_graph, graph in self._graphs:
            self.check(nx_graph, eg.warshall_floyd(graph, lambda _: 1))

    def test_warshall_floyd_directed(self):
        for nx_graph, graph in self._digraphs:
            self.check(nx_graph, eg.warshall_floyd(graph, lambda _: 1))

if __name__ == '__main__':
    unittest.main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import print_function
"""
Created on Tue Sep  1 13:06:23 2020

@author: xingshuli
"""

import os
import numpy as np

from keras import backend as K
from keras.models import load_model
from keras.preprocessing import image

#import cv2

import matplotlib.pyplot as plt

#load model
model_save_dir = os.path.join(os.getcwd(), 'Multi_Scale_Model')
model_name = 'keras_trained_model.h5'
model_save_path = os.path.join(model_save_dir, model_name)
model = load_model(model_save_path)

#get output of ith layer: 68, 69, 70, color = b, m, r
i = 70
get_ith_layer_output = K.function([model.layers[0].input, K.learning_phase()],
                                  [model.layers[i].output])

#load image
img_path = '/home/xingshuli/Desktop/test_pictures/green_2.jpg'

img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x /=255.
print('Input image shape:', x.shape)

#output in test mode = 0
layer_output = get_ith_layer_output([x, 0])[0]
length = layer_output.shape[3]
layer_output = layer_output.reshape(length)
layer_output = np.array(layer_output)

mu = np.mean(layer_output)
mu = round(mu, 4)
sigma = np.std(layer_output)
sigma = round(sigma, 4)

#draw histogram

plt.hist(layer_output,
         bins = 40,
         edgecolor = 'k',
         color = 'r')
title_name = 'mu = ' + str(mu) + ', ' + 'sigma = ' + str(sigma)
plt.title(title_name, fontsize = 16)
plt.xlabel('Value', fontsize = 14)
plt.ylabel('Count', fontsize = 14)

plt.rcParams['xtick.labelsize'] = 14
plt.rcParams['ytick.labelsize'] = 14

plt.savefig('s.png', dpi = 800)


from datetime import datetime

import syncano
from syncano.models import Class, GeoPoint, Object

INSTANCE_NAME = 'INSTANCE NAME'
API_KEY = 'ADMIN API KEY'

connection = syncano.connect(
    api_key=API_KEY,
    instance_name=INSTANCE_NAME,
)

class RestaurantAppDataCreator(object):

    ITEM = 'item'
    MENU = 'menu'
    RESERVATION = 'reservation'
    TABLE = 'table'
    TAG = 'tag'
    RESTAURANT = 'restaurant'

    item_schema = [
        {"name": "name", "type": "string", "filter_index": True},
        {"name": "description", "type": "string"},
        {"name": "price", "type": "integer"},
        {"name": "header_picture", "type": "file"},
        {"name": "body_picture", "type": "file"},
    ]

    menu_schema = [
        {"name": "name", "type": "string"},
        {"name": "items", "type": "relation", "target": "item"},
        {"name": "start_date", "type": "datetime", "filter_index": True},
        {"name": "end_date", "type": "datetime", "filter_index": True},
        {"name": "restaurant", "type": "reference", "target": "restaurant", "filter_index": True},
    ]

    reservation_schema = [
        {"name": "date", "type": "datetime"},
        {"name": "user_identifier", "type": "string"},
    ]

    table_schema = [
        {"name": "identifier", "type": "string"},
        {"name": "person_count", "type": "integer", "filter_index": True},
        {"name": "by_window", "type": "boolean", "filter_index": True},
        {"name": "reserved", "type": "boolean", "filter_index": True},
        {"name": "reservations", "type": "relation", "target": "reservation"},
    ]

    tag_schema = [
        {"name": "tag", "type": "string", "filter_index": True},
        {"name": "description", "type": "string"},
    ]

    restaurant_schema = [
        {"name": "name", "type": "string", "filter_index": True},
        {"name": "location", "type": "geopoint", "filter_index": True},
        {"name": "phone_number", "type": "string"},
        {"name": "tables", "type": "relation", "target": "table", "filter_index": True},
        {"name": "tags", "type": "relation", "target": "tag", "filter_index": True},
    ]

    def clear_classes(self):
        for class_name in [self.ITEM, self.MENU, self.TABLE, self.TAG, self.RESTAURANT, self.RESERVATION]:
            try:
                Class.please.delete(name=class_name)
            except Class.DoesNotExist:
                continue

    def populate_classes(self):

        classes = [
            (self.RESERVATION, self.reservation_schema),
            (self.TABLE, self.table_schema),
            (self.TAG, self.tag_schema),
            (self.RESTAURANT, self.restaurant_schema),
            (self.ITEM, self.item_schema),
            (self.MENU, self.menu_schema),
        ]

        for cl in classes:
            class_name = cl[0]
            class_schema = cl[1]
            Class.please.create(name=class_name, schema=class_schema)

    def populate_initial_objects(self):
        # create restaurants
        # you can do it that way
        pit_bull = Object.please.create(
            class_name=self.RESTAURANT,
            name='Pit Bull - London Steakhouse',
            phone_number='+48 444 333 222',
            location=GeoPoint(52.2297, 21.0122),
        )
        # or that way (this one is shorter and looks better)
        restaurant_class = Class.please.get(name=self.RESTAURANT)  # this can be assigned when class was created;
        blue_pizza = restaurant_class.objects.create(
            name='Blue Pizza',
            phone_number='+48 444 333 111',
            location=GeoPoint(51.2000, 20.0100),
        )

        # create tags

        steaks_tag = Object.please.create(class_name=self.TAG, tag='steaks')
        burgers_tag = Object.please.create(class_name=self.TAG, tag='burgers')
        pizza_tag = Object.please.create(class_name=self.TAG, tag='pizza')
        pasta_tag = Object.please.create(class_name=self.TAG, tag='pasta')

        # assing tags to restaurants
        pit_bull.tags_set.add(steaks_tag, burgers_tag)
        blue_pizza.tags_set.add(pizza_tag, pasta_tag)

        # create tables
        table_in_pit_bull_a = Object.please.create(
            class_name=self.TABLE,
            person_count=4,
            by_window=True,
            reserved=False,
            identifier='Table A',
        )
        table_in_pit_bull_b = Object.please.create(
            class_name=self.TABLE,
            person_count=2,
            by_window=False,
            reserved=False,
            identifier='Table B'
        )

        table_in_blue_pizza_c = Object.please.create(
            class_name=self.TABLE,
            person_count=4,
            by_window=True,
            reserved=False,
            identifier='Table C',
        )
        table_in_blue_pizza_d = Object.please.create(
            class_name=self.TABLE,
            person_count=2,
            by_window=False,
            reserved=False,
            identifier='Table D'
        )

        # assign to restaurants
        pit_bull.tables_set.add(table_in_pit_bull_a, table_in_pit_bull_b)
        blue_pizza.tables_set.add(table_in_blue_pizza_c, table_in_blue_pizza_d)

        # create menu items

        steak = Object.please.create(
            class_name=self.ITEM,
            name="T Bone",
            description="T Bone steak",
            price=60
        )
        burger = Object.please.create(
            class_name=self.ITEM,
            name="The Killer",
            description="300 g burger with 200 g of bacon",
            price=35
        )
        pizza = Object.please.create(
            class_name=self.ITEM,
            name="Four seasons",
            description="Four kinds of cheese",
            price=30
        )
        pasta = Object.please.create(
            class_name=self.ITEM,
            name="Carbonara",
            description="Pasta with bacon and eggs",
            price=35
        )

        # create menus
        now = datetime.now()
        steakhouse_menu = Object.please.create(  # noqa
            class_name=self.MENU,
            name="Burger promo 1",
            restaurant=pit_bull.id,
            start_date=now,
            items=[steak, burger]
        )
        pizza_menu = Object.please.create(  # noqa
            class_name=self.MENU,
            name="Calzone promo 1",
            restaurant=blue_pizza.id,
            start_date=now,
            items=[pizza, pasta]
        )

    def rebuild_data(self):
        self.clear_classes()
        self.populate_classes()
        self.populate_initial_objects()

r_app = RestaurantAppDataCreator()
r_app.rebuild_data()


import pathlib
from typing import Optional

import cv2
import copy
import matplotlib.pyplot as plt
import numpy as np

from ..module import Module
from ...utils import normalize, MovingAverageFilter

class ReprojectionModule(Module):
    def __init__(self, log_dir: pathlib.Path, args=None):
        super(ReprojectionModule, self).__init__(name="reprojection_module",
                                                 inputs=["position_module:homography"],
                                                 outputs=[("points3d", 1000), ("criticality", 1000)],
                                                 log_dir=log_dir)

        self.average_filter = MovingAverageFilter()
        self.use_alignment = False

        self.last_update_ts = None
        self.P0 = np.dot(self.intrinsic_matrix, np.eye(3, 4))

        self.forward_direction = np.array((1., 0., 0.))

    def start(self):
        criticality_smooth = 0.0
        while True:
            homog_payload = self.get("position_module:homography")
            if homog_payload:
                homography = homog_payload["data"]["homography"]
                point_pairs = homog_payload["data"]["point_pairs"]
                timestamps = homog_payload["data"]["timestamps"]
                image = homog_payload["data"]["image"]

                P1 = np.dot(self.intrinsic_matrix, homography)

                points_homo = cv2.triangulatePoints(self.P0, P1, np.transpose(point_pairs[0]), np.transpose(point_pairs[1]))
                points3d = cv2.convertPointsFromHomogeneous(points_homo.T)

                # Ensure that signs of points are correct
                for point in points3d:
                    # Matrix to vector
                    point_temp = copy.deepcopy(point[0])
                    point = point[0]

                    # Change coordinate system
                    point[0] =  point_temp[2]
                    point[1] = -point_temp[0]
                    point[2] = -point_temp[1]

                collision_probability = self.update_collision_probability(points3d, timestamps[1], image, homography)

                self.publish("points3d", data={"cloud": points3d, "crit": collision_probability}, validity=-1, timestamp=self.get_time_ms())

                uncertainty = self.average_filter("uncertainty", self.update_uncertainty(points3d.shape[0], timestamps[1]))

                self.last_update_ts = timestamps[1]

    def project3dto2d(self, homography: np.array, points3d: np.array):
        rot_vec = cv2.Rodrigues(homography[:, :3])[0]
        trans_vec = homography[:, 3:]
        try:
            points2d = cv2.projectPoints(points3d, rot_vec, trans_vec, self.intrinsic_matrix, distCoeffs=None)[0]
        except Exception as e:
            points2d = np.array([])
        return points2d

    @staticmethod
    def visualize_reprojection(point_pairs: np.array, points2d: np.array, image: np.array):
        pink = (255, 153, 255)
        orange = (255, 128, 0)
        keypoints = [cv2.KeyPoint(points2d[i, 0, 0], points2d[i, 0, 1], 5) for i in range(points2d.shape[0])]
        image = cv2.drawKeypoints(image, keypoints, None, color=pink, flags=0)
        for i in range(point_pairs.shape[0]):
            image = cv2.line(image, tuple(point_pairs[1, :, i]), tuple(points2d[i, 0, :]), orange, 5)

        return image

    def update_collision_probability(self, points3d: np.array, timestamp: float, image: np.array, homography):

        point_vectors: np.array = points3d.reshape((points3d.shape[0], 3))

        distances = np.linalg.norm(point_vectors, axis=1, keepdims=False)

        smooth_mean_distance = self.average_filter("mean_distance", distances.mean(), 20)

        # get the indices of the 10th percentile smallest distances
        n = int(0.05 * distances.shape[0])
        if n > 5:
            idxs = np.argpartition(distances, n)[:n]
            critical_points_3d = point_vectors[idxs, :]

            alignment_vectors = np.cross(critical_points_3d, self.forward_direction)
            alignment = np.linalg.norm(alignment_vectors, axis=1, keepdims=False)

            smooth_critical_alignment = self.average_filter("critical_alignments", np.arctan(alignment.mean()) * 2 / np.pi, 20)

            probability = (np.arctan(1 / distances) * 2 / np.pi).mean()
        else:
            probability = 0.0
        smooth_probability = self.average_filter("probability", probability, 50)

        # plt.scatter(timestamp, smooth_mean_distance, c="b")
        # plt.scatter(timestamp, smooth_critical_alignment , c="g")
        #plt.scatter(timestamp, smooth_probability, c="r")
        #plt.pause(0.001)

        return 2.0*smooth_probability

    def update_uncertainty(self, n_features: int, timestamp: float):
        # compares the expected number of features and the actual number of features.
        expected_n_features = self.average_filter("n_features", n_features, window_size=20)
        if n_features > expected_n_features:
            features_confidence = 1.0
        else:
            features_confidence = (expected_n_features - n_features) / expected_n_features

        assert 0 <= features_confidence <= 1.0, f"features_confidence should be in interval 0,1 but was {features_confidence}"

        if self.last_update_ts is not None:

            time_delta = timestamp - self.last_update_ts
            expected_time_delta = self.average_filter("time_delta", time_delta, window_size=20)

            if time_delta > expected_time_delta:
                time_confidence = 1.0
            else:
                time_confidence = (expected_time_delta - time_delta) / expected_time_delta
        else:
            time_confidence = 1.0

        assert 0 <= time_confidence <= 1.0, "time_confidence should be in interval 0,1"

        # take the average between the feature confidence and the time confidence
        confidence: float = (features_confidence + time_confidence) / 2

        uncertainty: float = 1. - confidence

        assert 0 <= uncertainty <= 1.0, "uncertainty should be in interval 0,1"
        return uncertainty


import cv2

vid = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier()
face_cascade.load('face_model.xml')

if face_cascade is None:
    print('something fishy')

while True:
    state, frame = vid.read()
    if not state:
        print('cant find any frame in video, exiting')
        break
    # face detection logic
    gray =cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray)
    print("faces",len(faces))
    if len(faces) > 0:
        for x,y,w,h, in faces:
            frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,255,0),6)

    cv2.imshow("video",frame)
    if cv2.waitKey(1) == ord('q'):
        break

vid.release()
cv2.destroyAllWindows()


import PyPDF2
import os

def parse_docs():
    path = "./src/cache/"

    all_text = []

    for i, filename in enumerate(os.listdir(path)):
        file_path = os.path.join(path, filename)
        # checking if it is a file
        if os.path.isfile(file_path):

            text_obj = {}

            reader = PyPDF2.PdfReader(file_path)

            full_txt = ""
            for page in reader.pages:
                full_txt += page.extract_text()

            #For some reason ČSI labels all pdfs differently every year
            pdf_idx = file_path.replace("./src/cache/", "").replace(".pdf", "")[-1]
            if pdf_idx == "0" or pdf_idx == "1":

                #parse txt to get rid of useless parts
                idx = full_txt.find("Závěry")
                top_parse = full_txt[idx:]

                idx = top_parse.find("Seznam dokladů")
                bot_parse = top_parse[:idx]

            elif pdf_idx == "2":

                #parse txt to get rid of useless parts
                idx = full_txt.find("Celkové hodnocení školy")
                top_parse = full_txt[idx:]

                idx = top_parse.find("Seznam písemností,")
                bot_parse = top_parse[:idx]

            elif pdf_idx == "3":

                #parse txt to get rid of useless parts
                idx = full_txt.find("ZÁVĚR")
                top_parse = full_txt[idx:]

                idx = top_parse.find("Razítko")
                bot_parse = top_parse[:idx]

            elif pdf_idx == "4":

                #parse txt to get rid of useless parts
                idx = full_txt.find("ZÁVĚR")
                top_parse = full_txt[idx:]

                idx = top_parse.find("Razítko")
                bot_parse = top_parse[:idx]

            text_obj["label"] = file_path.replace("./src/cache/", "").replace(".pdf", "")[:-2]
            text_obj["text"] = bot_parse

            all_text.append(text_obj)

    return all_text

if __name__ == "__main__":
    print(os.getcwd())
    parse_docs()


import sys
import nltk
import json
import time
import datetime
from daterangeparser import parse
from extractor import extract_location, concat_cfp_event, extract_dates, extract_event_name

verbose = False
if len(sys.argv) > 1 and sys.argv[1] == '-v':
    verbose = True

# Email Evaluation
with open('labeled_emails.json') as f:
    emails = json.load(f)

num_correct_dates = 0
num_possible_dates = 0
num_correct = 0
num_correct_name_email = 0
num_labeled_emails = len(emails)
for email in emails:
    #print(email.keys())
    # Name Evaluation
    if 'name' in email.keys() and email['name'] != 'N/A' and email['location'] != 'N/A' \
        and email['submission_date'] != 'N/A':
      name_prediction = extract_event_name(email['description'])
      name_label = email['name']

      if verbose:
         print("Name Prediction: {}\t Name Label: {}".format(name_prediction, name_label))
         print()
      if name_prediction is not None:
         prediction_tokens = set(nltk.word_tokenize(str(name_prediction)))
         label_tokens = set(nltk.word_tokenize(name_label))
         correct = len(prediction_tokens.intersection(label_tokens)) > 3
         if correct:
               num_correct_name_email += 1
    else:
       num_labeled_emails -= 1

    # Dates Evaluation
    prediction = extract_dates(email['description'])
    labels = {}
    if 'submission_date' in email.keys() and email['submission_date'] != 'N/A':
       labels['submission'] = parse(email['submission_date'])
       num_possible_dates += 1
    if 'conference_date' in email.keys() and email['conference_date'] != 'N/A':
       labels['conference'] = parse(email['conference_date'])
       num_possible_dates += 1
    if 'notification_date' in email.keys() and email['notification_date'] != 'N/A':
       labels['notification'] = parse(email['notification_date'])
       num_possible_dates += 1
    if verbose:
       print("Prediction: {}\tLabel: {}".format(prediction, labels))
    for key in labels.keys():
       target = labels[key]
       if key in prediction.keys() and target[0] == prediction[key][0] and target[1] == prediction[key][1]:
          num_correct_dates += 1

    # Location Evaluation
    if 'location' in email.keys() and email['location'] != 'N/A':
      prediction = extract_location(email['description'])
      label = email['location']
      if verbose:
         print("Prediction: {}\tLabel: {}".format(prediction, label))
      prediction_tokens = set(nltk.word_tokenize(prediction))
      label_tokens = set(nltk.word_tokenize(label))
      correct = len(prediction_tokens.intersection(label_tokens)) > 0
      if correct:
         num_correct += 1

print("Email name accuracy: {}".format(num_correct_name_email / num_labeled_emails))
print("Email date accuracy: {}".format(num_correct_dates / num_possible_dates))
print("Email location accuracy: {}".format(num_correct / num_labeled_emails))

# CFP Extraction Evaluation
with open('cfp_events.json') as f:
    cfp_events = json.load(f)

test_events = [event for event in cfp_events
               if event['location'] != 'N/A' and
               event['location'] != 'NA']
num_correct = 0
test_size = len(test_events)

num_correct_name = 0

num_correct_dates = 0
num_possible_dates = 0

for event in cfp_events:
    # Name Evaluation
    name_prediction = extract_event_name(concat_cfp_event(event))
    name_label = event['title']

    if verbose:
        print("Name Prediction: {}\t Name Label: {}".format(name_prediction, name_label))
        print()
    if name_prediction is not None:
        prediction_tokens = set(nltk.word_tokenize(str(name_prediction)))
        label_tokens = set(nltk.word_tokenize(name_label))
        correct = len(prediction_tokens.intersection(label_tokens)) > 0
        if correct:
            num_correct_name += 1
    # Dates Evaluation
    prediction = extract_dates(concat_cfp_event(event))
    labels = {}
    if 'submission_date' in event.keys() and event['submission_date'] != 'N/A':
      submission = event['submission_date']
      labels['submission'] = (datetime.datetime(*(time.strptime(submission[submission.find(':') + 2:submission.find(':') + 12], '%Y-%m-%d'))[:3]), None)
      num_possible_dates += 1
    if 'notification_date' in event.keys() and event['notification_date'] != 'N/A':
      submission = event['notification_date']
      labels['notification'] = (datetime.datetime(*(time.strptime(submission[submission.find(':') + 2:submission.find(':') + 12], '%Y-%m-%d'))[:3]), None)
      num_possible_dates += 1
    if 'conference_date' in event.keys() and event['conference_date'] != 'N/A':
      submission = event['conference_date']
      labels['conference'] = (datetime.datetime(*(time.strptime(submission[submission.find(':') + 2:submission.find(':') + 12], '%Y-%m-%d'))[:3]), None)
      num_possible_dates += 1
    if verbose:
      print("Prediction: {}\tLabel: {}".format(prediction, labels))
    for key in labels.keys():
      target = labels[key]
      if key in prediction.keys() and target[0] == prediction[key][0]:
         num_correct_dates += 1

    # Location Evaluation
    prediction = extract_location(concat_cfp_event(event))
    label = event['location']
    if verbose:
        #print("Location Prediction: {}\t Location Label: {}".format(prediction, label))
        print()
    if prediction is not None:
        prediction_tokens = set(nltk.word_tokenize((prediction)))
        label_tokens = set(nltk.word_tokenize(label))
        correct = len(prediction_tokens.intersection(label_tokens)) > 0
        if correct:
            num_correct += 1

print("CFP name accuracy: {}".format(num_correct_name / test_size))
print("CFP date accuracy: {}".format(num_correct_dates / num_possible_dates))
print("CFP location accuracy: {}".format(num_correct / test_size))