import os
import pytest
import aiohttp
from homeassistant.core import HomeAssistant

from custom_components.hacs.webresponses.frontend import async_serve_frontend
from custom_components.hacs.hacsbase.configuration import Configuration

from custom_components.hacs.share import get_hacs

@pytest.mark.asyncio
async def test_frontend():
    hacs = get_hacs()
    hacs.hass = HomeAssistant()
    await async_serve_frontend()

@pytest.mark.asyncio
async def test_frontend_debug():
    hacs = get_hacs()
    hacs.hass = HomeAssistant()
    hacs.configuration = Configuration()
    hacs.configuration.debug = True
    await async_serve_frontend()
    hacs.configuration = Configuration()

@pytest.mark.asyncio
async def test_frontend_repo(tmpdir):
    hacs = get_hacs()
    hacs.hass = HomeAssistant()
    hacs.configuration = Configuration()
    hacs.configuration.frontend_repo = tmpdir

    await async_serve_frontend()

    os.makedirs(f"{tmpdir}/hacs_frontend", exist_ok=True)
    with open(f"{tmpdir}/hacs_frontend/main.js", "w") as target:
        target.write("")

    await async_serve_frontend()

    hacs.configuration = Configuration()

@pytest.mark.asyncio
async def test_frontend_frontend_repo_url(aresponses, event_loop):
    aresponses.add(
        "127.0.0.1", "/main.js", "get", "",
    )

    hacs = get_hacs()
    hacs.hass = HomeAssistant()
    hacs.configuration = Configuration()
    hacs.configuration.frontend_repo_url = "http://127.0.0.1"
    await async_serve_frontend()

    async with aiohttp.ClientSession(loop=event_loop) as session:
        hacs.session = session
        await async_serve_frontend()
        hacs.configuration = Configuration()


import torch
import torch.nn as nn
import torch.nn.init as init

class Encoder(nn.Module):
	def __init__(self, input_dim, hid_dim,layers):
		super(Encoder,self).__init__()
		self.n_layers = layers
		self.hidden = hid_dim
		self.inputd = input_dim
		self.lstm = nn.LSTM(input_dim, hid_dim, layers)
	def forward(self, src):
		batch, seqsize = src.shape
		datainput = torch.zeros([seqsize,batch,self.inputd])
		datainput[:,:,0] = torch.transpose(src,0,1)[:,:]
		h0 = torch.randn(self.n_layers,batch,self.hidden)
		c0 = torch.randn(self.n_layers,batch,self.hidden)
		outputs, (hidden, cell) = self.lstm(datainput,(h0,c0))
		return torch.transpose(outputs,0,1), hidden, cell


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

from __future__ import print_function
import keras
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
import os

batch_size = 32

num_classes = 3 # 3 people to recognize

epochs = 50 # 50 epochs to train thedata

#save the model
save_dir = os.path.join(os.getcwd(), 'saved_models')
model_name = 'keras_face_recognization_model.h5'

#image size
img_w = 150
img_h = 150

# save loss and accuracy
class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = {'batch':[], 'epoch':[]}
        self.accuracy = {'batch':[], 'epoch':[]}
        self.val_loss = {'batch':[], 'epoch':[]}
        self.val_acc = {'batch':[], 'epoch':[]}

    def on_batch_end(self, batch, logs={}):
        self.losses['batch'].append(logs.get('loss'))
        self.accuracy['batch'].append(logs.get('acc'))
        self.val_loss['batch'].append(logs.get('val_loss'))
        self.val_acc['batch'].append(logs.get('val_acc'))

    def on_epoch_end(self, batch, logs={}):
        self.losses['epoch'].append(logs.get('loss'))
        self.accuracy['epoch'].append(logs.get('acc'))
        self.val_loss['epoch'].append(logs.get('val_loss'))
        self.val_acc['epoch'].append(logs.get('val_acc'))

    def loss_plot(self, loss_type):
        iters = range(len(self.losses[loss_type]))
        plt.figure()
        # accuracy
        plt.plot(iters, self.accuracy[loss_type], 'r', label='train acc')
        # loss
        plt.plot(iters, self.losses[loss_type], 'g', label='train loss')
        if loss_type == 'epoch':
            # val_accuracy
            plt.plot(iters, self.val_acc[loss_type], 'b', label='val acc')
            # val_loss
            plt.plot(iters, self.val_loss[loss_type], 'k', label='val loss')
        plt.grid(True)
        plt.xlabel(loss_type)
        plt.ylabel('acc-loss')
        plt.legend(loc="upper right")
        plt.show()

model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same',
                 input_shape=(150, 150, 3))) # image is 150 * 150 * 3
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))

# initiate RMSprop optimizer
opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)

# Let's train the model using RMSprop
model.compile(loss='categorical_crossentropy',
              optimizer=opt,
              metrics=['accuracy'])

history = LossHistory()

train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1. / 255)

# use the training data
train_generator = train_datagen.flow_from_directory(
    './data/train',
    target_size=(img_w, img_h),
    batch_size=batch_size,
    shuffle=True,
    class_mode='categorical')

#test the model
validation_generator = test_datagen.flow_from_directory(
    './data/validation',
    target_size=(img_w, img_h),
    batch_size=batch_size,
    shuffle=True,
    class_mode='categorical')

# training model
model.fit_generator(
    train_generator,
    samples_per_epoch=2400,
    nb_epoch=epochs,
    validation_data=validation_generator,
    nb_val_samples=800,
    callbacks=[history])

# Save model and weights
if not os.path.isdir(save_dir):
    os.makedirs(save_dir)
model_path = os.path.join(save_dir, model_name)
model.save(model_path)
print('Saved trained model at %s ' % model_path)

history.loss_plot('epoch')


import flask

from koyomi.database import get_db_connection
from koyomi.template import render_template

bp = flask.Blueprint("search", __name__)

@bp.route("/search")
def search():
    query_string = flask.request.args.get('q');
    if not query_string:
        return render_template('search.tmpl', title="Search", query_string="")

    cnx = get_db_connection();
    try:
        cursor = cnx.cursor()
        cursor.execute("SELECT query.link, query.title, "
                       "pgroonga_snippet_html(query.content, pgroonga_query_extract_keywords(%s)) FROM "
                       "(SELECT post.link AS link, post.content AS content, post.title AS title "
                       "FROM post "
                       ") AS query WHERE query.content &@~ %s",
                       (query_string, query_string))
        ret = render_template("search.tmpl", title=query_string, cursor=cursor, query_string=query_string)
    finally:
        cnx.close()

    return ret


from __future__ import division
from baseband import vdif
import numpy as np
import astropy.units as u
import matplotlib.pylab as plt
import glob
import sys
from astropy.time import Time
from mpi4py import MPI

comm = MPI.COMM_WORLD
Csize = comm.Get_size()
rank = comm.Get_rank()

size = 2 ** 16  # there are 2**26 time samples per file
sample_rate = 800/1024. * u.MHz
dt1 = 2.56e-6 * u.s

fedge = 800 * u.MHz
dispersion_delay_constant = 4149. * u.s * u.MHz**2 * u.cm**3 / u.pc
#dm = 555. * u.pc / u.cm**3  # Frb121011
dm = 12.4370 * u.pc / u.cm**3  # b1919 / LGM1

# Set up frequencies for de-dispersion
freq = np.linspace(400,800,1025)[:-1]*u.MHz
freq = freq[::-1]
fref = freq
fcoh = freq - np.fft.fftfreq(size, 1024 / (400*u.MHz))[:, np.newaxis]

# Pre-calculate de-dispersion delays (coherent phases + incoherent offsets)
dang = (dispersion_delay_constant * dm * freq * (1./fref-1./fcoh)**2) * u.cycle
with u.set_enabled_equivalencies(u.dimensionless_angles()):
    dd_coh = np.exp(dang * 1j).conj().astype(np.complex64);

# Dispersion delays relative to 800MHz
dt = dispersion_delay_constant * dm * (1./freq**2 - 1./(800*u.MHz)**2)

