"""
Model Share
===========

Provides functions that are common to all models in the TAMOC suite

This module defines functions that perform standard tasks for the modeling
modules in the TAMOC suite.  These include standard authoring of output
files and reading ambient data from output files.

Notes
-----
These class objects and helper functions may be used throughout the TAMOC
modeling suite.

"""
# S. Socolofsky, November 2014, Texas A&M University <socolofs@tamu.edu>.

from __future__ import (absolute_import, division, print_function)

from tamoc import ambient

from netCDF4 import Dataset
from datetime import datetime
import os
from warnings import warn

# ----------------------------------------------------------------------------
# Functions to work with netCDF datasets of model output
# ----------------------------------------------------------------------------

def tamoc_nc_file(fname, title, summary, source):
    """
    Write the header meta data to an netCDF file for a TAMOC output

    The TAMOC suite stores its output by detaul in a netCDF dataset file.
    This function writes the standard TAMOC metadata to the header of the
    netCDF file.

    Parameters
    ----------
    fname : str
        File name of the file to write
    title:  str
        String stating the TAMOC module where the data originated and the
        type of data contained.
    summary : str
        String summarizing what is contained in the dataset or information
        needed to interpret the dataset
    source : str
        String describing the source of the data in the dataset or of related
        datasets

    Returns
    -------
    nc : `netCDF4.Dataset` object
        The `netCDF4.Dataset` object containing the open netCDF4 file where
        the data should be stored.

    """

    # Create the netCDF dataset object
    nc = Dataset(fname, 'w', format='NETCDF4_CLASSIC')

    # Write the netCDF header data for a TAMOC suite output
    nc.Conventions = 'TAMOC Modeling Suite Output File'
    nc.Metadata_Conventions = 'TAMOC Python Model'
    nc.featureType = 'profile'
    nc.cdm_data_type = 'Profile'
    nc.nodc_template_version = \
        'NODC_NetCDF_Profile_Orthogonal_Template_v1.0'
    nc.title = title
    nc.summary = summary
    nc.source = source
    nc.creator_url = 'http://github.com/socolofs/tamoc'
    nc.date_created = datetime.today().isoformat(' ')
    nc.date_modified = datetime.today().isoformat(' ')
    nc.history = 'Creation'

    # Return the netCDF dataset
    return nc

def profile_from_model_savefile(nc, fname, ctdname=None):
    """
    Load the `ambient.Profile` data pointed to by the netCDF file

    Each netCDF model save file for the TAMOC suite models stores the file
    name and path to the ambient CTD data used in the simulation.  This
    prevents the save files from having to encapsulate all of the ambient
    CTD data with results for every simulation run.  This block of code
    looks for the ambient data and loads it into memory if found.

    Parameters
    ----------
    nc : `netCDF4.Dataset` object
        The netCDF dataset object containing the saved model simulation

    fname : str
        File name of the netCDF file.  This is used to get the complete
        path to the current directory so that the Profile data can be found.

    Returns
    -------
    profile : `ambient.Profile` object
        The profile data as an `ambient.Profile` object.

    See Also
    --------
    single_bubble_model.Model.save_sim, stratified_plume_model.Mode.save_sim,
    bent_plume_model.Model.save_sim

    Notes
    -----
    If the profile data are not found, a message is echoed to the command
    line.  No other warnings or errors are thrown.

    """
    try:
        # Try to locate and load in the profile data
        nc_path = os.path.normpath(os.path.join(os.getcwd(), \
                                   os.path.dirname(fname)))
        if ctdname is not None:
            prf_path = os.path.normpath(os.path.join(nc_path, ctdname))
        else:
            prf_path = os.path.normpath(os.path.join(nc_path, nc.summary))
        amb_data = Dataset(prf_path)
        profile = ambient.Profile(amb_data, chem_names='all')
        profile.close_nc()

    except IOError:
        # Tell user that profile data read failed
        message = ['File not found: %s' % prf_path]
        message.append(' ... Continuing without profile data')
        warn(''.join(message))
        profile = None

    # Send back the final profile object
    return profile


import json
import numpy as np
import xarray as xr
import turkr.mturk.manage_hit
import turkr.qualifications.qual_utils as qual_utils

DEFAULT_BONUS_USD_PER_REWARD = 0.0025

QUALIFICATION_IDS = {
    'IS_PREVIOUS_WORKER_TOKEN_QUALIFICATION_TYPEID':'3P3HAQ0W8GNHNPOIEDB8HR4LTP3I0P',
    'sandboxIS_PREVIOUS_WORKER_TOKEN_QUALIFICATION_TYPEID':'3X9YVAW8NUMPS8W7XHFYIZSXBXH4K5',
    'LOW_WARMUP_TASK':'3Y9OUGTYA7OC9QNI42VNEHLP09VJEP',
    'sandboxLOW_WARMUP_TASK': '3S62YK7QBY6O37DV3X0OHPYCNM2DQV',
}

def _get_bonus_amount_for_sequence(sequence_data:dict):
    errors = []

    """
    cur_subtask['max_bonus_usd'],
    cur_subtask['min_performance_for_bonus'],
    """
    coords = sequence_data['coords']
    max_bonus_usd = coords['max_bonus_usd']
    min_performance_for_bonus = coords['min_performance_for_bonus']

    data_vars = sequence_data['data_vars']
    perf_seq = data_vars['perf']

    average_perf = np.mean(perf_seq)

    bonus_amount_usd = max_bonus_usd / (1 - min_performance_for_bonus) * (average_perf - min_performance_for_bonus)
    bonus_amount_usd = np.max(bonus_amount_usd, 0)

    return bonus_amount_usd

def get_total_bonus(answer:dict):

    behavioral_data = answer['data']

    total_usd_reward = 0
    for i_sequence, sequence_data in enumerate(behavioral_data):

        cur_bonus = _get_bonus_amount_for_sequence(sequence_data=sequence_data)
        total_usd_reward += (cur_bonus)

    return total_usd_reward

def evaluate_warmup_behavior(answer:dict):
    """
    Ascertains whether the subject "goofed off" on the warmup task, defined as taking 60 trials to complete instead of exiting early from 9/10 rolling performance
    """

    errors = []
    if 'data' not in answer:
        errors.append('Could not find key "data" in answer; found only keys %s' % (str(answer.keys())))
        return False, errors

    behavioral_data = answer['data']
    # Validate answer data
    if not isinstance(behavioral_data, list):
        errors.append('Expected behavioral data to be a list, but is a %s'%(type(behavioral_data)))
        return False, errors

    if len(behavioral_data) == 0:
        errors.append('Did not find any behavioral data')
        behavioral_data = [{'data_vars':{'perf':[]}}]

    warmup_data = behavioral_data[0]
    if not isinstance(warmup_data, dict):
        errors.append('Warmup sequence data was expected to be a dict, but got%s'%(str(type(warmup_data))))
        perf = []

    if 'perf' not in warmup_data['data_vars']:
        errors.append('Could not find key "perf" in warmup_data["data_vars"]; found only %s. Defaulting to []' % (str(warmup_data['data_vars'].keys())))
        perf = []
    else:
        perf = warmup_data['data_vars']['perf']

        if not isinstance(perf, list):
            errors.append('Could not identify a list of performance outcomes; got %s of dtype %s' % (str(perf), type(perf)))
            perf = []
    ntrials_to_complete = len(perf)

    if (ntrials_to_complete) >= 60:
        print('Detected `goof off\' subject' )
        return True, errors

    return False, errors

def extract_answer(asn):
    parse_errors = []
    try:
        answer = asn['Answer']
        answer = answer.split('<FreeText>')[-1].split('</FreeText>')[0]
        answer = json.loads(answer)
    except Exception as e:
        parse_errors.append(str(e))
        answer = {}

    return answer, parse_errors

def assignment_post_process_function(
        client,
        asn: dict,
):
    # This function does 5 things:
    # 1) Approves the assignment in any case.
    # 2) Grants the "previous worker" qualification in any case.
    # 2) If possible, identify a valid bonus amount, and pay the worker.
    # 3) Returns any JavaScript runtime errors the worker encountered.
    # 4) Returns a list of failures from attempting to extract the answer and extract the bonus. If there are no errors, returns None instead.

    errors = []

    assignment_id = asn['AssignmentId']
    worker_id = asn['WorkerId']

    # Approve the assignment, if not already approved
    if(asn['AssignmentStatus'] != 'Approved'):
        try:
            turkr.mturk.manage_hit.approve_assignment(assignment_id=assignment_id, client=client)
            print('(workerId:%s, assignmentId:%s): approved' % (worker_id, assignment_id))
        except:
            pass

    # Grant a dicarlo lab "previous worker" qualification
    sandbox = 'sandbox' in client.meta.endpoint_url.lower()

    if sandbox:
        qual_id = QUALIFICATION_IDS['sandboxIS_PREVIOUS_WORKER_TOKEN_QUALIFICATION_TYPEID']
    else:
        qual_id = QUALIFICATION_IDS['IS_PREVIOUS_WORKER_TOKEN_QUALIFICATION_TYPEID']

    ncompleted = qual_utils.get_current_qual_value(client=client, worker_id=worker_id, qualification_type_id=qual_id)
    if ncompleted is None:
        ncompleted = 0

    # Extract answer string and convert to JSON
    answer, parse_errors = extract_answer(asn)
    errors.extend(parse_errors)

    # Attempt to extract bonus amount.
    bonus_usd = get_total_bonus(answer)

    # Pay worker if a bonus was earned
    if bonus_usd > 0:
        try:
            if turkr.mturk.manage_hit.grant_bonus(worker_id=worker_id, assignment_id=assignment_id, bonus_usd=bonus_usd, client=client):
                qual_utils.grant_qualification(client=client, worker_id=worker_id, qualification_type_id=qual_id, value=ncompleted + 1)
                print('(workerId:%s, assignmentId:%s): Marked as having performed %d tasks' % (worker_id, assignment_id, ncompleted + 1))
        except Exception as e:
            print('Failed to grant bonus: ')
            print(e)
    # Print and return any errors
    if len(errors) == 0:
        return None
    else:
        for e in errors:
            print('(workerId:%s, assignmentId:%s):'%(worker_id, assignment_id), e)
        return errors

def to_dataset(assignment_json:dict):

    answer, errors = extract_answer(assignment_json)
    answer = answer['data']

    # Attach session coords

    dlist = []
    for cur in answer:
        data_vars = cur['data_vars']
        coords = cur['coords']

        # Adjust timestamps to be in Unix time (seconds since epoch start)
        timestamp_session_start = float(coords['timestamp_session_start'])

        coords['timestamp_session_start'] = timestamp_session_start/1000
        data_vars['timestamp_start'] = (timestamp_session_start + np.array(data_vars['rel_timestamp_start']))/1000
        data_vars['timestamp_stimulus_on'] = (timestamp_session_start + np.array(data_vars['rel_timestamp_stimulus_on']))/1000
        data_vars['timestamp_stimulus_off'] = (timestamp_session_start + np.array(data_vars['rel_timestamp_stimulus_off']))/1000
        data_vars['timestamp_choices_on'] = (timestamp_session_start + np.array(data_vars['rel_timestamp_choices_on']))/1000

        del data_vars['rel_timestamp_start']
        del data_vars['rel_timestamp_stimulus_on']
        del data_vars['rel_timestamp_stimulus_off']
        del data_vars['rel_timestamp_choices_on']

        # Unpack URLs
        if 'stimulus_url_prefix' in coords:
            stimulus_url_prefix = coords['stimulus_url_prefix']
            stimulus_urls = [stimulus_url_prefix + suffix for suffix in data_vars['stimulus_url_suffix']]
            del coords['stimulus_url_prefix']
            del data_vars['stimulus_url_suffix']
            data_vars['stimulus_url'] = stimulus_urls

        # Attach trial coordinate
        ntrials = None
        for k in data_vars:
            if ntrials is not None:
                assert ntrials == len(data_vars[k]), 'Key %s has length %d, but assumed to have length %d'%(k, len(data_vars[k]), ntrials)
            ntrials = len(data_vars[k])
            data_vars[k] = (['trial_sequence'], data_vars[k])

        coords['trial_sequence'] = np.arange(ntrials)

        ds = xr.Dataset(data_vars = cur['data_vars'], coords = cur['coords'], )

        dlist.append(ds)

    if len(dlist) == 0:
        return None
    ds_all = xr.concat(dlist, 'slot', coords = 'all')
    ds_all['slot'] = np.arange(len(answer))
    ds_all = ds_all.assign_coords(worker_id = assignment_json['WorkerId'])
    ds_all = ds_all.assign_coords(assignment_id=assignment_json['AssignmentId'])
    ds_all = ds_all.assign_coords(timestamp_session_submit=assignment_json['SubmitTime'])

    session_duration_sec = (ds_all.timestamp_start.max() - ds_all.timestamp_start.min())
    ds_all = ds_all.assign_coords(session_duration_sec = session_duration_sec)

    ds_all = ds_all.rename({'trial_sequence':'trial'})

    return ds_all


