import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np

class DoubleConv(nn.Module):
	"""(convolution => [BN] => ReLU) * 2"""

	def __init__(self, in_channels, out_channels, attention=False):
		super().__init__()
		self.attention = attention
		self.double_conv = nn.Sequential(
			nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),
			nn.BatchNorm2d(out_channels),
			# nn.ReLU(inplace=True),
			nn.LeakyReLU(0.2, True),
			nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),
			nn.BatchNorm2d(out_channels),
			# nn.ReLU(inplace=True)
			nn.LeakyReLU(0.2, True),
		)
		self.se = SEModule(out_channels)

	def forward(self, x):
		out = self.double_conv(x)
		if(self.attention):
			out = self.se(out)
			# out, weights = self.se(out)
			# return out, weights
		return out

class Down(nn.Module):
	"""Downscaling with maxpool then double conv"""

	def __init__(self, in_channels, out_channels):
		super().__init__()
		self.maxpool_conv = nn.Sequential(
			nn.MaxPool2d(2),
			DoubleConv(in_channels, out_channels, True)
		)

	def forward(self, x):
		return self.maxpool_conv(x)

class Up(nn.Module):
	"""Upscaling then double conv"""

	def __init__(self, in_channels, out_channels, bilinear=False):
		super().__init__()

		# if bilinear, use the normal convolutions to reduce the number of channels
		if bilinear:
			self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
		else:
			self.up = nn.ConvTranspose2d(in_channels // 2, in_channels // 2, kernel_size=2, stride=2)
			# self.up = nn.ConvTranspose2d(in_channels // 3, in_channels // 3, kernel_size=2, stride=2)

		self.conv = DoubleConv(in_channels, out_channels)

	def forward(self, x1, x2):
		x1 = self.up(x1)
		# input is CHW
		diffY = torch.tensor([x2.size()[2] - x1.size()[2]])
		diffX = torch.tensor([x2.size()[3] - x1.size()[3]])

		x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,
						diffY // 2, diffY - diffY // 2])
		# if you have padding issues, see
		# https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a
		# https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd
		x = torch.cat([x2, x1], dim=1)
		return self.conv(x)

class OutConv(nn.Module):
	def __init__(self, in_channels, out_channels):
		super(OutConv, self).__init__()
		self.conv = nn.Sequential(
				nn.Conv2d(in_channels, out_channels, kernel_size=1),
				nn.BatchNorm2d(out_channels),
				# nn.ReLU(inplace=True),
				# nn.LeakyReLU(0.2, True),
				# nn.Sigmoid(),
				# nn.Tanh(),
			)

	def forward(self, x):
		return self.conv(x)

class Reshape(nn.Module):
	def __init__(self, shape):
		super(Reshape, self).__init__()
		self.shape = shape

	def forward(self, x):
		return x.view(self.shape)

class SEModule(nn.Module):
	def __init__(self, channel, reduction=16):
		super(SEModule, self).__init__()
		self.globalAvgPool = nn.AdaptiveAvgPool2d(1)
		self.fc = nn.Sequential(
				nn.Linear(channel, channel//reduction, bias=False),
				nn.ReLU(True),
				# nn.LeakyReLU(0.2, True),
				nn.Linear(channel//reduction, channel, bias=False),
				nn.Sigmoid()
			)

	def forward(self, x):
		batchSize, channel, _, _ = x.size()
		y = self.globalAvgPool(x).view(batchSize, channel)
		y = self.fc(y).view(batchSize, channel, 1, 1)
		return x * y.expand_as(x)

def mixup_process(x, y, lam, indices):
	x_out = x * lam + x[indices] * (1 - lam)
	y_out = y * lam + y[indices] * (1 - lam)

	return x_out, y_out

class UNet(nn.Module):
	def __init__(self, input_shape, output_shape, num_classes, bilinear=False):
		super(UNet, self).__init__()
		self.input_shape = input_shape
		self.output_shape = output_shape
		self.num_classes = num_classes
		self.bilinear = bilinear
		self.input_size = input_shape[0] * input_shape[1] * input_shape[2]
		self.output_size = output_shape[0] * output_shape[1] * output_shape[2]

		# linearSize = 1024
		channelSize = 16

		self.merge5 = DoubleConv(channelSize*16, channelSize*8)
		self.merge4 = DoubleConv(channelSize*16, channelSize*8)
		self.merge3 = DoubleConv(channelSize*8, channelSize*4)
		self.merge2 = DoubleConv(channelSize*4, channelSize*2)
		self.merge1 = DoubleConv(channelSize*2, channelSize)

		self.inc = DoubleConv(input_shape[0], channelSize, True)
		# self.inc = DoubleConv(input_shape[0]*2+1, channelSize)
		self.down1 = Down(channelSize, channelSize*2)
		self.down2 = Down(channelSize*2, channelSize*4)
		self.down3 = Down(channelSize*4, channelSize*8)
		self.down4 = Down(channelSize*8, channelSize*8)
		self.up1 = Up(channelSize*16, channelSize*4, bilinear)
		self.up2 = Up(channelSize*8, channelSize*2, bilinear)
		self.up3 = Up(channelSize*4, channelSize, bilinear)
		self.up4 = Up(channelSize*2, channelSize, bilinear)
		self.outc = OutConv(channelSize, output_shape[0])

	# def clean(self, features, logits, indices, label):
	def clean(self, features, indices, label):
		r1, r2 = label

		# a = features * r1
		# b = features[indices] * r2

		# --------------------------------------------------------------------------------

		ones = torch.ones(round(features.shape[1] * r1)).cuda()
		zeros = torch.zeros(round(features.shape[1] * r2)).cuda()
		mask = torch.cat([ones, zeros])
		ind = torch.randperm(len(mask))
		mask = mask[ind]
		mask2 = torch.ones(len(mask)).cuda() - mask
		a = features * mask.view(1, features.shape[1], 1, 1)
		b = features[indices] * mask2.view(1, features.shape[1], 1, 1)

		# --------------------------------------------------------------------------------

		# logits = torch.sigmoid(features)
		# ones = torch.ones(features.shape).cuda()
		# zeros = torch.zeros(features.shape).cuda()
		# maxx = torch.max(features, 1).values.view(features.shape[0], 1, features.shape[2], features.shape[3])
		# minn = torch.min(features, 1).values.view(features.shape[0], 1, features.shape[2], features.shape[3])
		# logits = (features - minn) / (maxx - minn)
		# a = features * torch.where(logits >= r2, ones, zeros).expand_as(features) * r1
		# b = features[indices] * torch.where(logits[indices] >= r1, ones, zeros).expand_as(features) * r2

		# --------------------------------------------------------------------------------

		# avg = self.globalAvgPool(logits).view(logits.shape[0], logits.shape[1])
		# num1 = round(logits.shape[1] * r1)
		# num2 = logits.shape[1] - num1
		# topk1 = torch.topk(logits, k=max(num1, num2), dim=1).indices
		# x = torch.zeros(features.shape).cuda()
		# for i, idx in enumerate(topk1[:, :num1]):
		#     x[i, idx] = 1
		# a = features * x

		# --------------------------------------------------------------------------------

		# topk2 = topk1[indices]
		# x = torch.zeros(features.shape).cuda()
		# for i, idx in enumerate(topk2[:, :num2]):
		#     x[i, idx] = 1
		# b = features[indices] * x

		# --------------------------------------------------------------------------------

		# ones = torch.ones(logits.shape).cuda()
		# zeros = torch.zeros(logits.shape).cuda()
		# maxx = torch.max(logits, 1).values.view(logits.shape[0], 1, 1, 1)
		# minn = torch.min(logits, 1).values.view(logits.shape[0], 1, 1, 1)
		# logits = (logits - minn) / (maxx - minn)
		# a = features * torch.where(logits >= r2, ones, zeros).expand_as(features)
		# b = features[indices] * torch.where(logits[indices] >= r1, ones, zeros).expand_as(features)

		return a, b

	def forward(self, a, indices, label):
		# By concat
		# label = self.labelDense(label).view(x1.shape[0], 1, self.input_shape[1], self.input_shape[2])
		# x = torch.cat([x1, label, x2], 1)

		# By Linear1
		# a = self.xDense(x1.view(x1.shape[0], -1))
		# b = self.xDense(x2.view(x2.shape[0], -1))
		# x = torch.cat([a, label, b], 1)
		# x = self.outDense(x).view(x1.shape[0], x1.shape[1], x1.shape[2], x1.shape[3])

		# By Linear2
		# x = torch.cat([a.view(a.shape[0], -1), b.view(b.shape[0], -1), label], 1)
		# x = self.fc(x).view(-1, a.shape[1], a.shape[2], a.shape[3])

		# a1, weights1 = self.inc(a)
		# a1, b1 = self.clean(a1, weights1, indices, label)
		# a2, weights2 = self.down1(a1)
		# a2, b2 = self.clean(a2, weights2, indices, label)
		# a3, weights3 = self.down2(a2)
		# a3, b3 = self.clean(a3, weights3, indices, label)
		# a4, weights4 = self.down3(a3)
		# a4, b4 = self.clean(a4, weights4, indices, label)
		# a5, weights5 = self.down4(a4)
		# a5, b5 = self.clean(a5, weights5, indices, label)

		a1 = self.inc(a)
		a1, b1 = self.clean(a1, indices, label)
		a2 = self.down1(a1)
		a2, b2 = self.clean(a2, indices, label)
		a3 = self.down2(a2)
		a3, b3 = self.clean(a3, indices, label)
		a4 = self.down3(a3)
		a4, b4 = self.clean(a4, indices, label)
		a5 = self.down4(a4)
		a5, b5 = self.clean(a5, indices, label)

		cated = self.merge5(torch.cat([a5, b5], 1))
		u1 = self.up1(cated, self.merge4(torch.cat([a4, b4], 1)))
		u2 = self.up2(u1, self.merge3(torch.cat([a3, b3], 1)))
		u3 = self.up3(u2, self.merge2(torch.cat([a2, b2], 1)))
		u4 = self.up4(u3, self.merge1(torch.cat([a1, b1], 1)))

		x_mix = self.outc(u4)

		return x_mix

# ------------------------------------------------------------------------------
		# a1, b1 = self.clean(self.inc(a), indices, label)
		# a2, b2 = self.clean(self.down1(a1), indices, label)
		# a3, b3 = self.clean(self.down2(a2), indices, label)
		# a4, b4 = self.clean(self.down3(a3), indices, label)
		# a5, b5 = self.clean(self.down4(a4), indices, label)

# -----------------------------------------------------------------------------
		# cleanLayer = np.random.randint(0, 5)
		# if(cleanLayer == 0):
		# 	a5 = self.clean(a5, label[0])
		# 	b5 = self.clean(b5, label[1])
		# cated = self.merge5(torch.cat([a5, b5], 1))

		# if(cleanLayer == 1):
		# 	a4 = self.clean(a4, label[0])
		# 	b4 = self.clean(b4, label[1])
		# u1 = self.up1(cated, self.merge4(torch.cat([a4, b4], 1)))

		# if(cleanLayer == 2):
		# 	a3 = self.clean(a3, label[0])
		# 	b3 = self.clean(b3, label[1])
		# u2 = self.up2(u1, self.merge3(torch.cat([a3, b3], 1)))

		# if(cleanLayer == 3):
		# 	a2 = self.clean(a2, label[0])
		# 	b2 = self.clean(b2, label[1])
		# u3 = self.up3(u2, self.merge2(torch.cat([a2, b2], 1)))

		# if(cleanLayer == 4):
		# 	a1 = self.clean(a1, label[0])
		# 	b1 = self.clean(b1, label[1])
		# u4 = self.up4(u3, self.merge1(torch.cat([a1, b1], 1)))

# ---------------------------------------------------------------------------------------------------------------

		# # label5 = self.labelDense5(label).view(a.shape[0], 1, a5.shape[2], a5.shape[3])
		# cated = self.merge5(torch.cat([a5*label[0][0], b5*label[0][1]], 1))
		# u1 = self.up1(cated, self.merge4(torch.cat([a4*label[0][0], b4*label[0][1]], 1)))
		# u2 = self.up2(u1, self.merge3(torch.cat([a3*label[0][0], b3*label[0][1]], 1)))
		# u3 = self.up3(u2, self.merge2(torch.cat([a2*label[0][0], b2*label[0][1]], 1)))
		# u4 = self.up4(u3, self.merge1(torch.cat([a1*label[0][0], b1*label[0][1]], 1)))

# ------------------------------------------------------------------------------------------------------

		# label = self.labelDense(label)
		# cated = self.merge(torch.cat([a5.view(a5.shape[0], -1), b5.view(b5.shape[0], -1), label], 1)).view(a5.shape[0], a5.shape[1], a5.shape[2], a5.shape[3])
		# # label4 = self.labelDense4(label).view(a.shape[0], 1, a4.shape[2], a4.shape[3])
		# # u1 = self.up1(cated, self.merge4(torch.cat([a4.view(a4.shape[0], -1), b4.view(b4.shape[0], -1), label4], 1)))
		# u1 = self.up1(cated, self.merge4(torch.cat([a4, b4], 1)))
		# u2 = self.up2(u1, self.merge3(torch.cat([a3, b3], 1)))
		# u3 = self.up3(u2, self.merge2(torch.cat([a2, b2], 1)))
		# u4 = self.up4(u3, self.merge1(torch.cat([a1, b1], 1)))

# ------------------------------------------------------------------------------------------------------

		# label5 = self.labelDense5(label).view(a.shape[0], 1, a5.shape[2], a5.shape[3])
		# cated = self.merge5(torch.cat([a5, b5, label5], 1))

		# label4 = self.labelDense4(label).view(a.shape[0], 1, a4.shape[2], a4.shape[3])
		# u1 = self.up1(cated, self.merge4(torch.cat([a4, b4, label4], 1)))

		# label3 = self.labelDense3(label).view(a.shape[0], 1, a3.shape[2], a3.shape[3])
		# u2 = self.up2(u1, self.merge3(torch.cat([a3, b3, label3], 1)))

		# label2 = self.labelDense2(label).view(a.shape[0], 1, a2.shape[2], a2.shape[3])
		# u3 = self.up3(u2, self.merge2(torch.cat([a2, b2, label2], 1)))

		# label1 = self.labelDense1(label).view(a.shape[0], 1, a1.shape[2], a1.shape[3])
		# u4 = self.up4(u3, self.merge1(torch.cat([a1, b1, label1], 1)))

		# x_mix = self.outc(u4)

		# # Backup
		# x1 = self.inc(x)
		# x2 = self.down1(x1)
		# x3 = self.down2(x2)
		# x4 = self.down3(x3)
		# x5 = self.down4(x4)
		# u1 = self.up1(x5, x4)
		# u2 = self.up2(u1, x3)
		# u3 = self.up3(u2, x2)
		# u4 = self.up4(u3, x1)
		# x_mix = self.outc(u4)

		# return x_mix

		# print('x1.shape = {}'.format(x1.shape))
		# print('x2.shape = {}'.format(x2.shape))
		# print('x3.shape = {}'.format(x3.shape))
		# print('x4.shape = {}'.format(x4.shape))
		# print('x5.shape = {}'.format(x5.shape))
		# print('up1.shape = {}'.format(u1.shape))
		# print('up2.shape = {}'.format(u2.shape))
		# print('up3.shape = {}'.format(u3.shape))
		# print('up4.shape = {}'.format(u4.shape))

		# layer_mix = np.random.randint(0, 4)
		# if(layer_mix == 0):
		# 	x, y_mix = mixup_process(x, y, lam, indices)
		# x1 = self.inc(x)
		# x2 = self.down1(x1)

		# if(layer_mix == 1):
		# 	x2, y_mix = mixup_process(x2, y, lam, indices)
		# x3 = self.down2(x2)

		# if(layer_mix == 2):
		# 	x3, y_mix = mixup_process(x3, y, lam, indices)
		# x4 = self.down3(x3)

		# if(layer_mix == 3):
		# 	x4, y_mix = mixup_process(x4, y, lam, indices)
		# x5 = self.down4(x4)

		# if(layer_mix == 4):
		# 	x5, y_mix = mixup_process(x5, y, lam, indices)
		# x = self.up1(x5, x4)

		# if(layer_mix == 5):
		# 	x, y_mix = mixup_process(x, y, lam, indices)
		# x = self.up2(x, x3)

		# if(layer_mix == 6):
		# 	x, y_mix = mixup_process(x, y, lam, indices)
		# x = self.up3(x, x2)

		# if(layer_mix == 7):
		# 	x, y_mix = mixup_process(x, y, lam, indices)
		# x = self.up4(x, x1)

		# if(layer_mix == 8):
		# 	x, y_mix = mixup_process(x, y, lam, indices)
		# x_mix = self.outc(x)


# librerias basicas
import torch, torchvision
import torch.backends.cudnn as cudnn
from torchvision import transforms, datasets

import mmdet
from mmcv.ops import get_compiling_cuda_version, get_compiler_version

# librerias para el detector de mascaras
import mmcv
from mmcv.runner import load_checkpoint

from mmdet.apis import inference_detector, show_result_pyplot
from mmdet.models import build_detector
from mmdet.datasets.pipelines import Compose

# profundidad
from models.model import GLPDepth
#tracker
from tracker.byte_tracker import BYTETracker

#librerias de fichero
import os, sys, errno

import glob
import argparse

# librerias para trar con la imagen
import numpy as np
import PIL.Image as pil
import matplotlib as mpl
import matplotlib.cm as cm

import cv2
from collections import OrderedDict

# tiempo
from timer import Timer

class Me_model():

    def __init__ (self,detector,depth,tracker,camera=[0,0,1],device=None,half_img_mm=True):
        """
        detector : argumentos detector
        depth : argumentos depth
        tracker :argumentos tracker
        camera : punto de convergencia de lines de perpectiva
        """
        torch.cuda.empty_cache()
        # Cargamos los modelos necesarios

        # Set the device to be used for evaluation

        if device:
            self.device=device
        else:
            self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        # Load the config
        config = mmcv.Config.fromfile(detector.config)
        # Set pretrained to be None since we do not need pretrained model here
        config.model.pretrained = None

        # Initialize the detector
        self.model = build_detector(config.model)

        # Load checkpoint
        checkpoint = load_checkpoint(self.model,detector.checkpoint, map_location=self.device)

        # Set the classes of models for inference
        self.model.CLASSES = checkpoint['meta']['CLASSES']

        # We need to set the model's cfg for inference
        self.model.cfg = config

        # Convert the model to GPU
        self.model.to(self.device)

        # Convert the model into evaluation mode
        self.model.eval()

        self.depth = GLPDepth(max_depth=10, is_train=False).to(self.device)
        depth_weight = torch.load(depth.checkpoint)
        if 'module' in next(iter(depth_weight.items()))[0]:
                depth_weight = OrderedDict((k[7:], v) for k, v in depth_weight.items())
        self.depth.load_state_dict(depth_weight)
        self.depth.eval()

        self.tracker = BYTETracker(tracker, frame_rate=tracker.frame_rate)
        self.ags_tracker=tracker
        self.shape=(480,640)

        self.pp=[camera[0],camera[1]]
        self.valpix=camera[2]
        self.half_img_mm=half_img_mm # lo hacemos si tomamos como referencia la mitad de la imagen para saber los metros en pixel

    def pixel2realx(self,punto):

        punto[1]=self.pp[1]*2-punto[1]
        pp=np.array(self.pp)
        m=(punto[0]-pp[1])/(punto[0]-pp[0])
        x=((-pp[1])/m)+pp[0]
        #x=self.valpix*x
        return x*(0.4*8/self.valpix)

    def pixel2realhx(self,punto):
        p=[punto[0],punto[1],1]
        rows = self.shape[0]; cols = self.shape[1]
        pts1 = np.float32([[0,250],[0,rows],[cols,250],[cols,rows]])
        x = 195
        pts2 = np.float32([[0,0],[x,rows],[cols,0],[cols-x,rows]])
        #Se calcula la matriz para la corrección de perspectiva
        M = cv2.getPerspectiveTransform(pts1,pts2)
        #print(M)
        pn=np.dot(M,p.T)
        pn=[pn[0]/pn[2],pn[1]/pn[2]]

        return (pn[0]-x)*(0.4*16/(cols-x-x))

    def pixel2reald(self,punto,b = 57.66066148,w = -0.22307059):
        #w = [[-0.22307059]], b = [57.66066148]
        #b = 57.66066148
        if punto>200:
            return -w*punto+b
        else:
            w=-0.00185376
            b=11.51382925
            return -w*punto+b

    def plot_tracking(self,image, tlwhs, obj_ids, scores=None, frame_id=0, fps=0., ids2=None):
        im = np.ascontiguousarray(np.copy(image))
        im_h, im_w = im.shape[:2]

        top_view = np.zeros([im_w, im_w, 3], dtype=np.uint8) + 255

        #text_scale = max(1, image.shape[1] / 1600.)
        #text_thickness = 2
        #line_thickness = max(1, int(image.shape[1] / 500.))
        text_scale = 2
        text_thickness = 2
        line_thickness = 3

        radius = max(5, int(im_w/140.))
        cv2.putText(im, 'frame: %d fps: %.2f num: %d' % (frame_id, fps, len(tlwhs)),
                    (0, int(15 * text_scale)), cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), thickness=2)

        for i, tlwh in enumerate(tlwhs):
            x1, y1, w, h = tlwh
            intbox = tuple(map(int, (x1, y1, x1 + w, y1 + h)))
            obj_id = int(obj_ids[i])
            id_text = '{}'.format(int(obj_id))
            if ids2 is not None:
                id_text = id_text + ', {}'.format(int(ids2[i]))
            color = self.get_color(abs(obj_id))
            cv2.rectangle(im, intbox[0:2], intbox[2:4], color=color, thickness=line_thickness)
            cv2.putText(im, id_text, (intbox[0], intbox[1]), cv2.FONT_HERSHEY_PLAIN, text_scale, (0, 0, 255),
                        thickness=text_thickness)
        return im

    def pos_x_y_new(self,boxs,ids,masks,depth,depths,frame,view=True):
        if view:

            depth1= cv2.cvtColor(depth, cv2.COLOR_RGB2GRAY )
            imagen_depth=np.zeros((depth1.shape))
            image_depth_human=np.zeros((depth.shape))
            imagen_view_new=np.zeros((depth.shape))
            self.shape=depth1.shape

        puntos=[]
        puntos_real=[]
        cont_nop=0

        for idx_box in range(len(boxs)):
            if view:
                mascara=masks[idx_box]*255
                mascara=np.uint8(mascara)

                imagen_unida=  cv2.bitwise_and(depth1, depth1, mask=mascara)
                imagen_depth+=imagen_unida

            depth= depths[idx_box]

            puntos.append((int( boxs[idx_box][0]+boxs[idx_box][2]//2) , int(depth*self.shape[0]/255) ) )

            x_real=self.pixel2realx([ boxs[idx_box][0]+boxs[idx_box][2]//2,boxs[idx_box][3]] )
            x_real_3=self.pixel2realhx([ boxs[idx_box][0]+boxs[idx_box][2]//2,boxs[idx_box][3]] )
            puntos_real.append((int( x_real ) , int(depth),int(x_real_3) ) )
            if view:
                str_save="\t".join([str(frame),str(ids[idx_box]),str(puntos[idx_box][0]),str(puntos[idx_box][1])])
                dep_r=self.pixel2reald(puntos_real[idx_box][1])
                str_save2="\t".join([str(frame),str(ids[idx_box]),str(puntos_real[idx_box][0]),str(puntos_real[idx_box][1]),str(punto),str(dep_r)])
                str_save2="\t".join([str(frame),str(ids[idx_box]),str(puntos_real[idx_box][0]),str(puntos_real[idx_box][1]),str(punto),str(dep_r),str(puntos_real[idx_box][3])])
                self.fichero.write(str_save + os.linesep)
                self.fichero2.write(str_save2 + os.linesep)
                self.fichero3.write(str_save3 + os.linesep)
            if view:
                cv2.circle(imagen_view_new,(puntos[idx_box][0],puntos[idx_box][1]),10,(self.get_color(ids[idx_box])),-1)

        if view:
            image_depth_human[:,:,0]=imagen_depth
            image_depth_human[:,:,1]=imagen_depth
            image_depth_human[:,:,2]=imagen_depth

            return np.concatenate([image_depth_human,imagen_view_new], 1),puntos

        else:
            return puntos

    def change_view(self,path,paths_out="out",ext="png",save=True):

        paths= sorted(glob.glob(os.path.join(path, '*.{}'.format(ext))))
        os.makedirs(paths_out, exist_ok=True)
        if save:
            self.fichero = open(paths_out+'/mi_fichero', 'w')
            self.fichero2 = open(paths_out+'/mi_ficheror', 'w')
            self.fichero3 = open(paths_out+'/mi_ficheror2', 'w')
        timer = Timer()
        for idx, image_path in enumerate(paths):# Use the detector to do inference

                timer.tic()

                img= cv2.imread(image_path)

                self.shape=img.shape
                if idx==0:
                    self.pp=[self.shape[1]//2,self.shape[0]//2]
                    if self.half_img_mm:
                        self.valpix=self.valpix/self.pp[0]

                if idx%1==0:
                    result=inference_detector(self.model, img)

                    bboxes,masks=self.gef_get_box([result[0][0],[result[1][0]]])

                    #profundidad en los pixeles pares

                    im = pil.fromarray(img)

                    original_width, original_height= im.size

                    input_image = transforms.ToTensor()(im).unsqueeze(0)
                    input_image = input_image.to(self.device)
                    outputs = self.depth(input_image)

                    disp = outputs["pred_d"]
                    disp_resized = torch.nn.functional.interpolate(
                    disp, (original_height, original_width), mode="bilinear", align_corners=False)

                    output_name = os.path.splitext(os.path.basename(image_path))[0]

                    name_dest_npy = os.path.join(paths_out, "{}.png".format(output_name))

                    disp_resized_np = disp_resized.squeeze().cpu().detach().numpy()

                    imga=np.ones((disp_resized_np.shape))*disp_resized_np.max()
                    disp_resized_np=imga-disp_resized_np
                    vmax = np.percentile(disp_resized_np, 95)
                    normalizer = mpl.colors.Normalize(vmin=disp_resized_np.min(), vmax=vmax)
                    mapper = cm.ScalarMappable(norm=normalizer, cmap='magma')
                    colormapped_im = (mapper.to_rgba(disp_resized_np)[:, :, :3] * 255).astype(np.uint8)

                if bboxes is not None:
                        if idx%1==0:
                            online_targets = self.tracker.update(bboxes,masks ,[img.shape[0],img.shape[1]], [img.shape[0],img.shape[1]],
                                                            colormapped_im)
                        else:
                            #actualizamos la profundida con el mismo valor
                            online_targets = self.tracker.update(bboxes,masks ,[img.shape[0],img.shape[1]], [img.shape[0],img.shape[1]],
                            update_depth=True)

                        online_tlwhs = []
                        online_mask = []
                        online_ids = []
                        online_scores = []
                        online_depth=[]
                        for t in online_targets:
                                tlwh = t.tlwh

                                tid = t.track_id
                                vertical = tlwh[2] / tlwh[3] > self.ags_tracker.aspect_ratio_thresh
                                if tlwh[2] * tlwh[3] > self.ags_tracker.min_box_area and not vertical:
                                    online_tlwhs.append(tlwh)
                                    online_ids.append(tid)
                                    online_scores.append(t.score)
                                    online_mask.append(t.mask)
                                    online_depth.append(t.depth)
                                    #print(np.max(np.array(online_depth)))

                        timer.toc()

                        image_depth_human=self.pos_x_y_new(online_tlwhs,online_ids,online_mask,colormapped_im,online_depth,idx,save)

                        if len(image_depth_human)>1:
                            image_depth_human,puntos=image_depth_human
                            image_depth_human=self.plot_tracking(
                                image_depth_human, online_tlwhs, online_ids, frame_id= idx + 1, fps=1. / timer.average_time)

                        else:
                            puntos=image_depth_human
                            image_depth_human=np.zeros((img.shape[0],img.shape[1]*2,img.shape[2]))
                        if save:
                            online_im = self.plot_tracking(
                                    img, online_tlwhs, online_ids, frame_id= idx + 1, fps=1. / timer.average_time)

                else:
                    online_im = img
                    image_depth_human=np.zeros((img.shape[0],img.shape[1]*2,img.shape[2]))
                    timer.toc()

                if save:
                    colormapped_im2=self.plot_tracking(
                                    colormapped_im.copy(), online_tlwhs, online_ids, frame_id= idx + 1, fps=1. / timer.average_time)

                    online_im=np.concatenate([online_im,colormapped_im2], 1)

                    online_im=np.concatenate([online_im,image_depth_human], 0)

                    cv2.imwrite(name_dest_npy, online_im)

                print(" foto ",idx,"fps", 1. / max(1e-5, timer.average_time))

        self.fichero3.close()
        self.fichero.close()
        self.fichero2.close()
    @staticmethod
    def gef_get_box(result):
        bbox_result,mask_result = result
        bboxes = np.vstack(bbox_result)
        scores = bboxes[:,4]

        if len(result) == 0:
            bboxes = np.zeros([0, 5])
            masks = np.zeros([0, 0, 0])

        else:
            masks = mmcv.concat_list(mask_result)

            if isinstance(masks[0], torch.Tensor):
                masks = torch.stack(masks, dim=0).detach().cpu().numpy()
            else:
                masks = np.stack(masks, axis=0)

            if bboxes[:, :4].sum() == 0:
                num_masks = len(bboxes)
                x_any = masks.any(axis=1)
                y_any = masks.any(axis=2)
                for idx in range(num_masks):
                    x = np.where(x_any[idx, :])[0]
                    y = np.where(y_any[idx, :])[0]
                    if len(x) > 0 and len(y) > 0:
                        bboxes[idx, :4] = np.around( np.array(
                            [x[0], y[0], x[-1] + 1, y[-1] + 1],
                            dtype=np.float32) )

        return  bboxes,masks

    @staticmethod
    def get_color(idx):
        idx = idx * 3
        color = ((37 * idx) % 255, (17 * idx) % 255, (29 * idx) % 255)

        return color


import time
import json

from canbus import CanBUS

from receivingthread import ReceivingThread
from transmittingthread import TransmittingThread
from errorcounter import ErrorCounter
import config
from logger import Logger

"""
@author Olivier Cros
CAN BUS Simulation Main file
Launching simulation and logging machine
"""

def launchNode(nodeId, canFilter, networkNodes, isSigned, params):
    """
    Initializing the bus interface
    and preparing the reception and transmission threads
    """
    bus = CanBUS(interface='socketcan',
                 channel=params["channel"],
                 can_filters=canFilter,
                 receive_own_messages=True)

    bus.set_filters(canFilter)
    ec = ErrorCounter()
    totalNodes = params["totalNodes"]
    totalGroups = params["groups"]

    recThread = ReceivingThread(bus, nodeId, ec, isSigned)
    transThread = TransmittingThread(bus, nodeId, networkNodes,
                                     ec, isSigned, totalNodes, totalGroups)

    # Starting reception thread
    print("Launching the nodes ")
    if(params["reception"]):
        print("Starting the receiver " + str(nodeId))
        recThread.start()

    # Starting transmission thread
    if(params["transmission"]):
        print("Starting the transmitter " + str(nodeId))
        transThread.start()

    return (recThread, transThread)

def prepareSim(params):
    """
    Setting up the network nodes and the filters applied to it
    """
    networkNodes = []
    for i in range(0, params["nbNodes"]):
        networkNodes.append((params["id"]+i, params["sign"]))

    node_id = params["id"]

    # Receiver mask
    if(params["sign"]):
        # canFilter = [{"can_id": (node_id << 16), "can_mask": 0x000000000}]
        canFilter = [{"can_id": 0x00000000, "can_mask": 0x000000000}]
    else:
        canFilter = [{"can_id": 0x1230 + node_id, "can_mask": 0x00001FFF}]

    # Initialize thread list
    threads = []

    filters = []

    # create a bus instance
    for k in range(len(networkNodes)):
        if(params["sign"]):
            # canFilter[0]["can_id"] = canFilter[0]["can_id"]+0x00010000
            # newfilt = [{"can_id": canFilter[0]["can_id"],
            #            "can_mask": 0x000000000}]
            newfilt = [{"can_id":  0x000000000,
                        "can_mask": 0x000000000}]
        else:
            newfilt = [{"can_id": canFilter[0]["can_id"] + k,
                        "can_mask": 0x00001FF0}]

        filters.append(newfilt)
        threads.append(launchNode(networkNodes[k][0],
                                  newfilt,
                                  networkNodes,
                                  networkNodes[k][1],
                                  params))

    return (threads, filters, networkNodes)

def launchSim(params):
    """
    Launching the simulation for a given time
    """
    # nitialize thread list and prepare simulation
    threads, filters, networkNodes = prepareSim(params)

    j = 0
    params["startTime"] = time.time()
    errorsCount = {}

    while (params["verbose"]
           and (time.time() - params["startTime"]) < params["delay"]):
        currentTime = time.time()

        if(params["verbose"]):
            logger = Logger()
            errorsCount = logger.logSim(threads, filters, networkNodes, params)
        errorsCount = 0
        timeVal = currentTime-params["startTime"]
        timeVal = round(timeVal*100)/100
        j = j+1
        time.sleep(0.5)

    # file.close()
    return errorsCount

if __name__ == "__main__":
    """
    Opening the JSON config file and preparing the simulation
    """
    # JSON Config loading
    with open(config.CONFIGPATH + 'config.json', 'r') as f:
        params = json.load(f)

    startTime = time.time()

    # Start the simulation
    errorsCount = launchSim(params)


import cv2
import io
import numpy as np
from django.core.files.uploadedfile import InMemoryUploadedFile

#convert memory image to numpy array that can be used by opencv
def convert_to_numpy(image):
    image_bytes = image.read()
    image = np.frombuffer(image_bytes, np.uint8)
    image = cv2.imdecode(image, cv2.IMREAD_COLOR)
    return image
def convert_to_memory(image):
    _, image = cv2.imencode(".png", image)
    image = io.BytesIO(image)
    image = InMemoryUploadedFile(image, None, "image.png", "image/png", image.tell(), None)
    return image
#rotate

#mirror
def mirror(image):
    image = convert_to_numpy(image)
    mirroredImage = cv2.flip(image, 1)
    image = convert_to_memory(mirroredImage)
    return image
#resize
def resize(image, width, height):
    image = convert_to_numpy(image)
    resizedImage = cv2.resize(image, (width, height))
    image = convert_to_memory(resizedImage)
    return image

def rotate(image, angle):
    image = convert_to_numpy(image)

    rotatedImage = cv2.getRotationMatrix2D((image.shape[1] / 2, image.shape[0] / 2), -angle, 1)
    rotatedImage = cv2.warpAffine(image, rotatedImage, (image.shape[1], image.shape[0]))

    image = convert_to_memory(rotatedImage)
    return image

#crop
def crop(image, top_coordinate,left_coordinate,bottom_coordinate,right_coordinate):
    image = convert_to_numpy(image)
    croppedImage = image[top_coordinate:bottom_coordinate, left_coordinate:right_coordinate]
    image = convert_to_memory(croppedImage)
    return image

def mirror_v(image):
    #vertical mirror
    image = convert_to_numpy(image)
    mirroredImage = cv2.flip(image, 0)
    image = convert_to_memory(mirroredImage)
    return image


import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np

class Qnet(torch.nn.Module):
    ''' 只有一层隐藏层的Q网络 '''
    def __init__(self, state_dim, hidden_dim, action_dim):
        super(Qnet, self).__init__()
        self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
        self.fc2 = torch.nn.Linear(hidden_dim, action_dim)

    def forward(self, x):
        x = F.relu(self.fc1(x))  # 隐藏层使用ReLU激活函数
        return self.fc2(x)
class VDN:
    def __init__(self, agents_num, state_dim, hidden_dim, action_dim, learning_rate, gamma,
                  epsilon, target_update, device):

        # 智能体数量
        self.agents_num = agents_num
        # 状态维度
        self.state_dim = state_dim
        # 隐藏层维度
        self.hidden_dim = hidden_dim
        # 动作维度
        self.action_dim = action_dim
        # 学习率
        self.learning_rate = learning_rate
        # 折扣因子
        self.gamma = gamma
        # epsilon-贪婪策略
        self.epsilon = epsilon
        # 目标网络更新频率
        self.target_update = target_update
        # 设备
        self.device = device
        self.count = 0  # 计数器,记录更新次数

        Qnet_input_dim = state_dim * self.agents_num

        # 神经网络
        # 所有智能体共用一个决策q网络，但是每个智能体有一个独立的target_q网络
        self.eval_qnet = Qnet(Qnet_input_dim, hidden_dim,
                          self.action_dim).to(device)   # 每个agent选动作的网络
        self.target_qnet = []
        for i in range(self.agents_num):
            self.target_qnet.append(Qnet(Qnet_input_dim, hidden_dim,
                          self.action_dim).to(device))  # 每个agent选动作的网络

        # 让target_net和eval_net的网络参数相同
        for i in range(self.agents_num):
            self.target_qnet[i].load_state_dict(self.eval_qnet.state_dict())

        self.optimizer = torch.optim.Adam(self.eval_qnet.parameters(), lr=self.learning_rate)

        print('Init alg VDN')

    def update(self, transition_dict):
        """更新Q网络参数"""
        states = torch.tensor(transition_dict['states'],
                              dtype=torch.float).to(self.device)
        actions1 = torch.tensor(transition_dict['actions1']).view(-1, 1).to(
            self.device)
        actions2 = torch.tensor(transition_dict['actions2']).view(-1, 1).to(
            self.device)
        rewards = torch.tensor(transition_dict['rewards'],
                               dtype=torch.float).view(-1, 1).to(self.device)
        next_states = torch.tensor(transition_dict['next_states'],
                                   dtype=torch.float).to(self.device)
        dones = torch.tensor(transition_dict['dones'],
                             dtype=torch.float).view(-1, 1).to(self.device)

        # 计算loss
        q_values_1 = self.eval_qnet(states)
        q_values_2 = self.eval_qnet(states)
        # 分别计算每个智能体的target_q值并加起来
        for i in range(self.agents_num):
            next_q_value= self.target_qnet[i](next_states)
            if i == 0:
                next_q_values = next_q_value
            else:
                next_q_values = next_q_values + next_q_value

        with torch.no_grad():
            max_next_q_values = next_q_values.max(dim=1)[0].unsqueeze(1)
            target_q_values = rewards + (self.gamma * max_next_q_values * (1 - dones))
        # # detach()函数将target_q_values从计算图中分离出来，防止梯度传播
        # target_q_values = target_q_values.detach()
        # 获取对应的q值
        q_values1 = q_values_1.gather(1, actions1)
        q_values2 = q_values_2.gather(1, actions2)
        q_values = q_values1 + q_values2
        loss = nn.functional.mse_loss(q_values, target_q_values)

        # 反向传播更新参数
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()

        # 更新target网络
        if self.count % self.target_update == 0:
            for i in range(self.agents_num):
                self.target_qnet[i].load_state_dict(self.eval_qnet.state_dict())
        self.count += 1

    def take_action(self, state):  # epsilon-贪婪策略采取动作
        if np.random.random() < self.epsilon:
            action = np.random.randint(self.action_dim)

        else:
            state = torch.tensor([state], dtype=torch.float).to(self.device)
            action = self.eval_qnet(state).argmax().item()

        return action


import sqlite3
from zipfile import ZipFile
from tempfile import TemporaryDirectory
import json
from tqdm import tqdm
import os
import re
import logging

from .config import config
from .util import MediaType
from . import db

def init(database, **kwargs):
    db.database.init(database, **kwargs)
    if not os.path.exists(database):
        db.create_all_tables()

def update_config(markdown=False, srs=None):
    config.update(markdown=markdown, srs=srs)
    if db.Settings.get_or_none() is None:
        db.Settings().save()
    else:
        config.update(db.Settings.to_dict())

def import_apkg(src_apkg, skip_media=False):
    """

    :param src_apkg:
    :param bool|list skip_media:
    :return:
    """
    info = dict()

    with TemporaryDirectory() as temp_dir:
        with db.database.atomic():
            with ZipFile(src_apkg) as zf:
                zf.extractall(temp_dir)

            conn = sqlite3.connect(os.path.join(temp_dir, 'collection.anki2'))
            conn.row_factory = sqlite3.Row

            try:
                d = dict(conn.execute('''SELECT * FROM col LIMIT 1''').fetchone())
                for model in tqdm(tuple(json.loads(d['models']).values()), desc='models'):
                    db.Model.create(
                        id=model['id'],
                        name=model['name'],
                        css=model['css']
                    )

                    info.setdefault('model', dict())[int(model['id'])] = model
                    for media_name in re.findall(r'url\([\'\"]((?!.*//)[^\'\"]+)[\'\"]\)', model['css']):
                        info.setdefault('media', dict())\
                            .setdefault(MediaType.font, dict())\
                            .setdefault(media_name, [])\
                            .append(model['id'])

                    for template in model['tmpls']:
                        db_template = db.Template.get_or_create(
                            model_id=model['id'],
                            name=template['name'],
                            question=template['qfmt'],
                            answer=template['afmt'],
                        )[0]

                        info.setdefault('template', dict())[db_template.id] = template

                for deck in tqdm(tuple(json.loads(d['decks']).values()), desc='decks'):
                    db.Deck.create(
                        id=deck['id'],
                        name=deck['name']
                    )

                c = conn.execute('''SELECT * FROM notes''')
                for note in tqdm(c.fetchall(), desc='notes'):
                    info_model = info['model'][note['mid']]
                    header = [field['name'] for field in info_model['flds']]

                    db_note = db.Note.create(
                        id=note['id'],
                        model_id=note['mid'],
                        data=dict(zip(header, note['flds'].split('\u001f')))
                    )

                    for tag in set(t for t in note['tags'].split(' ') if t):
                        db_tag = db.Tag.get_or_create(
                            name=tag
                        )[0]

                        db_tag.notes.add(db_note)

                    info.setdefault('note', dict())[note['id']] = dict(note)

                    for media_name in re.findall(r'src=[\'\"]((?!.*//)[^\'\"]+)[\'\"]', note['flds']):
                        info.setdefault('media', dict())\
                            .setdefault(MediaType.image, dict())\
                            .setdefault(media_name, [])\
                            .append(note['id'])

                    for media_name in re.findall(r'\[sound:[^\]]+\]', note['flds']):
                        info.setdefault('media', dict()) \
                            .setdefault(MediaType.audio, dict()) \
                            .setdefault(media_name, []) \
                            .append(note['id'])

                c = conn.execute('''SELECT * FROM cards''')
                for card in tqdm(c.fetchall(), desc='cards'):
                    info_note = info['note'][card['nid']]
                    info_model = info['model'][info_note['mid']]
                    db_model = db.Model.get(id=info_model['id'])
                    db_template = db_model.templates[0]

                    if '{{cloze:' not in db_template.question:
                        db_template = db_model.templates[card['ord']]
                        db.Card.create(
                            id=card['id'],
                            note_id=card['nid'],
                            deck_id=card['did'],
                            template_id=db_template.id
                        )
                    else:
                        for db_template_n in db_model.templates:
                            db.Card.create(
                                id=card['id'],
                                note_id=card['nid'],
                                deck_id=card['did'],
                                cloze_order=card['ord'] + 1,
                                template_id=db_template_n.id
                            )

                for db_deck in db.Deck.select():
                    if not db_deck.cards:
                        db_deck.delete_instance()
            finally:
                conn.close()

            if not skip_media:
                if skip_media is False:
                    skip_media = []

                with open(os.path.join(temp_dir, 'media')) as f:
                    info_media = info.get('media', dict())
                    for media_id, media_name in tqdm(json.load(f).items(), desc='media'):
                        with open(os.path.join(temp_dir, media_id), 'rb') as image_f:
                            db_media = db.Media.create(
                                id=int(media_id),
                                name=media_name,
                                data=image_f.read()
                            )

                            if MediaType.image not in skip_media:
                                for note_id in info_media.get(MediaType.image, dict()).get(media_name, []):
                                    db_media.notes.add(db.Note.get(id=note_id))

                            if MediaType.audio not in skip_media:
                                for note_id in info_media.get(MediaType.audio, dict()).get(media_name, []):
                                    db_media.notes.add(db.Note.get(id=note_id))

                            if MediaType.font not in skip_media:
                                for model_id in info_media.get(MediaType.font, dict()).get(media_name, []):
                                    db_media.models.add(db.Model.get(id=model_id))

                            if not db_media.notes and db_media.models:
                                logging.error('%s not connected to Notes or Models. Deleting...', media_name)
                                db_media.delete_instance()


"""
Procuret Python
Customer Payment Module
author: hugh@blinkybeach.com
"""
from procuret.data.codable import Codable, CodingDefinition as CD
from procuret.time.time import ProcuretTime
from decimal import Decimal
from procuret.human.headline import HumanHeadline
from procuret.data.disposition import Disposition
from procuret.payment_method.headline import PaymentMethodHeadline
from procuret.money.currency import Currency
from typing import Optional

class CustomerPayment(Codable):

    coding_map = {
        'public_id': CD(str),
        'executor': CD(HumanHeadline),
        'created': CD(ProcuretTime),
        'executed': CD(ProcuretTime),
        'magnitude': CD(Decimal),
        'disposition': CD(Disposition),
        'active': CD(bool),
        'payment_method': CD(PaymentMethodHeadline, optional=True),
        'commitment_id': CD(str),
        'denomination': CD(Currency)
    }

    def __init__(
        self,
        public_id: str,
        executor: HumanHeadline,
        created: ProcuretTime,
        executed: ProcuretTime,
        magnitude: Decimal,
        disposition: Disposition,
        active: bool,
        payment_method: Optional[PaymentMethodHeadline],
        commitment_id: str,
        denomination: Currency
    ) -> None:

        self._public_id = public_id
        self._executor = executor
        self._created = created
        self._executed = executed
        self._disposition = disposition
        self._magnitude = magnitude
        self._active = active
        self._payment_method = payment_method
        self._commitment_id = commitment_id
        self._denomination = denomination

        return

    public_id: str = property(lambda s: s._public_id)
    executor: HumanHeadline = property(lambda s: s._executor)
    created: ProcuretTime = property(lambda s: s._created)
    executed: ProcuretTime = property(lambda s: s._executed)
    magnitude: Decimal = property(lambda s: s._magnitude)
    disposition: Disposition = property(lambda s: s._disposition)
    active: bool = property(lambda s: s._active)
    payment_method: Optional[PaymentMethodHeadline] = property(
        lambda s: s._payment_method
    )
    commitment_id: str = property(lambda s: s._commitment_id)
    denomination: Currency = property(lambda s: s._denomination)


import requests
import pygame

BASE_URL = "https://www.random.org/"

def get_nums_array(size, minimum, maximum, col=1, base=10):
    if size > 10000:
        size = 10000
    full_url = BASE_URL + 'integers/?num=' + str(size) + '&min=' + \
        str(minimum) + '&max=' + str(maximum) + '&col=' + str(col) + \
        '&base=' + str(base) + '&format=plain&rnd=new'
    print(full_url)
    request = requests.get(full_url)
    numbers_list = []
    for num in request.content:
        numbers_list.append(num)
    print(numbers_list)
    return numbers_list

def generate_random_image(x_size, y_size, canvas):
    total_pixels = x_size * y_size
    pixArr = pygame.PixelArray(canvas)
    color_nums = get_nums_array(total_pixels, 0, 255)
    color_iter = 0
    x_pos = 0
    y_pos = 0
    for i in range(0, total_pixels):
        # color = pygame.Color.hsla((code, 100, 100, 100))
        # Draw on each pixel
        color = ''
        color_range_check = (i - (len(color_nums) * color_iter)) * 3
        print(color_range_check)
        if color_range_check + 2 >= len(color_nums):
            get_nums_array(total_pixels, 0, 255)
            color_iter += 1
        color = [color_nums[(i - (len(color_nums) * color_iter)) * 3 + j] for j in range(0, 3)]
        if x_pos >= x_size:
            y_pos += 1
            x_pos = 0
        pixArr[x_pos][y_pos] = (color[0], color[1], color[2])

if __name__ == '__main__':
    pygame.init()
    size = width, height = 128, 128
    white = 255, 255, 255
    screen = pygame.display.set_mode(size)
    generate_random_image(width, height, screen)


"""
common used functions
"""

from functools import reduce
from numpy import trapz
import numpy as np
from astropy.time import Time
from astropy.modeling import models
from astropy.modeling.fitting import LevMarLSQFitter

class Experiment:
    """
     Experiment class
    """

    def __init__(self, **entries):
        self.flag = None
        self.modifiedJulianDays = None
        self.Iteration_number = None
        self.polarizationAVG = None
        self.polarizationU9 = None
        self.polarizationU1 = None
        self.location = None
        self.Date = None
        self.specie = None
        self.type = None
        self.__dict__.update(entries)

def file_len(file_name):
    """

    :param file_name: file name
    :return: rows of file
    """
    i = 0
    with open(file_name) as file:
        for i, _ in enumerate(file):
            pass
    return i + 1

def get_iteration_from_output_file(file):
    return int(file.split(".")[1].split("_")[-1])

def indexies(array, value):
    """

    :param array: nupmy array
    :param value: value to search
    :return: indexes in array for value
    """
    indexes = list()
    for i in range(0, len(array) - 1):
        if array[i] == value:
            indexes.append(i)
    return indexes

def find_nearest_index(array, value):
    """

    :param array: array
    :param value: value to search
    :return: nearest index of value for array
    """
    array = np.asarray(array)
    index = (np.abs(array - value)).argmin()
    return index

def correct_numpy_read_data(data):
    """

    :param data: numpy array
    :return: corrected numpy array
    """
    corrected_data = list()
    for dd_ in data:
        corrected_data.append(dd_[0])
    return np.array(corrected_data)

def convert_datetime_object_to_mjd(time):
    """

    :param time: datetime object
    :return: MJD
    """
    time = time.isoformat()
    tt_ = Time(time, format='isot')
    return tt_.mjd

def compute_gauss(xarray, avg_y_not_smooht_data, gauss_lines):
    """

    :param xarray: xarray
    :param avg_y_not_smooht_data:
    :param gauss_lines: gauss_lines
    :return: area under signal from spectre
    """
    ampvid = avg_y_not_smooht_data
    velocity = xarray
    indexs = [(np.abs(velocity - float(line))).argmin() for line in gauss_lines]
    mons = [max(ampvid[index - 5:index + 5]) for index in indexs]
    gaussian = [models.Gaussian1D(mons[index], gauss_lines[index],
                                  0.05, bounds={'stddev': (None, 0.15)})
                for index in range(0, len(mons))]

    gg_init = reduce(lambda a, b : a + b, gaussian)
    fit = LevMarLSQFitter()
    gg_fit = fit(gg_init, velocity, ampvid)
    if len(gauss_lines) > 1:
        sts = [models.Gaussian1D(gg_fit[index].amplitude,
                                 gg_fit[index].mean,
                                 gg_fit[index].stddev) for index in range(0, len(gauss_lines))]
        gaussian_areas = []
        gaussiana_amplitudes = [str(gg_fit[index].amplitude).split("=")[-1].replace(")", "")
                                for index in range(0, len(gauss_lines))]
        gaussiana_mean = [str(gg_fit[index].mean).split("=")[-1].replace(")", "")
                          for index in range(0, len(gauss_lines))]
        gaussiana_std = [str(gg_fit[index].stddev).split(",")[1].split("=")[-1]
                         for index in range(0, len(gauss_lines))]

        for st_ in sts:
            gaussian_areas.append(trapz(st_(velocity), velocity))

        return (gaussian_areas, sts, gg_fit, velocity, ampvid, gauss_lines,
                gaussiana_amplitudes, gaussiana_mean, gaussiana_std)

    else:
        sts = models.Gaussian1D(gg_fit.amplitude, gg_fit.mean, gg_fit.stddev)
        gaussian_areas = []
        gaussiana_amplitudes = str(gg_fit.amplitude).split("=")[-1].replace(")", "")
        gaussiana_mean = str(gg_fit.mean).split("=")[-1].replace(")", "")
        gaussiana_std = str(gg_fit.stddev).split(",")[1].split("=")[-1]

        gaussian_areas.append(trapz(sts(velocity), velocity))

        return (gaussian_areas, sts, gg_fit, velocity, ampvid,
                gauss_lines, gaussiana_amplitudes, gaussiana_mean, gaussiana_std)


import struct
import ecdsa

import trezor_pb2 as proto
import tools

def raw_tx_header(inputs_count):
    s = ''
    s += '\x01\x00\x00\x00'  # version
    s += tools.var_int(inputs_count)  # number of inputs
    return s

def raw_tx_input(inp, script_sig):
    s = ''
    s += inp.prev_hash[::-1]  # prev hash
    s += struct.pack('<L', inp.prev_index)  # prev index
    if script_sig != '':
        s += tools.var_int(len(script_sig))  # script length
        s += script_sig  # script sig
    s += "\xff\xff\xff\xff"  # sequence
    return s

def raw_tx_middle(outputs_count):
    s = ''
    s += tools.var_int(outputs_count)  # number of outputs
    return s

def raw_tx_output(out):
    s = ''
    s += struct.pack('<Q', out.amount)  # amount

    if out.script_type == proto.PAYTOADDRESS:
        script = '\x76\xa9'  # op_dup, op_hash_160
        script += '\x14'  # push 0x14 bytes
        script += tools.bc_address_to_hash_160(out.address)
        script += '\x88\xac'  # op_equalverify, op_checksig

    elif out.script_type == proto.PAYTOSCRIPTHASH:
        raise Exception("P2SH not implemented yet!")

    else:
        raise Exception("Unknown script type!")

    s += tools.var_int(len(script))  # script length
    s += script  # script
    return s

def raw_tx_footer(for_sign):
    s = ''
    s += '\x00\x00\x00\x00'  # lock time
    if for_sign:
        s += '\x01\x00\x00\x00'  # hash type
    return s

'''
# https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_integer
def raw_tx(inputs, outputs, for_sig):
    s = ''
    s += raw_tx_header(len(inputs))

    for i in range(len(inputs)):
        inp = inputs[i]

        if for_sig == i:
            script_sig = inp.script_sig
        else:
            script_sig = ''

        s += raw_tx_input(inp, script_sig)

    s += raw_tx_middle(len(outputs))

    for output in outputs:
        s += raw_tx_output(output)

    s += raw_tx_footer()
    return s
'''

def sign_input(algo, secexp, addr_n, tx_hash):
    pk = algo.get_private_key(secexp, addr_n)
    private_key = ecdsa.SigningKey.from_string(pk, curve=tools.SECP256k1)
    sig = private_key.sign_digest(tx_hash, sigencode=ecdsa.util.sigencode_der)
    public_key = private_key.get_verifying_key()
    pubkey = public_key.to_string()
    return (pubkey, sig)

'''
def sign_inputs(algo, secexp, inputs, outputs):
    # This is reworked but backward compatible (non-streaming) method from Electrum
    signatures = []
    for i in range(len(inputs)):
        addr_n = inputs[i].address_n
        print addr_n

        tx = raw_tx(inputs, outputs, for_sig=i)
        tx_hash = tools.Hash(tx)
        signatures.append(sign_input(algo, secexp, addr_n, tx_hash))
    return signatures
'''


import logging
import re

from SpiffWorkflow.exceptions import SpiffWorkflowException
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskException

from ..specs.model import HitPolicy

logger = logging.getLogger('spiff.dmn')

class DMNEngine:
    """
    Handles the processing of a decision table.
    """

    def __init__(self, decision_table):
        self.decision_table = decision_table

    def decide(self, task):
        rules = []
        for rule in self.decision_table.rules:
            if self.__check_rule(rule, task):
                rules.append(rule)
                if self.decision_table.hit_policy == HitPolicy.UNIQUE.value:
                    return rules
        return rules

    def result(self, task):
        """Returns the results of running this decision table against
        a given task."""
        result = {}
        matched_rules = self.decide(task)
        if self.decision_table.hit_policy == HitPolicy.COLLECT.value:
            # each output will be an array of values, all outputs will
            # be placed in a dict, which we will then merge.
            for rule in matched_rules:
                rule_output = rule.output_as_dict(task)
                for key in rule_output.keys():
                    if key not in result:
                        result[key] = []
                    result[key].append(rule_output[key])
        elif len(matched_rules) > 0:
            result = matched_rules[0].output_as_dict(task)
        return result

    def __check_rule(self, rule, task):
        for input_entry in rule.inputEntries:
            for lhs in input_entry.lhs:
                if lhs is not None:
                    input_val = DMNEngine.__get_input_val(input_entry, task.data)
                else:
                    input_val = None
                try:
                    if not self.evaluate(input_val, lhs, task):
                        return False
                except SpiffWorkflowException as se:
                    se.add_note(f"Rule failed on row {rule.row_number}")
                    raise se
                except Exception as e:
                    error = WorkflowTaskException(str(e), task=task, exception=e)
                    error.add_note(f"Failed to execute DMN Rule on row {rule.row_number}")
                    raise error
                else:
                    # Empty means ignore decision value
                    continue  # Check the other operators/columns
        return True

    def needs_eq(self, script_engine, text):
        try:
            # this should work if we can just do a straight equality
            script_engine.validate(text)
            return True
        except SyntaxError:
            # if we have problems parsing, then we introduce a variable on the left hand side
            # and try that and see if that parses. If so, then we know that we do not need to
            # introduce an equality operator later in the dmn
            script_engine.validate(f'v {text}')
            return False

    def evaluate(self, input_expr, match_expr, task):
        """
        Here we need to handle a few things such as if it is an equality or if
        the equality has already been taken care of. For now, we just assume
         it is equality.

         An optional task can be included if this is being executed in the
         context of a BPMN task.
        """
        if match_expr is None:
            return True

        script_engine = task.workflow.script_engine
        # NB - the question mark allows us to do a double ended test - for
        # example - our input expr is 5 and the match expr is 4 < ? < 6  -
        # this should evaluate as 4  < 5 < 6 and it should evaluate as 'True'
        # NOTE:  It should only do this replacement outside of quotes.
        # for example, provided "This thing?"  in quotes, it should not
        # do the replacement.
        match_expr = re.sub(r'(\?)(?=(?:[^\'"]|[\'"][^\'"]*[\'"])*$)', 'dmninputexpr', match_expr)
        if 'dmninputexpr' in match_expr:
            external_context = {
                'dmninputexpr': script_engine.evaluate(task, input_expr)
            }
            return script_engine.evaluate(task, match_expr,
                                          external_context=external_context)

        # The input expression just has to be something that can be parsed as is by the engine.
        script_engine.validate(input_expr)

        # If we get here, we need to check whether the match expression includes
        # an operator or if can use '=='
        needs_eq = self.needs_eq(script_engine, match_expr)
        # Disambiguate cases like a == 0 == True when we add '=='
        expr = f'({input_expr}) == ({match_expr})' if needs_eq else input_expr + match_expr
        return script_engine.evaluate(task, expr)

    @staticmethod
    def __get_input_val(input_entry, context):
        """
        The input of the decision method should be an expression,  but will
        fallback to the likely very bad idea of trying to use the label.

        :param inputEntry:
        :param context:  # A dictionary that provides some context/local vars.
        :return:
        """
        if input_entry.input.expression:
            return input_entry.input.expression
        else:
            # Backwards compatibility
            return "%r" % context[input_entry.input.label]


"""Definition of the Galleryfolder content type
"""

from zope.interface import implements

from Products.Archetypes import atapi
from Products.ATContentTypes.content import folder
from Products.ATContentTypes.content import schemata

# -*- Message Factory Imported Here -*-

from collective.ptg.galleryfolder.interfaces import IGalleryfolder
from collective.ptg.galleryfolder.config import PROJECTNAME

GalleryfolderSchema = folder.ATFolderSchema.copy() + atapi.Schema((

    # -*- Your Archetypes field definitions here ... -*-

))

# Set storage on fields copied from ATFolderSchema, making sure
# they work well with the python bridge properties.

GalleryfolderSchema['title'].storage = atapi.AnnotationStorage()
GalleryfolderSchema['description'].storage = atapi.AnnotationStorage()

schemata.finalizeATCTSchema(
    GalleryfolderSchema,
    folderish=True,
    moveDiscussion=False
)

class Galleryfolder(folder.ATFolder):
    """Gallery Content Type for Plone Truegallery"""
    implements(IGalleryfolder)

    meta_type = "Galleryfolder"
    schema = GalleryfolderSchema

    title = atapi.ATFieldProperty('title')
    description = atapi.ATFieldProperty('description')

    # -*- Your ATSchema to Python Property Bridges Here ... -*-

atapi.registerType(Galleryfolder, PROJECTNAME)


"""Creates database table with a defined schema if it does not already exist."""
import argparse
import os
import sys
import sqlite3

def get_schema(path):
    """read schema and strip \n, returning a single line string"""
    with open(path, "r") as schema:
        schema_text = schema.read()
    return schema_text.replace("\n", " ")

# Setup parser

parser = argparse.ArgumentParser(
    description="Create database table if it does not already exist."
)
parser.add_argument("-db", help="full path to a valid database")
parser.add_argument("-schema", help="full path to a schema file")

# script

args = parser.parse_args()

if not os.path.exists(args.schema):
    sys.exit(f"Schema file {args.schema} does not exist.")

schema = get_schema(args.schema)
con = sqlite3.connect(args.db)
try:
    con.execute(schema)
except Exception as e:
    print(f"Something went wrong. Exception:\n {e}")

sys.exit("Table created")


from django.urls import path

from . import views

urlpatterns = [
    path('doMonitor', views.doMonitor, name='doMonitor'),
    path('registeredPi', views.registeredPi, name='registeredPi'),
    path('addResponseDevice', views.addResponseDevice, name='addResponseDevice'),
    path('addSensor', views.addSensor, name='addSensor'),
]


#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class ComboBox(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_title("ComboBox")
        self.set_default_size(150, -1)
        self.connect("destroy", Gtk.main_quit)

        liststore = Gtk.ListStore(str)

        for item in ["Debian", "Fedora", "Tiny Core", "Linux Mint", "Mageia"]:
            liststore.append([item])

        combobox = Gtk.ComboBox()
        combobox.set_model(liststore)
        combobox.set_active(0)
        combobox.connect("changed", self.on_combobox_changed)
        self.add(combobox)

        cellrenderertext = Gtk.CellRendererText()
        combobox.pack_start(cellrenderertext, True)
        combobox.add_attribute(cellrenderertext, "text", 0)

    def on_combobox_changed(self, combobox):
        treeiter = combobox.get_active_iter()
        model = combobox.get_model()

        print("ComboBox selected item: %s" % (model[treeiter][0]))

window = ComboBox()
window.show_all()

Gtk.main()


import argparse
import gzip
import hashlib
import json
import logging
from pathlib import Path
from tqdm import tqdm

logging_fmt="%(asctime)s %(levelname)s: %(message)s"
logging.basicConfig(format=logging_fmt)
logger=logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)

def get_md5_hash(text:str)->str:
    return hashlib.md5(text.encode()).hexdigest()

def main(args):
    logger.info(args)

    wikipedia_data_filepath:str=args.wikipedia_data_filepath
    extract_root_dirname:str=args.extract_root_dirname

    extract_root_dir=Path(extract_root_dirname)
    extract_root_dir.mkdir(parents=True,exist_ok=True)

    logger.info("Wikipediaデータの行数を数えています...")

    num_wiki_data_lines=0
    with gzip.open(wikipedia_data_filepath,"r") as r:
        for line in r:
            num_wiki_data_lines+=1

    logger.info("行数: {}".format(num_wiki_data_lines))

    with gzip.open(wikipedia_data_filepath,"r") as r:
        for line in tqdm(r,total=num_wiki_data_lines):
            data=json.loads(line)

            title=data["title"]
            text=data["text"]

            title_hash=get_md5_hash(title)

            wiki_save_dir=extract_root_dir.joinpath(title_hash)
            wiki_save_dir.mkdir(exist_ok=True)

            title_file=wiki_save_dir.joinpath("title.txt")
            with title_file.open("w") as w:
                w.write(title)

            text_file=wiki_save_dir.joinpath("text.txt")
            with text_file.open("w") as w:
                w.write(text)

    logger.info("処理が完了しました")

if __name__=="__main__":
    parser=argparse.ArgumentParser()
    parser.add_argument("--wikipedia_data_filepath",type=str,default="../Data/all_entities.json.gz")
    parser.add_argument("--extract_root_dirname",type=str,default="../Data/Wikipedia")
    args=parser.parse_args()

    main(args)


import os
import configparser as cp

globals().update(os.environ)

frps_ini = cp.ConfigParser()
frps_ini.read('frps.ini', encoding='utf8')

for section in frps_ini.sections():
    for option in frps_ini.options(section):
        env_arg_str = f'{section}_{option}'.upper()
        if env_arg_str in globals():
            frps_ini[section][option] = eval(env_arg_str)

with open('frps.ini', 'w+', encoding='utf8') as ini_file:
    frps_ini.write(ini_file)


# https://www.acmicpc.net/problem/16724

# ===== 라이브러리 ===== #
from collections import Counter
import sys

# ===== 변수/상수 ===== #
input = sys.stdin.readline
LEFT, RIGHT, UP, DOWN = 'L', 'R', 'U', 'D'
dx = { 'L' : 0, 'R' : 0, 'U' : -1, 'D' : 1 }
dy = { 'L' : -1, 'R' : 1, 'U' : 0, 'D' : 0 }

# ===== 함수 ===== #
def find(target: int) -> int:
    if tree[target] == target: return target
    tree[target] = find(tree[target])
    return tree[target]

def union(u: int, v: int) -> None:
    u = find(u)
    v = find(v)
    if u != v: tree[u] = v

def xy_to_tree(x: int, y: int) -> int:
    return x * m + y

def union_area(x: int, y: int, c: str) -> None:
    tx, ty = x + dx[c], y + dy[c]
    if 0 <= tx < n and 0 <= ty < m:
        union(xy_to_tree(x, y), xy_to_tree(tx, ty))

# ===== 입력/초기화 ===== #
n, m = map(int, input().split())
arr = [list(input()) for _ in range(n)]
tree = [i for i in range(n * m)]

# ===== 메인 ===== #
for i in range(n):
    for j in range(m):
        union_area(i, j, arr[i][j])

for i in range(n * m):
    tree[i] = find(tree[i])

# ===== 출력 ===== #
print(len(Counter(tree)))


import numpy as np
import sys
import matplotlib.pyplot as plt
from matplotlib import style
style.use("ggplot")

filename = "abalone.data.txt"
# x and y coordinates, whitespace-separated
X = np.loadtxt( filename, delimiter=',', usecols=(2,4) )
model = 5.1 * X[:,0] ** 2

plt.scatter(X[:, 0],X[:, 1], marker = 'o', s=150, alpha = 0.5,label='Observed')
plt.scatter(X[:, 0],model,marker='.',color='blue',label=r'Model: W=5.1D$^2$ ')
plt.xlabel('D')
plt.ylabel('W')
plt.legend()

plt.savefig("abalone.png")


'''
in degree array
Kahn's Algorithm
'''

from collections import deque

def _get_adj_list(n, edges):
    adj_list = [[] for _ in range(n)]
    in_degree = [0] * n
    for from_v, to_v in edges:
        adj_list[from_v].append(to_v)
        in_degree[to_v] += 1
    return adj_list, in_degree

def topo_sort_bfs(n, edges):
    adj_list, in_degree = _get_adj_list(n, edges)
    result = []
    queue = deque()
    _fill_queue(queue, in_degree)
    while queue:
        current = queue.popleft()
        result.append(current)
        _update_indegree(current, adj_list, in_degree)
        _fill_queue(queue, in_degree)
    if _is_cycle_present(in_degree):
        return []
    else:
        return result

def _is_cycle_present(in_degree):
    for num in in_degree:
        if num >= 0:
            return True
    return False

def _update_indegree(vertex, adj_list, in_degree):
    for adj_vertex in adj_list[vertex]:
        in_degree[adj_vertex] -= 1

def _fill_queue(queue, in_degree):
    for idx in range(len(in_degree)):
        if in_degree[idx] == 0:
            queue.append(idx)
            in_degree[idx] -= 1

n = 6
edges = [[5, 0], [4, 0], [5, 2], [4, 1], [2, 3], [3, 1]]
print(topo_sort_bfs(n, edges))

# cycle
n = 4
edges = [[0, 1], [1, 2], [2, 3], [3, 1]]
print(topo_sort_bfs(n, edges))


import numpy as np
import pandas as pd
import ntpath
import logging

import wx
import wx.grid as gridlib
#import wx.lib.inspection

from lims.plugins.plugin_collection import PluginCollection
import lims.result

EVEN_ROW_COLOUR = '#CCE6FF'
GRID_LINE_COLOUR = '#ccc'

class DataTable(wx.grid.GridTableBase):
    def __init__(self, data=None):
        wx.grid.GridTableBase.__init__(self)
        self.headerRows = 1
        if data is None:
            data = pd.DataFrame()
        self.data = data

    def GetNumberRows(self):
        return len(self.data)

    def GetNumberCols(self):
        return len(self.data.columns) + 1

    def GetValue(self, row, col):
        if col == 0:
            return self.data.index[row]
        return self.data.iloc[row, col - 1]

    def SetValue(self, row, col, value):
        self.data.iloc[row, col - 1] = value

    def GetColLabelValue(self, col):
        if col == 0:
            if self.data.index.name is None:
                return 'Index'
            else:
                return self.data.index.name
        return str(self.data.columns[col - 1])

    def GetTypeName(self, row, col):
        return wx.grid.GRID_VALUE_STRING

    def GetAttr(self, row, col, prop):
        attr = wx.grid.GridCellAttr()
        if row % 2 == 1:
            attr.SetBackgroundColour(EVEN_ROW_COLOUR)
        return attr

class DataGrid(gridlib.Grid):
    def __init__(self, parent, size=wx.Size(1000, 500)):
        self.parent = parent
        gridlib.Grid.__init__(self, self.parent, -1)
        self.SetGridLineColour(GRID_LINE_COLOUR)
        self.SetRowLabelSize(0)
        self.SetColLabelSize(30)
        self.table = DataTable()

class LIMS(wx.Frame):

    def __init__(self, parent, title):
        super(LIMS, self).__init__(parent, title=title, size=wx.Size(1025, 650))

        self.data = None
        self.gbs = None
        self.grid = None
        self.tc_input = None
        self.tc_id = None
        self.tc_name = None
        self.tc_desc = None
        self.tc_file_type = None
        self.cb_proc = None
        self.processors = {}
        self.processor_names = []

        self.get_processors()
        self.InitUI()
        self.Layout()
        self.Centre()
        self.Show()

    def create_grid(self, panel, data):
        table = DataTable(data)
        grid = DataGrid(panel)
        grid.CreateGrid(len(data), len(data.columns))
        grid.SetTable(table)
        grid.AutoSize()
        grid.AutoSizeColumns(True)
        return grid

    def get_processors(self):
        plugins = PluginCollection('lims.processors')
        for proc in plugins.plugins:
            self.processors[proc.name] = proc
            self.processor_names.append(proc.name)

    def InitUI(self):

        #self.SetSize(wx.Size(500, 500))
        processors = ["AAAA", "BBBB", "CCCC"]

        panel = wx.Panel(self, name="MainPanel")
        #self.data_grid = self.create_grid(panel, self.data)

        hbox = wx.BoxSizer(wx.HORIZONTAL)

        #fgs = wx.FlexGridSizer(5, 5, 9, 35)
        gbs = wx.GridBagSizer(9, 30)
        self.gbs = gbs

        stat_txt1 = wx.StaticText(panel, label='')
        #stat_txt2 = wx.StaticText(panel, label='')
        stat_txt3 = wx.StaticText(panel, label='')
        stat_txt3b = wx.StaticText(panel, label='')
        stat_txt4 = wx.StaticText(panel, label='')
        stat_txt4b = wx.StaticText(panel, label='')
        #stat_txt5 = wx.StaticText(panel, label='')

        #Row 1
        lbl_processor = wx.StaticText(panel, label="Processor")
        #tc_proc = wx.TextCtrl(panel, wx.EXPAND)
        self.cb_proc = wx.Choice(panel, wx.EXPAND, choices = self.processor_names)
        self.Bind(wx.EVT_CHOICE , self.on_select_combo, self.cb_proc)
        gbs.Add(lbl_processor, pos=(0,0),flag=wx.EXPAND)
        #gbs.Add(tc_proc, pos=(0,1),flag=wx.EXPAND)
        gbs.Add(self.cb_proc, pos=(0,1),flag=wx.EXPAND)

        gbs.Add(stat_txt1, pos=(0,2),flag=wx.EXPAND)

        lbl_id = wx.StaticText(panel, label="ID:")
        self.tc_id = wx.TextCtrl(panel, wx.EXPAND)
        self.tc_id.SetEditable(False)
        gbs.Add(lbl_id, pos=(0,3),flag=wx.EXPAND)
        gbs.Add(self.tc_id, pos=(0,4),flag=wx.EXPAND)

        #Row 2
        lbl_input = wx.StaticText(panel, label="Input File")
        self.tc_input = wx.TextCtrl(panel)
        btn_select_file = wx.Button(panel, wx.ID_ANY, '...')
        gbs.Add(lbl_input, pos=(1,0),flag=wx.EXPAND)
        gbs.Add(self.tc_input, pos=(1,1),flag=wx.EXPAND)

        #gbs.Add(stat_txt2, pos=(1,2),flag=wx.EXPAND)
        gbs.Add(btn_select_file, pos=(1,2),flag=wx.EXPAND)
        self.Bind(wx.EVT_BUTTON, self.on_select_file, btn_select_file)

        lbl_name = wx.StaticText(panel, label="Name:")
        self.tc_name = wx.TextCtrl(panel)
        self.tc_name.SetEditable(False)
        gbs.Add(lbl_name, pos=(1,3),flag=wx.EXPAND)
        gbs.Add(self.tc_name, pos=(1,4),flag=wx.EXPAND)

        #Row 3
        gbs.Add(stat_txt3, pos=(2,0),flag=wx.EXPAND)
        btn_run = wx.Button(panel, wx.ID_ANY, 'Run')
        self.Bind(wx.EVT_BUTTON, self.on_run, btn_run)
        gbs.Add(btn_run, pos=(2,1),flag=wx.EXPAND)

        gbs.Add(stat_txt3b, pos=(2,2),flag=wx.EXPAND)

        lbl_desc = wx.StaticText(panel, label="Description:")
        self.tc_desc = wx.TextCtrl(panel)
        self.tc_desc.SetEditable(False)
        gbs.Add(lbl_desc, pos=(2,3),flag=wx.EXPAND)
        gbs.Add(self.tc_desc, pos=(2,4),flag=wx.EXPAND)

        #Row 4
        gbs.Add(stat_txt4, pos=(3,0),flag=wx.EXPAND)
        btn_save = wx.Button(panel, wx.ID_ANY, 'Save')
        self.Bind(wx.EVT_BUTTON, self.on_save, btn_save)
        gbs.Add(btn_save, pos=(3,1),flag=wx.EXPAND)

        gbs.Add(stat_txt4b, pos=(3,2),flag=wx.EXPAND)

        lbl_file_type = wx.StaticText(panel, label="File Type:")
        self.tc_file_type = wx.TextCtrl(panel)
        self.tc_file_type.SetEditable(False)
        gbs.Add(lbl_file_type, pos=(3,3),flag=wx.EXPAND)
        gbs.Add(self.tc_file_type, pos=(3,4),flag=wx.EXPAND)

        self.grid = wx.grid.Grid(panel, -1, size= wx.Size(900, 400), name="DataGrid")

        gbs.Add(self.grid, pos=(4,0), span = (1, 5), flag= wx.SYS_VSCROLL_X | wx.SYS_HSCROLL_Y)

        #hbox.Add(gbs, proportion=1, flag=wx.ALL, border=15)
        #panel.SetSizer(hbox)

        self.CreateStatusBar()
        self.SetStatusText("")

        self.set_empty_table()

    def on_select_file(self, event):
        with wx.FileDialog(self, "Select instrument file", wildcard="All file (*.*)|*.*",
                       style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:

            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return     # the user changed their mind

            # Proceed loading the file chosen by the user
            pathname = fileDialog.GetPath()
            file_name = ntpath.basename(pathname)
            self.tc_input.SetValue(pathname)

    def on_select_combo(self, event):
        print("Combobox handler")
        idx = self.cb_proc.GetSelection()
        proc_name = self.cb_proc.GetString(idx)
        print("Processor: " + proc_name)
        if self.processors is not None:
            for key, proc in self.processors.items():
                if proc.name == proc_name:
                    self.tc_name.SetValue(proc.name)
                    self.tc_desc.SetValue(proc.description)
                    self.tc_file_type.SetValue(proc.file_type)

    def on_run(self, event):

        idx = self.cb_proc.GetSelection()
        proc_name = self.cb_proc.GetString(idx)

        file = self.tc_input.GetValue()
        if proc_name == '':
            return

        if self.processors is not None:
            proc = self.processors[proc_name]
            result = proc.execute(file)

        print('onOK handler')
        #item = self.gbs.FindItemAtPosition((4,0))
        #if self.grid != None:
        #    self.gbs.Hide(self.grid)

        #df = pd.DataFrame(np.random.random((100, 10)))
        df = result.df
        df.to_excel(result.table_name +".xlsx", index=False)
        table = DataTable(df)

        self.grid.SetTable(table, takeOwnership=True)
        self.grid.AutoSizeColumns()

        self.gbs.Layout()
        self.Layout()

    def on_save(self, event):
        ival = 1

    def set_empty_table(self):
        data = {'Aliquot':[''],
            	'Analyte Identifier':[''],
                'Measured Value':[''],
                'Units':[''],
                'Dilution Factor':[''],
                'Analysis Date/Time':[''],
                'Comment':[''],
                'Description':[''],
                'User Defined 1':[''],
                'User Defined 2':[''],
                'User Defined 3':[''],
                'User Defined 4':[''],
                'User Defined 5':[''],
                'User Defined 6':[''],
                'User Defined 7':[''],
                'User Defined 8':[''],
                'User Defined 9':[''],
                'User Defined 10':[''],
                'User Defined 11':[''],
                'User Defined 12':[''],
                'User Defined 13':[''],
                'User Defined 14':[''],
                'User Defined 15':[''],
                'User Defined 16':[''],
                'User Defined 17':[''],
                'User Defined 18':[''],
                'User Defined 19':[''],
                'User Defined 20':['']
        }
        df = pd.DataFrame(data)
        table = DataTable(df)
        self.grid.SetTable(table, takeOwnership=True)
        self.grid.AutoSizeColumns()

        self.gbs.Layout()
        self.Layout()
        return table

def main():

    logger = logging.getLogger("LIMS_Run_Processor")
    f_handler = logging.FileHandler('file.log',mode='a')
    f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S')
    f_handler.setFormatter(f_format)
    logger.addHandler(f_handler)

    app = wx.App()
    ex = LIMS(None, title='Laboratory Information Management System')
    ex.Show()
    #wx.lib.inspection.InspectionTool().Show()
    app.MainLoop()

if __name__ == '__main__':
    main()


"""
Database class
"""
import os
from ase.db import connect

def make_entry_from_CSD(code):
    """
    make entry dictionary from CSD codes

    Args:
        code: a list of CSD codes
    """
    from pyxtal.msg import CSDError
    from pyxtal import pyxtal
    from rdkit.Chem.Descriptors import ExactMolWt
    from rdkit.Chem.rdMolDescriptors import CalcMolFormula
    from rdkit import Chem

    url0 = "https://www.ccdc.cam.ac.uk/structures/Search?Ccdcid="
    xtal = pyxtal(molecular=True)
    try:
        xtal.from_CSD(code)
    except CSDError as e:
        print("CSDError", code, e.message)
    if xtal.valid:
        m = Chem.MolFromSmiles(xtal.tag['smiles'])
        mol_wt = ExactMolWt(m)
        mol_formula = CalcMolFormula(m)
        kvp = {
                "csd_code": xtal.tag['csd_code'],
                "mol_smi": xtal.tag['smiles'],
                "ccdc_number": xtal.tag['ccdc_number'],
                "space_group": xtal.group.symbol,
                "spg_num": xtal.group.number,
                "Z": sum(xtal.numMols),
                "Zprime": xtal.get_zprime()[0],
                "url": url0 + str(xtal.tag['ccdc_number']),
                "mol_formula": mol_formula,
                "mol_weight": mol_wt,
                "mol_name": xtal.tag['csd_code'],
                "l_type": xtal.lattice.ltype,
              }
        entry = (xtal.to_ase(), kvp, None)
        return entry
    else:
        return None

def make_db_from_CSD(dbname, codes):
    """
    make database from CSD codes

    Args:
        dbname: db file name
        codes: a list of CSD codes
    """
    # open
    db = database(dbname)

    # add structure
    for i, code in enumerate(codes):
        entry = make_entry_from_CSD(code)
        if entry is not None:
            db.add(entry)
            print(i, code)

class database():
    """
    This is a database class to process crystal data

    Args:
        db_name: *.db format from ase database
    """

    def __init__(self, db_name):
        self.db_name = db_name
        #if not os.path.exists(db_name):
        #    raise ValueError(db_name, 'doesnot exist')

        self.db = connect(db_name)
        self.get_all_codes()
        self.keys = ['csd_code', 'space_group', 'spg_num',
                     'Z', 'Zprime', 'url', 'mol_name',
                     'mol_smi', 'mol_formula', 'mol_weight',
                     'l_type',
                    ]
        self.calculators = ['charmm',
                            'gulp',
                            'ani',
                            'dftb_D3',
                            'dftb_TS',
                           ]

    def vacuum(self):
        self.db.vacuum()

    def get_all_codes(self):
        codes = []
        for row in self.db.select():
            if row.csd_code not in codes:
                codes.append(row.csd_code)
            else:
                print('find duplicate! remove', row.csd_code)
                self.db.delete(row.id)
        self.codes = codes

    def add(self, entry):
        (atom, kvp, data) = entry
        if kvp['csd_code'] not in self.codes:
            kvp0 = self.process_kvp(kvp)
            self.db.write(atom, key_value_pairs=kvp0, data=data)
            self.codes.append(kvp['csd_code'])

    def add_from_code(self, code):
        entry = make_entry_from_CSD(code)
        if entry is not None:
            self.add(entry)
        else:
            print("{:s} is not a valid entry".format(code))

    def process_kvp(self, kvp):
        kvp0 = {}
        for key in self.keys:
            if key in kvp:
                kvp0[key] = kvp[key]
            else:
                print('Error, cannot find ', key, ' from the input')
                return
        return kvp0

    def check_status(self, show=False):
        """
        Check the current status of each entry
        """
        ids = []
        for row in self.db.select():
            if len(row.data.keys())==len(self.calculators):
                ids.append(row.id)
                if show:
                    row_info = self.get_row_info(id=row.id)
                    self.view(row_info)
            else:
                print(row.csd_code) #, row.data['charmm_info']['prm'])
        return ids

    def copy(self, db_name, csd_codes):
        """
        copy the entries to another db

        Args:
            db_name: db file name
            csd_codes: list of codes
        """
        if db_name == self.db_name:
            raise RuntimeError('Cannot use the same db file for copy')
        with connect(db_name) as db:
            for csd_code in csd_codes:
                row_info = self.get_row_info(code=csd_code)
                (atom, kvp, data) = row_info
                db.write(atom, key_value_pairs=kvp, data=data)

    def view(self, row_info):
        """
        print the summary of benchmark results

        Args:
            row: row object
        """
        from pyxtal import pyxtal
        from pyxtal.util import ase2pymatgen
        from pyxtal.representation import representation
        from pyxtal.msg import ReadSeedError

        (atom, kvp, data) = row_info

        #Reference
        xtal = self.get_pyxtal(kvp['csd_code'])
        rep = xtal.get_1D_representation()
        print('\n', kvp['csd_code'], kvp['mol_smi'], xtal.lattice.volume)
        print(rep.to_string() + ' reference')

        #calcs
        for key in data.keys():
            calc = key[:-5]
            time = data[key]['time']

            rep = data[key]['rep']
            if type(rep[0]) is not list: rep = [rep]
            rep = representation(rep, kvp['mol_smi']).to_string()

            (dv, msd1, msd2) = data[key]['diff']
            strs = "{:s} {:8s} {:6.2f} {:6.3f}".format(rep, calc, time/60, dv)
            if msd1 is not None:
                strs += "{:6.3f}{:6.3f}".format(msd1, msd2)
            print(strs)

    def get_row_info(self, id=None, code=None):
        match = False
        if id is not None:
            for row in self.db.select(id=id):
                match = True
                break
        elif code is not None:
            for row in self.db.select(csd_code=code):
                match = True
                break
        if match:

            kvp = {}
            for key in self.keys:
                kvp[key] = row.key_value_pairs[key]

            data0 = {}
            for calc in self.calculators:
                key = calc + '_info'
                if key in row.data.keys():
                    data0[key] = row.data[key]

            atom = self.db.get_atoms(id=row.id)
            return (atom, kvp, data0)
        else:
            msg = 'cannot find the entry from ' + id + code
            raise RuntimeError(msg)

    def get_row(self, code):
        for row in self.db.select(csd_code=code):
            return row
        msg = 'cannot find the entry from ' + code
        raise RuntimeError(msg)

    def get_pyxtal(self, code):
        from pyxtal import pyxtal
        from pyxtal.util import ase2pymatgen
        from pyxtal.msg import ReadSeedError

        row = self.get_row(code)
        atom = self.db.get_atoms(id=row.id)
        #Reference
        pmg = ase2pymatgen(atom)
        smi = row.mol_smi
        smiles = smi.split('.')
        molecules = [smile+'.smi' for smile in smiles]

        xtal = pyxtal(molecular=True)
        try:
            xtal.from_seed(pmg, molecules=molecules)
        except ReadSeedError:
            xtal.from_seed(pmg, molecules=molecules, add_H=True)

        return xtal

    def compute(self, row, work_dir, skf_dir):
        if len(row.data.keys())<len(self.calculators):
            #not label information, run antechamber
            atom = self.db.get_atoms(id=row.id)
            if 'gulp_info' not in row.data.keys():
                pmg, c_info, g_info = get_parameters(row, atom)
                row.data = {'charmm_info': c_info,
                            'gulp_info': g_info
                           }
            else:
                pmg = ase2pymatgen(atom)

            data = compute(row, pmg, work_dir, skf_dir)
            self.db.update(row.id, data=data)
            print('updated the data for', row.csd_code)

if __name__ == "__main__":
    # open
    db = database('test.db')
    print("Total number of entries", len(db.codes))

    # view structure
    c = db.get_pyxtal('HXMTAM')
    print(c)

{'pyxtal': 'pyxtal.pyxtal', 'ase2pymatgen': 'pyxtal.util.ase2pymatgen', 'representation': 'pyxtal.representation.representation', 'ReadSeedError': 'pyxtal.msg.ReadSeedError'}


"""added sos_med1 relationship

Revision ID: 1b537bf709ce
Revises: a05bc3ddcd23
Create Date: 2023-01-27 18:44:16.429531

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '1b537bf709ce'
down_revision = 'a05bc3ddcd23'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('user', schema=None) as batch_op:
        batch_op.add_column(sa.Column('sos_med1', sa.Integer(), nullable=True))
        batch_op.create_foreign_key(batch_op.f('fk_user_sos_med1_lib_med'), 'lib_med', ['sos_med1'], ['id'])

    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('user', schema=None) as batch_op:
        batch_op.drop_constraint(batch_op.f('fk_user_sos_med1_lib_med'), type_='foreignkey')
        batch_op.drop_column('sos_med1')

    # ### end Alembic commands ###


import json
import os

def get_setting():
    path_utils = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    path_root = os.path.dirname(os.path.dirname(path_utils))
    path_conf = os.path.join(path_root, '.conf')
    path_file_settings_local = os.path.join(path_conf, 'settings_local.json')
    with open(path_file_settings_local, 'r') as f:
        config_str = f.read()
    config = json.loads(config_str)
    return config


#!/bin/python
# -*- coding: UTF-8 -*-

import torch
import torch.nn as nn
from torch.distributions.categorical import Categorical
from torch.optim import Adam
import numpy as np
import gym
from gym.spaces import Discrete, Box
import sys
import json
import pdb
import os
import gym_arc
import time
sys.path.append('./gym_arc/envs/')
from config import LR, EPOCHS, batch_size, RENDER, MODEL, INPUT_FILE, STEPS_LIMIT, DECAY, FILE_ID, device, action_model

# soft-ac, ppo
# 怎样优化重复动作，无意义动作
# 找最核心特征
# 适配所有题目，看是否泛化

def generate_model(feature_num, action_num):
    hidden_size = 82

    net = nn.Sequential(
        nn.Linear(feature_num, hidden_size),
        nn.Dropout(0.3),
        nn.ReLU(),
        nn.Linear(hidden_size, hidden_size),
        nn.Dropout(0.3),
        nn.ReLU(),
        nn.Linear(hidden_size, hidden_size),
        nn.Dropout(0.3),
        nn.ReLU(),
        nn.Linear(hidden_size, action_num),
        nn.Softmax()
    )

    for layer in net:
        if isinstance(layer, nn.Linear):
            nn.init.xavier_uniform(layer.weight)

    return net

def get_categorical(model, obs):
    model.eval()
    probs = model(obs)
    return Categorical(probs=probs)

def get_action(model, obs):
    return get_categorical(model, obs).sample().item()

def compute_loss(model, obs, action, weights):
    logp = get_categorical(model, obs).log_prob(action)
    return -(logp * weights).mean()

def train():
    with open(INPUT_FILE, 'r') as f:
        puzzle = json.load(f)

    envs = []
    env_idx = 0

    for i in range(len(puzzle['train'])):
        p = puzzle['train'][i]
        e = gym.make('arc-v0', input=p['input'], output=p['output'], need_ui=RENDER, action_mode='single')
        envs.append(e)

    #envs = envs[:1]
    #pdb.set_trace()

    test_input = puzzle['test'][0]['input']
    test_output = puzzle['test'][0]['output']
    env_test = gym.make('arc-v0', input=test_input, output=test_output, need_ui=RENDER, action_mode='single')

    n_feature = env_test.observation_space.shape[0]
    n_acts = env_test.action_space.n
    print('feature(%d) actions(%d)' % (n_feature, n_acts))

    #
    if (MODEL == ''):
        net = generate_model(n_feature, n_acts)
        net.train()
    else:
        net = torch.load(MODEL)
        envs.append(env_test)
        print(envs)
        net.eval()

    net.to(device)

    optimizer = Adam(net.parameters(), lr=LR)

    for epoch_idx in range(EPOCHS):
        batch_obs = []
        batch_acts = []
        batch_weights = []
        rewards = []

        env = envs[0]
        obs = env.reset()
        steps = 0

        while True:
            steps += 1

            if RENDER: env.render()

            act = get_action(net, torch.as_tensor(obs, dtype = torch.float32).to(device))
            next_obs, r, done, info = env.step(act)

            if (steps >= STEPS_LIMIT):
                done = True

            batch_acts.append(act)
            batch_obs.append(obs)
            rewards.append(r)

            obs = next_obs

            #time.sleep(5)

            if done:
                print('epoch_idx:%4d %100s     ----> %2.1f\t env:%2d' % (epoch_idx, info['steps'][:20], info['total_reward'], env_idx))

                if (len(envs) > 1):
                    env_idx = (env_idx + 1) % len(envs)
                    env = envs[env_idx]

                returns = [0] * len(rewards)
                acc_rewards = 0
                for i in reversed(range(len(rewards))):
                    acc_rewards = rewards[i] + DECAY * acc_rewards
                    returns[i] = acc_rewards
                batch_weights += returns

                obs, done, rewards, steps = env.reset(), False, [], 0

                if len(batch_obs) > batch_size:
                    break

        if (MODEL == ''):
            net.train()
            optimizer.zero_grad()
            print('----------------------------- learning --------------------------')
            loss = compute_loss(net,
                                    torch.as_tensor(batch_obs, dtype = torch.float32).to(device),
                                    torch.as_tensor(batch_acts, dtype = torch.int32).to(device),
                                    torch.as_tensor(batch_weights, dtype = torch.float32).to(device)
                                    )

            loss.backward()
            optimizer.step()

            if (epoch_idx % 20 == 0):
                torch.save(net, ('./result/%s_%4d.model' % (FILE_ID, epoch_idx)))

if __name__ == '__main__':
    train()