import wx
import cv2
import numpy as np
from guide import FigureGuide, TextGuide
from detector import LineDetector, TextDetector
from figureparts import Box
from define_property import define_property
import concurrent.futures

class MyThread(concurrent.futures.ProcessPoolExecutor):
    def __init__(self):
        super(MyThread, self).__init__()

class Mode():
    def __init__(self, *, mode_list=[], initial_mode=None):
        define_property(self, name='mode_list', value=mode_list)
        for mode in self.__mode_list:
            define_property(self, str(mode), mode, writable=False)

        if initial_mode in self.__mode_list:
            define_property(self, 'mode', str(initial_mode))
        else:
            define_property(self, 'mode', str(self.__mode_list[0]))

class WebcamPanel(wx.Panel):
    def __init__(self, parent, camera, fps=15):
        wx.Panel.__init__(self, parent)

        self.camera = camera
        while True:
            ret, frame = self.camera.read()
            if ret:
                break

        height, width = frame.shape[:2]
        self.SetSize((width, height))

        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        self.bmp = wx.Bitmap.FromBuffer(width, height, frame)

        self.calibrate_points = Box(
            (0, 0), (width - 1, height - 1))
        self.timer = wx.Timer(self)
        self.timer.Start(int(1000. / fps))

        self.Bind(wx.EVT_PAINT, self.on_paint)
        self.Bind(wx.EVT_TIMER, self.next_frame)

    def next_frame(self, event):  # カメラ画像書き換え
        return_value, frame = self.camera.read()
        if return_value:
            for line in self.calibrate_points.lines:
                cv2.line(frame,
                         tuple(line.start.coordinate),
                         tuple(line.end.coordinate),
                         (187, 111, 0), 2)
                cv2.circle(frame,
                           tuple(line.start.coordinate),
                           radius=8,
                           color=(187, 111, 0),
                           thickness=cv2.FILLED)

            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            self.bmp.CopyFromBuffer(frame)
            self.Refresh()

    def on_paint(self, event):
        dc = wx.BufferedPaintDC(self)
        dc.DrawBitmap(self.bmp, 0, 0)

class MainWindow(wx.Frame):
    def __init__(self):
        # 継承
        wx.Frame.__init__(self, None)
        self.Title = "Blavo"
        mode_list = ['none', 'calibration', 'set_color', 'figure', 'text']
        self.mode = Mode(mode_list=mode_list, initial_mode='None')
        # ガイドを表示するウィンドウを作成，表示
        self.guide_window = GuideWindow(self)
        self.guide_window.Show()
        self.line_detector = LineDetector()
        self.chara_detector = TextDetector()
        self.is_mouse_down = False

        # カメラ
        self.camera = cv2.VideoCapture(0)
        return_value, frame = self.camera.read()
        height, width = frame.shape[:2]
        # カメラパネルに渡す
        self.webcampanel = WebcamPanel(self, self.camera, fps=10)

        # ボタン配置，キャリブレーション設定
        self.calibration_button = wx.Button(self, wx.ID_ANY, '範囲設定')
        self.calibration_button.Bind(wx.EVT_BUTTON, self.calib_state_change)
        self.calibration_button.SetBackgroundColour('#ffffff')

        self.set_color_button = wx.Button(self, wx.ID_ANY, 'チョーク色取得')
        self.set_color_button.Bind(wx.EVT_BUTTON, self.set_color_state_change)
        self.set_color_button.SetBackgroundColour('#ffffff')
        self.choke_color = (255, 255, 255)

        self.cancel_button = wx.Button(self, wx.ID_ANY, 'CANCEL')
        self.cancel_button.SetBackgroundColour('#ffffff')
        self.cancel_button.Disable()
        self.cancel_button.Bind(wx.EVT_BUTTON, self.state_change)

        self.guide_button = wx.Button(self, wx.ID_ANY, 'ガイド開始')
        self.guide_button.SetBackgroundColour('#ffffff')
        self.guide_button.Bind(wx.EVT_BUTTON, self.state_change)

        self.webcampanel.Bind(wx.EVT_LEFT_DOWN, self.mouse_down)
        self.webcampanel.Bind(wx.EVT_MOTION, self.mouse_move)
        self.webcampanel.Bind(wx.EVT_LEFT_UP, self.mouse_left_up)
        self.webcampanel.Bind(wx.EVT_RIGHT_UP, self.mouse_right_up)

        button_box_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_box_sizer.Add(self.cancel_button, 1, wx.EXPAND)
        button_box_sizer.Add(self.calibration_button,
                             2, wx.BOTTOM | wx.EXPAND)
        button_box_sizer.Add(self.set_color_button,
                             2, wx.BOTTOM | wx.EXPAND)
        button_box_sizer.Add(self.guide_button, 1, wx.EXPAND)

        # メインウィンドウのサイズ決定，パネル，ボタン配置
        main_window_sizer = wx.BoxSizer(wx.VERTICAL)
        main_window_sizer.Add(self.webcampanel, 7,
                              wx.CENTER | wx.BOTTOM | wx.EXPAND, 1)
        main_window_sizer.SetItemMinSize(self.webcampanel, (640, 480))
        main_window_sizer.Add(button_box_sizer, 1, wx.BOTTOM | wx.EXPAND)
        # サイズを合わせる
        main_window_sizer.Fit(self)
        self.SetSizer(main_window_sizer)

    def frame_calibration(self, target_pts, w, h):
        # カメラ画像の特定の位置を抜き出し、指定したサイズに変換
        return_value, frame = self.camera.read()
        if return_value:
            dst_pts = np.array(
                [[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]], dtype=np.float32)
            perspective = cv2.getPerspectiveTransform(
                target_pts.astype(np.float32), dst_pts)
            return cv2.warpPerspective(frame, perspective, (w, h))

    def button_state_change(self, mode):
        self.calibration_button.SetBackgroundColour('#ffffff')
        self.guide_button.SetBackgroundColour('#ffffff')
        self.cancel_button.SetBackgroundColour('#ffffff')
        self.cancel_button.Disable()

        if mode == "none":
            self.set_color_button.Enable()
            self.calibration_button.Enable()
            self.guide_button.Enable()

        elif mode == "calibration":
            self.calibration_button.SetBackgroundColour('#99aaff')

        elif mode == "figure":
            self.guide_button.SetBackgroundColour('#74e69d')
            self.guide_button.Enable()
            self.calibration_button.Disable()
            self.set_color_button.Disable()
            self.cancel_button.Enable()

    def calib_state_change(self, event):
        # キャリブレーション状態切替
        if self.mode.mode != "calibration":
            self.mode.mode = "calibration"
            self.guide_window.guide_panel.color = True
            self.guide_window.guide_panel.Refresh()
        else:
            self.mode.mode = "none"
        self.button_state_change(self.mode.mode)

    def set_color_state_change(self, event):
        # チョーク色取得状態切替
        if self.mode.mode != "set_color":
            self.mode.mode = "set_color"
            self.guide_window.guide_panel.color = False
            self.guide_window.guide_panel.Refresh()
        else:
            self.mode.mode = "none"
        self.button_state_change(self.mode.mode)

    def state_change(self, event):
        if self.mode.mode != "figure":
            self.mode.mode = "figure"
            guide_display = wx.Display(self.guide_window.display_index)
            _, _, w, h = guide_display.GetGeometry()
            calibrate_frame = self.frame_calibration(
                self.webcampanel.calibrate_points.asrearray, w, h)
            self.guide_window.guide_panel.color = False
            self.guide_window.guide_panel.Refresh()
            self.line_detector.queue(img=calibrate_frame)
            self.chara_detector.queue(img=calibrate_frame)
            self.line_detector.set_back(img=calibrate_frame)
            self.chara_detector.set_back(img=calibrate_frame)
        else:
            self.mode.mode = "none"
        self.button_state_change(self.mode.mode)

    def mouse_down(self, event):
        self.is_mouse_down = True
        self.mouse_move(event)

    def mouse_move(self, event):
        if self.is_mouse_down:
            if self.mode.mode == "calibration":
                mouse_pt = (event.X, event.Y)
                min_index = self.closed_point_index(
                    mouse_pt, self.webcampanel.calibrate_points.asarray)
                self.webcampanel.calibrate_points[min_index] = mouse_pt

            elif self.mode.mode == "set_color":
                return_value, frame = self.camera.read()
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                if return_value:
                    self.set_color_button.SetBackgroundColour(
                        tuple(frame[event.Y, event.X]))

    def mouse_left_up(self, event):
        self.is_mouse_down = False
        if self.mode.mode == "set_color":
            return_value, frame = self.camera.read()
            if return_value:
                hsvframe = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV_FULL)
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                self.line_detector.save_picture([frame, ], ["not_calib", ])
                choke_color = hsvframe[event.Y, event.X]
                self.set_color_button.SetBackgroundColour(
                    tuple(frame[event.Y, event.X]))
                self.line_detector.set_color(choke_color)
                self.chara_detector.set_color(choke_color, 80, 80)

        elif self.mode.mode == "figure":
            guide_display = wx.Display(self.guide_window.display_index)
            _, _, w, h = guide_display.GetGeometry()
            calibrate_frame = self.frame_calibration(
                self.webcampanel.calibrate_points.asrearray, w, h)
            self.line_detector.queue(img=calibrate_frame)
            self.chara_detector.queue(img=calibrate_frame)

    def mouse_right_up(self, event):
        if self.mode.mode == "figure":
            # self.guide_window.guide_panel.figure_key_num += 1
            # self.guide_window.guide_panel.figure_key_num %= len(
            # self.guide_window.guide_panel.text_guide_mode_key)
            self.guide_window.guide_panel.text_key_num += 1
            self.guide_window.guide_panel.text_key_num %= len(
                self.guide_window.guide_panel.text_guide_mode_key)
            detected_line = self.line_detector.detect_line()
            text_box = self.chara_detector.detect_text()
            self.show_guide(detected_line, text_box)

    def closed_point_index(self, pt, target_pts):
        # マウスが押された点を要素とする長さ4の配列
        src_pts = np.full_like(target_pts, pt)
        # 現在の検出範囲4点のx,y座標とマウスが押されたx,y座標との差
        check_array = target_pts - src_pts
        # chack_arrayで求めたx,y座標からマウスが押された点と検出範囲の4角との距離を計算
        distance = np.sum(np.square(check_array), axis=1)
        # 一番短い距離となった配列番号を取得
        min_index = np.argmin(distance)
        # 上で求めた配列番号の点をマウスが離された点に変更
        return min_index

    def show_guide(self, target_line, target_box):
        self.guide_window.guide_panel.set_figure_guide(target_line)
        self.guide_window.guide_panel.set_text_guide(target_box)
        self.guide_window.guide_panel.Refresh()

class GuidePanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        guide_display = wx.Display(parent.display_index)
        _, _, width, height = guide_display.GetGeometry()
        self.figure_guide = FigureGuide()
        self.text_guide = TextGuide()
        self.figure_guide_mode_key = list(self.figure_guide.guide_mode.keys())
        self.text_guide_mode_key = list(self.text_guide.guide_mode.keys())
        self.color = True
        self.figure_key_num = self.figure_guide_mode_key.index('no')
        self.text_key_num = self.text_guide_mode_key.index('no')
        self.SetSize(width, height)
        self.bmp = wx.Bitmap(width, height, -1)
        self.Bind(wx.EVT_PAINT, self.on_paint)

    def set_figure_guide(self, line):
        self.figure_guide.line = line

    def set_text_guide(self, box):
        self.text_guide.text_box = box

    def on_paint(self, event):
        dc = wx.BufferedPaintDC(self)
        if self.color:
            dc.SetBackground(wx.Brush('red'))
        else:
            dc.SetBackground(wx.Brush('black'))

        dc.Clear()
        dc.SetBrush(wx.Brush(wx.Colour(0, 0, 0, 100),
                             wx.BRUSHSTYLE_TRANSPARENT))
        dc.SetPen(wx.Pen('green', 10, wx.PENSTYLE_DOT))
        lines, circles = self.figure_guide.get_guide(
            self.figure_guide_mode_key[self.figure_key_num]
        )
        box_lines = self.text_guide.get_guide(
            self.text_guide_mode_key[self.text_key_num]
        )
        lines += box_lines
        # Draw graphics.
        for line in lines:
            start = line.start.coordinate
            end = line.end.coordinate
            dc.DrawLine(start, end)

        for circle in circles:
            center = (circle.center.coordinate)
            radius = circle.radius
            dc.DrawCircle(center, radius)

class GuideWindow(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)
        self.display_index = 0
        self.switch_window(parent)
        self.guide_panel = GuidePanel(self)
        self.guide_panel.Refresh()
        self.Maximize(True)

        main_window_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_window_sizer.Add(self.guide_panel, 7,
                              wx.CENTER | wx.BOTTOM | wx.EXPAND, 1)
        main_window_sizer.SetItemMinSize(self.guide_panel, (1200, 1024))
        # サイズを合わせる
        main_window_sizer.Fit(self)
        self.SetSizer(main_window_sizer)

    def switch_window(self, parent):
        if wx.Display.GetCount() == 2:
            self.parent_display_index = wx.Display.GetFromWindow(parent)
            self.display_index = (self.parent_display_index + 1) % 2

            self.parent_display = wx.Display(self.parent_display_index)
            _, _, parent_display_w, parent_display_h = self.parent_display.GetGeometry()
            self.guide_display = wx.Display(self.display_index)
            _, _, self.guide_display_w, self.guide_display_h = self.guide_display.GetGeometry()

            parent_position_x, parent_position_y = parent.GetPosition()

            if parent_display_w > parent_position_x:
                self.SetPosition(
                    (int(parent_display_w + (self.guide_display_w / 2)), int(self.guide_display_h / 2)))
            else:
                self.SetPosition(
                    (int(self.guide_display_w / 2), int(self.guide_display_h / 2)))
            self.Maximize(True)

def main():
    app = wx.App()
    main_window = MainWindow()
    main_window.Show()
    app.MainLoop()

# main関数呼び出し
if __name__ == "__main__":
    main()


'''
Your function should take in a single parameter (a string `word`)
Your function should return a count of how many occurences of ***"th"*** occur within `word`. Case matters.
Your function must utilize recursion. It cannot contain any loops.
'''
def count_th(word):
    th = 0

    # since th is 2 letters, any word less than 2 letters means there are none
    if len(word) < 2:
        return 0

    # search for 'th' in the string
    if word[:2] == 'th':
        th = th + 1

    # the recursive portion to continue through the string
    th = th + count_th(word[1:])
    return th

# test it
print("The number of times 'th' occurs in your string is: ", count_th("welcomethtomythhousethopethnupthechampagne,popthIt'smyhouse,comeon,turnitupth"))


__author__ = 'pittnuts'
'''
Main script to run classification/test/prediction/evaluation
'''
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import *
from PIL import Image
import caffe
import sys
import lmdb
from caffe.proto import caffe_pb2
from pittnuts import *
from os import system
from caffe_apps import *
import time
plt.rcParams['figure.figsize'] = (10, 10)
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'
caffe_root = './'

#imagenet_val_path  = '/home/wew57/cuda-workspace/SCNN_MAKEFILE_PRJ/caffe/examples/imagenet/ilsvrc12_val_lmdb'
imagenet_val_path  = '/home/public/imagenet/ilsvrc12_val_lmdb'
#imagenet_val_path  = 'examples/images/ilsvrc12_train_lmdb'

import os
#if not os.path.isfile(caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'):
#    print("Downloading pre-trained CaffeNet model...")
#    #!../scripts/download_model_binary.py ../models/bvlc_reference_caffenet
#    os.system("./scripts/download_model_binary.py ./models/bvlc_reference_caffenet")

# GPU mode
caffe.set_device(2)
caffe.set_mode_gpu()

#caffe.set_mode_cpu()

#net = caffe.Net(caffe_root + 'models/eilab_reference_sparsenet/deploy_scnn.prototxt',
#                caffe_root + 'models/eilab_reference_sparsenet/eilab_reference_sparsenet.caffemodel',
#                caffe.TEST)

#net = caffe.Net(caffe_root + 'models/eilab_reference_sparsenet/deploy_scnn_skipped.prototxt',
#                '/home/wew57/bincaffe/models/eilab_reference_sparsenet/l1_0001weighdecay_0001grpdecay_001lr_80000stepsize_160000iter/sparsenet_train_iter_160000.caffemodel',
#                caffe.TEST)

# net = caffe.Net(caffe_root + 'models/eilab_reference_sparsenet/deploy_scnn.prototxt',
#                 'models/eilab_reference_sparsenet/sparsenet_train_iter_160000.caffemodel',
#                 caffe.TEST)

#net = caffe.Net(caffe_root + 'examples/cifar10/cifar10_quick_scnn.prototxt',
#                caffe_root + 'examples/cifar10/cifar10_quick_iter_5000_sparsenet.caffemodel',
#                caffe.TEST)

#net = caffe.Net(caffe_root + 'models/eilab_reference_sparsenet/deploy_scnn.prototxt',
#                caffe_root + 'models/eilab_reference_sparsenet/sparsenet_train_iter_10000_l1.caffemodel',
#                caffe.TEST)

net = caffe.Net(caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt',
              caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel',
             caffe.TEST)
#
#net = caffe.Net(caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt',
#              caffe_root + 'models/bvlc_reference_caffenet/0.001_0.0003_0.0_0.0_0.0_Fri_Apr__8_13-24-15_EDT_2016/caffenet_train_iter_160000_0.57278_0.001_0.0003_0.0_0.0_0.0.caffemodel',
#             caffe.TEST)

#net = caffe.Net(caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt',
#net = caffe.Net(caffe_root + 'models/bvlc_reference_caffenet/deploy_conv_mode.prototxt',
              #caffe_root + 'models/bvlc_reference_caffenet/caffenet_train_grouplasso_iter_160000_0.519_intel.caffemodel',
              #caffe_root + 'models/bvlc_reference_caffenet/caffenet_train_grouplasso_iter_160000_0.54214_1.0e-3.caffemodel',
#              caffe_root + 'models/bvlc_reference_caffenet/caffenet_train_iter_160000_0.56318_finetuned_from_0.001_0.0005_0.0_0.0_0.0003.caffemodel',
#              caffe.TEST)

# input preprocessing: 'data' is the name of the input blob == net.inputs[0]
#transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
#transformer.set_transpose('data', (2,0,1))
#transformer.set_mean('data', np.load(caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy').mean(1).mean(1)) # mean pixel
#transformer.set_raw_scale('data', 255)  # the reference model operates on images in [0,255] range instead of [0,1]
#transformer.set_channel_swap('data', (2,1,0))  # the reference model has channels in BGR order instead of RGB

# set net to batch size
height = 227
width = 227
if height!=width:
    warnings.warn("height!=width, please double check their dimension position",RuntimeWarning)

#net.blobs['data'].reshape(1,3,height,width)

#im = np.array(Image.open(caffe_root+'examples/images/cat.jpg'))
#plt.title("original image")
#plt.imshow(im)
#plt.show()
#plt.axis('off')

'''
net.blobs['data'].data[...] = transformer.preprocess('data', caffe.io.load_image(caffe_root + 'examples/images/cat.jpg'))
out = net.forward()
print("Predicted class is #{}.".format(out['prob'].argmax()))

# load labels
imagenet_labels_filename = caffe_root + 'data/ilsvrc12/synset_words.txt'
try:
    labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')
except:
    print "Downloading ilsvrc12 synset"
    os.system("../data/ilsvrc12/get_ilsvrc_aux.sh")
    labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')

# sort top k predictions from softmax output
top_k = net.blobs['prob'].data[0].flatten().argsort()[-1:-6:-1]
print labels[top_k]

# the parameters are a list of [weights, biases]
filters = net.params['conv1'][0].data
vis_square(filters.transpose(0, 2, 3, 1))

feat = net.blobs['conv1'].data[0, :36]
vis_square(feat, padval=1)
'''
########## PCA #############
#for idx in range(0,5):
#    data = net.params[net.params.keys()[idx]][0].data
#    #if idx != 0:
#    #    data = data[0:data.shape[0]/2,:,:,:]
#    weights = transpose(data,(2,3,1,0))
#    P,S,Q,q = kernel_factorization(weights)
#    print weights.shape
#    #print q
#    weights_recover,R = kernel_recover(P,S,Q,q)
#    print "[{}] W: %{} error".format(net.params.keys()[idx],100*sum((weights-weights_recover)**2)/sum((weights)**2))
#    r_width = 0.0001
#    print "[{}] S: %{} zeros".format(net.params.keys()[idx],100*sum((abs(S)<r_width).flatten())/(float)(S.size))
#    print "[{}] R: %{} zeros".format(net.params.keys()[idx],100*sum((abs(R)<r_width).flatten())/(float)(R.size))
#    net.params[net.params.keys()[idx]][0].data[:] = weights_recover.transpose((3,2,0,1))