T = 4.0*u.s
binf = 512
tbin = dt1*binf
ntbin = size // binf
tfile = dt1*size
tpad = int(max(dt) // tbin + 1)

# Begin at time offset specified in command (seconds from start of obs)
tstart = int(sys.argv[1]) * u.s
dstart = int(tstart // tfile)

# Initialize empty array for waterfall
w = np.zeros((int(T // tbin) + tpad, 2, 1024)) + 0j

#filelist = glob.glob('./data/20160422T132947Z_aro_raw/*vdif')
filelist = glob.glob('/media/drive2/b1919/*vdif')
filelist = np.sort(filelist)

N = int(T//tfile)+1
Npcore = max(N // Csize, 1)

for i in range(rank*Npcore + dstart, (rank+1)*Npcore + dstart):

    if (i - dstart) > N:
        print("Rank %s exiting" % (rank))
        break

    print("Rank %s on %s of %s" % ( rank, (i - rank*Npcore - dstart), Npcore) )
    fn = filelist[i]
    fh = vdif.open(fn, mode='rs', sample_rate=sample_rate)
    try:
        d = fh.read(size)
        d_ft = np.fft.fft(d, axis=0)
        d_ft *= dd_coh
        d = np.fft.ifft(d_ft, axis=0)
        d = d.reshape(-1, binf, 2, 1024).mean(1)

        w[i*ntbin:(i+1)*ntbin] = d
    except:
        print("file %s failed assertion" % (str(i)))

for i in xrange(len(dt)):
    w[...,i] = np.roll(w[...,i], int(dt[i]//tbin), axis=0)

w = abs(w.sum(1))
w2 = np.zeros_like(w)
comm.Reduce(w, w2, op=MPI.SUM, root=0)

if rank == 0:
    np.save('waterfall-t%s-%ssec.npy' % (str(tstart.value), str(T.value)), w2)
#    plt.imshow(abs(w2[:,0]).T, aspect='auto', interpolation='nearest')
#    plt.show()


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

__author__ = 'diwan'

"""
This script contains functions that make several different kinds of plots of ADCP
netCDF-format data. The types of plots are:
    1. North and East current velocities (one plot containing a subplot for each)
    2. Along and cross-shelf current velocities (one plot containing a subplot for each)
    3. North and East Godin or 30h-averaged filtered current velocities
    4. Along and cross-shelf Godin or 30h-averaged filtered current velocities
    5. Bin plot for one month's worth of velocity data comparing raw and filtered (Godin or 30h-averaged) data
    6. Diagnostic plot containing subplots of:
        1. Time-averaged backscatter over depth
        2. Time-averaged velocity over depth
        3. Mean orientation

Plots can be made from L0-, L1- or L2-processed data.

Credits:
Diagnostic plot code adapted from David Spear (originally in MatLab)
fmamidir() and fpcdir() function code from Roy Hourston (originally in MatLab)

From Roy Hourston's fpcdir.m script:
    "THETA = fpcdir(X,Y) is the principal component direction of X and Y.
    In other words, it is the angle of rotation counter-clockwise from
    north of the first principal component of X and Y. Applies to
    bivariate data set only. See Emery and Thomson, Data Analysis Methods
    in Oceanography, 1997, p.327, and Preisendorfer, Principal Component
    Analysis in Meteorology and Oceanography, 1988, p.15. Second principal
    angle is given by THETA + 90 degrees."
"""

import xarray as xr
import matplotlib.pyplot as plt
import numpy as np
import os
import math
import pandas as pd

def resolve_to_alongcross(u_true, v_true, along_angle):
    # Rotate North and East velocities to along- and cross-shore velocities given an along-shore angle
    # along_angle measured in degrees counter-clockwise from geographic East
    along_angle = np.deg2rad(along_angle)

    u_along = u_true * np.cos(along_angle) + v_true * np.sin(along_angle)
    u_cross = u_true * np.sin(along_angle) - v_true * np.cos(along_angle)

    return u_along, u_cross

def get_L1_start_end(ncdata):
    # Obtain the number of leading and trailing ensembles that were set to nans in L1 processing
    # from the processing_history global attribute.
    # Then get the index of the last ensemble cut from the beginning of the time series
    # and the index of the first ensemble cut from the end of the time series.
    # ncdata: dataset-type object created by reading in a netCDF ADCP file with the xarray package

    digits_in_process_hist = [int(s) for s in ncdata.attrs['processing_history'].split() if s.isdigit()]
    # The indices used are conditional upon the contents of the processing history remaining unchanged
    # in L1 and before L2. Appending to the end of the processing history is ok
    start_end_indices = (digits_in_process_hist[1], len(ncdata.time.data) - digits_in_process_hist[2] - 1)

    return start_end_indices

def fmamidir(u, v):
    # Computes principal component direction of u and v

    ub = np.nanmean(u)
    vb = np.nanmean(v)
    uu = np.nanmean(u ** 2)
    vv = np.nanmean(v ** 2)
    uv = np.nanmean(u * v)
    uu = uu - (ub * ub)
    vv = vv - (vb * vb)
    uv = uv - (ub * vb)

    # Solve for the quadratic
    a = 1.0
    b = -(uu + vv)
    c = (uu * vv) - (uv * uv)
    s1 = (-b + np.sqrt((b * b) - (4.0 * a * c)) / (2.0 * a))
    s2 = (-b - np.sqrt((b * b) - (4.0 * a * c)) / (2.0 * a))
    major = s1
    minor = s2
    if minor > major:
        major = s2
        minor = s1

    # Return major and minor axes
    return major, minor

def fpcdir(x, y):
    if x.shape != y.shape:
        ValueError('u and v are different sizes!')
    else:
        # Compute major and minor axes
        major, minor = fmamidir(x, y)

        # Compute principal component direction
        u = x
        v = y
        ub = np.nanmean(u)
        vb = np.nanmean(v)
        uu = np.nanmean(u ** 2)
        uv = np.nanmean(u * v)
        uu = uu - (ub * ub)
        uv = uv - (ub * vb)

        e1 = -uv / (uu - major)
        e2 = 1
        rad_deg = 180 / np.pi  # conversion factor
        theta = np.arctan2(e1, e2) * rad_deg
        theta = -theta  # change rotation angle to be CCW from North

    return theta

def calculate_depths(dataset):
    """
    Calculate ADCP bin depths in the water column
    Inputs:
        - dataset: dataset-type object created by reading in a netCDF ADCP file with the xarray package
    Outputs:
        - numpy array of ADCP bin depths
    """
    # depths = np.mean(ncdata.PRESPR01[0,:]) - ncdata.distance  #What Di used
    if dataset.orientation == 'up':
        return float(dataset.instrument_depth) - dataset.distance.data
    else:
        return float(dataset.instrument_depth) + dataset.distance.data

def vb_flag(dataset):
    """
    Create flag for missing vertical beam data in files from Sentinel V ADCPs
    flag = 0 if Sentinel V file has vertical beam data, or file not from Sentinel V
    flag = 1 if Sentinel V file does not have vertical beam data
    Inputs:
        - dataset: dataset-type object created by reading in a netCDF ADCP file with the xarray package
    Outputs:
        - value of flag
    """
    try:
        x = dataset.TNIHCE05.data
        return 0
    except AttributeError:
        if dataset.instrumentSubtype == 'Sentinel V':
            return 1
        else:
            return 0

def get_plot_dir(filename, dest_dir):
    if 'L0' in filename.data.tolist():
        plot_dir = './{}/L0_Python_plots/'.format(dest_dir)
    elif 'L1' in filename.data.tolist():
        plot_dir = './{}/L1_Python_plots/'.format(dest_dir)
    elif 'L2' in filename.data.tolist():
        plot_dir = './{}/L2_Python_plots/'.format(dest_dir)
    else:
        ValueError('Input netCDF file must be a L0, L1 or L2-processed file.')

    return plot_dir

def plots_diagnostic(nc, dest_dir, level0=False):
    """
    Preliminary plots:
    (1) Backscatter against depth, (2) mean velocity, and (3) principle component direction
    Credits: David Spear, Roy Hourston
    Inputs:
        - d: dataset-type object created by reading in a netCDF ADCP file with the xarray package
    Outputs:
        None
    """
    # Subplot 1/3: Plot avg backscatter against depth

    # First calculate depths
    depths = calculate_depths(nc)

    # Check if vertical beam data present in Sentinel V file
    flag_vb = vb_flag(nc)

    # Calculate average backscatter (amplitude intensity)
    amp_mean_b1 = np.nanmean(nc.TNIHCE01.data, axis=1)
    amp_mean_b2 = np.nanmean(nc.TNIHCE02.data, axis=1)
    amp_mean_b3 = np.nanmean(nc.TNIHCE03.data, axis=1)
    amp_mean_b4 = np.nanmean(nc.TNIHCE04.data, axis=1)

    if nc.instrumentSubtype == 'Sentinel V' and flag_vb == 0:
        amp_mean_b5 = np.nanmean(nc.TNIHCE05.data, axis=1)
        amp = [amp_mean_b1, amp_mean_b2, amp_mean_b3, amp_mean_b4, amp_mean_b5]
        colours = ['b', 'g', 'c', 'm', 'y'] #list of plotting colours
    else:
        # Done calculating time-averaged amplitude intensity
        amp = [amp_mean_b1, amp_mean_b2, amp_mean_b3, amp_mean_b4]
        colours = ['b', 'g', 'c', 'm']

    # Start plot

    # Make plot and first subplot
    fig = plt.figure(figsize=(11, 8.5))
    ax = fig.add_subplot(1, 3, 1)

    beam_no = 1
    for dat, col in zip(amp, colours):
        f1 = ax.plot(dat, depths, label='Beam {}'.format(beam_no), linewidth=1, marker='o', markersize=2, color=col)
        beam_no += 1
    ax.set_ylim(depths[-1], depths[0])
    ax.legend(loc='lower left')
    ax.set_xlabel('Counts')
    ax.set_ylabel('Depth (m)')  # Set y axis label for this subplot only out of the 3
    ax.grid()
    ax.tick_params(axis='both', direction='in', top=True, right=True)
    ax.set_title('Mean Backscatter', fontweight='semibold')  # subplot title
    # Flip over x-axis if instrument oriented 'up'
    if nc.orientation == 'up':
        plt.gca().invert_yaxis()

    # Subplot 2/3: Mean velocity
    ax = fig.add_subplot(1, 3, 2)

    # Calculate average velocities
    u_mean = np.zeros(int(nc.numberOfCells), dtype='float32')
    v_mean = np.zeros(int(nc.numberOfCells), dtype='float32')
    w_mean = np.zeros(int(nc.numberOfCells), dtype='float32')

    if level0:
        for i in range(len(u_mean)):
            u_mean[i] = np.nanmean(nc.VEL_MAGNETIC_EAST.data[i, :])
            v_mean[i] = np.nanmean(nc.VEL_MAGNETIC_NORTH.data[i, :])
            w_mean[i] = np.nanmean(nc.LRZAAP01.data[i, :])
    else:
        for i in range(len(u_mean)):
            u_mean[i] = np.nanmean(nc.LCEWAP01.data[i, :])
            v_mean[i] = np.nanmean(nc.LCNSAP01.data[i, :])
            w_mean[i] = np.nanmean(nc.LRZAAP01.data[i, :])

    if nc.instrumentSubtype == 'Sentinel V' and flag_vb == 0:
        w5_mean = np.zeros(int(nc.numberOfCells), dtype='float32')
        for i in range(len(u_mean)):
            w5_mean[i] = np.nanmean(nc.LRZUVP01.data[i, :])

        if level0:
            names = ['VEL_MAGNETIC_EAST', 'VEL_MAGNETIC_NORTH', 'LRZAAP01', 'LRZUVP01']
        else:
            names = ['LCEWAP01', 'LCNSAP01', 'LRZAAP01', 'LRZUVP01']
        vels = [u_mean, v_mean, w_mean, w5_mean]
    else:
        if level0:
            names = ['VEL_MAGNETIC_EAST', 'VEL_MAGNETIC_NORTH', 'LRZAAP01']
        else:
            names = ['LCEWAP01', 'LCNSAP01', 'LRZAAP01']
        vels = [u_mean, v_mean, w_mean]

    # Plot
    for i in range(len(names)):
        f2 = ax.plot(vels[i], depths, label=names[i], linewidth=1, marker='o', markersize=2, color=colours[i])
    ax.set_ylim(depths[-1], depths[0])  # set vertical limits
    ax.legend(loc='lower left')
    ax.set_xlabel('Velocity (m/s)')
    ax.grid()
    ax.tick_params(axis='both', direction='in', top=True, right=True)
    ax.set_title('Mean Velocity', fontweight='semibold')  # subplot title
    # Flip over x-axis if instrument oriented 'up'
    if nc.orientation == 'up':
        plt.gca().invert_yaxis()

    # Subplot 3/3: Principal axis

    orientation = np.zeros(int(nc.numberOfCells), dtype='float32')
    for ibin in range(len(orientation)):
        if level0:
            xx = nc.VEL_MAGNETIC_EAST.data[ibin, :]
            yy = nc.VEL_MAGNETIC_NORTH.data[ibin, :]
        else:
            xx = nc.LCEWAP01.data[ibin, :]
            yy = nc.LCNSAP01.data[ibin, :]
        orientation[ibin] = fpcdir(xx, yy)  # convert to CW direction

    mean_orientation = np.round(np.nanmean(orientation), decimals=1)
    middle_orientation = np.mean([np.nanmin(orientation), np.nanmax(orientation)])  #text plotting coordinate
    mean_depth = np.nanmean(depths)  #text plotting coordinate

    # Make the subplot
    ax = fig.add_subplot(1, 3, 3)
    f3 = ax.plot(orientation, depths, linewidth=1, marker='o', markersize=2)
    ax.set_ylim(depths[-1], depths[0])  # set vertical limits
    ax.set_xlabel('Orientation')
    ax.text(x=middle_orientation, y=mean_depth, s='Mean orientation = ' + str(mean_orientation) + '$^\circ$',
            horizontalalignment='center', verticalalignment='center', fontsize=10)
    ax.grid()  # set grid
    ax.tick_params(axis='both', direction='in', top=True, right=True)
    ax.set_title('Principal Axis', fontweight='semibold')  # subplot title
    # Flip over x-axis if instrument oriented 'up'
    if nc.orientation == 'up':
        plt.gca().invert_yaxis()

    # Create centred figure title
    fig.suptitle('{}-{} {} at {} m depth'.format(nc.station, nc.deployment_number, nc.serial_number,
                                                 nc.instrument_depth), fontweight='semibold')

    # Create plots subfolder
    plot_dir = get_plot_dir(nc.filename, dest_dir)
    if not os.path.exists(plot_dir):
        os.makedirs(plot_dir)

    fig_name = plot_dir + '{}-{}_{}_nc_diagnostic.png'.format(
        nc.station, str(nc.deployment_number), nc.serial_number)
    fig.savefig(fig_name)
    plt.close()

    return os.path.abspath(fig_name)

def limit_data(ncdata, ew_data, ns_data):
    if ncdata.orientation == 'up':
        bin_depths = ncdata.instrument_depth - ncdata.distance.data
    else:
        bin_depths = ncdata.instrument_depth + ncdata.distance.data
    print(bin_depths)

    # data.time should be limited to the data.time with no NA values; bins must be limited
    if 'L1' in ncdata.filename.data.tolist() or 'L2' in ncdata.filename.data.tolist():
        new_first_last = get_L1_start_end(ncdata=ncdata)
    else:
        new_first_last = (0, len(ew_data[0]))

    # Remove bins where surface backscatter occurs
    time_lim = ncdata.time.data[new_first_last[0]:new_first_last[1]]

    bin_depths_lim = bin_depths[bin_depths >= 0]
    print(bin_depths_lim)

    ew_lim = ew_data[bin_depths >= 0, new_first_last[0]:new_first_last[1]]
    ns_lim = ns_data[bin_depths >= 0, new_first_last[0]:new_first_last[1]]

    return time_lim, bin_depths_lim, ns_lim, ew_lim

def get_vminvmax(v1_data, v2_data):
    """
    Get range of pcolor color bar
    Inputs:
        - v1_data, v2_data: 2 raw or filtered velocity data components (East and North or Along- and Cross-shore)
    Outputs:
        - 2-element list containing the color bar min and max
    """
    v1_std = np.nanstd(v1_data)
    v1_mean = np.nanmean(v1_data)
    v1_lim = np.max([np.abs(-(v1_mean + 2 * v1_std)), np.abs(v1_mean + 2 * v1_std)])
    v2_std = np.nanstd(v2_data)
    v2_mean = np.nanmean(v2_data)
    v2_lim = np.max([np.abs(-(v2_mean + 2 * v2_std)), np.abs(v2_mean + 2 * v2_std)])

    # determine which limit to use
    vel_lim = np.max([v1_lim, v2_lim])
    print(vel_lim)
    vminvmax = [-vel_lim, vel_lim]
    print(vminvmax)
    return vminvmax

def make_pcolor_ne(nc, dest_dir, time_lim, bin_depths_lim, ns_lim, ew_lim, level0=False, filter_type='raw'):
    # filter_type options: 'raw' (default), '30h' (or, 35h, etc, average), 'Godin' (Godin Filtered)

    magnetic = '' #specify "Magnetic (North)" for L0 files, since magnetic declination wasn't applied to them
    if level0:
        magnetic = 'Magnetic '

    # vminvmax = [-0.5, 0.5] #vertical min and max of the colour bar in the plots
    vminvmax = get_vminvmax(ns_lim, ew_lim)
    fig = plt.figure(figsize=(13.75, 10))
    ax = fig.add_subplot(2, 1, 1)

    f1 = ax.pcolor(time_lim, bin_depths_lim, ns_lim[:, :], cmap='RdBu_r', vmin=vminvmax[0], vmax=vminvmax[1])
    cbar = fig.colorbar(f1, shrink=0.8)
    cbar.set_label('Velocity [m s$^{-1}$]', fontsize=14)
    ax.set_ylabel('Depth [m]', fontsize=14)

    if filter_type == '30h':
        ax.set_title(
            'ADCP ({}North, 30h average) {}-{} {}m'.format(magnetic, nc.attrs['station'],
                                                           nc.attrs['deployment_number'],
                                                           str(int(nc.instrument_depth))), fontsize=14)
    elif filter_type == 'Godin':
        ax.set_title(
            'ADCP ({}North, Godin Filtered) {}-{} {}m'.format(magnetic, nc.attrs['station'],
                                                              nc.attrs['deployment_number'],
                                                              str(int(nc.instrument_depth))), fontsize=14)
    elif filter_type == 'raw':
        ax.set_title(
            'ADCP ({}North, raw) {}-{} {}m'.format(magnetic, nc.attrs['station'], nc.attrs['deployment_number'],
                                                   str(int(nc.instrument_depth))), fontsize=14)
    else:
        ValueError('Not a recognized data type; choose one of \'raw\', \'30h\' or \'Godin\'')

    if nc.orientation == 'up':
        plt.gca().invert_yaxis()

    ax2 = fig.add_subplot(2, 1, 2)

    f2 = ax2.pcolor(time_lim, bin_depths_lim, ew_lim[:, :], cmap='RdBu_r', vmin=vminvmax[0], vmax=vminvmax[1])
    cbar = fig.colorbar(f2, shrink=0.8)
    cbar.set_label('Velocity [m s$^{-1}$]', fontsize=14)

    ax2.set_ylabel('Depth [m]', fontsize=14)
    if 'h' in filter_type:  # xxh-average; e.g. '30h', '35h'
        ax2.set_title('ADCP ({}East, {} average) {}-{} {}m'.format(magnetic, filter_type, nc.attrs['station'],
                                                                   nc.attrs['deployment_number'],
                                                                   str(int(nc.instrument_depth))), fontsize=14)
    elif filter_type == 'Godin':
        ax2.set_title('ADCP ({}East, Godin Filtered) {}-{} {}m'.format(magnetic, nc.attrs['station'],
                                                                       nc.attrs['deployment_number'],
                                                                       str(int(nc.instrument_depth))), fontsize=14)
    elif filter_type == 'raw':
        ax2.set_title(
            'ADCP ({}East, raw) {}-{} {}m'.format(magnetic, nc.attrs['station'], nc.attrs['deployment_number'],
                                                  str(int(nc.instrument_depth))), fontsize=14)

    if nc.orientation == 'up':
        plt.gca().invert_yaxis()

    # Create L1_Python_plots or L2_Python_plots subfolder if not made already
    plot_dir = get_plot_dir(nc.filename, dest_dir)

    if not os.path.exists(plot_dir):
        os.makedirs(plot_dir)

    if level0:
        plot_name = plot_dir + nc.attrs['station'] + '-' + nc.attrs['deployment_number'] + '_{0}m'.format(
            str(int(nc.instrument_depth))) + '-magn_NE_{}.png'.format(filter_type)
    else:
        plot_name = plot_dir + nc.attrs['station'] + '-' + nc.attrs['deployment_number'] + '_{0}m'.format(
            str(int(nc.instrument_depth))) + '-NE_{}.png'.format(filter_type)
    fig.savefig(plot_name)
    plt.close()

    return os.path.abspath(plot_name)

def determine_dom_angle(u_true, v_true):
    # Determine the dominant angle in degrees
    # along_angle measured in degrees relative to geographic East, counter-clockwise
    angles = np.arange(0, 180)
    max_rms = 0.
    max_angle = 0.
    for angle in angles:
        along_angle = np.deg2rad(angle)

        u_along = u_true * np.cos(along_angle) + v_true * np.sin(along_angle)
        rms = np.sqrt(np.nanmean(u_along * u_along))
        if rms > max_rms:
            max_rms = rms
            max_angle = angle # in degrees
    along_angle = max_angle
    cross_angle = max_angle - 90.
    return along_angle, cross_angle

def make_pcolor_ac(data, dest_dir, time_lim, bin_depths_lim, ns_lim, ew_lim, filter_type='raw', along_angle=None):
    # filter_type options: 'raw' (default), '30h' (or, 35h, etc, average), 'Godin' (Godin Filtered)
    # cross_angle in degrees; defaults to 25
    if along_angle is None:
        along_angle, cross_angle = determine_dom_angle(ew_lim, ns_lim)
    else:
        cross_angle = along_angle - 90  # deg
    print(along_angle, cross_angle)

    u_along, u_cross = resolve_to_alongcross(ew_lim, ns_lim, along_angle)
    AS = u_along
    CS = u_cross

    # vminvmax = [-0.5, 0.5] #vertical min and max of the colour bar in the plots
    vminvmax = get_vminvmax(AS, CS)
    fig = plt.figure(figsize=(13.75, 10))
    ax1 = fig.add_subplot(2, 1, 1)

    f1 = ax1.pcolor(time_lim, bin_depths_lim, AS[:, :], cmap='RdBu_r', vmin=vminvmax[0], vmax=vminvmax[1])
    cbar = fig.colorbar(f1, shrink=0.8)
    cbar.set_label('Velocity [m s$^{-1}$]', fontsize=14)

    ax1.set_ylabel('Depth [m]', fontsize=14)
    if 'h' in filter_type:
        ax1.set_title(
            'ADCP (along, {} average) {}$^\circ$ (CCW from E) {}-{} {}m'.format(filter_type, along_angle,
                                                                                data.attrs['station'],
                                                                                data.attrs['deployment_number'],
                                                                                math.ceil(data.instrument_depth)),
            fontsize=14)
    elif filter_type == 'Godin':
        ax1.set_title(
            'ADCP (along, Godin Filtered) {}$^\circ$ (CCW from E) {}-{} {}m'.format(along_angle, data.attrs['station'],
                                                                                data.attrs['deployment_number'],
                                                                                math.ceil(data.instrument_depth)),
            fontsize=14)
    elif filter_type == 'raw':
        ax1.set_title('ADCP (along, raw) {}$^\circ$ (CCW from E) {}-{} {}m'.format(along_angle, data.attrs['station'],
                                                                                data.attrs['deployment_number'],
                                                                                math.ceil(data.instrument_depth)),
                      fontsize=14)
    else:
        ValueError('Not a recognized data type; choose one of \'raw\', \'30h\' or \'Godin\'')

    if data.orientation == 'up':
        plt.gca().invert_yaxis()

    ax2 = fig.add_subplot(2, 1, 2)

    f2 = ax2.pcolor(time_lim, bin_depths_lim, CS[:, :], cmap='RdBu_r', vmin=vminvmax[0], vmax=vminvmax[1])
    cbar = fig.colorbar(f2, shrink=0.8)
    cbar.set_label('Velocity [m s$^{-1}$]', fontsize=14)

    ax2.set_ylabel('Depth [m]', fontsize=14)
    if 'h' in filter_type:  # xxh-average; e.g. '30h', '35h'
        ax2.set_title(
            'ADCP (cross, {} average) {}$^\circ$ (CCW from E) {}-{} {}m'.format(filter_type, cross_angle,
                                                                                data.attrs['station'],
                                                                                data.attrs['deployment_number'],
                                                                                math.ceil(data.instrument_depth)),
            fontsize=14)
    elif filter_type == 'Godin':
        ax2.set_title(
            'ADCP (cross, Godin Filtered) {}$^\circ$ (CCW from E) {}-{} {}m'.format(str(cross_angle),
                                                                                data.attrs['station'],
                                                                                data.attrs['deployment_number'],
                                                                                str(math.ceil(
                                                                                data.instrument_depth))),
            fontsize=14)
    elif filter_type == 'raw':
        ax2.set_title(
            'ADCP (cross, raw) {}$^\circ$ (CCW from E) {}-{} {}m'.format(str(cross_angle), data.attrs['station'],
                                                                         data.attrs['deployment_number'],
                                                                         str(math.ceil(data.instrument_depth))),
            fontsize=14)
    else:
        ValueError('Not a recognized data type; choose one of \'raw\', \'30h\' or \'Godin\'')

    if data.orientation == 'up':
        plt.gca().invert_yaxis()

    # Create plots subfolder if not made already
    plot_dir = get_plot_dir(data.filename, dest_dir)
    if not os.path.exists(plot_dir):
        os.makedirs(plot_dir)

    plot_name = plot_dir + data.attrs['station'] + '-' + data.attrs['deployment_number'] + '_{}m'.format(
        math.ceil(data.instrument_depth)) + '-AC_{}.png'.format(filter_type)
    fig.savefig(plot_name)
    plt.close()

    return os.path.abspath(plot_name)

def num_ens_per_hr(nc):
    # Calculate the number of ensembles recorded per hour
    time_incr = float(nc.time.data[1] - nc.time.data[0])
    hr2min = 60
    min2sec = 60
    sec2nsec = 1e9
    hr2nsec = hr2min * min2sec * sec2nsec
    return int(np.round(hr2nsec / time_incr, decimals=0))

def filter_godin(nc):
    # Make North and East lowpassed plots using the simple 3-day Godin filter
    # Running average of 24 hours first, then another time with a 24 hour filter, the again with a 25 hour filter
    # Repeat with along- and cross-shore velocities
    # nc: xarray Dataset-type object from reading in a netCDF file; contains 1D numpy array of values
    # Output: 1D numpy array of values of same size as the time series within nc, padded with nan's

    # Determine the number of ensembles taken per hour
    ens_per_hr = num_ens_per_hr(nc)
    print('Time stamps per hour:', ens_per_hr, sep=' ')
    window = int(ens_per_hr)
    num_hrs = 24

    # Rolling window calculations
    # Need to take transpose so that the rolling average is taken along the time (not bin) axis
    if 'L0' in nc.filename.data.tolist():
        ew_df = pd.DataFrame(data=nc.VEL_MAGNETIC_EAST.data.transpose())
        ns_df = pd.DataFrame(data=nc.VEL_MAGNETIC_NORTH.data.transpose())
    else:
        ew_df = pd.DataFrame(data=nc.LCEWAP01.data.transpose())
        ns_df = pd.DataFrame(data=nc.LCNSAP01.data.transpose())
    # 24h rolling average
    ew_filt_temp1 = ew_df.rolling(window=num_hrs * window, min_periods=None, center=True, win_type=None).median()
    ns_filt_temp1 = ns_df.rolling(window=num_hrs * window, min_periods=None, center=True, win_type=None).median()
    # 24h rolling average
    ew_filt_temp2 = ew_filt_temp1.rolling(window=num_hrs * window, min_periods=None, center=True,
                                          win_type=None).median()
    ns_filt_temp2 = ns_filt_temp1.rolling(window=num_hrs * window, min_periods=None, center=True,
                                          win_type=None).median()
    # 25h rolling average
    ew_filt_final = ew_filt_temp2.rolling(window=(num_hrs + 1) * window, min_periods=None, center=True,
                                          win_type=None).median()
    ns_filt_final = ns_filt_temp2.rolling(window=(num_hrs + 1) * window, min_periods=None, center=True,
                                          win_type=None).median()

    # Convert to numpy arrays
    ew_filt_final = ew_filt_final.to_numpy().transpose()
    ns_filt_final = ns_filt_final.to_numpy().transpose()

    return ew_filt_final, ns_filt_final

def filter_XXh(nc, num_hrs=30):
    # Perform XXh averaging on velocity data (30-hour, 35-hour, ...)
    # nc: xarray Dataset-type object from reading in a netCDF file; contains 1D numpy array of values
    # Output: 1D numpy array of values of same size as the time series within nc, padded with nan's

    # Determine the number of ensembles taken per hour
    ens_per_hr = num_ens_per_hr(nc)
    print(ens_per_hr)
    window = int(ens_per_hr)

    # Rolling window calculations
    # Need to take transpose so that the rolling average is taken along the time (not bin) axis
    if 'L0' in nc.filename.data.tolist():
        ew_df = pd.DataFrame(data=nc.VEL_MAGNETIC_EAST.data.transpose())
        ns_df = pd.DataFrame(data=nc.VEL_MAGNETIC_NORTH.data.transpose())
    else:
        ew_df = pd.DataFrame(data=nc.LCEWAP01.data.transpose())
        ns_df = pd.DataFrame(data=nc.LCNSAP01.data.transpose())
    ew_filt_final = ew_df.rolling(window=num_hrs * window, min_periods=None, center=True, win_type=None).median()
    ns_filt_final = ns_df.rolling(window=num_hrs * window, min_periods=None, center=True, win_type=None).median()

    # Convert to numpy arrays
    ew_filt_final = ew_filt_final.to_numpy().transpose()
    ns_filt_final = ns_filt_final.to_numpy().transpose()

    return ew_filt_final, ns_filt_final

def binplot_compare_filt(nc, dest_dir, time, dat_raw, dat_filt, filter_type, direction):
    # Function to take one bin from the unfiltered (raw) data and the corresponding bin in the filtered
    # data, and plot the time series together on one plot. Restrict time series to 1 month.
    # dat_filt: data filtered using the method defined in filter_type
    # filter_type options: 'Godin' or 'xxh' (e.g., '30h', '35h')
    # direction: 'east' or 'north'

    if direction == 'magnetic_east':
        vel_code = 'VEL_MAGNETIC_EAST'
    elif direction == 'magnetic_north':
        vel_code = 'VEL_MAGNETIC_NORTH'
    elif direction == 'east':
        vel_code = 'LCEWAP01'
    elif direction == 'north':
        vel_code = 'LCNSAP01'

    # Calculate the number of ensembles in 1 month
    ens_per_hr = num_ens_per_hr(nc)
    hr2day = 24
    day2mth = 30
    ens_per_mth = ens_per_hr * hr2day * day2mth

    bin_index = 0  # which bin to plot
    if nc.orientation == 'up':
        bin_depth = nc.instrument_depth - (bin_index + 1) * nc.cellSize
    else:
        bin_depth = nc.instrument_depth + (bin_index + 1) * nc.cellSize

    fig = plt.figure(figsize=(13.75, 10))

    ax1 = fig.add_subplot(1, 1, 1)

    f1 = ax1.plot(time[:ens_per_mth], dat_raw[bin_index, :ens_per_mth], color='k', label='Raw')
    if filter_type == 'Godin':
        f2 = ax1.plot(time[:ens_per_mth], dat_filt[bin_index, :ens_per_mth], color='b', label='Godin Filtered')
    elif 'h' in filter_type:
        f2 = ax1.plot(time[:ens_per_mth], dat_filt[bin_index, :ens_per_mth], color='b',
                      label='{} average'.format(filter_type))

    ax1.set_ylabel('Velocity [m s$^{-1}$]', fontsize=14)
    ax1.legend(loc='lower left')
    ax1.set_title(
        'ADCP {}-{} {} bin {} at {}m'.format(nc.attrs['station'], nc.attrs['deployment_number'],
                                             vel_code, bin_index + 1, bin_depth), fontsize=14)

    # Create L1_Python_plots or L2_Python_plots subfolder if not made already
    plot_dir = get_plot_dir(nc.filename, dest_dir)
    if not os.path.exists(plot_dir):
        os.makedirs(plot_dir)

    plot_name = plot_dir + nc.attrs['station'] + '-' + nc.attrs['deployment_number'] + '_{0}m'.format(
        str(math.ceil(nc.instrument_depth))) + '-{}_bin{}_compare_{}.png'.format(vel_code, bin_index + 1,
                                                                                filter_type)
    fig.savefig(plot_name)
    plt.close()
    return os.path.abspath(plot_name)

def create_westcoast_plots(ncfile, dest_dir, filter_type="Godin", along_angle=None):
    """
    Inputs:
        - ncfile: file name of netCDF ADCP file
        - dest_dir: destination directory for output files
        - filter_type: "Godin", "30h", or "35h"
        - along_angle: Along-shore angle measured in degrees relative to geographic East, counter-clockwise
    Outputs:
        - list of absolute file names of output files
    """
    ncdata = xr.open_dataset(ncfile)

    if "L0" in ncfile:
        fname_diagnostic = plots_diagnostic(ncdata, dest_dir, True)

        time_lim, bin_depths_lim, ns_lim, ew_lim = limit_data(ncdata, ncdata.VEL_MAGNETIC_EAST.data, ncdata.VEL_MAGNETIC_NORTH.data)
        # North/East velocity plots
        fname_ne = make_pcolor_ne(ncdata, dest_dir, time_lim, bin_depths_lim, ns_lim, ew_lim, True)

        # Along/Cross-shelf velocity plots
        fname_ac = make_pcolor_ac(ncdata, dest_dir, time_lim, bin_depths_lim, ns_lim, ew_lim, 'raw', along_angle)

    else:
        fname_diagnostic = plots_diagnostic(ncdata, dest_dir)

        time_lim, bin_depths_lim, ns_lim, ew_lim = limit_data(ncdata, ncdata.LCEWAP01.data, ncdata.LCNSAP01.data)
        # North/East velocity plots
        fname_ne = make_pcolor_ne(ncdata, dest_dir, time_lim, bin_depths_lim, ns_lim, ew_lim)

        # Along/Cross-shelf velocity plots
        fname_ac = make_pcolor_ac(ncdata, dest_dir, time_lim, bin_depths_lim, ns_lim, ew_lim, 'raw', along_angle)

    # Redo whole process with filtered data

    if filter_type == "Godin":
        ew_filt, ns_filt = filter_godin(ncdata)
    elif filter_type == "30h":
        ew_filt, ns_filt = filter_XXh(ncdata, num_hrs=30)
    elif filter_type == "35h":
        ew_filt, ns_filt = filter_XXh(ncdata, num_hrs=35)
    else:
        ValueError("filter_type value not understood !")

    # Limit data
    time_lim, bin_depths_lim, ns_filt_lim, ew_filt_lim = limit_data(ncdata, ew_filt, ns_filt)

    # East/North
    if "L0" in ncfile:
        fname_ne_filt = make_pcolor_ne(ncdata, dest_dir, time_lim, bin_depths_lim, ns_filt_lim, ew_filt_lim, True,
                                       filter_type)
    else:
        fname_ne_filt = make_pcolor_ne(ncdata, dest_dir, time_lim, bin_depths_lim, ns_filt_lim, ew_filt_lim, False,
                                       filter_type)

    # Along-shore/cross-shore
    fname_ac_filt = make_pcolor_ac(ncdata, dest_dir, time_lim, bin_depths_lim, ns_filt_lim, ew_filt_lim, filter_type, along_angle)

    # Compare velocity in bin 1
    if 'L0' in ncfile:
        fname_binplot = binplot_compare_filt(ncdata, dest_dir, time_lim, ew_lim, ew_filt_lim, filter_type,
                                             direction='magnetic_east')
    else:
        fname_binplot = binplot_compare_filt(ncdata, dest_dir, time_lim, ew_lim, ew_filt_lim, filter_type,
                                             direction='east')

    return [fname_diagnostic, fname_ne, fname_ac, fname_ne_filt, fname_ac_filt, fname_binplot]


#!/share/home/cuiyaning/anaconda3/bin/python3
# -*- coding:utf-8 -*-
## 2019/11/27_v1

##!/user/bin/env python2

import numpy as np
import spglib

symbol_map = {
    "H":1,
    "He":2,
    "Li":3,
    "Be":4,
    "B":5,
    "C":6,
    "N":7,
    "O":8,
    "F":9,
    "Ne":10,
    "Na":11,
    "Mg":12,
    "Al":13,
    "Si":14,
    "P":15,
    "S":16,
    "Cl":17,
    "Ar":18,
    "K":19,
    "Ca":20,
    "Sc":21,
    "Ti":22,
    "V":23,
    "Cr":24,
    "Mn":25,
    "Fe":26,
    "Co":27,
    "Ni":28,
    "Cu":29,
    "Zn":30,
    "Ga":31,
    "Ge":32,
    "As":33,
    "Se":34,
    "Br":35,
    "Kr":36,
    "Rb":37,
    "Sr":38,
    "Y":39,
    "Zr":40,
    "Nb":41,
    "Mo":42,
    "Tc":43,
    "Ru":44,
    "Rh":45,
    "Pd":46,
    "Ag":47,
    "Cd":48,
    "In":49,
    "Sn":50,
    "Sb":51,
    "Te":52,
    "I":53,
    "Xe":54,
    "Cs":55,
    "Ba":56,
    "La":57,
    "Ce":58,
    "Pr":59,
    "Nd":60,
    "Pm":61,
    "Sm":62,
    "Eu":63,
    "Gd":64,
    "Tb":65,
    "Dy":66,
    "Ho":67,
    "Er":68,
    "Tm":69,
    "Yb":70,
    "Lu":71,
    "Hf":72,
    "Ta":73,
    "W":74,
    "Re":75,
    "Os":76,
    "Ir":77,
    "Pt":78,
    "Au":79,
    "Hg":80,
    "Tl":81,
    "Pb":82,
    "Bi":83,
    "Po":84,
    "At":85,
    "Rn":86,
    "Fr":87,
    "Ra":88,
    "Ac":89,
    "Th":90,
    "Pa":91,
    "U":92,
    "Np":93,
    "Pu":94,
    "Am":95,
    "Cm":96,
    "Bk":97,
    "Cf":98,
    "Es":99,
    "Fm":100,
    "Md":101,
    "No":102,
    "Lr":103,
    "Rf":104,
    "Db":105,
    "Sg":106,
    "Bh":107,
    "Hs":108,
    "Mt":109,
    "Ds":110,
    "Rg":111,
    "Cn":112,
    "Uut":113,
    "Uuq":114,
    "Uup":115,
    "Uuh":116,
    "Uus":117,
    "Uuo":118,
    }

#for st in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
#    with open("POSCAR-"+str(st), "r") as f:
#        file = f.readlines()

for st in ["POSCAR", "CONTCAR"]:
    try:
        with open(st, "r") as f:
            file = f.readlines()
    except FileNotFoundError:
        print("Not find %s"%st)
        continue

    lists = []
    for a in [2, 3, 4]:
        row = []
        for b in file[a].split():
            row.append(float(b))
        lists.append(row)
    lattice = np.array(lists) * float(file[1])

    num = 0
    numbers = []
    atmtyp = file[5].strip().split()
    elenu = file[6].split()
    numbers = []
    for ine,a in enumerate(elenu):
        for i in range(int(a)):
            numbers.append(symbol_map.get(atmtyp[ine]))
        num = num+int(a)
        #numbers.append(int(a))

    positions = []
    for a in range(8,8+num):
        row = []
        for b in file[a].split():
            row.append(float(b))
        positions.append(row)

    cell = (lattice, positions, numbers)

    #magmoms = [m_1, m_2, ...]
    #cell = (lattice, positions, numbers, magmoms)

    spgobj = spglib.get_symmetry_dataset(cell, symprec=1e-5, hall_number=0)
    print(st)
    print(spgobj.get("international"))
    print(spglib.get_spacegroup_type(spgobj.get("hall_number")).get("schoenflies") + "\n")

#print(spglib.get_spacegroup(cell, symprec=1e-5))

#mesh = [8, 8, 8]
#
##
## Gamma centre mesh
##
#mapping, grid = spglib.get_ir_reciprocal_mesh(mesh, cell, is_shift=[0, 0, 0])
#
## All k-points and mapping to ir-grid points
#for i, (ir_gp_id, gp) in enumerate(zip(mapping, grid)):
#    print("%3d ->%3d %s" % (i, ir_gp_id, gp.astype(float) / mesh))
#
## Irreducible k-points
#print("Number of ir-kpoints: %d" % len(np.unique(mapping)))
#print(grid[np.unique(mapping)] / np.array(mesh, dtype=float))
#
##
## With shift
##
#mapping, grid = spglib.get_ir_reciprocal_mesh(mesh, cell, is_shift=[1, 1, 1])
#
## All k-points and mapping to ir-grid points
#for i, (ir_gp_id, gp) in enumerate(zip(mapping, grid)):
#    print("%3d ->%3d %s" % (i, ir_gp_id, (gp + [0.5, 0.5, 0.5]) / mesh))
#
## Irreducible k-points
#print("Number of ir-kpoints: %d" % len(np.unique(mapping)))
#print((grid[np.unique(mapping)] + [0.5, 0.5, 0.5]) / mesh)


"""
Setup-View
"""
from django.contrib import messages
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.views.generic import TemplateView
from django.utils.translation import ugettext_lazy as _
from skd.models import Configuration, UserKey

class SetupView(TemplateView):
    """
    Creates a setup view for basic installation tasks such as creating
    a new ssh key pair.

    **Template:**

    :template:`skd/setup.html`

    """

    template_name = "skd/setup.html"

    # SKD administrative groups

    default_groups = [
        {
            "name": "skd_viewer",
            "description": "Users can only view and list objects like users, "
                           "keys, hosts, etc. They cannot edit, delete or "
                           "create them and cannot apply changes. They cannot"
                           " see the Action Log.",
            "permissions": [
                "skd.list_users",
                "skd.list_users_keys",
                "skd.list_usermaps",
                "skd.list_usergroups",
                "skd.list_users_in_usergroups",
                "skd.list_hosts",
                "skd.list_hostgroups",
                "skd.list_hosts_in_hostgroups",
                "skd.list_usergroups_in_hostgroups"
            ]
        },
        {
            "name": "skd_audit",
            "description": "Users can see the action log.",
            "permissions": [
                "skd.list_users",
                "skd.list_users_keys",
                "skd.list_usermaps",
                "skd.list_usergroups",
                "skd.list_users_in_usergroups",
                "skd.list_hosts",
                "skd.list_hostgroups",
                "skd.list_hosts_in_hostgroups",
                "skd.list_usergroups_in_hostgroups",
                "skd.list_actionlog"
            ]
        },
        {
            "name": "skd_usermanager",
            "description": "Users have full control of the user, "
                           "usergroup and key objects",
            "permissions": [
                "skd.list_users",
                "skd.list_users_keys",
                "skd.list_usermaps",
                "skd.list_usergroups",
                "skd.list_users_in_usergroups",
                "skd.list_hosts",
                "skd.list_hostgroups",
                "skd.list_hosts_in_hostgroups",
                "skd.list_usergroups_in_hostgroups",
                "skd.list_actionlog",
                "skd.add_user",
                "skd.change_user",
                "skd.delete_user",
                "skd.add_userkey",
                "skd.change_userkey",
                "skd.delete_userkey",
                "skd.add_usermap",
                "skd.change_usermap",
                "skd.delete_usermap",
                "skd.add_usergroup",
                "skd.change_usergroup",
                "skd.delete_usergroup",
                "skd.add_useringroup",
                "skd.change_useringroup",
                "skd.delete_useringroup",
                "skd.add_actionlog",
                "skd.add_applylog"
            ]
        },
        {
            "name": "skd_hostmanager",
            "description": "Users have the permissions in skd_audit "
                           "plus full control of the host and hostgroup "
                           "objects.",
            "permissions": [
                "skd.list_users",
                "skd.list_users_keys",
                "skd.list_usermaps",
                "skd.list_usergroups",
                "skd.list_users_in_usergroups",
                "skd.list_hosts",
                "skd.list_hostgroups",
                "skd.list_hosts_in_hostgroups",
                "skd.list_usergroups_in_hostgroups",
                "skd.list_actionlog",
                "skd.add_host",
                "skd.change_host",
                "skd.delete_host",
                "skd.add_hostgroup",
                "skd.change_hostgroup",
                "skd.delete_hostgroup",
                "skd.add_hostingroup",
                "skd.change_hostingroup",
                "skd.delete_hostingroup",
                "skd.add_actionlog",
                "skd.add_applylog",
                "skd.setup_host"
            ]
        },
        {
            "name": "skd_manager",
            "description": "skd_usermanager and "
                           "skd_hostmanager combined.",
            "permissions": [
                "skd.list_users",
                "skd.list_users_keys",
                "skd.list_usermaps",
                "skd.list_usergroups",
                "skd.list_users_in_usergroups",
                "skd.list_hosts",
                "skd.list_hostgroups",
                "skd.list_hosts_in_hostgroups",
                "skd.list_usergroups_in_hostgroups",
                "skd.list_actionlog",
                "skd.add_user",
                "skd.change_user",
                "skd.delete_user",
                "skd.add_userkey",
                "skd.change_userkey",
                "skd.delete_userkey",
                "skd.add_usermap",
                "skd.change_usermap",
                "skd.delete_usermap",
                "skd.add_usergroup",
                "skd.change_usergroup",
                "skd.delete_usergroup",
                "skd.add_useringroup",
                "skd.change_useringroup",
                "skd.delete_useringroup",
                "skd.add_host",
                "skd.change_host",
                "skd.delete_host",
                "skd.add_hostgroup",
                "skd.change_hostgroup",
                "skd.delete_hostgroup",
                "skd.add_hostingroup",
                "skd.change_hostingroup",
                "skd.delete_hostingroup",
                "skd.add_usergroupinhostgroup",
                "skd.change_usergroupinhostgroup",
                "skd.delete_usergroupinhostgroup",
                "skd.add_actionlog",
                "skd.add_applylog"
            ]
        },
        {
            "name": "skd_deployer",
            "description": "Can manage the whole database and apply the "
                           "changes (thus deploy new keys). Can delete the "
                           "actionlog.",
            "permissions": [
                "skd.list_users",
                "skd.list_users_keys",
                "skd.list_usermaps",
                "skd.list_usergroups",
                "skd.list_users_in_usergroups",
                "skd.list_hosts",
                "skd.list_hostgroups",
                "skd.list_hosts_in_hostgroups",
                "skd.list_usergroups_in_hostgroups",
                "skd.list_actionlog",
                "skd.add_user",
                "skd.change_user",
                "skd.delete_user",
                "skd.add_userkey",
                "skd.change_userkey",
                "skd.delete_userkey",
                "skd.add_usermap",
                "skd.change_usermap",
                "skd.delete_usermap",
                "skd.add_usergroup",
                "skd.change_usergroup",
                "skd.delete_usergroup",
                "skd.add_useringroup",
                "skd.change_useringroup",
                "skd.delete_useringroup",
                "skd.add_host",
                "skd.change_host",
                "skd.delete_host",
                "skd.add_hostgroup",
                "skd.change_hostgroup",
                "skd.delete_hostgroup",
                "skd.add_hostingroup",
                "skd.change_hostingroup",
                "skd.delete_hostingroup",
                "skd.add_usergroupinhostgroup",
                "skd.change_usergroupinhostgroup",
                "skd.delete_usergroupinhostgroup",
                "skd.add_actionlog",
                "skd.change_actionlog",
                "skd.delete_actionlog",
                "skd.can_apply",
                "skd.add_applylog",
                "skd.change_applylog",
                "skd.delete_applylog"
            ]
        }
    ]

    generation_messages = ""
    generation_status = "none"

    def get_context_data(self, **kwargs):
        context = super(SetupView, self).get_context_data(**kwargs)

        context["generation_messages"] = self.generation_messages
        context["generation_status"] = self.generation_status

        if Configuration.objects.filter(key="sshkey_public").exists():

            context["sshkey_public"] = Configuration.objects.get(
                key="sshkey_public"
            ).value

        if not Group.objects.filter(name__istartswith="skd_").exists():

            context["no_groups"] = True
            context["default_groups"] = self.default_groups

        return context

    def post(self, request, *args, **kwargs):

        if "sshkey_generate" in request.POST:

            # Generate a new Keypair

            if Configuration.objects.filter(key="sshkey_public"):

                # Get current configuration objects

                public_key = Configuration.objects.get(
                    key="sshkey_public"
                )

                private_key = Configuration.objects.get(
                    key="sshkey_private"
                )

            else:

                # Generate new configuration objects

                public_key = Configuration()
                public_key.key = "sshkey_public"

                private_key = Configuration()
                private_key.key = "sshkey_private"

            passphrase = self.request.POST.get("passphrase", None)
            keytype = self.request.POST.get("keytype", "dsa")
            bits = int(self.request.POST.get("bits", "1024"))

            # Call keygen to generate the keypair

            keyret = UserKey.objects.keygen(
                u"%s" % _("skd master key"),
                keytype,
                bits,
                passphrase
            )

            self.generation_status = keyret["generation_status"]

            if self.generation_status == "success":

                # Generation successful. Store keypair and type.

                if Configuration.objects.filter(key="sshkey_type"):

                    keytype_conf = Configuration.objects.get(key="sshkey_type")

                else:

                    keytype_conf = Configuration()
                    keytype_conf.key = "sshkey_type"

                keytype_conf.value = keytype
                keytype_conf.save()

                public_key.value = keyret["public_key"]

                public_key.save()

                private_key.value = keyret["private_key"]

                private_key.save()

                messages.success(
                    request,
                    _("The skd master key has been successfully generated.")
                )

            else:

                messages.error(request, keyret["generation_messages"])

        if "groups_generate" in request.POST:

            # We should generate the default groups.

            if not Group.objects.filter(name__istartswith="skd_").exists():

                # But only, if they haven't been already.

                for group in self.default_groups:

                    # Generate the default groups based on the permission
                    # dictionary above.

                    current_group = Group(
                        name=group["name"]
                    )

                    current_group.save()

                    for permission in group["permissions"]:
                        app, codename = permission.split(".")

                        app_ids = ContentType.objects.filter(
                            app_label=app
                        )

                        permission_object = Permission.objects.get(
                            codename=codename,
                            content_type_id__in=app_ids
                        )

                        current_group.permissions.add(permission_object)

                    current_group.save()

                messages.success(
                    request,
                    _("Default groups have been successfully generated.")
                )

            else:

                messages.error(
                    request,
                    _("Default groups have already been generated and can't "
                      "automatically been recreated. You have to manually "
                      "remove all groups starting with 'skd_'")
                )

        return self.get(request, *args, **kwargs)


my_list=[]
count=1
print('Creating the list')
while len(my_list)<7: #creating the list
    print('Enter the integer number',count,end='')
    a=input(':')
    try:
        val=int(a)
        my_list.append(val)
        count+=1
    except ValueError:
        try:
            val=float(a)
            print('You entered a float. ')
        except ValueError:
            print('You did not enter a number. ')
count_1=0
while count_1==0:
    print('Enter the number from the list you want to find its difference from the mid number',end='')
    x=input(':')
    try:
        val=int(x)
        count_1+=1
    except ValueError :
        try:
            val=float(x)
            print('You entered a float. ')
        except ValueError :
            print('You did not enter a number. ')
def finddiff(a,array):#This function receives a number and a list.Then calculates the difference between mid number and received number.
    count=0
    for i in range(7):
        if array[i]==a:
            diff=abs(a-array[3])
            count+=1
    if count==0:
        print('This number does not exist in the list ')
    else:
        print(diff,'is the difference of mid number and received number.')
finddiff(val,my_list)


#!/usr/bin/env python3
# PYTHON_ARGCOMPLETE_OK

import argparse
import os
import pickle

import argcomplete
import numpy as np
from keras.models import Model, load_model
from keras.preprocessing import image
from keras import backend as K
from keras.layers.convolutional import Conv2D
from keras.layers.core import Dense, Flatten

def load_image(img_path):
    img = image.load_img(img_path, target_size=(28, 28), color_mode="grayscale")
     # (height, width, channels)
    img_tensor = image.img_to_array(img)
    # (1, height, width, channels), add a dimension because the model
    # expects this shape: (batch_size, height, width, channels)
    img_tensor = np.expand_dims(img_tensor, axis=0)
    img_tensor /= 255.

    return img_tensor

def create_parser():
    # create the top-level parser
    parser = argparse.ArgumentParser(prog='run')

    parser.add_argument('h5_file',
                        default="sample_project/BUILD_TRAIN/mnist_model.h5",
                        nargs=1,
                        help='Trained model in h5 format')

    parser.add_argument('-i', '--image_file',
                        type=str,
                        default="examples/1/1037.pgm",
                        help='Image file')

    parser.add_argument('-D', '--directory',
                        type=str,
                        default=".",
                        help='directory to store pickles in')

    operat = parser.add_mutually_exclusive_group(required=True)

    operat.add_argument('-l', '--list',
                        help='list layer names',
                        action='store_true')
    operat.add_argument('-p', '--print',
                        nargs=1,
                        type=int,
                        help='print the output of a layer number')
    operat.add_argument('-d', '--dump_layers',
                        action='store_true',
                        help='pickles an array of the outputs of each layer')
    operat.add_argument('-P', '--predict',
                        action='store_true',
                        help='print the output of a layer number')
    operat.add_argument('-w', '--dump_weights',
                        type=str,
                        help='pickles an array of the weights of each Conv2D or Dense layer')
    return parser

def list_layers(model):
    model.summary()
    for idx, layer in enumerate(model.layers):
        print("{idx:3d}) {layer.name}".format(idx=idx, layer=layer))

def print_layer(model, layer_num, input_image):
    name = model.layers[layer_num].name
    int_model = Model(inputs=model.input,
                      outputs=model.get_layer(name).output)
    int_output = int_model.predict(input_image)
    print(int_output)

def predict(model, input_image):
    output = model.predict(input_image)
    print(np.argmax(output))

def reorganize_dimensions(output):
    # remove batch dimension and order channel first
    # Also store outputs in an array to be compatible with nntool outputs
    output = output[0]
    if K.image_data_format() == 'channels_last' and len(output.shape) > 1:
        current = [idx for idx in range(len(output.shape))]
        first = current.pop()
        current.insert(0, first)
        output = output.transpose(current)
    return [output]

def dump_layers(model, input_image, filename):
    outputs = [reorganize_dimensions(input_image)]
    for idx in range(len(model.layers)):
        name = model.layers[idx].name
        int_model = Model(inputs=model.input,
                          outputs=model.get_layer(name).output)
        int_output = int_model.predict(input_image)
        outputs.append(reorganize_dimensions(int_output))

    with open(filename, 'wb') as pickle_fp:
        pickle.dump(outputs, pickle_fp)

def dump_weights(model, filename):
    outputs = []
    for layer_idx, layer in enumerate(model.layers):
        if isinstance(layer, Conv2D):
            params = layer.get_weights()
            outputs.append({
                'name': layer.name,
                'weights': params[0].transpose((3, 2, 0, 1)),
                'biases': params[1]
            })
        elif isinstance(layer, Dense):
            params = layer.get_weights()
            # The weights of a Dense layer are in the wrong order to validate against an adjusted
            # graph ready for the AutoTiler. We need to reorder them.
            # The shape of the input to the dense layer has already been flattened.
            # The previous layer should be a flatten which we can use to discover the original shape
            assert isinstance(model.layers[layer_idx - 1], Flatten)
            # use the input shape of the flatten layer to figure out the full shape
            shape = model.layers[layer_idx - 1].input_shape
            in_c = shape[3]
            h = shape[2]
            w = shape[1]
            out_c = layer.output_shape[1]
            # expand the weights to the full shape
            weights = params[0].reshape((h, w, in_c, out_c))
            # AutoTiler kernels expect Activations in c, h, w order
            # The AutoTiler linear layer expects c_out, in_sz
            # So the order of the weights should be c_out, c_in, h, w
            weights = weights.transpose((3, 2, 0, 1))
            # now reshape to c_out, in_sz
            weights = weights.reshape((out_c, in_c * h * w))
            outputs.append({'name': layer.name, 'weights': weights, 'biases': params[1]})
        else:
            outputs.append({'name': layer.name})

    with open(filename, 'wb') as pickle_fp:
        pickle.dump(outputs, pickle_fp)

def main():
    parser = create_parser()
    argcomplete.autocomplete(parser)
    args = parser.parse_args()

    model = load_model(args.h5_file[0])

    if args.list:
        list_layers(model)
        parser.exit(0)
        return
    elif args.dump_weights:
        filename = os.path.join(args.directory,
                                args.dump_weights)
        print("dumping weights to {} ...".format(filename))
        dump_weights(model, filename)
        parser.exit(0)
        return

    if not args.image_file:
        parser.error("you need to specify an image")
        parser.exit(1)
        return

    input_image = load_image(args.image_file)

    if args.print:
        print_layer(model, args.print, input_image)
    elif args.predict:
        predict(model, input_image)
    elif args.dump_layers:
        filename = os.path.join(args.directory,
                                os.path.basename(args.image_file)+'.pickle')
        print("dumping layers to {} ...".format(filename))
        dump_layers(model, input_image, filename)
    parser.exit(0)

if __name__ == "__main__":
    main()