# coding: utf-8
import ctypes
import time

def get_display_name():
    GetUserNameEx = ctypes.windll.secur32.GetUserNameExW
    NameDisplay = 3

    size = ctypes.pointer(ctypes.c_ulong(0))
    GetUserNameEx(NameDisplay, None, size)

    nameBuffer = ctypes.create_unicode_buffer(size.contents.value)
    GetUserNameEx(NameDisplay, nameBuffer, size)
    return nameBuffer.value

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 8377))

keyOwnerIp = ""

while True:
        sock.listen(5)
        client, address = sock.accept()
        print("{} connected".format( address ))

        response = client.recv(255)
        if response != "":
                print(response)
                keyOwnerIp = address[0]
                break
port = 8376

time.sleep(10)
print(get_display_name(), (keyOwnerIp, port))
time.sleep(1)

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((keyOwnerIp, port))
print("Connection on {}".format(port))

socket.send(bytes(get_display_name(), "utf-8"))

print ("Close")
client.close()
sock.close()


#! /usr/bin/env python
######################
#Authors: Sarah Habib
#	  Orlando Melchor-Alonso
#Last Updated: 2018/07/24
######################
#Objective: create an animation for the components and superposition of sound signals
######################

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from math import pi, sin
import soundtest as st
import sys
import time
import pyaudio
from sklearn.ensemble import RandomForestClassifier
import pickle

#directories
model_dir = 'models/'

#number of harmonics to read
numNotes = int(sys.argv[1])

##########FFT of mic input##########
Format   = pyaudio.paInt16
Channels = 1                  #stero currently not supported

#parameters below here must be powers of 2 for a faster fft
Rate       = pow(2,16)        #near double the highest audible frequency
Chunk      = pow(2,10)        #1024 bit
Rec_secs   = pow(2,-1)        #duration in seconds (more secs means more samples so must reshape using this)
noise_secs = pow(2,3)		  #duration in seconds for nosie gathering (more secs means more samples so must reshape using this)

#parameters below here do not have to be powers of 2
min_freq = 29                #min detected frequency (lowest audible)
max_freq = 20000 	          #max detected frequency (highest audible)
cents    = 200		          #amount to remove around peak frequency (in cents) once it is found

noteNames='C C# D D# E F F# G G# A A# B'.split() # names for all the notes ## are there more?

def freq_to_MIDI(f):
	if f == 0:
		return 0
	'''Converts frequency to MIDI number'''
	return 69 + 12*np.log2(f/440.0)

def MIDI_to_name(n):
	if n == 0:
		return ''
	'''Converts MIDI number to note names'''
	return noteNames[int(n % 12)] + str(int(n/12) - 1)

#collect signal every Rec_secs seconds
def collect_signal(rec=Rec_secs):
	frames = []
	for i in range(0, int(Rate/Chunk*rec)):
		data = stream.read(Chunk)
		frames.append(data)
	frames = b''.join(frames)
	signal = np.fromstring(frames, 'Int16')
	return signal

#detect the first n harmonics from mic
def sample_sound(n):
	#filter background noise by subtracting it out
	signal = collect_signal()
	#use real one dimensional fft
	FFT = np.abs(np.fft.rfft(signal,norm='ortho'))
	#filter above certain threshold and remove low and high pass
	filter_FFT(FFT)
	#determine harmonics
	f0, amp = harmonic_detector(FFT, n)
	#get all harmonics above the root
	f0_idx = model.predict([f0])
	f = f0[f0>=f0[f0_idx]]
	amp = amp[f0>=f0[f0_idx]]
	#pad the missing harmonics with zeros
	padding = f0.shape[0] - f.shape[0]
	f = np.pad(f, (0,padding), 'constant')
	amp = np.pad(amp, (0,padding), 'constant')
	return f, amp

#gather noise to remove from the signal
def collect_noise(rec=noise_secs):
	noise = collect_signal(rec)
	rec_mult = noise.shape[0]//signal.shape[0]
	#take the average of the noise signal over equal Rec_secs intervals
	noise = noise.reshape(rec_mult,-1)
	return np.mean(np.abs(np.fft.rfft(noise)),axis=0)

#filters the FFT using from threshold and low/high pass filter
def filter_FFT(FFT):
	#must first resize filters
	low_pass  = int(min_freq*Rec_secs)
	high_pass = int(max_freq*Rec_secs)
	#low pass filter
	FFT[:low_pass] = 0
	#high paas filter
	FFT[high_pass:] = 0
	#remove noise within a certain percent of max
	FFT[FFT < thresh] = 0

#detects the peak frequencies in an FFT
def harmonic_detector(FFT, numHarm):
	harmonics = np.zeros(numHarm)
	amplitude = np.zeros(numHarm)
	for i in range(numHarm):
		#get the current peak
		curr_max = np.argmax(FFT)
		low_idx  = int(pow(2,-cents/1200.)*curr_max)
		high_idx = int(pow(2,cents/1200.)*curr_max)
		#exclude in and around current peak in future searches
		amplitude[i] = FFT[curr_max]
		FFT[low_idx:high_idx] = 0
		#the harmonic is too high to be detected never too low
		harmonics[i] = curr_max / Rec_secs
	#must resize harmonics because there are more samples with more Rec_secs
	return harmonics, amplitude

#random forest model for fundamental detection
print('loading fundamental frequency model...')
filename = '{}fundamental_frequency_{}.sav'.format(model_dir,numNotes)
model = pickle.load(open(filename, 'rb'))

print('initializing signal detector...')
#start stream
audio = pyaudio.PyAudio()
stream = audio.open(format=Format,
                    channels=Channels,
                    rate=Rate,
                    input=True,
                    frames_per_buffer=Chunk)
#gather initial signal for initialization
signal = collect_signal()

#gathering background noise
print('do not play collecting background noise...')
noise = collect_noise()

#maximum threshold is the peak of the environment
thresh = 0

xdata = np.linspace(0, 2*np.pi, 30000)
j = np.size(xdata)

xdata = np.reshape(xdata, (1, j))
fig = plt.figure()
ax = fig.add_subplot(211)
ax2 = fig.add_subplot(212)

def update(frame):
	ax.clear()
	ax2.clear()
	#A Major Chord exhibit (A, C#, E)
	#f, name = np.asarray([440.0, 554.37, 659.25]), ["A","C#","E"]
	#Microphone input exhibit
	f, amp = sample_sound(numNotes)
	f = np.asarray(np.reshape(f, (1, numNotes)))
	curve_arr = np.dot(f.T,(xdata+float(frame)))
	actual = np.zeros(j)
	for k in range(numNotes):
		curve = amp[k]*np.sin(curve_arr[k]+time.time())
		ax.plot(xdata[0], curve, label='{} (freq: {})'.format(MIDI_to_name(freq_to_MIDI(f[0,k])), str(int(f[0,k]))))
		ax.set_xlabel('Time')
		ax.set_ylabel('Amplitude')
		ax.set_title('Sound Components')
		actual +=  curve
	if (numNotes > 1):
		ax2.plot(xdata[0], actual, label="superposition")
		ax2.set_xlabel('Time')
		ax2.set_ylabel('Amplitude')
	ax.set_xlim(0, np.pi/50)
	ax.set_ylim(-np.max(amp), np.max(amp))
	ax2.set_xlim(0, np.pi/50)
	ax2.set_ylim(-2*np.max(amp), 2*np.max(amp))
	ax.legend(bbox_to_anchor=(1,1), bbox_transform=plt.gcf().transFigure)
	ax2.legend()
ani = FuncAnimation(fig, update, interval=10)
plt.show()


from colorama import Fore, Back, Style
def remover_emails_repetidos(lista_emails):
    emails_unicos = list(set(lista_emails))
    emails_removidos = len(lista_emails) - len(emails_unicos)
    return emails_unicos, emails_removidos

lista_emails = ['']
emails_unicos, emails_removidos = remover_emails_repetidos(lista_emails)

#print(emails_unicos)
print('\n'.join([f"{email}" for email in lista_emails]))
print(f'Quantidade de emails removidos: {Back.RED}{Fore.WHITE}  {emails_removidos}  {Style.RESET_ALL}')


import logging
import json
import sys
if (sys.version_info > (3,)):
  from urllib.parse import quote
else:
  from urllib import quote
from io import StringIO
import os
import jsonpickle
import cairis.core.BorgFactory
from cairis.core.Borg import Borg
from cairis.core.TemplateAsset import TemplateAsset
from cairis.core.ValueTypeParameters import ValueTypeParameters
from cairis.core.TemplateAssetParameters import TemplateAssetParameters
from cairis.core.TemplateAssetParameters import TemplateAssetParameters
from cairis.test.CairisDaemonTestCase import CairisDaemonTestCase
from cairis.mio.ModelImport import importModelFile
from cairis.tools.JsonConverter import json_deserialize

__author__ = 'Shamal Faily'

def addTestData():
  f = open(os.environ['CAIRIS_SRC'] + '/test/templateassets.json')
  d = json.load(f)
  f.close()
  iAccessRights = d['access_rights']
  iSurfaceTypes = d['surface_type']
  iTemplateAssets = d['template_assets']
  iPrivileges = d['privileges']
  cairis.core.BorgFactory.initialise()
  b = Borg()
  iar1 = ValueTypeParameters(iAccessRights[0]["theName"], iAccessRights[0]["theDescription"], 'access_right','',iAccessRights[0]["theValue"],iAccessRights[0]["theRationale"])
  iar2 = ValueTypeParameters(iAccessRights[1]["theName"], iAccessRights[1]["theDescription"], 'access_right','',iAccessRights[1]["theValue"],iAccessRights[1]["theRationale"])
  ist1 = ValueTypeParameters(iSurfaceTypes[0]["theName"], iSurfaceTypes[0]["theDescription"], 'surface_type','',iSurfaceTypes[0]["theValue"],iSurfaceTypes[0]["theRationale"])
  ipr1 = ValueTypeParameters(iPrivileges[0]["theName"], iPrivileges[0]["theDescription"], 'privilege','',iPrivileges[0]["theValue"],iPrivileges[0]["theRationale"])
  b.dbProxy.addValueType(iar1)
  b.dbProxy.addValueType(iar2)
  b.dbProxy.addValueType(ist1)
  b.dbProxy.addValueType(ipr1)
  spValues = [0,0,0,0,0,0,0,0]
  srValues = ['None','None','None','None','None','None','None','None']
  ifs = iTemplateAssets[0]
  iTap = TemplateAssetParameters(iTemplateAssets[0]["theName"], iTemplateAssets[0]["theShortCode"], iTemplateAssets[0]["theDescription"], iTemplateAssets[0]["theSignificance"],iTemplateAssets[0]["theType"],iTemplateAssets[0]["theSurfaceType"],iTemplateAssets[0]["theAccessRight"],spValues,srValues,[],[('anInterface','provided','trusted','privileged')])
  b.dbProxy.addTemplateAsset(iTap)