#######################
count = 0
correct_top1 = 0
correct_top5 = 0
labels_set = set()
lmdb_env = lmdb.open(imagenet_val_path)
lmdb_txn = lmdb_env.begin()
lmdb_cursor = lmdb_txn.cursor()
#pixel_mean = np.load(caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy').mean(1).mean(1)
mean_blob = caffe.proto.caffe_pb2.BlobProto()
mean_data = open( 'data/ilsvrc12/imagenet_mean.binaryproto' , 'rb' ).read()
mean_blob.ParseFromString(mean_data)
#pixel_mean = tile(pixel_mean.reshape([1,3]),(height*width,1)).reshape(height,width,3).transpose(2,0,1)
pixel_mean = np.array( caffe.io.blobproto_to_array(mean_blob) )

avg_time = 0
batch_size = net.blobs['data'].num
label = zeros((batch_size,1))
image_count = 0
for key, value in lmdb_cursor:
    datum = caffe.proto.caffe_pb2.Datum()
    datum.ParseFromString(value)
    label[image_count%batch_size,0] = int(datum.label)
    image = caffe.io.datum_to_array(datum)
    #net.blobs['data'].data[...] = transformer.preprocess('data', caffe.io.load_image(caffe_root + 'examples/images/cat.jpg'))
    image = image.astype(np.uint8)

    #out = net.forward_all(data=np.asarray([image]))
    #image_tmp = image[(0,1,2),:,:]
    #image_tmp = image_tmp.transpose(0,2,1)
    #plt.imshow(image.transpose(1,2,0)[:,:,(2,1,0)])
    #plt.show()
    #crop_range = range(14,14+227)
    image = image-pixel_mean.mean(0)
    image = image[:,14:14+227,14:14+227]
    #net.blobs['data'].data[...] = image-pixel_mean #transformer.preprocess('data', image)
    net.blobs['data'].data[image_count%batch_size] = image#image-pixel_mean
    if image_count % batch_size == (batch_size-1):
        starttime = time.time()
        out = net.forward()
        endtime = time.time()
        #plabel = int(out['prob'][0].argmax(axis=0))
        plabel = out['prob'][:].argmax(axis=1)
        plabel_top5 = argsort(out['prob'][:],axis=1)[:,-1:-6:-1]
        assert (plabel==plabel_top5[:,0]).all()
        count = image_count + 1
        #avg_time = (avg_time*(count-1)+(endtime-starttime))/count
        current_test_time = endtime-starttime

        #iscorrect = label == plabel
        correct_top1 = correct_top1 + sum(label.flatten() == plabel.flatten())#(1 if iscorrect else 0)

        #iscorrect_top5 = contains(plabel_top5,label)
        correct_top5_count = sum(contains2D(plabel_top5,label))
        correct_top5 = correct_top5 + correct_top5_count

        #labels_set.update([label, plabel])

        #if not iscorrect:
        #print("\rError: key=%s, expected %i but predicted %i" % (key, label, plabel))

        #sys.stdout.write("\rAccuracy (Top 1): %.1f%%" % (100.*correct_top1/count))
        sys.stdout.write("\n[{}] Accuracy (Top 1): {:.1f}%".format(count,100.*correct_top1/count))
        sys.stdout.write("  (Top 5): %.1f%%" % (100.*correct_top5/count))
        sys.stdout.write("  (current time): {}\n".format(1000*current_test_time))
        sys.stdout.flush()
    image_count += 1

#print(str(correct_top1) + " out of " + str(count) + " were classified correctly")

plt.show()


# -*- mode: python; encoding: utf-8 -*-
#
# Copyright 2017 the Critic contributors, Opera Software ASA
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License.  You may obtain a copy of
# the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
# License for the specific language governing permissions and limitations under
# the License.

# type: ignore

import logging

logger = logging.getLogger(__name__)

from . import ReviewMailGroup, changed_lines_per_file
from .rendercommit import render_commit
from ..replayer import extract_unmerged_paths
from critic import api

class CommitsPushedGenerator:
    email_type = "updatedReview.commitsPushed"

    def setBranchUpdate(self, branchupdate):
        self.branchupdate = branchupdate

    def setChangesets(self, changesets):
        self.changesets = changesets

    async def __call__(self, mail):
        review = await mail.group.event.review
        from_user = mail.group.from_user
        to_user = mail.to_user

        commits = await self.branchupdate.associated_commits
        if len(commits) == 1:
            what = "an additional commit"
        else:
            what = "%d additional commits" % len(commits)

        branch = await review.branch
        repository = await review.repository

        mail.add_section(
            f"{from_user.fullname} has updated the review by pushing {what} to "
            "the branch",
            f"  {branch.name}",
            "in the repository",
            *(f"  {url}" for url in await repository.urls),
        )

        if to_user in await review.assigned_reviewers:
            rfcs = set()
            for changeset in self.changesets:
                rfcs.update(
                    await api.reviewablefilechange.fetchAll(
                        review, changeset=changeset, assignee=to_user
                    )
                )
            if rfcs:
                mail.add_section(
                    "These changes were assigned to you:",
                    *await changed_lines_per_file(mail, rfcs),
                )

        for commit in commits.topo_ordered:
            mail.add_section(
                *await render_commit(mail.group, commit, 3), wrap_lines=False
            )

class ReviewRebasedGenerator:
    email_type = "updatedReview.reviewRebased"

    def setRebase(self, rebase):
        self.rebase = rebase

    async def __call__(self, mail):
        review = await mail.group.event.review
        from_user = mail.group.from_user

        if isinstance(self.rebase, api.rebase.HistoryRewrite):
            mail.add_section(
                f"{from_user.fullname} has rewritten the history on the review "
                "branch."
            )
        else:
            mail.add_section(
                f"{from_user.fullname} has rebased the changes on the review "
                f"branch onto a new upstream."
            )

            replay = await self.rebase.equivalent_merge
            if not replay:
                replay = await self.rebase.replayed_rebase

            unmerged_paths = extract_unmerged_paths(replay) if replay else None
            if unmerged_paths:
                mail.add_section(
                    "Conflicts were detected in these paths:",
                    "",
                    *("  " + path for path in unmerged_paths),
                )

        branch = await review.branch
        commits = await branch.commits

        branch_log = [
            f"{commit.sha1[:8]} {commit.summary}" for commit in commits.topo_ordered
        ]

        mail.add_section(
            "The new branch log is:", "", *("  " + line for line in branch_log)
        )

async def handle_branchupdate(critic, event):
    branchupdate = await event.branchupdate
    review = await event.review

    if review.state == "draft":
        return

    rebase = await branchupdate.rebase

    if rebase is None:
        generator = CommitsPushedGenerator()
        generator.setBranchUpdate(branchupdate)
        generator.setChangesets(
            await api.changeset.fetchMany(critic, branchupdate=branchupdate)
        )
    else:
        generator = ReviewRebasedGenerator()
        generator.setRebase(rebase)

    group = ReviewMailGroup(event, await event.user, generator.email_type)

    async with group:
        await group.ensure_parent_message_ids()
        await group.generate(generator)


#!/usr/bin/env python3
"""
Functions define R3BP parameters
Yuri Shimane
"""

import numpy as np

from .. import SolarSystemConstants as sscs
from .. import Keplerian as kepl

# initialise
class Parameters():
    pass

# ----------------------------------------------------------------------------------------------- #
def get_cr3bp_mu(m1_naifID, m2_naifID):
    """Function returns mass-parameter mu of the CR3BP system

    Args:
        m1_naifID (str): mass of first primary
        m2_naifID (str): mass of second primary
    Returns:
        (float): mass-parameter mu
    """
    # list of gm
    gmlst = sscs.get_gm(m1_naifID, m2_naifID)
    m1_gm, m2_gm = gmlst[0], gmlst[1]
    if m1_gm > m2_gm:
        return m2_gm / (m1_gm + m2_gm)
    else:
        return m1_gm / (m1_gm + m2_gm)

def get_bcr4bp_mus(m1_naifID, m2_naifID):
    """Function returns mass-parameter mu of the CR3BP system

    Args:
        m1_naifID (str): mass of first primary
        m2_naifID (str): mass of second primary
    Returns:
        (float): mass-parameter mu

    Raises:

    """
    # list of gm
    gmlst = sscs.get_gm(m1_naifID, m2_naifID, "10")
    m1_gm, m2_gm, m3_gm = gmlst[0], gmlst[1], gmlist[2]
    if m1_gm < m2_gm:
        raise Exception("Excepting m1 > m2!")
    mu  = m2_gm / (m1_gm + m2_gm)
    mu3 = m3_gm / (m1_gm + m2_gm)
    return mu, mu3

# ----------------------------------------------------------------------------------------------- #
def get_cr3bp_param(m1_naifID, m2_naifID):
    """Function returns CR3BP parameters mu, Lstar, Tstar, soi of m2

    Args:
        m1_naifID (str): mass of first primary
        m2_naifID (str): mass of second primary

    Returns:
        (obj): object with fields:
            mu (float): mass-parameter
            lstar (float): non-dimensional distance
            tstar (float): non-dimensional time
            m2_soi (float): sphere of influence of second mass, in km
    """
    # initialize empty parameter object
    paramCR3BP = Parameters()
    # list of semi-major axis
    semiMajorAxes = sscs.get_semiMajorAxes(m1_naifID, m2_naifID)
    a1, a2 = semiMajorAxes[0], semiMajorAxes[1]
    # list of gm
    gmlst = sscs.get_gm(m1_naifID, m2_naifID)
    m1_gm, m2_gm = gmlst[0], gmlst[1]
    if m1_gm < m2_gm:
        raise Exception("Excepting m1 > m2!")
    # create list of parameters
    paramCR3BP.mu     = m2_gm / (m1_gm + m2_gm)
    paramCR3BP.lstar  = a2
    paramCR3BP.tstar  = np.sqrt( ( a2 )**3 / ( m1_gm + m2_gm ) )
    paramCR3BP.mstar  = m1_gm + m2_gm
    paramCR3BP.m2_soi = a2 * (m2_gm/m1_gm)**(2/5)
    return paramCR3BP

