#!/usr/bin/env python

'''
camera calibration for distorted images with chess board samples
reads distorted images, calculates the calibration and write undistorted images

usage:
    calibration.py [--debug <output path>] [--square_size] [<image mask>]

default values:

    --debug:    ./output/
    --square_size: 1.0
    --pattern_size
    <image mask> '../yourdatafolder/img_name*.imgformat'
                 example '../data/left*.jpg'

This version is adapted from samples of opencv calibrate.py
'''

# Python 2/3 compatibility
from __future__ import print_function

import numpy as np
import cv2

print(cv2.__version__)

# local modules
from common import splitfn

# built-in modules
import os

if __name__ == '__main__':
    import sys
    import getopt
    from glob import glob

    args, img_mask = getopt.getopt(sys.argv[1:], '', ['debug=', 'square_size='])
    args = dict(args)
    args.setdefault('--debug', './output/')
    args.setdefault('--square_size', 1.0)
    # args.setdefault('--size_1', 9)
    # args.setdefault('--size_2', 6)

    if not img_mask:
        raise ValueError('no image has been found')
    else:
        img_mask = img_mask[0]

    img_names = glob(img_mask)
    debug_dir = args.get('--debug')
    if not os.path.isdir(debug_dir):
        os.mkdir(debug_dir)
    square_size = float(args.get('--square_size'))

    pattern_size = (7, 5)
    pattern_points = np.zeros((np.prod(pattern_size), 3), np.float32)
    pattern_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2)
    pattern_points *= square_size

    obj_points = []
    img_points = []
    h, w = 0, 0
    img_names_undistort = []
    print(img_names)
    print('starting the process...')
    print ('number of images {}'.format(np.shape(img_names)))
    img_names2 = img_names[::15]
    for fn in img_names2:
        print('processing %s... ' % fn, end='')
        img = cv2.imread(fn, 0)
        if img is None:
            print("Failed to load", fn)
            continue

        h, w = img.shape[:2]
        found, corners = cv2.findChessboardCorners(img, pattern_size)
        if found:
            term = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1)
            cv2.cornerSubPix(img, corners, (5, 5), (-1, -1), term)

        if (debug_dir):
            vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
            cv2.drawChessboardCorners(vis, pattern_size, corners, found)
            path, name, ext = splitfn(fn)
            outfile = debug_dir + name + '_chess.tiff'
            cv2.imwrite(outfile, vis)

            if found:
                img_names_undistort.append(debug_dir + name)

        if not found:
            print('chessboard not found')
            continue

        img_points.append(corners.reshape(-1, 2))
        obj_points.append(pattern_points)

        print('ok')

    # calculate camera distortion
    print (np.shape(obj_points))
    print (np.shape(img_points))
    rvecs = []
    tvecs = []
    obj_points_array = np.float32(np.asarray(obj_points))
    img_points_array = np.float32(np.asarray(img_points))

    print (obj_points[0][0])
    print (obj_points_array.dtype)

    rms, camera_matrix, dist_coefs, rvecs, tvecs = cv2.fisheye.calibrate(
        obj_points, img_points, (w, h), None, None)

    print("\nRMS:", rms)
    print("camera matrix:\n", camera_matrix)
    print("distortion coefficients: ", dist_coefs.ravel())

    # undistort the image with the calibration
    print('')
    for fn in img_names:
        img = cv2.imread(fn, 0)
        h, w = img.shape[:2]
        newcameramtx, roi = cv2.getOptimalNewCameraMatrix(
            camera_matrix, dist_coefs, (w, h), 1, (w, h))

        dst = cv2.fisheye.undistortImage(img, camera_matrix, dist_coefs, None, newcameramtx)

        # crop and save the image
        #x, y, w, h = roi
        #dst = dst[y:y+h, x:x+w]
        path, name, ext = splitfn(fn)
        outfile = debug_dir + name + '_undistorted.jpg'
        print('Undistorted image written to: %s' % outfile)
        cv2.imwrite(outfile, dst)

   # cv2.destroyAllWindows()


import re

from periscope.models.matrix import Matrix, RowReader
from periscope.models.value import EmptyValue, FloatValue, IntValue, DateValue

_FLOAT_PATTERN = re.compile(r"\d+\.\d*([Ee]\-?\d+)?")
_INT_PATTERN = re.compile(r"\d*([Ee]\-?\d+)?")

def parse_csv(file_, separator):
    m = Matrix()
    for line in file_:
        if line.startswith('#'):
            continue

        m.add_row([field.strip() for field in line.split(separator)])
    return m

class CsvRowReader(RowReader):
    def __init__(self, file_, separator, encoding=None):
        self._file = file_
        self._separator = separator
        self._encoding = encoding

    def __enter__(self):
        self._file.__enter__()
        self._file.seek(0)
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._file.__exit__(exc_type, exc_val, exc_tb)

    def __iter__(self):
        return self

    def __next__(self):
        line = next(self._file)

        if self._encoding is not None:
            line = line.decode(self._encoding)

        if line.startswith('#'):
            return next(self)
        else:
            return [s.strip() for s in line.split(self._separator)]


import cv2
import threading
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtGui
from PyQt5 import QtCore
from PyQt5 import uic
from PyQt5.QtWidgets import *

form_class=uic.loadUiType("MyEvent.ui")[0]