class TemplateAssetAPITests(CairisDaemonTestCase):

  @classmethod
  def setUpClass(cls):
    importModelFile(os.environ['CAIRIS_SRC'] + '/../examples/exemplars/ACME_Water/ACME_Water.xml',1,'test')
    addTestData()

  def setUp(self):
    self.logger = logging.getLogger(__name__)
    f = open(os.environ['CAIRIS_SRC'] + '/test/templateassets.json')
    d = json.load(f)
    f.close()
    iTemplateAssets = d['template_assets']
    self.new_ta = d['template_assets'][1]
    self.new_ta_dict = {
      'session_id' : 'test',
      'object': self.new_ta
    }
    self.existing_ta_name = 'Application Data'
    self.upd_ta = d['template_assets'][0]
    self.upd_ta_dict = {
      'session_id' : 'test',
      'object': self.new_ta
    }
    self.existing_ta_name = 'Application Data'

  def test_get_all(self):
    method = 'test_get'
    url = '/api/template_assets?session_id=test'
    self.logger.info('[%s] URL: %s', method, url)
    rv = self.app.get(url)
    if (sys.version_info > (3,)):
      responseData = rv.data.decode('utf-8')
    else:
      responseData = rv.data
    tas = jsonpickle.decode(responseData)
    self.assertIsNotNone(tas, 'No results after deserialization')
    self.assertIsInstance(tas, list, 'The result is not a list as expected')
    self.assertGreater(len(tas), 0, 'No template assets in the list')
    self.logger.info('[%s] Template assets found: %d', method, len(tas))
    ta = tas[0]
    self.logger.info('[%s] First template asset: %s \n', method, ta['theName'])

  def test_get_by_name(self):
    method = 'test_get_by_name'
    url = '/api/template_assets/name/%s?session_id=test' % quote(self.existing_ta_name)
    rv = self.app.get(url)
    self.assertIsNotNone(rv.data, 'No response')
    if (sys.version_info > (3,)):
      responseData = rv.data.decode('utf-8')
    else:
      responseData = rv.data
    self.logger.debug('[%s] Response data: %s', method, responseData)
    ta = jsonpickle.decode(responseData)
    self.assertIsNotNone(ta, 'No results after deserialization')
    self.logger.info('[%s] Template asset: %s \n', method, ta['theName'])

  def test_post(self):
    method = 'test_post_new'
    rv = self.app.post('/api/template_assets', content_type='application/json', data=jsonpickle.encode(self.new_ta_dict))
    if (sys.version_info > (3,)):
      responseData = rv.data.decode('utf-8')
    else:
      responseData = rv.data
    self.logger.debug('[%s] Response data: %s', method, responseData)
    json_resp = json_deserialize(responseData)
    self.assertIsNotNone(json_resp, 'No results after deserialization')
    ackMsg = json_resp.get('message', None)
    self.assertGreater(ackMsg.find('created'), -1, 'Template asset not created')

  def test_put(self):
    method = 'test_put'
    self.upd_ta_dict['object']['theName'] = self.existing_ta_name
    self.upd_ta_dict['object']['theDescription'] = 'Updated description'
    url = '/api/template_assets/name/%s?session_id=test' % quote(self.existing_ta_name)
    rv = self.app.put(url, content_type='application/json', data=jsonpickle.encode(self.upd_ta_dict))
    if (sys.version_info > (3,)):
      responseData = rv.data.decode('utf-8')
    else:
      responseData = rv.data
    self.logger.debug('[%s] Response data: %s', method, responseData)
    json_resp = json_deserialize(responseData)
    self.assertIsNotNone(json_resp, 'No results after deserialization')
    ackMsg = json_resp.get('message', None)
    self.assertGreater(ackMsg.find('updated'), -1, 'Template asset not updated')

  def test_delete(self):
    method = 'test_delete'

    rv = self.app.post('/api/template_assets', content_type='application/json', data=jsonpickle.encode(self.new_ta_dict))
    if (sys.version_info > (3,)):
      responseData = rv.data.decode('utf-8')
    else:
      responseData = rv.data
    self.logger.debug('[%s] Response data: %s', method, responseData)
    json_resp = json_deserialize(responseData)

    url = '/api/template_assets/name/%s?session_id=test' % quote(self.new_ta['theName'])
    rv = self.app.delete(url)
    if (sys.version_info > (3,)):
      responseData = rv.data.decode('utf-8')
    else:
      responseData = rv.data
    self.logger.debug('[%s] Response data: %s', method, responseData)
    json_resp = json_deserialize(responseData)
    self.assertIsNotNone(json_resp, 'No results after deserialization')
    ackMsg = json_resp.get('message', None)
    self.assertGreater(ackMsg.find('deleted'), -1, 'Template asset not deleted')


import math

def get_mean(lst):
    sum = 0.0
    for i in lst:
        sum += i

    return sum/len(lst)

def calc_volatility_from_samples(samples):
    """
    Calculate the historical volatility of a stock price over a given number of samples.
    Use standard deviation as a metric of volatility.
    timeseries- list of stock price samples in order
    sample_interval- time between samples
    """
    mean = get_mean(samples)

    dev_sq_sum = 0.0
    for s in samples:
        # calc deviation
        dev = mean - s
        # add the squared deviation
        dev_sq_sum += dev*dev

    return math.sqrt(dev_sq_sum / len(samples))

def calc_volatility_over_time(timeseries, interval):
    """
    Generate volatility over time for given timeseries price data.
    i.e. Get a measure of volatility for each price entry of a stock over time.
    Return in list format.
    timeseries- list of stock price samples in order
    interval- how many samples to calculate the volatility over
    """

    # initialize volatility array, ensure it has the same length as the timeseries data
    vols = [None] * len(timeseries)

    # start at end of first interval. Dont calc vol for values before this, we cant
    for i in range(interval-1, len(timeseries)):
        vols[i] = calc_volatility_from_samples(timeseries[i-(interval-1):i+1])

    return vols


#배송비 계산
#주문 상품 가격이 2만원 미만이면 배송비 2500원 포함하고
#아니면 배송비를 포함하지 않는다.
"""
price = 25000
delivery = 2500
if price < 20000:
    price = price + delivery
else:
    price
print(price)
"""

def delprice(unit_price, num):
    delivery = 2500
    price = unit_price * num
    if price < 20000:
        price = price + delivery
    else:
        price
    return price
order1 = delprice(25000, 2)
order2 = delprice(3000, 5)
print(order1)
print(order2)


from torch import nn
import torch

class LSTMNet(nn.Module):

    def __init__(self, emb_size=26, hidden_size=1024, lstm_layers=1, dropout=0.1):
        super(LSTMNet, self).__init__()
        self.emb_size = emb_size
        self.layers = lstm_layers
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size=emb_size, hidden_size=hidden_size, num_layers=lstm_layers, batch_first=True, dropout=dropout)
        self.fc1 = nn.Linear(hidden_size, emb_size)

    def forward(self, x, pv_st):
        out, st = self.lstm(x, pv_st)
        out=self.fc1(out)
        return out, st

    def init_state(self, batch_size=None):
        if batch_size:
            return (
                torch.zeros((self.layers, batch_size, self.hidden_size), dtype=torch.float),
                torch.zeros((self.layers, batch_size, self.hidden_size),dtype=torch.float)
            )
        else:
            return (
                torch.zeros((self.layers, self.hidden_size), dtype=torch.float),
                torch.zeros((self.layers, self.hidden_size),dtype=torch.float)
            )


#!/usr/bin/env python
# coding: utf-8

# In[78]:

#imports
import numpy as np
import pandas as pd
from nltk.stem.porter import *
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from matplotlib import pyplot as plt
import string

stemmer = PorterStemmer()

# In[79]:

IMDB = pd.read_csv('imdb_labelled.txt', sep="\t", quoting=3, header=None)
AMAZON= pd.read_csv('amazon_cells_labelled.txt', sep="\t", header=None)
YELP= pd.read_csv('yelp_labelled.txt', sep="\t", header=None)

# concatenate imdb, amazon ang yelp data
frames = [IMDB, AMAZON, YELP]
result = pd.concat(frames, ignore_index=True)

# extract separately sentences and scores
sentences=result.loc[:,0]
scores=result.loc[:,1]

# In[80]:

#-----------------------------------------Erwtima 3-1-----------------------------------------#

# words extraction
words=[]
words_temp=[]
for i in range(0, len(sentences)):
    words_of_sentence=word_tokenize(sentences[i])
    words_temp.append(words_of_sentence)

words=[item for sublist in words_temp for item in sublist]

# stemming
stemmed_words = [stemmer.stem(word) for word in words]

# removing stop words
stop_words = set(stopwords.words('english'))
words = [word for word in stemmed_words if not word in stop_words]

# removing punctuation
words = [''.join(c for c in s if c not in string.punctuation) for s in words]

# removing empty strings
words =  [word for word in words if word]

# turning all words into lowercase
words = [w.lower() for w in words]

# removing duplicates
words = list(set(words))

# sorting list
words.sort()

# In[81]:

len(words)

# In[82]:

#-----------------------------------------Erwtima 3-2-----------------------------------------#

# initializing array that will contain all sentence vectors
sentence_vector=np.zeros((len(sentences), len(words)), dtype=int)

for s in range(0, len(sentences)):
    # turning the sentence lowercase
    sentence = sentences[s].lower()
    # removing punctuation
    sentence="".join(l for l in sentence if l not in string.punctuation)
    # words extraction
    words_of_sentence=word_tokenize(sentence)
    # stemming
    words_of_sentence_stemmed=[stemmer.stem(word) for word in words_of_sentence]
    # removing stop words
    words_of_sentence_filtered = [word for word in words_of_sentence_stemmed if not word in stop_words]

    # turning the list of the words in the sentence into a vector
    for i in range(0, len(words_of_sentence_filtered)):
        for j in range(0, len(words)):
            if (words_of_sentence_filtered[i]==words[j]):
                sentence_vector[s,j]=sentence_vector[s,j]+1

# In[83]:

#-----------------------------------------Erwtima 3-3-----------------------------------------#

from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score

# In[84]:

# X -> sentence_vector
# y -> scores

X_train, X_test, y_train, y_test = train_test_split(sentence_vector, scores, test_size=0.25)

# In[85]:

clf=svm.SVC(kernel='linear', decision_function_shape='ovo')
clf.fit(X_train, y_train)
y_pred=clf.predict(X_test)
accuracy_score(y_test, y_pred)

# In[ ]:

# tuning hyperparameter C

# In[69]:

from sklearn.model_selection import cross_val_score

# In[74]:

C_range=np.array([x * 0.1 for x in range(2, 10)])
C_scores=[]
for c in C_range:
    clf=svm.SVC(C=c, kernel='linear', decision_function_shape='ovo')
    scores = cross_val_score(clf, X_train, y_train, cv=10, scoring='accuracy')
    C_scores.append(scores.mean())

# In[75]:

print(C_scores)

# In[76]:

plt.plot(C_range, C_scores)
plt.xlabel("Value C for SVM")
plt.ylabel("Cross-validated Accuracy")

# In[86]:

X_train, X_test, y_train, y_test = train_test_split(sentence_vector, scores, test_size=0.25)

# In[91]:

clf=svm.SVC(C=0.5, kernel='linear', decision_function_shape='ovo')
clf.fit(X_train, y_train)
y_pred=clf.predict(X_test)
accuracy_score(y_test, y_pred)