def get_bcr4bp_param(m1_naifID, m2_naifID):
    """Function returns bcr4bp parameters mu, Lstar, Tstar, soi of m2,

    Args:
        m1_naifID (str): mass of first primary, m1 > m2
        m2_naifID (str): mass of second primary, m1 > m2

    Returns:
        (obj): object with fields:
            mu (float): mass-parameter
            lstar (float): non-dimensional distance
            tstar (float): non-dimensional time
            m2_soi (float): sphere of influence of second mass, in km
    """
    # initialize empty parameter object
    paramBCR4BP = Parameters()
    # inherit parameters from the CR3BP system
    paramCR3BP = get_cr3bp_param(m1_naifID, m2_naifID)

    # get information of Sun
    gm_sun     = sscs.get_gm("10")
    a_m1_sun   = sscs.get_semiMajorAxes(m1_naifID) # semi-major axis of first (larger) body
    period_sun = 2*np.pi*np.sqrt(a_m1_sun**3/gm)   # [sec]

    # compute rotation rate of sun about m1-m2 barycenter
    tsyn   = kepl.get_synodic_period(period_sun, paramCR3BP.tstar)  # [sec]
    om_sun = 2*np.pi / (tsyn / paramCR3BP.tstar)                    # [rad/canonical time]

    # compute scaled gm and length of sun
    a_sun = a_m1_sun / paramCR3BP.lstar
    mu3   = gm_sun   / paramCR3BP.mstar

    # house and return parameter object
    paramBCR4BP.om_sun = om_sun
    paramBCR4BP.a_sun  = a_sun
    paramBCR4BP.mu3    = mu3
    # inherit parameters from cr3bp
    paramBCR4BP.mu     = paramCR3BP.mu
    paramBCR4BP.lstar  = paramCR3BP.lstar
    paramBCR4BP.tstar  = paramCR3BP.tstar
    paramBCR4BP.mstar  = paramCR3BP.mstar
    paramBCR4BP.m2_soi = paramCR3BP.m2_soi
    return paramBCR4BP


from PySide2.QtCore import QObject, QUrl, qDebug, qCritical, QFileInfo, Signal
from PySide2.QtGui import QColor
import threading
import vtk

m_defaultModelColor:QColor = QColor("#0277bd")
m_selectedModelColor:QColor = QColor("#03a9f4")

def setSelectedModelColor(selectedModelColor:QColor):
    global m_selectedModelColor
    m_selectedModelColor = selectedModelColor

class Model(QObject):
    positionXChanged = Signal(float)
    positionYChanged = Signal(float)

    def __init__(self, modelData:vtk.vtkPolyData):
        super().__init__()
        self.__m_propertiesMutex = threading.Lock()
        self.__m_positionX:float = 0.0
        self.__m_positionY:float = 0.0
        self.__m_selected:bool = False
        self.__m_mouseDeltaX:float = 0.0
        self.__m_mouseDeltaY:float = 0.0

        self.__m_modelData:vtk.vtkPolyData = modelData
        #* Place model with lower Z bound at zero
        self.__m_positionZ:float = self.__m_modelData.GetBounds()[4]

        translation = vtk.vtkTransform()
        translation.Translate(self.__m_positionX, self.__m_positionY, self.__m_positionZ)

        self.__m_modelFilterTranslate:vtk.vtkTransformPolyDataFilter = vtk.vtkTransformPolyDataFilter()
        self.__m_modelFilterTranslate.SetInputData(self.__m_modelData)
        self.__m_modelFilterTranslate.SetTransform(translation)
        self.__m_modelFilterTranslate.Update()

        #* Model Mapper
        self.__m_modelMapper:vtk.vtkPolyDataMapper = vtk.vtkPolyDataMapper()
        self.__m_modelMapper.SetInputConnection(self.__m_modelFilterTranslate.GetOutputPort())
        self.__m_modelMapper.ScalarVisibilityOff()

        #* Model Actor
        self.__m_modelActor:vtk.vtkActor = vtk.vtkActor()
        self.__m_modelActor.SetMapper(self.__m_modelMapper)
        self.__m_modelActor.GetProperty().SetInterpolationToFlat()

        self.__m_modelActor.GetProperty().SetAmbient(0.1)
        self.__m_modelActor.GetProperty().SetDiffuse(0.7)
        self.__m_modelActor.GetProperty().SetSpecular(0.3)
        self.__setColor(m_defaultModelColor)

        self.__m_modelActor.SetPosition(0.0, 0.0, 0.0)

    def getModelActor(self) -> vtk.vtkActor:
        return self.__m_modelActor

    def getPositionX(self) -> float:
        self.__m_propertiesMutex.acquire()
        positionX = self.__m_positionX
        self.__m_propertiesMutex.release()
        return positionX

    def getPositionY(self) -> float:
        self.__m_propertiesMutex.acquire()
        positionY = self.__m_positionY
        self.__m_propertiesMutex.release()
        return positionY

    def __setPositionX(self, positionX:float):
        if self.__m_positionX != positionX:
            self.__m_positionX = positionX
            self.positionXChanged.emit(self.__m_positionX)

    def __setPositionY(self, positionY:float):
        if self.__m_positionY != positionY:
            self.__m_positionY = positionY
            self.positionYChanged.emit(self.__m_positionY)

    def translateToPosition(self, x:float,  y:float):
        if self.__m_positionX == x and self.__m_positionY == y:
            return

        self.__m_propertiesMutex.acquire()
        self.__setPositionX(x)
        self.__setPositionY(y)
        self.__m_propertiesMutex.release()

        translation = vtk.vtkTransform()
        translation.Translate(self.__m_positionX, self.__m_positionY, self.__m_positionZ)
        self.__m_modelFilterTranslate.SetTransform(translation)
        self.__m_modelFilterTranslate.Update()

        self.positionXChanged.emit(self.__m_positionX)
        self.positionYChanged.emit(self.__m_positionY)

    def setSelected(self, selected:bool):
        if self.__m_selected != selected:
            self.__m_selected = selected

            self.updateModelColor()

    def updateModelColor(self):
        if self.__m_selected:
            self.__setColor(m_selectedModelColor)
        else:
            self.__setColor(m_defaultModelColor)

    def __setColor(self, color:QColor):
        self.__m_modelActor.GetProperty().SetColor(color.redF(), color.greenF(), color.blueF())

    def getMouseDeltaX(self) -> float:
        return self.__m_mouseDeltaX

    def getMouseDeltaY(self) -> float:
        return self.__m_mouseDeltaY

    def setMouseDeltaXY(self, deltaX:float, deltaY:float):
        self.__m_mouseDeltaX = deltaX
        self.__m_mouseDeltaY = deltaY


import argparse
import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data
from torch.utils.tensorboard import SummaryWriter
import torch.nn.functional as F
from losses import AMSoftmaxLoss, AngleSimpleLinear, SoftTripleLoss, SoftTripleLinear
import albumentations as A
from tqdm import tqdm
from utils import *
import os
from eval_protocol import evaulate
import cv2

parser = argparse.ArgumentParser(description='antispoofing training')
current_dir = os.path.dirname(os.path.abspath(__file__))

# parse arguments
parser.add_argument('--GPU', type=int, default=1, help='specify which gpu to use')
parser.add_argument('--print-freq', '-p', default=5, type=int, help='print frequency (default: 20)')
parser.add_argument('--save_checkpoint', type=bool, default=True, help='whether or not to save your model')
parser.add_argument('--config', type=str, default='config.py', required=True,
                        help='Configuration file')

# global variables and argument parsing
args = parser.parse_args()
path_to_config = os.path.join(current_dir, args.config)
config = read_py_config(path_to_config)
experiment_snapshot = config['checkpoint']['snapshot_name']
experiment_path = config['checkpoint']['experiment_path']
WRITER = SummaryWriter(experiment_path)
STEP, VAL_STEP = 0, 0
BEST_ACCURACY, BEST_AUC, BEST_EER, BEST_ACER = 0, 0, float('inf'), float('inf')
def main():
    global args, BEST_ACCURACY, BEST_EER, BEST_AUC, BEST_ACER, config
    # print experiments param
    init_experiment(config, path_to_config)
    # preprocessing data
    normalize = A.Normalize(**config['img_norm_cfg'])
    train_transform_real = A.Compose([
                            A.Resize(**config['resize'], interpolation=cv2.INTER_CUBIC),
                            A.HorizontalFlip(p=0.5),
                            A.augmentations.transforms.Blur(blur_limit=3, p=0.2),
                            A.augmentations.transforms.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2, brightness_by_max=True, always_apply=False, p=0.3),
                            A.augmentations.transforms.MotionBlur(blur_limit=4, p=0.2),
                            # A.augmentations.transforms.RGBShift(p=0.2),
                            A.augmentations.transforms.ISONoise(color_shift=(0.15,0.35), intensity=(0.2, 0.5)),
                            normalize,
                            ])

    train_transform_spoof = A.Compose([
                            A.Resize(**config['resize'], interpolation=cv2.INTER_CUBIC),
                            A.HorizontalFlip(p=0.5),
                            A.augmentations.transforms.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.2, brightness_by_max=True, always_apply=False, p=0.3),
                            # A.augmentations.transforms.RGBShift(p=0.2),
                            A.augmentations.transforms.MotionBlur(blur_limit=4, p=0.2),
                            A.augmentations.transforms.ISONoise(color_shift=(0.15,0.35), intensity=(0.2, 0.5), p=0.2),
                            normalize,
                            ])

    val_transform = A.Compose([
                A.Resize(**config['resize'], interpolation=cv2.INTER_CUBIC),
                normalize,
                ])

    # load data
    sampler = config['data']['sampler']
    print(f'SAMLPER:{sampler}')
    if sampler:
        weights = make_weights(config)
        sampler = torch.utils.data.WeightedRandomSampler(weights, 494185, replacement=True)
    train_transform = Transform(train_spoof=train_transform_spoof, train_real=train_transform_real)
    val_transform = Transform(val=val_transform)
    train_dataset, val_dataset = make_dataset(config, train_transform, val_transform)
    train_loader, val_loader = make_loader(train_dataset, val_dataset, config, sampler=sampler)
    test_dataset = make_dataset(config, val_transform=val_transform, mode='eval')
    test_loader = DataLoader(dataset=test_dataset, batch_size=config['data']['batch_size'],
                                                shuffle=True, pin_memory=config['data']['pin_memory'],
                                                num_workers=config['data']['data_loader_workers'])
    # build model and put it to cuda and if it needed then wrap model to data parallel
    model = build_model(config, args, strict=False)
    model.cuda(args.GPU)

    if config['data_parallel']['use_parallel']:
        model = torch.nn.DataParallel(model, **config['data_parallel']['parallel_params'])

    # build a criterion
    criterion = build_criterion(config, args)

    # build optimizer and scheduler for it
    optimizer = torch.optim.SGD(model.parameters(), **config['optimizer'])
    scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, **config['scheduler'])

    # learning epochs
    for epoch in range(config['epochs']['start_epoch'], config['epochs']['max_epoch']):
        if epoch != config['epochs']['start_epoch']:
            scheduler.step()

        # train for one epoch
        train_loss, train_accuracy = train(train_loader, model, criterion, optimizer, epoch)
        print(f'epoch: {epoch}  train loss: {train_loss}   train accuracy: {train_accuracy}')

        # evaluate on validation set
        accuracy = validate(val_loader, model, criterion)

        # remember best accuracy, AUC, EER, ACER and save checkpoint
        if (epoch == 0 or epoch >=60) and accuracy > BEST_ACCURACY and args.save_checkpoint:
            AUC, EER, _ , apcer, bpcer, acer = evaulate(model, val_loader, config, args, compute_accuracy=False)
            print(f'epoch: {epoch}   AUC: {AUC}   EER: {EER}   APCER: {apcer}   BPCER: {bpcer}   ACER: {acer}')
            if acer < BEST_ACER:
                BEST_ACER = acer
                checkpoint = {'state_dict': model.state_dict(), 'optimizer': optimizer.state_dict(), 'epoch':epoch}
                save_checkpoint(checkpoint, f'{experiment_path}/{experiment_snapshot}')
                BEST_ACCURACY = accuracy
                BEST_EER = EER
                BEST_AUC = AUC

        # evaluate on val every 10 epoch and save snapshot if better results achieved
        if ((epoch%10 == 0) or (epoch == config['epochs']['max_epoch']-1)) and args.save_checkpoint:
            # printing results
            AUC, EER, accur, apcer, bpcer, acer, _, _ = evaulate(model, test_loader, config, args, compute_accuracy=True)
            print(f'epoch: {epoch}  accur: {round(np.mean(accur),3)}   AUC: {AUC}   EER: {EER}   APCER: {apcer}   BPCER: {bpcer}   ACER: {acer}')

    # evaulate in the end of training
    if config['evaulation']:
        eval_model(model, config, val_transform, map_location = args.GPU, eval_func = evaulate, file_name='LCC_FASD.txt', flag=None)
        eval_model(model, config, val_transform, map_location = args.GPU, eval_func = evaulate, file_name='Celeba_test.txt', flag=True)