class MyWindow(QDialog, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.initUI()

    def initUI(self):
        self.setWindowTitle("파일 오픈")
        self.pushButton.clicked.connect(self.fileopen)
        self.startButton.clicked.connect(self.start)

    def fileopen(self):
        global filename, FILE
        filename= QtWidgets.QFileDialog.getOpenFileName(self,'Open File')
        self.lineEdit.setText(filename[0])
        FILE = filename[0]
        print(FILE)

    def start(self):
        global FILE
        print(FILE)

if __name__=="__main__":
    app = QApplication(sys.argv)
    myWindow = MyWindow()
    myWindow.show()
    app.exec_()


import torch
import torch.nn as nn
from torch.utils.data import DataLoader
import os
from dataset import Data_ganerator
import importlib
from face_decoder import Face_Decoder
from face_decoder import VGG_Model
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import torchvision.transforms as transforms
import cv2

unloader = transforms.ToPILImage()
transform1 = transforms.Compose([transforms.ToTensor()])

def load_image( image_dir):
    image = Image.open(image_dir).convert('RGB')
    if image.size != (224, 224):
        image = image.resize((224, 224), resample=Image.BILINEAR)
    image = transform1(image)
    print('1111111111111111111', image)
    return image

def test():
    L1 = nn.PairwiseDistance(1)
    L2 = nn.PairwiseDistance(2)
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

    print('Load pretrained model')
    net1 = VGG_Model().to(device)
    checkpoint = torch.load('E:/PycharmProjects/facedecoder/vgg_face_dag.pth', map_location='cpu')
    net1.load_state_dict(checkpoint)
    for para in net1.parameters():
        para.requires_grad = False
    net1.eval()

    image1 = load_image(r'E:\PycharmProjects\result\f2f\f2f3.jpg')
    image2 = load_image(r'D:\BaiduNetdiskDownload\s2fTrueFace\s2fTrueFace\3.jpg')
    image1.unsqueeze_(0)
    image2.unsqueeze_(0)
    print(image1.shape)
    feat_7, _ = net1(image1)
    feat_71, _ = net1(image2)
    print('111111111')
    print(L1(feat_7,feat_71))
    print(L2(feat_7, feat_71))

if __name__ == '__main__':
    test()


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

EPS = 3e-1

def init_weights(size):
    v = 1. / np.sqrt(size[0])
    return torch.Tensor(size).uniform_(-v, v)

def LeakyReLU(x):
    return F.leaky_relu(x, 0.1)

class ActorNN(nn.Module) :
    def __init__(self,state_dim=3,action_dim=2,action_scaler=1.0,HER=False,actfn=LeakyReLU, use_cuda=False ) :
        super(ActorNN,self).__init__()

        self.state_dim = state_dim
        self.action_dim = action_dim
        self.action_scaler = action_scaler

        self.HER = HER
        if self.HER :
            self.state_dim *= 2

        self.actfn = actfn
        #Features :
        self.featx = nn.Linear(self.state_dim,400)
        self.featx.weight.data = init_weights(self.featx.weight.data.size())

        # Actor network :
        self.actor1 = nn.Linear(400,300)
        self.actor1.weight.data.uniform_(-EPS,EPS)
        self.actor2 = nn.Linear(300,self.action_dim)
        self.actor2.weight.data.uniform_(-EPS,EPS)

        self.use_cuda = use_cuda
        if self.use_cuda :
            self = self.cuda()

    def features(self,x) :
        fx = self.actfn( self.featx( x) )
        # batch x 400
        return fx

    def forward(self, x) :
        fx = self.features(x)
        # batch x 400
        out = self.actfn( self.actor1( fx ) )
        # batch x 300
        out = self.actor2( fx )
        # batch x self.action_dim

        #scale the actions :
        unscaled = F.tanh(xx)
        scaled = unscaled * self.action_scaler
        return scaled

    def clone(self):
        cloned = ActorNN(state_dim=self.state_dim,action_dim=self.action_dim,action_scaler=self.action_scaler,CNN=self.CNN,HER=self.HER,actfn=self.actfn, use_cuda=self.use_cuda)
        cloned.load_state_dict( self.state_dict() )
        return cloned

class CriticNN(nn.Module) :
    def __init__(self,state_dim=3,action_dim=2,HER=False,actfn=LeakyReLU, use_cuda=False  ) :
        super(CriticNN,self).__init__()

        self.state_dim = state_dim
        self.action_dim = action_dim

        self.HER = HER
        if self.HER :
            self.state_dim *= 2

        self.actfn = actfn

        #Features :
        self.featx = nn.Linear(self.state_dim,400)
        self.featx.weight.data = init_weights(self.featx.weight.data.size())

        # Critic network :
        ## state value path :
        self.critic1 = nn.Linear(400+self.action_dim,300)
        self.critic1.weight.data = init_weights(self.critic1.weight.data.size())

        self.critic2 = nn.Linear(300,1)
        self.critic2.weight.data.uniform_(-EPS*1e-1,EPS*1e-1)

        self.use_cuda = use_cuda
        if self.use_cuda :
            self = self.cuda()

    def features(self,x) :
        fx = self.actfn( self.featx(x) )
        # batch x 400

        return fx

    def forward(self, x,a) :
        fx = self.features(x)
        # batch x 400
        concat = torch.cat([ fx, a], dim=1)
        # batch x 400+self.action_dim
        out = self.actfn( self.critic1( concat ) )
        # batch x 300
        out = self.critic2(out)
        # batch x 1
        return out

    def clone(self):
        cloned = CriticNN(state_dim=self.state_dim,action_dim=self.action_dim,CNN=self.CNN,HER=self.HER,actfn=self.actfn, use_cuda=self.use_cuda)
        cloned.load_state_dict( self.state_dict() )
        return cloned


from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User

class Quack(models.Model):
    tags = models.CharField(max_length=100)
    content = models.TextField(max_length=250)
    date_posted = models.DateTimeField(default=timezone.now)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    likes = models.ManyToManyField(User, blank=True, related_name='fans')

    @property
    def total_likes(self):
        """
        Likes for the company
        :return: Integer: Likes for the company
        """
        return self.likes.count()

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    date_joined = models.DateField(default=timezone.now())
    location = models.TextField(max_length=30, blank=True)

    def __str__(self):
        return f'{self.user.username}\'s Profile'


import csv

def readTextFile(filename):
    text = ""
    f = open(filename, 'r')
    for line in f:
        text += line

    f.close()
    return text

def writeTextFile(filename, text):
    f = open(filename, 'w')
    for item in text:
        f.write(item)
    f.close()

def writeCSVFile(filename, llist):
    with open(filename, 'w', newline="") as ofile:
        writer = csv.writer(ofile, delimiter=",")
        for newdata in llist:
            writer.writerow(newdata)

# fungsi menghitung mse
def hitungMAE(teks1, teks2):
    #bandingkan ukuran kedua file
    if len(teks1) == len(teks2):
        print("[MAE] Kedua file memiliki ukuran yang sama")

        #hitung nilai mse
        jmlchar = len(teks1)
        jmlabs = 0

        #hitung jumlah absolute
        for i in range(jmlchar):
            # print(teks1[i], teks2[i], ord(teks1[i]), ord(teks2[i]))
            jmlabs = jmlabs + abs(ord(teks1[i]) - ord(teks2[i]))
            # print("tes : ", jmlkuadrat)

        mae = jmlabs / jmlchar

        return mae
    else:
        return -1

# fungsi menghitung MSE
def hitungMSE(teks1, teks2):
    #bandingkan ukuran kedua file
    if len(teks1) == len(teks2):
        print("[MSE] Kedua file memiliki ukuran yang sama")

        #hitung nilai mse
        jmlchar = len(teks1)
        jmlkuadrat = 0

        #hitung jumlah absolute
        for i in range(jmlchar):
            # print(teks1[i], teks2[i], ord(teks1[i]), ord(teks2[i]))
            jmlkuadrat = jmlkuadrat + abs(ord(teks1[i]) - ord(teks2[i]))**2
            # print("tes : ", jmlkuadrat)

        mse = jmlkuadrat / jmlchar

        return mse
    else:
        return -1


import typing

from ...core import grammar as g, transform as t
from ...validation.transform_validation import annotate
from ..bnf._parser import ALLOWED_SYMBOLS

if typing.TYPE_CHECKING:
    # TypeVars should be referenced using forward references 'T' vs T so the lib
    # can do its magic
    T = typing.TypeVar('T')
    T2 = typing.TypeVar('T2')
    Addable = typing.TypeVar('Addable', str, list)

def syntax_accum(
    values: typing.Tuple[typing.Sequence[g.Rule], None]
) -> g.Language:
    rules = values[0]
    lang = g.Language.create(rules[0].name)
    eol_rule = g.Rule(
        'EOL',
        g.Syntax.create(
            g.TermGroup.create(
                g.Literal('\n')
            )
        )
    )
    eof_rule = g.Rule(
        'EOF',
        g.Syntax.create(
            g.TermGroup.create(
                g.EOFTerm()
            )
        )
    )
    lang.add_rule(eol_rule)
    lang.add_rule(eof_rule)
    for rule in rules:
        lang.add_rule(rule)
    return lang

def rule_accum(
    values: typing.Tuple[
        None,
        str,
        g.RuleName,
        str,
        None,
        str,
        None,
        typing.Sequence[g.TermGroup],
        None
    ]
) -> g.Rule:
    return g.Rule(values[2], g.Syntax(values[7]))

def expression_accum(
    values: typing.Tuple[
        g.TermGroup,
        None,
        str,
        None,
        typing.Sequence[g.TermGroup]
    ]
) -> typing.Sequence[g.TermGroup]:
    return [values[0]] + list(values[4])

def list_accum_1(
    values: typing.Tuple[g.Term]
) -> g.TermGroup:
    return g.TermGroup(list(values))

def list_accum_2(
    values: typing.Tuple[g.Term, None, g.TermGroup]
) -> g.TermGroup:
    return g.TermGroup([values[0]] + list(values[2].terms))

def text_accum_1(
    values: typing.Tuple[str]
) -> g.Literal:
    return g.Literal(values[0])

def text_accum_2(
    values: typing.Tuple[str, g.Literal]
) -> g.Literal:
    return g.Literal(values[0] + values[1].text)

def base_term_accum_rule(
    values: typing.Tuple[str, g.RuleName, str]
) -> g.Term:
    return g.RuleReference(values[1])

def literal_range_accum1(
    values: typing.Tuple[str, str, str]
) -> g.LiteralRange:
    number = int(values[1])
    return g.LiteralRange(number, number)

def literal_range_accum2(
    values: typing.Tuple[str, str, str, str, str]
) -> g.LiteralRange:
    first = int(values[1])
    second = int(values[3])
    return g.LiteralRange(first, second)

def repeat_term_accum(
    values: typing.Tuple[
        g.Term,
        str,
        typing.Tuple[int, typing.Optional[int]],
        str
    ]
) -> g.Term:
    return g.RepeatTerm(values[0], values[2][0], values[2][1])

def repeat_body_accum1(
    values: typing.Tuple[str]
) -> typing.Tuple[int, typing.Optional[int]]:
    num = int(values[0])
    return (num, num)

def repeat_body_accum2(
    values: typing.Tuple[str, str]
) -> typing.Tuple[int, typing.Optional[int]]:
    num = int(values[0])
    return (num, None)

def repeat_body_accum3(
    values: typing.Tuple[str, str, str]
) -> typing.Tuple[int, typing.Optional[int]]:
    return (int(values[0]), int(values[2]))

def list_of(
    values: typing.Tuple['T']
) -> typing.Sequence['T']:
    return [values[0]]

def push_list(
    values: typing.Tuple['T', typing.Sequence['T']]
) -> typing.Sequence['T']:
    return [values[0]] + list(values[1])

def nothing(_: typing.Tuple['T']) -> None:
    return None

def nothing2(_: typing.Tuple['T', 'T2']) -> None:
    return None

def identity(values: typing.Tuple['T']) -> 'T':
    return values[0]

def identity2(values: typing.Tuple['T']) -> 'T2':
    return values[0]  # type: ignore

def unescape(
    values: typing.Tuple[str, 'T', str]
) -> 'T':
    return values[1]

def add(
    values: typing.Tuple['Addable', 'Addable']
) -> 'Addable':
    iterable = iter(values)
    accum = next(iterable)
    for item in iterable:
        accum += item
    return accum

transform = t.LanguageTransformation.create(
    'Syntax', [syntax_accum]
)
transform <<= 'Rules', [
    annotate(list_of, T=g.Rule),
    annotate(push_list, T=g.Rule)
]
transform <<= 'Rule', [rule_accum]
transform <<= 'OptWhitespace', [
    annotate(nothing2, T=str, T2=None),
    annotate(nothing, T=str)
]
transform <<= 'Expression', [
    annotate(list_of, T=g.TermGroup),
    expression_accum
]
transform <<= 'LineEnd', [
    annotate(nothing, T=None),
    annotate(nothing2, T=None, T2=None),
]
transform <<= 'SingleLineEnd', [
    annotate(nothing2, T=None, T2=None)
]
transform <<= 'List', [
    list_accum_1,
    list_accum_2
]
transform <<= 'BaseTerm', [
    annotate(identity2, T=g.Literal, T2=g.Term),
    base_term_accum_rule,
    annotate(identity2, T=g.LiteralRange, T2=g.Term),
]
transform <<= 'Literal', [
    annotate(unescape, T=g.Literal),
    annotate(unescape, T=g.Literal),
]
transform <<= 'Text1', [
    text_accum_1,
    text_accum_2,
]
transform <<= 'Text2', [
    text_accum_1,
    text_accum_2,
]
transform <<= 'Character', [
    annotate(identity, T=str)
] * 3
transform <<= 'Letter', [
    annotate(identity, T=str)
] * 26 * 2
transform <<= 'Digit', [
    annotate(identity, T=str)
] * 2
transform <<= 'NonZeroDigit', [
    annotate(identity, T=str)
] * 9
transform <<= 'Symbol', [
    annotate(identity, T=str)
] * len(ALLOWED_SYMBOLS)
transform <<= 'Character1', [
    annotate(identity, T=str),
    annotate(identity, T=str)
]
transform <<= 'Character2', [
    annotate(identity, T=str),
    annotate(identity, T=str)
]
transform <<= 'RuleName', [
    annotate(identity, T=str),
    annotate(add, Addable=str)
]
transform <<= 'RuleEnd', [
    annotate(identity, T=str),
    annotate(add, Addable=str)
]
transform <<= 'OneRuleEnd', [
    annotate(identity, T=str),
    annotate(identity, T=str),
    annotate(add, Addable=str),
    annotate(add, Addable=str)
]
transform <<= 'EOL', [
    annotate(nothing, T=str)
]
transform <<= 'EOF', [
    annotate(nothing, T=str)
]
transform <<= 'LiteralRange', [
    literal_range_accum1,
    literal_range_accum2,
]
transform <<= 'Number', [
    annotate(identity, T=str),
    annotate(add, Addable=str)
]
transform <<= 'Digits', [
    annotate(identity, T=str),
    annotate(add, Addable=str)
]
transform <<= 'Term', [
    annotate(identity, T=g.Term),
    repeat_term_accum
]
transform <<= 'RepeatBody', [
    repeat_body_accum1,
    repeat_body_accum2,
    repeat_body_accum3,
]


from PySteppables import *
import CompuCell
import sys
import random
import math as m
import numpy
import os

Init_max_div = 4.0

gl_conversion_efficiency = .85
gl_death_threshold = 1.0
gl_initial_concentration = 15
qui_death_rate = .5

OUTPUT_FILE_NAME = os.path.expanduser("~/Dropbox/CompuCell Stuff/Final Project/FPGreen/output.txt")
outputFile = None

def kill(steppable, cell, type, mcs):
    writeCell(steppable, type, mcs, cell)
    cell.targetVolume = 0
    cell.lambdaVolume = 100

def switchstate(steppable,cell, cellDict):
    if cellDict["Internal_Glucose_Storage"] >= cellDict["pro_threshold"]:
        cellDict["state"]  = "P"
        cellDict["gl_metabolic_rate"] = 2

    if cellDict["Internal_Glucose_Storage"] <= cellDict["qui_threshold"]:
        cellDict["gl_metabolic_rate"] = 1.5
        cell.type = 3
        cellDict["state"]  = "Q"

def initOutputFile(fname = OUTPUT_FILE_NAME):

    global outputFile
    outputFile = open(fname, "w")

    s = "MCS"
    s += "; "
    s += "EVENT_ID"
    s += "; "
    s += "CELL_TYPE"
    s += "; "
    s += "CELL_ID"
    s += "; "
    s += "Parent_ID"
    s += "; "
    s += "Last_Stem_Cell_ID"
    s += "; "
    s += "P_STEM"
    s += "; "
    s += "MAX_DIVISIONS"
    s += "; "
    s += "CURRENT_DIVISIONS"
    s += "\n"

    outputFile.write(s)
    outputFile.flush()

def writeCell(steppable, eventId, mcs, cell):
    """
    Writes the state of a cell as a record in an output file.
    """
    global outputFile

    dict =  steppable.getDictionaryAttribute(cell)

    s = str(mcs)
    s += "; "
    s += str(eventId)
    s += "; "
    s += str(cell.type)
    s += "; "
    s += str(cell.id)
    s += "; "
    s += str(dict["Parent_ID"])
    s += "; "
    s += str(dict["Last_Stem_Cell_ID"])
    s += "; "
    s += str(dict["p_stem"])
    s += "; "
    s += str(dict["max_div"])
    s += "; "
    s += str(dict["cur_div"])
    s += "\n"

    outputFile.write(s)
    outputFile.flush()

from PySteppablesExamples import MitosisSteppableBase

class ConstraintInitializerSteppable(SteppableBasePy):
    def __init__(self,_simulator,_frequency=1):
        SteppableBasePy.__init__(self,_simulator,_frequency)
    def start(self):
        field=self.getConcentrationField("Glucose")
        field[:,:,:] = gl_initial_concentration

        initOutputFile()
        for cell in self.cellList:
            cellDict=self.getDictionaryAttribute(cell)
            cellDict["p_stem"]= .15
            cellDict["max_div"]= Init_max_div
            cellDict["cur_div"]=0
            cellDict["Parent_ID"] = cell.id
            cellDict["Last_Stem_Cell_ID"] = cell.id
            cellDict["state"] = None
            cellDict["Internal_Glucose_Storage"] = 8
            cellDict["qui_threshold"] = 2
            cellDict["pro_threshold"] = 4
            cellDict["gl_absorption_rate"] = .3
            cellDict["gl_growth_threshold"] = .3

            switchstate(self,cell,cellDict)

            cell.targetVolume=25
            cell.lambdaVolume=10.0
            writeCell(self, "INIT", 0, cell)

class GrowthSteppable(SteppableBasePy):
    def __init__(self,_simulator,_frequency=1):
        SteppableBasePy.__init__(self,_simulator,_frequency)
    def step(self,mcs):

        GlucField=self.getConcentrationField("Glucose")

        for cell in self.cellList:
            cellDict=self.getDictionaryAttribute(cell)
            if ((cell.type != 0) and (cell.type != 3)) \
            and (cell.targetVolume > 0):
                x = int(cell.xCOM)
                y = int(cell.yCOM)
                z = int(cell.zCOM)
                GlucValue = GlucField[x,y,z]
                GlucAbs = cellDict["gl_absorption_rate"] * GlucValue
                cellDict["Internal_Glucose_Storage"] += .1 * (GlucAbs - cellDict["gl_metabolic_rate"])
                #print cellDict["Internal_Glucose_Storage"]

                switchstate(self,cell,cellDict)

                GlucField[x,y,z]  = GlucValue - GlucAbs

                if (cell.targetVolume - cell.volume < 5)  and (cellDict["state"] == "P"):
                    cell.targetVolume += gl_conversion_efficiency * \
                    .9 * (GlucAbs - cellDict["gl_metabolic_rate"]) \
                    / (cellDict["gl_growth_threshold"] + .9 * (GlucAbs - cellDict["gl_metabolic_rate"]))

            if cellDict["Internal_Glucose_Storage"] <= gl_death_threshold:
                cell.type = 3
                writeCell(self, "Necrotic", mcs, cell)

            if cell.type == 3:
                cell.targetVolume -= qui_death_rate * cell.targetVolume
                if cell.targetVolume <= .1:
                    kill(self, cell, "Nutrient-Death", mcs)

class MitosisSteppable(MitosisSteppableBase):
    def __init__(self,_simulator,_frequency=1):
        MitosisSteppableBase.__init__(self,_simulator, _frequency)

    def step(self,mcs):
        self.mcs = mcs
        cells_to_divide=[]
        for cell in self.cellList:
            if cell.volume>40:
                cells_to_divide.append(cell)
        for cell in cells_to_divide:
            self.divideCellRandomOrientation(cell)

    def updateAttributes(self):

        parentCell=self.mitosisSteppable.parentCell
        childCell=self.mitosisSteppable.childCell
        parentCell.targetVolume=25
        childCell.targetVolume=25
        childCell.lambdaVolume=parentCell.lambdaVolume

        pdict=self.getDictionaryAttribute(parentCell)
        cdict=self.getDictionaryAttribute(childCell)

        childCell.targetVolume=parentCell.targetVolume
        childCell.lambdaVolume=parentCell.lambdaVolume

        if random.random() < 0.01:
            x = round(random.gauss(0.0,.5),2)
            if x >= 0:
                pdict["max_div"] += x
            else:
                pdict["max_div"] = pdict["max_div"] / (1 - x / Init_max_div)

            writeCell(self, "MAXDIV-MUTATION", self.mcs, parentCell)

        if random.random() < 0.1:
            x = round(random.gauss(0.0,.05),2)
            if (pdict['p_stem'] < 1) and (pdict['p_stem'] > 0):
                pdict["p_stem"] += x

            writeCell(self, "PSTEM-MUTATION", self.mcs, parentCell)

        if random.random() < 0.01:
            x = round(random.gauss(0.0,.05),2)
            pdict["qui_threshold"] += x

            writeCell(self, "Q-MUTATION", self.mcs, parentCell)

        if random.random() < 0.01:
            x = round(random.gauss(0.0,.05),2)
            pdict["pro_threshold"] += x

            writeCell(self, "P-MUTATION", self.mcs, parentCell)

        if random.random() < 0.01:
            x = round(random.gauss(0.0,.05),2)
            pdict["gl_absorption_rate"] += x

            writeCell(self, "ABSORPTION-MUTATION", self.mcs, parentCell)

        if random.random() < 0.01:
            x = round(random.gauss(0.0,.05),2)
            pdict["gl_growth_threshold"] += x

            writeCell(self, "GROWTH_THRESHOLD-MUTATION", self.mcs, parentCell)

        for key,value in pdict.items():
            cdict[key] = value

        if parentCell.type == 1:
            if random.random() < pdict['p_stem']:
                childCell.type=1
            else:
                cdict["cur_div"] += 1
                childCell.type = 2

        if parentCell.type == 2:
            pdict['cur_div'] += 1
            cdict['cur_div'] += 1
            childCell.type = 2

        cdict["Parent_ID"] = parentCell.id
        if parentCell.type == 1:
            cdict["Last_Stem_Cell_ID"] = parentCell.id
        else:
            cdict["Last_Stem_Cell_ID"] = pdict["Last_Stem_Cell_ID"]

        writeCell(self, "MITOSIS", self.mcs, childCell)

        if parentCell.type == 2:
            if (pdict['cur_div'] >= pdict['max_div']):
                kill(self, parentCell, "Limit-Death", self.mcs)

class DeathSteppable(SteppableBasePy):
    def __init__(self,_simulator,_frequency=1):
        SteppableBasePy.__init__(self,_simulator,_frequency)
    def step(self,mcs):
        pass

class Graph(SteppableBasePy):
    def __init__(self,_simulator,_frequency=10):
        SteppableBasePy.__init__(self,_simulator,_frequency)

    def start(self):
        pass

    def step(self,mcs):
        pass

    def finish(self):
        pass


#!/usr/bin/env python

#
# Copyright 2014 Cachebox, Inc. All rights reserved. This software
# is property of Cachebox, Inc and contains trade secrects,
# confidential & proprietary information. Use, disclosure or copying
# this without explicit written permission from Cachebox, Inc is
# prohibited.
#
# Author: Cachebox, Inc (sales@cachebox.com)
#

import json
import random
import subprocess
import cherrypy

from src.auth import authRequestHandler, authAdminRequestHandler
from src.util import getusize

class Storage(object):
    exposed = True

    storages = [
                {
                 'id': random.randint(1, 100),
                 'name': 'HDD Datastore 1',
                 'created': "20 Jan 2015 23:11:10",
                 'modified': "20 Jan 2015 23:11:10",
                 'dtype': "VOLUME",
                 'source_path': "server1",
                 'container_path': "/dev/sdb",
                 'backing_volume': "/dev/sdb,/dev/sdd",
                 'application_id': None,
                 'size' : getusize(4 << 40),
                 'tier': 'hdd',
                 'state': 'created'
                },
                {
                 'id': random.randint(2, 100),
                 'name': 'SSD Datastore 1',
                 'created': "20 Jan 2015 23:11:10",
                 'modified': "20 Jan 2015 23:11:10",
                 'dtype': "VOLUME",
                 'source_path': "server2",
                 'container_path': "/dev/sdb",
                 'backing_volume': "/dev/sdc",
                 'application_id': None,
                 'size' : getusize(1 << 40),
                 'tier': 'flash',
                 'state': 'created'
                },

               ]

    @authRequestHandler
    def GET(self, arg):
        return {'storages': self.storages}

    @cherrypy.tools.json_in()
    @authAdminRequestHandler
    def POST(self, op):
        data = cherrypy.request.json
        storage_id = data.get('storage_id', random.randint(1, 100))
        name = data.get('storage_name')
        volumes = data.get('storage_volumes')
        return {
                'msg': "Datastore %s successfully created" % name,
                'storages':[
                {
                  'id': storage_id,
                  'name': name,
                  'created': "20 Jan 2015 23:11:10",
                  'modified': "20 Jan 2015 23:11:10",
                  'dtype': "VOLUME",
                  'source_path': "server1",
                  'container_path': "/dev/sdb",
                  'backing_volume': "/dev/sdb,/dev/sdd",
                  'application_id': None,
                  'size' : getusize(4 << 40),
                  'tier': 'hdd',
                  'state': 'created'
                }
               ]
        }

class Volume(object):
    exposed = True

    volumes = [
               {
                 'id': random.randint(1, 100),
                 'name': '/dev/sdb',
                 'type': 'HDD',
                 'size': getusize(2 << 40),
                 'server': 'server1',
                 'datastore': random.randint(1, 100)
               },
               {
                 'id': random.randint(1, 100),
                 'name': '/dev/sdc',
                 'type': 'HDD',
                 'size': getusize(2 << 40),
                 'server': 'server1',
                 'datastore': random.randint(1, 100)
               },
               {
                 'id': random.randint(1, 100),
                 'name': '/dev/sdd',
                 'type': 'SSD',
                 'size': getusize(1 << 40),
                 'server': 'server1',
                 'datastore': None
               },
               {
                 'id': random.randint(1, 100),
                 'name': '/dev/sde',
                 'type': 'HDD',
                 'size': getusize(2 << 40),
                 'server': 'server1',
                 'datastore': None
               },
               {
                 'id': random.randint(1, 100),
                 'name': '/dev/sdb',
                 'type': 'HDD',
                 'size': getusize(2 << 40),
                 'server': 'server2',
                 'datastore': None
               },
               {
                 'id': random.randint(1, 100),
                 'name': '/dev/sdc',
                 'type': 'SSD',
                 'size': getusize(2 << 40),
                 'server': 'server2',
                 'datastore': random.randint(1, 100)
               },
               {
                 'id': random.randint(1, 100),
                 'name': '/dev/sdd',
                 'type': 'SSD',
                 'size': getusize(200 << 30),
                 'server': 'server2',
                 'datastore': None
               }
              ]

    @authAdminRequestHandler
    def GET(self, arg):
        return {'volumes': self.volumes}

conf = {
         '/volume': {
             'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
             'tools.sessions.on': True,
             'tools.response_headers.on': True
         },
         '/': {
             'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
             'tools.sessions.on': True,
             'tools.response_headers.on': True
         }
      }

webapp = Storage()
webapp.volume = Volume()
app = cherrypy.Application(webapp, '/storage', config = conf)


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def findBottomLeftValue(self, root: TreeNode) -> int:
        self.flag = []
        self.Search(root)
        print(self.flag)
        return self.flag[-1]

    def Search(self, root, deep=0):
        if root is None:
            return
        if len(self.flag) == deep:
            self.flag.append(root.val)
        self.Search(root.left, deep+1)
        self.Search(root.right, deep+1)


import random
import pygame

import team

from agent import *
from state import *

class Field:
    def __init__(self, size, ball):
        self.size = size
        self.ball = ball
        self.team_direction = (0, 1)
        self.game_state = None
        self.team1 = None
        self.team2 = None

    def update(self, dt):
        #tackles = []
        for a in (self.team1.players + self.team2.players):
            if a.active:
                a.update(dt, self.size, self.game_state, self.team1, self.team2, self.ball.pos, self.ball.velocity)
                if a.goal[0] == Goal.TACKLE:
                    tackles.append((a, a.goal[1]))
                elif a.goal[0] == Goal.KICK_BALL:
                    if random.random() * 10000.0 >= dist2(self.ball.velocity):
                        self.ball.velocity = add2(self.ball.velocity, scale(norm(*a.goal[1]), a.power * a.goal[2]))
                        self.ball.last_touch = a
                    a.active = False
                    a.activity_timer = a.goal[2]
                elif a.goal[0] == Goal.RECEIVE_BALL:
                    if random.random() * 10000.0 >= dist2(self.ball.velocity):
                        self.ball.velocity = scale(self.ball.velocity, 0.5)
                        self.ball.last_touch = a
                    a.active = False
                    a.activity_timer = 0.5
                elif a.goal[0] == Goal.THROW_BALL:
                    self.ball.velocity = add2(self.ball.velocity, scale(norm(*a.goal[1]), a.power * a.goal[2]))
                    self.ball.last_touch = a
                    a.active = False
                    a.activity_timer = a.goal[2]
                    self.game_state = (GameState.FREE_PLAY, ())

            else:
                a.activity_timer -= dt
                if a.activity_timer <= 0.0:
                    a.active = True

        '''
        for t in tackles:
            if random.random() <= 0.3:
                pass
            else:
                t[0].active = False
                t[0].activity_timer = 1.0 # 1 second
        '''

        self.ball.update(dt)

        last_pos = self.ball.get_last_pos(dt)
        if self.ball.pos[0] < 0.0 and last_pos[0] > 0.0:
            y_cross =  self.ball.pos[1] + (-self.ball.pos[0] / (last_pos[0] - self.ball.pos[0])) * (last_pos[1] - self.ball.pos[1])
            if y_cross >= 2.0 * self.size[1] / 5.0 and y_cross <= 3.0 * self.size[1] / 5.0:
                print("GOAL")
                self.start(len(self.agents))
        elif self.ball.pos[0] > self.size[0] and last_pos[0] < self.size[0]:
            y_cross =  self.ball.pos[1] + ((self.ball.pos[0] - self.size[0]) / (self.ball.pos[0] - last_pos[0])) * (last_pos[1] - self.ball.pos[1])
            if y_cross >= 2.0 * self.size[1] / 5.0 and y_cross <= 3.0 * self.size[1] / 5.0:
                print("GOAL")
                self.start(len(self.agents))
        if self.ball.pos[0] < 0.0 or self.ball.pos[0] > self.size[0] or self.ball.pos[1] < 0.0 or self.ball.pos[1] > self.size[1]:
            self.ball.pos = last_pos
            self.ball.velocity = (0.0, 0.0)
            self.game_state = (GameState.THROW_IN, self.ball.last_touch.team)

    def display(self, screen, pos):
        pygame.draw.rect(screen, pygame.color.Color("dark green"), (pos, self.size), 0)
        pygame.draw.rect(screen, pygame.color.Color("black"), (pos, self.size), 1)

        pygame.draw.rect(screen, pygame.color.Color("black"), (add2(pos, (-5, 2 * self.size[1] / 5.0)), (5, self.size[1] / 5.0)), 0)
        pygame.draw.rect(screen, pygame.color.Color("black"), (add2(pos, (self.size[0], 2 * self.size[1] / 5.0)), (5, self.size[1] / 5.0)), 0)
        self.ball.display(screen, pos)
        for a in (self.team1.players + self.team2.players):
            a.display(screen, pos, self.team1)

    def start(self, num_players):
        self.ball.velocity = (0.0, 150.0)
        self.ball.pos = scale(self.size, 0.5)
        self.team1 = team.Team([Agent((random.random() * 400, random.random() * 180), 20.0, 100.0, None, "position_here") for _ in range(num_players//2)], (), 1)
        for p in self.team1.players:
            p.team = self.team1
        self.team2 = team.Team([Agent((random.random() * 400, random.random() * 180), 20.0, 100.0, None, "position_here") for _ in range(num_players//2)], (), -1)
        for p in self.team2.players:
            p.team = self.team2
        self.game_state = (GameState.FREE_PLAY, ())


# import itertools

# n = int(input())
# result = 0
# M = n // 2
# for m in range(M+1):
#     n_ = n - m
#     numerator = 1
#     denominator = 1
#     for i,_ in enumerate(range(m)):
#         numerator *=  n_ - i
#         denominator *= m - i
#     result += int(numerator/denominator)
# print(result%10007)

n = int(input())
dp = [0]*(n+1)
if n ==1:
    print(1)
    exit(0)
dp[0] = 0
dp[1] = 1
dp[2] = 2
for i in range(3,n+1):
    dp[i] = dp[i-1]+dp[i-2]
# print(dp)
print(dp[n]%10007)


#!/usr/bin/python
import sys

x=int(sys.argv[1])
y=int(sys.argv[2])

def subtraction(num1, num2):
    return num1 - num2

def divisible(num):

    isEven=num%2

    if isEven == 0:

        difference=subtraction(num,1000)

        return difference

    else:

        return num

def multiply(num1, num2):

    return num1*num2

def addition(a):

    b=multiply(672.5,2.0)

    return a + b

num1=divisible(x)
num2=divisible(y)

product=multiply(num1,num2)

result=addition(product)

print(result)


import tensorflow as tf
import numpy as np
import scipy.io as spio
import matplotlib.pyplot as plt
from PIL import Image
import os
from pylab import *
from tensorflow.python.framework import ops
ops.reset_default_graph()

def rotate(list1, num):
    b = [[0 for i in range(num)] for j in range(num)]
    for i in range(num):
        for j in range(num):
            b[num-1-j][num-1-i] = list1[i][num-1-j]
    for i in range(num):
        for j in range(num):
            list1[i][j]=b[i][j]
    return list1
#load a color image
def Convert_Image(im):
#convert to grey level image
    Lim=im.convert('L')
#setup a converting table with constant threshold
    threshold=80
    table=[]
    for i in range( 256 ):
        if i<threshold:
            table.append(0)
        else :
            table.append( 1 )
 #  convert to binary image by the table
    bim=Lim.point(table,'1')
    width = bim.size[0]
    height = bim.size[1]
    print(width)
    print(height)
    flag=0
    for h in range(height):
        if flag==0:
            for w in range(width):
                pixel = bim.getpixel((w, h))
                if pixel==0:
                    top=h
                    flag=1
    flag=0
    for h in range(height):
        if flag==0:
            for w in range(width):
                pixel = bim.getpixel((w, height-h-1))
                if pixel==0:
                    down=height-h-1
                    flag=1
    flag=0
    for w in range(width):
        if flag==0:
            for h in range(height):
                pixel = bim.getpixel((w, h))
                if pixel==0:
                    left=w
                    flag=1
    flag=0
    for w in range(width):
       if flag==0:
           for h in range(height):
               pixel = bim.getpixel((width-w-1, h))
               if pixel==0:
                  right=width-w-1
                  flag=1
    bim2=bim.crop((left,top,right,down))
    bim3=bim2.convert('L')
    #bim3.show()
    bim4=bim3.resize((28,28),Image.ANTIALIAS)
    mtr=np.transpose(np.array(bim4,dtype=np.float))
    mtr1=mtr.reshape((1,28*28))
    for i in range(28*28):
        mtr1[0][i]=255-mtr1[0][i]
        mtr1[0][i]=mtr1[0][i]/255
    return mtr1

'''计算准确度函数'''
def compute_accuracy(xs,ys,X,y,keep_prob,sess,prediction,on):
    '''param on:on=1 means plot images'''
    y_pre = sess.run(prediction,feed_dict={xs:X,keep_prob:1.0})       # 预测，这里的keep_prob是dropout时用的，防止过拟合
    correct_prediction = tf.equal(tf.argmax(y_pre,1),tf.argmax(y,1))  #tf.argmax 给出某个tensor对象在某一维上的其数据最大值所在的索引值,即为对应的数字，tf.equal 来检测我们的预测是否真实标签匹配
    if on==1:
            n1=[]
            n2=[]
            for j in range(len(y)):
                c1=np.where(y_pre[j]==np.max(y_pre[j]))
                c2=np.where(y[j]==np.max(y[j]))
                n1.append(c1[0][0])
                n2.append(c2[0][0])
            plot_images(X,n1,n2)
    accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) # 平均值即为准确度
    result = sess.run(accuracy,feed_dict={xs:X,ys:y,keep_prob:1.0})
    return result
'''权重初始化函数'''
def weight_variable(shape):
    inital = tf.truncated_normal(shape, stddev=0.1)  # 使用truncated_normal进行初始化
    return tf.Variable(inital)

'''偏置初始化函数'''
def bias_variable(shape):
    inital = tf.constant(0.1,shape=shape)  # 偏置定义为常量
    return tf.Variable(inital)

'''卷积函数'''
def conv2d(x,W):#x是图片的所有参数，W是此卷积层的权重
    return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')#strides[0]和strides[3]的两个1是默认值，中间两个1代表padding时在x方向运动1步，y方向运动1步

'''池化函数'''
def max_pool_2x2(x):
    return tf.nn.max_pool(x,ksize=[1,2,2,1],
                          strides=[1,2,2,1],
                          padding='SAME')#池化的核函数大小为2x2，因此ksize=[1,2,2,1]，步长为2，因此strides=[1,2,2,1]
'''运行主函数'''

def test(X):
#    mydata = spio.loadmat('mydata.mat')
#    X = mydata['B']
#    y = mydata['Y']
#
#    mydata2 = spio.loadmat('mydata2.mat')
#    X2 = mydata2['B']
#    y2 = mydata2['Y']

    xs = tf.placeholder(tf.float32,[None,28*28])  # 输入图片的大小，28x28=784
    ys = tf.placeholder(tf.float32,[None,32])   # 输出0-9共10个数字
    keep_prob = tf.placeholder(tf.float32)      # 用于接收dropout操作的值，dropout为了防止过拟合
    x_image = tf.reshape(xs,[-1,28,28,1])       #-1代表先不考虑输入的图片例子多少这个维度，后面的1是channel的数量，因为我们输入的图片是黑白的，因此channel是1，例如如果是RGB图像，那么channel就是3

    '''第一层卷积，池化'''
    W_conv1 = weight_variable([5,5,1,32])  # 卷积核定义为5x5,1是输入的通道数目，32是输出的通道数目
    b_conv1 = bias_variable([32])          # 每个输出通道对应一个偏置
    h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1) # 卷积运算，并使用ReLu激活函数激活
    h_pool1 = max_pool_2x2(h_conv1)        # pooling操作
    '''第二层卷积，池化'''
    W_conv2 = weight_variable([5,5,32,64]) # 卷积核还是5x5,32个输入通道，64个输出通道
    b_conv2 = bias_variable([64])          # 与输出通道一致
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2)+b_conv2)
    h_pool2 = max_pool_2x2(h_conv2)
    '''全连接层'''
    h_pool2_flat = tf.reshape(h_pool2, [-1,7*7*64])   # 将最后操作的数据展开
    W_fc1 = weight_variable([7*7*64,1024])            # 下面就是定义一般神经网络的操作了，继续扩大为1024
    b_fc1 = bias_variable([1024])                     # 对应的偏置
    h_fc1 = tf.nn.sigmoid(tf.matmul(h_pool2_flat,W_fc1)+b_fc1)  # 运算、激活（这里不是卷积运算了，就是对应相乘）
    '''dropout'''
    h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)       # dropout操作
    '''最后一层全连接'''
    W_fc2 = weight_variable([1024,32])                # 最后一层权重初始化
    b_fc2 = bias_variable([32])                       # 对应偏置

    v1 = tf.Variable(1, name="v1")
    v2 = tf.Variable(1, name="v2")
    prediction = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)  # 使用softmax分类器
    cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),reduction_indices=[1]))  # 交叉熵损失函数来定义cost function
    train_step = tf.train.AdamOptimizer(1e-3).minimize(cross_entropy)  # 调用梯度下降

    saver = tf.train.Saver()

    with tf.Session() as sess:
        homedir = os.getcwd()
        saver.restore(sess, homedir+"/supermodel.tfmodel") #会将已经保存的变量值resotre到 变量中。
        print ("Model restored.")
        print("v1:", sess.run(v1)) # 打印v1、v2的值和之前的进行对比
        print("v2:", sess.run(v2))
        y_pre = sess.run(prediction,feed_dict={xs:X,keep_prob:1.0})
        c1=np.where(y_pre[0]==np.max(y_pre[0]))
