#!/usr/bin/env python
# -*- coding: utf-8 -*-
from datetime import datetime
import dlib
import gzip
import json
import numpy as np
import sys

def read_devset(fh, mapping):
    # format fr-url <TAB> en-url
    devset = set()
    # print "Reading devset from ", fh.name
    for line in fh:
        surl, turl = line.strip().split()
        if surl in mapping['source_url_to_index']:
            assert turl in mapping['target_url_to_index']
        if turl in mapping['target_url_to_index']:
            assert surl in mapping['source_url_to_index']
            tidx = mapping['target_url_to_index'][turl]
            sidx = mapping['source_url_to_index'][surl]
            devset.add((sidx, tidx))

    return devset

def read_idx2url(fh):
    mapping = json.load(fh)
    return mapping

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('-devset', help='WMT16 devset',
                        type=argparse.FileType('r'), required=True)
    parser.add_argument('-idx2url', help='url to index mapping',
                        type=argparse.FileType('r'), required=True)
    parser.add_argument('-matrix',
                        help='read prediction/feature matrix',
                        type=argparse.FileType('r'), required=True)
    parser.add_argument('-matching',
                        help='compute max-cost matching',
                        action='store_true')
    parser.add_argument('-prefix',
                        help='output prefix (domain name)',
                        default="PREFIX")

    args = parser.parse_args(sys.argv[1:])

    url_mapping = read_idx2url(args.idx2url)
    devset = read_devset(args.devset, url_mapping)
    print "Loaded %d expected pairs from %s" % (len(devset), args.devset.name)

    fh = args.matrix
    if fh.name.endswith('.gz'):
        fh = gzip.GzipFile(fileobj=fh, mode='r')
    score_matrix = np.load(fh).astype(np.float32, copy=False)

    n_source, n_target = score_matrix.shape
    n_samples = n_source * n_target

    print "%d source / %d target docs" \
        % (n_source, n_target)

    print datetime.now()
    if args.matching:
        print "Finding best matching"
        matching_pairs = set()

        full_matrix = np.pad(
            score_matrix,
            ((0, max(score_matrix.shape) - score_matrix.shape[0]),
             (0, max(score_matrix.shape) - score_matrix.shape[1])),
            mode='constant')

        cost = dlib.matrix(full_matrix)
        print "Searching with dlib"
        assignment = dlib.max_cost_assignment(cost)

        for sidx, tidx in enumerate(assignment):
            if sidx >= score_matrix.shape[0] or tidx >= score_matrix.shape[1]:
                continue
            matching_pairs.add((sidx, tidx))

        print "Found %d matches " % (len(matching_pairs))
        found = devset.intersection(matching_pairs)
        print "Found %d out of %d pairs = %f%%" \
            % (len(found), len(devset), 100. * len(found) / len(devset))
        print "RES:\t%s\t%s\t%d\t%d" % (args.prefix, args.matrix.name,
                                        len(found), len(devset))
    else:
        print "Finding best match (greedy / restricted + argsort)"
        matches = set()
        seen_cols = set()
        seen_rows = set()
        sorted_indices = np.argsort(score_matrix, axis=None)
        for idx in sorted_indices[::-1]:
            am_row, am_col = np.unravel_index(idx, score_matrix.shape)
            if am_row in seen_rows or am_col in seen_cols:
                continue
            matches.add((am_row, am_col))
            seen_cols.add(am_col)
            seen_rows.add(am_row)

        print "Found %d matches " % (len(matches))
        found = devset.intersection(matches)
        print "Found %d out of %d pairs = %f%%" \
            % (len(found), len(devset), 100. * len(found) / len(devset))

        print "RES:\t%s\t%s\t%d\t%d" % (args.prefix, args.matrix.name,
                                        len(found), len(devset))

    print datetime.now()

    sys.exit()

    print "Finding best match (greedy)"
    greedy_matches = set()
    correct, errors = [], []
    # score_matrix = features[-1]
    # np.savetxt("scores", score_matrix)
    for s_idx in range(n_source):
        t_idx = np.argmax(score_matrix[s_idx])
        greedy_matches.add((s_idx, t_idx))

    # devset = set(devset.items())
    # print devset
    found = devset.intersection(greedy_matches)
    print "Found %d matches " % (len(greedy_matches))
    print "Found %d out of %d pairs = %f%%" \
        % (len(found), len(devset), 100. * len(found) / len(devset))

    print "Finding best match (greedy / restricted)"
    matches = set()
    correct, errors = [], []
    score_copy = score_matrix.copy()
    score_copy -= np.min(score_copy)
    while True:
        am = np.argmax(score_copy)
        am_row = am / score_copy.shape[1]
        am_col = am % score_copy.shape[1]
        if score_copy[am_row, am_col] <= 0:
            break
        matches.add((am_row, am_col))
        score_copy[am_row, :] = 0
        score_copy[:, am_col] = 0

        # if len(matches) >= min(n_source, n_target):
        #     break

    print "Found %d matches " % (len(matches))
    # print greedy_matches
    found = devset.intersection(matches)
    print "Found %d out of %d pairs = %f%%" \
        % (len(found), len(devset), 100. * len(found) / len(devset))

    result_greedy = len(found)
    #

    print "Finding best matching"
    matching_pairs = set()

    full_matrix = np.pad(
        score_matrix,
        ((0, max(score_matrix.shape) - score_matrix.shape[0]),
         (0, max(score_matrix.shape) - score_matrix.shape[1])),
        mode='constant')

    # print full_matrix.shape, np.sum(full_matrix)
    # print score_matrix.shape, np.sum(score_matrix)

    cost = dlib.matrix(full_matrix)
    print "Searching with dlib"
    assignment = dlib.max_cost_assignment(cost)
    # print assignment

    for sidx, tidx in enumerate(assignment):
        if sidx >= score_matrix.shape[0] or tidx >= score_matrix.shape[1]:
            continue
        matching_pairs.add((sidx, tidx))

    print "Found %d matches " % (len(matching_pairs))
    # print greedy_matches
    found = devset.intersection(matching_pairs)
    print "Found %d out of %d pairs = %f%%" \
        % (len(found), len(devset), 100. * len(found) / len(devset))
    result_matching = len(found)
    print "RESULT\t%s\t%d\t%d\t%d" % (args.matrix.name, len(devset),
                                      result_greedy, result_matching)


from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import numpy as np
import pyaudio
import time
from audioled.effects import Effect

def print_audio_devices():
    """Print information about the system's audio devices"""
    p = pyaudio.PyAudio()
    for i in range(p.get_device_count()):
        info = p.get_device_info_by_index(i)
        print(info['name'])
        print('\tDevice index:', info['index'])
        print('\tSample rate:', info['defaultSampleRate'])
        print('\tMax input channels:', info['maxInputChannels'])
        print('\tMax output channels:', info['maxOutputChannels'])
    p.terminate()

def numInputChannels(device_index=None):
    p = pyaudio.PyAudio()
    device = device_index
    defaults = p.get_default_host_api_info()
    if device_index is None:
        device = defaults['defaultInputDevice']
    info = p.get_device_info_by_index(device)
    p.terminate()
    return info['maxInputChannels']