# In[ ]:


'''
Connection to other peers
'''

from ipaddress import ip_address, IPv4Address, IPv6Address
from socket import AF_INET, AF_INET6, SOCK_STREAM, socket
from threading import Thread

default_address = '::'
default_port = 53678
default_timeout = 500

def ipversion (address):
	'''
	Returns address's version
	It can be either 4 for IPv4, or 6 for IPv6, or 0 if this is not a IP address
	'''
	try:
		t = type (ip_address (address))
		if t == IPv4Address:
			return (4)
		if t == IPv6Address:
			return (6)
	except ValueError:
		return (0)

class Listenner (Thread):
	'''
	Listen to incomming connections
	'''
	def __init__ (self, secret, nodes, address = default_address, port = default_port):
		'''
		secret for internode communication
		port for the TCP port
		'''
		Thread.__init__ (self)
		self.secret = secret
		self.nodes = nodes
		self.address = address
		self.port = port
		if ipversion (self.address) == 6:
			self.socket = socket (AF_INET6, SOCK_STREAM)
		elif ipversion (self.address) == 4:
			self.socket = socket (AF_INET, SOCK_STREAM)
		else:
			raise (ConnectionError ('error string for listen address %s' % (self.address)))

	def run (self):
		'''
		Method started by threading routine
		'''
		# TODO: manage error while openning port or address
		self.socket.bind ((self.address, self.port))
		self.socket.listen (1)
		while True:
			c, a = self.socket.accept ()
			n = Node (self.secret, adresse = a, socket = c)
			n.start ()
			self.nodes.append (n)

class Node (Thread):
	'''
	Connector another node
	'''
	def __init__ (self, secret, address = None, port = default_port, socket = None, timeout = default_timeout):
		'''
		secret for internode communication
		address for IP (v4 or v6)
		port for the TCP port
		socket is for already openned socket (typically for incomming connections)
		timeout is the maximum time to wait for a answer from a node
		'''
		Thread.__init__ (self)
		if address is None and socket is None:
			raise (ConnectionError ('error string for node with neither socket, nor address'))
		self.secret = secret
		self.address = address
		self.port = port
		self.socket = socket
		self.timeout = timeout
		raise (NotImplementedError ())

	def ping (self):
		'''
		“Pings” the node
		This is really usefull only to know if everything is allright, the TCP layer cares about keeping the connection alive
		'''
		raise (NotImplementedError ())

	def send_file (self, file_object):
		'''
		Send a file to node
		file_object must be the special File object defined in this project
		'''
		raise (NotImplementedError ())

	def get_state (self):
		'''
		Returns node's state
		'''
		raise (NotImplementedError ())

	def get_name (self):
		'''
		Returns node's name
		'''
		raise (NotImplementedError ())

	def run (self):
		'''
		Method started by the threading routine
		'''
		raise (NotImplementedError ())


from setuptools import setup
from setuptools.command.test import test as TestCommand
import sys

class PyTest(TestCommand):

    def finalize_options(self):
        TestCommand.finalize_options(self)
        self.test_args = ['--cov', 'static', 'tests']
        self.test_suite = True

    def run_tests(self):
        # import here, cause outside the eggs aren't loaded
        import pytest
        errno = pytest.main(self.test_args)
        sys.exit(errno)

setup(name='static3',
      version='0.7.0',
      description=
      'A really simple WSGI way to serve static (or mixed) content.',
      long_description=open('README.rst', 'rb').read().decode('utf-8'),
      author='Roman Mohr',
      author_email='roman@fenkhuber.at',
      url='https://github.com/rmohr/static3',
      license="LGPL",
      py_modules=['static'],
      packages=[],
      cmdclass={'test': PyTest},
      tests_require=['pytest', 'webtest', 'pytest-cov'],
      extras_require={
          'KidMagic': 'kid',
          'GenshiMagic': 'Genshi',
      },
      entry_points="""
          [console_scripts]
              static=static:command
      """,
      keywords="wsgi web http static content webapps",
      classifiers=['Development Status :: 4 - Beta',
                   'Environment :: Web Environment',
                   'Intended Audience :: Developers',
                   'License :: OSI Approved :: GNU Library or '
                   'Lesser General Public License (LGPL)',
                   'Natural Language :: English',
                   'Operating System :: OS Independent',
                   'Programming Language :: Python',
                   'Topic :: Software Development :: Libraries',
                   'Topic :: Utilities'])


# -*- coding: utf-8 -*-
"""
py2ch
=====

What is this?
-------------

`py2ch` is a library for handling 2channel_,
one of the most famous BBS site like Digg.
Currently, this is mainly forcusing on browsing it,
i.e. not supporting posting comment to threads,
Be user login, and so on.

.. _2channel: http://www.2ch.net/

Setup
-----

::

   $ easy_install py2ch

"""

import sys
from setuptools import setup, find_packages

version = '0.0.3'

classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Environment :: Web Environment',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
        'Natural Language :: Japanese',
        'Operating System :: OS Independent',
        'Programming Language :: Python :: 2.7',
        'Topic :: Communications :: BBS',
        'Topic :: Software Development :: Libraries'
        'Topic :: Utilities',
    ]

setup(
    name='py2ch',
    version=version,
    url='https://github.com/ymotongpoo/py2ch',
    license='LGPL',
    author='Yoshifumi YAMAGUCHI',
    author_email='ymotongpoo@gmall.com',
    description='a library for handling 2ch bbs, mainly for browsing it.',
    long_description=__doc__,
    packages=['py2ch'],
    package_data={'py2ch':['test/data/*.dat']},
    install_requires=[
        'setuptools',
        ],
    extras_require=dict(
        test=[
            'nose>=1.0.0'
            ],
        ),
    test_suite='nose.collector',
    tests_require=['nose']
)


import pygame
from pygame.locals import *
from sys import exit

background_image_filename = '../assets/Valkyrie_Wallpaper.jpg'

pygame.init()

# screen = pygame.display.set_mode((640, 480), 0, 32)
screen = pygame.display.set_mode((1920, 1080), FULLSCREEN, 32)
background = pygame.image.load(background_image_filename).convert()

x, y = 0, 0
move_x, move_y = 0, 0

# Following line make pygame ignore mouse motion
pygame.event.set_blocked(MOUSEMOTION)

# pygame.event.set_blocked([KEYDOWN, KEYUP]) # set_blocked also works for specific keys
# pygame.event.set_blocked(None) # You can also unblock all events
# pygame.event.set_allowed(None) # Or block them

my_event = pygame.event.Event(KEYDOWN, key=K_SPACE, mod=0, unicode=u' ')  # you can also pass as dictionary
pygame.event.post(my_event)

CATONKEYBOARD = USEREVENT + 1
my_event = pygame.event.Event(CATONKEYBOARD, message="Bad cat!")
pygame.event.post(my_event)

print(pygame.display.list_modes())

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            exit()
        if event.type == CATONKEYBOARD:
            print(event.message)
        if event.type == KEYDOWN:
            if event.key == K_LEFT or event.key == K_a:
                move_x = -1
            elif event.key == K_RIGHT or event.key == K_d:
                move_x = +1
            elif event.key == K_UP or event.key == K_w:
                move_y = -1
            elif event.key == K_DOWN or event.key == K_s:
                move_y = +1
        elif event.type == KEYUP:
            if event.key == K_LEFT:
                move_x = 0
            elif event.key == K_RIGHT:
                move_x = 0
            elif event.key == K_UP:
                move_y = 0
            elif event.key == K_DOWN:
                move_y = 0
            if event.key == K_ESCAPE:
                pygame.quit()
                exit()

        x += move_x
        y += move_y

        screen.fill((0, 0, 0))
        screen.blit(background, (x, y))

        pygame.display.update()


from my_admin.admin_class import show_models
from django.db.models.query import Q
from django.utils.translation import gettext as _

def create_manger_table():
    app_dict = {}
    for model_name,model_value in show_models.items():
        model_app = model_value['model'].model._meta.app_label
        app_dict.update({model_app:show_models})
    return app_dict

def search_result(query_set,search_value,model_admin):
    search_fields = model_admin.search_fields
    q = Q()
    q.connector = 'OR'
    for field in search_fields:
        q.children.append((field+'__icontains',search_value,))
    result = query_set.filter(q)
    return result

def legal_filter_list(args,keyword):
    filter_keyword = {}
    for key, value in args.items():
        if key in keyword:
            continue
        filter_keyword.update({key: value})
    return filter_keyword

def dynamic_create_form(model_admin):
    from django import forms
    def __new__(cls,*args,**kwargs):
        for field_name,field_obj in cls.base_fields.items():
            field_obj.widget.attrs.update({'class':'form-control'})
            if  model_admin.readonly_table:
                field_obj.widget.attrs['disabled'] = 'disabled'
            elif not model_admin.add_form and field_name in model_admin.readonly_field:
                field_obj.widget.attrs['disabled'] = 'disabled'
        return forms.ModelForm.__new__(cls)

    def default_clean(self):
        error_list = []
        if model_admin.readonly_table:
            if self.data:
                error_list.append(forms.ValidationError(_('The %(table_name)s field is readonly, cannot be modified'),
                                                code='readonly_table',params={"table_name":model_admin.model._meta.verbose_name}))
        else:
            for field_name,initial_val in self.initial.items():
                if field_name in model_admin.readonly_field:
                    if self.data[field_name] != initial_val:
                        error_list.append(
                            forms.ValidationError(_('The %(field_name)s field is readonly, cannot be modified'),
                                                    code='readonly_field',params={"field_name":field_name}))
        try:
            model_admin.clean()
        except forms.ValidationError as e:
            error_list.append(e)
        if error_list:
            raise forms.ValidationError(error_list)
    class Meta:
        model = model_admin.model
        fields = '__all__'
    attrs = {'Meta':Meta}
    form_class = type('DynamicForm',(forms.ModelForm,),attrs)
    setattr(form_class,'__new__',__new__)
    setattr(form_class,'clean',default_clean)
    return form_class


import ctmcommands.cmd
from ctmcommands.param import Param

class ExportPackage(ctmcommands.cmd.CSKCommand):

    Description = 'Export a Package Definition as a portable backup JSON document.'
    API = 'export_package'
    Examples = '''
    ctm-export-package -p "Some Package Name"
'''
    Options = [Param(name='package', short_name='p', long_name='package',
                     optional=False, ptype='string',
                     doc='Value can be either a Package Definition ID or Name.')]

    def main(self):
        results = self.call_api(self.API, ['package'])
        print(results)


from flask import render_template
from app import app

from systeminfo.systeminfo import get_platform_info

@app.route('/')
def index():
	returnDict = {}
	returnDict['user'] = 'Emmet Tracey'
	returnDict['title'] = 'Home'
	returnDict['platform'] = get_platform_info()
	return render_template("index.html", **returnDict)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat May 25 14:52:46 2019
    post-processing LST data