#        gray()
#        imshow(X.reshape((28,28)))
#        show()
#        print(y_pre[0][17])
        print(y_pre[0][3])
        print(y_pre[0][6])
        print(y_pre[0][8])
        print(y_pre[0][16])
        print(c1[0][0])
        if c1[0][0]==0:
            print("北京")
        if c1[0][0]==1:
            print("上海")
        if c1[0][0]==2:
            print("福建")
        if c1[0][0]==3:
            print("广东")
        if c1[0][0]==4:
            print("天津")
        if c1[0][0]==5:
            print("重庆")
        if c1[0][0]==6:
            print("海南")
        if c1[0][0]==7:
            print("四川")
        if c1[0][0]==8:
            print("湖南")
        if c1[0][0]==9:
            print("辽宁")
        if c1[0][0]==10:
            print("云南")
        if c1[0][0]==11:
            print("贵州")
        if c1[0][0]==12:
            print("吉林")
        if c1[0][0]==13:
            print("河北")
        if c1[0][0]==14:
            print("青海")
        if c1[0][0]==15:
            print("甘肃")
        if c1[0][0]==16:
            print("河南")
        if c1[0][0]==17:
            print("湖北")
        if c1[0][0]==18:
            print("江西")
        if c1[0][0]==25:
            print("陕西")
        if c1[0][0]==29:
            print("浙江")
        if c1[0][0]==31:
            print("江苏")