def train(train_loader, model, criterion, optimizer, epoch):
    global STEP, args, config
    # meters
    batch_time = AverageMeter()
    data_time = AverageMeter()
    losses = AverageMeter()
    accuracy = AverageMeter()

    # model to cuda, criterion to cuda
    criterion.cuda(device=args.GPU)
    # switch to train mode and train one epoch
    model.train()
    loop = tqdm(enumerate(train_loader), total=len(train_loader), leave=False)
    for i, (input, target) in loop:
        if config['data']['cuda']:
            input = input.cuda(device=args.GPU)
            target = target.cuda(device=args.GPU)
        # compute output and loss
        if config['aug']['type_aug'] == 'mixup':
            aug_output = mixup_target(input, target, config, args.GPU)
        if config['aug']['type_aug'] == 'cutmix':
            aug_output = cutmix(input, target, config, args)
        if config['loss']['loss_type'] == 'amsoftmax':
            if config['aug']['type_aug'] != None:
                input, targets = aug_output
                output = make_output(model, input, target, config)
                loss = criterion(output, targets)
            else:
                new_target = F.one_hot(target, num_classes=2)
                output = make_output(model, input, new_target, config)
                loss = criterion(output, new_target)
        elif config['loss']['loss_type'] == 'cross_entropy':
            if config['aug']['type_aug'] != None:
                input, y_a, y_b, lam = aug_output
                new_target = F.one_hot(target, num_classes=2)
                output = make_output(model, input, new_target, config)
                loss = mixup_criterion(criterion, output, y_a, y_b, lam)
            else:
                new_target = F.one_hot(target, num_classes=2)
                output = make_output(model, input, new_target, config)
                loss = criterion(output, target)
        else:
            assert config['loss']['loss_type'] == 'soft_triple'
            new_target = F.one_hot(target, num_classes=2)
            output = make_output(model, input, new_target, config)
            loss = criterion(output, target)

        # compute gradient and do SGD step
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        # measure accuracy and record loss
        acc = precision(output, target, s=config['loss']['amsoftmax']['s'])
        losses.update(loss.item(), input.size(0))
        accuracy.update(acc, input.size(0))

        # write to writer for tensorboard
        WRITER.add_scalar('Train/loss', loss, global_step=STEP)
        WRITER.add_scalar('Train/accuracy',  accuracy.avg, global_step=STEP)
        STEP += 1

        # update progress bar
        max_epochs = config['epochs']['max_epoch']
        loop.set_description(f'Epoch [{epoch}/{max_epochs}]')
        loop.set_postfix(loss=loss.item(), avr_loss = losses.avg, acc=acc, avr_acc=accuracy.avg, lr=optimizer.param_groups[0]['lr'])
    return losses.avg, accuracy.avg

def validate(val_loader, model, criterion):
    global args, VAL_STEP, config
    # meters
    batch_time = AverageMeter()
    losses = AverageMeter()
    accuracy = AverageMeter()

    # switch to evaluation mode and inference the model
    model.eval()
    loop = tqdm(enumerate(val_loader), total=len(val_loader), leave=False)
    for i, (input, target) in loop:
        if config['data']['cuda']:
            input = input.cuda(device=args.GPU)
            target = target.cuda(device=args.GPU)

        # computing output and loss
        with torch.no_grad():
            features = model(input)
            if config['data_parallel']['use_parallel']:
                model1 = model.module
            else:
                model1 = model
            output = model1.make_logits(features)
            if config['loss']['loss_type'] == 'amsoftmax':
                new_target = F.one_hot(target, num_classes=2)
                loss = criterion(output, new_target)
            else:
                assert config['loss']['loss_type'] in ('cross_entropy', 'soft_triple')
                loss = criterion(output, target)

        # measure accuracy and record loss
        acc = precision(output, target, s=config['loss']['amsoftmax']['s'])
        losses.update(loss.item(), input.size(0))
        accuracy.update(acc, input.size(0))

        # update progress bar
        loop.set_postfix(loss=loss.item(), avr_loss = losses.avg, acc=acc, avr_acc=accuracy.avg)

    print(f'val accuracy on epoch: {round(accuracy.avg, 3)}, loss on epoch:{round(losses.avg, 3)}')
    # write val in writer
    WRITER.add_scalar('Val/loss', losses.avg, global_step=VAL_STEP)
    WRITER.add_scalar('Val/accuracy',  accuracy.avg, global_step=VAL_STEP)
    VAL_STEP += 1

    return accuracy.avg

def mixup_criterion(criterion, pred, y_a, y_b, lam):
    if type(pred) == tuple:
        pred = pred[0]
    return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)

def eval_model(model, config, transform, eval_func, file_name, map_location = 0, flag=None, save=True):
    if flag:
        config['test_dataset']['type'] = 'celeba-spoof'

    print('_____________EVAULATION_____________')
    # load snapshot
    path_to_experiment = os.path.join(config['checkpoint']['experiment_path'], config['checkpoint']['snapshot_name'])
    checkpoint = torch.load(path_to_experiment, map_location=torch.device(f'cuda:{map_location}'))
    load_checkpoint(checkpoint, model, optimizer=None)
    epoch_of_checkpoint = checkpoint['epoch']
    # making dataset
    test_dataset = make_dataset(config, val_transform=transform, mode='eval')
    test_loader = DataLoader(dataset=test_dataset, batch_size=config['data']['batch_size'],
                                                shuffle=True, pin_memory=config['data']['pin_memory'],
                                                num_workers=config['data']['data_loader_workers'])
    # printing results
    AUC, EER, accur, apcer, bpcer, acer, _, _ = evaulate(model, test_loader, config, args, compute_accuracy=True)
    results = f'''accuracy on test data = {round(np.mean(accur),3)}     AUC = {round(AUC,3)}     EER = {round(EER*100,2)}     apcer = {round(apcer*100,2)}     bpcer = {round(bpcer*100,2)}     acer = {round(acer*100,2)}   checkpoint made on {epoch_of_checkpoint} epoch'''
    if save:
        with open(os.path.join(config['checkpoint']['experiment_path'], file_name), 'w') as f:
            f.write(results)
    else:
        return  AUC, EER, accur, apcer, bpcer, acer

def init_experiment(config, path_to_config):
    print(f'_______INIT EXPERIMENT {os.path.splitext(path_to_config)[0][-2:]}______')
    print('\n\nSNAPSHOT')
    for key, item in config['checkpoint'].items():
            print(f'{key} --> {item}')
    print('\n\nMODEL')
    for key, item in config['model'].items():
            print(f'{key} --> {item}')
    loss_type = config['loss']['loss_type']
    print(f'\n\nLOSS TYPE : {loss_type.upper()}')
    if loss_type in ('amsoftmax', 'soft_triple'):
        for key, item in config['loss'][f'{loss_type}'].items():
            print(f'{key} --> {item}')
    print('\n\nDROPOUT PARAMS')
    for key, item in config['dropout'].items():
            print(f'{key} --> {item}')
    print('\n\nOPTIMAIZER')
    for key, item in config['optimizer'].items():
            print(f'{key} --> {item}')
    print('\n\nADDITIONAL USING PARAMETRS')
    if config['aug']['type_aug']:
        type_aug = config['aug']['type_aug']
        print(f'\nAUG TYPE = {type_aug} USING')
        for key, item in config['optimizer'].items():
            print(f'{key} --> {item}')
    if config['RSC']['use_rsc']:
        print(f'RSC USING')
        for key, item in config['RSC'].items():
            print(f'{key} --> {item}')
    if config['data_parallel']['use_parallel']:
        ids = config['data_parallel']['parallel_params']['device_ids']
        print(f'USING DATA PATALLEL ON {ids[0]} and {ids[1]} GPU')
    if config['data']['sampler']:
        print('USING SAMPLER')
    if config['loss']['amsoftmax']['ratio'] != [1,1]:
        print('USING ADAPTIVE LOSS')

if __name__=='__main__':
    main()


# www.NeatChange.com
# Make a difference in your life !
#
# Poplar Oct 7 2016
# Text 进阶

from tkinter import *

root = Tk()
root.title("Text组件")

text1 = Text(root, width=30, height=20)                # 设置宽度为30,高度为20
text1.pack()
text1.insert(INSERT, "I love Poplar ! \n\n")           # INSERT 表示光标当前的位置
text1.insert(END, "下面是Button组件：\n\n")              # END    表示text组件的结尾

photo = PhotoImage(file="外星人妹纸.png")                # 创建图片