class AudioInput(Effect):
    overrideDeviceIndex = None
    global_stream = None
    """
    Outputs:
    0: Audio Channel 0
    1: Audio Channel 1...
    """
    def __init__(self, device_index=None, chunk_rate=60, num_channels=2, autogain_max=10.0, autogain=False, autogain_time=10.0):
        self.device_index = device_index
        self.chunk_rate = chunk_rate
        self.num_channels = num_channels
        self.autogain_max = autogain_max
        self.autogain = autogain
        self.autogain_time = autogain_time
        self.__initstate__()

    def __initstate__(self):
        super(AudioInput, self).__initstate__()
        deviceIndex = self.device_index
        if self.overrideDeviceIndex is not None:
            deviceIndex = self.overrideDeviceIndex
        self._audioStream, self._sampleRate = self.stream_audio(chunk_rate=self.chunk_rate, channels=self.num_channels, device_index=deviceIndex)
        self._buffer = []
        self._chunk_size = int(self._sampleRate / self.chunk_rate)
        # increase cur_gain by percentage
        # we want to get to self.autogain_max in approx. self.autogain_time seconds
        min_value = 1. / self.autogain_max  # the minimum input value we want to bring to 1.0
        N = self.chunk_rate * self.autogain_time  # N = chunks_per_second * autogain_time
        # min_value * (perc)^N = 1.0?
        # perc = root(1.0 / min_value, N) = (1./min_value)**(1/N)
        self._autogain_perc = (1.0 / min_value)**float(1 / N)
        self._cur_gain = 1.0

    def _open_input_stream(self, device_index=None, channels=1, retry=0):
        """Opens a PyAudio audio input stream

        Parameters
        ----------
        device_index: int, optional
            Device index for the PyAudio audio input stream.
            If device index is not specified then the default audio device
            will be opened.
        """
        p = pyaudio.PyAudio()
        defaults = p.get_default_host_api_info()

        print("Using audio device {}".format(device_index))
        device_info = p.get_device_info_by_index(device_index)

        if device_info['maxInputChannels'] == 0:
            err = 'Your audio input device cannot be opened. '
            err += 'Change default audio device or try a different device index. '
            err += 'Device info:\n{}\n{}'.format(defaults, device_info)
            raise OSError(err)

        try:
            stream = p.open(format=pyaudio.paFloat32,
                            channels=channels,
                            rate=int(device_info['defaultSampleRate']),
                            input=True,
                            input_device_index=device_index,
                            frames_per_buffer=0)
        except OSError as e:
            if retry==5:
                err = 'Error occurred while attempting to open audio device. '
                err += 'Check your operating system\'s audio device configuration. '
                err += 'Audio device information: \n'
                err += str(device_info)
                print(err)
                raise e
            time.sleep(retry)
            return self._open_input_stream(device_index=device_index, channels=channels, retry=retry+1)
        return stream, int(device_info['defaultSampleRate'])

    def stream_audio(self, chunk_rate=60, ignore_overflows=True, device_index=None, channels=1):
        if device_index is None:
            print("No device_index for audio given. Using default.")
            p = pyaudio.PyAudio()
            defaults = p.get_default_host_api_info()
            p.terminate()
            device_index = defaults['defaultInputDevice']
            if device_index == -1:
                err = 'No default audio device configured. '
                err += 'Change default audio device or supply a specific device index. '
                raise OSError(err)
        # Get samplerate for device
        p = pyaudio.PyAudio()
        device_info = p.get_device_info_by_index(device_index)
        samplerate = int(device_info['defaultSampleRate'])

        chunk_length = int(samplerate // chunk_rate)

        def audio_chunks():
            fs = samplerate
            while True:
                try:
                    if AudioInput.global_stream is None:
                        AudioInput.global_stream, fs = self._open_input_stream(device_index, channels=channels)

                    chunk = AudioInput.global_stream.read(chunk_length)
                except IOError as e:
                    if e.errno == pyaudio.paInputOverflowed:
                        print('Audio buffer full')
                        if ignore_overflows:
                            AudioInput.global_stream, fs = self._open_input_stream(device_index, channels=channels)
                            continue
                        else:
                            raise e
                chunk = np.fromstring(chunk, np.float32).astype(np.float)
                yield chunk
        return audio_chunks(), samplerate

    def numOutputChannels(self):
        return self.num_channels

    def numInputChannels(self):
        return 0

    @staticmethod
    def getParameterDefinition():
        definition = {
            "parameters": {
                # default, min, max, stepsize
                "autogain_max": [1.0, 0.0, 50.0, 0.01],
                "autogain_time": [30.0, 1.0, 100.0, 0.1],
                "autogain": False,
                "num_channels": [2, 1, 100, 1]
            }
        }
        return definition

    def getParameter(self):
        definition = self.getParameterDefinition()
        definition['parameters']['autogain_max'][0] = self.autogain_max
        definition['parameters']['autogain_time'][0] = self.autogain_time
        definition['parameters']['autogain'] = self.autogain
        return definition

    def getSampleRate(self):
        return self._sampleRate

    async def update(self, dt):
        await super(AudioInput, self).update(dt)
        self._buffer = next(self._audioStream)

    def process(self):
        if self.autogain:
            # determine max value -> in range 0,1
            maxVal = np.max(self._buffer)
            if maxVal * self._cur_gain > 1:
                # reset cur_gain to prevent clipping
                self._cur_gain = 1. / maxVal
            elif self._cur_gain < self.autogain_max:
                self._cur_gain = min(self.autogain_max, self._cur_gain * self._autogain_perc)
            # print("cur_gain: {}, gained value: {}".format(self._cur_gain, self._cur_gain * maxVal))
        for i in range(0, self.num_channels):
            # layout for multiple channel is interleaved:
            # 00 01 .. 0n 10 11 .. 1n
            self._outputBuffer[i] = self._cur_gain * self._buffer[i::self.num_channels]
            #print("{}: {}".format(i, self._outputBuffer[i]))


import cv2
import os
import time
import numpy as np
from net.mtcnn import mtcnn
import utils.utils as utils
from net.inception import InceptionResNetV1

class face_rec():
    def __init__(self):
        # 创建mtcnn对象
        # 检测图片中的人脸
        self.mtcnn_model = mtcnn()
        # 门限函数
        self.threshold = [0.5,0.8,0.9]

        # 载入facenet
        # 将检测到的人脸转化为128维的向量
        self.facenet_model = InceptionResNetV1()
        # model.summary()
        model_path = './model_data/facenet_keras.h5'
        self.facenet_model.load_weights(model_path)

        #-----------------------------------------------#
        #   对数据库中的人脸进行编码
        #   known_face_encodings中存储的是编码后的人脸
        #   known_face_names为人脸的名字
        #-----------------------------------------------#
        face_list = os.listdir("face_dataset")

        self.known_face_encodings=[]

        self.known_face_names=[]

        for face in face_list:
            name = face.split(".")[0]

            img = cv2.imread("./face_dataset/"+face)
            img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

            # 检测人脸
            rectangles = self.mtcnn_model.detectFace(img, self.threshold)

            # 转化成正方形
            rectangles = utils.rect2square(np.array(rectangles))
            # facenet要传入一个160x160的图片
            rectangle = rectangles[0]
            # 记下他们的landmark
            landmark = (np.reshape(rectangle[5:15],(5,2)) - np.array([int(rectangle[0]),int(rectangle[1])]))/(rectangle[3]-rectangle[1])*160

            crop_img = img[int(rectangle[1]):int(rectangle[3]), int(rectangle[0]):int(rectangle[2])]
            crop_img = cv2.resize(crop_img,(160,160))

            new_img,_ = utils.Alignment_1(crop_img,landmark)

            new_img = np.expand_dims(new_img,0)
            # 将检测到的人脸传入到facenet的模型中，实现128维特征向量的提取
            face_encoding = utils.calc_128_vec(self.facenet_model,new_img)

            self.known_face_encodings.append(face_encoding)
            self.known_face_names.append(name)

    def recognize(self,draw):
        #-----------------------------------------------#
        #   人脸识别
        #   先定位，再进行数据库匹配
        #-----------------------------------------------#
        height,width,_ = np.shape(draw)
        draw_rgb = cv2.cvtColor(draw,cv2.COLOR_BGR2RGB)

        # 检测人脸
        rectangles = self.mtcnn_model.detectFace(draw_rgb, self.threshold)

        if len(rectangles)==0:
            return

        # 转化成正方形
        rectangles = utils.rect2square(np.array(rectangles,dtype=np.int32))
        rectangles[:,0] = np.clip(rectangles[:,0],0,width)
        rectangles[:,1] = np.clip(rectangles[:,1],0,height)
        rectangles[:,2] = np.clip(rectangles[:,2],0,width)
        rectangles[:,3] = np.clip(rectangles[:,3],0,height)
        #-----------------------------------------------#
        #   对检测到的人脸进行编码
        #-----------------------------------------------#
        face_encodings = []
        for rectangle in rectangles:
            landmark = (np.reshape(rectangle[5:15],(5,2)) - np.array([int(rectangle[0]),int(rectangle[1])]))/(rectangle[3]-rectangle[1])*160

            crop_img = draw_rgb[int(rectangle[1]):int(rectangle[3]), int(rectangle[0]):int(rectangle[2])]
            crop_img = cv2.resize(crop_img,(160,160))

            new_img,_ = utils.Alignment_1(crop_img,landmark)
            new_img = np.expand_dims(new_img,0)

            face_encoding = utils.calc_128_vec(self.facenet_model,new_img)
            face_encodings.append(face_encoding)

        face_names = []
        for face_encoding in face_encodings:
            # 取出一张脸并与数据库中所有的人脸进行对比，计算得分
            matches = utils.compare_faces(self.known_face_encodings, face_encoding, tolerance = 0.6)
            name = "Unknown"
            # 找出距离最近的人脸
            face_distances = utils.face_distance(self.known_face_encodings, face_encoding)
            # 取出这个最近人脸的评分
            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = self.known_face_names[best_match_index]
            face_names.append(name)

        rectangles = rectangles[:,0:4]
        #-----------------------------------------------#
        #   画框~!~
        #-----------------------------------------------#
        for (left, top, right, bottom), name in zip(rectangles, face_names):
            cv2.rectangle(draw, (left, top), (right, bottom), (0, 0, 255), 2)

            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(draw, name, (left , bottom - 15), font, 0.75, (255, 255, 255), 2)
        return draw

if __name__ == "__main__":

    dududu = face_rec()
    video_capture = cv2.VideoCapture(0)

    num_frames = 0
    since = time.time()
    while True:
        ret, draw = video_capture.read()
        #if num_frames % 4 == 1:
        dududu.recognize(draw)
        # put the text into video
        num_frames += 1
        cv2.putText(draw, f'FPS{num_frames / (time.time() - since):.2f}', (50,50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0,0,255), 2)
        cv2.imshow('Video', draw)
        if cv2.waitKey(20) & 0xFF == ord('q'):
            break

    video_capture.release()
    cv2.destroyAllWindows()


#!/usr/bin/env python3

# This script computes region proposals, confidence scores and speaker embeddings
# with RPNSD model

import argparse
import os
import random
import socket

import numpy as np
import torch
from diarization_dataset import DiarDataset_EVAL
from model.faster_rcnn.resnet import resnet
from model.utils.config import cfg_from_file
from utils import evaluate_no_nms

print(socket.gethostname())

torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False

parser = argparse.ArgumentParser(
    description='Region Proposal Network based Speaker Diarization Evaluation')
parser.add_argument('exp_dir', type=str,
                    help='path of experiment')
parser.add_argument('test_dir', type=str,
                    help='directory for test')
parser.add_argument('modelfile', type=str,
                    help='model filename')
parser.add_argument('--cfg_file', default="", type=str,
                    help='configure file')
parser.add_argument('--output_dir', default="", type=str,
                    help='output directory')

# data process parameters
parser.add_argument('--rate', default=8000, type=int,
                    help='sample rate')
parser.add_argument('--frame_size', default=512, type=int,
                    help='frame size')
parser.add_argument('--frame_shift', default=80, type=int,
                    help='frame shift')
parser.add_argument('--merge_dis', default=0.0, type=float,
                    help='merge two segments if their distance is smaller than merge_dis')
parser.add_argument('--min_dis', default=0.2, type=float,
                    help='minimum length of each segment, discard segments that are too short')

# training parameters
parser.add_argument('--batch_size', default=1, type=int,
                    help='mini-batch size')
parser.add_argument('--num_workers', default=0, type=int,
                    help='number of workers for data loading')
parser.add_argument('--seed', default=7, type=int,
                    help='random seed')
parser.add_argument('--freeze', default=0, type=int,
                    help='whether to freeze the model parameters')
parser.add_argument('--set_bn_fix', default=0, type=int,
                    help='whether to set batchnorm fixed')
parser.add_argument('--pretrain_resnet_model', default=None, type=str,
                    help='the directory of pretrained resnet model')
parser.add_argument('--use_gpu', default=0, type=int,
                    help='whether to use gpu for evaluation')

# network parameters
parser.add_argument('--arch', default='res101', type=str,
                    help='model architecture')
parser.add_argument('--nclass', default=1284, type=int,
                    help='number of classes (1283 spk and background)')

def main():
    global args
    args = parser.parse_args()
    print(args)

    # set random seed
    random.seed(args.seed)
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)

    if args.use_gpu:
        assert torch.cuda.is_available()
        device = torch.device("cuda:0")
    else:
        device = torch.device("cpu")

    # prepare test set
    test_dataset = DiarDataset_EVAL(args.test_dir, args.rate, args.frame_size, args.frame_shift, None, args.merge_dis,
                                    args.min_dis)

    test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                              batch_size=args.batch_size,
                                              num_workers=args.num_workers,
                                              shuffle=False)
    print("{} TEST segments".format(len(test_dataset)))

    if args.cfg_file == "":
        args.cfg_file = "cfgs/{}.yml".format(args.arch)
    print("Using configure file {}".format(args.cfg_file))

    if args.cfg_file is not None:
        cfg_from_file(args.cfg_file)

    # initilize the network here.
    if args.arch == 'res101':
        model = resnet(args.nclass, 101, pretrained=args.pretrain_resnet_model, freeze=args.freeze,
                       set_bn_fix=args.set_bn_fix)
    else:
        raise ValueError("Network is not supported")
    model.create_architecture()
    model = model.to(device)

    # load parameters
    if os.path.isfile(args.modelfile):
        print("Loading checkpoint '{}'".format(args.modelfile))
        if args.use_gpu:
            checkpoint = torch.load(args.modelfile)
        else:
            checkpoint = torch.load(args.modelfile, map_location="cpu")
        model.load_state_dict(checkpoint['model'])
        print("Loaded checkpoint '{}' (epoch {} iter {})"
              .format(args.modelfile, checkpoint['epoch'], checkpoint['iter']))
        print("Best score {:.4f}".format(checkpoint['best_score']))
    else:
        raise ValueError("=> No checkpoint found at '{}'".format(args.modelfile))

    if not os.path.exists(args.output_dir):
        os.makedirs(args.output_dir)

    # evaluation
    evaluate_no_nms(test_loader, model, device, args)
    return 0

if __name__ == "__main__":
    main()