mydata2 = spio.loadmat('mydata2.mat')

im=Image.open('1.jpg ')
imshow(im)
show()
#plt.imshow(im)
#plt.show()
X2=Convert_Image(im)
#X2 = mydata2['B']
test(X2[0:1])


import discord
import typing
import emoji

from discord.ext import commands

from .utils.checks import is_commander, bot_has_permissions
from .utils.converters import EqualRole

class AllEmojiConverter(commands.EmojiConverter):

    async def convert(self, ctx, arg):
        arg = arg.lower()

        try:
            return await super().convert(ctx, arg)
        except Exception:
            pass

        if arg not in emoji.UNICODE_EMOJI:
            raise commands.BadArgument(ctx.lang["emroles"]["incorrect_emoji"])

        return discord.PartialEmoji(name=arg)

class EmojiRoles(commands.Cog):

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

    async def get_reaction_role(self, message, emoji):
        emoji_id = emoji.id or str(emoji)
        emoji_role_id = await self.bot.db.execute(
            """
            SELECT `role_id`
            FROM `emoji_roles`
            WHERE `guild_id` = ? AND `emoji_id` = ? AND `message_id` = ?
            """,
            message.guild.id, str(emoji_id), message.id
        )

        return message.guild.get_role(emoji_role_id)

    def payload_to_data(self, payload):
        guild = self.bot.get_guild(payload.guild_id)
        channel = guild.get_channel(payload.channel_id) if guild else None
        member = guild.get_member(payload.user_id) if guild else None

        return {
            "guild": guild,
            "channel": channel,
            "member": member,
            "emoji": payload.emoji,
            "message_id": payload.message_id
        }

    async def process_payload(self, payload):
        if payload.guild_id is None:
            return

        data = self.payload_to_data(payload)

        if data["guild"] is None or data["member"] is None or data["member"].bot:
            return

        message = discord.Object(data["message_id"])
        setattr(message, "guild", data["guild"])

        emoji_role = await self.get_reaction_role(
            message,
            data["emoji"]
        )

        if emoji_role is None:
            return

        if data["channel"] is not None:
            perms = data["channel"].permissions_for(data["guild"].me)
        else:
            perms = data["guild"].me.guild_permissions

        if not perms.manage_roles:
            return

        if payload.event_type == "REACTION_ADD":
            if emoji_role not in data["member"].roles:
                await data["member"].add_roles(emoji_role)
        else:
            if emoji_role in data["member"].roles:
                await data["member"].remove_roles(emoji_role)

    @bot_has_permissions(manage_messages=True, manage_roles=True)
    @is_commander()
    @commands.group(invoke_without_command=True)
    async def emojirole(
        self, ctx,
        message: commands.MessageConverter,
        emoji: AllEmojiConverter,
        *, role: typing.Optional[EqualRole]
    ):
        emoji_id = emoji.id or str(emoji)
        emoji_role = await self.get_reaction_role(message, emoji)

        if role is None:
            if emoji_role is None:
                return await ctx.answer(ctx.lang["emroles"]["no_role"].format(str(emoji)))
            else:
                return await ctx.answer(ctx.lang["emroles"]["role"].format(
                    str(emoji), emoji_role.mention
                ))

        if emoji_role is None:
            await self.bot.db.execute(
                "INSERT INTO `emoji_roles` VALUES (?, ?, ?, ?)",
                ctx.guild.id,
                message.id,
                role.id,
                str(emoji_id),
                with_commit=True
            )
        else:
            await self.bot.db.execute(
                """
                UPDATE `emoji_roles`
                SET `role_id` = ?
                WHERE `guild_id` = ? AND `message_id` = ? WHERE `emoji_id` = ?
                """,
                role.id,
                ctx.guild.id,
                message.id,
                str(emoji_id),
                with_commit=True
            )

        await message.add_reaction(emoji)
        await ctx.answer(ctx.lang["emroles"]["role"].format(str(emoji), role.mention))

    @is_commander()
    @emojirole.command(name="remove")
    async def emojirole_remove(
        self, ctx,
        message: commands.MessageConverter,
        emoji: AllEmojiConverter
    ):
        emoji_role = await self.get_reaction_role(message, emoji)

        if emoji_role is None:
            return await ctx.answer(ctx.lang["emroles"]["no_role"].format(str(emoji)))

        await ctx.answer(ctx.lang["emroles"]["role_removed"].format(
            emoji_role.mention, str(emoji)
        ))

        await self.bot.db.execute(
            "DELETE FROM `emoji_roles` WHERE `guild_id` = ? AND `message_id` = ? AND `emoji_id` = ?",
            ctx.guild.id, message.id, str(emoji.id or emoji),
            with_commit=True
        )

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload):
        await self.process_payload(payload)

    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, payload):
        await self.process_payload(payload)