def show():
    text1.image_create(END, image=photo)
    text1.insert(END, "\n这是一个外星人妹纸...")

BT1 = Button(text1, text="点击有惊喜", command=show)     # 父组件必须是要插入到的组件
text1.window_create(INSERT, window=BT1)                # 在text1中为BT1创建窗口

root.mainloop()


import datetime
import board
import numpy as np
from adafruit_vl53l0x import VL53L0X
from adafruit_ssd1306 import SSD1306_I2C
from PIL import Image , ImageDraw ,ImageFont

FONT_SANS_12 = ImageFont.truetype("/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc" ,12)
FONT_SANS_18 = ImageFont.truetype("/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc" ,18)

display = SSD1306_I2C(128, 64, board.I2C(), addr=0x3C)
dsensor = VL53L0X(board.I2C(), address=0x29)

if __name__== '__main__':

    display.fill(0)
    display.show()
    distance_array = []

    # Main loop.
    while True:

        # 距離を取得(平均)
        data = dsensor.range
        distance_array.append(data)
        distance = round(np.average(distance_array))

        # 3回分の平均を表示
        if len(distance_array) == 3:
            img = Image.new("1",(display.width, display.height))
            draw = ImageDraw.Draw(img)

            # 時刻表示
            timestamp = datetime.datetime.now()
            draw.text((0,0),'時刻  ' + timestamp.strftime('%H:%M:%S'),font=FONT_SANS_12,fill=1)

            # H/W仕様の2mを超える値が返ってきたら"測定不能"とする
            if distance > 2000:
                draw.text((0,20),'距離  ' + '計測不能',font=FONT_SANS_18,fill=1)
            else:
                draw.text((0,20),'距離  ' + str(round(distance/10 ,1)) + 'cm',font=FONT_SANS_18,fill=1)
            display.image(img)
            display.show()

            # Array Clear
            distance_array = []


# https://projecteuler.net/problem=1
# https://www.hackerrank.com/contests/projecteuler/challenges/euler001/problem

def solution(max_num):
    max_num -= 1
    div_3 = max_num // 3
    s_3 = div_3 * (3 + div_3 * 3) // 2  # 166833
    div_5 = max_num // 5
    s_5 = div_5 * (5 + div_5 * 5) // 2  # 95550
    div_3_5 = max_num // 15
    s_3_5 = div_3_5 * (15 + div_3_5 * 15) // 2  # 233168.0
    result = s_3 + s_5 - s_3_5
    return int(result)

print(solution(1000))
print(solution(1))


from datapaths import timePath, timeImages, calPath, calImages, docTime, docCal
import shutil

# time data format images
for image in timeImages.glob("*.png"):
    shutil.copy2(image, docTime)
# copy ascii headers
asciiPath = timePath / "ascii"
shutil.copy2(asciiPath / "global.hdr", docTime / "ascii_global.hdr")
shutil.copy2(asciiPath / "chan_00.hdr", docTime / "ascii_chan_00.hdr")
asciiInternalPath = timePath / "asciiInternal"
shutil.copy2(asciiInternalPath / "comments.txt", docTime / "asciiInternal_comments.txt")
# copy ats
atsInternal = timePath / "atsInternal"
shutil.copy2(atsInternal / "global.hdr", docTime / "atsInternal_global.hdr")
shutil.copy2(atsInternal / "chan_00.hdr", docTime / "atsInternal_chan_00.hdr")
shutil.copy2(atsInternal / "comments.txt", docTime / "atsInternal_comments.txt")
atsAscii = timePath / "atsAscii"
shutil.copy2(asciiInternalPath / "comments.txt", docTime / "atsAscii_comments.txt")
# copy spam
spamInternalPath = timePath / "spamInternal"
shutil.copy2(spamInternalPath / "comments.txt", docTime / "spamInternal_comments.txt")
spamFilteredPath = timePath / "spamInternalFiltered"
shutil.copy2(spamFilteredPath / "comments.txt", docTime / "spamInternalFiltered_comments.txt")
spamInterpPath = timePath / "spamInterp"
shutil.copy2(spamInterpPath / "comments.txt", docTime / "spamInterp_comments.txt")
# copy phoenix
phoenixPath = timePath / "phoenixInternal" / "meas_ts5_2011-11-13-17-04-02_2011-11-14-14-29-46"
shutil.copy2(phoenixPath / "comments.txt", docTime / "phoenixInternal_comments.txt")
# copy lemi
lemiB423Path = timePath / "lemiB423"
shutil.copy2(lemiB423Path / "global.h423", docTime / "lemib423_global.h423")
shutil.copy2(lemiB423Path / "chan_00.h423", docTime / "lemib423_chan_00.h423")
shutil.copy2(lemiB423Path / "chan_03.h423", docTime / "lemib423_chan_03.h423")
lemiInternalPath = timePath / "lemiB423Internal"
shutil.copy2(lemiInternalPath / "comments.txt", docTime / "lemiB423Internal_comments.txt")
lemiB423EPath = timePath / "lemiB423E"
shutil.copy2(lemiB423EPath / "global.h423E", docTime / "lemib423_global.h423E")
shutil.copy2(lemiB423EPath / "chan_01.h423E", docTime / "lemib423_chan_01.h423E")
shutil.copy2(lemiB423EPath / "chan_03.h423E", docTime / "lemib423_chan_03.h423E")

# cal data format images
for image in calImages.glob("*.png"):
    shutil.copy2(image, docCal)
# ascii
shutil.copy2(calPath / "ascii.TXT", docCal)
shutil.copy2(calPath / "asciiWithData.TXT", docCal)
# metronix
shutil.copy2(calPath / "metronix2ascii.TXT", docCal)
shutil.copy2(calPath / "Hx_MFS06365.txt", docCal)
# rsp
shutil.copy2(calPath / "rsp2ascii.TXT", docCal)
shutil.copy2(calPath / "Metronix_Coil-----TYPE-006_BB-ID-000365.RSP", docCal)
# rspx
shutil.copy2(calPath / "rspx2ascii.TXT", docCal)
shutil.copy2(calPath / "Metronix_Coil-----TYPE-006_HF-ID-000133.RSPX", docCal)


import numpy as np
from scipy import optimize
from sklearn.model_selection import LeaveOneOut
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C

from numpy.matlib import rand,zeros,ones,empty,eye,shape
import itertools

def build_SM(t_all):

    nt = len(t_all)
    model=[]
    for i in range(nt):
        model.append(mt_tsgp(t_all[i].x,t_all[i].y))

    oos_y=[];xall=[];yall=[]
    for i in range(nt):
        model[i].srcmodels = [tmp.model for tmp in model if tmp!=model[i]]
        oos_y.append(model[i].calc_oos_y(t_all[i].x,t_all[i].y))
        xall.append(t_all[i].x)
        yall.append(t_all[i].y)

    model,rmp = calc_a(model,oos_y,xall,yall)

    return model, rmp

class mt_tsgp:

    def __init__(self,x,y):
        # Using RBF ARD Kernel.
        d = shape(x)[1]
        kernel = RBF(np.ones(d))
        self.model = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=9)
        self.model.fit(x,y)

    def calc_oos_y(self,x,y):
        n = y.shape[0]
        d = shape(x)[1]
        kernel_ini = RBF(np.ones(d))
        kernel = kernel_ini.clone_with_theta(self.model.kernel_.theta)

        loo = LeaveOneOut();i=0;
        oos_y = np.zeros(n)
        for i_trn, i_tst in loo.split(x):
            tmp_model = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=9,optimizer=None)
            tmp_model.fit(x[i_trn,:],y[i_trn])
            # tmp_model.kernel.theta = self.model.kernel_.theta
            oos_y[i_tst] = tmp_model.predict(x[i_tst,:])

        return oos_y

    def predict(self,x):
        x=np.array(x)
        n=np.shape(x)[0]

        t_src=len(self.srcmodels)
        y_src=zeros([n,t_src]);var_src=zeros([n,t_src])
        for i in range(t_src):
            y_tmp,std_tmp=self.srcmodels[i].predict(x,return_std = True)
            y_src[:,i] = y_tmp[np.newaxis].T
            var_src[:,i] = std_tmp[np.newaxis].T**2

        y_tmp,std_tmp = self.model.predict(x,return_std=True)
        y_tar = y_tmp[np.newaxis].T
        var_tar = std_tmp[np.newaxis].T

        A_y = np.hstack([y_src,y_tar,np.ones([n,1])])
        A_var = np.hstack([var_src,var_tar])

        y = A_y.dot(self.a)
        var = A_var.dot(np.multiply(self.a,self.a)[:-1])
        std = np.sqrt(var)

        return np.array(y),np.array(std)

# For
def calc_a(model, oos_y, xall, yall):
    ntask = len(model)

    A=[]
    ind = list(itertools.combinations(range(ntask), 2))
    nperm = len(ind)
    for i in range(ntask):
        x = xall[i][:]
        n = np.shape(x)[0]
        A.append(np.zeros([n,nperm+ntask]))
        A[i][:, i + nperm] = oos_y[i]

        for j in range(nperm):
            if i in ind[j]:
                isrc = [ii for ii in ind[j] if ii != i]
                tmp = model[isrc[0]].model.predict(x)
                A[i][:,j] = np.transpose(tmp)

    Acomb = np.vstack(A)
    b = np.hstack(yall)-np.hstack(oos_y)

    lb = np.zeros(nperm+ntask)
    # lb[-ntask:] = 1/ntask
    ub = np.ones(nperm + ntask)
    # ub[-ntask:] = 1
    bnds = list(zip(lb,ub))

    # http://stackoverflow.com/questions/20075714/scipy-minimize-with-constraints
    # http://stackoverflow.com/questions/31289023/scipy-optimize-a-function-with-argument-dependent-constraints
    # cons = {'type': 'eq', 'fun': lambda a: np.sum(a) - 1}
    cons = get_cons(ind,ntask)
    a_ini = ones([nperm+ntask,1])/ntask
    a = optimize.minimize(fnc, a_ini, args=(Acomb, b), constraints=cons, bounds=bnds, method='SLSQP',
                            options={'disp': True,'maxiter':100000})

    # a=optimize.lsq_linear(Acomb,b,bounds = (lb,ub))

    rmp = np.ones([ntask,ntask])
    for i in range(nperm):
        rmp[ind[i][0],ind[i][1]]=a.x[i]

    i_lower = np.tril_indices(ntask, -1)
    rmp[i_lower] = np.transpose(rmp)[i_lower]

    for i in range(ntask):
        idx = np.array([xx for xx in range(ntask) if xx!=i])
        model[i].a = np.hstack([rmp[i,idx],1,a.x[nperm+i]])

    return model,rmp