import numpy
import conf
import sys
import random
def STATS(NEVENT,NGOOD):
	# IMPLICIT #real*8 (A-H,O-Z)
	# IMPLICIT #integer*8 (I-N)
	# COMMON/SETP/TMAX,SMALL,API,ESTART,THETA,PHI,TCFMAX(10),TCFMAX1,RSTART,EFIELD,ETHRM,ECUT,NDELTA,IMIP,IWRITE
	# COMMON/IDEXC/NGEXC1,NGEXC2,NGEXC3,NGEXC4,NGEXC5,NGEXC6,IDG1,IDG2,IDG3,IDG4,IDG5,IDG6
	# COMMON/PRIM3/MSUM(10000),MCOMP(10000),MRAYL(10000),MPAIR(10000),MPHOT(10000),MVAC(10000)
	# COMMON/STTS/XST(150000),YST(150000),ZST(150000),TIME(150000),TTIME(150000),NFGF(150000),NFGPP(150000),NFGBR(150000),NELEC,NEGION,EST1,EST2
	# COMMON/STEXC/XSTEXC(150000),YSTEXC(150000),ZSTEXC(150000),TSTEXC(150000),NSTEXC
	# COMMON/STEXCNUL/XSTN(150000),YSTN(150000),ZSTN(150000),TSTN(150000),IDNUL(150000),NEXCNUL
	# COMMON/CLUS/XAV[100000],YAV[100000],ZAV[100000],TAV[100000],XYAV[100000],XYZAV[100000],DX(100000),DY(100000),DZ[100000],DT(100000),DXY(100000),DXYZ[100000],NCL(100000),FARX1(100000),FARY1(100000),FARZ1(100000),FARXY1(100000),RMAX1(100000),TSUM(100000),XNEG(100000), YNEG(100000),ZNEG(100000),EDELTA[100000],EDELTA2(100000),NCLEXC(100000)
	# COMMON/PLOT/NXPL10(31),NYPL10(31),NZPL10(31),NXPL40(31),NYPL40(31),NZPL40(31),NXPL100(31),NYPL100(31),NZPL100(31),NXPL400(31),NYPL400(31),NZPL400(31),NXPL1000(31),NYPL1000(31),NZPL1000(31),NXPL2(31),NYPL2(31),NZPL2(31),NXPL4000(31),NYPL4000(31),NZPL4000(31),NXPL10000(31),NYPL10000(31),NZPL10000(31),NXPL40000(31),NYPL40000(31),NZPL40000(31),NXPL100000(31),NYPL100000(31),NZPL100000(31),NRPL2(31),NRPL10(31),NRPL40(31),NRPL100(31),NRPL400(31),NRPL1000(31),NRPL4000(31),NRPL10000(31),NRPL40000(31),NRPL100000(31),NEPL1(100),NEPL10(100),NEPL100(100),MELEC(1000),MELEC3(1000),MELEC10(1000),MELEC30(1000),MELEC100(1000),MELEC300(1000)
	#COMMON/SETP/
	global TMAX,SMALL,API,ESTART,THETA,PHI,TCFMAX#(10)
	global TCFMAX1,RSTART,EFIELD,ETHRM,ECUT,NDELTA,IMIP,IWRITE
	#COMMON/IDEXC/
	global NGEXC1,NGEXC2,NGEXC3,NGEXC4,NGEXC5,NGEXC6,IDG1,IDG2,IDG3,IDG4,IDG5,IDG6
	#COMMON/PRIM3/
	global MSUM#(10000)
	global MCOMP#(10000)
	global MRAYL#(10000)
	global MPAIR#(10000)
	global MPHOT#(10000)
	global MVAC#(10000)
	#COMMON/STTS/
	global XST#(150000)
	global YST#(150000)
	global ZST#(150000)
	global TIME#(150000)
	global TTIME#(150000)
	global NFGF#(150000)
	global NFGPP#(150000)
	global NFGBR#(150000)
	global NELEC,NEGION,EST1,EST2
	#COMMON/STEXC/
	global XSTEXC#(150000)
	global YSTEXC#(150000)
	global ZSTEXC#(150000)
	global TSTEXC#(150000)
	global NSTEXC
	#COMMON/STEXCNUL/
	global XSTN#(150000)
	global YSTN#(150000)
	global ZSTN#(150000)
	global TSTN#(150000)
	global IDNUL#(150000)
	global NEXCNUL
	#COMMON/CLUS/
	global XAV#(100000)
	global YAV#(100000)
	global ZAV#(100000)
	global TAV#(100000)
	global XYAV#(100000)
	global XYZAV#(100000)
	global DX#(100000)
	global DY#(100000)
	global DZ#(100000)
	global DT#(100000)
	global DXY#(100000)
	global DXYZ#(100000)
	global NCL#(100000)
	global FARX1#(100000)
	global FARY1#(100000)
	global FARZ1#(100000)
	global FARXY1#(100000)
	global RMAX1#(100000)
	global TSUM#(100000)
	global XNEG#(100000)
	global YNEG#(100000)
	global ZNEG#(100000)
	global EDELTA#(100000)
	global EDELTA2#(100000)
	global NCLEXC#(100000)
	#COMMON/PLOT/
	global NXPL10#(31)
	global NYPL10#(31)
	global NZPL10#(31)
	global NXPL40#(31)
	global NYPL40#(31)
	global NZPL40#(31)
	global NXPL100#(31)
	global NYPL100#(31)
	global NZPL100#(31)
	global NXPL400#(31)
	global NYPL400#(31)
	global NZPL400#(31)
	global NXPL1000#(31)
	global NYPL1000#(31)
	global NZPL1000#(31)
	global NXPL2#(31)
	global NYPL2#(31)
	global NZPL2#(31)
	global NXPL4000#(31)
	global NYPL4000#(31)
	global NZPL4000#(31)
	global NXPL10000#(31)
	global NYPL10000#(31)
	global NZPL10000#(31)
	global NXPL40000#(31)
	global NYPL40000#(31)
	global NZPL40000#(31)
	global NXPL100000#(31)
	global NYPL100000#(31)
	global NZPL100000#(31)
	global NRPL2#(31)
	global NRPL10#(31)
	global NRPL40#(31)
	global NRPL100#(31)
	global NRPL400#(31)
	global NRPL1000#(31)
	global NRPL4000#(31)
	global NRPL10000#(31)
	global NRPL40000#(31)
	global NRPL100000#(31)
	global NEPL1#(100)
	global NEPL10#(100)
	global NEPL100#(100)
	global MELEC#(1000)
	global MELEC3#(1000)
	global MELEC10#(1000)
	global MELEC30#(1000)
	global MELEC100#(1000)
	global MELEC300#(1000)
	def get_globals():
		TMAX=conf.TMAX
		SMALL=conf.SMALL
		API=conf.API
		ESTART=conf.ESTART
		THETA=conf.THETA
		PHI=conf.PHI
		TCFMAX=conf.TCFMAX
		TCFMAX1=conf.TCFMAX1
		RSTART=conf.RSTART
		EFIELD=conf.EFIELD
		ETHRM=conf.ETHRM
		ECUT=conf.ECUT
		NDELTA=conf.NDELTA
		IMIP=conf.IMIP
		IWRITE  =conf.IWRITE
		NGEXC1=conf.NGEXC1
		NGEXC2=conf.NGEXC2
		NGEXC3=conf.NGEXC3
		NGEXC4=conf.NGEXC4
		NGEXC5=conf.NGEXC5
		NGEXC6=conf.NGEXC6
		IDG1=conf.IDG1
		IDG2=conf.IDG2
		IDG3=conf.IDG3
		IDG4=conf.IDG4
		IDG5=conf.IDG5
		IDG6=conf.IDG6
		MSUM=conf.MSUM
		MCOMP=conf.MCOMP
		MRAYL=conf.MRAYL
		MPAIR=conf.MPAIR
		MPHOT=conf.MPHOT
		MVAC=conf.MVAC
		XST=conf.XST
		YST=conf.YST
		ZST=conf.ZST
		TIME=conf.TIME
		TTIME=conf.TTIME
		NFGF=conf.NFGF
		NFGPP=conf.NFGPP
		NFGBR=conf.NFGBR
		NELEC=conf.NELEC
		NEGION=conf.NEGION
		EST1=conf.EST1
		EST2=conf.EST2
		XSTEXC=conf.XSTEXC
		YSTEXC=conf.YSTEXC
		ZSTEXC=conf.ZSTEXC
		TSTEXC=conf.TSTEXC
		NSTEXC=conf.NSTEXC
		XSTN=conf.XSTN
		YSTN=conf.YSTN
		ZSTN=conf.ZSTN
		TSTN=conf.TSTN
		IDNUL=conf.IDNUL
		NEXCNUL=conf.NEXCNUL
		XAV=conf.XAV
		YAV=conf.YAV
		ZAV=conf.ZAV
		TAV=conf.TAV
		XYAV=conf.XYAV
		XYZAV=conf.XYZAV
		DX=conf.DX
		DY=conf.DY
		DZ=conf.DZ
		DT=conf.DT
		DXY=conf.DXY
		DXYZ=conf.DXYZ
		NCL=conf.NCL
		FARX1=conf.FARX1
		FARY1=conf.FARY1
		FARZ1=conf.FARZ1
		FARXY1=conf.FARXY1
		RMAX1=conf.RMAX1
		TSUM=conf.TSUM
		XNEG=conf.XNEG
		YNEG=conf.YNEG
		ZNEG=conf.ZNEG
		EDELTA=conf.EDELTA
		EDELTA2=conf.EDELTA2
		NCLEXC=conf.NCLEXC
		NXPL10=conf.NXPL10
		NYPL10=conf.NYPL10
		NZPL10=conf.NZPL10
		NXPL40=conf.NXPL40
		NYPL40=conf.NYPL40
		NZPL40=conf.NZPL40
		NXPL100=conf.NXPL100
		NYPL100=conf.NYPL100
		NZPL100=conf.NZPL100
		NXPL400=conf.NXPL400
		NYPL400=conf.NYPL400
		NZPL400=conf.NZPL400
		NXPL1000=conf.NXPL1000
		NYPL1000=conf.NYPL1000
		NZPL1000=conf.NZPL1000
		NXPL2=conf.NXPL2
		NYPL2=conf.NYPL2
		NZPL2=conf.NZPL2
		NXPL4000=conf.NXPL4000
		NYPL4000=conf.NYPL4000
		NZPL4000=conf.NZPL4000
		NXPL10000=conf.NXPL10000
		NYPL10000=conf.NYPL10000
		NZPL10000=conf.NZPL10000
		NXPL40000=conf.NXPL40000
		NYPL40000=conf.NYPL40000
		NZPL40000=conf.NZPL40000
		NXPL100000=conf.NXPL100000
		NYPL100000=conf.NYPL100000
		NZPL100000=conf.NZPL100000
		NRPL2=conf.NRPL2
		NRPL10=conf.NRPL10
		NRPL40=conf.NRPL40
		NRPL100=conf.NRPL100
		NRPL400=conf.NRPL400
		NRPL1000=conf.NRPL1000
		NRPL4000=conf.NRPL4000
		NRPL10000=conf.NRPL10000
		NRPL40000=conf.NRPL40000
		NRPL100000=conf.NRPL100000
		NEPL1=conf.NEPL1
		NEPL10=conf.NEPL10
		NEPL100=conf.NEPL100
		MELEC=conf.MELEC
		MELEC3=conf.MELEC3
		MELEC10=conf.MELEC10
		MELEC30=conf.MELEC30
		MELEC100=conf.MELEC100
		MELEC300=conf.MELEC300
		globals().update(locals())
	get_globals()
	def update_globals():
		conf.TMAX=TMAX
		conf.SMALL=SMALL
		conf.API=API
		conf.ESTART=ESTART
		conf.THETA=THETA
		conf.PHI=PHI
		conf.TCFMAX=TCFMAX
		conf.TCFMAX1=TCFMAX1
		conf.RSTART=RSTART
		conf.EFIELD=EFIELD
		conf.ETHRM=ETHRM
		conf.ECUT=ECUT
		conf.NDELTA=NDELTA
		conf.IMIP=IMIP
		conf.IWRITE  =IWRITE
		conf.NGEXC1=NGEXC1
		conf.NGEXC2=NGEXC2
		conf.NGEXC3=NGEXC3
		conf.NGEXC4=NGEXC4
		conf.NGEXC5=NGEXC5
		conf.NGEXC6=NGEXC6
		conf.IDG1=IDG1
		conf.IDG2=IDG2
		conf.IDG3=IDG3
		conf.IDG4=IDG4
		conf.IDG5=IDG5
		conf.IDG6=IDG6
		conf.MSUM=MSUM
		conf.MCOMP=MCOMP
		conf.MRAYL=MRAYL
		conf.MPAIR=MPAIR
		conf.MPHOT=MPHOT
		conf.MVAC=MVAC
		conf.XST=XST
		conf.YST=YST
		conf.ZST=ZST
		conf.TIME=TIME
		conf.TTIME=TTIME
		conf.NFGF=NFGF
		conf.NFGPP=NFGPP
		conf.NFGBR=NFGBR
		conf.NELEC=NELEC
		conf.NEGION=NEGION
		conf.EST1=EST1
		conf.EST2=EST2
		conf.XSTEXC=XSTEXC
		conf.YSTEXC=YSTEXC
		conf.ZSTEXC=ZSTEXC
		conf.TSTEXC=TSTEXC
		conf.NSTEXC=NSTEXC
		conf.XSTN=XSTN
		conf.YSTN=YSTN
		conf.ZSTN=ZSTN
		conf.TSTN=TSTN
		conf.IDNUL=IDNUL
		conf.NEXCNUL=NEXCNUL
		conf.XAV=XAV
		conf.YAV=YAV
		conf.ZAV=ZAV
		conf.TAV=TAV
		conf.XYAV=XYAV
		conf.XYZAV=XYZAV
		conf.DX=DX
		conf.DY=DY
		conf.DZ=DZ
		conf.DT=DT
		conf.DXY=DXY
		conf.DXYZ=DXYZ
		conf.NCL=NCL
		conf.FARX1=FARX1
		conf.FARY1=FARY1
		conf.FARZ1=FARZ1
		conf.FARXY1=FARXY1
		conf.RMAX1=RMAX1
		conf.TSUM=TSUM
		conf.XNEG=XNEG
		conf.YNEG=YNEG
		conf.ZNEG=ZNEG
		conf.EDELTA=EDELTA
		conf.EDELTA2=EDELTA2
		conf.NCLEXC=NCLEXC
		conf.NXPL10=NXPL10
		conf.NYPL10=NYPL10
		conf.NZPL10=NZPL10
		conf.NXPL40=NXPL40
		conf.NYPL40=NYPL40
		conf.NZPL40=NZPL40
		conf.NXPL100=NXPL100
		conf.NYPL100=NYPL100
		conf.NZPL100=NZPL100
		conf.NXPL400=NXPL400
		conf.NYPL400=NYPL400
		conf.NZPL400=NZPL400
		conf.NXPL1000=NXPL1000
		conf.NYPL1000=NYPL1000
		conf.NZPL1000=NZPL1000
		conf.NXPL2=NXPL2
		conf.NYPL2=NYPL2
		conf.NZPL2=NZPL2
		conf.NXPL4000=NXPL4000
		conf.NYPL4000=NYPL4000
		conf.NZPL4000=NZPL4000
		conf.NXPL10000=NXPL10000
		conf.NYPL10000=NYPL10000
		conf.NZPL10000=NZPL10000
		conf.NXPL40000=NXPL40000
		conf.NYPL40000=NYPL40000
		conf.NZPL40000=NZPL40000
		conf.NXPL100000=NXPL100000
		conf.NYPL100000=NYPL100000
		conf.NZPL100000=NZPL100000
		conf.NRPL2=NRPL2
		conf.NRPL10=NRPL10
		conf.NRPL40=NRPL40
		conf.NRPL100=NRPL100
		conf.NRPL400=NRPL400
		conf.NRPL1000=NRPL1000
		conf.NRPL4000=NRPL4000
		conf.NRPL10000=NRPL10000
		conf.NRPL40000=NRPL40000
		conf.NRPL100000=NRPL100000
		conf.NEPL1=NEPL1
		conf.NEPL10=NEPL10
		conf.NEPL100=NEPL100
		conf.MELEC=MELEC
		conf.MELEC3=MELEC3
		conf.MELEC10=MELEC10
		conf.MELEC30=MELEC30
		conf.MELEC100=MELEC100
		conf.MELEC300=MELEC300
	#-----------------------------------------------------------------------
	#  NEVENT IS EVENT EVENT POINTER. NGOOD IS GOOD EVENT POINTER
	#  FORMS AVERAGES OVER EACH DELTA AND DOES SOME STATISTICS
	#  LOADS PLOT ARRAYS XPLOT YPLOT AND ZPLOT (SCALED BY 1 10 AND 100)
	#  OUTPUTS RAW DATA TO FILE IF IWRITE CONTROL GT  0
	#  OUTPUTS THERMALISED ELECTRON X,Y,Z AND T IF  IWRITE EQ 1
	#  OUTPUTS ALSO X,Y,Z AND T FOR EACH  EXCITATION IF
	#  IWRITE EQ 2
	# ----------------------------------------------------------------------
	if(NGOOD <= 0):
		print(' IN STATS NEVENT=',NEVENT,' NGOOD=',NGOOD)
	# endif
	NCLUS=NELEC-NEGION
	if(NCLUS > 150000):
		# GO TO 99
		pass
	else:
		SUMX=0.00
		SUMX2=0.00
		SUMY=0.00
		SUMY2=0.00
		SUMZ=0.00
		SUMZ2=0.00
		SUMRXY=0.00
		SUMRXY2=0.00
		SUMRXYZ=0.00
		SUMRXYZ2=0.00
		SUMT=0.00
		SUMT2=0.00
		FARX=0.00
		FARY=0.00
		FARZ=0.00
		FARXY=0.00
		RMAX=0.00
		SUMTT=0.00
		NXNEG=0
		NYNEG=0
		NZNEG=0
		ESUM=0.0
		ATOTR=0.0
		ATOTC=0.0
		ATOTP=0.0
		ATOTPE=0.0
		#
		for IS in range(1,int(NCLUS)+1):
			XST[IS]=XST[IS]*1.e6
			X=XST[IS]
			if(X < 0.0):
				NXNEG=NXNEG+1
				I1=int(X/2.0-0.5)
				I2=int(X/10.0-0.5)
				I3=int(X/40.0-0.5)
				I4=int(X/100.0-0.5)
				I5=int(X/400.0-0.5)
				I6=int(X/1000.0-0.5)
				I7=int(X/4000.0-0.5)
				I8=int(X/10000.0-0.5)
				I9=int(X/40000.0-0.5)
				I10=int(X/100000.0-0.5)
			else:
				I1=int(X/2.0+0.5)
				I2=int(X/10.0+0.5)
				I3=int(X/40.0+0.5)
				I4=int(X/100.0+0.5)
				I5=int(X/400.0+0.5)
				I6=int(X/1000.0+0.5)
				I7=int(X/4000.0+0.5)
				I8=int(X/10000.0+0.5)
				I9=int(X/40000.0+0.5)
				I10=int(X/100000.0+0.5)
			# endif
			I1=I1+16
			I2=I2+16
			I3=I3+16
			I4=I4+16
			I5=I5+16
			I6=I6+16
			I7=I7+16
			I8=I8+16
			I9=I9+16
			I10=I10+16
			if(I1 < 1):
				I1=1
			if(I1 > 31):
				I1=31
			if(I2 < 1):
				I2=1
			if(I2 > 31):
				I2=31
			if(I3 < 1):
				I3=1
			if(I3 > 31):
				I3=31
			if(I4 < 1):
				I4=1
			if(I4 > 31):
				I4=31
			if(I5 < 1):
				I5=1
			if(I5 > 31):
				I5=31
			if(I6 < 1):
				I6=1
			if(I6 > 31):
				I6=31
			if(I7 < 1):
				I7=1
			if(I7 > 31):
				I7=31
			if(I8 < 1):
				I8=1
			if(I8 > 31):
				I8=31
			if(I9 < 1):
				I9=1
			if(I9 > 31):
				I9=31
			if(I10 < 1):
				I10=1
			if(I10 > 31):
				I10=31
			NXPL2[I1]=NXPL2[I1]+1
			NXPL10[I2]=NXPL10[I2]+1
			NXPL40[I3]=NXPL40[I3]+1
			NXPL100[I4]=NXPL100[I4]+1
			NXPL400[I5]=NXPL400[I5]+1
			NXPL1000[I6]=NXPL1000[I6]+1
			NXPL4000[I7]=NXPL4000[I7]+1
			NXPL10000[I8]=NXPL10000[I8]+1
			NXPL40000[I9]=NXPL40000[I9]+1
			NXPL100000[I10]=NXPL100000[I10]+1
			X2=X*X
			SUMX=SUMX+X
			SUMX2=SUMX2+X2
			if(abs(X)> abs(FARX)):
				FARX=abs(X)
			YST[IS]=YST[IS]*1.e6
			Y=YST[IS]
			if(Y < 0.0):
				NYNEG=NYNEG+1
				I1=int(Y/2.0-0.5)
				I2=int(Y/10.0-0.5)
				I3=int(Y/40.0-0.5)
				I4=int(Y/100.0-0.5)
				I5=int(Y/400.0-0.5)
				I6=int(Y/1000.0-0.5)
				I7=int(Y/4000.0-0.5)
				I8=int(Y/10000.0-0.5)
				I9=int(Y/40000.0-0.5)
				I10=int(Y/100000.0-0.5)
			else:
				I1=int(Y/2.0+0.5)
				I2=int(Y/10.0+0.5)
				I3=int(Y/40.0+0.5)
				I4=int(Y/100.0+0.5)
				I5=int(Y/400.0+0.5)
				I6=int(Y/1000.0+0.5)
				I7=int(Y/4000.0+0.5)
				I8=int(Y/10000.0+0.5)
				I9=int(Y/40000.0+0.5)
				I10=int(Y/100000.0+0.5)
			# endif
			I1=I1+16
			I2=I2+16
			I3=I3+16
			I4=I4+16
			I5=I5+16
			I6=I6+16
			I7=I7+16
			I8=I8+16
			I9=I9+16
			I10=I10+16
			if(I1 < 1):
				I1=1
			if(I1 > 31):
				I1=31
			if(I2 < 1):
				I2=1
			if(I2 > 31):
				I2=31
			if(I3 < 1):
				I3=1
			if(I3 > 31):
				I3=31
			if(I4 < 1):
				I4=1
			if(I4 > 31):
				I4=31
			if(I5 < 1):
				I5=1
			if(I5 > 31):
				I5=31
			if(I6 < 1):
				I6=1
			if(I6 > 31):
				I6=31
			if(I7 < 1):
				I7=1
			if(I7 > 31):
				I7=31
			if(I8 < 1):
				I8=1
			if(I8 > 31):
				I8=31
			if(I9 < 1):
				I9=1
			if(I9 > 31):
				I9=31
			if(I10 < 1):
				I10=1
			if(I10 > 31):
				I10=31
			NYPL2[I1]=NYPL2[I1]+1
			NYPL10[I2]=NYPL10[I2]+1
			NYPL40[I3]=NYPL40[I3]+1
			NYPL100[I4]=NYPL100[I4]+1
			NYPL400[I5]=NYPL400[I5]+1
			NYPL1000[I6]=NYPL1000[I6]+1
			NYPL4000[I7]=NYPL4000[I7]+1
			NYPL10000[I8]=NYPL10000[I8]+1
			NYPL40000[I9]=NYPL40000[I9]+1
			NYPL100000[I10]=NYPL100000[I10]+1
			Y2=Y*Y
			SUMY=SUMY+Y
			SUMY2=SUMY2+Y2
			if(abs(Y)> abs(FARY)):
				FARY=abs(Y)
			ZST[IS]=ZST[IS]*1.e6
			Z=ZST[IS]
			if(Z < 0.0):
				NZNEG=NZNEG+1
				I1=int(Z/2.0-0.5)
				I2=int(Z/10.0-0.5)
				I3=int(Z/40.0-0.5)
				I4=int(Z/100.0-0.5)
				I5=int(Z/400.0-0.5)
				I6=int(Z/1000.0-0.5)
				I7=int(Z/4000.0-0.5)
				I8=int(Z/10000.0-0.5)
				I9=int(Z/40000.0-0.5)
				I10=int(Z/100000.0-0.5)
			else:
				I1=int(Z/2.0+0.5)
				I2=int(Z/10.0+0.5)
				I3=int(Z/40.0+0.5)
				I4=int(Z/100.0+0.5)
				I5=int(Z/400.0+0.5)
				I6=int(Z/1000.0+0.5)
				I7=int(Z/4000.0+0.5)
				I8=int(Z/10000.0+0.5)
				I9=int(Z/40000.0+0.5)
				I10=int(Z/100000.0+0.5)
			# endif
			I1=I1+16
			I2=I2+16
			I3=I3+16
			I4=I4+16
			I5=I5+16
			I6=I6+16
			I7=I7+16
			I8=I8+16
			I9=I9+16
			I10=I10+16
			if(I1 < 1):
				I1=1
			if(I1 > 31):
				I1=31
			if(I2 < 1):
				I2=1
			if(I2 > 31):
				I2=31
			if(I3 < 1):
				I3=1
			if(I3 > 31):
				I3=31
			if(I4 < 1):
				I4=1
			if(I4 > 31):
				I4=31
			if(I5 < 1):
				I5=1
			if(I5 > 31):
				I5=31
			if(I6 < 1):
				I6=1
			if(I6 > 31):
				I6=31
			if(I7 < 1):
				I7=1
			if(I7 > 31):
				I7=31
			if(I8 < 1):
				I8=1
			if(I8 > 31):
				I8=31
			if(I9 < 1):
				I9=1
			if(I9 > 31):
				I9=31
			if(I10 < 1):
				I10=1
			if(I10 > 31):
				I10=31
			NZPL2[I1]=NZPL2[I1]+1
			NZPL10[I2]=NZPL10[I2]+1
			NZPL40[I3]=NZPL40[I3]+1
			NZPL100[I4]=NZPL100[I4]+1
			NZPL400[I5]=NZPL400[I5]+1
			NZPL1000[I6]=NZPL1000[I6]+1
			NZPL4000[I7]=NZPL4000[I7]+1
			NZPL10000[I8]=NZPL10000[I8]+1
			NZPL40000[I9]=NZPL40000[I9]+1
			NZPL100000[I10]=NZPL100000[I10]+1
			Z=ZST[IS]
			R=math.sqrt(X*X+Y*Y+Z*Z)
			I1=int(R/2.0+0.5)
			I2=int(R/10.0+0.5)
			I3=int(R/40.0+0.5)
			I4=int(R/100.0+0.5)
			I5=int(R/400.0+0.5)
			I6=int(R/1000.0+0.5)
			I7=int(R/4000.0+0.5)
			I8=int(R/10000.0+0.5)
			I9=int(R/40000.0+0.5)
			I10=int(R/100000.0+0.5)
			I1=I1+16
			I2=I2+16
			I3=I3+16
			I4=I4+16
			I5=I5+16
			I6=I6+16
			I7=I7+16
			I8=I8+16
			I9=I9+16
			I10=I10+16
			if(I1 > 31):
				I1=31
			if(I2 > 31):
				I2=31
			if(I3 > 31):
				I3=31
			if(I4 > 31):
				I4=31
			if(I5 > 31):
				I5=31
			if(I6 > 31):
				I6=31
			if(I7 > 31):
				I7=31
			if(I8 > 31):
				I8=31
			if(I9 > 31):
				I9=31
			if(I10 > 31):
				I10=31
			if(I1 < 1):
				I1=1
			if(I2 < 1):
				I2=1
			if(I3 < 1):
				I3=1
			if(I4 < 1):
				I4=1
			if(I5 < 1):
				I5=1
			if(I6 < 1):
				I6=1
			if(I7 < 1):
				I7=1
			if(I8 < 1):
				I8=1
			if(I9 < 1):
				I9=1
			if(I10 < 1):
				I10=1
			NRPL2[I1]=NRPL2[I1]+1
			NRPL10[I2]=NRPL10[I2]+1
			NRPL40[I3]=NRPL40[I3]+1
			NRPL100[I4]=NRPL100[I4]+1
			NRPL400[I5]=NRPL400[I5]+1
			NRPL1000[I6]=NRPL1000[I6]+1
			NRPL4000[I7]=NRPL4000[I7]+1
			NRPL10000[I8]=NRPL10000[I8]+1
			NRPL40000[I9]=NRPL40000[I9]+1
			NRPL100000[I10]=NRPL100000[I10]+1
			Z2=Z*Z
			SUMZ=SUMZ+Z
			SUMZ2=SUMZ2+Z2
			if(abs(Z)> abs(FARZ)):
				FARZ=abs(Z)
			RXY=math.sqrt(X2+Y2)
			RXYZ=math.sqrt(X2+Y2+Z2)
			SUMRXY=SUMRXY+RXY
			SUMRXY2=SUMRXY2+RXY*2
			SUMRXYZ=SUMRXYZ+RXYZ
			SUMRXYZ2=SUMRXYZ2+RXYZ*2
			if(RXY > FARXY):
				FARXY=RXY
			if(RXYZ > RMAX):
				RMAX=RXYZ
			T=TIME[IS]
			SUMT=SUMT+T
			SUMT2=SUMT2+T*T
			SUMTT=SUMTT+TTIME(IS)
			#
			XSTEXC[IS]=XSTEXC[IS]*1.e6
			YSTEXC[IS]=YSTEXC[IS]*1.e6
			ZSTEXC[IS]=ZSTEXC[IS]*1.e6
		# 400 CONTINUE
		# OUTPUT THERMAL ELECTRON POSITIONS AND TIME
		f=open("fort.50","w+")
		if(IWRITE == 1):
			#      ITEST=123456
			#      WRITE(50,*) ITEST
			# WRITE(50,*)
			f.write(NGOOD,NCLUS,NSTEXC,NGEXC1,NGEXC2,NGEXC3,NGEXC4,NGEXC5,NGEXC6,MCOMP[NEVENT],MPAIR[NEVENT],NEXCNUL)
			#      DO 8876 IPR=1,NCLUS
			#      WRITE(50,*) IPR,XST[IPR],YST[IPR],ZST[IPR],TIME[IPR],NFGF[IPR],
			#    /NFGPP[IPR],NFGBR[IPR]
			#8876 CONTINUE
			# WRITE(50,*)
			for IPR in range(1,NCLUS+1):

				f.write(XST[IPR],YST[IPR],ZST[IPR],TIME[IPR],NFGF[IPR],NFGPP[IPR],NFGBR[IPR])
		# endif
		# OUTPUT EXCITATION CLOUD COORDINATES HERE
		if(IWRITE == 2):
			#      ITEST=123456
			#      WRITE(50,*) ITEST
			# WRITE(50,*)
			f.write(NGOOD,NCLUS,NSTEXC,NGEXC1,NGEXC2,NGEXC3,NGEXC4,NGEXC5,NGEXC6,MCOMP[NEVENT],MPAIR[NEVENT],NEXCNUL)
			#      DO 8877 IPR=1,NCLUS
			#      WRITE(50,*) IPR,XST[IPR],YST[IPR],ZST[IPR],TIME[IPR],NFGF[IPR],
			#    /NFGPP[IPR],NFGBR[IPR]
			#8877 CONTINUE
			# WRITE(50,*)
			for IPR in range(1,NCLUS+1):
				f.write(XST[IPR],YST[IPR],ZST[IPR],TIME[IPR],NFGF[IPR],NFGPP[IPR],NFGBR[IPR])
			#       DO 8878 IPR=1,NSTEXC
			#       WRITE(50,*) IPR,XSTEXC[IPR],YSTEXC[IPR],ZSTEXC[IPR],TSTEXC[IPR]
			# 8878 CONTINUE
			# WRITE(50,*)
			for IPR in range(1,NSTEXC+1):
				f.write(XSTEXC[IPR],YSTEXC[IPR],ZSTEXC[IPR],TSTEXC[IPR])
			if(NEXCNUL > 0):
				# WRITE(50,*)
				for IPR in range(1,NEXCNUL+1):
					f.write(XSTN[IPR],YSTN[IPR],ZSTN[IPR],TSTN[IPR],IDNUL[IPR])
			else:
				# WRITE BLANK LINE
				# WRITE(50,*)
				f.write(0.0,0.0,0.0,0.0,0 )
			# endif
		# endif
		f.close()
		#---------------------------------------------------
		I1=int(EST1+1.0)
		I2=int(EST1/10.0+1.0)
		I3=int(EST1/100.0+1.0)
		if(I1 > 100):
			I1=100
		if(I2 > 100):
			I2=100
		if(I3 > 100):
			I3=100
		NEPL1[I1]=NEPL1[I1]+1
		NEPL10[I2]=NEPL10[I2]+1
		NEPL100[I3]=NEPL100[I3]+1
		KDUM=NELEC
		KDUM3=1+(NELEC/3)
		KDUM10=1+(NELEC/10)
		KDUM30=1+(NELEC/30)
		KDUM100=1+(NELEC/100)
		KDUM300=1+(NELEC/300)
		if(KDUM > 1000):
			KDUM=1000
		MELEC[int(KDUM)]=MELEC[int(KDUM)]+1
		if(KDUM3 > 1000):
			KDUM3=1000
		MELEC3[int(KDUM3)]=MELEC3[int(KDUM3)]+1
		if(KDUM10 > 1000):
			KDUM10=1000
		MELEC10[int(KDUM10)]=MELEC10[int(KDUM10)]+1
		if(KDUM30 > 1000):
			KDUM30=1000
		MELEC30[int(KDUM30)]=MELEC30[int(KDUM30)]+1
		if(KDUM100 > 1000):
			KDUM100=1000
		MELEC100[int(KDUM100)]=MELEC100[int(KDUM100)]+1
		if(KDUM300 > 1000):
			KDUM300=1000
		MELEC300[int(KDUM300)]=MELEC300[int(KDUM300)]+1
		#
		# STORE AVERAGES AND WIDTHS FOR EACH DELTA
		#
		if(NCLUS == 0):
			return
		ACLUS=float(NCLUS)
		XAV[NGOOD]=SUMX/ACLUS
		YAV[NGOOD]=SUMY/ACLUS
		ZAV[NGOOD]=SUMZ/ACLUS
		TAV[NGOOD]=SUMT/ACLUS
		XYAV[NGOOD]=SUMRXY/ACLUS
		XYZAV[NGOOD]=SUMRXYZ/ACLUS
		#  IONISATION CLUSTER SIZE
		NCL[NGOOD]=NCLUS
		# EXCITATION CLUSTER SIZE
		NCLEXC[NGOOD]=NSTEXC
		#
		FARX1[NGOOD]=FARX
		FARY1[NGOOD]=FARY
		FARZ1[NGOOD]=FARZ
		FARXY1[NGOOD]=FARXY
		RMAX1[NGOOD]=RMAX
		TSUM[NGOOD]=SUMTT
		XNEG[NGOOD]=float(NXNEG)/ACLUS
		YNEG[NGOOD]=float(NYNEG)/ACLUS
		ZNEG[NGOOD]=float(NZNEG)/ACLUS
		EDELTA[NGOOD]=EST1
		EDELTA2[NGOOD]=EST2
		if(NCLUS > 1):
			NC2=NCLUS*NCLUS-NCLUS
			ANC2=float(NC2)
			DX[NGOOD]=math.sqrt(abs((ACLUS*SUMX2-SUMX*SUMX)/ANC2))
			DY[NGOOD]=math.sqrt(abs((ACLUS*SUMY2-SUMY*SUMY)/ANC2))
			DZ[NGOOD]=math.sqrt(abs((ACLUS*SUMZ2-SUMZ*SUMZ)/ANC2))
			DT[NGOOD]=math.sqrt(abs((ACLUS*SUMT2-SUMT*SUMT)/ANC2))
			DXY[NGOOD]=math.sqrt(abs((ACLUS*SUMRXY2-SUMRXY*SUMRXY)/ANC2))
			DXYZ[NGOOD]=math.sqrt(abs((ACLUS*SUMRXYZ2-SUMRXYZ*SUMRXYZ)/ANC2))
		else:
			DX[NGOOD]=0.0
			DY[NGOOD]=0.0
			DZ[NGOOD]=0.0
			DZ[NGOOD]=0.0
			DT[NGOOD]=0.0
			DXY[NGOOD]=0.0
			DXYZ[NGOOD]=0.0
		# endif
		return
	# 99 WRITE(6,991) NCLUS
	# 991
	print('\n\n\n WARNING OVERFLOW IN ARRAYS IN FUNCTION STATS. NCLUS =',NCLUS,' STOPPED: FUNCTION')
	sys.exit()
	# end