def setup(bot):
    bot.add_cog(EmojiRoles(bot))


# coding=utf-8
from __future__ import unicode_literals

import io
import json
import os
import shutil
import tempfile

from future.moves import sys
from mock import patch

from cli.cli import main_train_engine, main_cross_val_metrics, \
    main_train_test_metrics
from snips_nlu import SnipsNLUEngine
from snips_nlu.tests.utils import TEST_PATH, BEVERAGE_DATASET_PATH, \
    SnipsTest

def mk_sys_argv(args):
    return ["program_name"] + args

class TestCLI(SnipsTest):
    fixture_dir = os.path.join(TEST_PATH, "cli_fixture")

    # pylint: disable=protected-access
    def setUp(self):
        if not os.path.exists(self.fixture_dir):
            os.mkdir(self.fixture_dir)

        self.tmp_file_path = os.path.join(
            self.fixture_dir, next(tempfile._get_candidate_names()))
        while os.path.exists(self.tmp_file_path):
            self.tmp_file_path = os.path.join(
                self.fixture_dir, next(tempfile._get_candidate_names()))

    def tearDown(self):
        if os.path.exists(self.fixture_dir):
            shutil.rmtree(self.fixture_dir)

    def test_main_train_engine(self):
        # Given
        args = [BEVERAGE_DATASET_PATH, self.tmp_file_path]
        with patch.object(sys, "argv", mk_sys_argv(args)):
            # When
            main_train_engine()

            # Then
            if not os.path.exists(self.tmp_file_path):
                self.fail("No trained engine generated")
            msg = "Failed to create an engine from engine dict."
            with self.fail_if_exception(msg):
                with io.open(self.tmp_file_path, "r", encoding="utf8") as f:
                    trained_engine_dict = json.load(f)
                SnipsNLUEngine.from_dict(trained_engine_dict)

    def test_main_cross_val_metrics(self):
        # Given
        args = [BEVERAGE_DATASET_PATH, self.tmp_file_path]
        with patch.object(sys, "argv", mk_sys_argv(args)):
            # When
            main_cross_val_metrics()

            # Then
            if not os.path.exists(self.tmp_file_path):
                self.fail("No metrics found")

    def test_main_train_test_metrics(self):
        # Given
        args = [BEVERAGE_DATASET_PATH, BEVERAGE_DATASET_PATH,
                self.tmp_file_path]
        with patch.object(sys, "argv", mk_sys_argv(args)):
            # When
            main_train_test_metrics()

            # Then
            if not os.path.exists(self.tmp_file_path):
                self.fail("No metrics found")


#! /usr/bin/env python3

import tkinter as tk
from tkinter import messagebox
import requests
import bs4

def main():
    def scrolldown(*args):
        """Emulate scrolling by deleting the first line of content."""
        content.set('\n'.join(content.get().split('\n')[1:]))

    def back(*args):
        """Retrieve the previously accessed URL and load it."""
        try:
            future.append(history.pop())
            url.set(history.pop())
            go()
        except IndexError:
            pass

    def forward(*args):
        """Retrieve the page we went "back" from and load it."""
        try:
            url.set(future.pop())
            go()
        except IndexError:
            pass

    def go(*args):
        """Load the website written in the address bar."""
        if url.get() == 'disappear':
            tk.messagebox.showinfo("POOF!",
                "Salivili hipput tupput täppyt äppyt tipput hilijalleen!")
            root.quit()
            return
        # "Render" the requested page
        page = requests.get(url.get())
        soup = bs4.BeautifulSoup(page.text)
        [e.append('<{}>'.format(e['href'])) for e in soup.select('a[href]')]
        content.set(soup.body.get_text())

        # save in history
        history.append(url.get())

        # update window title
        root.title('nyyhkyytteek. ' + soup.title.string)

    root = tk.Tk()
    root.title('nyyhkyytteek')

    history = []
    future = []

    mainf = tk.Frame(root)
    mainf.grid(column=0, row=0)
    mainf.columnconfigure(0, weight=1)
    mainf.rowconfigure(0, weight=1)

    tk.Button(mainf, text='←', command=back).grid(column=0,row=1)
    tk.Button(mainf, text='→', command=forward).grid(column=1,row=1)

    url = tk.StringVar()
    url_entry = tk.Entry(mainf, width=100, textvariable=url)
    url_entry.grid(column=2, row=1)

    tk.Button(mainf, text='go!', command=go).grid(column=3, row=1)
    tk.Button(mainf, text='↓', command=scrolldown).grid(column=4,row=1)

    content = tk.StringVar(value='Enter a URL')
    content_page = tk.Message(mainf,
                              width=800,
                              justify='left',
                              font=(None,12),
                              textvariable=content)

    content_page.grid(column=2, row=2)

    url_entry.focus()
    root.bind('<Return>', go)
    root.bind('<Down>', scrolldown)
    root.mainloop()

if __name__ == '__main__':
    main()


from smop import *
from smop_functions import *
from modulation_functions import *