@author: weibo
"""

# %% Load necessary module
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

import matplotlib.ticker as ticker
from scipy.interpolate import interp1d, splev, splrep #, spline
from data_post import DataPost
import variable_analysis as fv
from timer import timer
from scipy.interpolate import griddata
import plt2pandas as p2p
from glob import glob

# %% data path settings
path = "/media/weibo/Data2/BFS_M1.7TS/"
pathP = path + "probes/"
pathF = path + "Figures/"
pathM = path + "MeanFlow/"
pathS = path + "SpanAve/"
pathT = path + "TimeAve/"
pathI = path + "Instant/"
pathL = path + "LST/"

# %% figures properties settings
plt.close("All")
plt.rc("text", usetex=True)
font = {
    "family": "Times New Roman",  # 'color' : 'k',
    "weight": "normal",
    "size": "large",
}
matplotlib.rcParams["xtick.direction"] = "in"
matplotlib.rcParams["ytick.direction"] = "in"
textsize = 13
numsize = 10

# %%
# path = "/media/weibo/VID2/BFS_M1.7SFD/"
# pathB = path + 'TP_data_15709808/'
# file = glob(pathB + '*plt')
# p2p.ReadAllINCAResults(pathB, FoldPath2=pathB,
#                        FileName=file, SpanAve='Y', OutFile="BaseFlow")
# base = pd.read_hdf(pathL + 'BaseFlow.h5')
base = pd.read_hdf(pathM + 'MeanFlow.h5')
varlist = ['x', 'y', 'z', 'u', 'v', 'w', 'rho', 'p', 'Mach', 'T']
base['u'] = base['<u>']
base['v'] = base['<v>']
base['w'] = base['<w>']
base['rho'] = base['<rho>']
base['p'] = base['<p>']
base['Mach'] = base['u']/np.sqrt(1.4*287*base['<T>'])
base['T'] = base['<T>']
x_loc = np.arange(-40.0, 0.0 + 1.0, 1.0)
for i in range(np.size(x_loc)):
    df = base.loc[(base['x']==x_loc[i]) & (base['z']==0.0), varlist]
    df.to_csv(pathL + 'InputProfile_' + str(x_loc[i]) + '.dat',
              index=False, float_format='%1.8e', sep=' ')

# %% Contour of TS mode
x_inlet = 0.382185449774020e3
blasius = 1.579375403141185e-04 # 1.669135812043661e-04
l_ref = 1.0e-3
rescale = blasius * np.sqrt(x_inlet/(x_inlet - 0.04)) / l_ref
ts_mode = pd.read_csv(path + 'TSMode2_-40.0.dat', sep=' ',
                      index_col=False, skipinitialspace=True)

phi = np.arange(50.0, 60.0 + 0.1, 0.1)
beta = np.arange(0.0001, 0.9, 0.001)
omega = np.arange(0.0001, 0.9, 0.0001)
ts_core = ts_mode # .query("phi >= 49.0 & phi <= 61.0")
x, y = np.meshgrid(beta, omega)
growth = griddata((ts_core['beta'], ts_core['omega']),
                  ts_core['alpha_i'], (x, y))
wave = griddata((ts_core['beta'], ts_core['omega']),
                ts_core['alpha_r'], (x, y))
# beta = np.tan(y/180*np.pi) * wave
print("growth_max=", np.max(growth))
print("growth_min=", np.min(growth))

fig, ax = plt.subplots(figsize=(6.4, 3.2))
matplotlib.rc("font", size=textsize)
rg1 = np.linspace(-0.0028, 0.0013, 42)
x_b = x * rescale
y_b = y * rescale
growth_b = growth * rescale
cbar = ax.contourf(x_b, y_b, growth_b, cmap='rainbow_r', levels=rg1)  # rainbow_r
cs = ax.contour(x_b, y_b, growth_b, levels=[-0.0025, -0.0023, -0.0019, -0.0015],
                linewidths=1.0, colors='w')
matplotlib.rc("font", size=textsize)
ax.clabel(cs, cs.levels, inline=False, fmt=r'$%5.4f$', inline_spacing=0,
          rightside_up=True, fontsize=numsize-1, colors='k')
ax.set_xlim(0.03, 0.12)
ax.set_ylim(0.008, 0.024)
ax.set_yticks(np.arange(0.008, 0.024 + 0.004, 0.004))
ax.ticklabel_format(axis='y', style='sci', useOffset=False, scilimits=(-2, 2))
ax.yaxis.offsetText.set_fontsize(numsize)
ax.tick_params(labelsize=numsize)
ax.set_xlabel(r"$\beta l$", fontsize=textsize)
ax.set_ylabel(r"$\omega \l / u_\infty$", fontsize=textsize)
ax.axvline(x=0.393, ymin=0, ymax=0.5,
           color="gray", linestyle="--", linewidth=1.0)
ax.axhline(y=0.101, xmin=0, xmax=0.32,
           color="gray", linestyle="--", linewidth=1.0)
# Add colorbar
rg2 = np.linspace(-0.0028, 0.0013, 3)
cbaxes = fig.add_axes([0.65, 0.80, 0.22, 0.06])  # x, y, width, height
cbaxes.tick_params(labelsize=numsize)
cbar = plt.colorbar(cbar, cax=cbaxes, orientation="horizontal", ticks=rg2)
cbar.formatter.set_powerlimits((-2, 2))
cbar.ax.xaxis.offsetText.set_fontsize(numsize)
cbar.update_ticks()
cbar.set_label(
    r"$\alpha_i \l$", rotation=0, x=-0.15,
    labelpad=-25, fontsize=textsize
)
cbaxes.tick_params(labelsize=numsize)
plt.savefig(pathF + "TS_mode_contour.pdf", bbox_inches="tight")
plt.show()

# %% Plot LST spectrum
spectrum = pd.read_csv(path + 'SpatEigVal-40.0.dat', sep=' ',
                       index_col=False, na_values=['Inf', '-Inf'],
                       skipinitialspace=True, keep_default_na=False)
spectrum.dropna()
fig, ax = plt.subplots(figsize=(3.2, 3.2))
matplotlib.rc("font", size=textsize)
# plot lines
ax.scatter(spectrum['alpha_r'], spectrum['alpha_i'], s=15, marker='o',
           facecolors='k', edgecolors='k', linewidths=0.5)
ax.set_xlim([-2, 2])
ax.set_ylim([-0.1, 0.3])
ax.set_xlabel(r'$\alpha_r \delta_0$', fontsize=textsize)
ax.set_ylabel(r'$\alpha_i \delta_0$', fontsize=textsize)
ax.tick_params(labelsize=numsize)
ax.grid(b=True, which="both", linestyle=":")
plt.savefig(pathF + "TS_mode_spectrum.svg", bbox_inches="tight")
plt.show()
# %% BL profiles to a specific format
path = 'E:/Data/project/LST/export/x270/'
col = [
       'y', 'u_r', 'u_i', 'v_r', 'v_i', 'w_r', 'w_i',
       't_r', 't_i', 'p_r', 'p_i', 'rho_r', 'rho_i'
       ]
ts_profile = pd.read_csv(path + 'profiles.dat', sep='\t',
                         names=col, header=0,
                         index_col=False, skiprows=0,
                         skipinitialspace=True)
myfile = path + 'UnstableMode.dat'
omega_r = 0.700000
omega_i = -0.021951
alpha = 0.758735
beta = 0.0
with open(myfile, 'w') as file:
    # file.write(col[:11]+'\t')
    file.write('alpha = ' + str(alpha) + '\n')
    file.write('beta = ' + str(beta) + '\n')
    file.write('omega_r = ' + str(omega_r) + '\n')
    file.write('omega_i = ' + str(omega_i) + '\n')
    file.write("\t".join(col[:11]) + '\n')
    input_mode = ts_profile[col[:11]]
    input_mode.to_csv(myfile, sep='\t', index=False, # header=0, #columns=col[:11], # mode='a', #
                      float_format='%1.8e')
# %% Plot LST perturbations profiles
path = 'E:/Data/project/LST/export/x270/'
ts_profile = pd.read_csv(path + 'UnstableMode.inp', sep='\t',
                         index_col=False, skiprows=4,
                         skipinitialspace=True)
ts_profile['u'] = np.sqrt(ts_profile['u_r']**2+ts_profile['u_i']**2)
ts_profile['v'] = np.sqrt(ts_profile['v_r']**2+ts_profile['v_i']**2)
ts_profile['w'] = np.sqrt(ts_profile['w_r']**2+ts_profile['w_i']**2)
ts_profile['t'] = np.sqrt(ts_profile['t_r']**2+ts_profile['t_i']**2)
ts_profile['p'] = np.sqrt(ts_profile['p_r']**2+ts_profile['p_i']**2)
# normalized
fct = 4
var_ref = np.max(ts_profile['u'])
ts_profile['u'] = ts_profile['u'] / var_ref
ts_profile['v'] = ts_profile['v'] / var_ref
ts_profile['w'] = ts_profile['w'] / var_ref
ts_profile['p'] = ts_profile['p'] / var_ref
ts_profile['t'] = ts_profile['t'] / var_ref / fct
fig, ax = plt.subplots(figsize=(3.2, 3.2))
matplotlib.rc("font", size=textsize)
# plot lines
ax.plot(ts_profile.u, ts_profile.y, 'k', linewidth=1.2)
ax.plot(ts_profile.v, ts_profile.y, 'r', linewidth=1.2)
ax.plot(ts_profile.w, ts_profile.y, 'g', linewidth=1.2)
ax.plot(ts_profile.p, ts_profile.y, 'b', linewidth=1.2)
ax.plot(ts_profile.t, ts_profile.y, 'c', linewidth=1.2)
# plot scatter
#ax.scatter(ts_profile.u[0::4], ts_profile.y[0::4], s=15, marker='x',
#           facecolors='k', edgecolors='k', linewidths=0.5, label=r'$u$')
ax.set_xlim(0.0, 4.0)
ax.tick_params(axis='x', which='major', pad=5)
ax.set_ylim(0.0, 10.0)
ax.set_xlabel(r'$|\tilde{q}|/|\tilde{u}|_\mathrm{max}$', fontsize=textsize)
ax.set_ylabel(r'$y\mathrm{(mm)}$', fontsize=textsize)
# ax.set_ylabel(r'$y/\delta_0$', fontsize=textsize)
ax.tick_params(labelsize=numsize)
ax.grid(b=True, which="both", linestyle=":")
plt.legend( (r'$u$', r'$v$', r'$w$', r'$p$', r'$T/4$'),
            fontsize=numsize, framealpha=0.5 )
plt.savefig(path + "2nd_mode_profile.png", dpi=300, bbox_inches="tight")
plt.show()

# %% omega-Rex
xloc = np.arange(-40.0, -6.0 + 1.0, 1.0)
x_inlet = 0.382185449774020e3
blasius = 1.579375403141185e-04 # 1.669135812043661e-04
delta = 1e-3
Re = 13718000
val = -0.0016
var = 'beta'
lst_var = np.zeros( (np.size(xloc), 3) )
Re_l = np.zeros(np.size(xloc))
for i in range(np.size(xloc)):
    xx = xloc[i]
    l_ref = blasius * np.sqrt((x_inlet + xx)/(x_inlet - 40.0))
    ts_mode = pd.read_csv(pathL + 'TSMode_' + str(xx) + '_' + var + '.dat',
                          sep=' ', index_col=False, skipinitialspace=True)
    # rescaled by Blasius length
    ts_mode = ts_mode.sort_values(var).reset_index()
    ts_mode = ts_mode / delta * l_ref
    ts_mode['phi'] = ts_mode['phi'] * delta / l_ref
    # max alpha_i
    ind = ts_mode[['alpha_i']].idxmin()[0]
    # upper branch
    ts_mode1 = ts_mode.iloc[:ind]
    lst_var[i, 0] = interp1d(ts_mode1['alpha_i'], ts_mode1[var])(val)
    # ind1 = (ts_mode1['alpha_i']-val).abs().argsort()[:1]
    # lst_var[i, 0] = ts_mode[var][ind1.values].values
    # lower branch
    ts_mode2 = ts_mode.iloc[ind:]
    lst_var[i, 1] = interp1d(ts_mode2['alpha_i'], ts_mode2[var])(val)
    lst_var[i, 2] = ts_mode[var][ind]  # maximum alpha_i
    # ind2 = (ts_mode2['alpha_i']-val).abs().argsort()[:1]
    # lst_var[i, 1] = ts_mode[var][ind2.values].values
    Re_l[i] = Re * l_ref

varval = np.column_stack((Re_l, lst_var))
df = pd.DataFrame(data=varval, columns=['Re', var+'1', var+'2', var+'3'])
df.to_csv(pathL + 'LST_' + var + str(val) + '.dat',
          index=False, float_format='%1.8e', sep=' ')

# %% plot Rel-beta
beta1 = pd.read_csv(pathL + 'LST_beta-0.0014.dat', sep=' ',
                    index_col=False, skipinitialspace=True)
beta2 = pd.read_csv(pathL + 'LST_beta-0.0015.dat', sep=' ',
                    index_col=False, skipinitialspace=True)
beta3 = pd.read_csv(pathL + 'LST_beta-0.0016.dat', sep=' ',
                    index_col=False, skipinitialspace=True)
Re1 = np.hstack((beta1['Re'], beta1['Re'][::-1]))
ReBeta1 = np.hstack((beta1['beta1'], beta1['beta2'][::-1]))
Re2 = np.hstack((beta2['Re'], beta2['Re'][::-1]))
ReBeta2 = np.hstack((beta2['beta1'], beta2['beta2'][::-1]))
Re3 = np.hstack((beta3['Re'], beta3['Re'][::-1]))
ReBeta3 = np.hstack((beta3['beta1'], beta3['beta2'][::-1]))
fig, ax = plt.subplots(figsize=(3.2, 3.2))
matplotlib.rc("font", size=textsize)
# plot lines
y_s1 = np.linspace(ReBeta1[1:-1].min(), ReBeta1[1:-1].max(), 200)
tck = splrep(ReBeta1[1:-1], Re1[1:-1], s=0)
x_s1 = splev(y_s1, tck) # spline(ReBeta1[1:-1], Re1[1:-1], y_s1)

y_s2 = np.linspace(ReBeta2[1:-1].min(), ReBeta2[1:-1].max(), 200)
tck = splrep(ReBeta2[1:-1], Re2[1:-1], s=0)
x_s2 = splev(y_s2, tck) # x_s2 = spline(ReBeta2[1:-1], Re2[1:-1], y_s2)

y_s3 = np.linspace(ReBeta3[1:-1].min(), ReBeta3[1:-1].max(), 200)
tck = splrep(ReBeta3[1:-1], Re3[1:-1], s=0)
x_s3 = splev(y_s3, tck) # x_s3 = spline(ReBeta3[1:-1], Re3[1:-1], y_s3)
ax.plot(x_s1, y_s1, 'k-', linewidth=1.2)
ax.plot(x_s2, y_s2, 'k--', linewidth=1.2)
ax.plot(x_s3, y_s3, 'k:', linewidth=1.2)
xm_s = np.linspace(beta3['Re'][1:].min(), beta3['Re'][1:].max(), 100)
tck = splrep(beta3['Re'][1:], beta3['beta3'][1:])
ym_s = splev(xm_s, tck) # ym_s = spline(beta3['Re'][1:], beta3['beta3'][1:], xm_s, order=4)
ax.plot(beta3['Re'][1:], beta3['beta3'][1:], 'k-.', linewidth=1.2)
#ax.plot(beta1['Re'], beta1['beta1'], 'r-',
#        beta1['Re'], beta1['beta2'], 'r-', linewidth=1.2)
#ax.plot(beta2['Re'], beta2['beta1'], 'r--',
#        beta2['Re'], beta2['beta2'], 'r--', linewidth=1.2)
#ax.plot(beta3['Re'], beta3['beta1'], 'r:',
#        beta3['Re'], beta3['beta2'], 'r:', linewidth=1.2)
# ax.set_yscale('logit')
ax.set_xlim([2160, 2280])
ax.set_ylim([0.02, 0.13])
ax.set_xlabel(r'$Re_l$', fontsize=textsize)
ax.set_ylabel(r'$\beta l$', fontsize=textsize)
ax.set_xticks(np.linspace(2175, 2275, 3))
ax.ticklabel_format(axis='y', style='sci', useOffset=False, scilimits=(-1, 1))
ax.yaxis.offsetText.set_fontsize(numsize)
ax.tick_params(labelsize=numsize)
ax.grid(b=True, which="both", linestyle=":")
plt.savefig(pathF + "Re_beta.svg", bbox_inches="tight")
plt.show()

# %% plot Rel-omega
beta1 = pd.read_csv(pathL + 'LST_omega-0.0014.dat', sep=' ',
                    index_col=False, skipinitialspace=True)
beta2 = pd.read_csv(pathL + 'LST_omega-0.0015.dat', sep=' ',
                    index_col=False, skipinitialspace=True)
beta3 = pd.read_csv(pathL + 'LST_omega-0.0016.dat', sep=' ',
                    index_col=False, skipinitialspace=True)
Re1 = np.hstack((beta1['Re'], beta1['Re'][::-1]))
ReBeta1 = np.hstack((beta1['omega1'], beta1['omega2'][::-1]))
Re2 = np.hstack((beta2['Re'], beta2['Re'][::-1]))
ReBeta2 = np.hstack((beta2['omega1'], beta2['omega2'][::-1]))
Re3 = np.hstack((beta3['Re'], beta3['Re'][::-1]))
ReBeta3 = np.hstack((beta3['omega1'], beta3['omega2'][::-1]))
fig, ax = plt.subplots(figsize=(3.2, 3.2))
matplotlib.rc("font", size=textsize)
# plot lines
y_s1 = np.linspace(ReBeta1[1:-1].min(), ReBeta1[1:-1].max(), 200)
tck = splrep(np.sort(ReBeta1[1:-1]), Re1[1:-1], s=0)
x_s1 = splev(y_s1, tck) # spline(ReBeta1[1:-1], Re1[1:-1], y_s1)

y_s2 = np.linspace(ReBeta2[1:-1].min(), ReBeta2[1:-1].max(), 200)
tck = splrep(np.sort(ReBeta2[1:-1]), Re2[1:-1], s=0)
x_s2 = splev(y_s2, tck) # x_s2 = spline(ReBeta2[1:-1], Re2[1:-1], y_s2)

y_s3 = np.linspace(ReBeta3[1:-1].min(), ReBeta3[1:-1].max(), 200)
tck = splrep(np.sort(ReBeta3[1:-1]), Re3[1:-1], s=0)
x_s3 = splev(y_s3, tck) # x_s3 = spline(ReBeta3[1:-1], Re3[1:-1], y_s3)
x_s1[0] = Re1[1]
y_s1[0] = ReBeta1[1]
x_s2[0] = Re2[1]
y_s2[0] = ReBeta2[1]
x_s3[0] = Re3[1]
y_s3[0] = ReBeta3[1]
ax.plot(x_s1, y_s1, 'k-', linewidth=1.2)
ax.plot(x_s2, y_s2, 'k--', linewidth=1.2)
ax.plot(x_s3, y_s3, 'k:', linewidth=1.2)
xm_s = np.linspace(beta1['Re'][1:].min(), beta1['Re'][1:].max(), 100)
tck = splrep(beta1['Re'][1:], beta1['omega3'][1:], s=0)
ym_s = splev(xm_s, tck)  # spline(beta1['Re'][1:], beta1['omega3'][1:], xm_s, order=4)
ax.plot(beta1['Re'][1:], beta1['omega3'][1:], 'k-.', linewidth=1.2)
# plot lines
#ax.plot(beta1['Re'], beta1['omega1'], 'r-',
#        beta1['Re'], beta1['omega2'], 'r-', linewidth=1.2)
#ax.plot(beta2['Re'], beta2['omega1'], 'r--',
#        beta2['Re'], beta2['omega2'], 'r--', linewidth=1.2)
#ax.plot(beta3['Re'], beta3['omega1'], 'r:',
#        beta3['Re'], beta3['omega2'], 'r:', linewidth=1.2)
ax.set_xlim([2160, 2280])
ax.set_ylim([0.006, 0.024])
ax.set_xticks(np.linspace(2175, 2275, 3))
ax.ticklabel_format(axis='y', style='sci', useOffset=False, scilimits=(-2, 2))
ax.yaxis.offsetText.set_fontsize(numsize)
ax.set_xlabel(r'$Re_l$', fontsize=textsize)
ax.set_ylabel(r'$\omega l/u_\infty$', fontsize=textsize)
ax.tick_params(labelsize=numsize)
ax.grid(b=True, which="both", linestyle=":")
plt.savefig(pathF + "Re_omega.pdf", bbox_inches="tight")
plt.show()

# %% TS-modes along streamwise
xloc = np.arange(-40.0, -1.0 + 1.0, 1.0)
x_inlet = 0.382185449774020e3
blasius = 1.579375403141185e-04 # 1.669135812043661e-04
delta = 1e-3
Re = 13718000
val = 0.06202
var = 'beta'
lst_ts = np.zeros( (np.size(xloc), 2) )
Re_l = np.zeros( (np.size(xloc), 3) )
pathL1 = pathL + 'from_baseflow/'
for i in range(np.size(xloc)):
    xx = xloc[i]
    l_ref = blasius * np.sqrt((x_inlet + xx)/(x_inlet - 40.0))
    ts_mode = pd.read_csv(pathL1 + 'TSMode_' + var + '_' + str(xx) + '.dat',
                          sep=' ', index_col=False, skipinitialspace=True)
    # rescaled by Blasius length
    ts_mode = ts_mode.sort_values(var).reset_index()
    val1 = val / l_ref * delta
    # ts_mode = ts_mode / delta * l_ref
    # ts_mode['phi'] = ts_mode['phi'] * delta / l_ref
    lst_ts[i, 0] = interp1d(ts_mode[var], ts_mode['alpha_r'])(val1)
    lst_ts[i, 1] = interp1d(ts_mode[var], ts_mode['alpha_i'])(val1)
    Re_l[i, 0] = xx
    Re_l[i, 1] = l_ref
    Re_l[i, 2] = Re * l_ref

varval = np.column_stack((Re_l, lst_ts))
df = pd.DataFrame(data=varval, columns=['x', 'bl', 'Re', 'alpha_r', 'alpha_i'])
df.to_csv(pathL1 + 'LST_TS.dat',
          index=False, float_format='%1.8e', sep=' ')

# %% plot alpha
xloc = np.arange(-40.0, -1.0 + 1.0, 1.0)
beta1 = pd.read_csv(pathL + 'LST_TS.dat', sep=' ',
                    index_col=False, skipinitialspace=True)
fig = plt.figure(figsize=(6.4, 3.2))
matplotlib.rc("font", size=textsize)
ax = fig.add_subplot(121)
ax.plot(xloc, beta1['alpha_r'], 'k--', linewidth=1.2)
ax.set_xlim([-40.0, 0.0])
ax.set_ylim([0.16, 0.26])
# ax.set_xticks(np.linspace(2175, 2275, 3))
ax.ticklabel_format(axis='y', style='sci', useOffset=False, scilimits=(-2, 2))
ax.yaxis.offsetText.set_fontsize(numsize)
ax.set_xlabel(r'$x/\delta_0$', fontsize=textsize)
ax.set_ylabel(r'$\alpha_r^* \delta_0$', fontsize=textsize)
ax.tick_params(labelsize=numsize)
ax.grid(b=True, which="both", linestyle=":")
ax.annotate("(a)", xy=(-0.23, 1.00), xycoords='axes fraction',
             fontsize=numsize)

ax1 = fig.add_subplot(122)
ax1.plot(xloc, -beta1['alpha_i'], 'k--', linewidth=1.2)
ax1.set_xlim([-40.0, 0.0])
ax1.set_ylim([0.0, 0.020])
# ax1.set_xticks(np.linspace(2175, 2275, 3))
ax1.ticklabel_format(axis='y', style='sci', useOffset=False, scilimits=(-2, 2))
ax1.yaxis.offsetText.set_fontsize(numsize)
ax1.set_xlabel(r'$x/\delta_0$', fontsize=textsize)
ax1.set_ylabel(r'$-\alpha_i^* \delta_0$', fontsize=textsize)
ax1.tick_params(labelsize=numsize)
ax1.grid(b=True, which="both", linestyle=":")
ax1.annotate("(b)", xy=(-0.21, 1.00), xycoords='axes fraction',
             fontsize=numsize)
plt.tight_layout(pad=0.5, w_pad=0.6, h_pad=1)
plt.savefig(pathF + "Re_alpha.svg")
plt.show()

# %% plot amplitude along x
path1 = 'E:/cases/large_oblique/'
var_x = pd.read_csv(path1 + 'var_x.dat', sep='\t', skipinitialspace=True)
path = 'E:/cases/project/LST/export/'
cols = ['x', 'omega_r', 'omega_i', 'alpha_r', 'alpha_i', 'beta_r', 'beta_i']
x_profile = pd.read_csv(path + 'x-eigenvalue.dat', sep=' ', names=cols,
                         index_col=False, skiprows=1,
                         skipinitialspace=True)
x_profile = x_profile.sort_values(by=['x'])
x1_profile = x_profile.iloc[540:941]
a0 = 1
fluc = a0*np.exp(x1_profile['alpha_i']*x1_profile['x'])
fig, ax = plt.subplots(figsize=(6.4, 6.4))
matplotlib.rc("font", size=textsize)
# plot lines
ax.scatter(x1_profile['x'], fluc, s=15, marker='o',
           facecolors='k', edgecolors='k', linewidths=0.5)
ax.plot(var_x['x']+270, np.sqrt(var_x['<T`T`>']), 'b-')
ax.set_xlim([280, 480])
# ax.set_ylim([-0.1, 0.3])
ax.set_xlabel(r'$x$', fontsize=textsize)
ax.set_ylabel(r'$q^\prime$', fontsize=textsize)
ax.tick_params(labelsize=numsize)
ax.grid(b=True, which="both", linestyle=":")
plt.savefig(path + "amplidue_x.svg", bbox_inches="tight")
plt.show()


import os
import torch
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
from torch.distributions import Categorical

from virne.solver import registry
from .instance_env import InstanceEnv
from .net import Actor, ActorCritic, Critic
from virne.solver.learning.rl_base import *
from virne.base import Solution, SolutionStepEnvironment

@registry.register(
    solver_name='pg_cnn2',
    env_cls=SolutionStepEnvironment,
    solver_type='r_learning')
class PgCnn2Solver(InstanceAgent, PPOSolver):
    """
    A Reinforcement Learning-based solver that uses
    Policy Gradient (PG) as the training algorithm and
    Convolutional Neural Network (CNN) as the neural network model.
    Additionally, more graph features are used as the input of the CNN.
    """
    def __init__(self, controller, recorder, counter, **kwargs):
        kwargs['use_negative_sample'] = False
        InstanceAgent.__init__(self, InstanceEnv)
        PPOSolver.__init__(self, controller, recorder, counter, make_policy, obs_as_tensor, **kwargs)
        self.use_negative_sample = False

def make_policy(agent, **kwargs):
    action_dim = agent.p_net_setting_num_nodes
    feature_dim = agent.p_net_setting_num_node_resource_attrs + agent.p_net_setting_num_link_resource_attrs + 5
    policy = ActorCritic(feature_dim, action_dim, agent.embedding_dim).to(agent.device)
    optimizer = torch.optim.Adam([
        {'params': policy.parameters(), 'lr': agent.lr_actor}
    ], weight_decay=agent.weight_decay)
    return policy, optimizer

def obs_as_tensor(obs, device):
    # one
    if isinstance(obs, dict):
        obs_batch = obs
        p_net_x = torch.FloatTensor(np.array([obs_batch['p_net_x']])).to(device)
        action_mask = torch.FloatTensor(np.array([obs_batch['action_mask']])).to(device)
        tensor_obs = {'p_net_x': p_net_x, 'action_mask': action_mask}
        return tensor_obs
    # batch
    else:
        p_net_x = torch.FloatTensor(np.array([observation['p_net_x'] for observation in obs])).to(device)
        action_mask = torch.FloatTensor(np.array([observation['action_mask'] for observation in obs])).to(device)
        tensor_obs = {'p_net_x': p_net_x, 'action_mask': action_mask}
        return tensor_obs


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

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def isSubtree(self, s, t):
        if s is None and t is None:
            return True
        elif s is None and t is not None:
            return False
        elif s is not None and t is None:
            return True
        elif self.isSameTree(s, t):
            return True
        return self.isSubtree(s.left, t) or self.isSubtree(s.right, t)

    def isSameTree(self, s, t):
        if s is None and t is None:
            return True
        elif s is None or t is None:
            return False
        return (
            s.val == t.val
            and self.isSameTree(s.left, t.left)
            and self.isSameTree(s.right, t.right)
        )

if __name__ == "__main__":
    solution = Solution()

    t0_0 = TreeNode(3)
    t0_1 = TreeNode(4)
    t0_2 = TreeNode(5)
    t0_3 = TreeNode(1)
    t0_4 = TreeNode(2)
    t0_1.right = t0_4
    t0_1.left = t0_3
    t0_0.right = t0_2
    t0_0.left = t0_1

    t1_0 = TreeNode(4)
    t1_1 = TreeNode(1)
    t1_2 = TreeNode(2)
    t1_0.right = t1_2
    t1_0.left = t1_1

    assert solution.isSubtree(t0_0, t1_0)

    t2_0 = TreeNode(3)
    t2_1 = TreeNode(4)
    t2_2 = TreeNode(5)
    t2_3 = TreeNode(1)
    t2_4 = TreeNode(2)
    t2_5 = TreeNode(0)
    t2_4.left = t2_5
    t2_1.right = t2_4
    t2_1.left = t2_3
    t2_0.right = t2_2
    t2_0.left = t2_1

    assert not solution.isSubtree(t2_0, t1_0)


import logging					# 로깅 모듈 탑재
import logging.config                           # 로깅 설정 모듈 탑재

# 설정 파일 읽어 오기
logging.config.fileConfig('12-2.logging.conf')

# 로거 생성
logger = logging.getLogger(__name__)            # 로거 생성

# 로그 메시지 출력
logger.debug('이 메시지는 개발자만 이해해요.')	# DEBUG 로그 출력
logger.info('생각대로 동작 하고 있어요.')	        # INFO 로그 출력
logger.warn('곧 문제가 생길 가능성이 높습니다.')	# WARNING 로그 출력
logger.error('문제가 생겼어요.기능이 동작 안해요.')	# ERROR 로그 출력
logger.critical('시스템이 다운됩니다!!!!')	        # CRITICAL 로그 출력


"""Uses the PCA reduction method from C-Library (pca/)."""

import ctypes
import os
from pycsdp.utilites import defaults, make
# import time
import numpy as np

__VERSION__ = 'Release'

def _clean_pca(model='all'):
    """Cleans all generated file dring make.

    Parameters
    ----------
    model: str
        l_pca, nl_pca, all (default: all)
    """

    nl_paths = [defaults.get_nlpca("Debug"), defaults.get_nlpca("Release")]
    l_paths = [defaults.get_lpca("Debug"), defaults.get_lpca("Release")]
    rm_paths = []

    if model == 'all':
        rm_paths = nl_paths + l_paths
    elif model == 'nl_pca':
        rm_paths = nl_paths
    elif model == 'l_pca':
        rm_paths = l_paths

    for mpath in rm_paths:
        make.make_clean(mpath)

def pca_reduction(model, ver=__VERSION__):

    if model == 'nl_pca':
        nl_path = defaults.get_nlpca(ver)
        nl_make = make.make_obj_red(nl_path)

        # add checks for process reliablity
        nl_fn, free_fs = load_nl_pca(nl_path, ver)
        return nl_fn, free_fs

    elif model == 'l_pca':
        l_path = defaults.get_lpca(ver)
        l_make = make.make_obj_red(l_path)

        # add checks for process reliablity
        l_fn, free_fs = load_l_pca(l_path, ver)
        return l_fn, free_fs

def load_nl_pca(nl_path, ver=__VERSION__):
    nl_lib = ctypes.CDLL(os.path.join(nl_path, 'nl_mvu_pca_dmoss_kemoss.so'))
    nl_fn = nl_lib.main
    free_fs = nl_lib.free_fs
    return nl_fn, free_fs

def load_l_pca(nl_path, ver=__VERSION__):
    l_lib = ctypes.CDLL(os.path.join(nl_path, 'l_pca_dmoss_kemoss.so'))
    l_fn = l_lib.main
    free_fs = l_lib.free_fs
    return l_fn, free_fs

def nl_pca_reduction(arr, nl_fn, free_fs, ver=__VERSION__):

    shape = arr.shape
    # dtype = arr.dtype
    c_double_p = ctypes.POINTER(ctypes.c_double)
    c_int_p = ctypes.POINTER(ctypes.c_int)
    data_p = arr.ctypes.data_as(c_double_p)

    nl_fn.argtypes = (c_double_p, ctypes.c_int, ctypes.c_int)
    nl_fn.restype = c_int_p

    free_fs.argtype = ctypes.c_void_p
    free_fs.restype = ctypes.c_int

    fs_ptr = nl_fn(data_p, shape[0], shape[1])
    fs_data = np.ctypeslib.as_array(fs_ptr, shape=(3,))
    fs = fs_data.copy()
    try:
        free_fs(fs_ptr)
    except:
        print("something went wrong!!")

    return fs

def l_pca_reduction(arr, l_fn, free_fs, ver=__VERSION__):

    shape = arr.shape
    # dtype = arr.dtype

    c_double_p = ctypes.POINTER(ctypes.c_double)
    c_int_p = ctypes.POINTER(ctypes.c_int)

    data_p = arr.ctypes.data_as(c_double_p)
    l_fn.argtypes = (c_double_p, ctypes.c_int, ctypes.c_int)
    l_fn.restype = c_int_p

    free_fs.argtype = ctypes.c_void_p
    free_fs.restype = ctypes.c_int

    fs_ptr = l_fn(data_p, shape[0], shape[1])
    fs_data = np.ctypeslib.as_array(fs_ptr, shape=(2,))
    fs = fs_data.copy()

    free_fs(fs_ptr)
    return fs


from pytorch.experiment.utils import RunningMeanAndVariance,RunningMean

import numpy as np
from torch.utils.data import Dataset,DataLoader
import torch
import os
from pytorch.dataset import ImageDataset

def run_all_dataset(model,dataset,config,rotations,conv_aggregation_function,batch_size=256):
    n=dataset.x_test.shape[0]
    effective_batch_size = min(n, batch_size)
    dataset= ImageDataset(dataset.x_test,dataset.y_test, rotation=True)
    layer_vars = eval_var(dataset, model, config, rotations, effective_batch_size,conv_aggregation_function)
    return [layer_vars],[0]

def run(model,dataset,config,rotations,conv_aggregation_function,batch_size=256):
    x = dataset.x_test
    y=dataset.y_test
    y_ids=y.argmax(axis=1)
    classes=np.unique(y_ids)
    classes.sort()

    class_layer_vars=[]
    # calculate the var measure for each class
    for i, c in enumerate(classes):
        # logging.debug(f"Evaluating vars for class {c}...")
        ids=np.where(y_ids==c)
        ids=ids[0]
        x_class,y_class=x[ids,:],y[ids]
        n=x_class.shape[0]
        class_dataset=ImageDataset(x_class,y_class,rotation=True)
        effective_batch_size=min(n,batch_size)
        layer_vars=eval_var(class_dataset, model, config, rotations, effective_batch_size,conv_aggregation_function)
        class_layer_vars.append(layer_vars)
    stratified_layer_vars=eval_stratified_var(class_layer_vars)

    return class_layer_vars,stratified_layer_vars,classes

# calculate the mean activation of each unit in each layer over the set of classes
def eval_stratified_var(class_layer_vars):

    layer_class_vars=[list(i) for i in zip(*class_layer_vars)]
    layer_vars=[ sum(layer_values)/len(layer_values) for layer_values in layer_class_vars]
    return [layer_vars]

# calculate the var measure for a given dataset and model
def eval_var(dataset,model,config,rotations,batch_size,conv_aggregation_function):
    #baseline vars
    layer_vars_baselines=get_baseline_variance_class(dataset,model,config,rotations,batch_size,conv_aggregation_function)
    layer_vars = eval_var_class(dataset, model, config, rotations,batch_size,conv_aggregation_function)
    normalized_layer_vars = calculate_var(layer_vars_baselines,layer_vars)

    # for i in range(len(layer_vars_baselines)):
    #     print(f"class {i}")
    #     n=len(layer_vars_baselines[i])
    #     print([ type(layer_vars_baselines[i][j]) for j in range(n)])
    #     print([type(layer_vars[i][j]) for j in range(n)])
    #     print([type(normalized_layer_vars[i][j]) for j in range(n)])

    return normalized_layer_vars

def calculate_var(layer_baselines, layer_measures):
    eps=0
    measures = []  # coefficient of variations

    for layer_baseline, layer_measure in zip(layer_baselines, layer_measures):
        #print(layer_baseline.shape, layer_measure.shape)
        normalized_measure= layer_measure.copy()
        normalized_measure[layer_baseline > eps] /= layer_baseline[layer_baseline > eps]
        both_below_eps=np.logical_and(layer_baseline <= eps,layer_measure <= eps )
        normalized_measure[both_below_eps] = 1
        only_baseline_below_eps=np.logical_and(layer_baseline <= eps,layer_measure > eps )
        normalized_measure[only_baseline_below_eps] = np.inf
        measures.append(normalized_measure)
    return measures

def get_baseline_variance_class(dataset,model,config,rotations,batch_size,conv_aggregation_function):
    n_intermediates = model.n_intermediates()
    baseline_variances = [RunningMeanAndVariance() for i in range(n_intermediates)]

    for i, r in enumerate(rotations):
        degrees = (r - 1, r + 1)
        # logging.debug(f"    Rotation {degrees}...")
        dataset.update_rotation_angle(degrees)
        dataloader=DataLoader(dataset,batch_size=batch_size,shuffle=False, num_workers=0,drop_last=True)
        # calculate std for all examples and this rotation
        dataset_var=get_dataset_var(model,dataloader,config,conv_aggregation_function)
        #update the mean of the stds for every rotation
        # each std is intra rotation/class, so it measures the baseline
        # std for that activation
        for j,m in enumerate(dataset_var):
            baseline_variances[j].update(m.std())
    mean_baseline_variances=[b.mean() for b in baseline_variances]
    return mean_baseline_variances

def get_dataset_var(model,dataloader,config,conv_aggregation_function):
    n_intermediates = model.n_intermediates()
    var = [RunningMeanAndVariance() for i in range(n_intermediates)]
    for x,y_true in dataloader:
        if config.use_cuda:
            x = x.cuda()
        with torch.no_grad():
            y, intermediates = model.forward_intermediates(x)
            for j, intermediate in enumerate(intermediates):
                flat_activations=transform_activations(intermediate,conv_aggregation_function)
                for h in range(flat_activations.shape[0]):
                    var[j].update(flat_activations[h,:])
    return var

#returns a list of RunningMeanAndVariance objects,
# one for each intermediate output of the model.
#Each RunningMeanAndVariance contains the mean and std of each intermediate
# output over the set of rotations
def eval_var_class(dataset,model,config,rotations,batch_size,conv_aggregation_function):
    n_intermediates = model.n_intermediates()
    layer_vars= [RunningMeanAndVariance() for i in range(n_intermediates)]
    n = len(dataset)
    batch_ranges=[ range(i,i+batch_size) for i in range(n//batch_size)]

    for batch_range in batch_ranges:
        batch_var=BatchvarMeasure(batch_size,n_intermediates)
        for r in rotations:
            degrees = (r - 1, r + 1)
            dataset.update_rotation_angle(degrees)
            x,y_true=dataset.get_batch(batch_range)
            if config.use_cuda:
                x = x.cuda()
            with torch.no_grad():
                y, batch_activations= model.forward_intermediates(x)
                batch_activations=[transform_activations(a,conv_aggregation_function) for a in batch_activations]
                batch_var.update(batch_activations)
        batch_var.update_global_measures(layer_vars)

    mean_layer_vars = [b.mean() for b in layer_vars]
    return mean_layer_vars

class BatchvarMeasure:
    def __init__(self,batch_size,n_intermediates):
        self.batch_size=batch_size
        self.n_intermediates=n_intermediates
        self.batch_stats = [[RunningMeanAndVariance() for i in range(batch_size)] for j in range(n_intermediates)]
        self.batch_stats = np.array(self.batch_stats)

    def update(self,batch_activations):
        for i, layer_activations in enumerate(batch_activations):
            for j in range(layer_activations.shape[0]):
                self.batch_stats[i, j].update(layer_activations[j, :])

    def update_global_measures(self,dataset_stats):
        for i in range(self.n_intermediates):
            mean_var=dataset_stats[i]
            for j in range(self.batch_size):
                mean_var.update(self.batch_stats[i, j].std())

def transform_activations(activations_gpu,conv_aggregation_function):
    activations = activations_gpu.detach().cpu().numpy()

    # if conv average out spatial dims
    if len(activations.shape) == 4:
        n, c, w, h = activations.shape
        flat_activations = np.zeros((n, c))
        for i in range(n):
            if conv_aggregation_function=="mean":
                flat_activations[i, :] = np.nanmean(activations[i, :, :, :],axis=(1, 2))
            elif conv_aggregation_function=="max":
                flat_activations[i, :] = np.nanmax(activations[i, :, :, :],axis=(1, 2))
            elif conv_aggregation_function=="sum":
                flat_activations[i, :] = np.nansum(activations[i, :, :, :],axis=(1, 2))
            else:
                raise ValueError(f"Invalid aggregation function: {conv_aggregation_function}. Options: mean, max, sum")
        assert (len(flat_activations.shape) == 2)
    else:
        flat_activations = activations

    return flat_activations

def global_average_variance(result):
    rm=RunningMean()
    for layers in result:
        for layer in layers:
            for act in layer[:]:
                if np.isfinite(act):
                    rm.update(act)
    return rm.mean()

def run_all(model,rotated_model,dataset, config, n_rotations,conv_aggregation_function,batch_size=256):
    rotations = np.linspace(-180, 180, n_rotations, endpoint=False)

    print("Calculating variance for all samples by class...")
    rotated_var, rotated_stratified_layer_vars, classes = run(rotated_model, dataset, config, rotations,conv_aggregation_function,batch_size=batch_size,)
    var, stratified_layer_vars, classes = run(model, dataset, config, rotations,conv_aggregation_function,batch_size=batch_size)

    # Plot variance for all
    print("Calculating variance for all samples...")
    rotated_var_all_dataset, classes = run_all_dataset(rotated_model, dataset, config,
                                                       rotations,conv_aggregation_function,batch_size=batch_size)
    var_all_dataset, classes = run_all_dataset(model, dataset, config, rotations,conv_aggregation_function,batch_size=batch_size)
    return var,stratified_layer_vars,var_all_dataset,rotated_var,rotated_stratified_layer_vars,rotated_var_all_dataset


# -*- coding: utf-8 -*-
"""
scan
#https://pyimagesearch.com/2014/09/01/build-kick-ass-mobile-document-scanner-just-5-minutes/
"""
import cv2
import matplotlib.pyplot as  plt
import numpy as np
import imutils

def ScanImage(address):
    image=cv2.imread(address) #이미지 불러오기

    orig =image.copy()
    im_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    im_gray = cv2.GaussianBlur(im_gray, ksize = (0,0), sigmaX= 1)
    edged=cv2.Canny(im_gray,50,200) #canny edge
    #모폴로지연산 closing으로 틈 제거
    k = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
    edged = cv2.morphologyEx(edged, cv2.MORPH_CLOSE, k)

    def order_point(pts):
        rect = np.zeros((4,2),dtype='float32')

        s=pts.sum(axis=1)
        rect[0]=pts[np.argmin(s)]
        rect[2]=pts[np.argmax(s)]

        diff=np.diff(pts, axis=1)
        rect[1]=pts[np.argmin(diff)]
        rect[3]=pts[np.argmax(diff)]

        return rect

    def four_point_transform(image, pts):
        rect=order_point(pts)
        (tl,tr,br,bl)=rect

        widthA=np.sqrt(((br[0]-bl[0])**2)+((br[1]-bl[1])**2))
        widthB=np.sqrt(((tr[0]-tl[0])**2)+((tr[1]-tl[1])**2))
        maxWidth=max(int(widthA),int(widthB))

        heightA=np.sqrt(((tr[0]-br[0])**2)+((tr[1]-br[1])**2))
        heightB=np.sqrt(((tl[0]-bl[0])**2)+((tl[1]-bl[1])**2))
        maxHeight=max(int(heightA),int(heightB))

        dst=np.array([
            [0,0],
            [maxWidth - 1, 0],
            [maxWidth-1,maxHeight-0],
            [0,maxHeight-1]], dtype="float32")
        M=cv2.getPerspectiveTransform(rect,dst)
        warped=cv2.warpPerspective(image,M,(maxWidth,maxHeight))

        return warped

    ##가장큰 사각형이 종이라는 가정
    cnts =cv2.findContours(edged.copy(),cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    #RETR_LIST 계층 상관없이 모든 경계선 찾기
    cnts = imutils.grab_contours(cnts)
    cnts = sorted(cnts, key=cv2.contourArea, reverse = True)
    #크기별 정렬
    for c in cnts:
        peri=cv2.arcLength(c,True)
        #arcLength 외곽선 길이 반환
        approx = cv2.approxPolyDP(c,0.02*peri, True)
        #외곽선 근사화/단순화
        if len(approx)==4:
            screenCnt = approx
            break
        #사각형일때 까지 ->가장큰 사각형 영역

    ##변환+전처리
    warped = four_point_transform(orig, screenCnt.reshape(4,2)) #변환/함수참고
    warped_g=cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
    warped_g = cv2.bilateralFilter(warped_g, -1, 50, 3)
    warped_inv=cv2.bitwise_not(warped_g)
    T,_ = cv2.threshold(warped_inv, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    _,sample = cv2.threshold(warped_inv, min(180,int(T*1.2)), 255, cv2.THRESH_BINARY )  #bi+ otsu*1.2
    (h, w) = warped.shape[:2]
    h_=int(h*0.9)
    w_=int(w*0.9)
    hh=h-h_
    ww=w-w_
    sample_c=sample[hh:h_,ww:w_].copy() #끝을 잘라낸 이미지
    scan=cv2.bitwise_not(sample) #scan image
    return scan,sample_c

if __name__=='__main__':

    #check scan
    scan,sample_c=ScanImage('test/scantest.jpg') #불러올 파일주소
    resize_scan=cv2.resize(scan, (0,0), fx=0.3, fy=0.3, interpolation=cv2.INTER_AREA)
    cv2.imwrite('test/scantest_result.jpg',scan) #파일저장
    cv2.imwrite('test/scantest_result_c.jpg',sample_c) #파일저장
    cv2.imshow('scan',resize_scan)

    cv2.waitKey(0)
    cv2.destroyAllWindows()
    plt.subplot(1,2,1)
    plt.imshow(scan, cmap='gray')
    plt.title('scan')
    plt.subplot(1,2,2)
    plt.imshow(sample_c, cmap='gray')
    plt.title('sample_c')
    plt.show()