def fnc(a,A,y):
    return np.sum((A.dot(a)-y)**2)

# def get_eq_con(ntask,nperm):
#     # a_tar > (individually) each a_src not multiplied by 0
#     cons1 = []
#     for i in range(ntask):
#
#         tmp = {'type': 'ineq', 'fun': lambda a:  }
#         cons1.append(tmp)
#     # a_tar must be between 1/ntask and 1
#     # a_tar + a_srcs = 1

def get_cons(ind,ntask):
    nperm = len(ind)
    ineq_cons = []
    eq_cons = []
    for ii in range(ntask):
        idx = [inner for outer in ind if outer[0]==ii or outer[1]==ii for inner in outer if inner!=ii]

        # a_tar + a_srcs = 1
        tmp_eq = {'type': 'eq', 'fun': lambda a: a[idx] + a[nperm + ii] - 1}
        eq_cons.append(tmp_eq)

        # a_tar > (individually) each a_src not multiplied by 0
        for jj in range(len(idx)):
            tmp_ineq = {'type': 'ineq', 'fun': lambda a: a[idx[jj]] - a[nperm+ii] }
            ineq_cons.append(tmp_ineq)

    return eq_cons #+ ineq_cons


def getMinimumCost(k, c):
    n = len(c)
    x = n // k
    price = 0
    for i in range(1 , x + 1):
        for _ in range(k):
            max_c = max(c)
            price += max_c * i
            c.remove(max_c)
    for j in c:
        price += j * (i +  1)
    return price

print(getMinimumCost(3 , [2, 5 , 6]))


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('janus', '0005_photogroup_order'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='photogroup',
            options={'ordering': ('gallery__title', 'order', 'title')},
        ),
        migrations.AddField(
            model_name='gallery',
            name='slug',
            field=models.CharField(default=b'', max_length=255),
            preserve_default=True,
        ),
    ]


# -*- coding: cp1252 -*-

import Tkinter

class simpleapp_tk(Tkinter.Tk):#Skapa klass för vårt fönster
	def __init__(self,parent):#Initieringsskit, constructor
		Tkinter.Tk.__init__(self,parent)
		self.parent = parent
		self.initialize()

	def initialize(self):
		self.grid()#Aktivera så gridden

		self.entryVariable = Tkinter.StringVar() #Gör en sträng variabel som vi sätter skriven text i
		self.entry = Tkinter.Entry(self,textvariable=self.entryVariable)#Skapa text ruta som går att skriva i
		self.entry.grid(column=0,row=0,sticky='EW')#Säg var den ska vara i griden
		self.entry.bind('<Return>', self.OnPressEnter)#När vi slår Return så händer OnPressEnter
		self.entryVariable.set(u'Enter text here.')#Sätt texten

		button = Tkinter.Button(self,text=u"Click me !", command=self.OnButtonClick)#Skapa en knapp som kallar på OnButtonClick
		button.grid(column=1,row=0)#Placera knappen i griden

		self.labelvariable = Tkinter.StringVar()#Skapa en variabel som visar text
		label = Tkinter.Label(self,textvariable=self.labelvariable,anchor='w',fg='white',bg='blue')#Gör den fin och säg att den ska titta på labelvariable
		label.grid(column=0,row=1,columnspan=2,sticky='ew')#Placera den i gridden
		self.labelvariable.set(u'Hello!')#En välkomnande text

		self.grid_columnconfigure(0,weight=1)#Gör att knapparna expanderar när fönstret gör det
		self.resizable(True,False)#Blockera horisontell förstoring av fönstret
		self.update()#Förhindra att fönstret ändrar storlek
		self.geometry(self.geometry())#Förhindra att fönstret ändrar storlek
		self.entry.focus_set()
		self.entry.selection_range(0, Tkinter.END)#Gör så att textmarkören hamnar på inmatningen efter events

	def OnButtonClick(self):#Skapa en klass för när vi trycker på knappen
		self.labelvariable.set( self.entryVariable.get() + "You clicked the button!")
		self.entry.focus_set()
		self.entry.selection_range(0, Tkinter.END)#Gör så att textmarkören hamnar på inmatningen efter events

	def OnPressEnter(self,event):#En klass för när vi slår Return
		#self.labelvariable.set( self.entryVariable.get() +  'You pressed enter!')
		self.CalcIt()
		self.entry.focus_set()
		self.entry.selection_range(0, Tkinter.END)#Gör så att textmarkören hamnar på inmatningen efter events

	def CalcIt(self):
		a=self.entryVariable.get()
		if a.isdigit():
			if int(a) % 2 == 0:
				self.labelvariable.set('Even')
			else:
				self.labelvariable.set('Uneven')
		else:
			self.labelvariable.set(a)

if __name__ == "__main__":#Här är vår loop som dunkar igång programmet
	app = simpleapp_tk(None)
	app.title('my application')
	app.mainloop()


import pickle
from scipy import stats

_file = open('util/troll_module.pkl', 'rb')
troll_module = pickle.load(_file)

def get_troll_score(champ_id, kda, dpm, gpm):
    '''이번 경기 성적이 해당티어(골드1) & 챔피언 중 상위 몇%인지 백분율'''

    data = [(kda, dpm, gpm)]
    pre_data = troll_module[champ_id]['pre_scaler'].transform(data)
    pca_data = troll_module[champ_id]['pca'].transform(pre_data)
    scaled_data = troll_module[champ_id]['post_scaler'].transform(pca_data)

    # 정규분포에서 누적분포함수(cumulative distribution function) 사용하여 백분율 환산
    return (1 - stats.norm(0, 1).cdf(scaled_data)[0][0]) * 100

def troll_preprocess(player, duration):
    '''플레이어와 게임시간을 입력받아 트롤지수 계산에 필요한 데이터 추출'''

    kills = player['stats']['kills']
    deaths = int(player['stats']['deaths'])
    deaths = 1 if deaths == 0 else deaths
    assists = player['stats']['assists']
    damage = player['stats']['totalDamageDealt']
    gold = player['stats']['goldEarned']

    # sec >> min 변환
    duration = duration / 60

    kda = (kills + assists) / deaths
    dpm = damage / duration
    gpm = gold / duration

    return (kda, dpm, gpm)

def main():
    score = get_troll_score(266, 0.2857142857142857, 50303/20, 5342/20)
    print(score) # 91.42267624213534

if __name__ == "__main__":
    main()


# from __future__ import print_function
import os, time, Image, sys
# sys.path.append("/home/pi/Python-Thermal-Printer")
# from Adafruit_Thermal import *

import kivy
kivy.require('1.0.6') # replace with your current kivy version !

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image as kivyImage
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle

# Some variables
photoPath = "/home/pi/photobooth/"
photoName = time.strftime("%Y%m%d%H%M%S") + "_photobooth.jpg"
photoResize = 512, 384
photoTitle = "Steves's Photo Booth!"

# Define printer
printer = Adafruit_Thermal("/dev/ttyAMA0", 19200, timeout=5)

# Callback function for photo button
def photo_callback(obj):
        # Define filename with timestamp
        photoName = time.strftime("%Y%m%d%H%M%S") + "_photobooth.jpg"
        # Take photo using "raspistill"
        os.system("sudo raspistill -p '144,48,512,384' --vflip -w 1920 -h 1440 -o " + photoPath + photoName)
        # Resize the high res photo to create thumbnail
        Image.open(photoPath + photoName).resize(photoResize, Image.ANTIALIAS).save(photoPath + "thumbnail.jpg")

# Callback function for print button
# def print_callback(obj):
        # Rotate the thumbnail for printing
        # Image.open(photoPath + "thumbnail.jpg").transpose(2).save(photoPath + "thumbnail-rotated.jpg")
        # Print the foto
        # printer.begin(90) # Warmup time
        # printer.setTimes(40000, 3000) # Set print and feed times
        # printer.justify('C') # Center alignment
        # printer.printImage(Image.open(photoPath + "line-top.png"), True)
        # printer.println(photoTitle)
        # printer.printImage(Image.open(photoPath + "line-bottom.png"), True)
        # printer.feed(1) # Add a blank line
        # printer.printImage(Image.open(photoPath + "thumbnail-rotated.jpg"), True) # Specify image to print
        # printer.feed(1) # Add a blank line
        # printer.printImage(Image.open(photoPath + "qr-code.png"), True) # Specify image to print
        # printer.feed(3) # Add a few blank lines

class MyApp(App):
        # Display the latest thumbnail
        photo = kivyImage(source="/home/pi/photobooth/thumbnail.jpg")

        def build(self):
                # Set up the layout
                photobox = GridLayout(cols=3, spacing=10, padding=10)

                # Create the UI objects (and bind them to callbacks, if necessary)
                photoButton = Button(text="photo", size_hint=(.20, 1)) # Button: 20% width, 100% height
                photoButton.bind(on_press=photo_callback) # when pressed, trigger the photo_callback function
                printButton = Button(text="print", size_hint=(.20, 1)) # Button: 20% width, 100% height
                # printButton.bind(on_press=print_callback) # when pressed, trigger the print_callback function
                printButton.bind(on_press=photo_callback) # when pressed, trigger the print_callback function

                # Periodically refresh the displayed photo using the callback function
                Clock.schedule_interval(self.callback, 1)

                # Add the UI elements to the layout
                photobox.add_widget(photoButton)
                photobox.add_widget(self.photo)
                photobox.add_widget(printButton)

                return photobox

        # Callback for thumbnail refresh
        def callback(self, instance):
                self.photo.reload()

if __name__ == '__main__':
        MyApp().run()


import argparse
import os
import random
import json
import shutil
import time
import warnings
import torch.cuda as cuda
import torch.backends.cudnn as cudnn
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision.datasets as datasets
import torchvision.transforms as T
from torch.utils.data import DataLoader, Dataset
from torch.optim import SGD
from torch.optim.lr_scheduler import MultiStepLR
import numpy as np
from logger import Logger
import os
from torch.nn.modules.loss import _Loss
import VGG_ImageNet as models
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
import PIL.Image as Image
from convOut_loader import convOut_Dataset

parser = argparse.ArgumentParser(description='PyTorch ImageNet Training')

parser.add_argument('--resume', default='', type=str)
parser.add_argument('--alpha', default='', type=str)
parser.add_argument('--gpu', default=0, type=int)
parser.add_argument('--convout',default='./ConvOut/convOut_CUB200_vgg16_bn_ft_L40_.pkl', type=str)
parser.add_argument('--sub_sampler', default='', type=str)
parser.add_argument('--model', default='sigmoid_p', type=str)
parser.add_argument('--sep_bar', action='store_true')
parser.add_argument('--bn', action='store_false')
parser.add_argument('--suffix', default='', type=str)
args = parser.parse_args()