def cut_irellevant(data, chunk_size=100, thresh=0.2):
    l = len(data) // chunk_size

    ### Do FFT by chunks
    chunk_array = [np.array(data[chunk_size * i:(i + 1) * chunk_size]) for i in range(l)]
    freq = np.fft.fftfreq(chunk_size, d=1 / SAMPLE_RATE)
    fft_array = [np.abs(np.fft.fft(arr)) for arr in chunk_array]

    ### Integral over relevant freqs
    cut_index = int(3 * chunk_size / 8)
    integral_array = [np.trapz(arr[cut_index:chunk_size // 2], freq[cut_index:chunk_size // 2]) for arr in fft_array]
    integral_array = np.asarray(integral_array) / (-freq[chunk_size // 2] + freq[cut_index])

    ### Filter by thresh
    good_chunks = [i for i in range(len(integral_array)) if integral_array[i] > thresh]
    plt.figure()
    plt.plot(integral_array)

    begin = good_chunks[0] * chunk_size
    end = (good_chunks[-1] + 1) * chunk_size

    ### Cut and return data
    return data[begin:end]

def DecypherPM(r, thresh):
    chunk_size = 200
    t = np.arange(len(r))
    r = butter_highpass_filter(r, FREQ, SAMPLE_RATE, order=8)
    z = hilbert(r)  # form the analytical signal from the received vector
    inst_phase = np.unwrap(np.angle(z))  # instaneous phase
    chunk_inst_phase = [inst_phase[i * chunk_size: (i + 1) * chunk_size] for i in range(len(inst_phase) // chunk_size)]
    t_chunk = [t[i * chunk_size:(i + 1) * chunk_size] for i in range(len(t) // chunk_size)]

    for i in range(len(chunk_inst_phase)):
        coef_ = np.polyfit(t_chunk[i], chunk_inst_phase[i], 1)
        offset = coef_[0] * t_chunk[i] + coef_[1]
        dem = np.abs(chunk_inst_phase[i] - offset)
        dem_chunk = None
        if i == 0:
            dem_chunk = dem
        else:
            dem_chunk = np.append(dem_chunk, [dem])

    dem_chunk[dem_chunk > thresh] = thresh
    print(np.max(dem_chunk))

    t = np.arange(len(dem_chunk))
    plt.figure()
    plt.plot(t, np.abs(dem_chunk))

    #     plt.xlim(0, 1000)
    #     plt.ylim(5, 20)
    return dem_chunk

def deal_queue(item, max_size, queue):
    queue.insert(0, item)
    if len(queue) > max_size:
        queue.pop()
    return queue

def redecyherPM(data, ChunkSize=int(DURATION_PM * SAMPLE_RATE), min_thresh=0.5, queue_max_size=10, sup=1):
    data = abs(data)
    thresh = min_thresh
    queue = []
    NumOfChunks = len(data) / ChunkSize
    ChunkList = np.array_split(data, NumOfChunks)
    data_num_of_times = []
    for chunk in ChunkList:
        if np.sum(chunk) / ChunkSize > thresh:
            data_num_of_times.append(1)
            if np.sum(chunk) / ChunkSize < sup:
                queue = deal_queue(np.sum(chunk) / ChunkSize, queue_max_size, queue)
        else:
            data_num_of_times.append(0)
        if len(queue) > 5:
            thresh = 6 / 10 * np.sum(queue) / len(queue)
    #     plt.figure()
    #     plt.plot(data_num_of_times)
    return data_num_of_times

def DecypherFreqShift(data, ChunkSize=CHUNK_SIZE, thresh=0.4):
    #     sos = signal.butter(4,FREQ - FREQ_SHIFT, btype = 'hp', fs=SAMPLE_RATE, output='sos')
    #     filtered = signal.sosfilt(sos, data)
    #     data = np.array(filtered[:,0])
    #     data = np.array(data[:, 0])
    NumOfChunks = len(data) / ChunkSize
    ChunkList = np.array_split(data, NumOfChunks)
    ForTrans = [np.abs(np.fft.fft(dat)) for dat in ChunkList]
    indexes = range(len(ForTrans))
    ForTrans = [[0] * (ChunkSize // 2 - 1) +
                list(ForTrans[index][ChunkSize // 2:3 * ChunkSize // 4]) +
                [0] * (ChunkSize // 4 + 1) for index in indexes]
    NewForTrans = ForTrans
    # for index in indexes:
    #     if np.max(ForTrans[index]) > thresh:
    #         NewForTrans.append(ForTrans[index])
    freqs = {index: np.fft.fftfreq(ChunkSize, d=1 / SAMPLE_RATE) for index in range(len(NewForTrans))}
    freqs_found = np.array([freqs[index]
                            [np.argmax(NewForTrans[index])]
                            for index in range(len(NewForTrans))])
    found = [1 if np.abs(FREQ + FREQ_SHIFT - np.abs(frequ))
                  < np.abs(FREQ - np.abs(frequ)) else 0 for frequ in freqs_found]
    #     print(found)
    return found

def RestoreChunks(DecyphData, Ratio):
    ChunkData = []
    Chunk = 0
    first = DecyphData[0]
    for i in range(len(DecyphData)):
        if DecyphData[i] == first:
            Chunk += 1
        else:
            first = DecyphData[i]
            ChunkData.append(Chunk)
            Chunk = 1
    ChunkData.append(Chunk)
    Sizes = [chunk // Ratio if chunk % Ratio < Ratio / 2
             else chunk // Ratio + 1 for chunk in ChunkData]
    data = []
    state = DecyphData[0]
    for i in Sizes:
        data = data + [state] * i
        state = 1 - state
    return data


import cv2
from math import cos, sin, radians
import matplotlib.pyplot as plt
import numpy as np
import open3d as o3d
from pathlib import Path
import tifffile as tiff

# TODO multiprocess

GINGERBREAD = 1
APARTMENTS_LOCAL = 2
APARTMENTS_LYNX = 3
RANCH = 4
SIMPLE = 5
SIMPLE2 = 6

model = APARTMENTS_LYNX

write_depth = True
write_xyz = True
write_az = False

if model == GINGERBREAD:
    # reading point cloud into numpy array
    gb_file = "C:\\Users\\rdgrldkb\\Documents\\gbhouse.txt"
    point_cloud = np.loadtxt(gb_file).astype(np.float)

    fname_stub = 'output/gingerbread'

    # first three columms are point positions
    world_points = point_cloud[:, :3].astype(np.float64)

    # last three columns are point colors
    world_colors = point_cloud[:, 3:6].astype(np.float64)

    # setting known values
    focal_length = 500
    image_i = 600
    image_j = 400

    # separating x, y, z values into their own respective arrays
    x_points = point_cloud[:, 0]
    y_points = point_cloud[:, 1]
    z_points = point_cloud[:, 2]

    # camera views the scene from this position
    t_vec = np.array([[0, 0, 10]]).astype(np.float)

elif model == APARTMENTS_LOCAL:
    # reading point cloud into numpy array
    apartment_file = "C:\\Users\\rdgrldkb\\Documents\\Apartments_C10_Local.ply"
    point_cloud = o3d.io.read_point_cloud(apartment_file)

    fname_stub = 'output/apartments_local'

    world_points = np.asarray(point_cloud.points)

    # last three columns are point colors
    world_colors = np.asarray(point_cloud.colors) * 255
    print(f'colors {world_colors[0]}')

    # setting known values
    focal_length = 10000
    image_i = 500
    image_j = 500

    # separating x, y, z values into their own respective arrays
    x_points = world_points[:, 0]
    y_points = world_points[:, 1]
    z_points = world_points[:, 2]

    # camera views the scene from this position
    t_vec = np.array([[0, 0, 500]]).astype(np.float)

elif model == APARTMENTS_LYNX:
    # reading point cloud into numpy array
    apartment_file = "C:\\Users\\rdgrldkb\\Documents\\Apartments_Lynx.ply"
    point_cloud = o3d.io.read_point_cloud(apartment_file)

    fname_stub = 'output/apartments_lynx'

    world_points = np.asarray(point_cloud.points)

    # last three columns are point colors
    world_colors = np.asarray(point_cloud.colors) * 255
    print(f'colors {world_colors[0]}')

    # setting known values
    focal_length = 10000
    image_i = 500
    image_j = 500

    # separating x, y, z values into their own respective arrays
    x_points = world_points[:, 0]
    y_points = world_points[:, 1]
    z_points = world_points[:, 2]

    # camera views the scene from this position
    t_vec = np.array([[0, 0, 500]]).astype(np.float)

elif model == RANCH:
    # reading point cloud into numpy array
    ranch_file = "C:\\Users\\rdgrldkb\\Documents\\OberRanchRTC360_barn.ply"
    point_cloud = o3d.io.read_point_cloud(ranch_file)

    fname_stub = 'output/ranch'

    world_points = np.asarray(point_cloud.points)

    # last three columns are point colors
    world_colors = np.asarray(point_cloud.colors) * 255
    print(f'colors {world_colors[0]}')

    # setting known values
    focal_length = 8000
    image_i = 200
    image_j = 400

    # separating x, y, z values into their own respective arrays
    x_points = world_points[:, 0]
    y_points = world_points[:, 1]
    z_points = world_points[:, 2]

    # camera views the scene from this position
    t_vec = np.array([[0, 2, 900]]).astype(np.float)

elif model == SIMPLE:
    fname_stub = 'output/simple'
    focal_length = 5
    image_i = 50
    image_j = 50

    world_points = np.array([[0, 0, 0],  # origin
                            [1.0, 0, 0],  # x axis, red
                            [0, 1.0, 0],  # y axis, green
                            [0, 0, 1.0]])  # z axis, blue

    world_colors = np.array([[128, 0, 128],  # purple
                            [255, 0, 0],  # red
                            [0, 255, 0],  # green
                            [0, 0, 255]])  # blue

    x_points = [i[0] for i in world_points]
    y_points = [i[1] for i in world_points]
    z_points = [i[2] for i in world_points]

    t_vec = np.array([[0, 10, 0]]).astype(np.float)

elif model == SIMPLE2:
    fname_stub = 'output/simple2'

    world_points = np.array([[1.0, 1, 1],  # purple
                             [1, -1, 1],   # bright red
                             [-1, -1, 1],  # light green
                             [-1, 1, 1],   # light blue
                             [1, 1, -1],   # gray
                             [1, -1, -1],  # maroon
                             [-1, -1, -1], # dark green
                             [-1, 1, -1]]) # dark blue

    world_colors = np.array([[128, 0, 128],  # purple
                      [255, 0, 0],     # bright red
                      [0, 255, 0],     # light green
                      [0, 0, 255],     # light blue
                      [127, 127, 127],  # gray
                      [127, 0, 0],     # maroon
                      [0, 127, 0],     # dark green
                      [0, 0, 127]])    # dark blue

    focal_length = 10
    image_i = 50
    image_j = 50

    x_points = [i[0] for i in world_points]
    y_points = [i[1] for i in world_points]
    z_points = [i[2] for i in world_points]

    t_vec = np.array([[0, 0, 0.5]]).astype(np.float)

# name: convert_polar
# inputs: xyz - an array of xy points (nx32)
#         camPos - current camera position
# description: returns a list of thetas corresponding to the
# spherical polar coordinates for each xyz point
def convert_polar(xy, camPos):
    x = xy[:, 0] + camPos[0]
    y = xy[:, 1] + camPos[1]

    return np.degrees(np.arctan2(y, x))  # theta probably

# name: test_plot
# inputs: num - figure number
#         pts - points to plot
#         colors - colors corresponding to points in pts
# description: test function to plot
def test_plot(num, pts, colors):
    x_list = pts[:, 1]
    y_list = pts[:, 0]

    plt.figure(num)
    ax = plt.axes()
    ax.scatter(x_list, y_list, c=colors/255, s=0.01)

# name: keep_in_frame
# inputs: projected_pts - set of points projected to an image frame
# description: removes points outside of the viewing window
def keep_in_frame(projected_pts):
    # Find good points inside the window.  These will be points with:
    # 1 <= i <= image_i *and* 1 <= j <= image_j.
    # Find indices greater than 1 for i,j
    keep1 = np.where(np.min(projected_pts, axis=1) >= 1.0)

    # Find indices with i <= image_i
    keep2 = np.where(projected_pts[0:, 1] <= image_i)

    # Find indices with j <= image_j
    keep3 = np.where(projected_pts[0:, 0] <= image_j)

    # find the intersection of the keep indices
    keep = np.intersect1d(keep1, np.intersect1d(keep2, keep3))
    return keep

# name: keep_in_az
# inputs: wptsKeep - already reduced set of projected points
#         camPos - camera position
#         fov_low  - lower bound in degrees of fov
#         fov_high - upper bound in degrees of fov
# description: removes points outside of the camera's field of view
def keep_in_az(wptsKeep, camPos, fov_low, fov_high):
    wpts_keep_az = convert_polar(wptsKeep, camPos) - 90  # just getting theta

    # convert negative to positive
    wpts_keep_az[wpts_keep_az < 0] += 360

    # monkey business if low is negative
    if fov_low < 0:
        wpts_keep_az[wpts_keep_az >= (360 + fov_low)] -= 360

    # monkey business if high is over 360
    if fov_high > 360:
        wpts_keep_az[wpts_keep_az <= (fov_high - 360)] += 360

    keep_indices = np.argwhere(np.logical_and((wpts_keep_az >= fov_low), (wpts_keep_az <= fov_high)))
    return keep_indices, wpts_keep_az

# name: main
# inputs: wpts - point cloud model
# description: projects 3d point cloud to 2d at different angles
def main(wpts):

    world_points = wpts

    # field of view
    fov = np.degrees(np.arctan2(image_j / 2, focal_length))

    # getting the midpoints from each array so that the model can be centered at the origin
    xMid = np.mean([np.min(x_points), np.max(x_points)])
    yMid = np.mean([np.min(y_points), np.max(y_points)])
    zMid = np.mean([np.min(z_points), np.max(z_points)])

    offsets = [xMid, yMid, zMid]

    # center the model
    world_points -= offsets

    # assuming f_x = f_y and that there is no skew
    intrinsics = np.array([[focal_length, 0, image_j / 2],
                           [0, focal_length, image_i / 2],
                           [0, 0, 1.0]]).astype(np.float)

    # setting initial rotation values so we can rotate around the sides of the model
    rx = 90
    ry = 0
    rz = 0

    # loop through angles that are desired
    outer_start = time.time()
    for i in range(0, 31, 15):
        # base filename
        fname_base = f'{fname_stub}_{i}'
        fname_img = Path(f'{fname_base}.tif')

        # Image name to contain XYZ coordinates for each pixel in the
        # synthetic image.
        fname_xyz_img = Path(f'{fname_base}_xyz.tif')

        # Image name to contain depth values.
        fname_depth_img = Path(f'{fname_base}_depth.tif')

        # Image name to contain azimuth values.
        fname_az_img = Path(f'{fname_base}_az.tif')

        # remove files if they exist
        fname_img.unlink(missing_ok=True)
        fname_xyz_img.unlink(missing_ok=True)
        fname_depth_img.unlink(missing_ok=True)
        fname_az_img.unlink(missing_ok=True)

        img = np.zeros(shape=(image_i, image_j, 3), dtype=np.uint8)
        imgXYZ = np.empty(shape=(image_i, image_j, 3))
        img_depth = np.array(np.ones((image_i, image_j))*np.inf)
        img_az = np.empty(shape=(image_i, image_j))

        rz = i

        Rx = np.array([[1.0, 0, 0],
                      [0, cos(radians(rx)), -sin(radians(rx))],
                      [0, sin(radians(rx)), cos(radians(rx))]])

        Ry = np.array([[cos(radians(ry)), 0, sin(radians(ry))],
                       [0, 1.0, 0],
                       [-sin(radians(ry)), 0, cos(radians(ry))]])

        Rz = np.array([[cos(radians(rz)), -sin(radians(rz)), 0],
                       [sin(radians(rz)), cos(radians(rz)), 0],
                       [0, 0, 1.0]])

        R = np.matmul(np.matmul(Rz, Ry), Rx)

        # Get camera position to use in the code below to calculate depth.
        camPos = np.matmul(np.negative(np.transpose(R)), np.transpose(t_vec))
        print(camPos)

        # get rotation vector
        r_vec, _ = cv2.Rodrigues(R)
        # This is the money function.  Project world points to image points.
        projected_pts = cv2.projectPoints(world_points, r_vec, t_vec, intrinsics, distCoeffs=0)[0]

        # reshape to nx2
        projected_pts = projected_pts[0:, 0, 0:]

        # find which projected points are still in the frame
        keep = keep_in_frame(projected_pts)

        # Get keeper XYZ
        wptsKeep = world_points[keep]

        # Get keeper projected i,j points
        projected_pts = projected_pts[keep]

        # Get keeper colors
        colorsKeep = world_colors[keep]

        # find which points are behind the camera to avoid false projections
        keep_indices, wpts_keep_az = keep_in_az(wptsKeep, camPos, i-fov, i+fov)

        wptsKeep = wptsKeep[keep_indices]
        projected_pts = projected_pts[keep_indices]
        colorsKeep = colorsKeep[keep_indices]

        # reshape
        projected_pts = projected_pts[:, 0, :]
        colorsKeep = colorsKeep[:, 0, :]

        # making sure campos is the same shape as a point so the elements don't get
        # broadcasted weirdly in the depth calculation
        camPos = np.transpose(camPos)

        # Fill in data for TIFFs based on depth (we want the closest point if 2+ overlap)
        for n in range(0, (np.size(projected_pts, 0))):
            # Get current pixel i,j
            ii = round(projected_pts[n, 1]) - 1
            jj = round(projected_pts[n, 0]) - 1

            # Compute delta XYZ from the camera to the current point.
            d = np.linalg.norm(wptsKeep[n, :] - camPos)

            # if we already have a closer point in this pixel, skip the current one
            if d > img_depth[ii, jj]:
                continue

            # If we get here we have a good point.
            # Update depth map.
            img_depth[ii, jj] = d

            # Update RGB image.
            img[ii, jj, :] = colorsKeep[n, :]

            # Update XYZ image.
            imgXYZ[ii, jj, :] = wptsKeep[n, :] + offsets

            # Update azimuth image.
            img_az[ii, jj] = wpts_keep_az[n]

        # flipping everything correctly in the tiff file
        img = np.flip(img, 0)
        imgXYZ = np.flip(imgXYZ, 0)
        img_depth = np.flip(img_depth, 0)
        img_az = np.flip(img_az, 0)

        img = np.flip(img, 1)
        imgXYZ = np.flip(imgXYZ, 1)
        img_depth = np.flip(img_depth, 1)
        img_az = np.flip(img_az, 1)

        # Write out images.
        tiff.imwrite(fname_img, img)
        if write_xyz:
            tiff.imwrite(fname_xyz_img, imgXYZ)
        if write_depth:
            tiff.imwrite(fname_depth_img, img_depth)
        if write_az:
            tiff.imwrite(fname_az_img, img_az)

if __name__ == '__main__':
    main(world_points)


from collections import OrderedDict, defaultdict
from itertools import dropwhile
import re
import os
from os.path import join, isfile, isdir, basename, exists, dirname, realpath
import shutil
import traceback

from ngs_utils.logger import critical, err, info, warn, debug
from ngs_utils.file_utils import verify_dir, verify_file, splitext_plus, safe_mkdir, file_transaction, can_reuse

def _sample_name_special_chars(sn):
    fixed_sn = re.sub(r'[\W_]+', r'[\W_]+', sn)
    if fixed_sn.endswith('+'):
        fixed_sn = fixed_sn[:-1] + '*'
    return fixed_sn

def get_hiseq4000_miseq_regexp(sample, suf):
    # sn = ''.join(c for c in sample.name if c.isalnum() or c in ['-', '_', '.', '/'])
    return _sample_name_special_chars(sample.name) + '_S\d+_L\d\d\d_' + suf + '.*\.fastq\.gz'

def get_hiseq_regexp(sample, suf):
    # sn = ''.join(c for c in sample.name if c.isalnum() or c in ['-', '_', '.', '/'])
    return _sample_name_special_chars(sample.name) + '_' + sample.index + '_L\d\d\d_' + suf + '.*\.fastq\.gz'

def get_nextseq500_regexp(sample, suf):
    # sn = ''.join(c for c in sample.name if c.isalnum() or c in ['-', '_', '.', '/'])
    return _sample_name_special_chars(sample.name) + '_S\d+_' + suf + '.*\.fastq\.gz'

class DatasetStructure:
    pre_fastqc_repr = 'Preproc FastQC'
    downsample_targqc_repr = 'TargQC downsampled'

    @staticmethod
    def create(input_dir, proj_infos, samplesheet=None, **kwargs):
        if 'datasets/miseq/' in input_dir.lower():
            return MiSeqStructure(input_dir, proj_infos, samplesheet, **kwargs)

        elif 'datasets/hiseq/' in input_dir.lower():
            return HiSeqStructure(input_dir, proj_infos, samplesheet, **kwargs)

        elif 'datasets/hiseq4000/' in input_dir.lower():
            return HiSeq4000Structure(input_dir, proj_infos, samplesheet, **kwargs)

        elif 'datasets/nextseq500' in input_dir.lower():
            return NextSeq500Structure(input_dir, proj_infos, samplesheet, **kwargs)

        else:
            critical('Directory must be datasets/miseq/, datasets/nextseq500, datasets/hiseq/, or datasets/hiseq4000/. Found ' + input_dir)

    def __init__(self, input_dir, proj_infos, samplesheet=None, **kwargs):
        self.proj_infos = proj_infos

        illumina_project_name = None
        if '/Unalign' in input_dir:
            self.illumina_dir = input_dir.split('/Unalign')[0]
            self.unaligned_dirpath = self.__find_unaligned_dir()
            verify_dir(self.unaligned_dirpath, description='Unalign dir', is_critical=True)
            illumina_project_name = input_dir.split('/Unalign')[1].split('/', 1)[1]  # something like AURA.FFPE.AZ300, in contast with project_name which is something like Bio_123_AURA_FFPE_AZ300
            info('Processing sub-project ' + illumina_project_name)
        else:
            self.illumina_dir = input_dir
            self.unaligned_dirpath = self.__find_unaligned_dir()

        self.basecalls_dirpath = join(self.illumina_dir, 'Data/Intensities/BaseCalls')
        verify_dir(self.basecalls_dirpath, is_critical=True)

        self.basecalls_reports_dirpath = None
        self.bcl2fastq_dirpath = None
        self.source_fastq_dirpath = None

        if samplesheet:
            self.samplesheet_fpath = samplesheet
        else:
            self.samplesheet_fpath = self.__find_sample_sheet()
        self.project_by_name = self._parse_sample_sheet(self.samplesheet_fpath)

        if illumina_project_name:  # we want only a specific project
            if illumina_project_name not in self.project_by_name:
                info()
                critical('Err: project ' + illumina_project_name + ' not in the SampleSheet ' + self.samplesheet_fpath)
            else:
                self.project_by_name = {illumina_project_name: self.project_by_name[illumina_project_name]}

    def __find_unaligned_dir(self):
        unaligned_dirpath = join(self.illumina_dir, 'Unalign')
        if verify_dir(unaligned_dirpath, description='"Unalign" directory', silent=True):
            unaligned_dirpath = unaligned_dirpath
        else:
            unaligned_dirpath = None
            warn('No unalign directory')
        return unaligned_dirpath

    def __find_sample_sheet(self):
        ss_fpath = join(self.illumina_dir, 'SampleSheet.csv')
        if not isfile(ss_fpath):
            ss_fpath = join(self.basecalls_dirpath, 'SampleSheet.csv')
        verify_file(ss_fpath, description='Sample sheet', is_critical=True)
        return ss_fpath

    def _parse_sample_sheet(self, sample_sheet_fpath):
        info('Parsing sample sheet ' + sample_sheet_fpath)
        with open(sample_sheet_fpath) as f:
            def check_if_header(l):
                return any(l.startswith(w) for w in [
                    'Sample_ID,',  # MiSeq
                    'FCID,',       # HiSeq
                    'Lane,',       # HiSeq4000
                ])

            sample_lines = dropwhile(lambda l: not check_if_header(l), f)
            sample_infos = []
            keys = []
            for l in sample_lines:
                if check_if_header(l):
                    keys = l.strip().split(',')
                else:
                    fs = l.strip().split(',')
                    sample_infos.append(dict(zip(keys, fs)))

        project_by_name = OrderedDict()

        for i, info_d in enumerate(sample_infos):
            proj_name = info_d.get('Sample_Project', info_d.get('SampleProject', info_d.get('Project')))
            if proj_name is None:
                warn('  no SampleProject or Sample_Project or Project field in the SampleSheet ' + sample_sheet_fpath)
            elif not proj_name:
                warn('  SampleProject/Sample_Project/Project field is empty in the SampleSheet ' + sample_sheet_fpath)
                     # ', using ' + self.az_prjname_by_subprj[''])
                # proj_name = self.az_prjname_by_subprj['']
            proj_name = proj_name or ''
            if proj_name is not None and proj_name not in project_by_name:
                project_by_name[proj_name] = DatasetProject(proj_name)
            project = project_by_name[proj_name]

            sname = info_d.get('Sample_Name') or info_d.get('SampleName') or info_d.get('SampleRef')
            if sname in project.sample_by_name:
                s = project.sample_by_name[sname]
                s.lane_numbers.add(info_d.get('Lane', 1))  # lanes are in HiSeq and HiSeq4000 (not in MiSeq!)
            else:
                s = DatasetSample(sname, index=info_d.get('index', info_d.get('Index')))
                info('  ' + proj_name + ': ' + s.name)
                s.lane_numbers.add(info_d.get('Lane', 1))  # lanes are in HiSeq and HiSeq4000 (not in MiSeq!)
                if 'FCID' in info_d:
                    s.fcid = info_d['FCID']  # HiSeq only
                project.sample_by_name[sname] = s
                # sample_names.append(info_d[key].replace(' ', '-') + '_' + info_d['Index'] + '_L%03d' % lane)
                # sample_names.append(info_d[key].replace(' ', '-').replace('_', '-') + '_S' + str(i + 1) + '_L001')

        return project_by_name

    def _get_output_dir(self, proj_infos, pname):
        if len(proj_infos) != len(self.project_by_name):
            critical('The number of projects in the input config != the number of projects SampleSheet')

        analysis_dir = None
        output_dir = None
        az_proj_name = None
        if len(proj_infos) == 1:
            analysis_dir = list(proj_infos.values())[0].analysis_dir
            output_dir = list(proj_infos.values())[0].output_dir
            az_proj_name = list(proj_infos.values())[0].project_name
        elif pname in proj_infos:
            analysis_dir = proj_infos[pname].analysis_dir
            output_dir = proj_infos[pname].output_dir
            az_proj_name = proj_infos[pname].project_name
        else:
            critical('Error: cannot correspond the subproject name in the SampleSheet (' + pname + ') and the lines in the conf. ' +
                 'Please, follow the SOP for multiple-project run: http://wiki.rd.astrazeneca.net/display/NG/SOP+-+Pre+Processing+QC+Reporting')
        safe_mkdir(output_dir)
        return analysis_dir, output_dir, az_proj_name

class HiSeqStructure(DatasetStructure):
    def __init__(self, input_dir, proj_infos, samplesheet=None, **kwargs):
        info('Parsing the HiSeq project structure')
        self.kind = 'hiseq'
        DatasetStructure.__init__(self, input_dir, proj_infos, samplesheet=samplesheet, **kwargs)

        verify_dir(self.unaligned_dirpath, is_critical=True)

        self.basecall_stat_html_reports = self.__get_basecall_stats_reports()

        for pname, project in self.project_by_name.items():
            ds_proj_dir = join(self.unaligned_dirpath, 'Project_' + pname.replace(' ', '-'))  #.replace('-', '_').replace('.', '_'))

            analysis_dir, output_dir, az_proj_name = self._get_output_dir(proj_infos, pname)

            project.set_dirpath(ds_proj_dir, analysis_dir, output_dir, az_proj_name)
            for sname, sample in project.sample_by_name.items():
                sample.source_fastq_dirpath = join(project.ds_dir, 'Sample_' + sname.replace(' ', '-'))  #.replace('-', '_').replace('.', '_'))
                sample.set_up_out_dirs(project.fastq_dirpath, project.fastqc_dirpath, project.downsample_targqc_dirpath)

            basecalls_symlink = join(project.ds_dir, 'BaseCallsReports')
            if not exists(basecalls_symlink):
                info('Creating BaseCalls symlink ' + self.basecalls_dirpath + ' -> ' + basecalls_symlink)
                try:
                    os.symlink(self.basecalls_dirpath, basecalls_symlink)
                except OSError:
                    err('Cannot create symlink')
                    traceback.print_exc()
                else:
                    info('Created')
            if exists(basecalls_symlink):
                self.basecalls_dirpath = basecalls_symlink

        self.get_fastq_regexp_fn = get_hiseq_regexp

    # def __get_bcl2fastq_dirpath(self):
    #     # Reading project name
    #     bcl2fastq_dirpath = None
    #     try:
    #         bcl2fastq_dirpath = join(self.unaligned_dirpath, next(fn for fn in os.listdir(self.unaligned_dirpath) if fn.startswith('Project_')))
    #     except StopIteration:
    #         critical('Could not find directory starting with Project_ in ' + self.unaligned_dirpath)
    #     return bcl2fastq_dirpath

    def __get_basecall_stats_reports(self):
        basecall_stats_dirnames = [fname for fname in os.listdir(self.unaligned_dirpath) if fname.startswith('Basecall_Stats_')]
        if len(basecall_stats_dirnames) > 1:
            err('More than 1 Basecall_Stats_* dirs found in unalign_dirpath')
        if len(basecall_stats_dirnames) == 0:
            err('No Basecall_Stats_* dirs found in unalign_dirpath')
        if len(basecall_stats_dirnames) == 1:
            self.basecalls_reports_dirpath = join(self.unaligned_dirpath, basecall_stats_dirnames[0])
            basecall_reports = [verify_file(join(self.basecalls_reports_dirpath, html_fname)) for html_fname in
                                ['Demultiplex_Stats.htm', 'All.htm', 'IVC.htm']]
            return filter(None, basecall_reports)

class MiSeqStructure(DatasetStructure):
    def __init__(self, input_dir, proj_infos, samplesheet=None, **kwargs):
        info('Parsing the MiSeq project structure')
        self.kind = 'miseq'
        DatasetStructure.__init__(self, input_dir, proj_infos, samplesheet=samplesheet, **kwargs)

        base_dirpath = self.unaligned_dirpath
        if not verify_dir(base_dirpath, silent=True):
            base_dirpath = self.basecalls_dirpath
        verify_dir(base_dirpath, description='Source fastq dir')

        for pname, project in self.project_by_name.items():
            ds_proj_dir = join(base_dirpath, pname)
            if not verify_dir(ds_proj_dir, silent=True):
                ds_proj_dir = base_dirpath

            analysis_dir, output_dir, az_proj_name = self._get_output_dir(proj_infos, pname)

            project.set_dirpath(ds_proj_dir, analysis_dir, output_dir, az_proj_name)
            for sample in project.sample_by_name.values():
                sample.source_fastq_dirpath = project.ds_dir
                sample.set_up_out_dirs(project.fastq_dirpath, project.fastqc_dirpath, project.downsample_targqc_dirpath)

        self.basecall_stat_html_reports = self.__get_basecall_stats_reports()
        if self.basecall_stat_html_reports:
            info('basecall_stat_html_reports: ' + str(self.basecall_stat_html_reports))

        self.get_fastq_regexp_fn = get_hiseq4000_miseq_regexp

    def __find_fastq_dir(self):
        for dname in os.listdir(self.unaligned_dirpath):
            dpath = join(self.unaligned_dirpath, dname)
            if isdir(dpath) and any(f.endswith('.fastq.gz') for f in os.listdir(dpath)):
                return dpath

    def __get_basecall_stats_reports(self):
        self.basecalls_reports_dirpath = join(self.unaligned_dirpath, 'Reports', 'html')
        index_html_fpath = join(self.basecalls_reports_dirpath, 'index.html')
        if verify_dir(self.illumina_dir) and verify_file(index_html_fpath):
            return [index_html_fpath]

class HiSeq4000Structure(DatasetStructure):
    def __init__(self, input_dir, proj_infos, samplesheet=None, **kwargs):
        info('Parsing the HiSeq4000 project structure')
        self.kind = 'hiseq4000'
        DatasetStructure.__init__(self, input_dir, proj_infos, samplesheet=samplesheet, **kwargs)

        verify_dir(self.unaligned_dirpath, is_critical=True)

        for pname, project in self.project_by_name.items():
            ds_proj_dir = join(self.unaligned_dirpath, pname)

            analysis_dir, output_dir, az_proj_name = self._get_output_dir(proj_infos, pname)

            project.set_dirpath(ds_proj_dir, analysis_dir, output_dir, az_proj_name)
            for sample in project.sample_by_name.values():
                sample.source_fastq_dirpath = project.ds_dir
                sample.set_up_out_dirs(project.fastq_dirpath, project.fastqc_dirpath, project.downsample_targqc_dirpath)

        self.basecall_stat_html_reports = self.__get_basecall_stats_reports()
        info('basecall_stat_html_reports: ' + str(self.basecall_stat_html_reports))

        self.get_fastq_regexp_fn = get_hiseq4000_miseq_regexp

    def __find_fastq_dir(self):
        for dname in os.listdir(self.unaligned_dirpath):
            dpath = join(self.unaligned_dirpath, dname)
            if isdir(dpath) and any(f.endswith('.fastq.gz') for f in os.listdir(dpath)):
                return dpath

    def __get_basecall_stats_reports(self):
        self.basecalls_reports_dirpath = join(self.unaligned_dirpath, 'Reports', 'html')
        index_html_fpath = join(self.basecalls_reports_dirpath, 'index.html')
        if verify_dir(self.illumina_dir) and verify_file(index_html_fpath):
            return [index_html_fpath]

class NextSeq500Structure(DatasetStructure):
    def __init__(self, input_dir, proj_infos, samplesheet=None, **kwargs):
        info('Parsing the NextSeq500 project structure')
        self.kind = 'nextseq500'
        DatasetStructure.__init__(self, input_dir, proj_infos, samplesheet=samplesheet, **kwargs)
        debug('proj_infos: ' + str(proj_infos))

        verify_dir(self.unaligned_dirpath, is_critical=True)

        for pname, project in self.project_by_name.items():
            analysis_dir, output_dir, az_proj_name = self._get_output_dir(proj_infos, pname)

            project.set_dirpath(self.unaligned_dirpath, analysis_dir, output_dir, az_proj_name)
            for sample in project.sample_by_name.values():
                sample.source_fastq_dirpath = project.ds_dir
                sample.set_up_out_dirs(project.fastq_dirpath, project.fastqc_dirpath, project.downsample_targqc_dirpath)

        self.basecall_stat_html_reports = self.__get_basecall_stats_reports()

        self.get_fastq_regexp_fn = get_nextseq500_regexp

    def __find_fastq_dir(self):
        for dname in os.listdir(self.unaligned_dirpath):
            dpath = join(self.unaligned_dirpath, dname)
            if isdir(dpath) and any(f.endswith('.fastq.gz') for f in os.listdir(dpath)):
                return dpath

    def __get_basecall_stats_reports(self):
        self.basecalls_reports_dirpath = join(self.unaligned_dirpath, 'Reports', 'html')
        index_html_fpath = join(self.basecalls_reports_dirpath, 'index.html')
        if verify_dir(self.basecalls_reports_dirpath) and verify_file(index_html_fpath):
            return [index_html_fpath]

class DatasetProject:
    def __init__(self, name):
        self.name = name
        self.sample_by_name = OrderedDict()
        self.ds_dir = None
        self.output_dir = None
        self.analysis_dir = None
        self.az_project_name = None

        self.fastq_dirpath = None
        self.fastqc_dirpath = None
        self.downsample_metamapping_dirpath = None
        self.downsample_targqc_dirpath = None
        self.downsample_targqc_report_fpath = None
        self.multiqc_report_html_fpath = None
        self.mergred_dir_found = False

    def set_dirpath(self, ds_dir, analysis_dir, output_dir, az_project_name):
        self.ds_dir = ds_dir
        self.output_dir = output_dir.format(ds_proj_name=self.name)
        self.analysis_dir = analysis_dir
        self.az_project_name = az_project_name
        verify_dir(self.ds_dir, is_critical=True)

        found_merged_dirpath = join(self.ds_dir, 'merged')
        if verify_dir(found_merged_dirpath, silent=True):
            self.mergred_dir_found = True
            self.fastq_dirpath = self.fastqc_dirpath = found_merged_dirpath
        else:
            self.fastq_dirpath = join(self.ds_dir, 'fastq')
            try:
                safe_mkdir(self.fastq_dirpath)
            except:
                self.fastq_dirpath = join(self.output_dir, 'fastq')
            self.fastqc_dirpath = join(self.output_dir, 'FastQC')
        info()

        self.downsample_targqc_report_fpath = None
        self.multiqc_report_html_fpath = join(self.output_dir, 'multiqc_report.html')

        self.downsample_metamapping_dirpath = join(self.output_dir, 'Downsample_MetaMapping')
        self.downsample_targqc_dirpath = join(self.output_dir, 'Downsample_TargQC')
        self.downsample_targqc_report_fpath = join(self.downsample_targqc_dirpath, 'summary.html')

    def concat_fastqs(self, get_fastq_regexp):
        info('Preparing fastq files for the project named ' + self.name or self.az_project_name)
        if self.mergred_dir_found:
            info('  found already merged fastq dir, skipping.')
            return
        if not self.sample_by_name:
            err('  no samples found.')
            return
        try:
            if not isdir(self.fastq_dirpath):
                safe_mkdir(self.fastq_dirpath)
                open(join(self.fastq_dirpath, 'folder_created_by_prealign'), 'a').close()
        except OSError as e:
            err('Error: cannot write to ' + self.fastq_dirpath + '(' + str(e) + '). ' +
                'Writing fastq to ' + join(self.output_dir, 'fastq') + ' instead')
            self.fastq_dirpath = join(self.output_dir, 'fastq')

        try:
            fastqc_symlink = join(self.fastq_dirpath, 'FastQC')
            if not exists(fastqc_symlink):
                os.symlink(self.fastqc_dirpath, fastqc_symlink)
        except OSError:
            pass

        for s in self.sample_by_name.values():
            _concat_fastq(s.find_raw_fastq(get_fastq_regexp, 'R1'), s.l_fpath)
            _concat_fastq(s.find_raw_fastq(get_fastq_regexp, 'R2'), s.r_fpath)
        info()

class DatasetSample:
    def __init__(self, name, index=None, source_fastq_dirpath=None):
        self.name = re.sub(r'[\W_]', r'_', name)
        self.index = index

        self.fastq_dirpath = None
        self.source_fastq_dirpath = source_fastq_dirpath
        self.l_fpath = None
        self.r_fpath = None

        self.fastqc_dirpath = None
        self.l_fastqc_base_name = None
        self.r_fastqc_base_name = None
        self.l_fqc_sample = None
        self.r_fqc_sample = None

        self.lane_numbers = set()
        self.fcid = None  # for HiSeq

        self.targqc_sample = None
        self.downsample_targqc_dirpath = None

    def set_up_out_dirs(self, fastq_dirpath, fastqc_dirpath, downsample_targqc_dirpath):
        self.fastq_dirpath = fastq_dirpath
        self.fastqc_dirpath = fastqc_dirpath
        self.downsample_targqc_dirpath = downsample_targqc_dirpath

        self.l_fpath = join(fastq_dirpath, self.name + '_R1.fastq.gz')
        self.r_fpath = join(fastq_dirpath, self.name + '_R2.fastq.gz')

        # self.sample_fastqc_dirpath = join(fastqc_dirpath, self.name + '.fq_fastqc')
        # self.fastqc_html_fpath = join(fastqc_dirpath, self.name + '.fq_fastqc.html')
        self.l_fastqc_base_name = splitext_plus(basename(self.l_fpath))[0]
        self.r_fastqc_base_name = splitext_plus(basename(self.r_fpath))[0]
        # self.l_fastqc_html_fpath = None  # join(ds.fastqc_dirpath,  + '_fastqc.html')
        # self.r_fastqc_html_fpath = None  # join(ds.fastqc_dirpath, splitext_plus(self.r_fpath)[0] + '_fastqc.html')

        # if not isfile(self.fastqc_html_fpath):
        #     self.fastqc_html_fpath = join(self.sample_fastqc_dirpath, 'fastqc_report.html')

        # self.targqc_sample = targqc.Sample(self.name, join(downsample_targqc_dirpath, self.name), )
        # self.targqc_html_fpath = self.targqc_sample.targqc_html_fpath

    def find_raw_fastq(self, get_regexp, suf='R1'):
        fastq_fpaths = [
            join(self.source_fastq_dirpath, fname)
                for fname in os.listdir(self.source_fastq_dirpath)
                if re.match(get_regexp(self, suf), fname)]
        fastq_fpaths = sorted(fastq_fpaths)
        if not fastq_fpaths:
            critical('Error: no fastq files for the sample ' + self.name +
                     ' were found inside ' + self.source_fastq_dirpath)
        info(self.name + ': found raw fastq files ' + ', '.join(fastq_fpaths))
        return fastq_fpaths

def _concat_fastq(fastq_fpaths, output_fpath):
    if len(fastq_fpaths) == 1:
        if not isfile(output_fpath):
            info('  no need to merge - symlinking ' + fastq_fpaths[0] + ' -> ' + output_fpath)
            if not isdir(dirname(output_fpath)):
                safe_mkdir(output_fpath)
                critical('Dir for the symlink ' + dirname(output_fpath) + ' does not exist')
            os.symlink(fastq_fpaths[0], output_fpath)
            return output_fpath
    else:
        info('  merging ' + ', '.join(fastq_fpaths))
        if can_reuse(output_fpath, fastq_fpaths):
            info(output_fpath + ' exists, reusing')
        else:
            with file_transaction(None, output_fpath) as tx:
                with open(tx, 'wb') as out:
                    for fq_fpath in fastq_fpaths:
                        with open(fq_fpath, 'rb') as inp:
                            shutil.copyfileobj(inp, out)
        return output_fpath


import math

class Interval1D:

    def __init__(self, lo, hi):
        if math.isinf(lo) or math.isinf(hi):
            raise ValueError('Endpoints must be finite')
        if math.isnan(lo) or math.isnan(hi):
            raise ValueError('Endpoints cannot be NaN')

        if lo <= hi:
            self.__lo = lo
            self.__hi = hi
        else:
            raise ValueError('Illegal interval')

    def __repr__(self) -> str:
        return '[' + str(self.__lo) + ',' + str(self.__hi) + ']'

    def intersect(self, that):
        if self.__lo > that.__hi:
            return False
        if self.__hi < that.__lo:
            return False
        return True