'''Trains a simple convnet on the MNIST dataset.

Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''
from __future__ import print_function
import argparse
import numpy as np
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
import keras
from keras import backend as K
from jetiter import *
import ROOT as rt
from array import array
from keras.backend.tensorflow_backend import set_session
import matplotlib.pyplot as plt
#plt.switch_backend('agg')

batch_size = 100000

parser=argparse.ArgumentParser()
parser.add_argument("--end",type=float,default=1,help='end ratio')
parser.add_argument("--epoch",type=int,default=None,help='epoch')
parser.add_argument("--save",type=str,default="test",help='rch')
parser.add_argument("--rc",type=str,default='rc',help='rnn or cnn')
parser.add_argument("--gpu",type=int,default=0,help='gpu')
parser.add_argument("--pt",type=int,default=200,help='pt range pt~pt*1.1')
parser.add_argument("--ptmin",type=float,default=0.,help='pt range pt~pt*1.1')
parser.add_argument("--ptmax",type=float,default=2.,help='pt range pt~pt*1.1')
parser.add_argument("--isz",type=int,default=0,help='0 or z or not')
parser.add_argument("--channel",type=int,default=64,help='sequence channel')
parser.add_argument("--order",type=int,default=1,help='pt ordering')
parser.add_argument("--eta",type=float,default=0.,help='end ratio')
parser.add_argument("--etabin",type=float,default=2.4,help='end ratio')
parser.add_argument("--unscale",type=int,default=1,help='end ratio')
parser.add_argument("--normb",type=float,default=10.,help='end ratio')
parser.add_argument("--stride",type=int,default=2,help='end ratio')

args=parser.parse_args()

os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"]=str(args.gpu)
config =tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction=0.3

set_session(tf.Session(config=config))

# input image dimensions
img_rows, img_cols = 33, 33

input_shape1= (9,33,33)
input_shape2= (20,10)

#model.compile(loss=keras.losses.categorical_crossentropy,
#              optimizer=keras.optimizers.Adadelta(),
#              metrics=['accuracy'])
#model=keras.models.load_model('save/fullydijetsame_10')
savename="save/"+str(args.save)
history=open(savename+"/history").readlines()
try:
  try:
    hist=eval(history[0])
    #a=hist['val1_auc']
    a=hist['val_loss']
  except:
    hist=eval(history[0])
    #a=hist['val1_auc']
    a=hist['val_loss']
except:
  sepoch=eval(history[0])
  hist=eval(history[1])
vjjdata="Data/jj_pt_{0}_{1}.root".format(args.pt,int(args.pt*1.1))
from sklearn.metrics import roc_auc_score, auc, roc_curve
if(args.isz==0):iii=1
if(args.isz==1):iii=2
if(args.isz==-1):iii=3
#if(args.epoch==None):epoch=hist['val1_auc'.format(iii)].index(max(hist['val1_auc'.format(iii)]))+1
if(args.epoch==None):epoch=hist['val_loss'.format(iii)].index(min(hist['val_loss'.format(iii)]))+1
else:epoch=args.epoch
try:
  epoch=hist['val_loss'.format(iii)].index(min(hist['val_loss'.format(iii)]))+1
  model=keras.models.load_model(savename+"/check_"+str(epoch))
except:
  epoch=sepoch+1
  model=keras.models.load_model(savename+"/check_"+str(epoch))
rc=""
for sha in model._feed_inputs:
  if(sha._keras_shape[2]==10):
    rc+="c"
  if(sha._keras_shape[2]==64):
    rc+="r"
rc="r"
onehot=0
test2=jetiter([vjjdata],batch_size=batch_size,begin=0.7,end=1.,rc=rc,etabin=args.etabin,pt=args.pt,ptmin=args.ptmin,ptmax=args.ptmax,unscale=args.unscale,normb=args.normb,stride=args.stride)
entries=test2.totalnum()
print ("test   ",entries)
#epoch=eval(open(savename+"/history").readline())+1
#if(args.epoch==None):
f=rt.TFile("{}/get2.root".format(savename),"recreate")
#else:
#  f=rt.TFile("{}/{}get.root".format(savename,args.epoch),"recreate")
qs=[]
gs=[]
p=array('f',[0.])
pt=array('f',[0.])
eta=array('f',[0.])
pid=array('f',[0.])
trees={}
for i in range(args.stride):
  for jetid in ["q","g"]:
    trees["{}{}".format(jetid,i)]=rt.TTree("{}{}".format(jetid,i+1),"{}{} tree".format(jetid,i+1))
    trees["{}{}".format(jetid,i)].Branch("p",p,"p/F")
    trees["{}{}".format(jetid,i)].Branch("pt",pt,"pt/F")
    trees["{}{}".format(jetid,i)].Branch("eta",eta,"eta/F")
    trees["{}{}".format(jetid,i)].Branch("pid",pid,"pid/F")
#for jetid in ["qq","qg","gq","gg"]:
#    trees["{}".format(jetid)]=rt.TTree("{}".format(jetid),"{} tree".format(jetid))
#    trees["{}".format(jetid)].Branch("p",p,"p/F")
#    trees["{}".format(jetid)].Branch("pt",pt,"pt/F")
#    trees["{}".format(jetid)].Branch("eta",eta,"eta/F")
#    trees["{}".format(jetid)].Branch("pid",pid,"pid/F")
"""q1=rt.TTree("q1","q1 tree")
g1=rt.TTree("g1","g1 tree")
q2=rt.TTree("q2","q2 tree")
g2=rt.TTree("g2","g2 tree")
q1.Branch("p",p,"p/F")
q1.Branch("pt",pt,"pt/F")
q1.Branch("eta",eta,"eta/F")
q1.Branch("pid",pid,"pid/F")
g1.Branch("p",p,"p/F")
g1.Branch("pt",pt,"pt/F")
g1.Branch("eta",eta,"eta/F")
g1.Branch("pid",pid,"pid/F")
q2.Branch("p",p,"p/F")
q2.Branch("pt",pt,"pt/F")
q2.Branch("eta",eta,"eta/F")
q2.Branch("pid",pid,"pid/F")
g2.Branch("p",p,"p/F")
g2.Branch("pt",pt,"pt/F")
g2.Branch("eta",eta,"eta/F")
g2.Branch("pid",pid,"pid/F")"""
gen=test2
x=[]
y=[]
g=[]
q=[]
dens1=model.get_layer(index=21).output
dens2=model.get_layer(index=21).output
md1=keras.layers.Model(inputs=model.input,outputs=dens1)
md2=keras.layers.Model(inputs=model.input,outputs=dens2)
b1p=md1.predict(gen.seqset,verbose=0)
b2p=md2.predict(gen.seqset,verbose=0)
mb=[b1p,b2p]
bp=model.predict(gen.seqset,verbose=0)
bpt=gen.ptset
beta=gen.etaset
bpid=gen.pidset
#trees=[qs[0],qs[1],gs[0],gs[1]]
#trees=[q1,q2,g1,g2]
#qq qg gq gg
pairlist=test2.pairlist
chek=[]
for i in range(len(bp)):
  for pic in range(len(pairlist)):
    if(test2.labelset[i][pic]==1):
      for j in range(args.stride):
        p[0]=0
        for k in range(pow(2,args.stride)):
          if(pairlist[k][j]==pairlist[pic][j]):
            p[0]+=bp[i][k]
        p[0]=mb[j][i][0]
        pt[0]=bpt[i][j]
        eta[0]=beta[i][j]
        pid[0]=bpid[i][j]
        trees["{}{}".format(pairlist[pic][j],j)].Fill()
        #if(p[0]<0.2 and j == 0):
        #  #chek.append([i,test2.labelset[i],bp[i],j,p[0],pairlist[pic]])
    #p[0]=bp[i][pic]
    #pid[0]=np.where(test2.labelset[i]==1)[0][0]
    #trees["{}".format(pairlist[pic])].Fill()
"""  if(test2.labelset[i][0]==1): #qq
    for j in range(stride):
      p[0]=bp[i][0]+bp[i][1+j]
      if(j==0 and bp[i][0]+bp[i][1]!=p[0]): #qq qg
        print(i,j,test2.labelset[i])
      if(j==1 and bp[i][0]+bp[i][2]!=p[0]): #qq gq
        print(i,j,test2.labelset[i])
      pt[0]=bpt[i][j]
      eta[0]=beta[i][j]
      pid[0]=bpid[i][j]
      trees[j].Fill()
  if(test2.labelset[i][1]==1): #qg
    for j in range(2):
      p[0]=bp[i][1]+bp[i][3*j]
      if(j==0 and bp[i][1]+bp[i][0]!=p[0]):
        print(i,j,test2.labelset[i])
      if(j==1 and bp[i][1]+bp[i][3]!=p[0]):
        print(i,j,test2.labelset[i])
      pt[0]=bpt[i][j]
      eta[0]=beta[i][j]
      pid[0]=bpid[i][j]
      trees[j*3].Fill()
  if(test2.labelset[i][2]==1): #gq
    for j in range(2):
      p[0]=bp[i][2]+bp[i][3*(1-j)]
      if(j==0 and bp[i][2]+bp[i][3]!=p[0]):
        print(i,j,test2.labelset[i])
      if(j==1 and bp[i][2]+bp[i][0]!=p[0]):
        print(i,j,test2.labelset[i])
      pt[0]=bpt[i][j]
      eta[0]=beta[i][j]
      pid[0]=bpid[i][j]
      trees[2-j].Fill()
  if(test2.labelset[i][3]==1): #gg
    for j in range(2):
      p[0]=bp[i][3]+bp[i][2-j]
      if(j==0 and bp[i][3]+bp[i][2]!=p[0]):
        print(i,j,test2.labelset[i])
      if(j==1 and bp[i][3]+bp[i][1]!=p[0]):
        print(i,j,test2.labelset[i])
      pt[0]=bpt[i][j]
      eta[0]=beta[i][j]
      pid[0]=bpid[i][j]
      trees[2+j].Fill()"""
print("shape",np.array(bp).shape,test2.seqset.shape)
#for i in range(len(bp)):
#  p[0]=bp[i]
#  pt[0]=bpt[i]
#  eta[0]=beta[i]
#  pid[0]=bpid[i]
#  g1.Fill()
f.Write()
f.Close()


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

### update in wikiwho_api_api.py as well

import sys
reload(sys)
sys.setdefaultencoding("utf-8")         # to handle UnicodeDecode errors

import requests
from bs4 import BeautifulSoup
from traceback import format_exc
from os import path, listdir
from math import ceil
import sys
#from collections import OrderedDict
from operator import itemgetter
import pickle
from datetime import datetime           # for arithmetic on dates
from numpy import mean, std             # for computing standard scores
from pageviews import format_date, article_views

# to access functions from python files in another directory
sys.path.insert(0,'/home/priyanka/Documents/Wikipedia_Accuracy_Review/wikiwho_api/wikiwho_api')

from wikiwho_api_api import mainFunction

# can set parameters such as limit, offset, etc
url = 'https://en.wikipedia.org/w/index.php?title=Special:Search&limit=500&offset=0&profile=default&search=recently' ###
categ = path.basename(url)

recdir = 'PA_records' + path.sep   ###

def nextrecord():
    try:
        records = listdir(recdir)
        record = 1+int(max(records)[:9])
        ### todo: check for improperly named files
        return format(record, '09')
    except:
        return format(1, '09')

if __name__ == '__main__':

    try:
        r = requests.get(url)
    except:
            print "Error while querying Special Search" + title
            print format_exc()
    bs = BeautifulSoup(r.text)
    cnt = 0
    d = []
    results = bs.find('ul', 'mw-search-results')

    for entry in results.find_all('li'):

        try:
            heading = entry.find('div','mw-search-result-heading')
            link = "https://en.wikipedia.org" + heading.a.get('href')
            title = heading.a.get('title')
            if 'recently' in title.lower():     # title should not contain recently
                continue
            pageviews = article_views(title)
            if (pageviews == None):
                print 'Error while obtaining pageviews for article ' + title
                continue
            content = entry.find('div','searchresult')
            context = content.contents[0] + ''+content.contents[1].contents[0]+'' + content.contents[2]
            date = mainFunction(title)  # importing function from wikiwho_api_api.py. This uses the findWord function in Wikiwho_simple.py
            if (date == None):
                print 'Error while obtaining date for article ' + title
                continue
            print cnt+1, title, pageviews, date
            d.append([title,link, pageviews, context, str(date)])   # date is of type unicode
            cnt = cnt+1
            # if(cnt==500):
            #     break

        except:
            print "Error while parsing article " + title
            print format_exc()

    pv = []
    date = []
    for i in d:
        pv.append(i[2])     # get all the pageviews
        epoch = int(datetime.strptime(i[4], '%Y-%m-%d').strftime('%s'))
        date.append(epoch)  # get all the dates in epoch format for doing arithmetic operations on them
        i.append(epoch)     # appending epoch time to i

    mean_pv = mean(pv)
    std_pv = std(pv)
    mean_date = mean(date)
    std_date = std(date)
    for i in d:
        i. append(float(format(float((i[2] - mean_pv)/std_pv) - float(((i[5] - mean_date)/std_date)), '.2f')))  #  to rank higher in severity, article should rank high in pageview and low date epoch

    # od = OrderedDict(sorted(d.items(), key=lambda t:t[1][1], reverse=True)) # ordered dict in descending order of final score
    od = sorted(d, key=itemgetter(6), reverse=True) # ordered list in descending order of pageviews
    print '\n\nArticle rankings based on pageviews:\n'
    for item in od:
        print item
    with open('PA_pickles/recently_ranking.pkl', 'wb') as f:    ###
        pickle.dump(od, f)

# if __name__ == '__main__':
#     with open('PA_pickles/recently_ranking.pkl', 'rb') as f:  ### use when od has already been created; comment above stuff
#         od = pickle.load(f)
    cnt = 0
    counter = 100 #int(ceil(0.25*len(od)))    # top 20% of rankings

    #url = 'http://127.0.0.1:5000/ask'   # url for POSTing to ask. Replace with Labs/PythonAnywhere instance if needed

    for i in od:

        # POSTing to ask
        # data = {'question':'The article '+i[1]+' has the word 'recently' inserted in '+i[4]+'. Is it still correctly used? The context is:\n'+i[3],
        #       'iframeurl':i[1]}
        # r = requests.post(url, data=data)

        fn = recdir + nextrecord() + 'q'
        if path.exists(fn):
            print('A billion questions reached! Start answering!')
            exit()

        with open(fn, 'w') as f:
            try:
                f.write('The article ' + i[0] +
                    ' has the word \'recently\' inserted in ' + i[4] +
                    '. Is it still correctly used? The context is:
' + i[3] +
                    '
'+i[1]+'[Can not display ' + i[1] + ' inline as an iframe here.]')
                cnt = cnt + 1
            except:
                print 'Error while creating file'
                print format_exc()

            if (cnt == counter):
                exit()


import cupy as xp
from chainer import Chain
import chainer.links as L
from lib.utils import *
from lib.functions import *

class YOLOv2(Chain):
    """
    YOLOv2
    - It takes (416, 416, 3) sized image as input
    """

    def __init__(self, n_classes, n_boxes):
        super(YOLOv2, self).__init__(
            ##### common layers for both pretrained layers and yolov2 #####
            conv1=L.Convolution2D(3, 32, ksize=3, stride=1, pad=1, nobias=True),
            bn1=L.BatchNormalization(32, use_beta=False, eps=2e-5),
            bias1=L.Bias(shape=(32,)),
            conv2=L.Convolution2D(32, 64, ksize=3, stride=1, pad=1, nobias=True),
            bn2=L.BatchNormalization(64, use_beta=False, eps=2e-5),
            bias2=L.Bias(shape=(64,)),
            conv3=L.Convolution2D(64, 128, ksize=3, stride=1, pad=1, nobias=True),
            bn3=L.BatchNormalization(128, use_beta=False, eps=2e-5),
            bias3=L.Bias(shape=(128,)),
            conv4=L.Convolution2D(128, 64, ksize=1, stride=1, pad=0, nobias=True),
            bn4=L.BatchNormalization(64, use_beta=False, eps=2e-5),
            bias4=L.Bias(shape=(64,)),
            conv5=L.Convolution2D(64, 128, ksize=3, stride=1, pad=1, nobias=True),
            bn5=L.BatchNormalization(128, use_beta=False, eps=2e-5),
            bias5=L.Bias(shape=(128,)),
            conv6=L.Convolution2D(128, 256, ksize=3, stride=1, pad=1, nobias=True),
            bn6=L.BatchNormalization(256, use_beta=False, eps=2e-5),
            bias6=L.Bias(shape=(256,)),
            conv7=L.Convolution2D(256, 128, ksize=1, stride=1, pad=0, nobias=True),
            bn7=L.BatchNormalization(128, use_beta=False, eps=2e-5),
            bias7=L.Bias(shape=(128,)),
            conv8=L.Convolution2D(128, 256, ksize=3, stride=1, pad=1, nobias=True),
            bn8=L.BatchNormalization(256, use_beta=False, eps=2e-5),
            bias8=L.Bias(shape=(256,)),
            conv9=L.Convolution2D(256, 512, ksize=3, stride=1, pad=1, nobias=True),
            bn9=L.BatchNormalization(512, use_beta=False, eps=2e-5),
            bias9=L.Bias(shape=(512,)),
            conv10=L.Convolution2D(512, 256, ksize=1, stride=1, pad=0, nobias=True),
            bn10=L.BatchNormalization(256, use_beta=False, eps=2e-5),
            bias10=L.Bias(shape=(256,)),
            conv11=L.Convolution2D(256, 512, ksize=3, stride=1, pad=1, nobias=True),
            bn11=L.BatchNormalization(512, use_beta=False, eps=2e-5),
            bias11=L.Bias(shape=(512,)),
            conv12=L.Convolution2D(512, 256, ksize=1, stride=1, pad=0, nobias=True),
            bn12=L.BatchNormalization(256, use_beta=False, eps=2e-5),
            bias12=L.Bias(shape=(256,)),
            conv13=L.Convolution2D(256, 512, ksize=3, stride=1, pad=1, nobias=True),
            bn13=L.BatchNormalization(512, use_beta=False, eps=2e-5),
            bias13=L.Bias(shape=(512,)),
            conv14=L.Convolution2D(512, 1024, ksize=3, stride=1, pad=1, nobias=True),
            bn14=L.BatchNormalization(1024, use_beta=False, eps=2e-5),
            bias14=L.Bias(shape=(1024,)),
            conv15=L.Convolution2D(1024, 512, ksize=1, stride=1, pad=0, nobias=True),
            bn15=L.BatchNormalization(512, use_beta=False, eps=2e-5),
            bias15=L.Bias(shape=(512,)),
            conv16=L.Convolution2D(512, 1024, ksize=3, stride=1, pad=1, nobias=True),
            bn16=L.BatchNormalization(1024, use_beta=False, eps=2e-5),
            bias16=L.Bias(shape=(1024,)),
            conv17=L.Convolution2D(1024, 512, ksize=1, stride=1, pad=0, nobias=True),
            bn17=L.BatchNormalization(512, use_beta=False, eps=2e-5),
            bias17=L.Bias(shape=(512,)),
            conv18=L.Convolution2D(512, 1024, ksize=3, stride=1, pad=1, nobias=True),
            bn18=L.BatchNormalization(1024, use_beta=False, eps=2e-5),
            bias18=L.Bias(shape=(1024,)),

            ###### new layer
            conv19=L.Convolution2D(1024, 1024, ksize=3, stride=1, pad=1, nobias=True),
            bn19=L.BatchNormalization(1024, use_beta=False),
            bias19=L.Bias(shape=(1024,)),
            conv20=L.Convolution2D(1024, 1024, ksize=3, stride=1, pad=1, nobias=True),
            bn20=L.BatchNormalization(1024, use_beta=False),
            bias20=L.Bias(shape=(1024,)),
            conv21=L.Convolution2D(3072, 1024, ksize=3, stride=1, pad=1, nobias=True),
            bn21=L.BatchNormalization(1024, use_beta=False),
            bias21=L.Bias(shape=(1024,)),
            conv22=L.Convolution2D(1024, n_boxes * (5 + n_classes), ksize=1, stride=1, pad=0, nobias=True),
            bias22=L.Bias(shape=(n_boxes * (5 + n_classes),)),
        )
        self.train = False
        self.finetune = False
        self.n_boxes = n_boxes
        self.n_classes = n_classes

    def __call__(self, x):
        ##### common layer
        h = F.leaky_relu(self.bias1(self.bn1(self.conv1(x), finetune=self.finetune)), slope=0.1)
        h = F.max_pooling_2d(h, ksize=2, stride=2, pad=0)
        h = F.leaky_relu(self.bias2(self.bn2(self.conv2(h), finetune=self.finetune)), slope=0.1)
        h = F.max_pooling_2d(h, ksize=2, stride=2, pad=0)
        h = F.leaky_relu(self.bias3(self.bn3(self.conv3(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias4(self.bn4(self.conv4(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias5(self.bn5(self.conv5(h), finetune=self.finetune)), slope=0.1)
        h = F.max_pooling_2d(h, ksize=2, stride=2, pad=0)
        h = F.leaky_relu(self.bias6(self.bn6(self.conv6(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias7(self.bn7(self.conv7(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias8(self.bn8(self.conv8(h), finetune=self.finetune)), slope=0.1)
        h = F.max_pooling_2d(h, ksize=2, stride=2, pad=0)
        h = F.leaky_relu(self.bias9(self.bn9(self.conv9(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias10(self.bn10(self.conv10(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias11(self.bn11(self.conv11(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias12(self.bn12(self.conv12(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias13(self.bn13(self.conv13(h), finetune=self.finetune)), slope=0.1)
        high_resolution_feature = reorg(h)  # 高解像度特徴量をreorgでサイズ落として保存しておく
        h = F.max_pooling_2d(h, ksize=2, stride=2, pad=0)
        h = F.leaky_relu(self.bias14(self.bn14(self.conv14(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias15(self.bn15(self.conv15(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias16(self.bn16(self.conv16(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias17(self.bn17(self.conv17(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias18(self.bn18(self.conv18(h), finetune=self.finetune)), slope=0.1)

        ###### new layer
        h = F.leaky_relu(self.bias19(self.bn19(self.conv19(h), finetune=self.finetune)), slope=0.1)
        h = F.leaky_relu(self.bias20(self.bn20(self.conv20(h), finetune=self.finetune)), slope=0.1)
        h = F.concat((high_resolution_feature, h), axis=1)  # output concatnation
        h = F.leaky_relu(self.bias21(self.bn21(self.conv21(h), finetune=self.finetune)), slope=0.1)
        h = self.bias22(self.conv22(h))

        return h

class YOLOv2Predictor(Chain):
    def __init__(self, predictor):
        super(YOLOv2Predictor, self).__init__(predictor=predictor)
        self.anchors = [[5.375, 5.03125], [5.40625, 4.6875], [2.96875, 2.53125], [2.59375, 2.78125], [1.9375, 3.25]]
        self.thresh = 0.6
        self.seen = 0
        self.unstable_seen = 5000

    def __call__(self, input_x, t):
        output = self.predictor(input_x)
        batch_size, _, grid_h, grid_w = output.shape
        self.seen += batch_size
        x, y, w, h, conf, prob = F.split_axis(
            F.reshape(output, (batch_size, self.predictor.n_boxes, self.predictor.n_classes + 5, grid_h, grid_w)),
            (1, 2, 3, 4, 5), axis=2)
        x = F.sigmoid(x)  # xのactivation
        y = F.sigmoid(y)  # yのactivation
        conf = F.sigmoid(conf)  # confのactivation
        prob = F.transpose(prob, (0, 2, 1, 3, 4))
        prob = F.softmax(prob)  # probablitiyのacitivation

        # 教師データの用意
        tw = xp.zeros(w.shape, dtype=xp.float32)  # wとhが0になるように学習(e^wとe^hは1に近づく -> 担当するbboxの倍率1)
        th = xp.zeros(h.shape, dtype=xp.float32)
        tx = xp.tile(0.5, x.shape).astype(xp.float32)  # 活性化後のxとyが0.5になるように学習()
        ty = xp.tile(0.5, y.shape).astype(xp.float32)

        if self.seen < self.unstable_seen:  # centerの存在しないbbox誤差学習スケールは基本0.1
            box_learning_scale = xp.tile(0.1, x.shape).astype(xp.float32)
        else:
            box_learning_scale = xp.tile(0, x.shape).astype(xp.float32)

        tconf = xp.zeros(conf.shape,
                         dtype=xp.float32)  # confidenceのtruthは基本0、iouがthresh以上のものは学習しない、ただしobjectの存在するgridのbest_boxのみ真のIOUに近づかせる
        conf_learning_scale = xp.tile(0.1, conf.shape).astype(xp.float32)

        tprob = prob.data.copy()  # best_anchor以外は学習させない(自身との二乗和誤差 = 0)

        # 全bboxとtruthのiouを計算(batch単位で計算する)
        x_shift = Variable(xp.broadcast_to(xp.arange(grid_w, dtype=xp.float32), x.shape[1:]))
        y_shift = Variable(xp.broadcast_to(xp.arange(grid_h, dtype=xp.float32).reshape(grid_h, 1), y.shape[1:]))
        w_anchor = Variable(xp.broadcast_to(
            xp.reshape(xp.array(self.anchors, dtype=xp.float32)[:, 0], (self.predictor.n_boxes, 1, 1, 1)), w.shape[1:]))
        h_anchor = Variable(xp.broadcast_to(
            xp.reshape(xp.array(self.anchors, dtype=xp.float32)[:, 1], (self.predictor.n_boxes, 1, 1, 1)), h.shape[1:]))
        x_shift.to_gpu(), y_shift.to_gpu(), w_anchor.to_gpu(), h_anchor.to_gpu()
        best_ious = []
        for batch in range(batch_size):
            n_truth_boxes = len(t[batch])
            box_x = (x[batch] + x_shift) / grid_w
            box_y = (y[batch] + y_shift) / grid_h
            box_w = F.exp(w[batch]) * w_anchor / grid_w
            box_h = F.exp(h[batch]) * h_anchor / grid_h

            ious = []
            for truth_index in range(n_truth_boxes):
                truth_box_x = Variable(
                    xp.broadcast_to(xp.array(t[batch][truth_index]["x"], dtype=xp.float32), box_x.shape))
                truth_box_y = Variable(
                    xp.broadcast_to(xp.array(t[batch][truth_index]["y"], dtype=xp.float32), box_y.shape))
                truth_box_w = Variable(
                    xp.broadcast_to(xp.array(t[batch][truth_index]["w"], dtype=xp.float32), box_w.shape))
                truth_box_h = Variable(
                    xp.broadcast_to(xp.array(t[batch][truth_index]["h"], dtype=xp.float32), box_h.shape))
                truth_box_x.to_gpu(), truth_box_y.to_gpu(), truth_box_w.to_gpu(), truth_box_h.to_gpu()
                ious.append(multi_box_iou(Box(box_x, box_y, box_w, box_h),
                                          Box(truth_box_x, truth_box_y, truth_box_w, truth_box_h)).data.get())
            ious = xp.array(ious)
            best_ious.append(xp.max(ious, axis=0))
        best_ious = xp.array(best_ious)

        # 一定以上のiouを持つanchorに対しては、confを0に下げないようにする(truthの周りのgridはconfをそのまま維持)。
        tconf[best_ious > self.thresh] = conf.data.get()[best_ious > self.thresh]
        conf_learning_scale[best_ious > self.thresh] = 0

        # objectの存在するanchor boxのみ、x、y、w、h、conf、probを個別修正
        abs_anchors = self.anchors / xp.array([grid_w, grid_h])
        for batch in range(batch_size):
            for truth_box in t[batch]:
                truth_w = int(float(truth_box["x"]) * grid_w)
                truth_h = int(float(truth_box["y"]) * grid_h)
                truth_n = 0
                best_iou = 0.0
                for anchor_index, abs_anchor in enumerate(abs_anchors):
                    iou = box_iou(Box(0, 0, float(truth_box["w"]), float(truth_box["h"])),
                                  Box(0, 0, abs_anchor[0], abs_anchor[1]))
                    if best_iou < iou:
                        best_iou = iou
                        truth_n = anchor_index

                # objectの存在するanchorについて、centerを0.5ではなく、真の座標に近づかせる。anchorのスケールを1ではなく真のスケールに近づかせる。学習スケールを1にする。
                box_learning_scale[batch, truth_n, :, truth_h, truth_w] = 1.0
                tx[batch, truth_n, :, truth_h, truth_w] = float(truth_box["x"]) * grid_w - truth_w
                ty[batch, truth_n, :, truth_h, truth_w] = float(truth_box["y"]) * grid_h - truth_h
                tw[batch, truth_n, :, truth_h, truth_w] = xp.log(float(truth_box["w"]) / abs_anchors[truth_n][0])
                th[batch, truth_n, :, truth_h, truth_w] = xp.log(float(truth_box["h"]) / abs_anchors[truth_n][1])
                tprob[batch, :, truth_n, truth_h, truth_w] = 0
                tprob[batch, int(truth_box["label"]), truth_n, truth_h, truth_w] = 1

                # IOUの観測
                full_truth_box = Box(float(truth_box["x"]), float(truth_box["y"]), float(truth_box["w"]),
                                     float(truth_box["h"]))
                predicted_box = Box(
                    (x[batch][truth_n][0][truth_h][truth_w].data.get() + truth_w) / grid_w,
                    (y[batch][truth_n][0][truth_h][truth_w].data.get() + truth_h) / grid_h,
                    xp.exp(w[batch][truth_n][0][truth_h][truth_w].data.get()) * abs_anchors[truth_n][0],
                    xp.exp(h[batch][truth_n][0][truth_h][truth_w].data.get()) * abs_anchors[truth_n][1]
                )
                predicted_iou = box_iou(full_truth_box, predicted_box)
                tconf[batch, truth_n, :, truth_h, truth_w] = predicted_iou
                conf_learning_scale[batch, truth_n, :, truth_h, truth_w] = 10.0

            # debug prints
            maps = F.transpose(prob[batch], (2, 3, 1, 0)).data
            print("best confidences and best conditional probability and predicted class of each grid:")
            for i in range(grid_h):
                for j in range(grid_w):
                    print("%2d" % (int(conf[batch, :, :, i, j].data.max() * 100)), end=" ")
                print("     ", end="")
                for j in range(grid_w):
                    print("%2d" % (maps[i][j][int(maps[i][j].max(axis=1).argmax())].argmax()), end=" ")
                print("     ", end="")
                for j in range(grid_w):
                    print("%2d" % (maps[i][j][int(maps[i][j].max(axis=1).argmax())].max() * 100), end=" ")
                print()

            print("best default iou: %.2f   predicted iou: %.2f   confidence: %.2f   class: %s" % (
                best_iou, predicted_iou, conf[batch][truth_n][0][truth_h][truth_w].data, t[batch][0]["label"]))
            print("-------------------------------")
        print("seen = %d" % self.seen)

        # loss計算
        tx, ty, tw, th, tconf, tprob = Variable(tx), Variable(ty), Variable(tw), Variable(th), Variable(
            tconf), Variable(tprob)
        box_learning_scale, conf_learning_scale = Variable(box_learning_scale), Variable(conf_learning_scale)
        tx.to_gpu(), ty.to_gpu(), tw.to_gpu(), th.to_gpu(), tconf.to_gpu(), tprob.to_gpu()
        box_learning_scale.to_gpu()
        conf_learning_scale.to_gpu()

        x_loss = F.sum((tx - x) ** 2 * box_learning_scale) / 2
        y_loss = F.sum((ty - y) ** 2 * box_learning_scale) / 2
        w_loss = F.sum((tw - w) ** 2 * box_learning_scale) / 2
        h_loss = F.sum((th - h) ** 2 * box_learning_scale) / 2
        c_loss = F.sum((tconf - conf) ** 2 * conf_learning_scale) / 2
        p_loss = F.sum((tprob - prob) ** 2) / 2
        print("x_loss: %f  y_loss: %f  w_loss: %f  h_loss: %f  c_loss: %f   p_loss: %f" %
              (F.sum(x_loss).data, F.sum(y_loss).data, F.sum(w_loss).data, F.sum(h_loss).data, F.sum(c_loss).data,
               F.sum(p_loss).data)
              )

        loss = x_loss + y_loss + w_loss + h_loss + c_loss + p_loss
        return loss

    def init_anchor(self, anchors):
        self.anchors = anchors

    def predict(self, input_x):
        output = self.predictor(input_x)
        batch_size, input_channel, input_h, input_w = input_x.shape
        batch_size, _, grid_h, grid_w = output.shape
        x, y, w, h, conf, prob = F.split_axis(
            F.reshape(output, (batch_size, self.predictor.n_boxes, self.predictor.n_classes + 5, grid_h, grid_w)),
            (1, 2, 3, 4, 5), axis=2)
        x = F.sigmoid(x)  # xのactivation
        y = F.sigmoid(y)  # yのactivation
        conf = F.sigmoid(conf)  # confのactivation
        prob = F.transpose(prob, (0, 2, 1, 3, 4))
        prob = F.softmax(prob)  # probablitiyのacitivation
        prob = F.transpose(prob, (0, 2, 1, 3, 4))

        # x, y, w, hを絶対座標へ変換
        x_shift = Variable(xp.broadcast_to(xp.arange(grid_w, dtype=xp.float32), x.shape))
        y_shift = Variable(xp.broadcast_to(xp.arange(grid_h, dtype=xp.float32).reshape(grid_h, 1), y.shape))
        w_anchor = Variable(xp.broadcast_to(
            xp.reshape(xp.array(self.anchors, dtype=xp.float32)[:, 0], (self.predictor.n_boxes, 1, 1, 1)), w.shape))
        h_anchor = Variable(xp.broadcast_to(
            xp.reshape(xp.array(self.anchors, dtype=xp.float32)[:, 1], (self.predictor.n_boxes, 1, 1, 1)), h.shape))
        # x_shift.to_gpu(), y_shift.to_gpu(), w_anchor.to_gpu(), h_anchor.to_gpu()
        box_x = (x + x_shift) / grid_w
        box_y = (y + y_shift) / grid_h
        box_w = F.exp(w) * w_anchor / grid_w
        box_h = F.exp(h) * h_anchor / grid_h

        return box_x, box_y, box_w, box_h, conf, prob


import keras
from keras.models import load_model
from PIL import Image
import matplotlib.pylab as plt
import numpy as np
import zipfile
print("Extract")
zip_ref = zipfile.ZipFile("./asset.zip", 'r')
zip_ref.extractall(".")
zip_ref.close()
print("Load Model")
model=load_model("cifar-model.h5")
CIFAR_10_CLASSES=["Plane","Car","bird","cat","deer","dog","frog","horse","ship","truck"]
def calc(imname):
    test_image =Image.open("asset/"+imname)
    test_image=test_image.resize((32,32),Image.ANTIALIAS)
    test_image=np.array(test_image,dtype="float32")
    test_image/=255
    test_image=test_image.reshape(-1,32,32,3)
    predictions=model.predict(test_image)
    index_max_pred=np.argmax(predictions)
    plt.title("Complete: {}".format(CIFAR_10_CLASSES[index_max_pred]))
    plt.imshow(test_image[0].reshape(32,32,3))
    print(predictions)
    plt.show()
print("START TEST")
calc("lkw-image.jpg")
calc("cat.jpg")
calc("frog.jpg")
calc("fog.jpg")
calc("lfog.jpg")
calc("d.jpg")
calc("b.jpg")
calc("bs.jpg")
calc("plapper.jpg")
calc("ds.jpg")
print("Complete")
print("End")
quit(0)


import cv2
import sys
import settings
import tempfile
import numpy as np
from matplotlib import pyplot as plt
from scipy.spatial import distance as dist
from imageai.Detection import VideoObjectDetection

from utils import send_image_telegram

class CrossingDetector():

    """Основной класс с реализацией логики отслеживания объектов

    Attributes:
        ident_counter (int): Идентификатор для отслеживаемого объекта
        max_disappeared (int): Максимальное количество исчезновений
        trackable_objects (list): Список с отслеживаемыми объектами класса TrackableObject
        y_border (int): Граница
    """

    def __init__(self, y_border, max_disappeared=50):
        """Конструктор класса CrossingDetector

        Args:
            y_border (int): Граница
            max_disappeared (int): Максимальное количество исчезновений
        """
        self.trackable_objects = []
        self.ident_counter = 0
        self.y_border = y_border
        self.max_disappeared = max_disappeared

    class TrackableObject():

        """Класс для отслеживаемых объектов на видео

        Attributes:
            ident (int): Идентификатор объекта
            centroids (list): Список положений центроидов отслеживаемого объекта
            checked (bool): Пересечение границы зафиксированно
            count_disappeared (int): Количество исчезновений на кадрах
        """

        def __init__(self, ident, centroid):
            """Конструктор класса TrackableObject

            Args:
                ident (int): Идентификатор объекта
                centroid (tuple): Первый зафиксированный центроид объекта
            """
            self.ident = ident
            self.centroids = [centroid]
            self.checked = False
            self.count_disappeared = 0

        def add_centroid(self, centroid):
            """Метод для добавления нового зафиксированного центроида

            Args:
                centroid (tuple): Новый зафиксированный центроид
            """
            self.centroids.append(centroid)

        def get_direction(self):
            """Метод для вычисления направления отслеживаемого объекта

            Returns:
                result (float): Разница между текущей координатой y и средним предыдущих
            """
            y_coordinates = [p[1] for p in self.centroids]
            result = 0

            if y_coordinates:
                result = y_coordinates[-1] - np.mean(y_coordinates[:-1])

            return result

    def register_object(self, centroid):
        """Метод для регистрации нового объекта

        Args:
            centroid (tuple): Центроид
        """
        self.ident_counter += 1
        centroid = np.array(centroid)
        self.trackable_objects.append(
            CrossingDetector.TrackableObject(
                self.ident_counter,
                centroid
            )
        )

    def actualize_trackable_objects(self, detected_objects):
        """Метод для обновления центроидов отслеживаемых объектов

        Args:
            detected_objects (list): Зафиксированные объекты на кадре
        """
        detected_centroids = np.array(
            [self.get_center(detected_object.get('box_points'))
             for detected_object in detected_objects]
        )
        current_objects_centroids = np.array(
            [to.centroids[-1] for to in self.trackable_objects]
        )
        dist_matrix = dist.cdist(current_objects_centroids, detected_centroids)

        rows = dist_matrix.min(axis=1).argsort()
        cols = dist_matrix.argmin(axis=1)[rows]

        used_rows = set()
        used_cols = set()

        for (row, col) in zip(rows, cols):
            if row in used_rows or col in used_cols:
                continue

            self.trackable_objects[row].add_centroid(detected_centroids[col])
            self.trackable_objects[row].count_disappeared = 0
            used_rows.add(row)
            used_cols.add(col)

        unused_rows = set(range(0, dist_matrix.shape[0])).difference(used_rows)
        unused_cols = set(range(0, dist_matrix.shape[1])).difference(used_cols)

        if dist_matrix.shape[0] >= dist_matrix.shape[1]:
            for row in unused_rows:
                self.incr_object_count_disappeared(row)
        else:
            for col in unused_cols:
                self.register_object(detected_centroids[col])

    def incr_object_count_disappeared(self, index):
        """Метод для увеличения счетчика исчезновений объекта

        Args:
            index (int): Индекс объекта в списке
        """
        self.trackable_objects[index].count_disappeared += 1
        if self.trackable_objects[index].count_disappeared > self.max_disappeared:
            del self.trackable_objects[index]

    def register_detected_objects(self, objects):
        """Метод для регистрации новых объектов

        Args:
            objects (list): Список новых зафиксированных объектов
        """
        [self.register_object(self.get_center(detected_object.get(
            'box_points'))) for detected_object in objects]

    def get_center(self, box_points):
        """Метод для вычисления координат центроида

        Args:
            box_points (tuple): Координаты (x1, y1, x2, y2) рамки зафиксированного объекта

        Returns:
            tuple: Координаты центра рамки
        """
        x1, y1, x2, y2 = box_points
        def asix_center(v1, v2): return int((v2 - v1) / 2) + v1
        return asix_center(x1, x2), asix_center(y1, y2)

    def process_and_send_image(self, centroid, frame_img):
        """Метод для предобработки и отправки изображения

        Args:
            centroid (tuple): Центроид
            frame_img (array): Изображение
        """
        image = cv2.cvtColor(frame_img, cv2.COLOR_BGR2RGB)
        image = np.array(image)
        shape = image.shape
        plt.imshow(image, aspect='auto')
        plt.scatter(centroid[0], centroid[1], s=30, color='blue')
        plt.hlines(y=self.y_border, xmin=0, xmax=(shape[1] - 1), color='green')

        with tempfile.NamedTemporaryFile(suffix=".png") as tmpfile:
            plt.savefig(tmpfile, format="png")
            send_image_telegram(tmpfile.name)

    def process_frame(self, frame):
        """Метод для обработки кадра

        Args:
            frame (dict): Кадр
        """
        frame_num, objects, count_objects, frame_img = frame

        if frame_num == 1:
            self.register_detected_objects(objects)
            return

        if not objects:
            for i, to in enumerate(self.trackable_objects):
                self.incr_object_count_disappeared(i)
            return

        self.actualize_trackable_objects(objects)

        for to in self.trackable_objects:
            if not to.checked:
                to_direction = to.get_direction()
                curr_centroid = to.centroids[-1]
                first_centroid = to.centroids[0]

                if (to_direction > 0 and curr_centroid[1] > self.y_border and first_centroid[1] < self.y_border) or (
                        to_direction < 0 and curr_centroid[1] < self.y_border and first_centroid[1] > self.y_border):
                    self.process_and_send_image(curr_centroid, frame_img)
                    to.checked = True


import tkinter as tk
from tkinter import *
import cv2
from PIL import Image, ImageTk
import os
import numpy as np
import cv2
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D
from keras.optimizers import Adam
from keras.layers import MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator

emotion_model = Sequential()

emotion_model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(48, 48, 1)))
emotion_model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))
emotion_model.add(Dropout(0.25))

emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
emotion_model.add(MaxPooling2D(pool_size=(2, 2)))
emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
emotion_model.add(Dropout(0.25))

emotion_model.add(Flatten())
emotion_model.add(Dense(1024, activation='relu'))
emotion_model.add(Dropout(0.5))
emotion_model.add(Dense(7, activation='softmax'))
emotion_model.load_weights('emotion_model.h5')

cv2.ocl.setUseOpenCL(False)

emotion_dict = {0: "Angry", 1: "Disgusted", 2: "Fearful", 3: "Happy", 4: "Neutral",
                5: "Sad", 6: "Surprised"}

emoji_dist = {0: "emojis/angry.png", 1: "emojis/disgusted.png", 2: "emojis/fearful.png",
              3: "emojis/happy.png", 4: "emojis/neutral.png", 5: "emojis/sad.png", 6: "emojis/surpriced.png"}

global last_frame1
last_frame1 = np.zeros((480, 640, 3), dtype=np.uint8)
global cap1
show_text=[0]
def show_vid():
    cap1 = cv2.VideoCapture(0)
    if not cap1.isOpened():
        print("Can't open camera1")
    flag1, frame1 = cap1.read()
    frame1 = cv2.resize(frame1, (600, 500))

    bounding_box = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    gray_frame = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
    num_faces = bounding_box.detectMultiScale(gray_frame, scaleFactor=1.3, minNeighbors=5)

    for (x,y,w,h) in num_faces:
        cv2.rectangle(frame1, (x,y-50), (x+w, y+h+10), (255, 0, 0), 2)
        roi_gray_frame = gray_frame[y: y+h, x: x+w]
        cropped_img = np.expand_dims(np.expand_dims(cv2.resize(roi_gray_frame, (48, 48)), -1), 0)
        prediction = emotion_model.predict(cropped_img)

        maxindex = int(np.argmax(prediction))

        show_text[0]=maxindex
        if flag1 is None:
            print("Major error!")
        elif flag1:
            global last_frame1
            last_frame1 = frame1.copy()
            pic = cv2.cvtColor(last_frame1, cv2.COLOR_BGR2RGB)
            img = Image.fromarray(pic)
            imgtk = ImageTk.PhotoImage(image=img)
            lmain.imgtk = imgtk
            lmain.configure(image=imgtk)
            lmain.after(10, show_vid)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            exit()

def show_vid2():
    frame2=cv2.imread(emoji_dist[show_text[0]])
    pic2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2RGB)
    img2 = Image.fromarray(frame2)
    imgtk2 = ImageTk.PhotoImage(image=img2)
    lmain2.imgtk2 = imgtk2
    lmain3.configure(text=emotion_dict[show_text[0]],font=('arial',45,'bold'))

    lmain2.configure(image=imgtk2)
    lmain2.after(10, show_vid2)

if __name__ == '__main__':
    root = tk.Tk()
    # img = ImageTk.PhotoImage(Image.open("logo.png"))
    heading = Label(root, bg='black')
    heading.pack()
    heading2 = Label(root, text="Photo to Emoji", pady=20, font=('arial', 45, 'bold'),
                     bg='black', fg='#CDCDCD')
    heading2.pack()
    lmain = tk.Label(master=root, padx=50, bd=10)
    lmain2 = tk.Label(master=root, bd=10)

    lmain3 = tk.Label(master=root, bd=10, fg='#CDCDCD', bg='black')
    lmain.pack(side=LEFT)
    lmain.place(x=50, y=250)
    lmain3.pack()
    lmain3.place(x=960, y=250)
    lmain2.pack(side=RIGHT)
    lmain2.place(x=900, y=350)

    root.title("Photo to Emoji")
    root.geometry("1400x900+100+10")
    root['bg'] = 'black'
    exitbutton = Button(root, text='Quit', fg="red", command= root.destroy,
                        font=('arial', 25, 'bold')).pack(side=BOTTOM)
    show_vid()
    show_vid2()
    root.mainloop()