device_ids=[2,3]
arch='vgg16_bn_ft'
seed=0
batch_size=64
# resume='model_best_CUB200_vgg16_bn_ft_v0.pth.tar'
# resume2='model_best_CUB200__vgg16_bn_sd_10_ep300.pth.tar'
dataset='CUB200'
topk=[1,3]

l = 37

convOut_path = args.convout
resume = args.resume
gpu = args.gpu

save_img = True
cmap = 'jet'

normalize = T.Normalize(mean=[0.485, 0.456, 0.406],
                        std=[0.229, 0.224, 0.225])

if dataset == 'ilsvrc':
    valdir = '/data/HaoChen/knowledge_distillation/ILSVRC2012_img_val'
    val_dataset = datasets.ImageFolder(
        valdir, T.Compose([
            T.Resize(256),
            T.CenterCrop(224),
            T.ToTensor(),
            normalize,
        ]))
    val_loader = DataLoader(
        val_dataset, batch_size=batch_size, shuffle=False,
        num_workers=4, pin_memory=True)

    criterion = nn.CrossEntropyLoss()  # .cuda(gpu_id)

    optimizer = torch.optim.SGD(net.parameters(), lr,
                                momentum=momentum,
                                weight_decay=weight_decay)
elif dataset == 'cifar10':
    transform_test = T.Compose([
        T.ToTensor(),  # [0, 256] -> [0, 1]
        T.Normalize(mean=[0.4914, 0.4822, 0.4465],  # mean
                    std=[0.2470, 0.2435, 0.2616]),  # std
    ])

    val_dataset = datasets.CIFAR10(root='/data/HaoChen/knowledge_distillation/data/CIFAR10', train=True,
                                   download=True, transform=transform_test)

elif dataset == 'CUB':
    valdir = '/data/HaoChen/CUB_bird_binary/val/'

    normalize = T.Normalize(mean=[0.4795, 0.4822, 0.4218],
                            std=[0.2507, 0.2469, 0.2760])

    val_dataset = datasets.ImageFolder(valdir, T.Compose([
        T.Resize(224),
        T.ToTensor(),
        normalize,
    ]))

elif dataset == 'CUB200':
    valdir = '/data/HaoChen/CUB_200_2011/crop/test'
    val_dataset = datasets.ImageFolder(
        valdir, T.Compose([
#                 T.RandomResizedCrop(224),
#                 T.RandomHorizontalFlip(),
            T.Resize((224,224)),
#             T.CenterCrop(224),
            T.ToTensor(),
            normalize,
        ]))
    val_loader = DataLoader(
        val_dataset, batch_size=batch_size, shuffle=False,
        num_workers=6, pin_memory=True)

denormalize = T.Normalize(mean=[-0.485/0.229, -0.456/0.224, -0.406/0.225],
                        std=[1/0.229, 1/0.224, 1/0.225])
toPIL = T.Compose([denormalize, T.ToPILImage()])

if args.sub_sampler =='':
    sub_idx = range(len(val_dataset))
else:
    sub_idx = np.load(args.sub_sampler).tolist()

if args.model == 'v2':
    from linearTest_v2 import LinearTester
elif args.model == 'new':
    from linearTest import LinearTester
elif args.model == 'sigmoid_p':
    from linearTest_sigmoidP import LinearTester
elif args.model == 'sigmoid_p_old':
    from linearTest_sigmoidP_old import LinearTester
elif args.model == 'v2p':
    from linearTest_v2_sigmoidP import LinearTester
else:
    from linearTest_v0 import LinearTester

if args.suffix != '':
    args.suffix = '('+args.suffix+')'

train_dataset = convOut_Dataset(convOut_path)
input_size = train_dataset.convOut1.shape[1:4]
output_size = train_dataset.convOut2.shape[1:4]
model = LinearTester(input_size,output_size, gpu_id= gpu, bn=args.bn).cuda(gpu)
checkpoint = torch.load(resume, map_location=torch.device("cuda:{}".format(gpu)))
model.load_state_dict(checkpoint['state_dict'])
del checkpoint

model.eval()
s_list = np.arange(0,len(sub_idx),len(sub_idx)//40)
show_list = np.arange(0,512,32)
ps = model.get_p().data.cpu().numpy()

for s in s_list:
    i = sub_idx[s]
    pack = train_dataset[i]
    input = pack['convOut1'].unsqueeze(0).cuda(gpu, non_blocking=True)
    target = pack['convOut2']
    output, output_n, output_contrib, output_zero = model.val_linearity(input)
    inputs = input.cpu().squeeze(0).numpy()
    output = output.numpy()
    output_n = output_n.numpy()
    target = target.numpy()
    residual = np.abs(target - output)
    # output_n[1] = output_n[1] / ps[0]
    # output_n[2] = output_n[2] / ps[0] / ps[1]
    vmin1 = np.min((inputs, output))
    vmin2 = np.min(output_n)
    vmax1 = np.max((inputs, output))
    vmax2 = np.max(output_n)
    if not args.sep_bar:
        vmax1 = vmax2 = np.max((vmax1, vmax2))
        vmin1 = vmin2 = np.min((vmin1, vmin2))
    #############################################################

    # show_list = np.random.permutation(np.arange(512))[:32]

    img_path = 'v2p_test_figs/normal/alpha' + args.alpha +args.suffix

    sub_img_path = img_path + '/%04d'%(i)

    if save_img:
        if not os.path.exists(img_path):
            os.makedirs(img_path)
        if not os.path.exists(sub_img_path):
            os.makedirs(sub_img_path)

    sum_output = np.sum(output, 0)
    sum_target = np.sum(target, 0)
    sum_output_n = np.sum(output_n, 1)
    sum_inputs = np.sum(inputs, 0)

    svmin1 = np.min((sum_inputs, sum_output))
    svmax1 = np.max((sum_inputs, sum_output))
    svmin2 = np.min(sum_output_n)
    svmax2 = np.max(sum_output_n)
    if not args.sep_bar:
        svmax1 = svmax2 = np.max((svmax1, svmax2))
        svmin1 = svmin2 = np.min((svmin1, svmin2))

    fig1, axes = plt.subplots(2, 4, figsize=(12, 12))
    fig1.suptitle("Sum of channels Alpha {}{}".format(args.alpha,args.suffix))
    axes[0][0].imshow(toPIL(val_dataset[i][0]))
    #     axes[1][0].imshow(toPIL(val_dataset[i][0]))
    axes[0][1].imshow(sum_inputs, cmap=cmap, vmin=svmin1, vmax=svmax1)
    axes[0][1].set_title("In")
    axes[0][2].imshow(sum_target, cmap=cmap, vmin=svmin1, vmax=svmax1)
    axes[0][2].set_title("Tar")
    im0 = axes[0][3].imshow(sum_output, cmap=cmap, vmin=svmin1, vmax=svmax1)
    axes[0][3].set_title("Out")

    axes[1][0].bar([0, 1, 2], [1.0, *ps[::-1]], 0.8)
    ylim = axes[1][0].get_ylim()
    xlim = axes[1][0].get_xlim()
    axes[1][0].set_aspect((xlim[1] - xlim[0]) / (ylim[1] - ylim[0]) * 1.5)
    axes[1][0].set_title('Ps')

    for k in range(1, 4):
        im1 = axes[1][k].imshow(sum_output_n[k - 1], cmap=cmap, vmin=svmin2, vmax=svmax2)
        axes[1][k].set_title("Y{}".format(k - 1))

    fig1.tight_layout()
    fig1.subplots_adjust(right=0.8)
    if args.sep_bar:
        cbar_ax1 = fig1.add_axes([0.85, 0.55, 0.05, 0.35])
        fig1.colorbar(im0, cax=cbar_ax1)
        cbar_ax2 = fig1.add_axes([0.85, 0.10, 0.05, 0.35])
        fig1.colorbar(im1, cax=cbar_ax2)
    else:
        cbar_ax2 = fig1.add_axes([0.85, 0.10, 0.05, 0.80])
        fig1.colorbar(im1, cax=cbar_ax2)
    plt.savefig(sub_img_path+'/'+'Sum{:04d}'.format(i))
    plt.close()

    for t in show_list[:]:
        print("Channel: ", t)
        fig1, axes = plt.subplots(2, 4, figsize=(12, 12))
        fig1.suptitle("Channel: {:03d} Alpha {}{}".format(t, args.alpha,args.suffix))
        axes[0][0].imshow(toPIL(val_dataset[i][0]))
        #     axes[1][0].imshow(toPIL(val_dataset[i][0]))
        axes[0][1].imshow(inputs[t], cmap=cmap, vmin=vmin1, vmax=vmax1)
        axes[0][1].set_title("In")
        axes[0][2].imshow(target[t], cmap=cmap, vmin=vmin1, vmax=vmax1)
        axes[0][2].set_title("Tar")
        im0 = axes[0][3].imshow(output[t], cmap=cmap, vmin=vmin1, vmax=vmax1)
        axes[0][3].set_title("Out")

        axes[1][0].bar([0, 1, 2], [1.0, *ps[::-1]], 0.8)
        ylim = axes[1][0].get_ylim()
        xlim = axes[1][0].get_xlim()
        axes[1][0].set_aspect((xlim[1] - xlim[0]) / (ylim[1] - ylim[0]) * 1.5)
        axes[1][0].set_title('Ps')

        for k in range(1, 4):
            im1 = axes[1][k].imshow(output_n[k - 1][t], cmap=cmap, vmin=vmin2, vmax=vmax2)
            axes[1][k].set_title("Y{}".format(k - 1))

        fig1.tight_layout()
        fig1.subplots_adjust(right=0.8)
        if args.sep_bar:
            cbar_ax1 = fig1.add_axes([0.85, 0.55, 0.05, 0.35])
            fig1.colorbar(im0, cax=cbar_ax1)
            cbar_ax2 = fig1.add_axes([0.85, 0.10, 0.05, 0.35])
            fig1.colorbar(im1, cax=cbar_ax2)
        else:
            cbar_ax2 = fig1.add_axes([0.85, 0.10, 0.05, 0.80])
            fig1.colorbar(im1, cax=cbar_ax2)
        fig1.colorbar(im1, cax=cbar_ax2)

        if save_img:
            plt.savefig(sub_img_path + '/' + "Channel_{:03d}".format(t))
    #     plt.show()
        plt.close()